gantt-lib 0.72.2 → 0.73.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/index.mjs CHANGED
@@ -4151,6 +4151,26 @@ var CopyIcon = () => /* @__PURE__ */ jsxs9(
4151
4151
  ]
4152
4152
  }
4153
4153
  );
4154
+ var UngroupIcon = () => /* @__PURE__ */ jsxs9(
4155
+ "svg",
4156
+ {
4157
+ xmlns: "http://www.w3.org/2000/svg",
4158
+ width: "16",
4159
+ height: "16",
4160
+ viewBox: "0 0 24 24",
4161
+ fill: "none",
4162
+ stroke: "currentColor",
4163
+ strokeWidth: "2",
4164
+ strokeLinecap: "round",
4165
+ strokeLinejoin: "round",
4166
+ children: [
4167
+ /* @__PURE__ */ jsx12("path", { d: "M3 12h10" }),
4168
+ /* @__PURE__ */ jsx12("path", { d: "m6 9-3 3 3 3" }),
4169
+ /* @__PURE__ */ jsx12("path", { d: "M13 6h8" }),
4170
+ /* @__PURE__ */ jsx12("path", { d: "M13 18h8" })
4171
+ ]
4172
+ }
4173
+ );
4154
4174
  var TASK_COLOR_PALETTE = [
4155
4175
  // { label: "Палисандр", value: "#A61E4D" },
4156
4176
  // { label: "Киноварь", value: "#E8590C" },
@@ -4583,6 +4603,7 @@ var TaskListRow = React9.memo(
4583
4603
  onToggleCollapse,
4584
4604
  onPromoteTask,
4585
4605
  onDemoteTask,
4606
+ onUngroupTask,
4586
4607
  onDuplicateTask,
4587
4608
  canDemoteTask = true,
4588
4609
  isLastChild = true,
@@ -4594,7 +4615,8 @@ var TaskListRow = React9.memo(
4594
4615
  businessDays,
4595
4616
  isFilterMatch = false,
4596
4617
  isFilterHideMode = false,
4597
- resolvedColumns
4618
+ resolvedColumns,
4619
+ taskListMenuCommands = []
4598
4620
  }) => {
4599
4621
  const [editingColumnId, setEditingColumnId] = useState4(null);
4600
4622
  const editingName = editingColumnId === "name";
@@ -4628,6 +4650,7 @@ var TaskListRow = React9.memo(
4628
4650
  [task.id, allTasks]
4629
4651
  );
4630
4652
  const isChild = task.parentId !== void 0;
4653
+ const isMilestoneRow = normalizedTask.type === "milestone";
4631
4654
  const weekendPredicate = useMemo7(
4632
4655
  () => createCustomDayPredicate({ customDays, isWeekend: isWeekend3 }),
4633
4656
  [customDays, isWeekend3]
@@ -5150,6 +5173,38 @@ var TaskListRow = React9.memo(
5150
5173
  },
5151
5174
  [allTasks, isParent, onTasksChange, task]
5152
5175
  );
5176
+ const handleUngroup = useCallback4(
5177
+ (e) => {
5178
+ e.stopPropagation();
5179
+ setContextMenuOpen(false);
5180
+ onUngroupTask?.(task.id);
5181
+ },
5182
+ [onUngroupTask, task.id]
5183
+ );
5184
+ const visibleCustomMenuCommands = useMemo7(
5185
+ () => taskListMenuCommands.filter(
5186
+ (command) => {
5187
+ const scope = command.scope ?? "all";
5188
+ if (scope === "group" && !isParent) return false;
5189
+ if (scope === "linear" && (isParent || isMilestoneRow)) return false;
5190
+ if (scope === "milestone" && !isMilestoneRow) return false;
5191
+ return command.isVisible?.(task) ?? true;
5192
+ }
5193
+ ),
5194
+ [taskListMenuCommands, task, isParent, isMilestoneRow]
5195
+ );
5196
+ const hasContextMenu = visibleCustomMenuCommands.length > 0 || !!onDuplicateTask || !!onDelete || !!onTasksChange || isParent && !!onUngroupTask;
5197
+ const handleCustomMenuCommandClick = useCallback4(
5198
+ (command) => (e) => {
5199
+ e.stopPropagation();
5200
+ if (command.closeOnSelect !== false) {
5201
+ setContextMenuOpen(false);
5202
+ setColorMenuOpen(false);
5203
+ }
5204
+ command.onSelect(task);
5205
+ },
5206
+ [task]
5207
+ );
5153
5208
  const handleAddClick = useCallback4(
5154
5209
  (e) => {
5155
5210
  e.stopPropagation();
@@ -5576,7 +5631,7 @@ var TaskListRow = React9.memo(
5576
5631
  "aria-hidden": "true"
5577
5632
  }
5578
5633
  ),
5579
- !editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onDuplicateTask || onTasksChange) && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-name-actions", children: [
5634
+ !editingName && (onInsertAfter || onDelete || onPromoteTask || onDemoteTask || onUngroupTask || onDuplicateTask || onTasksChange || hasContextMenu) && /* @__PURE__ */ jsxs9("div", { className: "gantt-tl-name-actions", children: [
5580
5635
  onInsertAfter && /* @__PURE__ */ jsx12(
5581
5636
  "button",
5582
5637
  {
@@ -5622,7 +5677,7 @@ var TaskListRow = React9.memo(
5622
5677
  onDemote: onDemoteTask ? handleDemote : void 0
5623
5678
  }
5624
5679
  ),
5625
- (onDuplicateTask || onDelete || onTasksChange) && /* @__PURE__ */ jsxs9(Popover, { open: contextMenuOpen, onOpenChange: (open) => {
5680
+ hasContextMenu && /* @__PURE__ */ jsxs9(Popover, { open: contextMenuOpen, onOpenChange: (open) => {
5626
5681
  setContextMenuOpen(open);
5627
5682
  if (!open) setColorMenuOpen(false);
5628
5683
  }, children: [
@@ -5715,6 +5770,32 @@ var TaskListRow = React9.memo(
5715
5770
  ]
5716
5771
  }
5717
5772
  ),
5773
+ visibleCustomMenuCommands.map((command) => /* @__PURE__ */ jsxs9(
5774
+ "button",
5775
+ {
5776
+ type: "button",
5777
+ className: `gantt-tl-context-menu-item${command.danger ? " gantt-tl-context-menu-item-danger" : ""}`,
5778
+ onClick: handleCustomMenuCommandClick(command),
5779
+ disabled: command.isDisabled?.(task) ?? false,
5780
+ children: [
5781
+ command.icon,
5782
+ command.label
5783
+ ]
5784
+ },
5785
+ command.id
5786
+ )),
5787
+ isParent && onUngroupTask && /* @__PURE__ */ jsxs9(
5788
+ "button",
5789
+ {
5790
+ type: "button",
5791
+ className: "gantt-tl-context-menu-item",
5792
+ onClick: handleUngroup,
5793
+ children: [
5794
+ /* @__PURE__ */ jsx12(UngroupIcon, {}),
5795
+ "\u0420\u0430\u0437\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C"
5796
+ ]
5797
+ }
5798
+ ),
5718
5799
  onDelete && /* @__PURE__ */ jsxs9(
5719
5800
  "button",
5720
5801
  {
@@ -6410,6 +6491,7 @@ var TaskList = ({
6410
6491
  onToggleCollapse: externalOnToggleCollapse,
6411
6492
  onPromoteTask,
6412
6493
  onDemoteTask,
6494
+ onUngroupTask,
6413
6495
  customDays,
6414
6496
  isWeekend: isWeekend3,
6415
6497
  businessDays,
@@ -6417,7 +6499,8 @@ var TaskList = ({
6417
6499
  filterMode = "highlight",
6418
6500
  filteredTaskIds = /* @__PURE__ */ new Set(),
6419
6501
  isFilterActive = false,
6420
- additionalColumns
6502
+ additionalColumns,
6503
+ taskListMenuCommands
6421
6504
  }) => {
6422
6505
  const [internalCollapsedParentIds, setInternalCollapsedParentIds] = useState6(/* @__PURE__ */ new Set());
6423
6506
  const collapsedParentIds = externalCollapsedParentIds ?? internalCollapsedParentIds;
@@ -7081,6 +7164,7 @@ var TaskList = ({
7081
7164
  onToggleCollapse: handleToggleCollapse,
7082
7165
  onPromoteTask,
7083
7166
  onDemoteTask: onDemoteTask ? handleDemoteWrapper : void 0,
7167
+ onUngroupTask,
7084
7168
  onDuplicateTask: onReorder ? handleDuplicateTask : void 0,
7085
7169
  canDemoteTask,
7086
7170
  isLastChild: lastChildIds.has(task.id),
@@ -7092,7 +7176,8 @@ var TaskList = ({
7092
7176
  businessDays,
7093
7177
  isFilterMatch: filterMode === "highlight" ? highlightedTaskIds.has(task.id) : false,
7094
7178
  isFilterHideMode: filterMode === "hide" && isFilterActive,
7095
- resolvedColumns
7179
+ resolvedColumns,
7180
+ taskListMenuCommands
7096
7181
  }
7097
7182
  ),
7098
7183
  pendingInsertDisplayTaskId === task.id && /* @__PURE__ */ jsx14(
@@ -7512,6 +7597,7 @@ function GanttChartInner(props, ref) {
7512
7597
  onReorder,
7513
7598
  onPromoteTask,
7514
7599
  onDemoteTask,
7600
+ onUngroupTask,
7515
7601
  enableAddTask = true,
7516
7602
  viewMode = "day",
7517
7603
  customDays,
@@ -7524,7 +7610,8 @@ function GanttChartInner(props, ref) {
7524
7610
  highlightedTaskIds,
7525
7611
  disableTaskDrag = false,
7526
7612
  showChart = true,
7527
- additionalColumns
7613
+ additionalColumns,
7614
+ taskListMenuCommands
7528
7615
  } = props;
7529
7616
  const containerRef = useRef7(null);
7530
7617
  const scrollContainerRef = useRef7(null);
@@ -7940,6 +8027,33 @@ function GanttChartInner(props, ref) {
7940
8027
  };
7941
8028
  onTasksChange?.([updatedDemotedTask]);
7942
8029
  }, [tasks, onTasksChange, onDemoteTask]);
8030
+ const handleUngroupTask = useCallback6((taskId) => {
8031
+ if (onUngroupTask) {
8032
+ onUngroupTask(taskId);
8033
+ return;
8034
+ }
8035
+ const parentTask = tasks.find((task) => task.id === taskId);
8036
+ if (!parentTask) return;
8037
+ const hasDirectChildren = tasks.some((task) => task.parentId === taskId);
8038
+ if (!hasDirectChildren) return;
8039
+ const changedTasks = [];
8040
+ for (const task of tasks) {
8041
+ if (task.id === taskId) continue;
8042
+ const nextParentId = task.parentId === taskId ? parentTask.parentId : task.parentId;
8043
+ const nextDependencies = task.dependencies?.filter((dep) => dep.taskId !== taskId);
8044
+ if (nextParentId !== task.parentId || nextDependencies?.length !== task.dependencies?.length) {
8045
+ changedTasks.push({
8046
+ ...task,
8047
+ parentId: nextParentId,
8048
+ dependencies: nextDependencies
8049
+ });
8050
+ }
8051
+ }
8052
+ if (changedTasks.length > 0) {
8053
+ onTasksChange?.(changedTasks);
8054
+ }
8055
+ onDelete?.(taskId);
8056
+ }, [tasks, onTasksChange, onDelete, onUngroupTask]);
7943
8057
  const panStateRef = useRef7(null);
7944
8058
  const handlePanStart = useCallback6((e) => {
7945
8059
  if (e.button !== 0) return;
@@ -8018,6 +8132,7 @@ function GanttChartInner(props, ref) {
8018
8132
  onToggleCollapse: handleToggleCollapse,
8019
8133
  onPromoteTask: onPromoteTask ?? handlePromoteTask,
8020
8134
  onDemoteTask: onDemoteTask ?? handleDemoteTask,
8135
+ onUngroupTask: onUngroupTask ?? handleUngroupTask,
8021
8136
  highlightedTaskIds: taskListHighlightedTaskIds,
8022
8137
  customDays,
8023
8138
  isWeekend: isWeekend3,
@@ -8025,7 +8140,8 @@ function GanttChartInner(props, ref) {
8025
8140
  filterMode,
8026
8141
  filteredTaskIds: matchedTaskIds,
8027
8142
  isFilterActive: !!taskFilter,
8028
- additionalColumns
8143
+ additionalColumns,
8144
+ taskListMenuCommands
8029
8145
  }
8030
8146
  ),
8031
8147
  /* @__PURE__ */ jsxs12(