gantt-lib 0.61.0 → 0.63.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.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import React$1, { ReactNode } from 'react';
2
- import { T as Task$1, V as ValidationResult } from './index-BlUshzVg.js';
3
- export { D as DAY_MS, a as DependencyError, G as GanttDateRange, b as GridConfig, c as GridLine, L as LinkType, M as MonthSpan, d as TaskBarGeometry, W as WeekendBlock, e as alignToWorkingDay, f as areTasksHierarchicallyRelated, g as buildAdjacencyList, h as buildTaskRangeFromEnd, i as buildTaskRangeFromStart, j as calculateSuccessorDate, k as cascadeByLinks, l as clampDateRangeForIncomingFS, m as clampTaskRangeForIncomingFS, n as computeLagFromDates, o as computeParentDates, p as computeParentProgress, q as detectCycles, r as findParentId, s as getAllDependencyEdges, t as getAllDescendants, u as getBusinessDayOffset, v as getChildren, w as getDependencyLag, x as getSuccessorChain, y as getTaskDuration, z as getTransitiveCascadeChain, A as isAncestorTask, B as isTaskParent, C as moveTaskRange, E as moveTaskWithCascade, F as normalizeDependencyLag, H as normalizeUTCDate, I as parseDateOnly, J as recalculateIncomingLags, K as recalculateProjectSchedule, N as recalculateTaskFromDependencies, O as reflowTasksOnModeSwitch, P as removeDependenciesBetweenTasks, Q as resizeTaskWithCascade, R as resolveDateRangeFromPixels, S as shiftBusinessDayOffset, U as universalCascade, X as validateDependencies } from './index-BlUshzVg.js';
2
+ import { T as Task$1, V as ValidationResult } from './index-DMA7NbWe.js';
3
+ export { D as DAY_MS, a as DependencyError, G as GanttDateRange, b as GridConfig, c as GridLine, L as LinkType, M as MonthSpan, d as TaskBarGeometry, W as WeekendBlock, e as alignToWorkingDay, f as areTasksHierarchicallyRelated, g as buildAdjacencyList, h as buildTaskRangeFromEnd, i as buildTaskRangeFromStart, j as calculateSuccessorDate, k as cascadeByLinks, l as clampTaskRangeForIncomingFS, m as computeLagFromDates, n as computeParentDates, o as computeParentProgress, p as detectCycles, q as findParentId, r as getAllDependencyEdges, s as getAllDescendants, t as getBusinessDayOffset, u as getChildren, v as getDependencyLag, w as getSuccessorChain, x as getTaskDuration, y as getTransitiveCascadeChain, z as isAncestorTask, A as isTaskParent, B as moveTaskRange, C as moveTaskWithCascade, E as normalizeDependencyLag, F as normalizeUTCDate, H as parseDateOnly, I as recalculateIncomingLags, J as recalculateProjectSchedule, K as recalculateTaskFromDependencies, N as reflowTasksOnModeSwitch, O as removeDependenciesBetweenTasks, P as resizeTaskWithCascade, Q as shiftBusinessDayOffset, R as universalCascade, S as validateDependencies } from './index-DMA7NbWe.js';
4
4
  import * as RadixPopover from '@radix-ui/react-popover';
5
5
 
6
6
  /**
@@ -863,6 +863,40 @@ interface UseTaskDragReturn {
863
863
  */
864
864
  declare const useTaskDrag: (options: UseTaskDragOptions) => UseTaskDragReturn;
865
865
 
866
+ /**
867
+ * UI adapter: converts pixel coordinates to date ranges for drag interactions.
868
+ * @module adapters/scheduling
869
+ *
870
+ * These functions bridge the chart's pixel-space (left, width, dayWidth)
871
+ * with the scheduling domain's date-space. They depend on core scheduling
872
+ * primitives but are NOT part of the domain core themselves.
873
+ */
874
+
875
+ /**
876
+ * Convert pixel coordinates to a date range, applying business-day alignment
877
+ * when businessDays mode is active. This is the pure scheduling core of
878
+ * drag-to-date conversion.
879
+ *
880
+ * Extracted from useTaskDrag.ts resolveDraggedRange.
881
+ */
882
+ declare function resolveDateRangeFromPixels(mode: 'move' | 'resize-left' | 'resize-right', left: number, width: number, monthStart: Date, dayWidth: number, task: Task$1, businessDays?: boolean, weekendPredicate?: (date: Date) => boolean): {
883
+ start: Date;
884
+ end: Date;
885
+ };
886
+ /**
887
+ * Clamp a proposed date range based on incoming FS dependencies.
888
+ * For resize-right mode, returns range unchanged (only start is clamped).
889
+ *
890
+ * Extracted from useTaskDrag.ts clampDraggedRangeForIncomingFS.
891
+ */
892
+ declare function clampDateRangeForIncomingFS(task: Task$1, range: {
893
+ start: Date;
894
+ end: Date;
895
+ }, allTasks: Task$1[], mode: 'move' | 'resize-left' | 'resize-right', businessDays?: boolean, weekendPredicate?: (date: Date) => boolean): {
896
+ start: Date;
897
+ end: Date;
898
+ };
899
+
866
900
  /**
867
901
  * Checks whether a task is behind the expected progress for the current date.
868
902
  * Uses the same progress-based rule as expired task highlighting in TaskRow.
@@ -1051,4 +1085,4 @@ interface VisibleReorderPosition {
1051
1085
  */
1052
1086
  declare function getVisibleReorderPosition(orderedTasks: TaskLike[], visibleTasks: TaskLike[], movedTaskId: string, originVisibleIndex: number, dropVisibleIndex: number): VisibleReorderPosition | null;
1053
1087
 
1054
- export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, GridBackground, Input, type InputProps, type MonthBlock, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TodayIndicator, ValidationResult, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, subtractBusinessDays, useTaskDrag, withoutDeps };
1088
+ export { type BuiltInTaskListColumnId, Button, type ButtonProps, Calendar, type CalendarProps, type CustomDayConfig, type CustomDayPredicateConfig, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, GridBackground, Input, type InputProps, type MonthBlock, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskDependency, TaskList, type TaskListColumn, type TaskListColumnContext, type TaskListProps, type TaskPredicate, TaskRow, TimeScaleHeader, TodayIndicator, ValidationResult, type VisibleReorderPosition, type WeekBlock, type WeekSpan, type YearSpan, addBusinessDays, and, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateMonthGridLines, calculateOrthogonalPath, calculateTaskBar, calculateWeekGridLines, calculateWeekendBlocks, clampDateRangeForIncomingFS, createCustomDayPredicate, createDateKey, detectEdgeZone, expired, flattenHierarchy, formatDateLabel, formatDateRangeLabel, getBusinessDaysCount, getCursorForPosition, getDayOffset, getMonthBlocks, getMonthDays, getMonthSpans, getMultiMonthDays, getVisibleReorderPosition, getWeekBlocks, getWeekSpans, getYearSpans, inDateRange, isTaskExpired, isToday, isWeekend, nameContains, normalizeHierarchyTasks, normalizeTaskDates, not, or, parseUTCDate, pixelsToDate, progressInRange, resolveDateRangeFromPixels, subtractBusinessDays, useTaskDrag, withoutDeps };
package/dist/index.js CHANGED
@@ -1662,65 +1662,6 @@ function validateDependencies(tasks) {
1662
1662
  };
1663
1663
  }
1664
1664
 
1665
- // src/adapters/scheduling/drag.ts
1666
- init_dateMath();
1667
- function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
1668
- const dayOffset = Math.round(left / dayWidth);
1669
- const rawStartDate = new Date(Date.UTC(
1670
- monthStart.getUTCFullYear(),
1671
- monthStart.getUTCMonth(),
1672
- monthStart.getUTCDate() + dayOffset
1673
- ));
1674
- const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
1675
- const rawEndDate = new Date(Date.UTC(
1676
- monthStart.getUTCFullYear(),
1677
- monthStart.getUTCMonth(),
1678
- monthStart.getUTCDate() + rawEndOffset
1679
- ));
1680
- if (!(businessDays && weekendPredicate)) {
1681
- return { start: rawStartDate, end: rawEndDate };
1682
- }
1683
- if (mode === "move") {
1684
- const originalStart2 = new Date(task.startDate);
1685
- const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
1686
- return moveTaskRange(
1687
- task.startDate,
1688
- task.endDate,
1689
- rawStartDate,
1690
- true,
1691
- weekendPredicate,
1692
- snapDirection2
1693
- );
1694
- }
1695
- if (mode === "resize-right") {
1696
- const fixedStart = new Date(task.startDate);
1697
- const originalEnd = new Date(task.endDate);
1698
- const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
1699
- const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
1700
- const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
1701
- return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
1702
- }
1703
- const fixedEnd = new Date(task.endDate);
1704
- const originalStart = new Date(task.startDate);
1705
- const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
1706
- const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
1707
- const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
1708
- return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
1709
- }
1710
- function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
1711
- if (mode === "resize-right") {
1712
- return range;
1713
- }
1714
- return clampTaskRangeForIncomingFS(
1715
- task,
1716
- range.start,
1717
- range.end,
1718
- allTasks,
1719
- businessDays,
1720
- weekendPredicate
1721
- );
1722
- }
1723
-
1724
1665
  // src/utils/hierarchyOrder.ts
1725
1666
  init_dateUtils();
1726
1667
  function flattenHierarchy(tasks) {
@@ -2202,6 +2143,67 @@ var isTaskExpired = (task, referenceDate = /* @__PURE__ */ new Date()) => {
2202
2143
 
2203
2144
  // src/hooks/useTaskDrag.ts
2204
2145
  var import_react2 = require("react");
2146
+
2147
+ // src/adapters/scheduling/drag.ts
2148
+ init_dateMath();
2149
+ function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
2150
+ const dayOffset = Math.round(left / dayWidth);
2151
+ const rawStartDate = new Date(Date.UTC(
2152
+ monthStart.getUTCFullYear(),
2153
+ monthStart.getUTCMonth(),
2154
+ monthStart.getUTCDate() + dayOffset
2155
+ ));
2156
+ const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
2157
+ const rawEndDate = new Date(Date.UTC(
2158
+ monthStart.getUTCFullYear(),
2159
+ monthStart.getUTCMonth(),
2160
+ monthStart.getUTCDate() + rawEndOffset
2161
+ ));
2162
+ if (!(businessDays && weekendPredicate)) {
2163
+ return { start: rawStartDate, end: rawEndDate };
2164
+ }
2165
+ if (mode === "move") {
2166
+ const originalStart2 = new Date(task.startDate);
2167
+ const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
2168
+ return moveTaskRange(
2169
+ task.startDate,
2170
+ task.endDate,
2171
+ rawStartDate,
2172
+ true,
2173
+ weekendPredicate,
2174
+ snapDirection2
2175
+ );
2176
+ }
2177
+ if (mode === "resize-right") {
2178
+ const fixedStart = new Date(task.startDate);
2179
+ const originalEnd = new Date(task.endDate);
2180
+ const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
2181
+ const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
2182
+ const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
2183
+ return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
2184
+ }
2185
+ const fixedEnd = new Date(task.endDate);
2186
+ const originalStart = new Date(task.startDate);
2187
+ const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
2188
+ const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
2189
+ const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
2190
+ return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
2191
+ }
2192
+ function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
2193
+ if (mode === "resize-right") {
2194
+ return range;
2195
+ }
2196
+ return clampTaskRangeForIncomingFS(
2197
+ task,
2198
+ range.start,
2199
+ range.end,
2200
+ allTasks,
2201
+ businessDays,
2202
+ weekendPredicate
2203
+ );
2204
+ }
2205
+
2206
+ // src/hooks/useTaskDrag.ts
2205
2207
  var globalActiveDrag = null;
2206
2208
  var globalRafId = null;
2207
2209
  function getDayOffsetFromMonthStart(date, monthStart) {
@@ -5431,7 +5433,8 @@ var TaskListRow = import_react10.default.memo(
5431
5433
  id: crypto.randomUUID(),
5432
5434
  name: "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430",
5433
5435
  startDate: todayISO,
5434
- endDate: endISO
5436
+ endDate: endISO,
5437
+ parentId: task.parentId
5435
5438
  };
5436
5439
  onInsertAfter(task.id, newTask);
5437
5440
  },
@@ -5999,10 +6002,17 @@ TaskListRow.displayName = "TaskListRow";
5999
6002
  // src/components/TaskList/NewTaskRow.tsx
6000
6003
  var import_react11 = require("react");
6001
6004
  var import_jsx_runtime13 = require("react/jsx-runtime");
6002
- var NewTaskRow = ({ rowHeight, onConfirm, onCancel }) => {
6005
+ var NewTaskRow = ({
6006
+ rowHeight,
6007
+ onConfirm,
6008
+ onCancel,
6009
+ nestingDepth = 0
6010
+ }) => {
6003
6011
  const [nameValue, setNameValue] = (0, import_react11.useState)("");
6004
6012
  const inputRef = (0, import_react11.useRef)(null);
6005
6013
  const confirmedRef = (0, import_react11.useRef)(false);
6014
+ const inputInnerPadding = 4;
6015
+ const levelOffset = nestingDepth > 0 ? nestingDepth * 20 + 8 : 0;
6006
6016
  (0, import_react11.useEffect)(() => {
6007
6017
  if (inputRef.current) {
6008
6018
  inputRef.current.focus();
@@ -6041,7 +6051,12 @@ var NewTaskRow = ({ rowHeight, onConfirm, onCancel }) => {
6041
6051
  onKeyDown: handleKeyDown,
6042
6052
  onBlur: handleBlur,
6043
6053
  placeholder: "\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435",
6044
- className: "gantt-tl-name-input"
6054
+ className: "gantt-tl-name-input",
6055
+ style: {
6056
+ left: `${Math.max(0, levelOffset - inputInnerPadding)}px`,
6057
+ width: levelOffset > 0 ? `calc(100% - ${Math.max(0, levelOffset - inputInnerPadding)}px)` : "100%",
6058
+ paddingLeft: `${inputInnerPadding}px`
6059
+ }
6045
6060
  }
6046
6061
  ) }),
6047
6062
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "gantt-tl-cell" }),
@@ -6465,6 +6480,7 @@ var TaskList = ({
6465
6480
  onTasksChange?.([{ ...task, dependencies: updatedDeps }]);
6466
6481
  }, [tasks, onTasksChange]);
6467
6482
  const [isCreating, setIsCreating] = (0, import_react12.useState)(false);
6483
+ const [pendingInsert, setPendingInsert] = (0, import_react12.useState)(null);
6468
6484
  const [draggingIndex, setDraggingIndex] = (0, import_react12.useState)(null);
6469
6485
  const [dragOverIndex, setDragOverIndex] = (0, import_react12.useState)(null);
6470
6486
  const dragOriginIndexRef = (0, import_react12.useRef)(null);
@@ -6623,6 +6639,81 @@ var TaskList = ({
6623
6639
  setIsCreating(false);
6624
6640
  }, [onAdd]);
6625
6641
  const handleCancelNewTask = (0, import_react12.useCallback)(() => setIsCreating(false), []);
6642
+ const findInsertAfterTaskId = (0, import_react12.useCallback)((anchorTaskId) => {
6643
+ const anchorIndex = orderedTasks.findIndex((task) => task.id === anchorTaskId);
6644
+ if (anchorIndex === -1) {
6645
+ return anchorTaskId;
6646
+ }
6647
+ const taskById = new Map(orderedTasks.map((task) => [task.id, task]));
6648
+ let insertAfterTaskId = anchorTaskId;
6649
+ for (let index = anchorIndex + 1; index < orderedTasks.length; index += 1) {
6650
+ let currentParentId = orderedTasks[index]?.parentId;
6651
+ let isDescendant = false;
6652
+ while (currentParentId) {
6653
+ if (currentParentId === anchorTaskId) {
6654
+ isDescendant = true;
6655
+ break;
6656
+ }
6657
+ currentParentId = taskById.get(currentParentId)?.parentId;
6658
+ }
6659
+ if (!isDescendant) {
6660
+ break;
6661
+ }
6662
+ insertAfterTaskId = orderedTasks[index].id;
6663
+ }
6664
+ return insertAfterTaskId;
6665
+ }, [orderedTasks]);
6666
+ const pendingInsertDisplayTaskId = (0, import_react12.useMemo)(() => {
6667
+ if (!pendingInsert) {
6668
+ return null;
6669
+ }
6670
+ const taskById = new Map(visibleTasks.map((task) => [task.id, task]));
6671
+ if (!taskById.has(pendingInsert.anchorTaskId)) {
6672
+ return null;
6673
+ }
6674
+ let displayTaskId = pendingInsert.anchorTaskId;
6675
+ for (const task of visibleTasks) {
6676
+ let currentParentId = task.parentId;
6677
+ while (currentParentId) {
6678
+ if (currentParentId === pendingInsert.anchorTaskId) {
6679
+ displayTaskId = task.id;
6680
+ break;
6681
+ }
6682
+ currentParentId = taskById.get(currentParentId)?.parentId;
6683
+ }
6684
+ }
6685
+ return displayTaskId;
6686
+ }, [pendingInsert, visibleTasks]);
6687
+ const handleStartInsertAfter = (0, import_react12.useCallback)((taskId, newTask) => {
6688
+ const anchorTask = orderedTasks.find((task) => task.id === taskId);
6689
+ if (!anchorTask) {
6690
+ return;
6691
+ }
6692
+ setIsCreating(false);
6693
+ setPendingInsert({
6694
+ anchorTaskId: taskId,
6695
+ insertAfterTaskId: findInsertAfterTaskId(taskId),
6696
+ parentId: anchorTask.parentId,
6697
+ startDate: newTask.startDate,
6698
+ endDate: newTask.endDate,
6699
+ nestingDepth: nestingDepthMap.get(taskId) ?? 0
6700
+ });
6701
+ }, [findInsertAfterTaskId, nestingDepthMap, orderedTasks]);
6702
+ const handleConfirmInsertedTask = (0, import_react12.useCallback)((name) => {
6703
+ if (!pendingInsert) {
6704
+ return;
6705
+ }
6706
+ const newTask = {
6707
+ id: crypto.randomUUID(),
6708
+ name,
6709
+ startDate: pendingInsert.startDate,
6710
+ endDate: pendingInsert.endDate,
6711
+ parentId: pendingInsert.parentId
6712
+ };
6713
+ onInsertAfter?.(pendingInsert.insertAfterTaskId, newTask);
6714
+ setPendingInsert(null);
6715
+ }, [onInsertAfter, pendingInsert]);
6716
+ const handleCancelInsertedTask = (0, import_react12.useCallback)(() => setPendingInsert(null), []);
6626
6717
  function getTaskDepth(task, tasks2) {
6627
6718
  if (!task) return 0;
6628
6719
  let depth = 0;
@@ -6762,73 +6853,87 @@ var TaskList = ({
6762
6853
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "gantt-tl-body", style: { height: `${totalHeight}px` }, children: visibleTasks.map((task, index) => {
6763
6854
  const previousVisibleTask = index > 0 ? visibleTasks[index - 1] : void 0;
6764
6855
  const canDemoteTask = index === 0 || !task.parentId || previousVisibleTask?.id !== task.parentId;
6765
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6766
- TaskListRow,
6767
- {
6768
- task,
6769
- rowIndex: index,
6770
- taskNumber: originalTaskNumberMap[task.id] || "",
6771
- taskNumberMap: originalTaskNumberMap,
6772
- rowHeight,
6773
- onTasksChange,
6774
- selectedTaskId,
6775
- onRowClick: handleRowClick,
6776
- disableTaskNameEditing,
6777
- disableDependencyEditing,
6778
- allTasks: tasks,
6779
- activeLinkType,
6780
- onSetActiveLinkType: setActiveLinkType,
6781
- selectingPredecessorFor,
6782
- dependencyPickMode,
6783
- onSetDependencyPickMode: setDependencyPickMode,
6784
- onSetSelectingPredecessorFor: setSelectingPredecessorFor,
6785
- onAddDependency: handleAddDependency,
6786
- onRemoveDependency: handleRemoveDependency,
6787
- selectedChip,
6788
- onChipSelect: handleChipSelect,
6789
- onScrollToTask,
6790
- onDelete,
6791
- onAdd,
6792
- onInsertAfter,
6793
- editingTaskId: propEditingTaskId,
6794
- isDragging: draggingIndex === index,
6795
- isDragOver: dragOverIndex === index,
6796
- onDragStart: handleDragStart,
6797
- onDragOver: handleDragOver,
6798
- onDrop: handleDrop,
6799
- onDragEnd: handleDragEnd,
6800
- collapsedParentIds,
6801
- onToggleCollapse: handleToggleCollapse,
6802
- onPromoteTask,
6803
- onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
6804
- onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
6805
- canDemoteTask,
6806
- isLastChild: lastChildIds.has(task.id),
6807
- nestingDepth: nestingDepthMap.get(task.id) ?? 0,
6808
- ancestorContinues: ancestorContinuesMap.get(task.id) ?? [],
6809
- customDays,
6810
- isWeekend: isWeekend3,
6811
- businessDays,
6812
- isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
6813
- isFilterHideMode: filterMode === "hide" && isFilterActive,
6814
- resolvedColumns
6815
- },
6816
- task.id
6817
- );
6856
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react12.default.Fragment, { children: [
6857
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6858
+ TaskListRow,
6859
+ {
6860
+ task,
6861
+ rowIndex: index,
6862
+ taskNumber: originalTaskNumberMap[task.id] || "",
6863
+ taskNumberMap: originalTaskNumberMap,
6864
+ rowHeight,
6865
+ onTasksChange,
6866
+ selectedTaskId,
6867
+ onRowClick: handleRowClick,
6868
+ disableTaskNameEditing,
6869
+ disableDependencyEditing,
6870
+ allTasks: tasks,
6871
+ activeLinkType,
6872
+ onSetActiveLinkType: setActiveLinkType,
6873
+ selectingPredecessorFor,
6874
+ dependencyPickMode,
6875
+ onSetDependencyPickMode: setDependencyPickMode,
6876
+ onSetSelectingPredecessorFor: setSelectingPredecessorFor,
6877
+ onAddDependency: handleAddDependency,
6878
+ onRemoveDependency: handleRemoveDependency,
6879
+ selectedChip,
6880
+ onChipSelect: handleChipSelect,
6881
+ onScrollToTask,
6882
+ onDelete,
6883
+ onAdd,
6884
+ onInsertAfter: handleStartInsertAfter,
6885
+ editingTaskId: propEditingTaskId,
6886
+ isDragging: draggingIndex === index,
6887
+ isDragOver: dragOverIndex === index,
6888
+ onDragStart: handleDragStart,
6889
+ onDragOver: handleDragOver,
6890
+ onDrop: handleDrop,
6891
+ onDragEnd: handleDragEnd,
6892
+ collapsedParentIds,
6893
+ onToggleCollapse: handleToggleCollapse,
6894
+ onPromoteTask,
6895
+ onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
6896
+ onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
6897
+ canDemoteTask,
6898
+ isLastChild: lastChildIds.has(task.id),
6899
+ nestingDepth: nestingDepthMap.get(task.id) ?? 0,
6900
+ ancestorContinues: ancestorContinuesMap.get(task.id) ?? [],
6901
+ customDays,
6902
+ isWeekend: isWeekend3,
6903
+ businessDays,
6904
+ isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
6905
+ isFilterHideMode: filterMode === "hide" && isFilterActive,
6906
+ resolvedColumns
6907
+ }
6908
+ ),
6909
+ pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6910
+ NewTaskRow,
6911
+ {
6912
+ rowHeight,
6913
+ onConfirm: handleConfirmInsertedTask,
6914
+ onCancel: handleCancelInsertedTask,
6915
+ nestingDepth: pendingInsert?.nestingDepth ?? 0
6916
+ }
6917
+ )
6918
+ ] }, task.id);
6818
6919
  }) }),
6819
- isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6920
+ isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6820
6921
  NewTaskRow,
6821
6922
  {
6822
6923
  rowHeight,
6823
6924
  onConfirm: handleConfirmNewTask,
6824
- onCancel: handleCancelNewTask
6925
+ onCancel: handleCancelNewTask,
6926
+ nestingDepth: 0
6825
6927
  }
6826
6928
  ),
6827
- enableAddTask && onAdd && !isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6929
+ enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6828
6930
  "button",
6829
6931
  {
6830
6932
  className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
6831
- onClick: () => setIsCreating(true),
6933
+ onClick: () => {
6934
+ setPendingInsert(null);
6935
+ setIsCreating(true);
6936
+ },
6832
6937
  onDragEnter: (e) => {
6833
6938
  e.preventDefault();
6834
6939
  setDragOverIndex(visibleTasks.length);
@@ -7105,7 +7210,6 @@ function GanttChartInner(props, ref) {
7105
7210
  toDelete.forEach((id) => onDelete?.(id));
7106
7211
  }, [tasks, onTasksChange, onDelete]);
7107
7212
  const handleInsertAfter = (0, import_react13.useCallback)((taskId, newTask) => {
7108
- setEditingTaskId(newTask.id);
7109
7213
  onInsertAfter?.(taskId, newTask);
7110
7214
  }, [onInsertAfter]);
7111
7215
  const handleReorder = (0, import_react13.useCallback)((reorderedTasks, movedTaskId, inferredParentId) => {
@@ -7119,8 +7223,11 @@ function GanttChartInner(props, ref) {
7119
7223
  });
7120
7224
  }
7121
7225
  const normalized = normalizeHierarchyTasks(updated);
7226
+ if (onReorder) {
7227
+ onReorder(normalized, movedTaskId, inferredParentId);
7228
+ return;
7229
+ }
7122
7230
  onTasksChange?.(normalized);
7123
- onReorder?.(normalized, movedTaskId, inferredParentId);
7124
7231
  }, [onTasksChange, onReorder]);
7125
7232
  const dependencyOverrides = (0, import_react13.useMemo)(() => {
7126
7233
  const map = new Map(cascadeOverrides);