Skip to content

Commit

Permalink
fix: CF-425: cleaning graph loading screen (#1039)
Browse files Browse the repository at this point in the history
* feat: dark mode functionality added for editMarkModal's input and button elements

* feat: dark mode improvement for editMarkModal's cancel button

* feat: dark mode improvements for OptionHeader icons underneath the 'Term Planner' tab

* feat: dark mode added for the select menu in the settingsMenu tooltip under the TermPlanner tab

* feat: dark mode added to SettingMenu's DatePicker element

* feat: dark mode for export button done + editModalMark bug fixed

* fix: making sure the css for the select element in settingsMenu does not affect other select elements

* feat: dark mode improvement for popconfirm for unplan wanring, import tooltip, also moved the button for import and export tooltip to common styles

* feat: dark mode scrollbar added

* feat: dark mode scrollbar on courseSelector menu had ugly white padding, fixed it to be #333 color instead

* fix: href in courseSelector not very readable in dark mode, made the text a bit brighter and made a styled component for it

* feat: dark mode added for search bar

* feat: dark mode added for remove planner button

* fix: forgot to add the new styles.ts file

* feat: progressBar's text color and trailing color fixed

* feat: dividing line in courseDescription changed from white to a dark grey

* feat: bug icon turned into dark mode

* feat: dark mode added for quick add and remove buttons in course menu

* feat: courseProgression progress bar trailing color changed to dark grey

* feat: progress on dark mode for graph, need to save this commit before I merge in the latest changes since the graph was changed

* feat: dark mode for graph complete (nodes, arrows, hover states) + label now changes on hover (non-dark mode feature)

* feat: buttons on graphical selector are dark mode

* feat: saving progress on converting courseDescription panel to dark mode

* feat: dark mode added to the sidebar

* feat: sidebardrawer color changed, box shadow added to tabs so it looks more visible in dark mode

* feat: new images added in help menu in course selector, dark mode versions added too

* feat: TermPlanner's help menu tooltips now have dark mode pics and gifs

* feat: highlight adjacent nodes and edges on hover

* feat: highlight adjacent nodes opacity updated

* refactor: graph.ts, changing function names and object names to be more readable:

* feat: implemented a function that checks if a course is a prereq based on GraphData without calling the backend

* fix: two graphs get rendered if you switch tabs fast enough

* feat: created a function to store a hashmap of prereqs for later use for node styling

* fix: updated the function that checks for coursePrerequisite

Other options are:
1. Rely on GraphData, however it gets laggy when you hover over too many nodes
2. API call - would get slow with multiple requests
3. CourseEdge info gets stored into a hashmap at initialisation, so checking for prereqs is fast afterwards

* refactor: graph.ts function and object names made more readable

* refactor: rewriting the returns and using spread operator to reduce repetition in graph.ts

* feat: highlight prerequisite nodes on hover

* refactor: splitting functions up as they were getting too long

* fix: if the dark mode button is toggled on and off, it repaints the canvas more than one time

* feat: highlighted incoming edge if it's a prerequisite as well

* feat: forgot to add pics into the HelpMenu for the new graphical selector hover node feature

* feat: unlocked course nodes are now distinct from planned and locked courses

feat: HelpMenu pictures were also updated

* fix: adding and removing courses in graphical selector, updates the node in the graph without re-render

refactor: graph.ts duplicate function removed

* fix: endArrow opacity of graph was not changing on hover

* fix: instead of using courseSlicer, used axios request to update unlocked nodes after adding to planner

* fix: searchbar hidden while graph loads

fix: random course node that pops up is hidden now

feat: show all courses toggle has a loading screen now too

* docs: forgot to update comment which I copy pasted in

* fix: no-non-null-assertion warning fixed in graph.ts

---------

Co-authored-by: Daysure <[email protected]>
  • Loading branch information
Dasyure and Dasyure authored Jul 29, 2023
1 parent df01a76 commit a11ae10
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 15 deletions.
4 changes: 2 additions & 2 deletions frontend/src/components/Spinner/Spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ type Props = {
};

const Spinner = ({ text }: Props) => (
<S.Wrapper>
<S.Wrapper className="loading-spinner">
<Spin indicator={<LoadingOutlined style={{ fontSize: '2.5rem' }} spin />} />
<div>{text}</div>
<p>{text}</p>
</S.Wrapper>
);

Expand Down
21 changes: 19 additions & 2 deletions frontend/src/config/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ export const GlobalStyles = createGlobalStyle`
box-shadow: ${({ theme }) => theme.graph?.tabBoxShadow} !important;
}
// .spinner-wrapper .anticon anticon-loading anticon-spin ant-spin-dot {
.spinner-wrapper .ant-spin-dot {
color: ${({ theme }) => theme.graph.loadingIcon};
}
.loading-spinner p {
color: ${({ theme }) => theme.text};
text-shadow:
0.07em 0 ${({ theme }) => theme.graph.loadingText},
0 0.07em ${({ theme }) => theme.graph.loadingText},
-0.07em 0 ${({ theme }) => theme.graph.loadingText},
0 -0.07em ${({ theme }) => theme.graph.loadingText};
}
// Scrollbar settings
/* width */
::-webkit-scrollbar {
Expand Down Expand Up @@ -339,7 +353,8 @@ export const lightTheme: DefaultTheme = {
borderColor: '#c2c2c2',
tabColor: '#666',
tabBottomBorderColor: '#f0f0f0',
tabTextColor: '#000'
tabTextColor: '#000',
loadingText: '#fff'
},
sidebarDrawer: {
backgroundColor: '#fff',
Expand Down Expand Up @@ -484,7 +499,9 @@ export const darkTheme: DefaultTheme = {
tabColor: '#fff',
tabBottomBorderColor: '#5d5d5d',
tabTextColor: '#f1f1f1',
tabBoxShadow: 'inset 16px 0 8px -8px rgba(255, 255, 255, 0.08)'
tabBoxShadow: 'inset 16px 0 8px -8px rgba(255, 255, 255, 0.08)',
loadingIcon: '#d7b7fd',
loadingText: '#000'
},
sidebarDrawer: {
backgroundColor: '#343239',
Expand Down
36 changes: 28 additions & 8 deletions frontend/src/pages/GraphicalSelector/CourseGraph/CourseGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type Props = {
fullscreen: boolean;
focused?: string;
hasPlannerUpdated: React.MutableRefObject<boolean>;
loading: boolean;
setLoading: React.Dispatch<React.SetStateAction<boolean>>;
};

interface CoursePrerequisite {
Expand All @@ -50,7 +52,9 @@ const CourseGraph = ({
handleToggleFullscreen,
fullscreen,
focused,
hasPlannerUpdated
hasPlannerUpdated,
loading,
setLoading
}: Props) => {
const { theme } = useSelector((state: RootState) => state.settings);
const previousTheme = useRef<typeof theme>(theme);
Expand All @@ -61,8 +65,8 @@ const CourseGraph = ({
const windowSize = useAppWindowSize();

const graphRef = useRef<Graph | null>(null);
const initialising = useRef(false); // prevents multiple graphs being loaded
const [loading, setLoading] = useState(true);
const initialisingStart = useRef(false); // prevents multiple graphs being loaded
const initialisingEnd = useRef(false); // unhide graph after loading complete
const [unlockedCourses, setUnlockedCourses] = useState(false);
const [prerequisites, setPrerequisites] = useState<CoursePrerequisite>({});

Expand Down Expand Up @@ -185,6 +189,7 @@ const CourseGraph = ({
nodeStrength: 2500,
preventOverlap: true,
onLayoutEnd: () => {
initialisingEnd.current = true;
setLoading(false);
}
},
Expand All @@ -205,8 +210,11 @@ const CourseGraph = ({
edges: courseEdges
};

// Hide graph until it's finished loaded, due to incomplete initial graph generation
graphRef.current.data(data);
graphRef.current.render();
graphRef.current.getNodes().forEach((n) => n.hide());
graphRef.current.getEdges().forEach((e) => e.hide());

graphRef.current.on('node:click', async (ev) => {
// Clicking a node loads up course description for the course and set active
Expand Down Expand Up @@ -279,7 +287,7 @@ const CourseGraph = ({

const setupGraph = async () => {
try {
initialising.current = true;
initialisingStart.current = true;
const res = await Promise.allSettled([
axios.get<GraphPayload>(`/programs/graph/${programCode}/${specs.join('+')}`),
axios.post<CoursesAllUnlocked>(
Expand All @@ -300,7 +308,7 @@ const CourseGraph = ({
}
};

if (!initialising.current) setupGraph();
if (!initialisingStart.current) setupGraph();
if (hasPlannerUpdated.current) {
hasPlannerUpdated.current = false;
getUnlocked();
Expand All @@ -319,9 +327,19 @@ const CourseGraph = ({
prerequisites,
degree,
planner,
hasPlannerUpdated
hasPlannerUpdated,
setLoading
]);

// Show all nodes and edges once graph is initially loaded
useEffect(() => {
if (initialisingEnd.current) {
graphRef.current?.getNodes().forEach((n) => n.show());
graphRef.current?.getEdges().forEach((e) => e.show());
initialisingEnd.current = false;
}
}, [loading]);

const showAllCourses = () => {
if (!graphRef.current) return;
graphRef.current.getNodes().forEach((n) => n.show());
Expand All @@ -331,6 +349,7 @@ const CourseGraph = ({
const showUnlockedCourses = useCallback(async () => {
if (!graphRef.current) return;
try {
setLoading(true);
const {
data: { courses_state: coursesStates }
} = await axios.post<CoursesAllUnlocked>(
Expand All @@ -349,11 +368,12 @@ const CourseGraph = ({
n.getEdges().forEach((e) => e.hide());
}
});
setLoading(false);
} catch (e) {
// eslint-disable-next-line no-console
console.error('Error at showUnlockedCourses', e);
}
}, [degree, planner]);
}, [degree, planner, setLoading]);

const handleZoomIn = () => {
const viewportCenter = graphRef.current?.getViewPortCenterPoint();
Expand Down Expand Up @@ -406,7 +426,7 @@ const CourseGraph = ({
return (
<S.Wrapper ref={containerRef}>
{loading ? (
<S.SpinnerWrapper>
<S.SpinnerWrapper className="spinner-wrapper">
<Spinner text="Loading graph..." />
</S.SpinnerWrapper>
) : (
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/pages/GraphicalSelector/GraphicalSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const GraphicalSelector = () => {
const [fullscreen, setFullscreen] = useState(false);
const [courseCode, setCourseCode] = useState<string | null>(null);
const [activeTab, setActiveTab] = useState(HELP_TAB);
const [loading, setLoading] = useState(true);
const courseDescInfoCache = useRef({} as CourseDescInfoResCache);
const hasPlannerUpdated = useRef<boolean>(false);

Expand Down Expand Up @@ -54,10 +55,14 @@ const GraphicalSelector = () => {
handleToggleFullscreen={() => setFullscreen((prevState) => !prevState)}
focused={courseCode ?? undefined}
hasPlannerUpdated={hasPlannerUpdated}
loading={loading}
setLoading={setLoading}
/>
<S.SearchBarWrapper>
<CourseSearchBar onSelectCallback={setCourseCode} style={{ width: '25rem' }} />
</S.SearchBarWrapper>
{!loading && (
<S.SearchBarWrapper>
<CourseSearchBar onSelectCallback={setCourseCode} style={{ width: '25rem' }} />
</S.SearchBarWrapper>
)}
{fullscreen && (
<SidebarDrawer>
<Tabs
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/styled.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ declare module 'styled-components' {
tabBottomBorderColor: string;
tabTextColor: string;
tabBoxShadow?: string;
loadingIcon?: string;
loadingText: string;
};
sidebarDrawer: {
backgroundColor: string;
Expand Down

0 comments on commit a11ae10

Please sign in to comment.