gantt-lib 0.52.0 → 0.53.1
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.css.map +1 -1
- package/dist/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +72 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +70 -18
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +11 -6
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -721,6 +721,22 @@ function validateDependencies(tasks) {
|
|
|
721
721
|
}
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
|
+
for (const task of tasks) {
|
|
725
|
+
if (!task.dependencies) continue;
|
|
726
|
+
for (const dep of task.dependencies) {
|
|
727
|
+
if (!taskIds.has(dep.taskId)) {
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
if (areTasksHierarchicallyRelated(task.id, dep.taskId, tasks)) {
|
|
731
|
+
errors.push({
|
|
732
|
+
type: "constraint",
|
|
733
|
+
taskId: task.id,
|
|
734
|
+
message: `Dependencies between parent and child tasks are not allowed: ${dep.taskId} -> ${task.id}`,
|
|
735
|
+
relatedTaskIds: [dep.taskId, task.id]
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
724
740
|
const cycleResult = detectCycles(tasks);
|
|
725
741
|
if (cycleResult.hasCycle && cycleResult.cyclePath) {
|
|
726
742
|
errors.push({
|
|
@@ -979,6 +995,28 @@ function findParentId(taskId, tasks) {
|
|
|
979
995
|
const task = tasks.find((t) => t.id === taskId);
|
|
980
996
|
return task?.parentId;
|
|
981
997
|
}
|
|
998
|
+
function isAncestorTask(ancestorId, taskId, tasks) {
|
|
999
|
+
const taskById = new Map(tasks.map((task) => [task.id, task]));
|
|
1000
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1001
|
+
let current = taskById.get(taskId);
|
|
1002
|
+
while (current?.parentId) {
|
|
1003
|
+
if (current.parentId === ancestorId) {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
if (visited.has(current.parentId)) {
|
|
1007
|
+
return false;
|
|
1008
|
+
}
|
|
1009
|
+
visited.add(current.parentId);
|
|
1010
|
+
current = taskById.get(current.parentId);
|
|
1011
|
+
}
|
|
1012
|
+
return false;
|
|
1013
|
+
}
|
|
1014
|
+
function areTasksHierarchicallyRelated(taskId1, taskId2, tasks) {
|
|
1015
|
+
if (taskId1 === taskId2) {
|
|
1016
|
+
return true;
|
|
1017
|
+
}
|
|
1018
|
+
return isAncestorTask(taskId1, taskId2, tasks) || isAncestorTask(taskId2, taskId1, tasks);
|
|
1019
|
+
}
|
|
982
1020
|
function getAllDescendants(parentId, tasks) {
|
|
983
1021
|
const descendants = [];
|
|
984
1022
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -3257,6 +3295,20 @@ var DatePicker = ({
|
|
|
3257
3295
|
},
|
|
3258
3296
|
[selectedDate, updateFromDate, businessDays, isWeekend3]
|
|
3259
3297
|
);
|
|
3298
|
+
const handleTriggerKeyDown = useCallback3((e) => {
|
|
3299
|
+
if (disabled) return;
|
|
3300
|
+
if (e.key === "ArrowUp") {
|
|
3301
|
+
e.preventDefault();
|
|
3302
|
+
e.stopPropagation();
|
|
3303
|
+
handleDayShift(1);
|
|
3304
|
+
return;
|
|
3305
|
+
}
|
|
3306
|
+
if (e.key === "ArrowDown") {
|
|
3307
|
+
e.preventDefault();
|
|
3308
|
+
e.stopPropagation();
|
|
3309
|
+
handleDayShift(-1);
|
|
3310
|
+
}
|
|
3311
|
+
}, [disabled, handleDayShift]);
|
|
3260
3312
|
const handleKeyDown = useCallback3((e) => {
|
|
3261
3313
|
if (!dateInputRef.current) return;
|
|
3262
3314
|
const { value: inputVal } = dateInputRef.current;
|
|
@@ -3364,6 +3416,7 @@ var DatePicker = ({
|
|
|
3364
3416
|
type: "button",
|
|
3365
3417
|
className: `gantt-datepicker-trigger${className ? ` ${className}` : ""}`,
|
|
3366
3418
|
disabled,
|
|
3419
|
+
onKeyDown: handleTriggerKeyDown,
|
|
3367
3420
|
onClick: (e) => {
|
|
3368
3421
|
e.stopPropagation();
|
|
3369
3422
|
},
|
|
@@ -5834,7 +5887,7 @@ var TaskList = ({
|
|
|
5834
5887
|
const [selectingPredecessorFor, setSelectingPredecessorFor] = useState6(null);
|
|
5835
5888
|
const [dependencyPickMode, setDependencyPickMode] = useState6("successor");
|
|
5836
5889
|
const [typeMenuOpen, setTypeMenuOpen] = useState6(false);
|
|
5837
|
-
const [
|
|
5890
|
+
const [dependencyError, setDependencyError] = useState6(null);
|
|
5838
5891
|
const overlayRef = useRef6(null);
|
|
5839
5892
|
const [selectedChip, setSelectedChip] = useState6(null);
|
|
5840
5893
|
const handleChipSelect = useCallback5((chip) => {
|
|
@@ -5869,6 +5922,12 @@ var TaskList = ({
|
|
|
5869
5922
|
}, [selectingPredecessorFor, selectedChip, selectedTaskId, onTaskSelect, onSelectedChipChange]);
|
|
5870
5923
|
const handleAddDependency = useCallback5((successorTaskId, predecessorTaskId, linkType) => {
|
|
5871
5924
|
if (successorTaskId === predecessorTaskId) return;
|
|
5925
|
+
if (areTasksHierarchicallyRelated(successorTaskId, predecessorTaskId, tasks)) {
|
|
5926
|
+
setDependencyError("\u0421\u0432\u044F\u0437\u0438 \u043C\u0435\u0436\u0434\u0443 \u0440\u043E\u0434\u0438\u0442\u0435\u043B\u0435\u043C \u0438 \u043F\u043E\u0442\u043E\u043C\u043A\u043E\u043C \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u044B");
|
|
5927
|
+
setTimeout(() => setDependencyError(null), 3e3);
|
|
5928
|
+
setSelectingPredecessorFor(null);
|
|
5929
|
+
return;
|
|
5930
|
+
}
|
|
5872
5931
|
const successor = tasks.find((t) => t.id === successorTaskId);
|
|
5873
5932
|
if (!successor) return;
|
|
5874
5933
|
const alreadyExists = (successor.dependencies ?? []).some(
|
|
@@ -5884,8 +5943,11 @@ var TaskList = ({
|
|
|
5884
5943
|
);
|
|
5885
5944
|
const validation = validateDependencies(hypothetical);
|
|
5886
5945
|
if (!validation.isValid) {
|
|
5887
|
-
|
|
5888
|
-
|
|
5946
|
+
const hasHierarchyConstraint = validation.errors.some((error) => error.type === "constraint");
|
|
5947
|
+
setDependencyError(
|
|
5948
|
+
hasHierarchyConstraint ? "\u0421\u0432\u044F\u0437\u0438 \u043C\u0435\u0436\u0434\u0443 \u0440\u043E\u0434\u0438\u0442\u0435\u043B\u0435\u043C \u0438 \u043F\u043E\u0442\u043E\u043C\u043A\u043E\u043C \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u044B" : "\u0426\u0438\u043A\u043B \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u0435\u0439!"
|
|
5949
|
+
);
|
|
5950
|
+
setTimeout(() => setDependencyError(null), 3e3);
|
|
5889
5951
|
return;
|
|
5890
5952
|
}
|
|
5891
5953
|
const updatedTask = hypothetical.find((t) => t.id === successorTaskId);
|
|
@@ -6209,7 +6271,7 @@ var TaskList = ({
|
|
|
6209
6271
|
lt
|
|
6210
6272
|
)) }) })
|
|
6211
6273
|
] }),
|
|
6212
|
-
|
|
6274
|
+
dependencyError && /* @__PURE__ */ jsx14("div", { className: "gantt-tl-dep-error", children: dependencyError })
|
|
6213
6275
|
]
|
|
6214
6276
|
},
|
|
6215
6277
|
col.id
|
|
@@ -6556,20 +6618,8 @@ function GanttChartInner(props, ref) {
|
|
|
6556
6618
|
}
|
|
6557
6619
|
return;
|
|
6558
6620
|
}
|
|
6559
|
-
const
|
|
6560
|
-
|
|
6561
|
-
const { startDate: parentStart, endDate: parentEnd } = computeParentDates(updatedTask.id, tasks);
|
|
6562
|
-
const parentWithRecalcDates = {
|
|
6563
|
-
...updatedTask,
|
|
6564
|
-
startDate: parentStart.toISOString().split("T")[0],
|
|
6565
|
-
endDate: parentEnd.toISOString().split("T")[0]
|
|
6566
|
-
};
|
|
6567
|
-
const cascadedTasks = disableConstraints ? [parentWithRecalcDates] : universalCascade(parentWithRecalcDates, parentStart, parentEnd, tasks, businessDays, isCustomWeekend);
|
|
6568
|
-
onTasksChange?.(cascadedTasks);
|
|
6569
|
-
} else {
|
|
6570
|
-
const cascadedTasks = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, tasks, businessDays, isCustomWeekend);
|
|
6571
|
-
onTasksChange?.(cascadedTasks);
|
|
6572
|
-
}
|
|
6621
|
+
const cascadedTasks = disableConstraints ? [updatedTask] : universalCascade(updatedTask, newStart, newEnd, tasks, businessDays, isCustomWeekend);
|
|
6622
|
+
onTasksChange?.(cascadedTasks);
|
|
6573
6623
|
}, [tasks, onTasksChange, disableConstraints, editingTaskId, businessDays, isCustomWeekend]);
|
|
6574
6624
|
const handleDelete = useCallback6((taskId) => {
|
|
6575
6625
|
const toDelete = /* @__PURE__ */ new Set([taskId]);
|
|
@@ -7010,6 +7060,7 @@ export {
|
|
|
7010
7060
|
addBusinessDays,
|
|
7011
7061
|
alignToWorkingDay,
|
|
7012
7062
|
and,
|
|
7063
|
+
areTasksHierarchicallyRelated,
|
|
7013
7064
|
buildAdjacencyList,
|
|
7014
7065
|
buildTaskRangeFromEnd,
|
|
7015
7066
|
buildTaskRangeFromStart,
|
|
@@ -7056,6 +7107,7 @@ export {
|
|
|
7056
7107
|
getWeekSpans,
|
|
7057
7108
|
getYearSpans,
|
|
7058
7109
|
inDateRange,
|
|
7110
|
+
isAncestorTask,
|
|
7059
7111
|
isTaskExpired,
|
|
7060
7112
|
isTaskParent,
|
|
7061
7113
|
isToday,
|