-
Notifications
You must be signed in to change notification settings - Fork 9
#3845 mouse placement bug #3966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/gantt-chart-improvements
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||||
| import { Box, Chip, Typography } from '@mui/material'; | ||||||||
| import { useTheme } from '@mui/system'; | ||||||||
| import { CSSProperties, DragEvent, MouseEvent, useEffect, useState } from 'react'; | ||||||||
| import { CSSProperties, DragEvent, MouseEvent, useCallback, useEffect, useRef, useState } from 'react'; | ||||||||
| import useMeasure from 'react-use-measure'; | ||||||||
| import { addDaysToDate } from 'shared'; | ||||||||
| import { GanttChange, GanttTask, GANTT_CHART_CELL_SIZE } from '../../../../../utils/gantt.utils'; | ||||||||
|
|
@@ -33,18 +33,20 @@ export const GanttTaskBarEditView = <T,>({ | |||||||
| onAddTaskPressed | ||||||||
| }: GanttTaskBarEditProps<T>) => { | ||||||||
| const theme = useTheme(); | ||||||||
| const [startX, setStartX] = useState<number | null>(null); | ||||||||
| const [showDropPoints, setShowDropPoints] = useState(false); | ||||||||
| const [isResizing, setIsResizing] = useState(false); | ||||||||
| const [width, setWidth] = useState(0); // current width of component, will change on resize | ||||||||
| const [width, setWidth] = useState(0); | ||||||||
| const [correctWidth, setCorrectWidth] = useState(0); | ||||||||
| const [measureRef, bounds] = useMeasure(); | ||||||||
| const hasMeasuredRef = useRef(false); | ||||||||
| const boxRef = useRef<HTMLDivElement | null>(null); | ||||||||
| const widthPerDay = 7.2; //width per day to use for resizing calculations, kind of arbitrary, | ||||||||
|
|
||||||||
| const taskBarDisplayStyles: CSSProperties = { | ||||||||
| gridColumnStart: getStartCol(task.start), | ||||||||
| gridColumnEnd: getEndCol(task.end), | ||||||||
| height: '2rem', | ||||||||
| width: task.root ? 'unset' : width === 0 ? `unset` : `${width}px`, | ||||||||
| width: task.root ? 'unset' : correctWidth > 0 ? `${correctWidth}px` : 'auto', | ||||||||
| border: `1px solid ${isResizing ? theme.palette.text.primary : theme.palette.divider}`, | ||||||||
| borderRadius: '0.25rem', | ||||||||
| backgroundColor: task.styles ? task.styles.backgroundColor : theme.palette.background.paper, | ||||||||
|
|
@@ -67,48 +69,54 @@ export const GanttTaskBarEditView = <T,>({ | |||||||
| right: '-10' | ||||||||
| }; | ||||||||
|
|
||||||||
| const getCorrectWidth = useCallback((rawWidth: number) => { | ||||||||
| const newEventLengthInDays = roundToMultipleOf7(rawWidth / widthPerDay); | ||||||||
| const displayWeeks = newEventLengthInDays / 7 + 1; | ||||||||
| return displayWeeks * 40 + (displayWeeks - 1) * 10; | ||||||||
| }, []); | ||||||||
|
Comment on lines
+72
to
+76
|
||||||||
|
|
||||||||
| useEffect(() => { | ||||||||
| if (bounds.width !== 0 && width === 0) { | ||||||||
| if (!hasMeasuredRef.current && bounds.width > 0) { | ||||||||
| setWidth(bounds.width); | ||||||||
| setCorrectWidth(getCorrectWidth(bounds.width)); | ||||||||
| hasMeasuredRef.current = true; | ||||||||
| } | ||||||||
| }, [bounds, width]); | ||||||||
| }, [bounds.width, getCorrectWidth]); | ||||||||
|
|
||||||||
| // used to make sure that any changes to the start and end dates are made in multiples of 7 | ||||||||
| const roundToMultipleOf7 = (num: number) => { | ||||||||
| return Math.round(num / 7) * 7; | ||||||||
| return Math.ceil(num / 7) * 7; | ||||||||
|
||||||||
| return Math.ceil(num / 7) * 7; | |
| const weeks = Math.max(1, Math.round(num / 7)); | |
| return weeks * 7; |
Copilot
AI
Feb 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The roundToMultipleOf7 function is defined within the component body and referenced by getCorrectWidth. This causes the function to be redefined on every render. Consider moving roundToMultipleOf7 outside the component as a module-level utility function to improve performance and avoid unnecessary re-creations.
Copilot
AI
Feb 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function uses a non-null assertion operator on boxRef.current without checking if it's null. If handleMouseMove is called before handleMouseDown sets boxRef.current, or if the closest() call returns null, this will throw a runtime error. Consider adding a null check to prevent potential crashes.
Copilot
AI
Feb 21, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The closest() method can return null if no matching ancestor is found. This code uses type assertion to assume it's always an HTMLDivElement, which could lead to runtime errors. Consider adding a null check or using optional chaining to handle cases where the data-gantt-bar attribute might not be found in the element's ancestors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The magic number 40 appears to be changed from 38, but this is inconsistent with GANTT_CHART_CELL_SIZE which is defined as '2.375rem' (approximately 38px at 16px base font size). This hardcoded value should either use the constant or have a clear explanation for the 2px discrepancy. Similarly, the gap value of 10 doesn't match GANTT_CHART_GAP_SIZE ('0.75rem' = 12px). Consider using the constants or deriving pixel values from them to maintain consistency and make the calculation more maintainable.