gantt-lib 0.122.0 → 0.124.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/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/core/scheduling/index.js +157 -0
- package/dist/core/scheduling/index.js.map +1 -1
- package/dist/core/scheduling/index.mjs +155 -0
- package/dist/core/scheduling/index.mjs.map +1 -1
- package/dist/{index-OZVb2o_D.d.mts → index-DD3YvhvA.d.mts} +38 -1
- package/dist/{index-OZVb2o_D.d.ts → index-DD3YvhvA.d.ts} +38 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +225 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +223 -20
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +33 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -550,6 +550,159 @@ function calculateSuccessorDate(predecessorStart, predecessorEnd, linkType, lag
|
|
|
550
550
|
return shiftBusinessDayOffset(anchorDate, offset, weekendPredicate);
|
|
551
551
|
}
|
|
552
552
|
|
|
553
|
+
// src/core/scheduling/criticalPath.ts
|
|
554
|
+
function computeCriticalPath(tasks, options = {}) {
|
|
555
|
+
const { businessDays = false, weekendPredicate } = options;
|
|
556
|
+
const taskById = new Map(tasks.map((task) => [task.id, task]));
|
|
557
|
+
const childIds = /* @__PURE__ */ new Set();
|
|
558
|
+
for (const task of tasks) {
|
|
559
|
+
if (task.parentId) childIds.add(task.parentId);
|
|
560
|
+
}
|
|
561
|
+
const leafTasks = tasks.filter((task) => !childIds.has(task.id));
|
|
562
|
+
const leafIds = new Set(leafTasks.map((task) => task.id));
|
|
563
|
+
const leafIdsByAncestor = /* @__PURE__ */ new Map();
|
|
564
|
+
for (const leaf of leafTasks) {
|
|
565
|
+
let ancestor = leaf.parentId;
|
|
566
|
+
while (ancestor) {
|
|
567
|
+
const set = leafIdsByAncestor.get(ancestor) ?? /* @__PURE__ */ new Set();
|
|
568
|
+
set.add(leaf.id);
|
|
569
|
+
leafIdsByAncestor.set(ancestor, set);
|
|
570
|
+
ancestor = taskById.get(ancestor)?.parentId;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
const durationOf = (task) => getTaskDuration(task.startDate, task.endDate, businessDays, weekendPredicate);
|
|
574
|
+
const projectStartDate = leafTasks.reduce((earliest, task) => {
|
|
575
|
+
const taskStart = parseDateOnly(task.startDate);
|
|
576
|
+
return taskStart.getTime() < earliest.getTime() ? taskStart : earliest;
|
|
577
|
+
}, parseDateOnly(leafTasks[0]?.startDate ?? /* @__PURE__ */ new Date()));
|
|
578
|
+
const offsetFromProjectStart = (date) => {
|
|
579
|
+
const targetDate = parseDateOnly(date);
|
|
580
|
+
if (businessDays && weekendPredicate) {
|
|
581
|
+
return getBusinessDayOffset(projectStartDate, targetDate, weekendPredicate);
|
|
582
|
+
}
|
|
583
|
+
return Math.round((targetDate.getTime() - projectStartDate.getTime()) / DAY_MS);
|
|
584
|
+
};
|
|
585
|
+
const scheduledStart = /* @__PURE__ */ new Map();
|
|
586
|
+
for (const leaf of leafTasks) {
|
|
587
|
+
scheduledStart.set(leaf.id, offsetFromProjectStart(leaf.startDate));
|
|
588
|
+
}
|
|
589
|
+
const succByPred = /* @__PURE__ */ new Map();
|
|
590
|
+
const predBySucc = /* @__PURE__ */ new Map();
|
|
591
|
+
const seenEdges = /* @__PURE__ */ new Set();
|
|
592
|
+
const addEdge = (predecessorId, succId, lag, type) => {
|
|
593
|
+
const edgeKey = `${predecessorId}|${succId}|${type}`;
|
|
594
|
+
if (seenEdges.has(edgeKey)) return;
|
|
595
|
+
seenEdges.add(edgeKey);
|
|
596
|
+
const outEdges = succByPred.get(predecessorId) ?? [];
|
|
597
|
+
outEdges.push({ succId, lag, type });
|
|
598
|
+
succByPred.set(predecessorId, outEdges);
|
|
599
|
+
const inEdges = predBySucc.get(succId) ?? [];
|
|
600
|
+
inEdges.push({ predId: predecessorId, lag, type });
|
|
601
|
+
predBySucc.set(succId, inEdges);
|
|
602
|
+
};
|
|
603
|
+
for (const succ of leafTasks) {
|
|
604
|
+
for (const dep of succ.dependencies ?? []) {
|
|
605
|
+
const lag = getDependencyLag(dep);
|
|
606
|
+
if (leafIds.has(dep.taskId)) {
|
|
607
|
+
addEdge(dep.taskId, succ.id, lag, dep.type);
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
const descendants = leafIdsByAncestor.get(dep.taskId);
|
|
611
|
+
if (!descendants || descendants.size === 0) continue;
|
|
612
|
+
for (const leafId of descendants) {
|
|
613
|
+
if (leafId === succ.id) continue;
|
|
614
|
+
addEdge(leafId, succ.id, lag, dep.type);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
const indegree = /* @__PURE__ */ new Map();
|
|
619
|
+
for (const leaf of leafTasks) indegree.set(leaf.id, 0);
|
|
620
|
+
for (const edges of succByPred.values()) {
|
|
621
|
+
for (const { succId } of edges) {
|
|
622
|
+
indegree.set(succId, (indegree.get(succId) ?? 0) + 1);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
const order = [];
|
|
626
|
+
const enqueued = /* @__PURE__ */ new Set();
|
|
627
|
+
const queue = leafTasks.filter((leaf) => (indegree.get(leaf.id) ?? 0) === 0).map((leaf) => leaf.id);
|
|
628
|
+
for (const id of queue) enqueued.add(id);
|
|
629
|
+
while (queue.length > 0) {
|
|
630
|
+
const current = queue.shift();
|
|
631
|
+
order.push(current);
|
|
632
|
+
for (const { succId } of succByPred.get(current) ?? []) {
|
|
633
|
+
const next = (indegree.get(succId) ?? 0) - 1;
|
|
634
|
+
indegree.set(succId, next);
|
|
635
|
+
if (next === 0 && !enqueued.has(succId)) {
|
|
636
|
+
enqueued.add(succId);
|
|
637
|
+
queue.push(succId);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
const projectFinish = Math.max(
|
|
642
|
+
0,
|
|
643
|
+
...leafTasks.map((leaf) => (scheduledStart.get(leaf.id) ?? 0) + durationOf(leaf))
|
|
644
|
+
);
|
|
645
|
+
const LF = /* @__PURE__ */ new Map();
|
|
646
|
+
const LS = /* @__PURE__ */ new Map();
|
|
647
|
+
for (const leaf of leafTasks) LF.set(leaf.id, projectFinish);
|
|
648
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
649
|
+
const id = order[i];
|
|
650
|
+
const task = taskById.get(id);
|
|
651
|
+
const durPred = durationOf(task);
|
|
652
|
+
const outEdges = succByPred.get(id) ?? [];
|
|
653
|
+
let lf = projectFinish;
|
|
654
|
+
if (outEdges.length > 0) {
|
|
655
|
+
const candidates = outEdges.map(({ succId, lag, type }) => {
|
|
656
|
+
const succLs = LS.get(succId) ?? projectFinish;
|
|
657
|
+
const durSucc = durationOf(taskById.get(succId));
|
|
658
|
+
switch (type) {
|
|
659
|
+
case "FS":
|
|
660
|
+
return succLs - lag;
|
|
661
|
+
case "SS":
|
|
662
|
+
return succLs - lag + durPred;
|
|
663
|
+
case "FF":
|
|
664
|
+
return succLs + durSucc - lag;
|
|
665
|
+
case "SF":
|
|
666
|
+
return succLs + durSucc - lag + durPred;
|
|
667
|
+
default:
|
|
668
|
+
return projectFinish;
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
lf = Math.min(projectFinish, ...candidates);
|
|
672
|
+
}
|
|
673
|
+
LF.set(id, lf);
|
|
674
|
+
LS.set(id, lf - durPred);
|
|
675
|
+
}
|
|
676
|
+
const critical = /* @__PURE__ */ new Set();
|
|
677
|
+
const ordered = new Set(order);
|
|
678
|
+
for (const leaf of leafTasks) {
|
|
679
|
+
if (!ordered.has(leaf.id)) continue;
|
|
680
|
+
const hasGraphEdge = (succByPred.get(leaf.id)?.length ?? 0) > 0 || (predBySucc.get(leaf.id)?.length ?? 0) > 0;
|
|
681
|
+
if (!hasGraphEdge && (leaf.dependencies?.length ?? 0) > 0) continue;
|
|
682
|
+
const es = scheduledStart.get(leaf.id) ?? 0;
|
|
683
|
+
const ls = LS.get(leaf.id) ?? 0;
|
|
684
|
+
if (ls - es <= 0) critical.add(leaf.id);
|
|
685
|
+
}
|
|
686
|
+
return critical;
|
|
687
|
+
}
|
|
688
|
+
function extendCriticalIdsToParents(criticalLeafIds, tasks) {
|
|
689
|
+
const result = new Set(criticalLeafIds);
|
|
690
|
+
const parentByChild = /* @__PURE__ */ new Map();
|
|
691
|
+
for (const task of tasks) {
|
|
692
|
+
if (task.parentId) parentByChild.set(task.id, task.parentId);
|
|
693
|
+
}
|
|
694
|
+
const stack = Array.from(criticalLeafIds);
|
|
695
|
+
while (stack.length > 0) {
|
|
696
|
+
const id = stack.pop();
|
|
697
|
+
const parentId = parentByChild.get(id);
|
|
698
|
+
if (parentId && !result.has(parentId)) {
|
|
699
|
+
result.add(parentId);
|
|
700
|
+
stack.push(parentId);
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
return result;
|
|
704
|
+
}
|
|
705
|
+
|
|
553
706
|
// src/core/scheduling/commands.ts
|
|
554
707
|
function buildTaskRangeFromStart(startDate, duration, businessDays = false, weekendPredicate, snapDirection = 1) {
|
|
555
708
|
const normalizedStart = businessDays && weekendPredicate ? alignToWorkingDay(startDate, snapDirection, weekendPredicate) : normalizeUTCDate(startDate);
|
|
@@ -2412,8 +2565,7 @@ function handleGlobalMouseMove(e) {
|
|
|
2412
2565
|
activeDrag.weekendPredicate,
|
|
2413
2566
|
activeDrag.cascadeContext
|
|
2414
2567
|
);
|
|
2415
|
-
const
|
|
2416
|
-
const previewTasks = hasTasksWithIncomingDependencies ? (() => {
|
|
2568
|
+
const previewTasks = (() => {
|
|
2417
2569
|
const mergedPreviewTaskById = new Map(activeDrag.cascadeContext?.taskById);
|
|
2418
2570
|
for (const task of cascadeResult) {
|
|
2419
2571
|
mergedPreviewTaskById.set(task.id, task);
|
|
@@ -2434,7 +2586,7 @@ function handleGlobalMouseMove(e) {
|
|
|
2434
2586
|
) : task.dependencies
|
|
2435
2587
|
};
|
|
2436
2588
|
});
|
|
2437
|
-
})()
|
|
2589
|
+
})();
|
|
2438
2590
|
const overrides = /* @__PURE__ */ new Map();
|
|
2439
2591
|
overrides.set(dragId, { left: newLeft, width: newWidth });
|
|
2440
2592
|
for (const task of cascadeResult) {
|
|
@@ -2837,10 +2989,10 @@ var useTaskDrag = (options) => {
|
|
|
2837
2989
|
// src/components/TaskRow/TaskRow.tsx
|
|
2838
2990
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2839
2991
|
var arePropsEqual = (prevProps, nextProps) => {
|
|
2840
|
-
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode;
|
|
2992
|
+
return prevProps.task.id === nextProps.task.id && prevProps.task.name === nextProps.task.name && prevProps.task.startDate === nextProps.task.startDate && prevProps.task.endDate === nextProps.task.endDate && prevProps.task.baselineStartDate === nextProps.task.baselineStartDate && prevProps.task.baselineEndDate === nextProps.task.baselineEndDate && prevProps.task.type === nextProps.task.type && prevProps.task.color === nextProps.task.color && prevProps.task.progress === nextProps.task.progress && prevProps.task.accepted === nextProps.task.accepted && prevProps.monthStart.getTime() === nextProps.monthStart.getTime() && prevProps.dayWidth === nextProps.dayWidth && prevProps.rowHeight === nextProps.rowHeight && prevProps.overridePosition?.left === nextProps.overridePosition?.left && prevProps.overridePosition?.width === nextProps.overridePosition?.width && prevProps.previewPositionStore === nextProps.previewPositionStore && prevProps.allTasks === nextProps.allTasks && prevProps.disableConstraints === nextProps.disableConstraints && prevProps.task.locked === nextProps.task.locked && prevProps.task.synced === nextProps.task.synced && prevProps.task.divider === nextProps.task.divider && prevProps.highlightExpiredTasks === nextProps.highlightExpiredTasks && prevProps.isCritical === nextProps.isCritical && prevProps.showBaseline === nextProps.showBaseline && prevProps.isFilterMatch === nextProps.isFilterMatch && prevProps.businessDays === nextProps.businessDays && prevProps.customDays === nextProps.customDays && prevProps.isWeekend === nextProps.isWeekend && prevProps.disableTaskDrag === nextProps.disableTaskDrag && prevProps.disableDependencyEditing === nextProps.disableDependencyEditing && prevProps.isDependencyDragActive === nextProps.isDependencyDragActive && prevProps.viewMode === nextProps.viewMode;
|
|
2841
2993
|
};
|
|
2842
2994
|
var TaskRow = React2.memo(
|
|
2843
|
-
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day" }) => {
|
|
2995
|
+
({ task, monthStart, dayWidth, rowHeight, onTasksChange, onDragStateChange, rowIndex, allTasks, enableAutoSchedule, disableConstraints, overridePosition, previewPositionStore, onCascadeProgress, onCascade, divider, highlightExpiredTasks, isCritical = false, showBaseline = false, isFilterMatch = false, businessDays, customDays, isWeekend: isWeekend3, disableTaskDrag = false, disableDependencyEditing = false, onDependencyPortPointerDown, isDependencyDragActive = false, viewMode = "day" }) => {
|
|
2844
2996
|
const defaultParentBarColor = "#782FC4";
|
|
2845
2997
|
const { divider: taskDivider } = task;
|
|
2846
2998
|
const normalizedTask = useMemo2(() => normalizeTaskDatesForType(task), [task]);
|
|
@@ -3030,7 +3182,7 @@ var TaskRow = React2.memo(
|
|
|
3030
3182
|
"div",
|
|
3031
3183
|
{
|
|
3032
3184
|
"data-taskbar": true,
|
|
3033
|
-
className: `gantt-tr-taskBar ${isDragging ? "gantt-tr-dragging" : ""} ${task.locked ? "gantt-tr-locked" : ""} ${task.synced === false ? "gantt-tr-unsynced" : ""} ${isParent ? "gantt-tr-parentBar" : ""} ${milestone ? "gantt-tr-milestone" : ""}`,
|
|
3185
|
+
className: `gantt-tr-taskBar ${isDragging ? "gantt-tr-dragging" : ""} ${task.locked ? "gantt-tr-locked" : ""} ${task.synced === false ? "gantt-tr-unsynced" : ""} ${isParent ? "gantt-tr-parentBar" : ""} ${milestone ? "gantt-tr-milestone" : ""} ${isCritical ? "gantt-tr-critical" : ""}`,
|
|
3034
3186
|
style: {
|
|
3035
3187
|
left: `${visualLeft}px`,
|
|
3036
3188
|
...barStyle,
|
|
@@ -3445,6 +3597,7 @@ var DependencyLines = React6.memo(({
|
|
|
3445
3597
|
rowIndexByTaskId,
|
|
3446
3598
|
dragOverrides,
|
|
3447
3599
|
selectedDep,
|
|
3600
|
+
criticalTaskIds,
|
|
3448
3601
|
businessDays = true,
|
|
3449
3602
|
weekendPredicate,
|
|
3450
3603
|
onDependencyClick
|
|
@@ -3583,6 +3736,9 @@ var DependencyLines = React6.memo(({
|
|
|
3583
3736
|
const to = { x: finalToX, y: toY };
|
|
3584
3737
|
const path = calculateDependencyPath(from, to, arrivesFromRight);
|
|
3585
3738
|
const hasCycle = cycleInfo.has(edge.predecessorId) || cycleInfo.has(edge.successorId);
|
|
3739
|
+
const isCritical = Boolean(
|
|
3740
|
+
criticalTaskIds?.has(edge.predecessorId) && criticalTaskIds.has(edge.successorId)
|
|
3741
|
+
);
|
|
3586
3742
|
lines2.push({
|
|
3587
3743
|
id: `${edge.predecessorId}-${edge.successorId}-${edge.type}`,
|
|
3588
3744
|
predecessorId: edge.predecessorId,
|
|
@@ -3595,12 +3751,13 @@ var DependencyLines = React6.memo(({
|
|
|
3595
3751
|
toX: finalToX,
|
|
3596
3752
|
fromY,
|
|
3597
3753
|
reverseOrder,
|
|
3598
|
-
isVirtual
|
|
3754
|
+
isVirtual,
|
|
3755
|
+
isCritical
|
|
3599
3756
|
});
|
|
3600
3757
|
}
|
|
3601
3758
|
}
|
|
3602
3759
|
return lines2;
|
|
3603
|
-
}, [tasks, allTasks, taskPositions, taskIndices, cycleInfo, collapsedParentIds]);
|
|
3760
|
+
}, [tasks, allTasks, taskPositions, taskIndices, cycleInfo, collapsedParentIds, criticalTaskIds]);
|
|
3604
3761
|
const svgHeight = totalHeight ?? tasks.length * rowHeight;
|
|
3605
3762
|
return /* @__PURE__ */ jsxs5(
|
|
3606
3763
|
"svg",
|
|
@@ -3687,20 +3844,41 @@ var DependencyLines = React6.memo(({
|
|
|
3687
3844
|
}
|
|
3688
3845
|
)
|
|
3689
3846
|
}
|
|
3847
|
+
),
|
|
3848
|
+
/* @__PURE__ */ jsx7(
|
|
3849
|
+
"marker",
|
|
3850
|
+
{
|
|
3851
|
+
id: "arrowhead-critical",
|
|
3852
|
+
markerWidth: "8",
|
|
3853
|
+
markerHeight: "6",
|
|
3854
|
+
markerUnits: "userSpaceOnUse",
|
|
3855
|
+
refX: "7",
|
|
3856
|
+
refY: "3",
|
|
3857
|
+
orient: "auto",
|
|
3858
|
+
children: /* @__PURE__ */ jsx7(
|
|
3859
|
+
"polygon",
|
|
3860
|
+
{
|
|
3861
|
+
points: "0 0, 8 3, 0 6",
|
|
3862
|
+
fill: "var(--gantt-critical-path-color, #dc2626)"
|
|
3863
|
+
}
|
|
3864
|
+
)
|
|
3865
|
+
}
|
|
3690
3866
|
)
|
|
3691
3867
|
] }),
|
|
3692
|
-
lines.map(({ id, predecessorId, successorId, linkType, path, hasCycle, lag, fromX, toX, fromY, reverseOrder, isVirtual }) => {
|
|
3868
|
+
lines.map(({ id, predecessorId, successorId, linkType, path, hasCycle, lag, fromX, toX, fromY, reverseOrder, isVirtual, isCritical }) => {
|
|
3693
3869
|
const isHovered = hoveredLineId === id;
|
|
3694
3870
|
const isSelected = selectedDep != null && id === `${selectedDep.predecessorId}-${selectedDep.successorId}-${selectedDep.linkType}`;
|
|
3695
3871
|
let pathClassName = "gantt-dependency-path";
|
|
3696
3872
|
if (isSelected) pathClassName += " gantt-dependency-selected";
|
|
3697
3873
|
else if (hasCycle) pathClassName += " gantt-dependency-cycle";
|
|
3874
|
+
else if (isCritical) pathClassName += " gantt-dependency-critical";
|
|
3698
3875
|
if (isVirtual && !isSelected) pathClassName += " gantt-dependency-virtual";
|
|
3699
3876
|
let markerEnd;
|
|
3700
3877
|
if (isSelected) markerEnd = "url(#arrowhead-selected)";
|
|
3701
3878
|
else if (hasCycle) markerEnd = "url(#arrowhead-cycle)";
|
|
3879
|
+
else if (isCritical) markerEnd = "url(#arrowhead-critical)";
|
|
3702
3880
|
else markerEnd = "url(#arrowhead)";
|
|
3703
|
-
const lagColor = isSelected ? "#ef4444" : hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : "var(--gantt-dependency-line-color, #666666)";
|
|
3881
|
+
const lagColor = isSelected ? "#ef4444" : hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : isCritical ? "var(--gantt-critical-path-color, #dc2626)" : "var(--gantt-dependency-line-color, #666666)";
|
|
3704
3882
|
return /* @__PURE__ */ jsxs5(React6.Fragment, { children: [
|
|
3705
3883
|
/* @__PURE__ */ jsxs5(
|
|
3706
3884
|
"g",
|
|
@@ -7386,6 +7564,7 @@ var TaskList = ({
|
|
|
7386
7564
|
disableTaskListReorder = false,
|
|
7387
7565
|
editingTaskId: propEditingTaskId,
|
|
7388
7566
|
enableAddTask = true,
|
|
7567
|
+
addTaskLabel = "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0440\u0430\u0431\u043E\u0442\u0443",
|
|
7389
7568
|
defaultTaskDurationDays = DEFAULT_TASK_DURATION_DAYS,
|
|
7390
7569
|
collapsedParentIds: externalCollapsedParentIds,
|
|
7391
7570
|
onToggleCollapse: externalOnToggleCollapse,
|
|
@@ -8479,7 +8658,7 @@ var TaskList = ({
|
|
|
8479
8658
|
nestingDepth: 0
|
|
8480
8659
|
}
|
|
8481
8660
|
),
|
|
8482
|
-
enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */
|
|
8661
|
+
enableAddTask && onAdd && !isCreating && !pendingInsert && /* @__PURE__ */ jsxs12(
|
|
8483
8662
|
"button",
|
|
8484
8663
|
{
|
|
8485
8664
|
className: `gantt-tl-add-btn${!reorderDisabled && dragOverTarget?.index === visibleTasks.length ? " gantt-tl-add-btn-drag-over" : ""}`,
|
|
@@ -8505,7 +8684,10 @@ var TaskList = ({
|
|
|
8505
8684
|
handleDrop(visibleTasks.length, e);
|
|
8506
8685
|
},
|
|
8507
8686
|
type: "button",
|
|
8508
|
-
children:
|
|
8687
|
+
children: [
|
|
8688
|
+
"+ ",
|
|
8689
|
+
addTaskLabel
|
|
8690
|
+
]
|
|
8509
8691
|
}
|
|
8510
8692
|
)
|
|
8511
8693
|
] })
|
|
@@ -12401,6 +12583,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12401
12583
|
onDemoteTask,
|
|
12402
12584
|
onUngroupTask,
|
|
12403
12585
|
enableAddTask = true,
|
|
12586
|
+
addTaskLabel = "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0440\u0430\u0431\u043E\u0442\u0443",
|
|
12404
12587
|
defaultTaskDurationDays,
|
|
12405
12588
|
taskFilter,
|
|
12406
12589
|
filterMode = "highlight",
|
|
@@ -12427,6 +12610,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12427
12610
|
onTaskDateChangeModeChange: externalOnTaskDateChangeModeChange
|
|
12428
12611
|
} = props;
|
|
12429
12612
|
const dayWidth = !isTableMatrixMode ? props.dayWidth ?? 40 : 40;
|
|
12613
|
+
const criticalPathMode = !isTableMatrixMode && !isPlanFactMode ? props.criticalPathMode : void 0;
|
|
12430
12614
|
const viewMode = !isTableMatrixMode && !isPlanFactMode ? props.viewMode ?? "day" : "day";
|
|
12431
12615
|
const customDays = !isTableMatrixMode ? props.customDays : void 0;
|
|
12432
12616
|
const isWeekend3 = !isTableMatrixMode ? props.isWeekend : void 0;
|
|
@@ -12626,10 +12810,23 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12626
12810
|
[resolvedRowContentLines, rowHeight]
|
|
12627
12811
|
);
|
|
12628
12812
|
const normalizedTasks = useMemo13(() => normalizeHierarchyTasks(tasks), [tasks]);
|
|
12813
|
+
const [previewTasksById, setPreviewTasksById] = useState12(/* @__PURE__ */ new Map());
|
|
12814
|
+
const previewNormalizedTasks = useMemo13(() => {
|
|
12815
|
+
if (previewTasksById.size === 0) return normalizedTasks;
|
|
12816
|
+
return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
12817
|
+
}, [normalizedTasks, previewTasksById]);
|
|
12629
12818
|
const isCustomWeekend = useMemo13(
|
|
12630
12819
|
() => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
|
|
12631
12820
|
[customDays, isWeekend3]
|
|
12632
12821
|
);
|
|
12822
|
+
const criticalTaskIds = useMemo13(() => {
|
|
12823
|
+
if (!criticalPathMode) return /* @__PURE__ */ new Set();
|
|
12824
|
+
const leafCritical = computeCriticalPath(previewNormalizedTasks, {
|
|
12825
|
+
businessDays,
|
|
12826
|
+
weekendPredicate: isCustomWeekend
|
|
12827
|
+
});
|
|
12828
|
+
return extendCriticalIdsToParents(leafCritical, previewNormalizedTasks);
|
|
12829
|
+
}, [criticalPathMode, previewNormalizedTasks, businessDays, isCustomWeekend]);
|
|
12633
12830
|
const dateRangeTasks = useMemo13(() => {
|
|
12634
12831
|
if (isPlanFactMode) {
|
|
12635
12832
|
return getPlanFactRangeTasks(normalizedTasks);
|
|
@@ -12674,8 +12871,11 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12674
12871
|
if (filterMode === "hide" && taskFilter) {
|
|
12675
12872
|
tasks2 = tasks2.filter(taskFilter);
|
|
12676
12873
|
}
|
|
12874
|
+
if (criticalPathMode === "hide") {
|
|
12875
|
+
tasks2 = tasks2.filter((task) => criticalTaskIds.has(task.id));
|
|
12876
|
+
}
|
|
12677
12877
|
return tasks2;
|
|
12678
|
-
}, [normalizedTasks, collapsedParentIds, filterMode, taskFilter]);
|
|
12878
|
+
}, [normalizedTasks, collapsedParentIds, filterMode, taskFilter, criticalPathMode, criticalTaskIds]);
|
|
12679
12879
|
const matchedTaskIds = useMemo13(() => {
|
|
12680
12880
|
if (!taskFilter) return /* @__PURE__ */ new Set();
|
|
12681
12881
|
return new Set(visibleTasks.filter(taskFilter).map((task) => task.id));
|
|
@@ -12868,7 +13068,6 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12868
13068
|
}, [effectiveRowHeight, tasks, visibleTasks]);
|
|
12869
13069
|
const [dragGuideLines, setDragGuideLines] = useState12(null);
|
|
12870
13070
|
const [draggedTaskOverride, setDraggedTaskOverride] = useState12(null);
|
|
12871
|
-
const [previewTasksById, setPreviewTasksById] = useState12(/* @__PURE__ */ new Map());
|
|
12872
13071
|
useEffect10(() => {
|
|
12873
13072
|
const result = validateDependencies(tasks);
|
|
12874
13073
|
setValidationResult(result);
|
|
@@ -12996,14 +13195,10 @@ function TaskGanttChartInner(props, ref) {
|
|
|
12996
13195
|
}
|
|
12997
13196
|
setCascadeOverrides((current) => arePositionMapsEqual(current, renderedOverrides) ? current : renderedOverrides);
|
|
12998
13197
|
setPreviewTasksById((current) => {
|
|
12999
|
-
const next = previewTasks.length > 0 ? new Map(previewTasks.
|
|
13198
|
+
const next = previewTasks.length > 0 ? new Map(previewTasks.map((task) => [task.id, task])) : /* @__PURE__ */ new Map();
|
|
13000
13199
|
return arePreviewTaskMapsEqual(current, next) ? current : next;
|
|
13001
13200
|
});
|
|
13002
13201
|
}, [previewPositionStore]);
|
|
13003
|
-
const previewNormalizedTasks = useMemo13(() => {
|
|
13004
|
-
if (previewTasksById.size === 0) return normalizedTasks;
|
|
13005
|
-
return normalizedTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
13006
|
-
}, [normalizedTasks, previewTasksById]);
|
|
13007
13202
|
const previewVisibleTasks = useMemo13(() => {
|
|
13008
13203
|
if (previewTasksById.size === 0) return visibleTasks;
|
|
13009
13204
|
return visibleTasks.map((task) => previewTasksById.get(task.id) ?? task);
|
|
@@ -13431,6 +13626,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
13431
13626
|
disableTaskDrag: disableTaskDrag || disableTaskListReorder,
|
|
13432
13627
|
editingTaskId,
|
|
13433
13628
|
enableAddTask,
|
|
13629
|
+
addTaskLabel,
|
|
13434
13630
|
defaultTaskDurationDays,
|
|
13435
13631
|
collapsedParentIds,
|
|
13436
13632
|
onToggleCollapse: handleToggleCollapse,
|
|
@@ -13602,7 +13798,8 @@ function TaskGanttChartInner(props, ref) {
|
|
|
13602
13798
|
selectedDep: selectedChip,
|
|
13603
13799
|
businessDays,
|
|
13604
13800
|
weekendPredicate: isCustomWeekend,
|
|
13605
|
-
onDependencyClick: handleDependencyLineClick
|
|
13801
|
+
onDependencyClick: handleDependencyLineClick,
|
|
13802
|
+
criticalTaskIds: criticalPathMode ? criticalTaskIds : void 0
|
|
13606
13803
|
}
|
|
13607
13804
|
),
|
|
13608
13805
|
dependencyLineMenu && /* @__PURE__ */ jsxs16(
|
|
@@ -13672,6 +13869,9 @@ function TaskGanttChartInner(props, ref) {
|
|
|
13672
13869
|
} else {
|
|
13673
13870
|
setDragGuideLines((current) => current === null ? current : null);
|
|
13674
13871
|
setDraggedTaskOverride((current) => current === null ? current : null);
|
|
13872
|
+
previewPositionStore.clear();
|
|
13873
|
+
setCascadeOverrides((current) => current.size === 0 ? current : /* @__PURE__ */ new Map());
|
|
13874
|
+
setPreviewTasksById((current) => current.size === 0 ? current : /* @__PURE__ */ new Map());
|
|
13675
13875
|
}
|
|
13676
13876
|
},
|
|
13677
13877
|
rowIndex: index,
|
|
@@ -13684,6 +13884,7 @@ function TaskGanttChartInner(props, ref) {
|
|
|
13684
13884
|
highlightExpiredTasks,
|
|
13685
13885
|
showBaseline,
|
|
13686
13886
|
isFilterMatch: filterMode === "highlight" ? matchedTaskIds.has(task.id) : false,
|
|
13887
|
+
isCritical: criticalTaskIds.has(task.id),
|
|
13687
13888
|
businessDays,
|
|
13688
13889
|
customDays,
|
|
13689
13890
|
isWeekend: isWeekend3,
|
|
@@ -13805,6 +14006,7 @@ export {
|
|
|
13805
14006
|
cascadeByLinks,
|
|
13806
14007
|
clampDateRangeForIncomingFS,
|
|
13807
14008
|
clampTaskRangeForIncomingFS,
|
|
14009
|
+
computeCriticalPath,
|
|
13808
14010
|
computeLagFromDates,
|
|
13809
14011
|
computeParentDates,
|
|
13810
14012
|
computeParentProgress,
|
|
@@ -13813,6 +14015,7 @@ export {
|
|
|
13813
14015
|
detectCycles,
|
|
13814
14016
|
detectEdgeZone,
|
|
13815
14017
|
expired,
|
|
14018
|
+
extendCriticalIdsToParents,
|
|
13816
14019
|
findParentId,
|
|
13817
14020
|
flattenHierarchy,
|
|
13818
14021
|
formatDateLabel,
|