Skip to content

Commit

Permalink
student button clickable
Browse files Browse the repository at this point in the history
  • Loading branch information
mchami02 committed Aug 25, 2024
1 parent 28b4097 commit df1fc69
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 174 deletions.
49 changes: 14 additions & 35 deletions src/NotebookSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,33 @@
import React, { useState, useEffect } from 'react';
import React, { useState } from 'react';
import '../style/notebookSelector.css';

interface NotebookSelectorProps {
notebookIds: number[];
onSelectionChange: (selectedIds: number[]) => void;
selectedNotebooks: number[];
}

const NotebookSelector: React.FC<NotebookSelectorProps> = ({ notebookIds, onSelectionChange }) => {
const [shownNotebooks, setShownNotebooks] = useState<Set<number>>(new Set([-2])); // Initialize with "ALL"
const NotebookSelector: React.FC<NotebookSelectorProps> = ({ notebookIds, onSelectionChange, selectedNotebooks }) => {
const [selectedValue, setSelectedValue] = useState<string>('');

useEffect(() => {
// Trigger the callback when shownNotebooks changes
onSelectionChange(Array.from(shownNotebooks));
}, [shownNotebooks, onSelectionChange]);



const handleRemoveNotebook = (notebookId: number) => {
const newShownNotebooks = new Set(shownNotebooks);
if (newShownNotebooks.has(notebookId)) {
newShownNotebooks.delete(notebookId);
// If the last notebook is removed, add "ALL" again
if (newShownNotebooks.size === 0) {
newShownNotebooks.add(-2);
}
setShownNotebooks(newShownNotebooks);
const newSelectedNotebooks = selectedNotebooks.filter(id => id !== notebookId);
if (newSelectedNotebooks.length === 0) {
onSelectionChange([-2]); // Add "ALL" if no notebooks are selected
} else {
onSelectionChange(newSelectedNotebooks);
}
};

const handleAddNotebook = () => {
const notebookId = selectedValue === "ALL" ? -2 : Number(selectedValue);

console.log('Current notebook IDs:', selectedNotebooks);
if (notebookId === -2) {
// If "ALL" is selected, clear all other selections and set "ALL"
const newShownNotebooks = new Set<number>();
newShownNotebooks.add(-2);
setShownNotebooks(newShownNotebooks);
} else if (!shownNotebooks.has(notebookId) && notebookIds.includes(notebookId)) {

console.log(notebookId);
const newShownNotebooks = new Set(shownNotebooks);
newShownNotebooks.add(notebookId);
if (newShownNotebooks.has(-2)) {
newShownNotebooks.delete(-2); // Remove "ALL" (-2) before adding a specific notebook
}
console.log(newShownNotebooks);
setShownNotebooks(newShownNotebooks);
console.log(newShownNotebooks);

onSelectionChange([-2]); // If "ALL" is selected, clear other selections and set "ALL"
} else if (!selectedNotebooks.includes(notebookId) && notebookIds.includes(notebookId)) {
const newSelectedNotebooks = [...selectedNotebooks, notebookId].filter(id => id !== -2); // Remove "ALL" (-2) before adding a specific notebook
onSelectionChange(newSelectedNotebooks);
}
setSelectedValue(''); // Clear the input after adding
};
Expand All @@ -57,7 +36,7 @@ const NotebookSelector: React.FC<NotebookSelectorProps> = ({ notebookIds, onSele
<div className="selector-container">
<div className="current-selection-text">Current selection:</div>
<div className="selected-elements" id="selected-elements">
{Array.from(shownNotebooks).map(notebookId => (
{selectedNotebooks.map(notebookId => (
<div key={notebookId} className="element">
{notebookId === -2 ? "ALL" : notebookId}
<button className="remove-button" onClick={() => handleRemoveNotebook(notebookId)}>Remove</button>
Expand Down
274 changes: 136 additions & 138 deletions src/VizContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,164 +10,162 @@ import * as React from 'react';
import VizComponent, { LoadingComponent, DataNotFoundComponent, VizData, NotebookCellWithID, NotebookWithCellId } from './VizComponent';
import NotebookSelector from './NotebookSelector';
import { FlowchartWidget } from './Flowchart';
import { useCallback, useEffect, useState } from 'react';

class VizContent extends ReactWidget {
private context: DocumentRegistry.Context;
private selectedNotebookIds: number[] = [];
private flowchartWidget: FlowchartWidget;

constructor(context: DocumentRegistry.Context, flowchartWidget: FlowchartWidget) {
super();
this.context = context;
this.flowchartWidget = flowchartWidget;
this.addClass('jp-vizContent');

// Listen for changes in the document and re-render the content
context.ready.then(() => {
this.context.model.contentChanged.connect(this.update, this);
this.update();
});
}


handleNotebookSelection = (selectedIds: number[]) => {
// Remove every element from selectedNotebookIds directly in the
while(this.selectedNotebookIds.length > 0){
this.selectedNotebookIds.pop();
}

// Add every element from selectedIds that is not in selectedNotebookIds
selectedIds.forEach(selectedId => {
if (!this.selectedNotebookIds.includes(selectedId)) {
this.selectedNotebookIds.push(selectedId);
}
});

this.update(); // Re-render the widget when the selection changes
interface VizContentProps {
context: DocumentRegistry.Context;
flowchartWidget: FlowchartWidget;
}

const content = this.context.model.toString();
const VizContent: React.FC<VizContentProps> = ({ context, flowchartWidget }) => {
const [selectedNotebookIds, setSelectedNotebookIds] = useState<number[]>([-2]);
const [isReady, setIsReady] = useState<boolean>(context.isReady);

//console.log(content)
let jsonData: VizData = { notebooks: [] };
let data: any = {};
if (content.trim() !== "") {
try {
jsonData = JSON.parse(content);
data = JSON.parse(content);
} catch (error) {
console.error("Error parsing JSON", error);
return;
}


let newNotebook: NotebookWithCellId = { notebook_id: -2, cells: [] };

jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];

if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title

}
const cellWithNotebookId = {
...cell,
originalNotebookId: notebook.notebook_id // Add a new property to store the original notebook ID
};

newNotebook.cells.push(cellWithNotebookId); }
)
useEffect(() => {
if (!context.isReady) {
context.ready.then(() => {
setIsReady(true);
});
jsonData.notebooks.push(newNotebook);
this.update(); // Re-render the widget when the selection changes

// Filter cells from selected notebooks only
const selectedCells: NotebookCellWithID[] = jsonData.notebooks
.filter(notebook => selectedIds.includes(notebook.notebook_id))
.flatMap(notebook =>
notebook.cells.map(cell => ({
...cell,
notebook_id: notebook.notebook_id, // Add notebook_id to each cell
}))
);

this.flowchartWidget.updateGraph(selectedCells);
} else {
setIsReady(true);
}
};
}, [context]);

// Function to handle notebook selection
const handleNotebookSelection = useCallback((selectedIds: number[]) => {
setSelectedNotebookIds([...selectedIds]);
console.log("Selected notebooks", selectedIds);
}, []);

// Function to update the flowchart widget when notebooks are selected
useEffect(() => {
if (isReady) {
const content = context.model.toString();

let jsonData: VizData = { notebooks: [] };
let data: any = {};

if (content.trim() !== "") {
try {
jsonData = JSON.parse(content);
data = JSON.parse(content);
} catch (error) {
console.error("Error parsing JSON", error);
return;
}

protected render(): React.ReactElement<any> {
if (!this.context.isReady) {
return <LoadingComponent />;
let newNotebook: NotebookWithCellId = { notebook_id: -2, cells: [] };

jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];

if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title
}
const cellWithNotebookId = {
...cell,
originalNotebookId: notebook.notebook_id // Add a new property to store the original notebook ID
};
newNotebook.cells.push(cellWithNotebookId);
});
});
jsonData.notebooks.push(newNotebook);

const selectedCells: NotebookCellWithID[] = jsonData.notebooks
.filter(notebook => selectedNotebookIds.includes(notebook.notebook_id))
.flatMap(notebook =>
notebook.cells.map(cell => ({
...cell,
notebook_id: notebook.notebook_id, // Add notebook_id to each cell
}))
);

flowchartWidget.updateGraph(selectedCells);
}
}
}, [isReady, selectedNotebookIds, context, flowchartWidget]);

const content = this.context.model.toString();
let jsonData: VizData = { notebooks: [] };
let data: any = {};
if (!isReady) {
return <LoadingComponent />;
}

if (content.trim() === "") {
return <DataNotFoundComponent />;
}
const content = context.model.toString();
let jsonData: VizData = { notebooks: [] };
let data: any = {};

try {
jsonData = JSON.parse(content);
data = JSON.parse(content);
if (content.trim() === "") {
return <DataNotFoundComponent />;
}

} catch (error) {
console.error("Error parsing JSON", error);
}
try {
jsonData = JSON.parse(content);
data = JSON.parse(content);
} catch (error) {
console.error("Error parsing JSON", error);
}

jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];
jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];

if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title

}
if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title
}
)
});
});

let newNotebook: NotebookWithCellId = { notebook_id: -2, cells: [] };

let newNotebook: NotebookWithCellId = { notebook_id: -2, cells: [] };

jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];
jsonData.notebooks.forEach(notebook => {
notebook.cells.forEach(cell => {
const classMetadata = data["metadata"]["clusters"][cell.class]["titles"];

if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title


}
const cellWithNotebookId = {
...cell,
originalNotebookId: notebook.notebook_id // Add a new property to store the original notebook ID
};

newNotebook.cells.push(cellWithNotebookId);
if (classMetadata && classMetadata[cell.cluster]) {
cell.cluster = classMetadata[cell.cluster]; // Replace cluster ID with the title
}
)
const cellWithNotebookId = {
...cell,
originalNotebookId: notebook.notebook_id // Add a new property to store the original notebook ID
};
newNotebook.cells.push(cellWithNotebookId);
});
jsonData.notebooks.push(newNotebook);
// Ensure only selected notebooks are displayed
const selectedNotebooks = jsonData.notebooks.filter(notebook =>
this.selectedNotebookIds.includes(notebook.notebook_id)
);

return (
<div style={{ height: '100%', overflowY: 'auto' }}> {/* Scrollable container */}
<NotebookSelector
notebookIds={jsonData.notebooks.map(notebook => notebook.notebook_id)}
onSelectionChange={this.handleNotebookSelection}
/>
<VizComponent
data={{ notebooks: selectedNotebooks }}
onSelectNotebook={this.handleNotebookSelection}
/>
</div>
);
});
jsonData.notebooks.push(newNotebook);

const selectedNotebooks = jsonData.notebooks.filter(notebook =>
selectedNotebookIds.includes(notebook.notebook_id)
);

return (
<div style={{ height: '100%', overflowY: 'auto' }}>
<NotebookSelector
notebookIds={jsonData.notebooks.map(notebook => notebook.notebook_id)}
selectedNotebooks={selectedNotebookIds}
onSelectionChange={handleNotebookSelection}
/>
<VizComponent
data={{ notebooks: selectedNotebooks }}
onSelectNotebook={handleNotebookSelection}
/>
</div>
);
};

class VizContentWidget extends ReactWidget {
private context: DocumentRegistry.Context;
private flowchartWidget: FlowchartWidget;

constructor(context: DocumentRegistry.Context, flowchartWidget: FlowchartWidget) {
super();
this.context = context;
this.flowchartWidget = flowchartWidget;
this.addClass('jp-vizContent');
}

protected render(): React.ReactElement<any> {
return <VizContent context={this.context} flowchartWidget={this.flowchartWidget} />;
}
}

export default VizContent;
export default VizContentWidget;
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { FlowchartWidget } from './Flowchart';
import { WidgetTracker } from '@jupyterlab/apputils';

const extension: JupyterFrontEndPlugin<void> = {
id: 'viz-file-handler',
id: 'viz-file-ext',
autoStart: true,
activate: (app: JupyterFrontEnd) => {
console.log('JupyterLab extension viz-file-handler is activated!');
Expand Down

0 comments on commit df1fc69

Please sign in to comment.