Skip to content

Commit d2758de

Browse files
authored
Merge pull request #3966 from Northeastern-Electric-Racing/#3845-mouse-placement-bug
#3845 mouse placement bug
2 parents 380e59e + 1cc8ded commit d2758de

2 files changed

Lines changed: 59 additions & 37 deletions

File tree

src/backend/src/prisma/seed.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,7 +1672,7 @@ const performSeed: () => Promise<void> = async () => {
16721672
'Bodywork Concept of Design',
16731673
changeRequestProjectHuskies1Id,
16741674
WorkPackageStage.Design,
1675-
toDateString(weeksAgo(12)),
1675+
weeksAgo(12).toISOString().split('T')[0],
16761676
6,
16771677
[],
16781678
[],
@@ -1718,7 +1718,7 @@ const performSeed: () => Promise<void> = async () => {
17181718
'Adhesive Shear Strength Test',
17191719
changeRequestProjectHuskies1Id,
17201720
WorkPackageStage.Research,
1721-
toDateString(weeksAgo(10)),
1721+
weeksAgo(10).toISOString().split('T')[0],
17221722
5,
17231723
[],
17241724
[],
@@ -1736,7 +1736,7 @@ const performSeed: () => Promise<void> = async () => {
17361736
'Manufacture Wiring Harness',
17371737
changeRequestProjectSlackbot1Id,
17381738
WorkPackageStage.Manufacturing,
1739-
toDateString(weeksAgo(9)),
1739+
weeksAgo(9).toISOString().split('T')[0],
17401740
4,
17411741
[],
17421742
[],
@@ -1769,7 +1769,7 @@ const performSeed: () => Promise<void> = async () => {
17691769
'Install Wiring Harness',
17701770
changeRequestProjectSlackbot1Id,
17711771
WorkPackageStage.Install,
1772-
toDateString(weeksAgo(5)),
1772+
weeksAgo(5).toISOString().split('T')[0],
17731773
6,
17741774
[],
17751775
[],
@@ -1922,7 +1922,7 @@ const performSeed: () => Promise<void> = async () => {
19221922
'Design Laser Canon',
19231923
changeRequestProjectJustice1Id,
19241924
WorkPackageStage.Design,
1925-
toDateString(weeksAgo(8)),
1925+
weeksAgo(8).toISOString().split('T')[0],
19261926
5,
19271927
[],
19281928
[],
@@ -1950,12 +1950,12 @@ const performSeed: () => Promise<void> = async () => {
19501950
await ChangeRequestsService.reviewChangeRequest(joeShmoe, projectJustice1WP1ActivationCrId, 'Approved!', true, ner, null);
19511951

19521952
/** Work Package 2 */
1953-
const { workPackage: project3WP2 } = await seedWorkPackage(
1953+
await seedWorkPackage(
19541954
lexLuther,
19551955
'Laser Canon Research',
19561956
changeRequestProjectJustice1Id,
19571957
WorkPackageStage.Research,
1958-
toDateString(weeksAgo(3)),
1958+
weeksAgo(3).toISOString().split('T')[0],
19591959
6,
19601960
[],
19611961
[],
@@ -1973,9 +1973,9 @@ const performSeed: () => Promise<void> = async () => {
19731973
'Laser Canon Testing',
19741974
changeRequestProjectJustice1Id,
19751975
WorkPackageStage.Testing,
1976-
toDateString(weeksFromNow(3)),
1976+
weeksFromNow(3).toISOString().split('T')[0],
19771977
4,
1978-
[project3WP1.wbsNum, project3WP2.wbsNum],
1978+
[],
19791979
[],
19801980
zatanna,
19811981
WbsElementStatus.Active,
@@ -2044,7 +2044,7 @@ const performSeed: () => Promise<void> = async () => {
20442044
'Stadium Research',
20452045
changeRequestProjectRavens1Id,
20462046
WorkPackageStage.Research,
2047-
toDateString(weeksAgo(14)),
2047+
weeksAgo(14).toISOString().split('T')[0],
20482048
7,
20492049
[],
20502050
[],
@@ -2077,7 +2077,7 @@ const performSeed: () => Promise<void> = async () => {
20772077
'Stadium Install',
20782078
changeRequestProjectRavens1Id,
20792079
WorkPackageStage.Install,
2080-
toDateString(weeksAgo(7)),
2080+
weeksAgo(7).toISOString().split('T')[0],
20812081
6,
20822082
[],
20832083
[],
@@ -2095,7 +2095,7 @@ const performSeed: () => Promise<void> = async () => {
20952095
'Stadium Testing',
20962096
changeRequestProjectRavens1Id,
20972097
WorkPackageStage.Testing,
2098-
toDateString(weeksAgo(1)),
2098+
weeksAgo(1).toISOString().split('T')[0],
20992099
5,
21002100
[],
21012101
[],

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

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Box, Chip, Typography } from '@mui/material';
22
import { useTheme } from '@mui/system';
3-
import { CSSProperties, DragEvent, MouseEvent, useEffect, useState } from 'react';
3+
import { CSSProperties, DragEvent, MouseEvent, useCallback, useEffect, useRef, useState } from 'react';
44
import useMeasure from 'react-use-measure';
55
import { addDaysToDate } from 'shared';
66
import { GanttChange, GanttTask, GANTT_CHART_CELL_SIZE } from '../../../../../utils/gantt.utils';
@@ -15,6 +15,10 @@ import {
1515
import { ArcherElement } from 'react-archer';
1616
import { v4 as uuidv4 } from 'uuid';
1717

18+
const CELL_SIZE_PX = 38 + 2; // 38px cell + 2px for borders (1px each side)
19+
const GAP_SIZE_PX = 10; // empirically determined, see note above
20+
const WIDTH_PER_DAY = 7.2; //width per day to use for resizing calculations, kind of arbitrary,
21+
1822
interface GanttTaskBarEditProps<T> {
1923
days: Date[];
2024
task: GanttTask<T>;
@@ -33,18 +37,19 @@ export const GanttTaskBarEditView = <T,>({
3337
onAddTaskPressed
3438
}: GanttTaskBarEditProps<T>) => {
3539
const theme = useTheme();
36-
const [startX, setStartX] = useState<number | null>(null);
3740
const [showDropPoints, setShowDropPoints] = useState(false);
3841
const [isResizing, setIsResizing] = useState(false);
39-
const [width, setWidth] = useState(0); // current width of component, will change on resize
42+
const [width, setWidth] = useState(0);
43+
const [correctWidth, setCorrectWidth] = useState(0);
4044
const [measureRef, bounds] = useMeasure();
41-
const widthPerDay = 7.2; //width per day to use for resizing calculations, kind of arbitrary,
45+
const hasMeasuredRef = useRef(false);
46+
const boxRef = useRef<HTMLDivElement | null>(null);
4247

4348
const taskBarDisplayStyles: CSSProperties = {
4449
gridColumnStart: getStartCol(task.start),
4550
gridColumnEnd: getEndCol(task.end),
4651
height: '2rem',
47-
width: task.root ? 'unset' : width === 0 ? `unset` : `${width}px`,
52+
width: task.root ? 'unset' : correctWidth > 0 ? `${correctWidth}px` : 'auto',
4853
border: `1px solid ${isResizing ? theme.palette.text.primary : theme.palette.divider}`,
4954
borderRadius: '0.25rem',
5055
backgroundColor: task.styles ? task.styles.backgroundColor : theme.palette.background.paper,
@@ -67,48 +72,65 @@ export const GanttTaskBarEditView = <T,>({
6772
right: '-10'
6873
};
6974

75+
const getCorrectWidth = useCallback((rawWidth: number) => {
76+
const newEventLengthInDays = floorToMultipleOf7(rawWidth / WIDTH_PER_DAY);
77+
const displayWeeks = newEventLengthInDays / 7 + 1;
78+
return displayWeeks * CELL_SIZE_PX + (displayWeeks - 1) * GAP_SIZE_PX;
79+
}, []);
80+
7081
useEffect(() => {
71-
if (bounds.width !== 0 && width === 0) {
82+
if (!hasMeasuredRef.current && bounds.width > 0) {
7283
setWidth(bounds.width);
84+
setCorrectWidth(getCorrectWidth(bounds.width));
85+
hasMeasuredRef.current = true;
7386
}
74-
}, [bounds, width]);
87+
}, [bounds.width, getCorrectWidth]);
7588

7689
// used to make sure that any changes to the start and end dates are made in multiples of 7
77-
const roundToMultipleOf7 = (num: number) => {
78-
return Math.round(num / 7) * 7;
90+
const floorToMultipleOf7 = (num: number) => {
91+
return Math.floor(num / 7) * 7;
92+
};
93+
94+
const ceilToMultipleOf7 = (num: number) => {
95+
return Math.ceil(num / 7) * 7;
96+
};
97+
98+
const getDistanceFromLeft = (clientX: number) => {
99+
if (!boxRef.current) return 0;
100+
const rect = boxRef.current.getBoundingClientRect();
101+
return clientX - rect.left;
79102
};
80103

81104
const handleMouseDown = (e: MouseEvent<HTMLElement>) => {
105+
const bar = (e.currentTarget as HTMLElement).closest('[data-gantt-bar]');
106+
if (!bar) return;
107+
108+
boxRef.current = (e.currentTarget as HTMLElement).closest('[data-gantt-bar]') as HTMLDivElement;
82109
setIsResizing(true);
83-
setStartX(e.clientX);
84110
};
85111

86112
const handleMouseMove = (e: MouseEvent<HTMLElement>) => {
87-
if (isResizing) {
88-
const currentX = e.clientX;
89-
const deltaX = currentX - startX!;
90-
setWidth(Math.max(100, width + deltaX));
91-
setStartX(currentX);
92-
}
113+
if (!isResizing) return;
114+
115+
const newWidth = Math.max(100, getDistanceFromLeft(e.clientX));
116+
117+
setWidth(newWidth); // sync render
118+
setCorrectWidth(getCorrectWidth(newWidth));
93119
};
94120

95121
const handleMouseUp = () => {
96122
if (isResizing) {
97123
setIsResizing(false);
98-
// Use change in width to calculate new length
99-
const newEventLengthInDays = roundToMultipleOf7(width / widthPerDay);
100-
// The gantt chart tasks are inclusive (their width includes the full width of their start and end date)
124+
const newEventLengthInDays = floorToMultipleOf7(width / WIDTH_PER_DAY);
101125
const displayWeeks = newEventLengthInDays / 7 + 1;
102-
// We need these magic pixel numbers to dynamically calculate the correct width of the task to keep it in sync with the stored end date
103-
const correctWidth = displayWeeks * 38 + (displayWeeks - 1) * 10;
104-
const newEndDate = addDaysToDate(task.start, newEventLengthInDays);
126+
const correctWidth = displayWeeks * 40 + (displayWeeks - 1) * 10;
105127
setWidth(correctWidth);
106128
createChange({
107129
id: uuidv4(),
108130
element: task.element,
109131
type: 'change-end-date',
110132
originalEnd: task.end,
111-
newEnd: newEndDate
133+
newEnd: addDaysToDate(task.start, newEventLengthInDays)
112134
});
113135
}
114136
};
@@ -124,7 +146,7 @@ export const GanttTaskBarEditView = <T,>({
124146
e.preventDefault();
125147
};
126148
const onDrop = (day: Date) => {
127-
const days = roundToMultipleOf7(differenceInDays(day, task.start));
149+
const days = ceilToMultipleOf7(differenceInDays(day, task.start));
128150
createChange({ id: uuidv4(), element: task.element, type: 'shift-by-days', days });
129151
};
130152

@@ -156,7 +178,7 @@ export const GanttTaskBarEditView = <T,>({
156178
};
157179
})}
158180
>
159-
<div ref={measureRef} style={taskBarDisplayStyles}>
181+
<div data-gantt-bar ref={measureRef} style={taskBarDisplayStyles}>
160182
<Box sx={webKitBoxContainerStyles()}>
161183
<Box draggable={!task.root} onDrag={onDragStart} onDragEnd={onDragEnd} sx={webKitBoxStyles()}>
162184
<Box sx={{ display: 'flex', flexDirection: 'row' }}>

0 commit comments

Comments
 (0)