Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/frontend/src/hooks/work-packages.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,17 @@ export const useAllWorkPackages = (queryParams?: { [field: string]: string }) =>
export const useAllWorkPackagesPreview = (status?: string) => {
return useQuery<WorkPackagePreview[], Error>(['work packages', 'preview', status], async () => {
const { data } = await getAllWorkPackagesPreview(status);
return data;

const seen = new Set<string>();

const uniqueData = data.filter((item: WorkPackagePreview) => {
const key = `${item.wbsNum.carNumber}-${item.wbsNum.projectNumber}-${item.wbsNum.workPackageNumber}`;
const isDuplicate = seen.has(key);
seen.add(key);
return !isDuplicate;
});

return uniqueData;
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
GanttTask,
HighlightTaskComparator,
OnMouseOverOptions,
RequestEventChange
} from '../../../../../utils/gantt.utils';
import { wbsPipe, WbsNumber } from 'shared';
import GanttTaskBarDisplay from './GanttTaskBarDisplay';

interface BlockedGanttTaskViewProps<T> {
parentTask: GanttTask<T>;
task: GanttTask<T>;
days: Date[];
getStartCol: (start: Date) => number;
getEndCol: (end: Date) => number;
handleOnMouseOver: (e: React.MouseEvent, task: OnMouseOverOptions) => void;
handleOnMouseLeave: () => void;
onShowChildrenToggle: () => void;
highlightedChange?: RequestEventChange<T>;
highlightTaskComparator: HighlightTaskComparator<T>;
highlightSubtaskComparator: HighlightTaskComparator<T>;
}

interface TaskWithBlockingInfo {
blockedBy: WbsNumber[];
wbsNum: WbsNumber;
}

const hasBlockingInfo = (value: unknown): value is TaskWithBlockingInfo => {
return (
typeof value === 'object' &&
value !== null &&
'blockedBy' in value &&
'wbsNum' in value &&
Array.isArray((value as { blockedBy: unknown }).blockedBy)
);
};

const shouldRenderUnderParent = <T,>(parentTask: GanttTask<T>, task: GanttTask<T>): boolean => {
if (!hasBlockingInfo(task.element) || !hasBlockingInfo(parentTask.element)) {
return true;
}

const parentWbs = wbsPipe(parentTask.element.wbsNum);
const [canonicalBlockedByParent] = task.element.blockedBy.map(wbsPipe).sort();
return canonicalBlockedByParent === parentWbs;
};

const BlockedGanttTaskView = <T,>({
parentTask,
task,
days,
getStartCol,
getEndCol,
handleOnMouseOver,
handleOnMouseLeave,
onShowChildrenToggle,
highlightedChange,
highlightSubtaskComparator,
highlightTaskComparator
}: BlockedGanttTaskViewProps<T>) => {
if (!shouldRenderUnderParent(parentTask, task)) {
return null;
}

return (
<>
<GanttTaskBarDisplay
days={days}
task={task}
handleOnMouseOver={handleOnMouseOver}
handleOnMouseLeave={handleOnMouseLeave}
onShowChildrenToggle={onShowChildrenToggle}
highlightSubtaskComparator={highlightSubtaskComparator}
highlightTaskComparator={highlightTaskComparator}
showChildren={false}
highlightedChange={highlightedChange}
getStartCol={getStartCol}
getEndCol={getEndCol}
/>
{task.blocking.map((child) => {
return (
<BlockedGanttTaskView
key={child.id}
parentTask={task}
task={child}
days={days}
getStartCol={getStartCol}
getEndCol={getEndCol}
handleOnMouseOver={handleOnMouseOver}
onShowChildrenToggle={onShowChildrenToggle}
highlightTaskComparator={highlightTaskComparator}
highlightSubtaskComparator={highlightSubtaskComparator}
handleOnMouseLeave={handleOnMouseLeave}
highlightedChange={highlightedChange}
/>
);
})}
</>
);
};

export default BlockedGanttTaskView;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { Collapse } from '@mui/material';
import GanttTaskBar from './GanttTaskBar';
import GanttTaskBarDisplay from './GanttTaskBarDisplay';
import BlockedGanttTaskView from './BlockedTaskBarView';
import { useState } from 'react';

interface GanttTaskBarViewProps<T> {
Expand Down Expand Up @@ -76,6 +77,24 @@ const GanttTaskBarView = <T,>({
/>
))}
</Collapse>
{task.blocking.map((blocking) => {
return (
<BlockedGanttTaskView
key={blocking.id}
parentTask={task}
task={blocking}
days={days}
getStartCol={getStartCol}
getEndCol={getEndCol}
handleOnMouseOver={handleOnMouseOver}
onShowChildrenToggle={handleToggle}
highlightSubtaskComparator={highlightSubtaskComparator}
highlightTaskComparator={highlightTaskComparator}
handleOnMouseLeave={handleOnMouseLeave}
highlightedChange={highlightedChange}
/>
);
})}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const GanttChartSection = <T,>({
);

return tasks.length > 0 ? (
<ArcherContainer strokeColor="#ef4545" ref={archerRef}>
<ArcherContainer strokeColor="#ef4545" noCurves ref={archerRef}>
<Box sx={{ width: 'fit-content' }}>
<Box sx={{ mt: '1rem', width: 'fit-content' }}>
{tasks.map((task) => {
Expand Down
10 changes: 6 additions & 4 deletions src/frontend/src/utils/gantt.utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ const getBlockingGanttTasks = <T extends WorkPackage>(

export const transformTaskToGanttTask = <T extends Task>(task: T, end: Date): GanttTask<T> => {
return {
id: task.taskId,
id: `task-${task.taskId}`,
element: task,

name: task.title,
Expand Down Expand Up @@ -441,7 +441,7 @@ export const transformWorkPackageToGanttTask = <T extends WorkPackage>(
allWorkPackages: T[]
): GanttTask<T> => {
return {
id: workPackage.id,
id: `work-package-${workPackage.id}`,
element: workPackage,

name: workPackage.name,
Expand Down Expand Up @@ -477,15 +477,17 @@ export const transformProjectToGanttTask = (
const taskList = hideTasks ? [] : project.tasks;

return {
id: project.id,
id: `project-${project.id}`,
element: project,

name: project.name,
start: startDate,
end: endDate,
blocking: [],
children: [
...project.workPackages.map((workPackage) => transformWorkPackageToGanttTask(workPackage, project.workPackages)),
...project.workPackages
.filter((wp) => wp.blockedBy.length === 0)
.map((workPackage) => transformWorkPackageToGanttTask(workPackage, project.workPackages)),
...taskList.map((task) => transformTaskToGanttTask(task, endDate))
],
overlays: [
Expand Down
Loading