gantt-lib 0.0.6 → 0.0.7
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/README.md +195 -6
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +27 -3
- package/dist/index.d.ts +27 -3
- package/dist/index.js +321 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +320 -62
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +26 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
TodayIndicator: () => TodayIndicator_default,
|
|
40
40
|
buildAdjacencyList: () => buildAdjacencyList,
|
|
41
41
|
calculateBezierPath: () => calculateBezierPath,
|
|
42
|
+
calculateDependencyPath: () => calculateDependencyPath,
|
|
42
43
|
calculateGridLines: () => calculateGridLines,
|
|
43
44
|
calculateGridWidth: () => calculateGridWidth,
|
|
44
45
|
calculateOrthogonalPath: () => calculateOrthogonalPath,
|
|
@@ -295,7 +296,7 @@ function validateDependencies(tasks) {
|
|
|
295
296
|
errors
|
|
296
297
|
};
|
|
297
298
|
}
|
|
298
|
-
function getSuccessorChain(draggedTaskId, allTasks) {
|
|
299
|
+
function getSuccessorChain(draggedTaskId, allTasks, linkTypes = ["FS"]) {
|
|
299
300
|
const successorMap = /* @__PURE__ */ new Map();
|
|
300
301
|
for (const task of allTasks) {
|
|
301
302
|
successorMap.set(task.id, []);
|
|
@@ -303,7 +304,7 @@ function getSuccessorChain(draggedTaskId, allTasks) {
|
|
|
303
304
|
for (const task of allTasks) {
|
|
304
305
|
if (!task.dependencies) continue;
|
|
305
306
|
for (const dep of task.dependencies) {
|
|
306
|
-
if (dep.type
|
|
307
|
+
if (linkTypes.includes(dep.type)) {
|
|
307
308
|
const list = successorMap.get(dep.taskId) ?? [];
|
|
308
309
|
list.push(task.id);
|
|
309
310
|
successorMap.set(dep.taskId, list);
|
|
@@ -525,6 +526,43 @@ var calculateBezierPath = (from, to) => {
|
|
|
525
526
|
const cp2y = to.y - (to.y > from.y ? cpOffset : -cpOffset);
|
|
526
527
|
return `M ${Math.round(from.x)} ${Math.round(from.y)} C ${Math.round(cp1x)} ${Math.round(cp1y)}, ${Math.round(cp2x)} ${Math.round(cp2y)}, ${Math.round(to.x)} ${Math.round(to.y)}`;
|
|
527
528
|
};
|
|
529
|
+
var calculateDependencyPath = (from, to, arrivesFromRight) => {
|
|
530
|
+
const fx = Math.round(from.x);
|
|
531
|
+
const fy = Math.round(from.y);
|
|
532
|
+
const tx = Math.round(to.x);
|
|
533
|
+
const ty = Math.round(to.y);
|
|
534
|
+
if (fy === ty) {
|
|
535
|
+
return `M ${fx} ${fy} H ${tx}`;
|
|
536
|
+
}
|
|
537
|
+
const C = 2;
|
|
538
|
+
const goingDown = ty > fy;
|
|
539
|
+
const dirY = goingDown ? 1 : -1;
|
|
540
|
+
if (arrivesFromRight) {
|
|
541
|
+
const goingRight = tx >= fx;
|
|
542
|
+
const dirX = goingRight ? 1 : -1;
|
|
543
|
+
if (Math.abs(ty - fy) >= C && Math.abs(tx - fx) >= C) {
|
|
544
|
+
return [
|
|
545
|
+
`M ${fx} ${fy}`,
|
|
546
|
+
`H ${tx - dirX * C}`,
|
|
547
|
+
`L ${tx} ${fy + dirY * C}`,
|
|
548
|
+
`V ${ty}`
|
|
549
|
+
].join(" ");
|
|
550
|
+
}
|
|
551
|
+
return `M ${fx} ${fy} H ${tx} V ${ty}`;
|
|
552
|
+
} else {
|
|
553
|
+
const goingRight = tx >= fx;
|
|
554
|
+
const dirX = goingRight ? 1 : -1;
|
|
555
|
+
if (Math.abs(ty - fy) >= C && Math.abs(tx - fx) >= C) {
|
|
556
|
+
return [
|
|
557
|
+
`M ${fx} ${fy}`,
|
|
558
|
+
`H ${tx - dirX * C}`,
|
|
559
|
+
`L ${tx} ${fy + dirY * C}`,
|
|
560
|
+
`V ${ty}`
|
|
561
|
+
].join(" ");
|
|
562
|
+
}
|
|
563
|
+
return `M ${fx} ${fy} H ${tx} V ${ty}`;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
528
566
|
var calculateOrthogonalPath = (from, to) => {
|
|
529
567
|
const fx = Math.round(from.x);
|
|
530
568
|
const fy = Math.round(from.y);
|
|
@@ -551,6 +589,36 @@ var calculateOrthogonalPath = (from, to) => {
|
|
|
551
589
|
|
|
552
590
|
// src/hooks/useTaskDrag.ts
|
|
553
591
|
var import_react2 = require("react");
|
|
592
|
+
function getTransitiveCascadeChain(draggedTaskId, allTasks, firstLevelLinkTypes) {
|
|
593
|
+
const allTypesSuccessorMap = /* @__PURE__ */ new Map();
|
|
594
|
+
for (const task of allTasks) {
|
|
595
|
+
allTypesSuccessorMap.set(task.id, []);
|
|
596
|
+
}
|
|
597
|
+
for (const task of allTasks) {
|
|
598
|
+
if (!task.dependencies) continue;
|
|
599
|
+
for (const dep of task.dependencies) {
|
|
600
|
+
const list = allTypesSuccessorMap.get(dep.taskId) ?? [];
|
|
601
|
+
list.push(task);
|
|
602
|
+
allTypesSuccessorMap.set(dep.taskId, list);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
const directSuccessors = getSuccessorChain(draggedTaskId, allTasks, firstLevelLinkTypes);
|
|
606
|
+
const chain = [...directSuccessors];
|
|
607
|
+
const visited = /* @__PURE__ */ new Set([draggedTaskId, ...directSuccessors.map((t) => t.id)]);
|
|
608
|
+
const queue = [...directSuccessors];
|
|
609
|
+
while (queue.length > 0) {
|
|
610
|
+
const current = queue.shift();
|
|
611
|
+
const successors = allTypesSuccessorMap.get(current.id) ?? [];
|
|
612
|
+
for (const successor of successors) {
|
|
613
|
+
if (!visited.has(successor.id)) {
|
|
614
|
+
visited.add(successor.id);
|
|
615
|
+
chain.push(successor);
|
|
616
|
+
queue.push(successor);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
return chain;
|
|
621
|
+
}
|
|
554
622
|
var globalActiveDrag = null;
|
|
555
623
|
var globalRafId = null;
|
|
556
624
|
function completeDrag() {
|
|
@@ -579,25 +647,43 @@ function cancelDrag() {
|
|
|
579
647
|
function snapToGrid(pixels, dayWidth) {
|
|
580
648
|
return Math.round(pixels / dayWidth) * dayWidth;
|
|
581
649
|
}
|
|
582
|
-
function recalculateIncomingLags(task, newStartDate, allTasks) {
|
|
650
|
+
function recalculateIncomingLags(task, newStartDate, newEndDate, allTasks) {
|
|
583
651
|
if (!task.dependencies) return [];
|
|
584
652
|
const taskById = new Map(allTasks.map((t) => [t.id, t]));
|
|
585
653
|
return task.dependencies.map((dep) => {
|
|
586
|
-
if (dep.type
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
)
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
654
|
+
if (dep.type === "FS") {
|
|
655
|
+
const predecessor = taskById.get(dep.taskId);
|
|
656
|
+
if (!predecessor) return dep;
|
|
657
|
+
const predEnd = new Date(predecessor.endDate);
|
|
658
|
+
const lagMs = Date.UTC(newStartDate.getUTCFullYear(), newStartDate.getUTCMonth(), newStartDate.getUTCDate()) - Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());
|
|
659
|
+
const lagDays = Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
660
|
+
return { ...dep, lag: lagDays };
|
|
661
|
+
}
|
|
662
|
+
if (dep.type === "SS") {
|
|
663
|
+
const predecessor = taskById.get(dep.taskId);
|
|
664
|
+
if (!predecessor) return dep;
|
|
665
|
+
const predStart = new Date(predecessor.startDate);
|
|
666
|
+
const lagMs = Date.UTC(newStartDate.getUTCFullYear(), newStartDate.getUTCMonth(), newStartDate.getUTCDate()) - Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate());
|
|
667
|
+
const lagDays = Math.max(0, Math.round(lagMs / (24 * 60 * 60 * 1e3)));
|
|
668
|
+
return { ...dep, lag: lagDays };
|
|
669
|
+
}
|
|
670
|
+
if (dep.type === "FF") {
|
|
671
|
+
const predecessor = taskById.get(dep.taskId);
|
|
672
|
+
if (!predecessor) return dep;
|
|
673
|
+
const predEnd = new Date(predecessor.endDate);
|
|
674
|
+
const lagMs = Date.UTC(newEndDate.getUTCFullYear(), newEndDate.getUTCMonth(), newEndDate.getUTCDate()) - Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());
|
|
675
|
+
const lagDays = Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
676
|
+
return { ...dep, lag: lagDays };
|
|
677
|
+
}
|
|
678
|
+
if (dep.type === "SF") {
|
|
679
|
+
const predecessor = taskById.get(dep.taskId);
|
|
680
|
+
if (!predecessor) return dep;
|
|
681
|
+
const predStart = new Date(predecessor.startDate);
|
|
682
|
+
const lagMs = Date.UTC(newEndDate.getUTCFullYear(), newEndDate.getUTCMonth(), newEndDate.getUTCDate()) - Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate()) + 24 * 60 * 60 * 1e3;
|
|
683
|
+
const lagDays = Math.min(0, Math.round(lagMs / (24 * 60 * 60 * 1e3)));
|
|
684
|
+
return { ...dep, lag: lagDays };
|
|
685
|
+
}
|
|
686
|
+
return dep;
|
|
601
687
|
});
|
|
602
688
|
}
|
|
603
689
|
function handleGlobalMouseMove(e) {
|
|
@@ -628,12 +714,12 @@ function handleGlobalMouseMove(e) {
|
|
|
628
714
|
newWidth = Math.max(dayWidth, snappedWidth);
|
|
629
715
|
break;
|
|
630
716
|
}
|
|
631
|
-
if (mode === "move" && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
717
|
+
if ((mode === "move" || mode === "resize-left") && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
632
718
|
const currentTask = allTasks.find((t) => t.id === globalActiveDrag?.taskId);
|
|
633
719
|
if (currentTask && currentTask.dependencies && currentTask.dependencies.length > 0) {
|
|
634
720
|
let minAllowedLeft = 0;
|
|
635
721
|
for (const dep of currentTask.dependencies) {
|
|
636
|
-
if (dep.type !== "FS") continue;
|
|
722
|
+
if (dep.type !== "FS" && dep.type !== "SS") continue;
|
|
637
723
|
const predecessor = globalActiveDrag.allTasks.find((t) => t.id === dep.taskId);
|
|
638
724
|
if (!predecessor) continue;
|
|
639
725
|
const predStart = new Date(predecessor.startDate);
|
|
@@ -649,25 +735,91 @@ function handleGlobalMouseMove(e) {
|
|
|
649
735
|
}
|
|
650
736
|
newLeft = Math.max(minAllowedLeft, newLeft);
|
|
651
737
|
}
|
|
738
|
+
if (mode === "resize-left") {
|
|
739
|
+
const rightEdge = globalActiveDrag.initialLeft + globalActiveDrag.initialWidth;
|
|
740
|
+
newWidth = Math.max(globalActiveDrag.dayWidth, rightEdge - newLeft);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
if ((mode === "move" || mode === "resize-right") && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
744
|
+
const currentTask = allTasks.find((t) => t.id === globalActiveDrag?.taskId);
|
|
745
|
+
if (currentTask && currentTask.dependencies && currentTask.dependencies.length > 0) {
|
|
746
|
+
for (const dep of currentTask.dependencies) {
|
|
747
|
+
if (dep.type !== "SF") continue;
|
|
748
|
+
const predecessor = globalActiveDrag.allTasks.find((t) => t.id === dep.taskId);
|
|
749
|
+
if (!predecessor) continue;
|
|
750
|
+
const predStart = new Date(predecessor.startDate);
|
|
751
|
+
const predStartOffset = Math.round(
|
|
752
|
+
(Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate()) - Date.UTC(globalActiveDrag.monthStart.getUTCFullYear(), globalActiveDrag.monthStart.getUTCDate(), globalActiveDrag.monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
753
|
+
);
|
|
754
|
+
const predStartLeft = Math.round(predStartOffset * globalActiveDrag.dayWidth);
|
|
755
|
+
const sfBoundaryRight = predStartLeft;
|
|
756
|
+
if (mode === "move") {
|
|
757
|
+
const proposedEndRight = newLeft + globalActiveDrag.initialWidth;
|
|
758
|
+
if (proposedEndRight > sfBoundaryRight) {
|
|
759
|
+
newLeft = Math.max(globalActiveDrag.initialLeft, sfBoundaryRight - globalActiveDrag.initialWidth);
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
const currentEndRight = newLeft + newWidth;
|
|
763
|
+
if (currentEndRight > sfBoundaryRight) {
|
|
764
|
+
newWidth = Math.max(globalActiveDrag.dayWidth, sfBoundaryRight - newLeft);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
652
769
|
}
|
|
653
|
-
|
|
770
|
+
const activeChain = mode === "resize-right" ? globalActiveDrag.cascadeChainEnd : (
|
|
771
|
+
// FS + FF
|
|
772
|
+
mode === "resize-left" ? globalActiveDrag.cascadeChainStart : (
|
|
773
|
+
// SS + SF
|
|
774
|
+
/* move */
|
|
775
|
+
globalActiveDrag.cascadeChain
|
|
776
|
+
)
|
|
777
|
+
);
|
|
778
|
+
if ((mode === "move" || mode === "resize-right" || mode === "resize-left" && globalActiveDrag.cascadeChainStart.length > 0) && !globalActiveDrag.disableConstraints && activeChain.length > 0 && globalActiveDrag.onCascadeProgress) {
|
|
654
779
|
const deltaDays = mode === "resize-right" ? Math.round((newWidth - globalActiveDrag.initialWidth) / globalActiveDrag.dayWidth) : Math.round((newLeft - globalActiveDrag.initialLeft) / globalActiveDrag.dayWidth);
|
|
655
780
|
const overrides = /* @__PURE__ */ new Map();
|
|
656
|
-
|
|
781
|
+
const draggedTaskId = globalActiveDrag.taskId;
|
|
782
|
+
const dayWidth2 = globalActiveDrag.dayWidth;
|
|
783
|
+
const monthStart = globalActiveDrag.monthStart;
|
|
784
|
+
for (const chainTask of activeChain) {
|
|
657
785
|
const chainStart = new Date(chainTask.startDate);
|
|
658
786
|
const chainEnd = new Date(chainTask.endDate);
|
|
659
787
|
const chainStartOffset = Math.round(
|
|
660
788
|
(Date.UTC(chainStart.getUTCFullYear(), chainStart.getUTCMonth(), chainStart.getUTCDate()) - Date.UTC(
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
789
|
+
monthStart.getUTCFullYear(),
|
|
790
|
+
monthStart.getUTCMonth(),
|
|
791
|
+
monthStart.getUTCDate()
|
|
792
|
+
)) / (24 * 60 * 60 * 1e3)
|
|
793
|
+
);
|
|
794
|
+
const chainEndOffset = Math.round(
|
|
795
|
+
(Date.UTC(chainEnd.getUTCFullYear(), chainEnd.getUTCMonth(), chainEnd.getUTCDate()) - Date.UTC(
|
|
796
|
+
monthStart.getUTCFullYear(),
|
|
797
|
+
monthStart.getUTCMonth(),
|
|
798
|
+
monthStart.getUTCDate()
|
|
664
799
|
)) / (24 * 60 * 60 * 1e3)
|
|
665
800
|
);
|
|
666
801
|
const chainDuration = Math.round(
|
|
667
802
|
(Date.UTC(chainEnd.getUTCFullYear(), chainEnd.getUTCMonth(), chainEnd.getUTCDate()) - Date.UTC(chainStart.getUTCFullYear(), chainStart.getUTCMonth(), chainStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
668
803
|
);
|
|
669
|
-
const
|
|
670
|
-
|
|
804
|
+
const hasFFDepOnDragged = chainTask.dependencies?.some(
|
|
805
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "FF"
|
|
806
|
+
);
|
|
807
|
+
const hasSFDepOnDragged = chainTask.dependencies?.some(
|
|
808
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "SF"
|
|
809
|
+
);
|
|
810
|
+
let chainLeft;
|
|
811
|
+
if (hasFFDepOnDragged || hasSFDepOnDragged) {
|
|
812
|
+
chainLeft = Math.round((chainEndOffset + deltaDays - chainDuration) * dayWidth2);
|
|
813
|
+
} else {
|
|
814
|
+
chainLeft = Math.round((chainStartOffset + deltaDays) * dayWidth2);
|
|
815
|
+
}
|
|
816
|
+
const chainWidth = Math.round((chainDuration + 1) * dayWidth2);
|
|
817
|
+
const hasSSDepOnDragged = chainTask.dependencies?.some(
|
|
818
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "SS"
|
|
819
|
+
);
|
|
820
|
+
if (hasSSDepOnDragged && (mode === "move" || mode === "resize-left")) {
|
|
821
|
+
chainLeft = Math.max(chainLeft, newLeft);
|
|
822
|
+
}
|
|
671
823
|
overrides.set(chainTask.id, { left: chainLeft, width: chainWidth });
|
|
672
824
|
}
|
|
673
825
|
globalActiveDrag.onCascadeProgress(overrides);
|
|
@@ -778,19 +930,32 @@ var useTaskDrag = (options) => {
|
|
|
778
930
|
}
|
|
779
931
|
if (wasOwner) {
|
|
780
932
|
if (!disableConstraints && onCascade && allTasks.length > 0) {
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
)
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
933
|
+
const origStartMs = Date.UTC(
|
|
934
|
+
initialStartDate.getUTCFullYear(),
|
|
935
|
+
initialStartDate.getUTCMonth(),
|
|
936
|
+
initialStartDate.getUTCDate()
|
|
937
|
+
);
|
|
938
|
+
const newStartMs = Date.UTC(
|
|
939
|
+
newStartDate.getUTCFullYear(),
|
|
940
|
+
newStartDate.getUTCMonth(),
|
|
941
|
+
newStartDate.getUTCDate()
|
|
942
|
+
);
|
|
943
|
+
const deltaFromStart = Math.round((newStartMs - origStartMs) / (24 * 60 * 60 * 1e3));
|
|
944
|
+
const origEndMs = Date.UTC(
|
|
945
|
+
initialEndDate.getUTCFullYear(),
|
|
946
|
+
initialEndDate.getUTCMonth(),
|
|
947
|
+
initialEndDate.getUTCDate()
|
|
948
|
+
);
|
|
949
|
+
const newEndMs = Date.UTC(
|
|
950
|
+
newEndDate.getUTCFullYear(),
|
|
951
|
+
newEndDate.getUTCMonth(),
|
|
952
|
+
newEndDate.getUTCDate()
|
|
953
|
+
);
|
|
954
|
+
const deltaFromEnd = Math.round((newEndMs - origEndMs) / (24 * 60 * 60 * 1e3));
|
|
955
|
+
const deltaDays = deltaFromStart === 0 ? deltaFromEnd : deltaFromStart;
|
|
956
|
+
const isResizeLeft = deltaFromStart !== 0 && deltaFromEnd === 0;
|
|
957
|
+
const chainForCompletion = deltaFromStart === 0 ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "FF"]) : isResizeLeft ? getTransitiveCascadeChain(taskId, allTasks, ["SS", "SF"]) : getTransitiveCascadeChain(taskId, allTasks, ["FS", "SS", "FF", "SF"]);
|
|
958
|
+
if (chainForCompletion.length > 0) {
|
|
794
959
|
const draggedTaskData = allTasks.find((t) => t.id === taskId);
|
|
795
960
|
const cascadedTasks = [
|
|
796
961
|
{
|
|
@@ -798,10 +963,10 @@ var useTaskDrag = (options) => {
|
|
|
798
963
|
startDate: newStartDate.toISOString(),
|
|
799
964
|
endDate: newEndDate.toISOString(),
|
|
800
965
|
...draggedTaskData?.dependencies && {
|
|
801
|
-
dependencies: recalculateIncomingLags(draggedTaskData, newStartDate, allTasks)
|
|
966
|
+
dependencies: recalculateIncomingLags(draggedTaskData, newStartDate, newEndDate, allTasks)
|
|
802
967
|
}
|
|
803
968
|
},
|
|
804
|
-
...
|
|
969
|
+
...chainForCompletion.map((chainTask) => {
|
|
805
970
|
const origStart = new Date(chainTask.startDate);
|
|
806
971
|
const origEnd = new Date(chainTask.endDate);
|
|
807
972
|
const newStart = new Date(Date.UTC(
|
|
@@ -823,7 +988,7 @@ var useTaskDrag = (options) => {
|
|
|
823
988
|
}
|
|
824
989
|
if (allTasks.length > 0 && onDragEnd) {
|
|
825
990
|
const currentTaskData = allTasks.find((t) => t.id === taskId);
|
|
826
|
-
const updatedDependencies = currentTaskData?.dependencies ? recalculateIncomingLags(currentTaskData, newStartDate, allTasks) : void 0;
|
|
991
|
+
const updatedDependencies = currentTaskData?.dependencies ? recalculateIncomingLags(currentTaskData, newStartDate, newEndDate, allTasks) : void 0;
|
|
827
992
|
onDragEnd({ id: taskId, startDate: newStartDate, endDate: newEndDate, updatedDependencies });
|
|
828
993
|
} else if (onDragEnd) {
|
|
829
994
|
onDragEnd({ id: taskId, startDate: newStartDate, endDate: newEndDate });
|
|
@@ -899,7 +1064,10 @@ var useTaskDrag = (options) => {
|
|
|
899
1064
|
onCancel: handleCancel,
|
|
900
1065
|
allTasks,
|
|
901
1066
|
disableConstraints,
|
|
902
|
-
cascadeChain: (
|
|
1067
|
+
cascadeChain: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "SS", "FF", "SF"]) : [],
|
|
1068
|
+
cascadeChainFS: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS"]) : [],
|
|
1069
|
+
cascadeChainStart: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["SS", "SF"]) : [],
|
|
1070
|
+
cascadeChainEnd: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "FF"]) : [],
|
|
903
1071
|
onCascadeProgress
|
|
904
1072
|
};
|
|
905
1073
|
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade]);
|
|
@@ -988,6 +1156,8 @@ var TaskRow = import_react3.default.memo(
|
|
|
988
1156
|
const durationDays = Math.round(
|
|
989
1157
|
(currentEndDate.getTime() - currentStartDate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
990
1158
|
) + 1;
|
|
1159
|
+
const estimatedTextWidth = durationDays >= 10 ? 76 : 62;
|
|
1160
|
+
const showProgressInside = progressWidth > 0 && displayWidth > estimatedTextWidth;
|
|
991
1161
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
992
1162
|
"div",
|
|
993
1163
|
{
|
|
@@ -1024,6 +1194,10 @@ var TaskRow = import_react3.default.memo(
|
|
|
1024
1194
|
durationDays,
|
|
1025
1195
|
" \u0434"
|
|
1026
1196
|
] }),
|
|
1197
|
+
progressWidth > 0 && showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-progressText", children: [
|
|
1198
|
+
progressWidth,
|
|
1199
|
+
"%"
|
|
1200
|
+
] }),
|
|
1027
1201
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleRight" })
|
|
1028
1202
|
]
|
|
1029
1203
|
}
|
|
@@ -1042,14 +1216,20 @@ var TaskRow = import_react3.default.memo(
|
|
|
1042
1216
|
] })
|
|
1043
1217
|
}
|
|
1044
1218
|
),
|
|
1045
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1219
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1046
1220
|
"div",
|
|
1047
1221
|
{
|
|
1048
1222
|
className: "gantt-tr-rightLabels",
|
|
1049
1223
|
style: {
|
|
1050
1224
|
left: `${displayLeft + displayWidth}px`
|
|
1051
1225
|
},
|
|
1052
|
-
children:
|
|
1226
|
+
children: [
|
|
1227
|
+
progressWidth > 0 && !showProgressInside && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "gantt-tr-externalProgress", children: [
|
|
1228
|
+
progressWidth,
|
|
1229
|
+
"%"
|
|
1230
|
+
] }),
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "gantt-tr-externalTaskName", children: task.name })
|
|
1232
|
+
]
|
|
1053
1233
|
}
|
|
1054
1234
|
)
|
|
1055
1235
|
] })
|
|
@@ -1198,6 +1378,62 @@ var DragGuideLines_default = DragGuideLines;
|
|
|
1198
1378
|
// src/components/DependencyLines/DependencyLines.tsx
|
|
1199
1379
|
var import_react6 = __toESM(require("react"));
|
|
1200
1380
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1381
|
+
function calculateEffectiveLag(edge, predPosition, succPosition, monthStart, dayWidth) {
|
|
1382
|
+
const predStartDate = pixelsToDate(predPosition.left, monthStart, dayWidth);
|
|
1383
|
+
const predEndDate = pixelsToDate(predPosition.right - dayWidth, monthStart, dayWidth);
|
|
1384
|
+
const succStartDate = pixelsToDate(succPosition.left, monthStart, dayWidth);
|
|
1385
|
+
const succEndDate = pixelsToDate(succPosition.right - dayWidth, monthStart, dayWidth);
|
|
1386
|
+
let lagMs = 0;
|
|
1387
|
+
switch (edge.type) {
|
|
1388
|
+
case "FS":
|
|
1389
|
+
lagMs = Date.UTC(
|
|
1390
|
+
succStartDate.getUTCFullYear(),
|
|
1391
|
+
succStartDate.getUTCMonth(),
|
|
1392
|
+
succStartDate.getUTCDate()
|
|
1393
|
+
) - Date.UTC(
|
|
1394
|
+
predEndDate.getUTCFullYear(),
|
|
1395
|
+
predEndDate.getUTCMonth(),
|
|
1396
|
+
predEndDate.getUTCDate()
|
|
1397
|
+
) - 24 * 60 * 60 * 1e3;
|
|
1398
|
+
break;
|
|
1399
|
+
case "SS":
|
|
1400
|
+
lagMs = Date.UTC(
|
|
1401
|
+
succStartDate.getUTCFullYear(),
|
|
1402
|
+
succStartDate.getUTCMonth(),
|
|
1403
|
+
succStartDate.getUTCDate()
|
|
1404
|
+
) - Date.UTC(
|
|
1405
|
+
predStartDate.getUTCFullYear(),
|
|
1406
|
+
predStartDate.getUTCMonth(),
|
|
1407
|
+
predStartDate.getUTCDate()
|
|
1408
|
+
);
|
|
1409
|
+
break;
|
|
1410
|
+
case "FF":
|
|
1411
|
+
lagMs = Date.UTC(
|
|
1412
|
+
succEndDate.getUTCFullYear(),
|
|
1413
|
+
succEndDate.getUTCMonth(),
|
|
1414
|
+
succEndDate.getUTCDate()
|
|
1415
|
+
) - Date.UTC(
|
|
1416
|
+
predEndDate.getUTCFullYear(),
|
|
1417
|
+
predEndDate.getUTCMonth(),
|
|
1418
|
+
predEndDate.getUTCDate()
|
|
1419
|
+
);
|
|
1420
|
+
break;
|
|
1421
|
+
case "SF":
|
|
1422
|
+
lagMs = Date.UTC(
|
|
1423
|
+
succEndDate.getUTCFullYear(),
|
|
1424
|
+
succEndDate.getUTCMonth(),
|
|
1425
|
+
succEndDate.getUTCDate()
|
|
1426
|
+
) - Date.UTC(
|
|
1427
|
+
predStartDate.getUTCFullYear(),
|
|
1428
|
+
predStartDate.getUTCMonth(),
|
|
1429
|
+
predStartDate.getUTCDate()
|
|
1430
|
+
) + 24 * 60 * 60 * 1e3;
|
|
1431
|
+
break;
|
|
1432
|
+
default:
|
|
1433
|
+
return 0;
|
|
1434
|
+
}
|
|
1435
|
+
return Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
1436
|
+
}
|
|
1201
1437
|
var DependencyLines = import_react6.default.memo(({
|
|
1202
1438
|
tasks,
|
|
1203
1439
|
monthStart,
|
|
@@ -1218,7 +1454,7 @@ var DependencyLines = import_react6.default.memo(({
|
|
|
1218
1454
|
const resolvedWidth = override?.width ?? computed.width;
|
|
1219
1455
|
indices.set(task.id, index);
|
|
1220
1456
|
positions.set(task.id, {
|
|
1221
|
-
left: resolvedLeft
|
|
1457
|
+
left: resolvedLeft,
|
|
1222
1458
|
right: resolvedLeft + resolvedWidth,
|
|
1223
1459
|
rowTop: index * rowHeight
|
|
1224
1460
|
});
|
|
@@ -1251,18 +1487,27 @@ var DependencyLines = import_react6.default.memo(({
|
|
|
1251
1487
|
fromY = predecessor.rowTop + rowHeight - 10;
|
|
1252
1488
|
toY = successor.rowTop + 6;
|
|
1253
1489
|
}
|
|
1254
|
-
const
|
|
1255
|
-
const
|
|
1256
|
-
const
|
|
1490
|
+
const fromX = edge.type === "SS" || edge.type === "SF" ? predecessor.left : predecessor.right;
|
|
1491
|
+
const toX = edge.type === "FF" || edge.type === "SF" ? successor.right : successor.left;
|
|
1492
|
+
const arrivesFromRight = edge.type === "FF" || edge.type === "SF";
|
|
1493
|
+
const from = { x: fromX, y: fromY };
|
|
1494
|
+
const to = { x: toX, y: toY };
|
|
1495
|
+
const path = calculateDependencyPath(from, to, arrivesFromRight);
|
|
1257
1496
|
const hasCycle = cycleInfo.has(edge.predecessorId) || cycleInfo.has(edge.successorId);
|
|
1497
|
+
const lag = calculateEffectiveLag(edge, predecessor, successor, monthStart, dayWidth);
|
|
1258
1498
|
lines2.push({
|
|
1259
|
-
id: `${edge.predecessorId}-${edge.successorId}`,
|
|
1499
|
+
id: `${edge.predecessorId}-${edge.successorId}-${edge.type}`,
|
|
1260
1500
|
path,
|
|
1261
|
-
hasCycle
|
|
1501
|
+
hasCycle,
|
|
1502
|
+
lag,
|
|
1503
|
+
fromX,
|
|
1504
|
+
toX,
|
|
1505
|
+
fromY,
|
|
1506
|
+
reverseOrder
|
|
1262
1507
|
});
|
|
1263
1508
|
}
|
|
1264
1509
|
return lines2;
|
|
1265
|
-
}, [tasks, taskPositions, taskIndices, cycleInfo]);
|
|
1510
|
+
}, [tasks, taskPositions, taskIndices, cycleInfo, monthStart, dayWidth, dragOverrides]);
|
|
1266
1511
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1267
1512
|
"svg",
|
|
1268
1513
|
{
|
|
@@ -1311,15 +1556,28 @@ var DependencyLines = import_react6.default.memo(({
|
|
|
1311
1556
|
}
|
|
1312
1557
|
)
|
|
1313
1558
|
] }),
|
|
1314
|
-
lines.map(({ id, path, hasCycle }) => /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1559
|
+
lines.map(({ id, path, hasCycle, lag, fromX, toX, fromY, reverseOrder }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react6.default.Fragment, { children: [
|
|
1560
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1561
|
+
"path",
|
|
1562
|
+
{
|
|
1563
|
+
d: path,
|
|
1564
|
+
className: hasCycle ? "gantt-dependency-path gantt-dependency-cycle" : "gantt-dependency-path",
|
|
1565
|
+
markerEnd: hasCycle ? "url(#arrowhead-cycle)" : "url(#arrowhead)"
|
|
1566
|
+
}
|
|
1567
|
+
),
|
|
1568
|
+
lag !== 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1569
|
+
"text",
|
|
1570
|
+
{
|
|
1571
|
+
className: "gantt-dependency-lag-label",
|
|
1572
|
+
x: lag < 0 ? toX + 14 : toX - 14,
|
|
1573
|
+
y: reverseOrder ? fromY - 4 : fromY + 12,
|
|
1574
|
+
textAnchor: "middle",
|
|
1575
|
+
fontSize: "10",
|
|
1576
|
+
fill: hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : "var(--gantt-dependency-line-color, #666666)",
|
|
1577
|
+
children: lag > 0 ? `+${lag}` : `${lag}`
|
|
1578
|
+
}
|
|
1579
|
+
)
|
|
1580
|
+
] }, id))
|
|
1323
1581
|
]
|
|
1324
1582
|
}
|
|
1325
1583
|
);
|
|
@@ -1537,6 +1795,7 @@ var GanttChart = ({
|
|
|
1537
1795
|
TodayIndicator,
|
|
1538
1796
|
buildAdjacencyList,
|
|
1539
1797
|
calculateBezierPath,
|
|
1798
|
+
calculateDependencyPath,
|
|
1540
1799
|
calculateGridLines,
|
|
1541
1800
|
calculateGridWidth,
|
|
1542
1801
|
calculateOrthogonalPath,
|