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.mjs
CHANGED
|
@@ -231,7 +231,7 @@ function validateDependencies(tasks) {
|
|
|
231
231
|
errors
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
|
-
function getSuccessorChain(draggedTaskId, allTasks) {
|
|
234
|
+
function getSuccessorChain(draggedTaskId, allTasks, linkTypes = ["FS"]) {
|
|
235
235
|
const successorMap = /* @__PURE__ */ new Map();
|
|
236
236
|
for (const task of allTasks) {
|
|
237
237
|
successorMap.set(task.id, []);
|
|
@@ -239,7 +239,7 @@ function getSuccessorChain(draggedTaskId, allTasks) {
|
|
|
239
239
|
for (const task of allTasks) {
|
|
240
240
|
if (!task.dependencies) continue;
|
|
241
241
|
for (const dep of task.dependencies) {
|
|
242
|
-
if (dep.type
|
|
242
|
+
if (linkTypes.includes(dep.type)) {
|
|
243
243
|
const list = successorMap.get(dep.taskId) ?? [];
|
|
244
244
|
list.push(task.id);
|
|
245
245
|
successorMap.set(dep.taskId, list);
|
|
@@ -461,6 +461,43 @@ var calculateBezierPath = (from, to) => {
|
|
|
461
461
|
const cp2y = to.y - (to.y > from.y ? cpOffset : -cpOffset);
|
|
462
462
|
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)}`;
|
|
463
463
|
};
|
|
464
|
+
var calculateDependencyPath = (from, to, arrivesFromRight) => {
|
|
465
|
+
const fx = Math.round(from.x);
|
|
466
|
+
const fy = Math.round(from.y);
|
|
467
|
+
const tx = Math.round(to.x);
|
|
468
|
+
const ty = Math.round(to.y);
|
|
469
|
+
if (fy === ty) {
|
|
470
|
+
return `M ${fx} ${fy} H ${tx}`;
|
|
471
|
+
}
|
|
472
|
+
const C = 2;
|
|
473
|
+
const goingDown = ty > fy;
|
|
474
|
+
const dirY = goingDown ? 1 : -1;
|
|
475
|
+
if (arrivesFromRight) {
|
|
476
|
+
const goingRight = tx >= fx;
|
|
477
|
+
const dirX = goingRight ? 1 : -1;
|
|
478
|
+
if (Math.abs(ty - fy) >= C && Math.abs(tx - fx) >= C) {
|
|
479
|
+
return [
|
|
480
|
+
`M ${fx} ${fy}`,
|
|
481
|
+
`H ${tx - dirX * C}`,
|
|
482
|
+
`L ${tx} ${fy + dirY * C}`,
|
|
483
|
+
`V ${ty}`
|
|
484
|
+
].join(" ");
|
|
485
|
+
}
|
|
486
|
+
return `M ${fx} ${fy} H ${tx} V ${ty}`;
|
|
487
|
+
} else {
|
|
488
|
+
const goingRight = tx >= fx;
|
|
489
|
+
const dirX = goingRight ? 1 : -1;
|
|
490
|
+
if (Math.abs(ty - fy) >= C && Math.abs(tx - fx) >= C) {
|
|
491
|
+
return [
|
|
492
|
+
`M ${fx} ${fy}`,
|
|
493
|
+
`H ${tx - dirX * C}`,
|
|
494
|
+
`L ${tx} ${fy + dirY * C}`,
|
|
495
|
+
`V ${ty}`
|
|
496
|
+
].join(" ");
|
|
497
|
+
}
|
|
498
|
+
return `M ${fx} ${fy} H ${tx} V ${ty}`;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
464
501
|
var calculateOrthogonalPath = (from, to) => {
|
|
465
502
|
const fx = Math.round(from.x);
|
|
466
503
|
const fy = Math.round(from.y);
|
|
@@ -487,6 +524,36 @@ var calculateOrthogonalPath = (from, to) => {
|
|
|
487
524
|
|
|
488
525
|
// src/hooks/useTaskDrag.ts
|
|
489
526
|
import { useEffect, useRef, useState, useCallback } from "react";
|
|
527
|
+
function getTransitiveCascadeChain(draggedTaskId, allTasks, firstLevelLinkTypes) {
|
|
528
|
+
const allTypesSuccessorMap = /* @__PURE__ */ new Map();
|
|
529
|
+
for (const task of allTasks) {
|
|
530
|
+
allTypesSuccessorMap.set(task.id, []);
|
|
531
|
+
}
|
|
532
|
+
for (const task of allTasks) {
|
|
533
|
+
if (!task.dependencies) continue;
|
|
534
|
+
for (const dep of task.dependencies) {
|
|
535
|
+
const list = allTypesSuccessorMap.get(dep.taskId) ?? [];
|
|
536
|
+
list.push(task);
|
|
537
|
+
allTypesSuccessorMap.set(dep.taskId, list);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
const directSuccessors = getSuccessorChain(draggedTaskId, allTasks, firstLevelLinkTypes);
|
|
541
|
+
const chain = [...directSuccessors];
|
|
542
|
+
const visited = /* @__PURE__ */ new Set([draggedTaskId, ...directSuccessors.map((t) => t.id)]);
|
|
543
|
+
const queue = [...directSuccessors];
|
|
544
|
+
while (queue.length > 0) {
|
|
545
|
+
const current = queue.shift();
|
|
546
|
+
const successors = allTypesSuccessorMap.get(current.id) ?? [];
|
|
547
|
+
for (const successor of successors) {
|
|
548
|
+
if (!visited.has(successor.id)) {
|
|
549
|
+
visited.add(successor.id);
|
|
550
|
+
chain.push(successor);
|
|
551
|
+
queue.push(successor);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return chain;
|
|
556
|
+
}
|
|
490
557
|
var globalActiveDrag = null;
|
|
491
558
|
var globalRafId = null;
|
|
492
559
|
function completeDrag() {
|
|
@@ -515,25 +582,43 @@ function cancelDrag() {
|
|
|
515
582
|
function snapToGrid(pixels, dayWidth) {
|
|
516
583
|
return Math.round(pixels / dayWidth) * dayWidth;
|
|
517
584
|
}
|
|
518
|
-
function recalculateIncomingLags(task, newStartDate, allTasks) {
|
|
585
|
+
function recalculateIncomingLags(task, newStartDate, newEndDate, allTasks) {
|
|
519
586
|
if (!task.dependencies) return [];
|
|
520
587
|
const taskById = new Map(allTasks.map((t) => [t.id, t]));
|
|
521
588
|
return task.dependencies.map((dep) => {
|
|
522
|
-
if (dep.type
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
589
|
+
if (dep.type === "FS") {
|
|
590
|
+
const predecessor = taskById.get(dep.taskId);
|
|
591
|
+
if (!predecessor) return dep;
|
|
592
|
+
const predEnd = new Date(predecessor.endDate);
|
|
593
|
+
const lagMs = Date.UTC(newStartDate.getUTCFullYear(), newStartDate.getUTCMonth(), newStartDate.getUTCDate()) - Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());
|
|
594
|
+
const lagDays = Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
595
|
+
return { ...dep, lag: lagDays };
|
|
596
|
+
}
|
|
597
|
+
if (dep.type === "SS") {
|
|
598
|
+
const predecessor = taskById.get(dep.taskId);
|
|
599
|
+
if (!predecessor) return dep;
|
|
600
|
+
const predStart = new Date(predecessor.startDate);
|
|
601
|
+
const lagMs = Date.UTC(newStartDate.getUTCFullYear(), newStartDate.getUTCMonth(), newStartDate.getUTCDate()) - Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate());
|
|
602
|
+
const lagDays = Math.max(0, Math.round(lagMs / (24 * 60 * 60 * 1e3)));
|
|
603
|
+
return { ...dep, lag: lagDays };
|
|
604
|
+
}
|
|
605
|
+
if (dep.type === "FF") {
|
|
606
|
+
const predecessor = taskById.get(dep.taskId);
|
|
607
|
+
if (!predecessor) return dep;
|
|
608
|
+
const predEnd = new Date(predecessor.endDate);
|
|
609
|
+
const lagMs = Date.UTC(newEndDate.getUTCFullYear(), newEndDate.getUTCMonth(), newEndDate.getUTCDate()) - Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());
|
|
610
|
+
const lagDays = Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
611
|
+
return { ...dep, lag: lagDays };
|
|
612
|
+
}
|
|
613
|
+
if (dep.type === "SF") {
|
|
614
|
+
const predecessor = taskById.get(dep.taskId);
|
|
615
|
+
if (!predecessor) return dep;
|
|
616
|
+
const predStart = new Date(predecessor.startDate);
|
|
617
|
+
const lagMs = Date.UTC(newEndDate.getUTCFullYear(), newEndDate.getUTCMonth(), newEndDate.getUTCDate()) - Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate()) + 24 * 60 * 60 * 1e3;
|
|
618
|
+
const lagDays = Math.min(0, Math.round(lagMs / (24 * 60 * 60 * 1e3)));
|
|
619
|
+
return { ...dep, lag: lagDays };
|
|
620
|
+
}
|
|
621
|
+
return dep;
|
|
537
622
|
});
|
|
538
623
|
}
|
|
539
624
|
function handleGlobalMouseMove(e) {
|
|
@@ -564,12 +649,12 @@ function handleGlobalMouseMove(e) {
|
|
|
564
649
|
newWidth = Math.max(dayWidth, snappedWidth);
|
|
565
650
|
break;
|
|
566
651
|
}
|
|
567
|
-
if (mode === "move" && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
652
|
+
if ((mode === "move" || mode === "resize-left") && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
568
653
|
const currentTask = allTasks.find((t) => t.id === globalActiveDrag?.taskId);
|
|
569
654
|
if (currentTask && currentTask.dependencies && currentTask.dependencies.length > 0) {
|
|
570
655
|
let minAllowedLeft = 0;
|
|
571
656
|
for (const dep of currentTask.dependencies) {
|
|
572
|
-
if (dep.type !== "FS") continue;
|
|
657
|
+
if (dep.type !== "FS" && dep.type !== "SS") continue;
|
|
573
658
|
const predecessor = globalActiveDrag.allTasks.find((t) => t.id === dep.taskId);
|
|
574
659
|
if (!predecessor) continue;
|
|
575
660
|
const predStart = new Date(predecessor.startDate);
|
|
@@ -585,25 +670,91 @@ function handleGlobalMouseMove(e) {
|
|
|
585
670
|
}
|
|
586
671
|
newLeft = Math.max(minAllowedLeft, newLeft);
|
|
587
672
|
}
|
|
673
|
+
if (mode === "resize-left") {
|
|
674
|
+
const rightEdge = globalActiveDrag.initialLeft + globalActiveDrag.initialWidth;
|
|
675
|
+
newWidth = Math.max(globalActiveDrag.dayWidth, rightEdge - newLeft);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
if ((mode === "move" || mode === "resize-right") && allTasks.length > 0 && !globalActiveDrag.disableConstraints) {
|
|
679
|
+
const currentTask = allTasks.find((t) => t.id === globalActiveDrag?.taskId);
|
|
680
|
+
if (currentTask && currentTask.dependencies && currentTask.dependencies.length > 0) {
|
|
681
|
+
for (const dep of currentTask.dependencies) {
|
|
682
|
+
if (dep.type !== "SF") continue;
|
|
683
|
+
const predecessor = globalActiveDrag.allTasks.find((t) => t.id === dep.taskId);
|
|
684
|
+
if (!predecessor) continue;
|
|
685
|
+
const predStart = new Date(predecessor.startDate);
|
|
686
|
+
const predStartOffset = Math.round(
|
|
687
|
+
(Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate()) - Date.UTC(globalActiveDrag.monthStart.getUTCFullYear(), globalActiveDrag.monthStart.getUTCDate(), globalActiveDrag.monthStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
688
|
+
);
|
|
689
|
+
const predStartLeft = Math.round(predStartOffset * globalActiveDrag.dayWidth);
|
|
690
|
+
const sfBoundaryRight = predStartLeft;
|
|
691
|
+
if (mode === "move") {
|
|
692
|
+
const proposedEndRight = newLeft + globalActiveDrag.initialWidth;
|
|
693
|
+
if (proposedEndRight > sfBoundaryRight) {
|
|
694
|
+
newLeft = Math.max(globalActiveDrag.initialLeft, sfBoundaryRight - globalActiveDrag.initialWidth);
|
|
695
|
+
}
|
|
696
|
+
} else {
|
|
697
|
+
const currentEndRight = newLeft + newWidth;
|
|
698
|
+
if (currentEndRight > sfBoundaryRight) {
|
|
699
|
+
newWidth = Math.max(globalActiveDrag.dayWidth, sfBoundaryRight - newLeft);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
588
704
|
}
|
|
589
|
-
|
|
705
|
+
const activeChain = mode === "resize-right" ? globalActiveDrag.cascadeChainEnd : (
|
|
706
|
+
// FS + FF
|
|
707
|
+
mode === "resize-left" ? globalActiveDrag.cascadeChainStart : (
|
|
708
|
+
// SS + SF
|
|
709
|
+
/* move */
|
|
710
|
+
globalActiveDrag.cascadeChain
|
|
711
|
+
)
|
|
712
|
+
);
|
|
713
|
+
if ((mode === "move" || mode === "resize-right" || mode === "resize-left" && globalActiveDrag.cascadeChainStart.length > 0) && !globalActiveDrag.disableConstraints && activeChain.length > 0 && globalActiveDrag.onCascadeProgress) {
|
|
590
714
|
const deltaDays = mode === "resize-right" ? Math.round((newWidth - globalActiveDrag.initialWidth) / globalActiveDrag.dayWidth) : Math.round((newLeft - globalActiveDrag.initialLeft) / globalActiveDrag.dayWidth);
|
|
591
715
|
const overrides = /* @__PURE__ */ new Map();
|
|
592
|
-
|
|
716
|
+
const draggedTaskId = globalActiveDrag.taskId;
|
|
717
|
+
const dayWidth2 = globalActiveDrag.dayWidth;
|
|
718
|
+
const monthStart = globalActiveDrag.monthStart;
|
|
719
|
+
for (const chainTask of activeChain) {
|
|
593
720
|
const chainStart = new Date(chainTask.startDate);
|
|
594
721
|
const chainEnd = new Date(chainTask.endDate);
|
|
595
722
|
const chainStartOffset = Math.round(
|
|
596
723
|
(Date.UTC(chainStart.getUTCFullYear(), chainStart.getUTCMonth(), chainStart.getUTCDate()) - Date.UTC(
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
724
|
+
monthStart.getUTCFullYear(),
|
|
725
|
+
monthStart.getUTCMonth(),
|
|
726
|
+
monthStart.getUTCDate()
|
|
727
|
+
)) / (24 * 60 * 60 * 1e3)
|
|
728
|
+
);
|
|
729
|
+
const chainEndOffset = Math.round(
|
|
730
|
+
(Date.UTC(chainEnd.getUTCFullYear(), chainEnd.getUTCMonth(), chainEnd.getUTCDate()) - Date.UTC(
|
|
731
|
+
monthStart.getUTCFullYear(),
|
|
732
|
+
monthStart.getUTCMonth(),
|
|
733
|
+
monthStart.getUTCDate()
|
|
600
734
|
)) / (24 * 60 * 60 * 1e3)
|
|
601
735
|
);
|
|
602
736
|
const chainDuration = Math.round(
|
|
603
737
|
(Date.UTC(chainEnd.getUTCFullYear(), chainEnd.getUTCMonth(), chainEnd.getUTCDate()) - Date.UTC(chainStart.getUTCFullYear(), chainStart.getUTCMonth(), chainStart.getUTCDate())) / (24 * 60 * 60 * 1e3)
|
|
604
738
|
);
|
|
605
|
-
const
|
|
606
|
-
|
|
739
|
+
const hasFFDepOnDragged = chainTask.dependencies?.some(
|
|
740
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "FF"
|
|
741
|
+
);
|
|
742
|
+
const hasSFDepOnDragged = chainTask.dependencies?.some(
|
|
743
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "SF"
|
|
744
|
+
);
|
|
745
|
+
let chainLeft;
|
|
746
|
+
if (hasFFDepOnDragged || hasSFDepOnDragged) {
|
|
747
|
+
chainLeft = Math.round((chainEndOffset + deltaDays - chainDuration) * dayWidth2);
|
|
748
|
+
} else {
|
|
749
|
+
chainLeft = Math.round((chainStartOffset + deltaDays) * dayWidth2);
|
|
750
|
+
}
|
|
751
|
+
const chainWidth = Math.round((chainDuration + 1) * dayWidth2);
|
|
752
|
+
const hasSSDepOnDragged = chainTask.dependencies?.some(
|
|
753
|
+
(dep) => dep.taskId === draggedTaskId && dep.type === "SS"
|
|
754
|
+
);
|
|
755
|
+
if (hasSSDepOnDragged && (mode === "move" || mode === "resize-left")) {
|
|
756
|
+
chainLeft = Math.max(chainLeft, newLeft);
|
|
757
|
+
}
|
|
607
758
|
overrides.set(chainTask.id, { left: chainLeft, width: chainWidth });
|
|
608
759
|
}
|
|
609
760
|
globalActiveDrag.onCascadeProgress(overrides);
|
|
@@ -714,19 +865,32 @@ var useTaskDrag = (options) => {
|
|
|
714
865
|
}
|
|
715
866
|
if (wasOwner) {
|
|
716
867
|
if (!disableConstraints && onCascade && allTasks.length > 0) {
|
|
717
|
-
const
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
)
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
868
|
+
const origStartMs = Date.UTC(
|
|
869
|
+
initialStartDate.getUTCFullYear(),
|
|
870
|
+
initialStartDate.getUTCMonth(),
|
|
871
|
+
initialStartDate.getUTCDate()
|
|
872
|
+
);
|
|
873
|
+
const newStartMs = Date.UTC(
|
|
874
|
+
newStartDate.getUTCFullYear(),
|
|
875
|
+
newStartDate.getUTCMonth(),
|
|
876
|
+
newStartDate.getUTCDate()
|
|
877
|
+
);
|
|
878
|
+
const deltaFromStart = Math.round((newStartMs - origStartMs) / (24 * 60 * 60 * 1e3));
|
|
879
|
+
const origEndMs = Date.UTC(
|
|
880
|
+
initialEndDate.getUTCFullYear(),
|
|
881
|
+
initialEndDate.getUTCMonth(),
|
|
882
|
+
initialEndDate.getUTCDate()
|
|
883
|
+
);
|
|
884
|
+
const newEndMs = Date.UTC(
|
|
885
|
+
newEndDate.getUTCFullYear(),
|
|
886
|
+
newEndDate.getUTCMonth(),
|
|
887
|
+
newEndDate.getUTCDate()
|
|
888
|
+
);
|
|
889
|
+
const deltaFromEnd = Math.round((newEndMs - origEndMs) / (24 * 60 * 60 * 1e3));
|
|
890
|
+
const deltaDays = deltaFromStart === 0 ? deltaFromEnd : deltaFromStart;
|
|
891
|
+
const isResizeLeft = deltaFromStart !== 0 && deltaFromEnd === 0;
|
|
892
|
+
const chainForCompletion = deltaFromStart === 0 ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "FF"]) : isResizeLeft ? getTransitiveCascadeChain(taskId, allTasks, ["SS", "SF"]) : getTransitiveCascadeChain(taskId, allTasks, ["FS", "SS", "FF", "SF"]);
|
|
893
|
+
if (chainForCompletion.length > 0) {
|
|
730
894
|
const draggedTaskData = allTasks.find((t) => t.id === taskId);
|
|
731
895
|
const cascadedTasks = [
|
|
732
896
|
{
|
|
@@ -734,10 +898,10 @@ var useTaskDrag = (options) => {
|
|
|
734
898
|
startDate: newStartDate.toISOString(),
|
|
735
899
|
endDate: newEndDate.toISOString(),
|
|
736
900
|
...draggedTaskData?.dependencies && {
|
|
737
|
-
dependencies: recalculateIncomingLags(draggedTaskData, newStartDate, allTasks)
|
|
901
|
+
dependencies: recalculateIncomingLags(draggedTaskData, newStartDate, newEndDate, allTasks)
|
|
738
902
|
}
|
|
739
903
|
},
|
|
740
|
-
...
|
|
904
|
+
...chainForCompletion.map((chainTask) => {
|
|
741
905
|
const origStart = new Date(chainTask.startDate);
|
|
742
906
|
const origEnd = new Date(chainTask.endDate);
|
|
743
907
|
const newStart = new Date(Date.UTC(
|
|
@@ -759,7 +923,7 @@ var useTaskDrag = (options) => {
|
|
|
759
923
|
}
|
|
760
924
|
if (allTasks.length > 0 && onDragEnd) {
|
|
761
925
|
const currentTaskData = allTasks.find((t) => t.id === taskId);
|
|
762
|
-
const updatedDependencies = currentTaskData?.dependencies ? recalculateIncomingLags(currentTaskData, newStartDate, allTasks) : void 0;
|
|
926
|
+
const updatedDependencies = currentTaskData?.dependencies ? recalculateIncomingLags(currentTaskData, newStartDate, newEndDate, allTasks) : void 0;
|
|
763
927
|
onDragEnd({ id: taskId, startDate: newStartDate, endDate: newEndDate, updatedDependencies });
|
|
764
928
|
} else if (onDragEnd) {
|
|
765
929
|
onDragEnd({ id: taskId, startDate: newStartDate, endDate: newEndDate });
|
|
@@ -835,7 +999,10 @@ var useTaskDrag = (options) => {
|
|
|
835
999
|
onCancel: handleCancel,
|
|
836
1000
|
allTasks,
|
|
837
1001
|
disableConstraints,
|
|
838
|
-
cascadeChain: (
|
|
1002
|
+
cascadeChain: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "SS", "FF", "SF"]) : [],
|
|
1003
|
+
cascadeChainFS: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS"]) : [],
|
|
1004
|
+
cascadeChainStart: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["SS", "SF"]) : [],
|
|
1005
|
+
cascadeChainEnd: !disableConstraints ? getTransitiveCascadeChain(taskId, allTasks, ["FS", "FF"]) : [],
|
|
839
1006
|
onCascadeProgress
|
|
840
1007
|
};
|
|
841
1008
|
}, [edgeZoneWidth, currentLeft, currentWidth, dayWidth, monthStart, taskId, onDragStateChange, handleProgress, handleComplete, handleCancel, allTasks, disableConstraints, onCascadeProgress, onCascade]);
|
|
@@ -924,6 +1091,8 @@ var TaskRow = React2.memo(
|
|
|
924
1091
|
const durationDays = Math.round(
|
|
925
1092
|
(currentEndDate.getTime() - currentStartDate.getTime()) / (1e3 * 60 * 60 * 24)
|
|
926
1093
|
) + 1;
|
|
1094
|
+
const estimatedTextWidth = durationDays >= 10 ? 76 : 62;
|
|
1095
|
+
const showProgressInside = progressWidth > 0 && displayWidth > estimatedTextWidth;
|
|
927
1096
|
return /* @__PURE__ */ jsx2(
|
|
928
1097
|
"div",
|
|
929
1098
|
{
|
|
@@ -960,6 +1129,10 @@ var TaskRow = React2.memo(
|
|
|
960
1129
|
durationDays,
|
|
961
1130
|
" \u0434"
|
|
962
1131
|
] }),
|
|
1132
|
+
progressWidth > 0 && showProgressInside && /* @__PURE__ */ jsxs2("span", { className: "gantt-tr-progressText", children: [
|
|
1133
|
+
progressWidth,
|
|
1134
|
+
"%"
|
|
1135
|
+
] }),
|
|
963
1136
|
/* @__PURE__ */ jsx2("div", { className: "gantt-tr-resizeHandle gantt-tr-resizeHandleRight" })
|
|
964
1137
|
]
|
|
965
1138
|
}
|
|
@@ -978,14 +1151,20 @@ var TaskRow = React2.memo(
|
|
|
978
1151
|
] })
|
|
979
1152
|
}
|
|
980
1153
|
),
|
|
981
|
-
/* @__PURE__ */
|
|
1154
|
+
/* @__PURE__ */ jsxs2(
|
|
982
1155
|
"div",
|
|
983
1156
|
{
|
|
984
1157
|
className: "gantt-tr-rightLabels",
|
|
985
1158
|
style: {
|
|
986
1159
|
left: `${displayLeft + displayWidth}px`
|
|
987
1160
|
},
|
|
988
|
-
children:
|
|
1161
|
+
children: [
|
|
1162
|
+
progressWidth > 0 && !showProgressInside && /* @__PURE__ */ jsxs2("span", { className: "gantt-tr-externalProgress", children: [
|
|
1163
|
+
progressWidth,
|
|
1164
|
+
"%"
|
|
1165
|
+
] }),
|
|
1166
|
+
/* @__PURE__ */ jsx2("span", { className: "gantt-tr-externalTaskName", children: task.name })
|
|
1167
|
+
]
|
|
989
1168
|
}
|
|
990
1169
|
)
|
|
991
1170
|
] })
|
|
@@ -1134,6 +1313,62 @@ var DragGuideLines_default = DragGuideLines;
|
|
|
1134
1313
|
// src/components/DependencyLines/DependencyLines.tsx
|
|
1135
1314
|
import React5, { useMemo as useMemo5 } from "react";
|
|
1136
1315
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1316
|
+
function calculateEffectiveLag(edge, predPosition, succPosition, monthStart, dayWidth) {
|
|
1317
|
+
const predStartDate = pixelsToDate(predPosition.left, monthStart, dayWidth);
|
|
1318
|
+
const predEndDate = pixelsToDate(predPosition.right - dayWidth, monthStart, dayWidth);
|
|
1319
|
+
const succStartDate = pixelsToDate(succPosition.left, monthStart, dayWidth);
|
|
1320
|
+
const succEndDate = pixelsToDate(succPosition.right - dayWidth, monthStart, dayWidth);
|
|
1321
|
+
let lagMs = 0;
|
|
1322
|
+
switch (edge.type) {
|
|
1323
|
+
case "FS":
|
|
1324
|
+
lagMs = Date.UTC(
|
|
1325
|
+
succStartDate.getUTCFullYear(),
|
|
1326
|
+
succStartDate.getUTCMonth(),
|
|
1327
|
+
succStartDate.getUTCDate()
|
|
1328
|
+
) - Date.UTC(
|
|
1329
|
+
predEndDate.getUTCFullYear(),
|
|
1330
|
+
predEndDate.getUTCMonth(),
|
|
1331
|
+
predEndDate.getUTCDate()
|
|
1332
|
+
) - 24 * 60 * 60 * 1e3;
|
|
1333
|
+
break;
|
|
1334
|
+
case "SS":
|
|
1335
|
+
lagMs = Date.UTC(
|
|
1336
|
+
succStartDate.getUTCFullYear(),
|
|
1337
|
+
succStartDate.getUTCMonth(),
|
|
1338
|
+
succStartDate.getUTCDate()
|
|
1339
|
+
) - Date.UTC(
|
|
1340
|
+
predStartDate.getUTCFullYear(),
|
|
1341
|
+
predStartDate.getUTCMonth(),
|
|
1342
|
+
predStartDate.getUTCDate()
|
|
1343
|
+
);
|
|
1344
|
+
break;
|
|
1345
|
+
case "FF":
|
|
1346
|
+
lagMs = Date.UTC(
|
|
1347
|
+
succEndDate.getUTCFullYear(),
|
|
1348
|
+
succEndDate.getUTCMonth(),
|
|
1349
|
+
succEndDate.getUTCDate()
|
|
1350
|
+
) - Date.UTC(
|
|
1351
|
+
predEndDate.getUTCFullYear(),
|
|
1352
|
+
predEndDate.getUTCMonth(),
|
|
1353
|
+
predEndDate.getUTCDate()
|
|
1354
|
+
);
|
|
1355
|
+
break;
|
|
1356
|
+
case "SF":
|
|
1357
|
+
lagMs = Date.UTC(
|
|
1358
|
+
succEndDate.getUTCFullYear(),
|
|
1359
|
+
succEndDate.getUTCMonth(),
|
|
1360
|
+
succEndDate.getUTCDate()
|
|
1361
|
+
) - Date.UTC(
|
|
1362
|
+
predStartDate.getUTCFullYear(),
|
|
1363
|
+
predStartDate.getUTCMonth(),
|
|
1364
|
+
predStartDate.getUTCDate()
|
|
1365
|
+
) + 24 * 60 * 60 * 1e3;
|
|
1366
|
+
break;
|
|
1367
|
+
default:
|
|
1368
|
+
return 0;
|
|
1369
|
+
}
|
|
1370
|
+
return Math.round(lagMs / (24 * 60 * 60 * 1e3));
|
|
1371
|
+
}
|
|
1137
1372
|
var DependencyLines = React5.memo(({
|
|
1138
1373
|
tasks,
|
|
1139
1374
|
monthStart,
|
|
@@ -1154,7 +1389,7 @@ var DependencyLines = React5.memo(({
|
|
|
1154
1389
|
const resolvedWidth = override?.width ?? computed.width;
|
|
1155
1390
|
indices.set(task.id, index);
|
|
1156
1391
|
positions.set(task.id, {
|
|
1157
|
-
left: resolvedLeft
|
|
1392
|
+
left: resolvedLeft,
|
|
1158
1393
|
right: resolvedLeft + resolvedWidth,
|
|
1159
1394
|
rowTop: index * rowHeight
|
|
1160
1395
|
});
|
|
@@ -1187,18 +1422,27 @@ var DependencyLines = React5.memo(({
|
|
|
1187
1422
|
fromY = predecessor.rowTop + rowHeight - 10;
|
|
1188
1423
|
toY = successor.rowTop + 6;
|
|
1189
1424
|
}
|
|
1190
|
-
const
|
|
1191
|
-
const
|
|
1192
|
-
const
|
|
1425
|
+
const fromX = edge.type === "SS" || edge.type === "SF" ? predecessor.left : predecessor.right;
|
|
1426
|
+
const toX = edge.type === "FF" || edge.type === "SF" ? successor.right : successor.left;
|
|
1427
|
+
const arrivesFromRight = edge.type === "FF" || edge.type === "SF";
|
|
1428
|
+
const from = { x: fromX, y: fromY };
|
|
1429
|
+
const to = { x: toX, y: toY };
|
|
1430
|
+
const path = calculateDependencyPath(from, to, arrivesFromRight);
|
|
1193
1431
|
const hasCycle = cycleInfo.has(edge.predecessorId) || cycleInfo.has(edge.successorId);
|
|
1432
|
+
const lag = calculateEffectiveLag(edge, predecessor, successor, monthStart, dayWidth);
|
|
1194
1433
|
lines2.push({
|
|
1195
|
-
id: `${edge.predecessorId}-${edge.successorId}`,
|
|
1434
|
+
id: `${edge.predecessorId}-${edge.successorId}-${edge.type}`,
|
|
1196
1435
|
path,
|
|
1197
|
-
hasCycle
|
|
1436
|
+
hasCycle,
|
|
1437
|
+
lag,
|
|
1438
|
+
fromX,
|
|
1439
|
+
toX,
|
|
1440
|
+
fromY,
|
|
1441
|
+
reverseOrder
|
|
1198
1442
|
});
|
|
1199
1443
|
}
|
|
1200
1444
|
return lines2;
|
|
1201
|
-
}, [tasks, taskPositions, taskIndices, cycleInfo]);
|
|
1445
|
+
}, [tasks, taskPositions, taskIndices, cycleInfo, monthStart, dayWidth, dragOverrides]);
|
|
1202
1446
|
return /* @__PURE__ */ jsxs5(
|
|
1203
1447
|
"svg",
|
|
1204
1448
|
{
|
|
@@ -1247,15 +1491,28 @@ var DependencyLines = React5.memo(({
|
|
|
1247
1491
|
}
|
|
1248
1492
|
)
|
|
1249
1493
|
] }),
|
|
1250
|
-
lines.map(({ id, path, hasCycle }) => /* @__PURE__ */
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1494
|
+
lines.map(({ id, path, hasCycle, lag, fromX, toX, fromY, reverseOrder }) => /* @__PURE__ */ jsxs5(React5.Fragment, { children: [
|
|
1495
|
+
/* @__PURE__ */ jsx6(
|
|
1496
|
+
"path",
|
|
1497
|
+
{
|
|
1498
|
+
d: path,
|
|
1499
|
+
className: hasCycle ? "gantt-dependency-path gantt-dependency-cycle" : "gantt-dependency-path",
|
|
1500
|
+
markerEnd: hasCycle ? "url(#arrowhead-cycle)" : "url(#arrowhead)"
|
|
1501
|
+
}
|
|
1502
|
+
),
|
|
1503
|
+
lag !== 0 && /* @__PURE__ */ jsx6(
|
|
1504
|
+
"text",
|
|
1505
|
+
{
|
|
1506
|
+
className: "gantt-dependency-lag-label",
|
|
1507
|
+
x: lag < 0 ? toX + 14 : toX - 14,
|
|
1508
|
+
y: reverseOrder ? fromY - 4 : fromY + 12,
|
|
1509
|
+
textAnchor: "middle",
|
|
1510
|
+
fontSize: "10",
|
|
1511
|
+
fill: hasCycle ? "var(--gantt-dependency-cycle-color, #ef4444)" : "var(--gantt-dependency-line-color, #666666)",
|
|
1512
|
+
children: lag > 0 ? `+${lag}` : `${lag}`
|
|
1513
|
+
}
|
|
1514
|
+
)
|
|
1515
|
+
] }, id))
|
|
1259
1516
|
]
|
|
1260
1517
|
}
|
|
1261
1518
|
);
|
|
@@ -1472,6 +1729,7 @@ export {
|
|
|
1472
1729
|
TodayIndicator_default as TodayIndicator,
|
|
1473
1730
|
buildAdjacencyList,
|
|
1474
1731
|
calculateBezierPath,
|
|
1732
|
+
calculateDependencyPath,
|
|
1475
1733
|
calculateGridLines,
|
|
1476
1734
|
calculateGridWidth,
|
|
1477
1735
|
calculateOrthogonalPath,
|