gantt-lib 0.72.2 → 0.73.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/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/core/scheduling/index.js +38 -39
- package/dist/core/scheduling/index.js.map +1 -1
- package/dist/core/scheduling/index.mjs +38 -39
- package/dist/core/scheduling/index.mjs.map +1 -1
- package/dist/{index-DlJm2l_7.d.mts → index-D8XWS1Ku.d.mts} +9 -0
- package/dist/{index-DlJm2l_7.d.ts → index-D8XWS1Ku.d.ts} +9 -0
- package/dist/index.d.mts +31 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +164 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1136,45 +1136,9 @@ function universalCascade(movedTask, newStart, newEnd, allTasks, businessDays =
|
|
|
1136
1136
|
}
|
|
1137
1137
|
return Array.from(resultMap.values());
|
|
1138
1138
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
const toISO = (d) => d.toISOString().split("T")[0];
|
|
1143
|
-
for (const task of tasks) {
|
|
1144
|
-
if (isTaskParent(task.id, tasks)) continue;
|
|
1145
|
-
const start = normalizeUTCDate(/* @__PURE__ */ new Date(`${task.startDate}T00:00:00.000Z`));
|
|
1146
|
-
const duration = getTaskDuration(task.startDate, task.endDate, fromBusinessDays, weekendPredicate);
|
|
1147
|
-
let range;
|
|
1148
|
-
if (toBusinessDays) {
|
|
1149
|
-
const alignedStart = alignToWorkingDay(start, 1, weekendPredicate);
|
|
1150
|
-
range = buildTaskRangeFromStart(alignedStart, duration, true, weekendPredicate);
|
|
1151
|
-
} else {
|
|
1152
|
-
range = buildTaskRangeFromStart(start, duration, false);
|
|
1153
|
-
}
|
|
1154
|
-
task.startDate = toISO(range.start);
|
|
1155
|
-
task.endDate = toISO(range.end);
|
|
1156
|
-
}
|
|
1157
|
-
for (const task of tasks) {
|
|
1158
|
-
if (!isTaskParent(task.id, tasks)) continue;
|
|
1159
|
-
const { startDate, endDate } = computeParentDates(task.id, tasks);
|
|
1160
|
-
task.startDate = toISO(startDate);
|
|
1161
|
-
task.endDate = toISO(endDate);
|
|
1162
|
-
}
|
|
1163
|
-
if (toBusinessDays) {
|
|
1164
|
-
const rootSeeds = tasks.filter(
|
|
1165
|
-
(t) => !t.parentId && (!t.dependencies || t.dependencies.length === 0)
|
|
1166
|
-
);
|
|
1167
|
-
for (const seed of rootSeeds) {
|
|
1168
|
-
const current = tasks.find((t) => t.id === seed.id);
|
|
1169
|
-
const start = /* @__PURE__ */ new Date(`${current.startDate}T00:00:00.000Z`);
|
|
1170
|
-
const end = /* @__PURE__ */ new Date(`${current.endDate}T00:00:00.000Z`);
|
|
1171
|
-
const cascaded = universalCascade(current, start, end, tasks, toBusinessDays, weekendPredicate);
|
|
1172
|
-
const updates = new Map(cascaded.map((t) => [t.id, t]));
|
|
1173
|
-
tasks = tasks.map((t) => updates.get(t.id) ?? t);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
return tasks;
|
|
1177
|
-
}
|
|
1139
|
+
|
|
1140
|
+
// src/core/scheduling/modeSwitch.ts
|
|
1141
|
+
init_dateMath();
|
|
1178
1142
|
|
|
1179
1143
|
// src/core/scheduling/execute.ts
|
|
1180
1144
|
init_dateMath();
|
|
@@ -1481,6 +1445,44 @@ function recalculateProjectSchedule(snapshot, options) {
|
|
|
1481
1445
|
return createChangedResult(snapshot, Array.from(workingMap.values()));
|
|
1482
1446
|
}
|
|
1483
1447
|
|
|
1448
|
+
// src/core/scheduling/modeSwitch.ts
|
|
1449
|
+
function reflowTasksOnModeSwitch(sourceTasks, toBusinessDays, weekendPredicate) {
|
|
1450
|
+
const fromBusinessDays = !toBusinessDays;
|
|
1451
|
+
let tasks = sourceTasks.map((task) => ({
|
|
1452
|
+
...task,
|
|
1453
|
+
dependencies: task.dependencies?.map((dependency) => ({ ...dependency }))
|
|
1454
|
+
}));
|
|
1455
|
+
const toISO = (date) => date.toISOString().split("T")[0];
|
|
1456
|
+
for (const task of tasks) {
|
|
1457
|
+
if (isTaskParent(task.id, tasks)) continue;
|
|
1458
|
+
const start = normalizeUTCDate(/* @__PURE__ */ new Date(`${task.startDate}T00:00:00.000Z`));
|
|
1459
|
+
const duration = getTaskDuration(task.startDate, task.endDate, fromBusinessDays, weekendPredicate);
|
|
1460
|
+
const range = toBusinessDays ? buildTaskRangeFromStart(
|
|
1461
|
+
alignToWorkingDay(start, 1, weekendPredicate),
|
|
1462
|
+
duration,
|
|
1463
|
+
true,
|
|
1464
|
+
weekendPredicate
|
|
1465
|
+
) : buildTaskRangeFromStart(start, duration, false);
|
|
1466
|
+
task.startDate = toISO(range.start);
|
|
1467
|
+
task.endDate = toISO(range.end);
|
|
1468
|
+
}
|
|
1469
|
+
for (const task of tasks) {
|
|
1470
|
+
if (!isTaskParent(task.id, tasks)) continue;
|
|
1471
|
+
const { startDate, endDate } = computeParentDates(task.id, tasks);
|
|
1472
|
+
task.startDate = toISO(startDate);
|
|
1473
|
+
task.endDate = toISO(endDate);
|
|
1474
|
+
}
|
|
1475
|
+
const rescheduled = recalculateProjectSchedule(tasks, {
|
|
1476
|
+
businessDays: toBusinessDays,
|
|
1477
|
+
weekendPredicate
|
|
1478
|
+
});
|
|
1479
|
+
if (rescheduled.changedTasks.length === 0) {
|
|
1480
|
+
return tasks;
|
|
1481
|
+
}
|
|
1482
|
+
const updates = new Map(rescheduled.changedTasks.map((task) => [task.id, task]));
|
|
1483
|
+
return tasks.map((task) => updates.get(task.id) ?? task);
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1484
1486
|
// src/core/scheduling/validation.ts
|
|
1485
1487
|
function buildAdjacencyList(tasks) {
|
|
1486
1488
|
const graph = /* @__PURE__ */ new Map();
|
|
@@ -4151,6 +4153,26 @@ var CopyIcon = () => /* @__PURE__ */ jsxs9(
|
|
|
4151
4153
|
]
|
|
4152
4154
|
}
|
|
4153
4155
|
);
|
|
4156
|
+
var UngroupIcon = () => /* @__PURE__ */ jsxs9(
|
|
4157
|
+
"svg",
|
|
4158
|
+
{
|
|
4159
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4160
|
+
width: "16",
|
|
4161
|
+
height: "16",
|
|
4162
|
+
viewBox: "0 0 24 24",
|
|
4163
|
+
fill: "none",
|
|
4164
|
+
stroke: "currentColor",
|
|
4165
|
+
strokeWidth: "2",
|
|
4166
|
+
strokeLinecap: "round",
|
|
4167
|
+
strokeLinejoin: "round",
|
|
4168
|
+
children: [
|
|
4169
|
+
/* @__PURE__ */ jsx12("path", { d: "M3 12h10" }),
|
|
4170
|
+
/* @__PURE__ */ jsx12("path", { d: "m6 9-3 3 3 3" }),
|
|
4171
|
+
/* @__PURE__ */ jsx12("path", { d: "M13 6h8" }),
|
|
4172
|
+
/* @__PURE__ */ jsx12("path", { d: "M13 18h8" })
|
|
4173
|
+
]
|
|
4174
|
+
}
|
|
4175
|
+
);
|
|
4154
4176
|
var TASK_COLOR_PALETTE = [
|
|
4155
4177
|
// { label: "Палисандр", value: "#A61E4D" },
|
|
4156
4178
|
// { label: "Киноварь", value: "#E8590C" },
|
|
@@ -4583,6 +4605,7 @@ var TaskListRow = React9.memo(
|
|
|
4583
4605
|
onToggleCollapse,
|
|
4584
4606
|
onPromoteTask,
|
|
4585
4607
|
onDemoteTask,
|
|
4608
|
+
onUngroupTask,
|
|
4586
4609
|
onDuplicateTask,
|
|
4587
4610
|
canDemoteTask = true,
|
|
4588
4611
|
isLastChild = true,
|
|
@@ -4594,7 +4617,8 @@ var TaskListRow = React9.memo(
|
|
|
4594
4617
|
businessDays,
|
|
4595
4618
|
isFilterMatch = false,
|
|
4596
4619
|
isFilterHideMode = false,
|
|
4597
|
-
resolvedColumns
|
|
4620
|
+
resolvedColumns,
|
|
4621
|
+
taskListMenuCommands = []
|
|
4598
4622
|
}) => {
|
|
4599
4623
|
const [editingColumnId, setEditingColumnId] = useState4(null);
|
|
4600
4624
|
const editingName = editingColumnId === "name";
|
|
@@ -4628,6 +4652,7 @@ var TaskListRow = React9.memo(
|
|
|
4628
4652
|
[task.id, allTasks]
|
|
4629
4653
|
);
|
|
4630
4654
|
const isChild = task.parentId !== void 0;
|
|
4655
|
+
const isMilestoneRow = normalizedTask.type === "milestone";
|
|
4631
4656
|
const weekendPredicate = useMemo7(
|
|
4632
4657
|
() => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
|
|
4633
4658
|
[customDays, isWeekend3]
|
|
@@ -5150,6 +5175,38 @@ var TaskListRow = React9.memo(
|
|
|
5150
5175
|
},
|
|
5151
5176
|
[allTasks, isParent, onTasksChange, task]
|
|
5152
5177
|
);
|
|
5178
|
+
const handleUngroup = useCallback4(
|
|
5179
|
+
(e) => {
|
|
5180
|
+
e.stopPropagation();
|
|
5181
|
+
setContextMenuOpen(false);
|
|
5182
|
+
onUngroupTask?.(task.id);
|
|
5183
|
+
},
|
|
5184
|
+
[onUngroupTask, task.id]
|
|
5185
|
+
);
|
|
5186
|
+
const visibleCustomMenuCommands = useMemo7(
|
|
5187
|
+
() => taskListMenuCommands.filter(
|
|
5188
|
+
(command) => {
|
|
5189
|
+
const scope = command.scope ?? "all";
|
|
5190
|
+
if (scope === "group" && !isParent) return false;
|
|
5191
|
+
if (scope === "linear" && (isParent || isMilestoneRow)) return false;
|
|
5192
|
+
if (scope === "milestone" && !isMilestoneRow) return false;
|
|
5193
|
+
return command.isVisible?.(task) ?? true;
|
|
5194
|
+
}
|
|
5195
|
+
),
|
|
5196
|
+
[taskListMenuCommands, task, isParent, isMilestoneRow]
|
|
5197
|
+
);
|
|
5198
|
+
const hasContextMenu = visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask;
|
|
5199
|
+
const handleCustomMenuCommandClick = useCallback4(
|
|
5200
|
+
(command) => (e) => {
|
|
5201
|
+
e.stopPropagation();
|
|
5202
|
+
if (command.closeOnSelect !== false) {
|
|
5203
|
+
setContextMenuOpen(false);
|
|
5204
|
+
setColorMenuOpen(false);
|
|
5205
|
+
}
|
|
5206
|
+
command.onSelect(task);
|
|
5207
|
+
},
|
|
5208
|
+
[task]
|
|
5209
|
+
);
|
|
5153
5210
|
const handleAddClick = useCallback4(
|
|
5154
5211
|
(e) => {
|
|
5155
5212
|
e.stopPropagation();
|
|
@@ -5576,7 +5633,7 @@ var TaskListRow = React9.memo(
|
|
|
5576
5633
|
"aria-hidden": "true"
|
|
5577
5634
|
}
|
|
5578
5635
|
),
|
|
5579
|
-
!editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onDuplicateTask || onTasksChange) && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-name-actions", children: [
|
|
5636
|
+
!editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-name-actions", children: [
|
|
5580
5637
|
onInsertAfter && /* @__PURE__ */ jsx12(
|
|
5581
5638
|
"button",
|
|
5582
5639
|
{
|
|
@@ -5622,7 +5679,7 @@ var TaskListRow = React9.memo(
|
|
|
5622
5679
|
onDemote: onDemoteTask ? handleDemote : void 0
|
|
5623
5680
|
}
|
|
5624
5681
|
),
|
|
5625
|
-
|
|
5682
|
+
hasContextMenu && /* @__PURE__ */ jsxs9(Popover, { open: contextMenuOpen, onOpenChange: (open) => {
|
|
5626
5683
|
setContextMenuOpen(open);
|
|
5627
5684
|
if (!open) setColorMenuOpen(false);
|
|
5628
5685
|
}, children: [
|
|
@@ -5715,6 +5772,32 @@ var TaskListRow = React9.memo(
|
|
|
5715
5772
|
]
|
|
5716
5773
|
}
|
|
5717
5774
|
),
|
|
5775
|
+
visibleCustomMenuCommands.map((command) => /* @__PURE__ */ jsxs9(
|
|
5776
|
+
"button",
|
|
5777
|
+
{
|
|
5778
|
+
type: "button",
|
|
5779
|
+
className: `gantt-tl-context-menu-item${command.danger ? " gantt-tl-context-menu-item-danger" : ""}`,
|
|
5780
|
+
onClick: handleCustomMenuCommandClick(command),
|
|
5781
|
+
disabled: command.isDisabled?.(task) ?? false,
|
|
5782
|
+
children: [
|
|
5783
|
+
command.icon,
|
|
5784
|
+
command.label
|
|
5785
|
+
]
|
|
5786
|
+
},
|
|
5787
|
+
command.id
|
|
5788
|
+
)),
|
|
5789
|
+
isParent && onUngroupTask && /* @__PURE__ */ jsxs9(
|
|
5790
|
+
"button",
|
|
5791
|
+
{
|
|
5792
|
+
type: "button",
|
|
5793
|
+
className: "gantt-tl-context-menu-item",
|
|
5794
|
+
onClick: handleUngroup,
|
|
5795
|
+
children: [
|
|
5796
|
+
/* @__PURE__ */ jsx12(UngroupIcon, {}),
|
|
5797
|
+
"\u0420\u0430\u0437\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C"
|
|
5798
|
+
]
|
|
5799
|
+
}
|
|
5800
|
+
),
|
|
5718
5801
|
onDelete && /* @__PURE__ */ jsxs9(
|
|
5719
5802
|
"button",
|
|
5720
5803
|
{
|
|
@@ -6410,6 +6493,7 @@ var TaskList = ({
|
|
|
6410
6493
|
onToggleCollapse: externalOnToggleCollapse,
|
|
6411
6494
|
onPromoteTask,
|
|
6412
6495
|
onDemoteTask,
|
|
6496
|
+
onUngroupTask,
|
|
6413
6497
|
customDays,
|
|
6414
6498
|
isWeekend: isWeekend3,
|
|
6415
6499
|
businessDays,
|
|
@@ -6417,7 +6501,8 @@ var TaskList = ({
|
|
|
6417
6501
|
filterMode = "highlight",
|
|
6418
6502
|
filteredTaskIds = /* @__PURE__ */ new Set(),
|
|
6419
6503
|
isFilterActive = false,
|
|
6420
|
-
additionalColumns
|
|
6504
|
+
additionalColumns,
|
|
6505
|
+
taskListMenuCommands
|
|
6421
6506
|
}) => {
|
|
6422
6507
|
const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState6(/* @__PURE__ */ new Set());
|
|
6423
6508
|
const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
|
|
@@ -7081,6 +7166,7 @@ var TaskList = ({
|
|
|
7081
7166
|
onToggleCollapse: handleToggleCollapse,
|
|
7082
7167
|
onPromoteTask,
|
|
7083
7168
|
onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
|
|
7169
|
+
onUngroupTask,
|
|
7084
7170
|
onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
|
|
7085
7171
|
canDemoteTask,
|
|
7086
7172
|
isLastChild: lastChildIds.has(task.id),
|
|
@@ -7092,7 +7178,8 @@ var TaskList = ({
|
|
|
7092
7178
|
businessDays,
|
|
7093
7179
|
isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
|
|
7094
7180
|
isFilterHideMode: filterMode === "hide" && isFilterActive,
|
|
7095
|
-
resolvedColumns
|
|
7181
|
+
resolvedColumns,
|
|
7182
|
+
taskListMenuCommands
|
|
7096
7183
|
}
|
|
7097
7184
|
),
|
|
7098
7185
|
pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ jsx14(
|
|
@@ -7512,6 +7599,7 @@ function GanttChartInner(props, ref) {
|
|
|
7512
7599
|
onReorder,
|
|
7513
7600
|
onPromoteTask,
|
|
7514
7601
|
onDemoteTask,
|
|
7602
|
+
onUngroupTask,
|
|
7515
7603
|
enableAddTask = true,
|
|
7516
7604
|
viewMode = "day",
|
|
7517
7605
|
customDays,
|
|
@@ -7524,7 +7612,8 @@ function GanttChartInner(props, ref) {
|
|
|
7524
7612
|
highlightedTaskIds,
|
|
7525
7613
|
disableTaskDrag = false,
|
|
7526
7614
|
showChart = true,
|
|
7527
|
-
additionalColumns
|
|
7615
|
+
additionalColumns,
|
|
7616
|
+
taskListMenuCommands
|
|
7528
7617
|
} = props;
|
|
7529
7618
|
const containerRef = useRef7(null);
|
|
7530
7619
|
const scrollContainerRef = useRef7(null);
|
|
@@ -7940,6 +8029,33 @@ function GanttChartInner(props, ref) {
|
|
|
7940
8029
|
};
|
|
7941
8030
|
onTasksChange?.([updatedDemotedTask]);
|
|
7942
8031
|
}, [tasks, onTasksChange, onDemoteTask]);
|
|
8032
|
+
const handleUngroupTask = useCallback6((taskId) => {
|
|
8033
|
+
if (onUngroupTask) {
|
|
8034
|
+
onUngroupTask(taskId);
|
|
8035
|
+
return;
|
|
8036
|
+
}
|
|
8037
|
+
const parentTask = tasks.find((task) => task.id === taskId);
|
|
8038
|
+
if (!parentTask) return;
|
|
8039
|
+
const hasDirectChildren = tasks.some((task) => task.parentId === taskId);
|
|
8040
|
+
if (!hasDirectChildren) return;
|
|
8041
|
+
const changedTasks = [];
|
|
8042
|
+
for (const task of tasks) {
|
|
8043
|
+
if (task.id === taskId) continue;
|
|
8044
|
+
const nextParentId = task.parentId === taskId ? parentTask.parentId : task.parentId;
|
|
8045
|
+
const nextDependencies = task.dependencies?.filter((dep) => dep.taskId !== taskId);
|
|
8046
|
+
if (nextParentId !== task.parentId || nextDependencies?.length !== task.dependencies?.length) {
|
|
8047
|
+
changedTasks.push({
|
|
8048
|
+
...task,
|
|
8049
|
+
parentId: nextParentId,
|
|
8050
|
+
dependencies: nextDependencies
|
|
8051
|
+
});
|
|
8052
|
+
}
|
|
8053
|
+
}
|
|
8054
|
+
if (changedTasks.length > 0) {
|
|
8055
|
+
onTasksChange?.(changedTasks);
|
|
8056
|
+
}
|
|
8057
|
+
onDelete?.(taskId);
|
|
8058
|
+
}, [tasks, onTasksChange, onDelete, onUngroupTask]);
|
|
7943
8059
|
const panStateRef = useRef7(null);
|
|
7944
8060
|
const handlePanStart = useCallback6((e) => {
|
|
7945
8061
|
if (e.button !== 0) return;
|
|
@@ -8018,6 +8134,7 @@ function GanttChartInner(props, ref) {
|
|
|
8018
8134
|
onToggleCollapse: handleToggleCollapse,
|
|
8019
8135
|
onPromoteTask: onPromoteTask ?? handlePromoteTask,
|
|
8020
8136
|
onDemoteTask: onDemoteTask ?? handleDemoteTask,
|
|
8137
|
+
onUngroupTask: onUngroupTask ?? handleUngroupTask,
|
|
8021
8138
|
highlightedTaskIds: taskListHighlightedTaskIds,
|
|
8022
8139
|
customDays,
|
|
8023
8140
|
isWeekend: isWeekend3,
|
|
@@ -8025,7 +8142,8 @@ function GanttChartInner(props, ref) {
|
|
|
8025
8142
|
filterMode,
|
|
8026
8143
|
filteredTaskIds: matchedTaskIds,
|
|
8027
8144
|
isFilterActive: !!taskFilter,
|
|
8028
|
-
additionalColumns
|
|
8145
|
+
additionalColumns,
|
|
8146
|
+
taskListMenuCommands
|
|
8029
8147
|
}
|
|
8030
8148
|
),
|
|
8031
8149
|
/* @__PURE__ */ jsxs12(
|