gantt-lib 0.6.0 → 0.6.1

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.mts CHANGED
@@ -924,4 +924,11 @@ declare const calculateOrthogonalPath: (from: {
924
924
  y: number;
925
925
  }) => string;
926
926
 
927
- export { Button, type ButtonProps, Calendar, type CalendarProps, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, type GanttDateRange, GridBackground, type GridConfig, type GridLine, Input, type InputProps, type MonthSpan, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskBarGeometry, type TaskDependency, TaskList, type TaskListProps, TaskRow, TimeScaleHeader, TodayIndicator, type WeekendBlock, buildAdjacencyList, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateOrthogonalPath, calculateSuccessorDate, calculateTaskBar, calculateWeekendBlocks, cascadeByLinks, computeLagFromDates, computeParentDates, computeParentProgress, detectCycles, detectEdgeZone, findParentId, formatDateLabel, getAllDependencyEdges, getChildren, getCursorForPosition, getDayOffset, getMonthDays, getMonthSpans, getMultiMonthDays, getSuccessorChain, getTransitiveCascadeChain, isTaskParent, isToday, isWeekend, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
927
+ /**
928
+ * Build a stable depth-first task order from parentId links.
929
+ * Sibling order follows the order in the input array.
930
+ * Tasks with missing parents are treated as root tasks.
931
+ */
932
+ declare function flattenHierarchy<T extends Task$1>(tasks: T[]): T[];
933
+
934
+ export { Button, type ButtonProps, Calendar, type CalendarProps, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, type GanttDateRange, GridBackground, type GridConfig, type GridLine, Input, type InputProps, type MonthSpan, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskBarGeometry, type TaskDependency, TaskList, type TaskListProps, TaskRow, TimeScaleHeader, TodayIndicator, type WeekendBlock, buildAdjacencyList, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateOrthogonalPath, calculateSuccessorDate, calculateTaskBar, calculateWeekendBlocks, cascadeByLinks, computeLagFromDates, computeParentDates, computeParentProgress, detectCycles, detectEdgeZone, findParentId, flattenHierarchy, formatDateLabel, getAllDependencyEdges, getChildren, getCursorForPosition, getDayOffset, getMonthDays, getMonthSpans, getMultiMonthDays, getSuccessorChain, getTransitiveCascadeChain, isTaskParent, isToday, isWeekend, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
package/dist/index.d.ts CHANGED
@@ -924,4 +924,11 @@ declare const calculateOrthogonalPath: (from: {
924
924
  y: number;
925
925
  }) => string;
926
926
 
927
- export { Button, type ButtonProps, Calendar, type CalendarProps, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, type GanttDateRange, GridBackground, type GridConfig, type GridLine, Input, type InputProps, type MonthSpan, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskBarGeometry, type TaskDependency, TaskList, type TaskListProps, TaskRow, TimeScaleHeader, TodayIndicator, type WeekendBlock, buildAdjacencyList, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateOrthogonalPath, calculateSuccessorDate, calculateTaskBar, calculateWeekendBlocks, cascadeByLinks, computeLagFromDates, computeParentDates, computeParentProgress, detectCycles, detectEdgeZone, findParentId, formatDateLabel, getAllDependencyEdges, getChildren, getCursorForPosition, getDayOffset, getMonthDays, getMonthSpans, getMultiMonthDays, getSuccessorChain, getTransitiveCascadeChain, isTaskParent, isToday, isWeekend, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
927
+ /**
928
+ * Build a stable depth-first task order from parentId links.
929
+ * Sibling order follows the order in the input array.
930
+ * Tasks with missing parents are treated as root tasks.
931
+ */
932
+ declare function flattenHierarchy<T extends Task$1>(tasks: T[]): T[];
933
+
934
+ export { Button, type ButtonProps, Calendar, type CalendarProps, DatePicker, type DatePickerProps, DragGuideLines, GanttChart, type GanttChartHandle, type GanttChartProps, type GanttDateRange, GridBackground, type GridConfig, type GridLine, Input, type InputProps, type MonthSpan, Popover, PopoverContent, type PopoverContentProps, type PopoverProps, PopoverTrigger, type Task, type TaskBarGeometry, type TaskDependency, TaskList, type TaskListProps, TaskRow, TimeScaleHeader, TodayIndicator, type WeekendBlock, buildAdjacencyList, calculateBezierPath, calculateDependencyPath, calculateGridLines, calculateGridWidth, calculateOrthogonalPath, calculateSuccessorDate, calculateTaskBar, calculateWeekendBlocks, cascadeByLinks, computeLagFromDates, computeParentDates, computeParentProgress, detectCycles, detectEdgeZone, findParentId, flattenHierarchy, formatDateLabel, getAllDependencyEdges, getChildren, getCursorForPosition, getDayOffset, getMonthDays, getMonthSpans, getMultiMonthDays, getSuccessorChain, getTransitiveCascadeChain, isTaskParent, isToday, isWeekend, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
package/dist/index.js CHANGED
@@ -61,6 +61,7 @@ __export(index_exports, {
61
61
  detectCycles: () => detectCycles,
62
62
  detectEdgeZone: () => detectEdgeZone,
63
63
  findParentId: () => findParentId,
64
+ flattenHierarchy: () => flattenHierarchy,
64
65
  formatDateLabel: () => formatDateLabel,
65
66
  getAllDependencyEdges: () => getAllDependencyEdges,
66
67
  getChildren: () => getChildren,
@@ -575,6 +576,36 @@ function findParentId(taskId, tasks) {
575
576
  return task?.parentId;
576
577
  }
577
578
 
579
+ // src/utils/hierarchyOrder.ts
580
+ function flattenHierarchy(tasks) {
581
+ const byId = new Map(tasks.map((task) => [task.id, task]));
582
+ const byParent = /* @__PURE__ */ new Map();
583
+ for (const task of tasks) {
584
+ const normalizedParentId = task.parentId && byId.has(task.parentId) ? task.parentId : void 0;
585
+ const siblings = byParent.get(normalizedParentId) ?? [];
586
+ siblings.push(task);
587
+ byParent.set(normalizedParentId, siblings);
588
+ }
589
+ const result = [];
590
+ const visited = /* @__PURE__ */ new Set();
591
+ const walk = (parentId) => {
592
+ const children = byParent.get(parentId) ?? [];
593
+ for (const task of children) {
594
+ if (visited.has(task.id)) continue;
595
+ visited.add(task.id);
596
+ result.push(task);
597
+ walk(task.id);
598
+ }
599
+ };
600
+ walk(void 0);
601
+ for (const task of tasks) {
602
+ if (!visited.has(task.id)) {
603
+ result.push(task);
604
+ }
605
+ }
606
+ return result;
607
+ }
608
+
578
609
  // src/components/TimeScaleHeader/TimeScaleHeader.tsx
579
610
  var import_react = require("react");
580
611
  var import_date_fns = require("date-fns");
@@ -3144,13 +3175,14 @@ var TaskList = ({
3144
3175
  return next;
3145
3176
  });
3146
3177
  }, []);
3178
+ const orderedTasks = (0, import_react12.useMemo)(() => flattenHierarchy(tasks), [tasks]);
3147
3179
  const visibleTasks = (0, import_react12.useMemo)(() => {
3148
- return tasks.filter((task) => {
3180
+ return orderedTasks.filter((task) => {
3149
3181
  if (!task.parentId) return true;
3150
3182
  const parentCollapsed = collapsedParentIds.has(task.parentId);
3151
3183
  return !parentCollapsed;
3152
3184
  });
3153
- }, [tasks, collapsedParentIds]);
3185
+ }, [orderedTasks, collapsedParentIds]);
3154
3186
  const totalHeight = (0, import_react12.useMemo)(
3155
3187
  () => visibleTasks.length * rowHeight,
3156
3188
  [visibleTasks.length, rowHeight]
@@ -3272,9 +3304,9 @@ var TaskList = ({
3272
3304
  dragOriginIndexRef.current = null;
3273
3305
  return;
3274
3306
  }
3275
- const reordered = [...tasks];
3307
+ const reordered = [...orderedTasks];
3276
3308
  const [moved] = reordered.splice(originIndex, 1);
3277
- const insertIndex = dropIndex === tasks.length ? tasks.length - 1 : originIndex < dropIndex ? dropIndex - 1 : dropIndex;
3309
+ const insertIndex = dropIndex === visibleTasks.length ? visibleTasks.length - 1 : originIndex < dropIndex ? dropIndex - 1 : dropIndex;
3278
3310
  const isChild = !!moved.parentId;
3279
3311
  const isParent = tasks.some((t) => t.parentId === moved.id);
3280
3312
  const taskType = isParent ? "PARENT" : isChild ? "CHILD" : "ROOT";
@@ -3289,7 +3321,7 @@ var TaskList = ({
3289
3321
  insertIndex,
3290
3322
  direction: originIndex < dropIndex ? "DOWN" : "UP"
3291
3323
  });
3292
- console.log("[TASKS ARRAY LENGTH]", tasks.length);
3324
+ console.log("[TASKS ARRAY LENGTH]", orderedTasks.length);
3293
3325
  let inferredParentId;
3294
3326
  if (moved.parentId) {
3295
3327
  const parentIndex = reordered.findIndex((t) => t.id === moved.parentId);
@@ -3374,7 +3406,7 @@ var TaskList = ({
3374
3406
  setDraggingIndex(null);
3375
3407
  setDragOverIndex(null);
3376
3408
  dragOriginIndexRef.current = null;
3377
- }, [tasks, onReorder, onTaskSelect]);
3409
+ }, [orderedTasks, visibleTasks.length, onReorder, onTaskSelect]);
3378
3410
  const handleDragEnd = (0, import_react12.useCallback)(() => {
3379
3411
  setDraggingIndex(null);
3380
3412
  setDragOverIndex(null);
@@ -3497,16 +3529,16 @@ var TaskList = ({
3497
3529
  enableAddTask && onAdd && !isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3498
3530
  "button",
3499
3531
  {
3500
- className: `gantt-tl-add-btn${dragOverIndex === tasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
3532
+ className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
3501
3533
  onClick: () => setIsCreating(true),
3502
3534
  onDragEnter: (e) => {
3503
3535
  e.preventDefault();
3504
- setDragOverIndex(tasks.length);
3536
+ setDragOverIndex(visibleTasks.length);
3505
3537
  },
3506
3538
  onDragOver: (e) => {
3507
3539
  e.preventDefault();
3508
3540
  e.dataTransfer.dropEffect = "move";
3509
- setDragOverIndex(tasks.length);
3541
+ setDragOverIndex(visibleTasks.length);
3510
3542
  },
3511
3543
  onDragLeave: (e) => {
3512
3544
  e.preventDefault();
@@ -3514,7 +3546,7 @@ var TaskList = ({
3514
3546
  },
3515
3547
  onDrop: (e) => {
3516
3548
  e.preventDefault();
3517
- handleDrop(tasks.length, e);
3549
+ handleDrop(visibleTasks.length, e);
3518
3550
  },
3519
3551
  type: "button",
3520
3552
  children: "+ \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443"
@@ -3561,13 +3593,14 @@ var GanttChart = (0, import_react13.forwardRef)(({
3561
3593
  () => Math.round(dateRange.length * dayWidth),
3562
3594
  [dateRange.length, dayWidth]
3563
3595
  );
3596
+ const orderedTasks = (0, import_react13.useMemo)(() => flattenHierarchy(tasks), [tasks]);
3564
3597
  const filteredTasks = (0, import_react13.useMemo)(() => {
3565
- return tasks.filter((task) => {
3598
+ return orderedTasks.filter((task) => {
3566
3599
  if (!task.parentId) return true;
3567
3600
  const parentCollapsed = collapsedParentIds.has(task.parentId);
3568
3601
  return !parentCollapsed;
3569
3602
  });
3570
- }, [tasks, collapsedParentIds]);
3603
+ }, [orderedTasks, collapsedParentIds]);
3571
3604
  const totalGridHeight = (0, import_react13.useMemo)(
3572
3605
  () => filteredTasks.length * rowHeight,
3573
3606
  [filteredTasks.length, rowHeight]
@@ -3813,9 +3846,9 @@ var GanttChart = (0, import_react13.forwardRef)(({
3813
3846
  updatedCount: updated.length
3814
3847
  });
3815
3848
  console.log("=== GANTT CHART handleReorder END ===\n");
3816
- return updated;
3849
+ return flattenHierarchy(updated);
3817
3850
  });
3818
- onReorder?.(reorderedTasks, movedTaskId, inferredParentId);
3851
+ onReorder?.(flattenHierarchy(reorderedTasks), movedTaskId, inferredParentId);
3819
3852
  }, [onChange, onReorder]);
3820
3853
  const dependencyOverrides = (0, import_react13.useMemo)(() => {
3821
3854
  const map = new Map(cascadeOverrides);
@@ -3882,15 +3915,15 @@ var GanttChart = (0, import_react13.forwardRef)(({
3882
3915
  const parentId = taskToPromote.parentId;
3883
3916
  const siblings = currentTasks.filter((t) => t.parentId === parentId);
3884
3917
  if (siblings.length <= 1) {
3885
- return currentTasks.map(
3918
+ return flattenHierarchy(currentTasks.map(
3886
3919
  (t) => t.id === taskId ? { ...t, parentId: void 0 } : t
3887
- );
3920
+ ));
3888
3921
  }
3889
3922
  const lastSiblingIndex = currentTasks.map((t, i) => ({ task: t, index: i })).filter(({ task }) => task.parentId === parentId).sort((a, b) => b.index - a.index)[0];
3890
3923
  if (!lastSiblingIndex) {
3891
- return currentTasks.map(
3924
+ return flattenHierarchy(currentTasks.map(
3892
3925
  (t) => t.id === taskId ? { ...t, parentId: void 0 } : t
3893
- );
3926
+ ));
3894
3927
  }
3895
3928
  const withoutPromotedTask = currentTasks.filter((t) => t.id !== taskId);
3896
3929
  const insertIndex = lastSiblingIndex.index + 1;
@@ -3900,7 +3933,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
3900
3933
  promotedTask,
3901
3934
  ...withoutPromotedTask.slice(insertIndex)
3902
3935
  ];
3903
- return newTasks;
3936
+ return flattenHierarchy(newTasks);
3904
3937
  });
3905
3938
  }, [onChange]);
3906
3939
  const handleDemoteTask = (0, import_react13.useCallback)((taskId, newParentId) => {
@@ -3933,7 +3966,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
3933
3966
  updatedTasks = updatedTasks.map(
3934
3967
  (t) => t.id === newParentId ? { ...t, startDate: parentDates.startDate.toISOString().split("T")[0], endDate: parentDates.endDate.toISOString().split("T")[0], progress: parentProgress } : t
3935
3968
  );
3936
- return updatedTasks;
3969
+ return flattenHierarchy(updatedTasks);
3937
3970
  });
3938
3971
  }, [onChange]);
3939
3972
  const panStateRef = (0, import_react13.useRef)(null);
@@ -3991,7 +4024,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
3991
4024
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3992
4025
  TaskList,
3993
4026
  {
3994
- tasks,
4027
+ tasks: orderedTasks,
3995
4028
  rowHeight,
3996
4029
  headerHeight,
3997
4030
  taskListWidth,
@@ -4046,7 +4079,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4046
4079
  DependencyLines_default,
4047
4080
  {
4048
4081
  tasks: filteredTasks,
4049
- allTasks: tasks,
4082
+ allTasks: orderedTasks,
4050
4083
  collapsedParentIds,
4051
4084
  monthStart,
4052
4085
  dayWidth,
@@ -4084,7 +4117,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4084
4117
  }
4085
4118
  },
4086
4119
  rowIndex: index,
4087
- allTasks: tasks,
4120
+ allTasks: orderedTasks,
4088
4121
  enableAutoSchedule: enableAutoSchedule ?? false,
4089
4122
  disableConstraints: disableConstraints ?? false,
4090
4123
  overridePosition: cascadeOverrides.get(task.id),
@@ -4151,6 +4184,7 @@ Button.displayName = "Button";
4151
4184
  detectCycles,
4152
4185
  detectEdgeZone,
4153
4186
  findParentId,
4187
+ flattenHierarchy,
4154
4188
  formatDateLabel,
4155
4189
  getAllDependencyEdges,
4156
4190
  getChildren,