diff --git a/package.json b/package.json index 709cf170c..5e3b41dd4 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@nestjs/axios": "^3.0.2", "@nestjs/terminus": "^10.2.2", "@nestjs/throttler": "^5.0.1", + "chakra-ui-ionicons": "^0.3.3", "cross-env": "^7.0.3", "fuse.js": "^7.0.0", "nodemailer": "^6.9.1" diff --git a/packages/common/src/major2-validation.ts b/packages/common/src/major2-validation.ts index f632d9db9..ec79abb82 100644 --- a/packages/common/src/major2-validation.ts +++ b/packages/common/src/major2-validation.ts @@ -66,6 +66,7 @@ type CourseError = { type: typeof MajorValidationErrorType.Course; requiredCourse: string; }; + export const CourseError = (c: IRequiredCourse): CourseError => ({ type: MajorValidationErrorType.Course, requiredCourse: courseToString(c), diff --git a/packages/common/src/test.js b/packages/common/src/test.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 4cbee12fa..79d200119 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -181,7 +181,6 @@ export type Requirement2 = | ICourseRange2 | IRequiredCourse | Section; - /** * Represents a requirement where X number of credits need to be completed from * a list of courses. diff --git a/packages/frontend/components/Sidebar/NUPathSection.tsx b/packages/frontend/components/Sidebar/NUPathSection.tsx index 019015369..1d1e05c76 100644 --- a/packages/frontend/components/Sidebar/NUPathSection.tsx +++ b/packages/frontend/components/Sidebar/NUPathSection.tsx @@ -62,6 +62,11 @@ const NUPathSection: React.FC = ({ if (loading) { validationStatus = SidebarValidationStatus.Loading; + } else if ( + Object.keys(nupathMap).length > 0 && + Object.keys(nupathMap).length < 13 + ) { + validationStatus = SidebarValidationStatus.InProgress; } else if (Object.keys(nupathMap).length === 13 && wiCount >= 2) { // Sidebar is complete if all 13 nupaths have been fulfilled (including 2 writing intensives) validationStatus = SidebarValidationStatus.Complete; @@ -105,11 +110,15 @@ const NUPathSection: React.FC = ({ ? green : validationStatus === SidebarValidationStatus.Error ? grey + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : "transparent" } borderColor={ validationStatus === SidebarValidationStatus.Complete ? green + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : grey } color={ @@ -130,7 +139,7 @@ const NUPathSection: React.FC = ({ p="xs" > {/* - The following three icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). + The following four icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). */} = ({ transition="opacity 0.25s ease" transitionDelay="0.1s" /> + + ... + NUpath Requirements diff --git a/packages/frontend/components/Sidebar/Sidebar.tsx b/packages/frontend/components/Sidebar/Sidebar.tsx index 0ed90ce3e..9917ccbad 100644 --- a/packages/frontend/components/Sidebar/Sidebar.tsx +++ b/packages/frontend/components/Sidebar/Sidebar.tsx @@ -36,6 +36,7 @@ export enum SidebarValidationStatus { Loading = "Loading", Error = "Error", Complete = "Complete", + InProgress = "InProgress", } export const COOP_BLOCK: ScheduleCourse2 = { @@ -106,6 +107,7 @@ const Sidebar: React.FC = memo( concentration: selectedPlan.concentration, requestNumber: currentRequestNum, }; + workerRef.current?.postMessage(validationInfo); }; @@ -188,8 +190,17 @@ const Sidebar: React.FC = memo( let concentrationValidationStatus = SidebarValidationStatus.Complete; if (validationStatus === undefined) { concentrationValidationStatus = SidebarValidationStatus.Loading; - } else if (concentrationValidationError) { + } else if ( + concentrationValidationError && + concentrationValidationError.type === "AND" && + concentrationValidationError.error.type === "AND_UNSAT_CHILD" && + concentrationValidationError.error.childErrors[0].type === "SECTION" && + concentrationValidationError.error.childErrors[0] + .maxPossibleChildCount === 0 + ) { concentrationValidationStatus = SidebarValidationStatus.Error; + } else { + concentrationValidationStatus = SidebarValidationStatus.InProgress; } const creditsTaken = totalCreditsInSchedule(selectedPlan.schedule); @@ -215,10 +226,21 @@ const Sidebar: React.FC = memo( getSectionError(index, validationStatus); let sectionValidationStatus = SidebarValidationStatus.Complete; + if (validationStatus === undefined) { sectionValidationStatus = SidebarValidationStatus.Loading; - } else if (sectionValidationError) { + } else if ( + sectionValidationError && + sectionValidationError.type === "SECTION" && + sectionValidationError.maxPossibleChildCount === 0 + ) { sectionValidationStatus = SidebarValidationStatus.Error; + } else if ( + sectionValidationError && + sectionValidationError.type === "SECTION" && + sectionValidationError.maxPossibleChildCount > 0 + ) { + sectionValidationStatus = SidebarValidationStatus.InProgress; } return ( diff --git a/packages/frontend/components/Sidebar/SidebarSection.tsx b/packages/frontend/components/Sidebar/SidebarSection.tsx index ee9ebddcc..9ad5442f9 100644 --- a/packages/frontend/components/Sidebar/SidebarSection.tsx +++ b/packages/frontend/components/Sidebar/SidebarSection.tsx @@ -5,6 +5,7 @@ import { SmallCloseIcon, WarningTwoIcon, } from "@chakra-ui/icons"; + import { Box, Flex, Spinner, Stack, Text } from "@chakra-ui/react"; import { ScheduleCourse2, Section } from "@graduate/common"; import { useState } from "react"; @@ -85,11 +86,15 @@ const SidebarSection: React.FC = ({ ? green : validationStatus === SidebarValidationStatus.Error ? grey + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : "transparent" } borderColor={ validationStatus === SidebarValidationStatus.Complete ? green + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : grey } color={ @@ -101,16 +106,17 @@ const SidebarSection: React.FC = ({ width="18px" height="18px" display="flex" - transition="background 0.25s ease, color 0.25s ease, border 0.25s ease" - transitionDelay="0.1s" alignItems="center" justifyContent="center" + transition="background 0.25s ease, color 0.25s ease, border 0.25s ease" + transitionDelay="0.1s" borderRadius="2xl" mt="4xs" p="xs" + position="relative" > {/* - The following three icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). + The following four icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). */} = ({ transition="opacity 0.25s ease" transitionDelay="0.1s" /> + + ... + {section.title} diff --git a/yarn.lock b/yarn.lock index 99d7e6a41..7abf37ebb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5903,6 +5903,16 @@ __metadata: languageName: node linkType: hard +"chakra-ui-ionicons@npm:^0.3.3": + version: 0.3.3 + resolution: "chakra-ui-ionicons@npm:0.3.3" + peerDependencies: + "@chakra-ui/react": ^1.0.0 + react: ">=16" + checksum: 23c06650c2f9ffb8283ef1b51dd52e1ed249dd90ac14bbc6ecadae4ee77bd489976d403912f99e39f24d6bc7b76ba831b1c01cb6176eeae760a7d6a818ea3618 + languageName: node + linkType: hard + "chalk@npm:3.0.0, chalk@npm:^3.0.0": version: 3.0.0 resolution: "chalk@npm:3.0.0" @@ -8169,6 +8179,7 @@ __metadata: "@types/nodemailer": ^6.4.7 "@typescript-eslint/eslint-plugin": ^5.15.0 "@typescript-eslint/parser": ^5.15.0 + chakra-ui-ionicons: ^0.3.3 concurrently: ^7.0.0 cross-env: ^7.0.3 eslint: ^8.11.0