gantt-lib 0.6.1 → 0.6.2

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
@@ -930,5 +930,11 @@ declare const calculateOrthogonalPath: (from: {
930
930
  * Tasks with missing parents are treated as root tasks.
931
931
  */
932
932
  declare function flattenHierarchy<T extends Task$1>(tasks: T[]): T[];
933
+ /**
934
+ * Normalize hierarchy-aware display fields.
935
+ * Parent task dates and progress are always recomputed from children,
936
+ * taking precedence over any hardcoded parent values from the input.
937
+ */
938
+ declare function normalizeHierarchyTasks<T extends Task$1>(tasks: T[]): T[];
933
939
 
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 };
940
+ 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, normalizeHierarchyTasks, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
package/dist/index.d.ts CHANGED
@@ -930,5 +930,11 @@ declare const calculateOrthogonalPath: (from: {
930
930
  * Tasks with missing parents are treated as root tasks.
931
931
  */
932
932
  declare function flattenHierarchy<T extends Task$1>(tasks: T[]): T[];
933
+ /**
934
+ * Normalize hierarchy-aware display fields.
935
+ * Parent task dates and progress are always recomputed from children,
936
+ * taking precedence over any hardcoded parent values from the input.
937
+ */
938
+ declare function normalizeHierarchyTasks<T extends Task$1>(tasks: T[]): T[];
933
939
 
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 };
940
+ 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, normalizeHierarchyTasks, parseUTCDate, pixelsToDate, recalculateIncomingLags, removeDependenciesBetweenTasks, useTaskDrag, validateDependencies };
package/dist/index.js CHANGED
@@ -75,6 +75,7 @@ __export(index_exports, {
75
75
  isTaskParent: () => isTaskParent,
76
76
  isToday: () => isToday,
77
77
  isWeekend: () => isWeekend,
78
+ normalizeHierarchyTasks: () => normalizeHierarchyTasks,
78
79
  parseUTCDate: () => parseUTCDate,
79
80
  pixelsToDate: () => pixelsToDate,
80
81
  recalculateIncomingLags: () => recalculateIncomingLags,
@@ -605,6 +606,25 @@ function flattenHierarchy(tasks) {
605
606
  }
606
607
  return result;
607
608
  }
609
+ function normalizeHierarchyTasks(tasks) {
610
+ const orderedTasks = flattenHierarchy(tasks).map((task) => ({ ...task }));
611
+ for (const task of [...orderedTasks].reverse()) {
612
+ if (!isTaskParent(task.id, orderedTasks)) continue;
613
+ const { startDate, endDate } = computeParentDates(task.id, orderedTasks);
614
+ const progress = computeParentProgress(task.id, orderedTasks);
615
+ const normalizedStartDate = startDate.toISOString().split("T")[0];
616
+ const normalizedEndDate = endDate.toISOString().split("T")[0];
617
+ const parentIndex = orderedTasks.findIndex((candidate) => candidate.id === task.id);
618
+ if (parentIndex === -1) continue;
619
+ orderedTasks[parentIndex] = {
620
+ ...orderedTasks[parentIndex],
621
+ startDate: normalizedStartDate,
622
+ endDate: normalizedEndDate,
623
+ progress
624
+ };
625
+ }
626
+ return orderedTasks;
627
+ }
608
628
 
609
629
  // src/components/TimeScaleHeader/TimeScaleHeader.tsx
610
630
  var import_react = require("react");
@@ -3175,7 +3195,7 @@ var TaskList = ({
3175
3195
  return next;
3176
3196
  });
3177
3197
  }, []);
3178
- const orderedTasks = (0, import_react12.useMemo)(() => flattenHierarchy(tasks), [tasks]);
3198
+ const orderedTasks = (0, import_react12.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
3179
3199
  const visibleTasks = (0, import_react12.useMemo)(() => {
3180
3200
  return orderedTasks.filter((task) => {
3181
3201
  if (!task.parentId) return true;
@@ -3586,21 +3606,21 @@ var GanttChart = (0, import_react13.forwardRef)(({
3586
3606
  const [selectedChip, setSelectedChip] = (0, import_react13.useState)(null);
3587
3607
  const [collapsedParentIds, setCollapsedParentIds] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
3588
3608
  const [editingTaskId, setEditingTaskId] = (0, import_react13.useState)(null);
3589
- const dateRange = (0, import_react13.useMemo)(() => getMultiMonthDays(tasks), [tasks]);
3609
+ const normalizedTasks = (0, import_react13.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
3610
+ const dateRange = (0, import_react13.useMemo)(() => getMultiMonthDays(normalizedTasks), [normalizedTasks]);
3590
3611
  const [validationResult, setValidationResult] = (0, import_react13.useState)(null);
3591
3612
  const [cascadeOverrides, setCascadeOverrides] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
3592
3613
  const gridWidth = (0, import_react13.useMemo)(
3593
3614
  () => Math.round(dateRange.length * dayWidth),
3594
3615
  [dateRange.length, dayWidth]
3595
3616
  );
3596
- const orderedTasks = (0, import_react13.useMemo)(() => flattenHierarchy(tasks), [tasks]);
3597
3617
  const filteredTasks = (0, import_react13.useMemo)(() => {
3598
- return orderedTasks.filter((task) => {
3618
+ return normalizedTasks.filter((task) => {
3599
3619
  if (!task.parentId) return true;
3600
3620
  const parentCollapsed = collapsedParentIds.has(task.parentId);
3601
3621
  return !parentCollapsed;
3602
3622
  });
3603
- }, [orderedTasks, collapsedParentIds]);
3623
+ }, [normalizedTasks, collapsedParentIds]);
3604
3624
  const totalGridHeight = (0, import_react13.useMemo)(
3605
3625
  () => filteredTasks.length * rowHeight,
3606
3626
  [filteredTasks.length, rowHeight]
@@ -3846,9 +3866,9 @@ var GanttChart = (0, import_react13.forwardRef)(({
3846
3866
  updatedCount: updated.length
3847
3867
  });
3848
3868
  console.log("=== GANTT CHART handleReorder END ===\n");
3849
- return flattenHierarchy(updated);
3869
+ return normalizeHierarchyTasks(updated);
3850
3870
  });
3851
- onReorder?.(flattenHierarchy(reorderedTasks), movedTaskId, inferredParentId);
3871
+ onReorder?.(normalizeHierarchyTasks(reorderedTasks), movedTaskId, inferredParentId);
3852
3872
  }, [onChange, onReorder]);
3853
3873
  const dependencyOverrides = (0, import_react13.useMemo)(() => {
3854
3874
  const map = new Map(cascadeOverrides);
@@ -3915,13 +3935,13 @@ var GanttChart = (0, import_react13.forwardRef)(({
3915
3935
  const parentId = taskToPromote.parentId;
3916
3936
  const siblings = currentTasks.filter((t) => t.parentId === parentId);
3917
3937
  if (siblings.length <= 1) {
3918
- return flattenHierarchy(currentTasks.map(
3938
+ return normalizeHierarchyTasks(currentTasks.map(
3919
3939
  (t) => t.id === taskId ? { ...t, parentId: void 0 } : t
3920
3940
  ));
3921
3941
  }
3922
3942
  const lastSiblingIndex = currentTasks.map((t, i) => ({ task: t, index: i })).filter(({ task }) => task.parentId === parentId).sort((a, b) => b.index - a.index)[0];
3923
3943
  if (!lastSiblingIndex) {
3924
- return flattenHierarchy(currentTasks.map(
3944
+ return normalizeHierarchyTasks(currentTasks.map(
3925
3945
  (t) => t.id === taskId ? { ...t, parentId: void 0 } : t
3926
3946
  ));
3927
3947
  }
@@ -3933,7 +3953,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
3933
3953
  promotedTask,
3934
3954
  ...withoutPromotedTask.slice(insertIndex)
3935
3955
  ];
3936
- return flattenHierarchy(newTasks);
3956
+ return normalizeHierarchyTasks(newTasks);
3937
3957
  });
3938
3958
  }, [onChange]);
3939
3959
  const handleDemoteTask = (0, import_react13.useCallback)((taskId, newParentId) => {
@@ -3966,7 +3986,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
3966
3986
  updatedTasks = updatedTasks.map(
3967
3987
  (t) => t.id === newParentId ? { ...t, startDate: parentDates.startDate.toISOString().split("T")[0], endDate: parentDates.endDate.toISOString().split("T")[0], progress: parentProgress } : t
3968
3988
  );
3969
- return flattenHierarchy(updatedTasks);
3989
+ return normalizeHierarchyTasks(updatedTasks);
3970
3990
  });
3971
3991
  }, [onChange]);
3972
3992
  const panStateRef = (0, import_react13.useRef)(null);
@@ -4024,7 +4044,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4024
4044
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4025
4045
  TaskList,
4026
4046
  {
4027
- tasks: orderedTasks,
4047
+ tasks: normalizedTasks,
4028
4048
  rowHeight,
4029
4049
  headerHeight,
4030
4050
  taskListWidth,
@@ -4079,7 +4099,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4079
4099
  DependencyLines_default,
4080
4100
  {
4081
4101
  tasks: filteredTasks,
4082
- allTasks: orderedTasks,
4102
+ allTasks: normalizedTasks,
4083
4103
  collapsedParentIds,
4084
4104
  monthStart,
4085
4105
  dayWidth,
@@ -4117,7 +4137,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
4117
4137
  }
4118
4138
  },
4119
4139
  rowIndex: index,
4120
- allTasks: orderedTasks,
4140
+ allTasks: normalizedTasks,
4121
4141
  enableAutoSchedule: enableAutoSchedule ?? false,
4122
4142
  disableConstraints: disableConstraints ?? false,
4123
4143
  overridePosition: cascadeOverrides.get(task.id),
@@ -4198,6 +4218,7 @@ Button.displayName = "Button";
4198
4218
  isTaskParent,
4199
4219
  isToday,
4200
4220
  isWeekend,
4221
+ normalizeHierarchyTasks,
4201
4222
  parseUTCDate,
4202
4223
  pixelsToDate,
4203
4224
  recalculateIncomingLags,