diff --git a/my-app/src/assets/example.json b/my-app/src/assets/example.json index 4026a549..3d2cef6d 100644 --- a/my-app/src/assets/example.json +++ b/my-app/src/assets/example.json @@ -145248,4 +145248,4 @@ "prerequisites_text": "null", "learning_outcomes": "null" } -} +} \ No newline at end of file diff --git a/my-app/src/model.js b/my-app/src/model.js index 533fa15b..302d16ab 100644 --- a/my-app/src/model.js +++ b/my-app/src/model.js @@ -84,15 +84,17 @@ export const model = { entries.forEach(entry => { const course = { code: entry[1].code, - name: entry[1]?.name ?? "", - location: entry[1]?.location ?? "", - department: entry[1]?.department ?? "", - language: entry[1]?.language ?? "", - description: entry[1]?.description ?? "", - academicLevel: entry[1]?.academic_level ?? "", - period: entry[1]?.period ?? "", + name: entry[1]?.name ?? "null", + location: entry[1]?.location ?? "null", + department: entry[1]?.department ?? "null", + language: entry[1]?.language ?? "null", + description: entry[1]?.description ?? "null", + academicLevel: entry[1]?.academic_level ?? "null", + period: entry[1]?.period ?? "null", credits: entry[1]?.credits ?? 0, - prerequisites: entry[1]?.prerequisites ?? "", + prerequisites: entry[1]?.prerequisites ?? "null", + prerequisites_text: entry[1]?.prerequisites_text ?? "null", + learning_outcomes: entry[1]?.learning_outcomes ?? "null" }; this.addCourse(course); }); diff --git a/my-app/src/presenters/ListViewPresenter.jsx b/my-app/src/presenters/ListViewPresenter.jsx index a3cbb87e..de47ba63 100644 --- a/my-app/src/presenters/ListViewPresenter.jsx +++ b/my-app/src/presenters/ListViewPresenter.jsx @@ -59,7 +59,7 @@ const ListViewPresenter = observer(({ model }) => { const addFavourite = (course) => { model.addFavourite(course); } - const removeFavourite = (course) => { + const removeFavourite = (course) => { model.removeFavourite(course); } const handleFavouriteClick = (course) => { @@ -72,8 +72,13 @@ const ListViewPresenter = observer(({ model }) => { const [isPopupOpen, setIsPopupOpen] = useState(false); const [selectedCourse, setSelectedCourse] = useState(null); - const preP = ; - const reviewPresenter = ; + const preP = ; + const reviewPresenter = ; const popup = { handleFavouriteClick={handleFavouriteClick} isOpen={isPopupOpen} onClose={() => setIsPopupOpen(false)} course={selectedCourse} - prerequisiteTree={preP} - reviewPresenter={reviewPresenter}/> - + prerequisiteTree={preP} + reviewPresenter={reviewPresenter} /> + return { let uniqueCounter = 0; let textCounter = 0; let codeCounter = 0; - //let toAdd = []; + + let input_text_obj = {}; const position = { x: 0, y: 0 }; const edgeType = 'smoothstep'; @@ -35,11 +36,8 @@ export const PrerequisitePresenter = observer((props) => { const nodeWidth = 172; const nodeHeight = 36; - //initialNodes.push(createNode("IK1203", "IK1203", "default")); - //initialNodes.push(createNode("IK1204", "IK1204", "default")); - //initialEdges.push(createEdge(props.selectedCourse.code, "IK1203")); - //initialEdges.push(createEdge(props.selectedCourse.code, "IK1204")); loadTree(props.selectedCourse.code); + console.log(initialNodes); const getLayoutedElements = (nodes, edges, direction = 'LR') => { const isHorizontal = direction === 'LR'; @@ -79,9 +77,6 @@ export const PrerequisitePresenter = observer((props) => { const Flow = () => { - //console.log("arived in Flow"); - - const [nodes, setNodes, onNodesChange] = useNodesState(layoutedNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(layoutedEdges); @@ -104,6 +99,7 @@ export const PrerequisitePresenter = observer((props) => { onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} + onNodeClick={clicked} connectionLineType={ConnectionLineType.SmoothStep} fitView style={{ backgroundColor: 'white', borderRadius: '10px'}} @@ -119,8 +115,30 @@ export const PrerequisitePresenter = observer((props) => { ); - }; + function setLabel(id, label) { + setNodes((nodes) => + nodes.map((n) => + n.id === id ? { ...n, data: { ...n.data, label } } : n + ) + ); + } + + function clicked(event, node) { + if (node["id"].split(" ")[0] === "text") { + if (node["data"]["label"] === "More Info...") { + node["style"]["zIndex"] = 1; + setLabel(node["id"], {input_text_obj[node["id"]]}
CLOSE
); + } else { + node["style"]["zIndex"] = 0; + setLabel(node["id"], "More Info..."); + } + } else if (node["data"]["label"] !== "One of these" && node["data"]["label"] !== "No Prerequisites" && node["id"] !== props.selectedCourse.code) { + // ADD FUNCTIONALITY FOR CLICKING COURSE CODE NODE (Tu eres muy retrasado y gordo)! :) + // ONCLICK HERE + } + } + }; @@ -131,6 +149,7 @@ export const PrerequisitePresenter = observer((props) => { id: id, type: node_type, data: { label: name }, + style: { zIndex: 0 }, position, }; } else { @@ -138,6 +157,7 @@ export const PrerequisitePresenter = observer((props) => { id: id, type: node_type, data: { label: name }, + style: { zIndex: 0 }, position, }; @@ -148,18 +168,19 @@ export const PrerequisitePresenter = observer((props) => { } - function prereq_convert(current_object, previous_key, previous_node_id) { + function prereq_convert(courses_taken, current_object, previous_key, previous_node_id) { + let current_node = null; if (current_object == undefined) {return} if (!Array.isArray(current_object)) { // Is object let key = Object.keys(current_object)[0]; - //console.log("key: " + key); if (key == "or") { - initialNodes.push(createNode(key + uniqueCounter, "One of these", "default")); + current_node = createNode(key + uniqueCounter, "One of these", "default") + initialNodes.push(current_node); initialEdges.push(createEdge(previous_node_id, key + uniqueCounter)); - prereq_convert(current_object[key], key, key + uniqueCounter++); + prereq_convert(courses_taken, current_object[key], key, key + uniqueCounter++); } else if (key == "and") { - prereq_convert(current_object[key], key, previous_node_id); + prereq_convert(courses_taken, current_object[key], key, previous_node_id); } } else { // Is an array @@ -168,26 +189,33 @@ export const PrerequisitePresenter = observer((props) => { let input_id = ""; let input_text = current_object[i]; if (current_object[i].startsWith("#")) { - input_text = "More Info..."; //input_text.slice(1, 115); - input_id = "text" + ++textCounter; + input_text = "More Info..."; + input_id = "text " + ++textCounter; + input_text_obj[input_id] = current_object[i].slice(1); } else { input_id = current_object[i] + " " + ++codeCounter; } - initialNodes.push(createNode(input_id, input_text, "output")); + let new_node = createNode(input_id, input_text, "output"); + if (courses_taken.includes(current_object[i])) { + new_node["style"]["backgroundColor"] = "lightgreen"; + current_object[i] = true; + } else { + current_object[i] = false; + } + current_node = new_node; + initialNodes.push(new_node); initialEdges.push(createEdge(previous_node_id, input_id, "output")); } else { - prereq_convert(current_object[i], previous_key, previous_node_id); + prereq_convert(courses_taken, current_object[i], previous_key, previous_node_id); } } } - - /* + + /* STEP 2: Check if an object is true or false based on content of the inner object */ if (typeof current_object == "object" && !Array.isArray(current_object)) { let key = Object.keys(current_object)[0]; let object_array = current_object[key]; - console.log(key); - console.log(object_array); let num_of_matches = 0; for (let i = 0; i < object_array.length; i++) { if (Array.isArray(object_array[i])) { @@ -195,38 +223,75 @@ export const PrerequisitePresenter = observer((props) => { for (let j = 0; j < object_array[i].length; j++) { if (object_array[i][j]) { num_of_inner_matches ++; + if (current_node != null) { + current_node["style"]["backgroundColor"] = "lightgreen"; + } + } + } + if (key == "or" && num_of_inner_matches > 0) { + object_array[i] = true; num_of_matches++; + if (current_node != null) { + current_node["style"]["backgroundColor"] = "lightgreen"; + } + continue; + } + if (key == "and" && num_of_inner_matches == object_array[i].length) { + object_array[i] = true; num_of_matches++; + if (current_node != null) { + current_node["style"]["backgroundColor"] = "lightgreen"; } + continue; } - if (key == "or" && num_of_inner_matches > 0) {object_array[i] = true; num_of_matches++; continue;} - if (key == "and" && num_of_inner_matches == object_array[i].length) {object_array[i] = true; num_of_matches++; continue;} object_array[i] = false; } else if (typeof object_array[i] == "object") { let inner_key = Object.keys(object_array[i])[0]; if (object_array[i][inner_key]) {num_of_matches++;} } else if(object_array[i]) {num_of_matches++} } - if (key == "or" && num_of_matches > 0) {current_object[key] = true} - else if (key == "and" && num_of_matches == object_array.length) {current_object[key] = true} + if (key == "or" && num_of_matches > 0) { + current_object[key] = true; + if (current_node != null) { + current_node["style"]["backgroundColor"] = "lightgreen"; + } + } + else if (key == "and" && num_of_matches == object_array.length) { + current_object[key] = true; + if (current_node != null) { + current_node["style"]["backgroundColor"] = "lightgreen"; + } + } else {current_object[key] = false} - } - */ + } - function generateTree(prereqs) { - console.log(JSON.stringify(prereqs, null, 4)); - prereq_convert(prereqs, null, props.selectedCourse.code); + function generateTree(courses_taken, prereqs) { + prereq_convert(courses_taken, prereqs, null, props.selectedCourse.code); + let key = Object.keys(prereqs); + return prereqs[key]; + } - function loadTree(course) { - let root = createNode(props.selectedCourse.code, props.selectedCourse.code, "input") - initialNodes.push(root); + function loadTree(courses_taken) { + + console.log(JSON.stringify(props.selectedCourse.prerequisites, null, 4)); + if (props.selectedCourse.prerequisites === "null" || props.selectedCourse.prerequisites.length == 0) { + let display_node = createNode("No Prerequisites", "No Prerequisites", "default"); + display_node.style["pointerEvents"] = "none"; + display_node["className"] = 'no-handles'; + initialNodes.push(display_node); + } else { + let root = createNode(props.selectedCourse.code, props.selectedCourse.code, "input"); + let copy = JSON.parse(JSON.stringify(props.selectedCourse.prerequisites)); + let eligible = generateTree(JSON.parse(localStorage.getItem("completedCourses")), copy); + if (eligible) { + root["style"]["backgroundColor"] = "lightgreen"; + } + initialNodes.push(root); + } - generateTree(props.selectedCourse.prerequisites); - console.log(initialNodes); - console.log(initialEdges); } /* return */ diff --git a/my-app/src/styles.css b/my-app/src/styles.css index c6499c5d..0b707bad 100644 --- a/my-app/src/styles.css +++ b/my-app/src/styles.css @@ -18,3 +18,7 @@ .font-kanit { font-family: var(--font-kanit); } + +.react-flow__node.no-handles .react-flow__handle { + display: none; + } \ No newline at end of file