gantt-task-react-v 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10038,10 +10038,10 @@
10038
10038
  const { id, comparisonLevel = 1 } = task;
10039
10039
  const onRootMouseDown = React.useCallback(
10040
10040
  (event) => {
10041
- event.preventDefault();
10042
10041
  if (event.button !== 0) {
10043
10042
  return;
10044
10043
  }
10044
+ event.preventDefault();
10045
10045
  if (task.type !== "empty") {
10046
10046
  scrollToTask(task);
10047
10047
  }
@@ -10924,204 +10924,6 @@
10924
10924
  ganttToday,
10925
10925
  ganttTodayCircle
10926
10926
  };
10927
- const getDateByOffset = (startDate, offset2, viewMode) => {
10928
- switch (viewMode) {
10929
- case ViewMode.Day:
10930
- return addDays(startDate, offset2);
10931
- case ViewMode.HalfDay:
10932
- return addHours(startDate, offset2 * 12);
10933
- case ViewMode.QuarterDay:
10934
- return addHours(startDate, offset2 * 6);
10935
- case ViewMode.Hour:
10936
- return addHours(startDate, offset2);
10937
- case ViewMode.Month:
10938
- return addMonths(startDate, offset2);
10939
- case ViewMode.Week:
10940
- return addWeeks(startDate, offset2);
10941
- case ViewMode.Year:
10942
- return addYears(startDate, offset2);
10943
- default:
10944
- throw new Error("Unknown view mode");
10945
- }
10946
- };
10947
- const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10948
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10949
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10950
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10951
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10952
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10953
- return index2 * columnWidth + percentOfInterval * columnWidth;
10954
- };
10955
- const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10956
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10957
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10958
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10959
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10960
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10961
- return index2 * columnWidth + percentOfInterval * columnWidth;
10962
- };
10963
- const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
10964
- const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
10965
- let progressX;
10966
- if (rtl) {
10967
- progressX = taskX2 - progressWidth;
10968
- } else {
10969
- progressX = taskX1;
10970
- }
10971
- return [progressWidth, progressX];
10972
- };
10973
- const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
10974
- let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
10975
- newDate = new Date(
10976
- newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
10977
- );
10978
- return newDate;
10979
- };
10980
- const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
10981
- let result;
10982
- switch (selectedTask.type) {
10983
- case "milestone":
10984
- result = handleTaskBySVGMouseEventForMilestone(
10985
- action,
10986
- selectedTask,
10987
- initialCoordinates,
10988
- coordinates,
10989
- xStep,
10990
- timeStep
10991
- );
10992
- break;
10993
- default:
10994
- result = handleTaskBySVGMouseEventForBar(
10995
- action,
10996
- selectedTask,
10997
- initialCoordinates,
10998
- coordinates,
10999
- xStep,
11000
- timeStep,
11001
- rtl
11002
- );
11003
- break;
11004
- }
11005
- return result;
11006
- };
11007
- const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11008
- const changedTask = { ...selectedTask };
11009
- let isChanged = false;
11010
- switch (action) {
11011
- case "progress":
11012
- isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
11013
- if (isChanged) {
11014
- changedTask.progress = Math.round(
11015
- coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11016
- );
11017
- }
11018
- break;
11019
- case "start": {
11020
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11021
- if (isChanged) {
11022
- if (rtl) {
11023
- changedTask.end = dateByX(
11024
- coordinates.x1,
11025
- initialCoordinates.x1,
11026
- selectedTask.end,
11027
- xStep,
11028
- timeStep
11029
- );
11030
- } else {
11031
- changedTask.start = dateByX(
11032
- coordinates.x1,
11033
- initialCoordinates.x1,
11034
- selectedTask.start,
11035
- xStep,
11036
- timeStep
11037
- );
11038
- }
11039
- }
11040
- break;
11041
- }
11042
- case "end": {
11043
- isChanged = initialCoordinates.x2 !== coordinates.x2;
11044
- if (isChanged) {
11045
- if (rtl) {
11046
- changedTask.start = dateByX(
11047
- coordinates.x2,
11048
- initialCoordinates.x2,
11049
- selectedTask.start,
11050
- xStep,
11051
- timeStep
11052
- );
11053
- } else {
11054
- changedTask.end = dateByX(
11055
- coordinates.x2,
11056
- initialCoordinates.x2,
11057
- selectedTask.end,
11058
- xStep,
11059
- timeStep
11060
- );
11061
- }
11062
- }
11063
- break;
11064
- }
11065
- case "move": {
11066
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11067
- if (isChanged) {
11068
- if (rtl) {
11069
- changedTask.end = dateByX(
11070
- coordinates.x1,
11071
- initialCoordinates.x1,
11072
- selectedTask.end,
11073
- xStep,
11074
- timeStep
11075
- );
11076
- changedTask.start = dateByX(
11077
- coordinates.x2,
11078
- initialCoordinates.x2,
11079
- selectedTask.start,
11080
- xStep,
11081
- timeStep
11082
- );
11083
- } else {
11084
- changedTask.start = dateByX(
11085
- coordinates.x1,
11086
- initialCoordinates.x1,
11087
- selectedTask.start,
11088
- xStep,
11089
- timeStep
11090
- );
11091
- changedTask.end = dateByX(
11092
- coordinates.x2,
11093
- initialCoordinates.x2,
11094
- selectedTask.end,
11095
- xStep,
11096
- timeStep
11097
- );
11098
- }
11099
- }
11100
- break;
11101
- }
11102
- }
11103
- return { isChanged, changedTask };
11104
- };
11105
- const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11106
- const changedTask = { ...selectedTask };
11107
- const isChanged = coordinates.x1 !== initialCoordinates.x1;
11108
- if (isChanged) {
11109
- switch (action) {
11110
- case "move": {
11111
- changedTask.start = dateByX(
11112
- coordinates.x1,
11113
- initialCoordinates.x1,
11114
- selectedTask.start,
11115
- xStep,
11116
- timeStep
11117
- );
11118
- changedTask.end = changedTask.start;
11119
- break;
11120
- }
11121
- }
11122
- }
11123
- return { isChanged, changedTask };
11124
- };
11125
10927
  const GanttTodayInner = ({
11126
10928
  additionalLeftSpace,
11127
10929
  distances: { columnWidth },
@@ -11130,8 +10932,6 @@
11130
10932
  rtl,
11131
10933
  startDate,
11132
10934
  viewMode,
11133
- taskHeight,
11134
- // Add taskHeight parameter
11135
10935
  showTodayLine = true,
11136
10936
  showDataDateLine = false,
11137
10937
  dataDate = null,
@@ -11145,14 +10945,38 @@
11145
10945
  return null;
11146
10946
  }
11147
10947
  const today = /* @__PURE__ */ new Date();
11148
- const x = taskXCoordinate(today, startDate, viewMode, columnWidth);
11149
- const adjustedX = rtl ? x + columnWidth : x;
10948
+ const todayIndex = getDatesDiff(today, startDate, viewMode);
10949
+ const extraMultiplier = () => {
10950
+ switch (viewMode) {
10951
+ case ViewMode.Week: {
10952
+ const percent = today.getDay() / 7;
10953
+ return 1 + percent * 0.2;
10954
+ }
10955
+ case ViewMode.Month: {
10956
+ const dayInMonth = today.getDate();
10957
+ const maxDaysInMonth = getDaysInMonth(
10958
+ today.getMonth(),
10959
+ today.getFullYear()
10960
+ );
10961
+ const percent = dayInMonth / maxDaysInMonth;
10962
+ return 1 + percent * 0.5;
10963
+ }
10964
+ case ViewMode.Year: {
10965
+ const percent = today.getMonth() / 12;
10966
+ return 1 + percent * 0.5;
10967
+ }
10968
+ default:
10969
+ return 1;
10970
+ }
10971
+ };
10972
+ const tickX = todayIndex * columnWidth * extraMultiplier();
10973
+ const x = rtl ? tickX + columnWidth : tickX;
11150
10974
  const color = todayColor || "var(--gantt-calendar-today-color)";
11151
10975
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11152
10976
  /* @__PURE__ */ jsxRuntime.jsx(
11153
10977
  "rect",
11154
10978
  {
11155
- x: additionalLeftSpace + adjustedX,
10979
+ x: additionalLeftSpace + x,
11156
10980
  y: 0,
11157
10981
  width: 2,
11158
10982
  height: ganttFullHeight,
@@ -11163,7 +10987,7 @@
11163
10987
  "circle",
11164
10988
  {
11165
10989
  className: styles$c.ganttTodayCircle,
11166
- cx: adjustedX + 1,
10990
+ cx: x + 1,
11167
10991
  cy: 6,
11168
10992
  r: 6,
11169
10993
  fill: color
@@ -11172,7 +10996,7 @@
11172
10996
  /* @__PURE__ */ jsxRuntime.jsx(
11173
10997
  "text",
11174
10998
  {
11175
- x: additionalLeftSpace + adjustedX + 8,
10999
+ x: additionalLeftSpace + x + 8,
11176
11000
  y: 10,
11177
11001
  fill: color,
11178
11002
  fontSize: 12,
@@ -11197,16 +11021,38 @@
11197
11021
  if (!showDataDateLine || !dataDate) {
11198
11022
  return null;
11199
11023
  }
11200
- const index2 = getDatesDiff(dataDate, startDate, viewMode);
11201
- const intervalEndX = (index2 + 1) * columnWidth;
11202
- const milestoneEndX = intervalEndX + taskHeight * 0.5;
11203
- const adjustedX = rtl ? milestoneEndX + columnWidth : milestoneEndX;
11024
+ const dataIndex = getDatesDiff(dataDate, startDate, viewMode);
11025
+ const extraMultiplier = () => {
11026
+ switch (viewMode) {
11027
+ case ViewMode.Week: {
11028
+ const percent = dataDate.getDay() / 7;
11029
+ return 1 + percent * 0.2;
11030
+ }
11031
+ case ViewMode.Month: {
11032
+ const dayInMonth = dataDate.getDate();
11033
+ const maxDaysInMonth = getDaysInMonth(
11034
+ dataDate.getMonth(),
11035
+ dataDate.getFullYear()
11036
+ );
11037
+ const percent = dayInMonth / maxDaysInMonth;
11038
+ return 1 + percent * 0.5;
11039
+ }
11040
+ case ViewMode.Year: {
11041
+ const percent = dataDate.getMonth() / 12;
11042
+ return 1 + percent * 0.5;
11043
+ }
11044
+ default:
11045
+ return 1;
11046
+ }
11047
+ };
11048
+ const tickX = dataIndex * columnWidth * extraMultiplier();
11049
+ const x = rtl ? tickX + columnWidth : tickX;
11204
11050
  const color = dataDateColor || "var(--gantt-calendar-today-color)";
11205
11051
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11206
11052
  /* @__PURE__ */ jsxRuntime.jsx(
11207
11053
  "rect",
11208
11054
  {
11209
- x: additionalLeftSpace + adjustedX,
11055
+ x: additionalLeftSpace + x,
11210
11056
  y: 0,
11211
11057
  width: 2,
11212
11058
  height: ganttFullHeight,
@@ -11218,7 +11064,7 @@
11218
11064
  "circle",
11219
11065
  {
11220
11066
  className: styles$c.ganttTodayCircle,
11221
- cx: adjustedX + 1,
11067
+ cx: x + 1,
11222
11068
  cy: 6,
11223
11069
  r: 6,
11224
11070
  fill: color
@@ -11227,7 +11073,7 @@
11227
11073
  /* @__PURE__ */ jsxRuntime.jsx(
11228
11074
  "text",
11229
11075
  {
11230
- x: additionalLeftSpace + adjustedX + 8,
11076
+ x: additionalLeftSpace + x + 8,
11231
11077
  y: 10,
11232
11078
  fill: color,
11233
11079
  fontSize: 12,
@@ -11243,7 +11089,6 @@
11243
11089
  rtl,
11244
11090
  startDate,
11245
11091
  viewMode,
11246
- taskHeight,
11247
11092
  showDataDateLine,
11248
11093
  dataDate,
11249
11094
  dataDateColor,
@@ -11942,6 +11787,204 @@
11942
11787
  }
11943
11788
  );
11944
11789
  };
11790
+ const getDateByOffset = (startDate, offset2, viewMode) => {
11791
+ switch (viewMode) {
11792
+ case ViewMode.Day:
11793
+ return addDays(startDate, offset2);
11794
+ case ViewMode.HalfDay:
11795
+ return addHours(startDate, offset2 * 12);
11796
+ case ViewMode.QuarterDay:
11797
+ return addHours(startDate, offset2 * 6);
11798
+ case ViewMode.Hour:
11799
+ return addHours(startDate, offset2);
11800
+ case ViewMode.Month:
11801
+ return addMonths(startDate, offset2);
11802
+ case ViewMode.Week:
11803
+ return addWeeks(startDate, offset2);
11804
+ case ViewMode.Year:
11805
+ return addYears(startDate, offset2);
11806
+ default:
11807
+ throw new Error("Unknown view mode");
11808
+ }
11809
+ };
11810
+ const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11811
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11812
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11813
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11814
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11815
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11816
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11817
+ };
11818
+ const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11819
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11820
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11821
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11822
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11823
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11824
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11825
+ };
11826
+ const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
11827
+ const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
11828
+ let progressX;
11829
+ if (rtl) {
11830
+ progressX = taskX2 - progressWidth;
11831
+ } else {
11832
+ progressX = taskX1;
11833
+ }
11834
+ return [progressWidth, progressX];
11835
+ };
11836
+ const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
11837
+ let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
11838
+ newDate = new Date(
11839
+ newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
11840
+ );
11841
+ return newDate;
11842
+ };
11843
+ const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11844
+ let result;
11845
+ switch (selectedTask.type) {
11846
+ case "milestone":
11847
+ result = handleTaskBySVGMouseEventForMilestone(
11848
+ action,
11849
+ selectedTask,
11850
+ initialCoordinates,
11851
+ coordinates,
11852
+ xStep,
11853
+ timeStep
11854
+ );
11855
+ break;
11856
+ default:
11857
+ result = handleTaskBySVGMouseEventForBar(
11858
+ action,
11859
+ selectedTask,
11860
+ initialCoordinates,
11861
+ coordinates,
11862
+ xStep,
11863
+ timeStep,
11864
+ rtl
11865
+ );
11866
+ break;
11867
+ }
11868
+ return result;
11869
+ };
11870
+ const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11871
+ const changedTask = { ...selectedTask };
11872
+ let isChanged = false;
11873
+ switch (action) {
11874
+ case "progress":
11875
+ isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
11876
+ if (isChanged) {
11877
+ changedTask.progress = Math.round(
11878
+ coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11879
+ );
11880
+ }
11881
+ break;
11882
+ case "start": {
11883
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11884
+ if (isChanged) {
11885
+ if (rtl) {
11886
+ changedTask.end = dateByX(
11887
+ coordinates.x1,
11888
+ initialCoordinates.x1,
11889
+ selectedTask.end,
11890
+ xStep,
11891
+ timeStep
11892
+ );
11893
+ } else {
11894
+ changedTask.start = dateByX(
11895
+ coordinates.x1,
11896
+ initialCoordinates.x1,
11897
+ selectedTask.start,
11898
+ xStep,
11899
+ timeStep
11900
+ );
11901
+ }
11902
+ }
11903
+ break;
11904
+ }
11905
+ case "end": {
11906
+ isChanged = initialCoordinates.x2 !== coordinates.x2;
11907
+ if (isChanged) {
11908
+ if (rtl) {
11909
+ changedTask.start = dateByX(
11910
+ coordinates.x2,
11911
+ initialCoordinates.x2,
11912
+ selectedTask.start,
11913
+ xStep,
11914
+ timeStep
11915
+ );
11916
+ } else {
11917
+ changedTask.end = dateByX(
11918
+ coordinates.x2,
11919
+ initialCoordinates.x2,
11920
+ selectedTask.end,
11921
+ xStep,
11922
+ timeStep
11923
+ );
11924
+ }
11925
+ }
11926
+ break;
11927
+ }
11928
+ case "move": {
11929
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11930
+ if (isChanged) {
11931
+ if (rtl) {
11932
+ changedTask.end = dateByX(
11933
+ coordinates.x1,
11934
+ initialCoordinates.x1,
11935
+ selectedTask.end,
11936
+ xStep,
11937
+ timeStep
11938
+ );
11939
+ changedTask.start = dateByX(
11940
+ coordinates.x2,
11941
+ initialCoordinates.x2,
11942
+ selectedTask.start,
11943
+ xStep,
11944
+ timeStep
11945
+ );
11946
+ } else {
11947
+ changedTask.start = dateByX(
11948
+ coordinates.x1,
11949
+ initialCoordinates.x1,
11950
+ selectedTask.start,
11951
+ xStep,
11952
+ timeStep
11953
+ );
11954
+ changedTask.end = dateByX(
11955
+ coordinates.x2,
11956
+ initialCoordinates.x2,
11957
+ selectedTask.end,
11958
+ xStep,
11959
+ timeStep
11960
+ );
11961
+ }
11962
+ }
11963
+ break;
11964
+ }
11965
+ }
11966
+ return { isChanged, changedTask };
11967
+ };
11968
+ const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11969
+ const changedTask = { ...selectedTask };
11970
+ const isChanged = coordinates.x1 !== initialCoordinates.x1;
11971
+ if (isChanged) {
11972
+ switch (action) {
11973
+ case "move": {
11974
+ changedTask.start = dateByX(
11975
+ coordinates.x1,
11976
+ initialCoordinates.x1,
11977
+ selectedTask.start,
11978
+ xStep,
11979
+ timeStep
11980
+ );
11981
+ changedTask.end = changedTask.start;
11982
+ break;
11983
+ }
11984
+ }
11985
+ }
11986
+ return { isChanged, changedTask };
11987
+ };
11945
11988
  const barWrapper = "_barWrapper_5jhkr_1";
11946
11989
  const barHandle = "_barHandle_5jhkr_11";
11947
11990
  const barHandleImportantVisible = "_barHandleImportantVisible_5jhkr_37";
@@ -12757,6 +12800,9 @@
12757
12800
  ]);
12758
12801
  const onMouseDown = React.useCallback(
12759
12802
  (event) => {
12803
+ if (event.button !== 0) {
12804
+ return;
12805
+ }
12760
12806
  event.stopPropagation();
12761
12807
  onSelectTaskOnMouseDown(task.id, event);
12762
12808
  },
@@ -13298,7 +13344,9 @@
13298
13344
  isDateChangeable,
13299
13345
  isRelationChangeable,
13300
13346
  visibleTasksMirror,
13301
- onArrowDoubleClick
13347
+ onArrowDoubleClick,
13348
+ showProgress,
13349
+ progressColor
13302
13350
  ]);
13303
13351
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "content", children: [
13304
13352
  renderedSelectedTasks,
@@ -13360,7 +13408,8 @@
13360
13408
  horizontalContainerRef,
13361
13409
  onVerticalScrollbarScrollX,
13362
13410
  verticalGanttContainerRef,
13363
- verticalScrollbarRef
13411
+ verticalScrollbarRef,
13412
+ onOpenGanttContextMenu
13364
13413
  } = props;
13365
13414
  const contentRef = React.useRef(null);
13366
13415
  const moveStateVertRef = React.useRef(null);
@@ -13498,6 +13547,12 @@
13498
13547
  height: ganttFullHeight,
13499
13548
  fontFamily: "var(--gantt-font-family)",
13500
13549
  ref: ganttSVGRef,
13550
+ onContextMenu: (event) => {
13551
+ event.preventDefault();
13552
+ if (onOpenGanttContextMenu) {
13553
+ onOpenGanttContextMenu(event.clientX, event.clientY);
13554
+ }
13555
+ },
13501
13556
  children: [
13502
13557
  /* @__PURE__ */ jsxRuntime.jsx(GanttToday, { ...ganttTodayProps }),
13503
13558
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -17697,9 +17752,13 @@
17697
17752
  toggleTask(taskId);
17698
17753
  return;
17699
17754
  }
17700
- selectTask(taskId);
17755
+ if (selectedIdsMirror[taskId]) {
17756
+ toggleTask(taskId);
17757
+ } else {
17758
+ selectTask(taskId);
17759
+ }
17701
17760
  },
17702
- [selectTask, selectTasksFromLastSelected, toggleTask]
17761
+ [selectTask, selectTasksFromLastSelected, toggleTask, selectedIdsMirror]
17703
17762
  );
17704
17763
  const cutTask = React.useCallback((task) => {
17705
17764
  setCutIdsMirror({
@@ -17729,7 +17788,9 @@
17729
17788
  );
17730
17789
  React.useEffect(() => {
17731
17790
  if (onSelectTaskIds) {
17732
- const selectedTaskIds = Object.keys(selectedIdsMirror).filter((x) => selectedIdsMirror[x]);
17791
+ const selectedTaskIds = Object.keys(selectedIdsMirror).filter(
17792
+ (x) => selectedIdsMirror[x]
17793
+ );
17733
17794
  onSelectTaskIds(selectedTaskIds);
17734
17795
  }
17735
17796
  }, [onSelectTaskIds, selectedIdsMirror]);
@@ -17932,9 +17993,16 @@
17932
17993
  }
17933
17994
  const { top, left } = wrapperNode.getBoundingClientRect();
17934
17995
  setContextMenu({
17935
- task,
17936
- x: clientX - left,
17937
- y: clientY - top
17996
+ task: null,
17997
+ x: 0,
17998
+ y: 0
17999
+ });
18000
+ requestAnimationFrame(() => {
18001
+ setContextMenu({
18002
+ task,
18003
+ x: clientX - left,
18004
+ y: clientY - top
18005
+ });
17938
18006
  });
17939
18007
  if (task.type !== "empty") {
17940
18008
  scrollToTask(task);
@@ -18074,7 +18142,12 @@
18074
18142
  }
18075
18143
  }, [context, task, x, y]);
18076
18144
  const focus = useFocus(context);
18077
- const dismiss = useDismiss(context);
18145
+ const dismiss = useDismiss(context, {
18146
+ outsidePress: true,
18147
+ outsidePressEvent: "mousedown",
18148
+ ancestorScroll: true,
18149
+ escapeKey: true
18150
+ });
18078
18151
  const role = useRole(context, { role: "tooltip" });
18079
18152
  const { getReferenceProps, getFloatingProps } = useInteractions([
18080
18153
  focus,
@@ -19051,6 +19124,34 @@
19051
19124
  [mapTaskToCoordinates, setScrollXProgrammatically]
19052
19125
  );
19053
19126
  const { contextMenu, handleCloseContextMenu, handleOpenContextMenu } = useContextMenu(wrapperRef, scrollToTask);
19127
+ const [ganttContextMenu, setGanttContextMenu] = React.useState({
19128
+ task: null,
19129
+ x: 0,
19130
+ y: 0
19131
+ });
19132
+ const handleOpenGanttContextMenu = React.useCallback(
19133
+ (task, clientX, clientY) => {
19134
+ const wrapperNode = wrapperRef.current;
19135
+ if (!wrapperNode) {
19136
+ return;
19137
+ }
19138
+ const { top, left } = wrapperNode.getBoundingClientRect();
19139
+ setGanttContextMenu({
19140
+ task: task || { id: "__gantt_area__", type: "empty" },
19141
+ // Use a dummy task for gantt area
19142
+ x: clientX - left,
19143
+ y: clientY - top
19144
+ });
19145
+ },
19146
+ [wrapperRef]
19147
+ );
19148
+ const handleCloseGanttContextMenu = React.useCallback(() => {
19149
+ setGanttContextMenu({
19150
+ task: null,
19151
+ x: 0,
19152
+ y: 0
19153
+ });
19154
+ }, []);
19054
19155
  const [dependencyMap, dependentMap, dependencyMarginsMap] = React.useMemo(
19055
19156
  () => getDependencyMap(
19056
19157
  sortedTasks,
@@ -19839,6 +19940,12 @@
19839
19940
  createDeleteOption(locale)
19840
19941
  ];
19841
19942
  }, [taskList.contextMenuOptions, locale]);
19943
+ const ganttContextMenuOptions = React.useMemo(() => {
19944
+ if (taskBar.taskGanttContextMenuOption) {
19945
+ return taskBar.taskGanttContextMenuOption;
19946
+ }
19947
+ return [createPasteOption(locale)];
19948
+ }, [taskBar.taskGanttContextMenuOption, locale]);
19842
19949
  const tooltipTaskFromMap = React.useMemo(() => {
19843
19950
  if (!tooltipTask) {
19844
19951
  return null;
@@ -19882,7 +19989,6 @@
19882
19989
  rtl,
19883
19990
  startDate,
19884
19991
  viewMode,
19885
- taskHeight,
19886
19992
  showTodayLine,
19887
19993
  showDataDateLine,
19888
19994
  dataDate,
@@ -19899,7 +20005,6 @@
19899
20005
  rtl,
19900
20006
  startDate,
19901
20007
  viewMode,
19902
- taskHeight,
19903
20008
  showTodayLine,
19904
20009
  showDataDateLine,
19905
20010
  dataDate,
@@ -20109,7 +20214,10 @@
20109
20214
  horizontalContainerRef,
20110
20215
  verticalScrollbarRef,
20111
20216
  onVerticalScrollbarScrollX,
20112
- verticalGanttContainerRef
20217
+ verticalGanttContainerRef,
20218
+ onOpenGanttContextMenu: (clientX, clientY) => {
20219
+ handleOpenGanttContextMenu(null, clientX, clientY);
20220
+ }
20113
20221
  }
20114
20222
  ),
20115
20223
  tooltipTaskFromMap && /* @__PURE__ */ jsxRuntime.jsx(
@@ -20148,6 +20256,18 @@
20148
20256
  options: contextMenuOptions
20149
20257
  }
20150
20258
  ),
20259
+ ganttContextMenu.task && !waitCommitTasks && /* @__PURE__ */ jsxRuntime.jsx(
20260
+ ContextMenu,
20261
+ {
20262
+ checkHasCopyTasks,
20263
+ checkHasCutTasks,
20264
+ contextMenu: ganttContextMenu,
20265
+ distances,
20266
+ handleAction,
20267
+ handleCloseContextMenu: handleCloseGanttContextMenu,
20268
+ options: ganttContextMenuOptions
20269
+ }
20270
+ ),
20151
20271
  /* @__PURE__ */ jsxRuntime.jsx(GanttLoader, { loading: waitCommitTasks })
20152
20272
  ]
20153
20273
  }