Skip to content

Commit fa87568

Browse files
authored
Merge pull request #4080 from Northeastern-Electric-Racing/gantt-task-bar-data-optimizations
#4079 Gantt Chart Improvements Data Optimization
2 parents f47433b + 45aa7bc commit fa87568

12 files changed

Lines changed: 168 additions & 248 deletions

File tree

src/frontend/src/app/AppAuthenticated.tsx

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,65 @@ interface AppAuthenticatedProps {
4040
userRole: Role;
4141
}
4242

43-
const AppAuthenticated: React.FC<AppAuthenticatedProps> = ({ userId, userRole }) => {
44-
const { isLoading, isError, error, data: userSettingsData } = useSingleUserSettings(userId);
45-
43+
const SidebarLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
4644
const theme = useTheme();
4745
const [drawerOpen, setDrawerOpen] = useState(false);
4846
const [moveContent, setMoveContent] = useState(false);
4947
const { onGuestHomePage } = useHomePageContext();
5048

49+
return (
50+
<>
51+
<Box
52+
onMouseEnter={() => {
53+
setDrawerOpen(true);
54+
}}
55+
sx={{
56+
height: '100vh',
57+
position: 'fixed',
58+
width: 15,
59+
borderRight: 2,
60+
borderRightColor: theme.palette.background.paper
61+
}}
62+
/>
63+
<IconButton
64+
onClick={() => {
65+
setDrawerOpen(true);
66+
setMoveContent(true);
67+
}}
68+
sx={{ position: 'fixed', left: -8, top: '3%' }}
69+
id="sidebar-button"
70+
>
71+
<ArrowCircleRightTwoToneIcon
72+
sx={{
73+
fontSize: '30px',
74+
zIndex: 1,
75+
'& path:first-of-type': { color: '#000000' },
76+
'& path:last-of-type': { color: '#ef4345' }
77+
}}
78+
/>
79+
</IconButton>
80+
<Sidebar
81+
drawerOpen={drawerOpen}
82+
setDrawerOpen={setDrawerOpen}
83+
moveContent={moveContent}
84+
setMoveContent={setMoveContent}
85+
/>
86+
<Box display={'flex'}>
87+
<HiddenContentMargin open={moveContent} variant="permanent" />
88+
<Container
89+
maxWidth={false}
90+
sx={{ width: onGuestHomePage && moveContent ? 'calc(100vw - 220px)' : `calc(100vw - 30px)` }}
91+
>
92+
{children}
93+
</Container>
94+
</Box>
95+
</>
96+
);
97+
};
98+
99+
const AppAuthenticated: React.FC<AppAuthenticatedProps> = ({ userId, userRole }) => {
100+
const { isLoading, isError, error, data: userSettingsData } = useSingleUserSettings(userId);
101+
51102
const {
52103
data: organization,
53104
isLoading: organizationIsLoading,
@@ -70,71 +121,26 @@ const AppAuthenticated: React.FC<AppAuthenticatedProps> = ({ userId, userRole })
70121

71122
return userSettingsData.slackId || isGuest(userRole) ? (
72123
<AppContextUser>
73-
{
74-
<>
75-
<Box
76-
onMouseEnter={() => {
77-
setDrawerOpen(true);
78-
}}
79-
sx={{
80-
height: '100vh',
81-
position: 'fixed',
82-
width: 15,
83-
borderRight: 2,
84-
borderRightColor: theme.palette.background.paper
85-
}}
86-
/>
87-
<IconButton
88-
onClick={() => {
89-
setDrawerOpen(true);
90-
setMoveContent(true);
91-
}}
92-
sx={{ position: 'fixed', left: -8, top: '3%' }}
93-
id="sidebar-button"
94-
>
95-
<ArrowCircleRightTwoToneIcon
96-
sx={{
97-
fontSize: '30px',
98-
zIndex: 1,
99-
'& path:first-of-type': { color: '#000000' },
100-
'& path:last-of-type': { color: '#ef4345' }
101-
}}
102-
/>
103-
</IconButton>
104-
<Sidebar
105-
drawerOpen={drawerOpen}
106-
setDrawerOpen={setDrawerOpen}
107-
moveContent={moveContent}
108-
setMoveContent={setMoveContent}
109-
/>
110-
</>
111-
}
112-
<Box display={'flex'}>
113-
<HiddenContentMargin open={moveContent} variant="permanent" />
114-
<Container
115-
maxWidth={false}
116-
sx={{ width: onGuestHomePage && moveContent ? 'calc(100vw - 220px)' : `calc(100vw - 30px)` }}
117-
>
118-
<Switch>
119-
<Route path={routes.PROJECTS} component={Projects} />
120-
<Redirect from={routes.CR_BY_ID} to={routes.CHANGE_REQUESTS_BY_ID} />
121-
<Route path={routes.CHANGE_REQUESTS} component={ChangeRequests} />
122-
<Route path={routes.GANTT} component={GanttChartPage} />
123-
<Route path={routes.TEAMS} component={Teams} />
124-
<Route path={routes.SETTINGS} component={Settings} />
125-
<Route path={routes.ADMIN_TOOLS} component={AdminTools} />
126-
<Route path={routes.INFO} component={InfoPage} />
127-
<Route path={routes.CREDITS} component={Credits} />
128-
<Route path={routes.FINANCE} component={Finance} />
129-
<Route path={routes.CALENDAR} component={Calendar} />
130-
<Route path={routes.STATISTICS} component={Statistics} />
131-
<Route path={routes.HOME} component={Home} />
132-
<Route path={routes.RETROSPECTIVE} component={RetrospectiveGanttChartPage} />
133-
<Redirect from={routes.BASE} to={routes.HOME} />
134-
<Route path="*" component={PageNotFound} />
135-
</Switch>
136-
</Container>
137-
</Box>
124+
<SidebarLayout>
125+
<Switch>
126+
<Route path={routes.PROJECTS} component={Projects} />
127+
<Redirect from={routes.CR_BY_ID} to={routes.CHANGE_REQUESTS_BY_ID} />
128+
<Route path={routes.CHANGE_REQUESTS} component={ChangeRequests} />
129+
<Route path={routes.GANTT} component={GanttChartPage} />
130+
<Route path={routes.TEAMS} component={Teams} />
131+
<Route path={routes.SETTINGS} component={Settings} />
132+
<Route path={routes.ADMIN_TOOLS} component={AdminTools} />
133+
<Route path={routes.INFO} component={InfoPage} />
134+
<Route path={routes.CREDITS} component={Credits} />
135+
<Route path={routes.FINANCE} component={Finance} />
136+
<Route path={routes.CALENDAR} component={Calendar} />
137+
<Route path={routes.STATISTICS} component={Statistics} />
138+
<Route path={routes.HOME} component={Home} />
139+
<Route path={routes.RETROSPECTIVE} component={RetrospectiveGanttChartPage} />
140+
<Redirect from={routes.BASE} to={routes.HOME} />
141+
<Route path="*" component={PageNotFound} />
142+
</Switch>
143+
</SidebarLayout>
138144
</AppContextUser>
139145
) : (
140146
<SetUserPreferences userSettings={userSettingsData} />

src/frontend/src/app/AppContextQuery.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
import { QueryClient, QueryClientProvider } from 'react-query';
77

8+
const queryClient = new QueryClient();
9+
810
const AppContextQuery: React.FC = (props) => {
9-
const queryClient = new QueryClient();
1011
return <QueryClientProvider client={queryClient}>{props.children}</QueryClientProvider>;
1112
};
1213

src/frontend/src/app/AppContextUser.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import ErrorPage from '../pages/ErrorPage';
1616

1717
export const UserContext = createContext<AuthenticatedUser | undefined>(undefined);
1818

19-
const AppContextUser: React.FC = (props) => {
19+
const AppContextUser: React.FC<{ children: React.ReactNode }> = (props) => {
2020
const auth = useAuth();
2121
const clarity = useClarity();
2222
const { data: teams, isLoading: teamsIsLoading, isError: teamsIsError, error: teamsError } = useGetUsersTeams();

src/frontend/src/pages/GanttPage/GanttChart/GanttChart.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,10 @@ interface GanttChartProps<E, T> {
2929
startDate: Date;
3030
endDate: Date;
3131
collections: GanttCollection<E, T>[];
32-
shouldShowChildren: (task: GanttTask<T>) => boolean;
33-
onShowChildrenToggle: (task: GanttTask<T>) => void;
34-
3532
editability?: GanttEditability<E, T>;
3633
}
3734

38-
const GanttChart = <E, T>({
39-
startDate,
40-
endDate,
41-
collections,
42-
shouldShowChildren,
43-
onShowChildrenToggle,
44-
editability
45-
}: GanttChartProps<E, T>) => {
35+
const GanttChart = <E, T>({ startDate, endDate, collections, editability }: GanttChartProps<E, T>) => {
4636
const theme = useTheme();
4737
const days = eachDayOfInterval({ start: startDate, end: endDate }).filter((day) => isMonday(day));
4838

@@ -74,8 +64,6 @@ const GanttChart = <E, T>({
7464
startDate={startDate}
7565
endDate={endDate}
7666
collection={collection}
77-
shouldShowChildren={shouldShowChildren}
78-
onShowChildrenToggle={onShowChildrenToggle}
7967
editability={editability}
8068
/>
8169
) : (

src/frontend/src/pages/GanttPage/GanttChart/GanttChartCollectionSection.tsx

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import { Edit } from '@mui/icons-material';
22
import { Box, Chip, IconButton, Typography, useTheme } from '@mui/material';
33
import GanttChartSection from './GanttChartSection';
4-
import { GanttCollection, GanttTask } from '../../../utils/gantt.utils';
4+
import { GanttCollection } from '../../../utils/gantt.utils';
55
import { useState } from 'react';
66
import { GanttEditability } from './GanttChart';
77

88
interface GanttChartCollectionSectionProps<E, T> {
99
startDate: Date;
1010
endDate: Date;
11-
shouldShowChildren: (task: GanttTask<T>) => boolean;
12-
onShowChildrenToggle: (task: GanttTask<T>) => void;
1311
collection: GanttCollection<E, T>;
1412
editability?: GanttEditability<E, T>;
1513
}
@@ -18,8 +16,6 @@ const GanttChartCollectionSection = <E, T>({
1816
startDate,
1917
endDate,
2018
collection,
21-
shouldShowChildren,
22-
onShowChildrenToggle,
2319
editability
2420
}: GanttChartCollectionSectionProps<E, T>) => {
2521
const theme = useTheme();
@@ -61,11 +57,6 @@ const GanttChartCollectionSection = <E, T>({
6157
setIsEditMode(true);
6258
};
6359

64-
// Sorting the work packages of each project based on their start date
65-
collection.tasks.forEach((task) => {
66-
task.children.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());
67-
});
68-
6960
const ignore = () => {};
7061

7162
const ignoreBool = () => false;
@@ -100,9 +91,7 @@ const GanttChartCollectionSection = <E, T>({
10091
createChange={editability?.onCreateChange ?? ignore}
10192
highlightedChange={editability?.highlightedChange}
10293
tasks={collection.tasks}
103-
shouldShowChildren={shouldShowChildren}
10494
onAddTaskPressed={editability?.onNewSubTaskPressed ?? ignore}
105-
onShowChildrenToggle={onShowChildrenToggle}
10695
highlightSubtaskComparator={editability?.highlightSubtaskComparator ?? ignoreBool}
10796
highlightTaskComparator={editability?.highlightTaskComparator ?? ignoreBool}
10897
/>

src/frontend/src/pages/GanttPage/GanttChart/GanttChartComponents/GanttTaskBar/GanttTaskBar.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ interface GanttTaskBarProps<T> {
2222
isEditMode: boolean;
2323
handleOnMouseOver: (e: React.MouseEvent, task: OnMouseOverOptions) => void;
2424
handleOnMouseLeave: () => void;
25-
onShowChildrenToggle: () => void;
26-
showChildren?: boolean;
2725
highlightedChange?: RequestEventChange<T>;
2826
onAddTaskPressed: (parent: GanttTask<T>) => void;
2927
highlightTaskComparator: HighlightTaskComparator<T>;
3028
highlightSubtaskComparator: HighlightTaskComparator<T>;
29+
onToggle?: () => void;
3130
}
3231

3332
const GanttTaskBar = <T,>({
@@ -36,13 +35,12 @@ const GanttTaskBar = <T,>({
3635
createChange,
3736
isEditMode,
3837
handleOnMouseOver,
39-
onShowChildrenToggle,
4038
handleOnMouseLeave,
41-
showChildren = false,
4239
highlightedChange,
4340
onAddTaskPressed,
4441
highlightSubtaskComparator,
45-
highlightTaskComparator
42+
highlightTaskComparator,
43+
onToggle
4644
}: GanttTaskBarProps<T>) => {
4745
const getStartCol = (start: Date) => {
4846
const startCol = days.findIndex((day) => toDateString(day) === toDateString(getMonday(start))) + 1;
@@ -76,12 +74,11 @@ const GanttTaskBar = <T,>({
7674
getEndCol={getEndCol}
7775
handleOnMouseOver={handleOnMouseOver}
7876
handleOnMouseLeave={handleOnMouseLeave}
79-
showChildren={showChildren}
80-
onShowChildrenToggle={onShowChildrenToggle}
8177
highlightedChange={highlightedChange}
8278
onAddTaskPressed={onAddTaskPressed}
8379
highlightSubtaskComparator={highlightSubtaskComparator}
8480
highlightTaskComparator={highlightTaskComparator}
81+
onToggle={onToggle}
8582
/>
8683
)}
8784
</div>

src/frontend/src/pages/GanttPage/GanttChart/GanttChartComponents/GanttTaskBar/GanttTaskBarView.tsx

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { Collapse } from '@mui/material';
88
import GanttTaskBar from './GanttTaskBar';
99
import GanttTaskBarDisplay from './GanttTaskBarDisplay';
10+
import { useState } from 'react';
1011

1112
interface GanttTaskBarViewProps<T> {
1213
days: Date[];
@@ -15,12 +16,11 @@ interface GanttTaskBarViewProps<T> {
1516
getEndCol: (end: Date) => number;
1617
handleOnMouseOver: (e: React.MouseEvent, task: OnMouseOverOptions) => void;
1718
handleOnMouseLeave: () => void;
18-
onShowChildrenToggle: () => void;
19-
showChildren: boolean;
2019
highlightedChange?: RequestEventChange<T>;
2120
onAddTaskPressed: (parent: GanttTask<T>) => void;
2221
highlightTaskComparator: HighlightTaskComparator<T>;
2322
highlightSubtaskComparator: HighlightTaskComparator<T>;
23+
onToggle?: () => void;
2424
}
2525

2626
const GanttTaskBarView = <T,>({
@@ -30,13 +30,18 @@ const GanttTaskBarView = <T,>({
3030
getEndCol,
3131
handleOnMouseOver,
3232
handleOnMouseLeave,
33-
onShowChildrenToggle,
34-
showChildren,
3533
highlightedChange,
3634
onAddTaskPressed,
3735
highlightSubtaskComparator,
38-
highlightTaskComparator
36+
highlightTaskComparator,
37+
onToggle
3938
}: GanttTaskBarViewProps<T>) => {
39+
const [showChildren, setShowChildren] = useState(false);
40+
41+
const handleToggle = () => {
42+
setShowChildren((prev) => !prev);
43+
};
44+
4045
return (
4146
<>
4247
<GanttTaskBarDisplay
@@ -45,33 +50,31 @@ const GanttTaskBarView = <T,>({
4550
handleOnMouseOver={handleOnMouseOver}
4651
handleOnMouseLeave={handleOnMouseLeave}
4752
showChildren={showChildren}
48-
onShowChildrenToggle={onShowChildrenToggle}
53+
onShowChildrenToggle={handleToggle}
4954
highlightedChange={highlightedChange}
5055
getStartCol={getStartCol}
5156
getEndCol={getEndCol}
5257
highlightSubtaskComparator={highlightSubtaskComparator}
5358
highlightTaskComparator={highlightTaskComparator}
5459
/>
5560

56-
<Collapse in={showChildren} unmountOnExit>
57-
{task.children.map((child) => {
58-
return (
59-
<GanttTaskBar
60-
key={child.id}
61-
days={days}
62-
task={child}
63-
isEditMode={false}
64-
createChange={() => {}}
65-
handleOnMouseOver={handleOnMouseOver}
66-
handleOnMouseLeave={handleOnMouseLeave}
67-
onShowChildrenToggle={onShowChildrenToggle}
68-
highlightedChange={highlightedChange}
69-
onAddTaskPressed={onAddTaskPressed}
70-
highlightSubtaskComparator={highlightSubtaskComparator}
71-
highlightTaskComparator={highlightTaskComparator}
72-
/>
73-
);
74-
})}
61+
<Collapse in={showChildren} unmountOnExit onEntered={onToggle} onExited={onToggle}>
62+
{task.children.map((child) => (
63+
<GanttTaskBar
64+
key={child.id}
65+
days={days}
66+
task={child}
67+
isEditMode={false}
68+
createChange={() => {}}
69+
handleOnMouseOver={handleOnMouseOver}
70+
handleOnMouseLeave={handleOnMouseLeave}
71+
highlightedChange={highlightedChange}
72+
onAddTaskPressed={onAddTaskPressed}
73+
highlightSubtaskComparator={highlightSubtaskComparator}
74+
highlightTaskComparator={highlightTaskComparator}
75+
onToggle={onToggle}
76+
/>
77+
))}
7578
</Collapse>
7679
</>
7780
);

0 commit comments

Comments
 (0)