gantt-lib 0.6.0 → 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 +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +79 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +77 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -924,4 +924,17 @@ declare const calculateOrthogonalPath: (from: {
|
|
|
924
924
|
y: number;
|
|
925
925
|
}) => string;
|
|
926
926
|
|
|
927
|
-
|
|
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
|
+
* 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[];
|
|
939
|
+
|
|
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
|
@@ -924,4 +924,17 @@ declare const calculateOrthogonalPath: (from: {
|
|
|
924
924
|
y: number;
|
|
925
925
|
}) => string;
|
|
926
926
|
|
|
927
|
-
|
|
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
|
+
* 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[];
|
|
939
|
+
|
|
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
|
@@ -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,
|
|
@@ -74,6 +75,7 @@ __export(index_exports, {
|
|
|
74
75
|
isTaskParent: () => isTaskParent,
|
|
75
76
|
isToday: () => isToday,
|
|
76
77
|
isWeekend: () => isWeekend,
|
|
78
|
+
normalizeHierarchyTasks: () => normalizeHierarchyTasks,
|
|
77
79
|
parseUTCDate: () => parseUTCDate,
|
|
78
80
|
pixelsToDate: () => pixelsToDate,
|
|
79
81
|
recalculateIncomingLags: () => recalculateIncomingLags,
|
|
@@ -575,6 +577,55 @@ function findParentId(taskId, tasks) {
|
|
|
575
577
|
return task?.parentId;
|
|
576
578
|
}
|
|
577
579
|
|
|
580
|
+
// src/utils/hierarchyOrder.ts
|
|
581
|
+
function flattenHierarchy(tasks) {
|
|
582
|
+
const byId = new Map(tasks.map((task) => [task.id, task]));
|
|
583
|
+
const byParent = /* @__PURE__ */ new Map();
|
|
584
|
+
for (const task of tasks) {
|
|
585
|
+
const normalizedParentId = task.parentId && byId.has(task.parentId) ? task.parentId : void 0;
|
|
586
|
+
const siblings = byParent.get(normalizedParentId) ?? [];
|
|
587
|
+
siblings.push(task);
|
|
588
|
+
byParent.set(normalizedParentId, siblings);
|
|
589
|
+
}
|
|
590
|
+
const result = [];
|
|
591
|
+
const visited = /* @__PURE__ */ new Set();
|
|
592
|
+
const walk = (parentId) => {
|
|
593
|
+
const children = byParent.get(parentId) ?? [];
|
|
594
|
+
for (const task of children) {
|
|
595
|
+
if (visited.has(task.id)) continue;
|
|
596
|
+
visited.add(task.id);
|
|
597
|
+
result.push(task);
|
|
598
|
+
walk(task.id);
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
walk(void 0);
|
|
602
|
+
for (const task of tasks) {
|
|
603
|
+
if (!visited.has(task.id)) {
|
|
604
|
+
result.push(task);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return result;
|
|
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
|
+
}
|
|
628
|
+
|
|
578
629
|
// src/components/TimeScaleHeader/TimeScaleHeader.tsx
|
|
579
630
|
var import_react = require("react");
|
|
580
631
|
var import_date_fns = require("date-fns");
|
|
@@ -3144,13 +3195,14 @@ var TaskList = ({
|
|
|
3144
3195
|
return next;
|
|
3145
3196
|
});
|
|
3146
3197
|
}, []);
|
|
3198
|
+
const orderedTasks = (0, import_react12.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
|
|
3147
3199
|
const visibleTasks = (0, import_react12.useMemo)(() => {
|
|
3148
|
-
return
|
|
3200
|
+
return orderedTasks.filter((task) => {
|
|
3149
3201
|
if (!task.parentId) return true;
|
|
3150
3202
|
const parentCollapsed = collapsedParentIds.has(task.parentId);
|
|
3151
3203
|
return !parentCollapsed;
|
|
3152
3204
|
});
|
|
3153
|
-
}, [
|
|
3205
|
+
}, [orderedTasks, collapsedParentIds]);
|
|
3154
3206
|
const totalHeight = (0, import_react12.useMemo)(
|
|
3155
3207
|
() => visibleTasks.length * rowHeight,
|
|
3156
3208
|
[visibleTasks.length, rowHeight]
|
|
@@ -3272,9 +3324,9 @@ var TaskList = ({
|
|
|
3272
3324
|
dragOriginIndexRef.current = null;
|
|
3273
3325
|
return;
|
|
3274
3326
|
}
|
|
3275
|
-
const reordered = [...
|
|
3327
|
+
const reordered = [...orderedTasks];
|
|
3276
3328
|
const [moved] = reordered.splice(originIndex, 1);
|
|
3277
|
-
const insertIndex = dropIndex ===
|
|
3329
|
+
const insertIndex = dropIndex === visibleTasks.length ? visibleTasks.length - 1 : originIndex < dropIndex ? dropIndex - 1 : dropIndex;
|
|
3278
3330
|
const isChild = !!moved.parentId;
|
|
3279
3331
|
const isParent = tasks.some((t) => t.parentId === moved.id);
|
|
3280
3332
|
const taskType = isParent ? "PARENT" : isChild ? "CHILD" : "ROOT";
|
|
@@ -3289,7 +3341,7 @@ var TaskList = ({
|
|
|
3289
3341
|
insertIndex,
|
|
3290
3342
|
direction: originIndex < dropIndex ? "DOWN" : "UP"
|
|
3291
3343
|
});
|
|
3292
|
-
console.log("[TASKS ARRAY LENGTH]",
|
|
3344
|
+
console.log("[TASKS ARRAY LENGTH]", orderedTasks.length);
|
|
3293
3345
|
let inferredParentId;
|
|
3294
3346
|
if (moved.parentId) {
|
|
3295
3347
|
const parentIndex = reordered.findIndex((t) => t.id === moved.parentId);
|
|
@@ -3374,7 +3426,7 @@ var TaskList = ({
|
|
|
3374
3426
|
setDraggingIndex(null);
|
|
3375
3427
|
setDragOverIndex(null);
|
|
3376
3428
|
dragOriginIndexRef.current = null;
|
|
3377
|
-
}, [
|
|
3429
|
+
}, [orderedTasks, visibleTasks.length, onReorder, onTaskSelect]);
|
|
3378
3430
|
const handleDragEnd = (0, import_react12.useCallback)(() => {
|
|
3379
3431
|
setDraggingIndex(null);
|
|
3380
3432
|
setDragOverIndex(null);
|
|
@@ -3497,16 +3549,16 @@ var TaskList = ({
|
|
|
3497
3549
|
enableAddTask && onAdd && !isCreating && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3498
3550
|
"button",
|
|
3499
3551
|
{
|
|
3500
|
-
className: `gantt-tl-add-btn${dragOverIndex ===
|
|
3552
|
+
className: `gantt-tl-add-btn${dragOverIndex === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
|
|
3501
3553
|
onClick: () => setIsCreating(true),
|
|
3502
3554
|
onDragEnter: (e) => {
|
|
3503
3555
|
e.preventDefault();
|
|
3504
|
-
setDragOverIndex(
|
|
3556
|
+
setDragOverIndex(visibleTasks.length);
|
|
3505
3557
|
},
|
|
3506
3558
|
onDragOver: (e) => {
|
|
3507
3559
|
e.preventDefault();
|
|
3508
3560
|
e.dataTransfer.dropEffect = "move";
|
|
3509
|
-
setDragOverIndex(
|
|
3561
|
+
setDragOverIndex(visibleTasks.length);
|
|
3510
3562
|
},
|
|
3511
3563
|
onDragLeave: (e) => {
|
|
3512
3564
|
e.preventDefault();
|
|
@@ -3514,7 +3566,7 @@ var TaskList = ({
|
|
|
3514
3566
|
},
|
|
3515
3567
|
onDrop: (e) => {
|
|
3516
3568
|
e.preventDefault();
|
|
3517
|
-
handleDrop(
|
|
3569
|
+
handleDrop(visibleTasks.length, e);
|
|
3518
3570
|
},
|
|
3519
3571
|
type: "button",
|
|
3520
3572
|
children: "+ \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0437\u0430\u0434\u0430\u0447\u0443"
|
|
@@ -3554,7 +3606,8 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3554
3606
|
const [selectedChip, setSelectedChip] = (0, import_react13.useState)(null);
|
|
3555
3607
|
const [collapsedParentIds, setCollapsedParentIds] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
|
|
3556
3608
|
const [editingTaskId, setEditingTaskId] = (0, import_react13.useState)(null);
|
|
3557
|
-
const
|
|
3609
|
+
const normalizedTasks = (0, import_react13.useMemo)(() => normalizeHierarchyTasks(tasks), [tasks]);
|
|
3610
|
+
const dateRange = (0, import_react13.useMemo)(() => getMultiMonthDays(normalizedTasks), [normalizedTasks]);
|
|
3558
3611
|
const [validationResult, setValidationResult] = (0, import_react13.useState)(null);
|
|
3559
3612
|
const [cascadeOverrides, setCascadeOverrides] = (0, import_react13.useState)(/* @__PURE__ */ new Map());
|
|
3560
3613
|
const gridWidth = (0, import_react13.useMemo)(
|
|
@@ -3562,12 +3615,12 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3562
3615
|
[dateRange.length, dayWidth]
|
|
3563
3616
|
);
|
|
3564
3617
|
const filteredTasks = (0, import_react13.useMemo)(() => {
|
|
3565
|
-
return
|
|
3618
|
+
return normalizedTasks.filter((task) => {
|
|
3566
3619
|
if (!task.parentId) return true;
|
|
3567
3620
|
const parentCollapsed = collapsedParentIds.has(task.parentId);
|
|
3568
3621
|
return !parentCollapsed;
|
|
3569
3622
|
});
|
|
3570
|
-
}, [
|
|
3623
|
+
}, [normalizedTasks, collapsedParentIds]);
|
|
3571
3624
|
const totalGridHeight = (0, import_react13.useMemo)(
|
|
3572
3625
|
() => filteredTasks.length * rowHeight,
|
|
3573
3626
|
[filteredTasks.length, rowHeight]
|
|
@@ -3813,9 +3866,9 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3813
3866
|
updatedCount: updated.length
|
|
3814
3867
|
});
|
|
3815
3868
|
console.log("=== GANTT CHART handleReorder END ===\n");
|
|
3816
|
-
return updated;
|
|
3869
|
+
return normalizeHierarchyTasks(updated);
|
|
3817
3870
|
});
|
|
3818
|
-
onReorder?.(reorderedTasks, movedTaskId, inferredParentId);
|
|
3871
|
+
onReorder?.(normalizeHierarchyTasks(reorderedTasks), movedTaskId, inferredParentId);
|
|
3819
3872
|
}, [onChange, onReorder]);
|
|
3820
3873
|
const dependencyOverrides = (0, import_react13.useMemo)(() => {
|
|
3821
3874
|
const map = new Map(cascadeOverrides);
|
|
@@ -3882,15 +3935,15 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3882
3935
|
const parentId = taskToPromote.parentId;
|
|
3883
3936
|
const siblings = currentTasks.filter((t) => t.parentId === parentId);
|
|
3884
3937
|
if (siblings.length <= 1) {
|
|
3885
|
-
return currentTasks.map(
|
|
3938
|
+
return normalizeHierarchyTasks(currentTasks.map(
|
|
3886
3939
|
(t) => t.id === taskId ? { ...t, parentId: void 0 } : t
|
|
3887
|
-
);
|
|
3940
|
+
));
|
|
3888
3941
|
}
|
|
3889
3942
|
const lastSiblingIndex = currentTasks.map((t, i) => ({ task: t, index: i })).filter(({ task }) => task.parentId === parentId).sort((a, b) => b.index - a.index)[0];
|
|
3890
3943
|
if (!lastSiblingIndex) {
|
|
3891
|
-
return currentTasks.map(
|
|
3944
|
+
return normalizeHierarchyTasks(currentTasks.map(
|
|
3892
3945
|
(t) => t.id === taskId ? { ...t, parentId: void 0 } : t
|
|
3893
|
-
);
|
|
3946
|
+
));
|
|
3894
3947
|
}
|
|
3895
3948
|
const withoutPromotedTask = currentTasks.filter((t) => t.id !== taskId);
|
|
3896
3949
|
const insertIndex = lastSiblingIndex.index + 1;
|
|
@@ -3900,7 +3953,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3900
3953
|
promotedTask,
|
|
3901
3954
|
...withoutPromotedTask.slice(insertIndex)
|
|
3902
3955
|
];
|
|
3903
|
-
return newTasks;
|
|
3956
|
+
return normalizeHierarchyTasks(newTasks);
|
|
3904
3957
|
});
|
|
3905
3958
|
}, [onChange]);
|
|
3906
3959
|
const handleDemoteTask = (0, import_react13.useCallback)((taskId, newParentId) => {
|
|
@@ -3933,7 +3986,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3933
3986
|
updatedTasks = updatedTasks.map(
|
|
3934
3987
|
(t) => t.id === newParentId ? { ...t, startDate: parentDates.startDate.toISOString().split("T")[0], endDate: parentDates.endDate.toISOString().split("T")[0], progress: parentProgress } : t
|
|
3935
3988
|
);
|
|
3936
|
-
return updatedTasks;
|
|
3989
|
+
return normalizeHierarchyTasks(updatedTasks);
|
|
3937
3990
|
});
|
|
3938
3991
|
}, [onChange]);
|
|
3939
3992
|
const panStateRef = (0, import_react13.useRef)(null);
|
|
@@ -3991,7 +4044,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
3991
4044
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3992
4045
|
TaskList,
|
|
3993
4046
|
{
|
|
3994
|
-
tasks,
|
|
4047
|
+
tasks: normalizedTasks,
|
|
3995
4048
|
rowHeight,
|
|
3996
4049
|
headerHeight,
|
|
3997
4050
|
taskListWidth,
|
|
@@ -4046,7 +4099,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
4046
4099
|
DependencyLines_default,
|
|
4047
4100
|
{
|
|
4048
4101
|
tasks: filteredTasks,
|
|
4049
|
-
allTasks:
|
|
4102
|
+
allTasks: normalizedTasks,
|
|
4050
4103
|
collapsedParentIds,
|
|
4051
4104
|
monthStart,
|
|
4052
4105
|
dayWidth,
|
|
@@ -4084,7 +4137,7 @@ var GanttChart = (0, import_react13.forwardRef)(({
|
|
|
4084
4137
|
}
|
|
4085
4138
|
},
|
|
4086
4139
|
rowIndex: index,
|
|
4087
|
-
allTasks:
|
|
4140
|
+
allTasks: normalizedTasks,
|
|
4088
4141
|
enableAutoSchedule: enableAutoSchedule ?? false,
|
|
4089
4142
|
disableConstraints: disableConstraints ?? false,
|
|
4090
4143
|
overridePosition: cascadeOverrides.get(task.id),
|
|
@@ -4151,6 +4204,7 @@ Button.displayName = "Button";
|
|
|
4151
4204
|
detectCycles,
|
|
4152
4205
|
detectEdgeZone,
|
|
4153
4206
|
findParentId,
|
|
4207
|
+
flattenHierarchy,
|
|
4154
4208
|
formatDateLabel,
|
|
4155
4209
|
getAllDependencyEdges,
|
|
4156
4210
|
getChildren,
|
|
@@ -4164,6 +4218,7 @@ Button.displayName = "Button";
|
|
|
4164
4218
|
isTaskParent,
|
|
4165
4219
|
isToday,
|
|
4166
4220
|
isWeekend,
|
|
4221
|
+
normalizeHierarchyTasks,
|
|
4167
4222
|
parseUTCDate,
|
|
4168
4223
|
pixelsToDate,
|
|
4169
4224
|
recalculateIncomingLags,
|