gantt-lib 0.90.0 → 0.91.0

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.
package/dist/index.mjs CHANGED
@@ -3807,7 +3807,8 @@ var DatePicker = ({
3807
3807
  className,
3808
3808
  disabled = false,
3809
3809
  isWeekend: isWeekend3,
3810
- businessDays = true
3810
+ businessDays = true,
3811
+ footer
3811
3812
  }) => {
3812
3813
  const [open, setOpen] = useState3(false);
3813
3814
  const [inputValue, setInputValue] = useState3("");
@@ -4085,7 +4086,8 @@ var DatePicker = ({
4085
4086
  initialDate: activeDate,
4086
4087
  isWeekend: isWeekend3
4087
4088
  }
4088
- )
4089
+ ),
4090
+ footer ? /* @__PURE__ */ jsx10("div", { className: "gantt-datepicker-footer", children: footer }) : null
4089
4091
  ]
4090
4092
  }
4091
4093
  )
@@ -4727,7 +4729,9 @@ var TaskListRow = React9.memo(
4727
4729
  resolvedColumns,
4728
4730
  isTaskSelected = false,
4729
4731
  onTaskSelectionChange,
4730
- taskListMenuCommands = []
4732
+ taskListMenuCommands = [],
4733
+ taskDateChangeMode = "preserve-duration",
4734
+ onTaskDateChangeModeChange
4731
4735
  }) => {
4732
4736
  const [editingColumnId, setEditingColumnId] = useState4(null);
4733
4737
  const editingName = editingColumnId === "name";
@@ -5130,24 +5134,22 @@ var TaskListRow = React9.memo(
5130
5134
  emitMilestoneDateChange(newDateISO);
5131
5135
  return;
5132
5136
  }
5133
- let nextEndISO;
5134
5137
  const normalizedInputStart = businessDays ? alignToWorkingDay(/* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`), 1, weekendPredicate) : /* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`);
5135
- if (businessDays) {
5136
- const duration = getDuration(task.startDate, task.endDate);
5137
- nextEndISO = buildTaskRangeFromStart(
5138
+ const { startDate: normalizedStart, endDate: normalizedEnd } = taskDateChangeMode === "free" ? normalizeTaskDates(
5139
+ normalizedInputStart,
5140
+ normalizedInputStart.getTime() > parseUTCDate(task.endDate).getTime() ? normalizedInputStart : parseUTCDate(task.endDate)
5141
+ ) : normalizeTaskDates(
5142
+ normalizedInputStart,
5143
+ businessDays ? buildTaskRangeFromStart(
5138
5144
  normalizedInputStart,
5139
- duration,
5145
+ getDuration(task.startDate, task.endDate),
5140
5146
  true,
5141
5147
  weekendPredicate,
5142
5148
  1
5143
- ).end.toISOString().split("T")[0];
5144
- } else {
5145
- const origStart = parseUTCDate(task.startDate);
5146
- const origEnd = parseUTCDate(task.endDate);
5147
- const durationMs = origEnd.getTime() - origStart.getTime();
5148
- nextEndISO = new Date(normalizedInputStart.getTime() + durationMs).toISOString().split("T")[0];
5149
- }
5150
- const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(normalizedInputStart, nextEndISO);
5149
+ ).end.toISOString().split("T")[0] : new Date(
5150
+ normalizedInputStart.getTime() + (parseUTCDate(task.endDate).getTime() - parseUTCDate(task.startDate).getTime())
5151
+ ).toISOString().split("T")[0]
5152
+ );
5151
5153
  const clampedRange = clampTaskRangeForIncomingFS(
5152
5154
  task,
5153
5155
  /* @__PURE__ */ new Date(`${normalizedStart}T00:00:00.000Z`),
@@ -5176,7 +5178,7 @@ var TaskListRow = React9.memo(
5176
5178
  }
5177
5179
  ]);
5178
5180
  },
5179
- [task, onTasksChange, businessDays, getDuration, getEndDate, allTasks, weekendPredicate, isMilestone, emitMilestoneDateChange]
5181
+ [task, onTasksChange, businessDays, getDuration, allTasks, weekendPredicate, isMilestone, emitMilestoneDateChange, taskDateChangeMode]
5180
5182
  );
5181
5183
  const handleEndDateChange = useCallback4(
5182
5184
  (newDateISO) => {
@@ -5185,24 +5187,22 @@ var TaskListRow = React9.memo(
5185
5187
  emitMilestoneDateChange(newDateISO);
5186
5188
  return;
5187
5189
  }
5188
- let nextStartISO;
5189
5190
  const normalizedInputEnd = businessDays ? alignToWorkingDay(/* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`), -1, weekendPredicate) : /* @__PURE__ */ new Date(`${newDateISO}T00:00:00.000Z`);
5190
- if (businessDays) {
5191
- const duration = getDuration(task.startDate, task.endDate);
5192
- nextStartISO = buildTaskRangeFromEnd(
5191
+ const { startDate: normalizedStart, endDate: normalizedEnd } = taskDateChangeMode === "free" ? normalizeTaskDates(
5192
+ normalizedInputEnd.getTime() < parseUTCDate(task.startDate).getTime() ? normalizedInputEnd : parseUTCDate(task.startDate),
5193
+ normalizedInputEnd
5194
+ ) : normalizeTaskDates(
5195
+ businessDays ? buildTaskRangeFromEnd(
5193
5196
  normalizedInputEnd,
5194
- duration,
5197
+ getDuration(task.startDate, task.endDate),
5195
5198
  true,
5196
5199
  weekendPredicate,
5197
5200
  -1
5198
- ).start.toISOString().split("T")[0];
5199
- } else {
5200
- const origStart = parseUTCDate(task.startDate);
5201
- const origEnd = parseUTCDate(task.endDate);
5202
- const durationMs = origEnd.getTime() - origStart.getTime();
5203
- nextStartISO = new Date(normalizedInputEnd.getTime() - durationMs).toISOString().split("T")[0];
5204
- }
5205
- const { startDate: normalizedStart, endDate: normalizedEnd } = normalizeTaskDates(nextStartISO, normalizedInputEnd);
5201
+ ).start.toISOString().split("T")[0] : new Date(
5202
+ normalizedInputEnd.getTime() - (parseUTCDate(task.endDate).getTime() - parseUTCDate(task.startDate).getTime())
5203
+ ).toISOString().split("T")[0],
5204
+ normalizedInputEnd
5205
+ );
5206
5206
  const clampedRange = clampTaskRangeForIncomingFS(
5207
5207
  task,
5208
5208
  /* @__PURE__ */ new Date(`${normalizedStart}T00:00:00.000Z`),
@@ -5231,8 +5231,19 @@ var TaskListRow = React9.memo(
5231
5231
  }
5232
5232
  ]);
5233
5233
  },
5234
- [task, onTasksChange, businessDays, getDuration, weekendPredicate, allTasks, isMilestone, emitMilestoneDateChange]
5234
+ [task, onTasksChange, businessDays, getDuration, weekendPredicate, allTasks, isMilestone, emitMilestoneDateChange, taskDateChangeMode]
5235
5235
  );
5236
+ const datePickerFooter = onTaskDateChangeModeChange ? /* @__PURE__ */ jsxs9("label", { className: "gantt-datepicker-mode-checkbox", children: [
5237
+ /* @__PURE__ */ jsx12(
5238
+ "input",
5239
+ {
5240
+ type: "checkbox",
5241
+ checked: taskDateChangeMode === "preserve-duration",
5242
+ onChange: (event) => onTaskDateChangeModeChange(event.target.checked ? "preserve-duration" : "free")
5243
+ }
5244
+ ),
5245
+ /* @__PURE__ */ jsx12("span", { children: "\u0421\u043E\u0445\u0440\u0430\u043D\u044F\u0442\u044C \u0434\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C" })
5246
+ ] }) : null;
5236
5247
  const handleRowClickInternal = useCallback4(() => {
5237
5248
  onRowClick?.(task.id);
5238
5249
  }, [task.id, onRowClick]);
@@ -5931,7 +5942,8 @@ var TaskListRow = React9.memo(
5931
5942
  portal: true,
5932
5943
  disabled: task.locked,
5933
5944
  isWeekend: weekendPredicate,
5934
- businessDays
5945
+ businessDays,
5946
+ footer: datePickerFooter
5935
5947
  }
5936
5948
  )
5937
5949
  }
@@ -5950,7 +5962,8 @@ var TaskListRow = React9.memo(
5950
5962
  portal: true,
5951
5963
  disabled: task.locked,
5952
5964
  isWeekend: weekendPredicate,
5953
- businessDays
5965
+ businessDays,
5966
+ footer: datePickerFooter
5954
5967
  }
5955
5968
  )
5956
5969
  }
@@ -6630,7 +6643,9 @@ var TaskList = ({
6630
6643
  isFilterActive = false,
6631
6644
  additionalColumns,
6632
6645
  hiddenTaskListColumns,
6633
- taskListMenuCommands
6646
+ taskListMenuCommands,
6647
+ taskDateChangeMode = "preserve-duration",
6648
+ onTaskDateChangeModeChange
6634
6649
  }) => {
6635
6650
  const [internalSelectedTaskIds, setInternalSelectedTaskIds] = useState6(/* @__PURE__ */ new Set());
6636
6651
  const effectiveSelectedTaskIds = selectedTaskIds ?? internalSelectedTaskIds;
@@ -7366,7 +7381,9 @@ var TaskList = ({
7366
7381
  resolvedColumns,
7367
7382
  isTaskSelected: effectiveSelectedTaskIds.has(task.id),
7368
7383
  onTaskSelectionChange: handleToggleTaskSelection,
7369
- taskListMenuCommands
7384
+ taskListMenuCommands,
7385
+ taskDateChangeMode,
7386
+ onTaskDateChangeModeChange
7370
7387
  }
7371
7388
  ),
7372
7389
  pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ jsx14(
@@ -9498,7 +9515,9 @@ function TaskGanttChartInner(props, ref) {
9498
9515
  showChart = true,
9499
9516
  additionalColumns,
9500
9517
  hiddenTaskListColumns,
9501
- taskListMenuCommands
9518
+ taskListMenuCommands,
9519
+ taskDateChangeMode: externalTaskDateChangeMode,
9520
+ onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange
9502
9521
  } = props;
9503
9522
  const containerRef = useRef9(null);
9504
9523
  const scrollContainerRef = useRef9(null);
@@ -9506,10 +9525,13 @@ function TaskGanttChartInner(props, ref) {
9506
9525
  const clearSelectedTaskTimeoutRef = useRef9(null);
9507
9526
  const [selectedTaskId, setSelectedTaskId] = useState9(null);
9508
9527
  const [taskListHasRightShadow, setTaskListHasRightShadow] = useState9(false);
9528
+ const [internalTaskDateChangeMode, setInternalTaskDateChangeMode] = useState9("preserve-duration");
9509
9529
  const [selectedChip, setSelectedChip] = useState9(null);
9510
9530
  const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState9(/* @__PURE__ */ new Set());
9511
9531
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
9512
9532
  const [editingTaskId, setEditingTaskId] = useState9(null);
9533
+ const taskDateChangeMode = externalTaskDateChangeMode ?? internalTaskDateChangeMode;
9534
+ const handleTaskDateChangeMode = externalOnTaskDateChangeModeChange ?? setInternalTaskDateChangeMode;
9513
9535
  const normalizedTasks = useMemo10(() => normalizeHierarchyTasks(tasks), [tasks]);
9514
9536
  const isCustomWeekend = useMemo10(
9515
9537
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
@@ -10106,7 +10128,9 @@ function TaskGanttChartInner(props, ref) {
10106
10128
  isFilterActive: !!taskFilter,
10107
10129
  additionalColumns,
10108
10130
  hiddenTaskListColumns,
10109
- taskListMenuCommands
10131
+ taskListMenuCommands,
10132
+ taskDateChangeMode,
10133
+ onTaskDateChangeModeChange: handleTaskDateChangeMode
10110
10134
  }
10111
10135
  ),
10112
10136
  /* @__PURE__ */ jsxs13(