@uipath/apollo-react 3.44.0 → 3.44.2-pr255.af80ea0

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.
Files changed (121) hide show
  1. package/dist/canvas/components/StageNode/CrossStageTaskDrag.stories.cjs +581 -0
  2. package/dist/canvas/components/StageNode/CrossStageTaskDrag.stories.d.ts +6 -0
  3. package/dist/canvas/components/StageNode/CrossStageTaskDrag.stories.d.ts.map +1 -0
  4. package/dist/canvas/components/StageNode/CrossStageTaskDrag.stories.js +544 -0
  5. package/dist/canvas/components/StageNode/DropPlaceholder.cjs +106 -0
  6. package/dist/canvas/components/StageNode/DropPlaceholder.d.ts +10 -0
  7. package/dist/canvas/components/StageNode/DropPlaceholder.d.ts.map +1 -0
  8. package/dist/canvas/components/StageNode/DropPlaceholder.js +72 -0
  9. package/dist/canvas/components/StageNode/StageNode.cjs +334 -389
  10. package/dist/canvas/components/StageNode/StageNode.d.ts.map +1 -1
  11. package/dist/canvas/components/StageNode/StageNode.js +336 -391
  12. package/dist/canvas/components/StageNode/StageNode.stories.cjs +1910 -1416
  13. package/dist/canvas/components/StageNode/StageNode.stories.d.ts +1 -1
  14. package/dist/canvas/components/StageNode/StageNode.stories.d.ts.map +1 -1
  15. package/dist/canvas/components/StageNode/StageNode.stories.js +1906 -1412
  16. package/dist/canvas/components/StageNode/StageNode.styles.cjs +1 -1
  17. package/dist/canvas/components/StageNode/StageNode.styles.js +1 -1
  18. package/dist/canvas/components/StageNode/StageNode.types.d.ts +26 -10
  19. package/dist/canvas/components/StageNode/StageNode.types.d.ts.map +1 -1
  20. package/dist/canvas/components/StageNode/StageNodeTaskUtilities.cjs +10 -5
  21. package/dist/canvas/components/StageNode/StageNodeTaskUtilities.d.ts +2 -1
  22. package/dist/canvas/components/StageNode/StageNodeTaskUtilities.d.ts.map +1 -1
  23. package/dist/canvas/components/StageNode/StageNodeTaskUtilities.js +6 -4
  24. package/dist/canvas/components/StageNode/TaskMenu.cjs +11 -43
  25. package/dist/canvas/components/StageNode/TaskMenu.d.ts +1 -6
  26. package/dist/canvas/components/StageNode/TaskMenu.d.ts.map +1 -1
  27. package/dist/canvas/components/StageNode/TaskMenu.js +13 -35
  28. package/dist/canvas/components/StageNode/index.cjs +17 -3
  29. package/dist/canvas/components/StageNode/index.d.ts +4 -1
  30. package/dist/canvas/components/StageNode/index.d.ts.map +1 -1
  31. package/dist/canvas/components/StageNode/index.js +3 -1
  32. package/dist/canvas/components/TaskNode/PlaceholderTaskNode.cjs +51 -0
  33. package/dist/canvas/components/TaskNode/PlaceholderTaskNode.d.ts +8 -0
  34. package/dist/canvas/components/TaskNode/PlaceholderTaskNode.d.ts.map +1 -0
  35. package/dist/canvas/components/TaskNode/PlaceholderTaskNode.js +17 -0
  36. package/dist/canvas/components/TaskNode/TaskNode.cjs +235 -0
  37. package/dist/canvas/components/TaskNode/TaskNode.d.ts +11 -0
  38. package/dist/canvas/components/TaskNode/TaskNode.d.ts.map +1 -0
  39. package/dist/canvas/components/TaskNode/TaskNode.js +198 -0
  40. package/dist/canvas/components/TaskNode/TaskNode.stories.cjs +558 -0
  41. package/dist/canvas/components/TaskNode/TaskNode.stories.d.ts +8 -0
  42. package/dist/canvas/components/TaskNode/TaskNode.stories.d.ts.map +1 -0
  43. package/dist/canvas/components/TaskNode/TaskNode.stories.js +515 -0
  44. package/dist/canvas/components/TaskNode/TaskNode.types.d.ts +40 -0
  45. package/dist/canvas/components/TaskNode/TaskNode.types.d.ts.map +1 -0
  46. package/dist/canvas/components/TaskNode/TaskNodeContext.cjs +86 -0
  47. package/dist/canvas/components/TaskNode/TaskNodeContext.d.ts +24 -0
  48. package/dist/canvas/components/TaskNode/TaskNodeContext.d.ts.map +1 -0
  49. package/dist/canvas/components/TaskNode/TaskNodeContext.js +40 -0
  50. package/dist/canvas/components/TaskNode/index.cjs +82 -0
  51. package/dist/canvas/components/TaskNode/index.d.ts +8 -0
  52. package/dist/canvas/components/TaskNode/index.d.ts.map +1 -0
  53. package/dist/canvas/components/TaskNode/index.js +6 -0
  54. package/dist/canvas/components/TaskNode/taskReorderUtils.cjs +206 -0
  55. package/dist/canvas/components/TaskNode/taskReorderUtils.d.ts +23 -0
  56. package/dist/canvas/components/TaskNode/taskReorderUtils.d.ts.map +1 -0
  57. package/dist/canvas/components/TaskNode/taskReorderUtils.js +154 -0
  58. package/dist/canvas/components/TaskNode/useTaskPositions.cjs +153 -0
  59. package/dist/canvas/components/TaskNode/useTaskPositions.d.ts +29 -0
  60. package/dist/canvas/components/TaskNode/useTaskPositions.d.ts.map +1 -0
  61. package/dist/canvas/components/TaskNode/useTaskPositions.js +110 -0
  62. package/dist/canvas/core/TaskTypeRegistry.cjs +132 -0
  63. package/dist/canvas/core/TaskTypeRegistry.d.ts +18 -0
  64. package/dist/canvas/core/TaskTypeRegistry.d.ts.map +1 -0
  65. package/dist/canvas/core/TaskTypeRegistry.js +98 -0
  66. package/dist/canvas/core/index.cjs +21 -3
  67. package/dist/canvas/core/index.d.ts +2 -0
  68. package/dist/canvas/core/index.d.ts.map +1 -1
  69. package/dist/canvas/core/index.js +2 -0
  70. package/dist/canvas/core/useTaskTypeRegistry.cjs +82 -0
  71. package/dist/canvas/core/useTaskTypeRegistry.d.ts +13 -0
  72. package/dist/canvas/core/useTaskTypeRegistry.d.ts.map +1 -0
  73. package/dist/canvas/core/useTaskTypeRegistry.js +33 -0
  74. package/dist/canvas/hooks/CrossStageDragContext.cjs +45 -0
  75. package/dist/canvas/hooks/CrossStageDragContext.d.ts +8 -0
  76. package/dist/canvas/hooks/CrossStageDragContext.d.ts.map +1 -0
  77. package/dist/canvas/hooks/CrossStageDragContext.js +8 -0
  78. package/dist/canvas/hooks/calculateTaskDropPosition.cjs +253 -0
  79. package/dist/canvas/hooks/calculateTaskDropPosition.d.ts +11 -0
  80. package/dist/canvas/hooks/calculateTaskDropPosition.d.ts.map +1 -0
  81. package/dist/canvas/hooks/calculateTaskDropPosition.js +216 -0
  82. package/dist/canvas/hooks/index.cjs +57 -30
  83. package/dist/canvas/hooks/index.d.ts +3 -0
  84. package/dist/canvas/hooks/index.d.ts.map +1 -1
  85. package/dist/canvas/hooks/index.js +3 -0
  86. package/dist/canvas/hooks/useCrossStageTaskDrag.cjs +346 -0
  87. package/dist/canvas/hooks/useCrossStageTaskDrag.d.ts +44 -0
  88. package/dist/canvas/hooks/useCrossStageTaskDrag.d.ts.map +1 -0
  89. package/dist/canvas/hooks/useCrossStageTaskDrag.js +312 -0
  90. package/dist/canvas/hooks/useTaskCopyPaste.cjs +155 -0
  91. package/dist/canvas/hooks/useTaskCopyPaste.d.ts +34 -0
  92. package/dist/canvas/hooks/useTaskCopyPaste.d.ts.map +1 -0
  93. package/dist/canvas/hooks/useTaskCopyPaste.js +121 -0
  94. package/dist/canvas/schema/index.cjs +12 -3
  95. package/dist/canvas/schema/index.d.ts +1 -0
  96. package/dist/canvas/schema/index.d.ts.map +1 -1
  97. package/dist/canvas/schema/index.js +1 -0
  98. package/dist/canvas/schema/task-definition/index.cjs +60 -0
  99. package/dist/canvas/schema/task-definition/index.d.ts +2 -0
  100. package/dist/canvas/schema/task-definition/index.d.ts.map +1 -0
  101. package/dist/canvas/schema/task-definition/index.js +1 -0
  102. package/dist/canvas/schema/task-definition/task-manifest.cjs +78 -0
  103. package/dist/canvas/schema/task-definition/task-manifest.d.ts +43 -0
  104. package/dist/canvas/schema/task-definition/task-manifest.d.ts.map +1 -0
  105. package/dist/canvas/schema/task-definition/task-manifest.js +29 -0
  106. package/dist/material/components/ap-sankey-diagram/ApSankeyDiagram.cjs +44 -21
  107. package/dist/material/components/ap-sankey-diagram/ApSankeyDiagram.d.ts.map +1 -1
  108. package/dist/material/components/ap-sankey-diagram/ApSankeyDiagram.js +44 -21
  109. package/package.json +3 -3
  110. package/dist/canvas/components/StageNode/DraggableTask.cjs +0 -271
  111. package/dist/canvas/components/StageNode/DraggableTask.d.ts +0 -4
  112. package/dist/canvas/components/StageNode/DraggableTask.d.ts.map +0 -1
  113. package/dist/canvas/components/StageNode/DraggableTask.js +0 -234
  114. package/dist/canvas/components/StageNode/DraggableTask.types.d.ts +0 -20
  115. package/dist/canvas/components/StageNode/DraggableTask.types.d.ts.map +0 -1
  116. package/dist/canvas/components/StageNode/StageNode.utils.cjs +0 -164
  117. package/dist/canvas/components/StageNode/StageNode.utils.d.ts +0 -19
  118. package/dist/canvas/components/StageNode/StageNode.utils.d.ts.map +0 -1
  119. package/dist/canvas/components/StageNode/StageNode.utils.js +0 -121
  120. /package/dist/canvas/components/{StageNode/DraggableTask.types.cjs → TaskNode/TaskNode.types.cjs} +0 -0
  121. /package/dist/canvas/components/{StageNode/DraggableTask.types.js → TaskNode/TaskNode.types.js} +0 -0
@@ -1,108 +1,85 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { DndContext, DragOverlay, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
3
- import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from "@dnd-kit/sortable";
4
2
  import { FontVariantToken, Padding, Spacing } from "@uipath/apollo-core";
5
3
  import { Column, Row } from "../../layouts/index.js";
6
- import { Position, useStore, useViewport } from "../../xyflow/react.js";
4
+ import { Position, useStore } from "../../xyflow/react.js";
7
5
  import { ApCircularProgress, ApIcon, ApIconButton, ApLink, ApTooltip, ApTypography } from "../../../material/index.js";
8
6
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
9
- import { createPortal } from "react-dom";
7
+ import { useCrossStageDragState } from "../../hooks/CrossStageDragContext.js";
10
8
  import { useConnectedHandles } from "../BaseCanvas/ConnectedHandlesContext.js";
11
9
  import { useButtonHandles } from "../ButtonHandle/useButtonHandles.js";
12
10
  import { ExecutionStatusIcon } from "../ExecutionStatusIcon/index.js";
13
11
  import { FloatingCanvasPanel } from "../FloatingCanvasPanel/index.js";
14
12
  import { NodeContextMenu } from "../NodeContextMenu/index.js";
15
13
  import { useNodeSelection } from "../NodePropertiesPanel/hooks/index.js";
14
+ import { TaskNodeProvider } from "../TaskNode/TaskNodeContext.js";
15
+ import { DEFAULT_TASK_POSITION_CONFIG, calculateStageContentHeight } from "../TaskNode/useTaskPositions.js";
16
16
  import { Toolbox } from "../Toolbox/index.js";
17
- import { DraggableTask, TaskContent } from "./DraggableTask.js";
18
- import { INDENTATION_WIDTH, STAGE_CONTENT_INSET, StageContainer, StageContent, StageHeader, StageParallelBracket, StageParallelLabel, StageTask, StageTaskGroup, StageTaskList, StageTitleContainer, StageTitleInput } from "./StageNode.styles.js";
19
- import { flattenTasks, getProjection, reorderTasks } from "./StageNode.utils.js";
20
- import { getContextMenuItems, getMenuItem } from "./StageNodeTaskUtilities.js";
17
+ import { INDENTATION_WIDTH, STAGE_CONTENT_INSET, StageContainer, StageContent, StageHeader, StageParallelBracket, StageParallelLabel, StageTaskList, StageTitleContainer, StageTitleInput } from "./StageNode.styles.js";
18
+ function calculateExecutionExtraHeight(execution) {
19
+ if (!execution) return 0;
20
+ if (execution.duration || execution.retryDuration || execution.badge) if (execution.retryDuration || execution.badge) return 26;
21
+ else return 18;
22
+ return 2;
23
+ }
24
+ function calculateParallelGroupY(groupIndex, taskIds, hasStageExecution, taskExecutionData, config = DEFAULT_TASK_POSITION_CONFIG) {
25
+ const headerHeight = hasStageExecution ? config.headerHeight + config.headerExecutionDescriptionHeight : config.headerHeight;
26
+ let y = headerHeight + config.contentPaddingTop;
27
+ for(let i = 0; i < groupIndex; i++){
28
+ const group = taskIds[i];
29
+ if (group) {
30
+ for(let j = 0; j < group.length; j++){
31
+ const taskId = group[j];
32
+ const execution = taskId ? taskExecutionData[taskId]?.execution : void 0;
33
+ const taskHeight = config.taskHeight + calculateExecutionExtraHeight(execution);
34
+ y += taskHeight;
35
+ if (j < group.length - 1) y += config.taskGap;
36
+ }
37
+ y += config.taskGap;
38
+ }
39
+ }
40
+ return y;
41
+ }
42
+ function calculateParallelGroupHeight(group, taskExecutionData, config = DEFAULT_TASK_POSITION_CONFIG) {
43
+ let height = 0;
44
+ for(let i = 0; i < group.length; i++){
45
+ const taskId = group[i];
46
+ const execution = taskId ? taskExecutionData[taskId]?.execution : void 0;
47
+ const taskHeight = config.taskHeight + calculateExecutionExtraHeight(execution);
48
+ height += taskHeight;
49
+ if (i < group.length - 1) height += config.taskGap;
50
+ }
51
+ return height;
52
+ }
21
53
  const StageNodeComponent = (props)=>{
22
- const { dragging, selected, id, width, execution, stageDetails, addTaskLabel = 'Add task', addTaskLoading = false, replaceTaskLabel = 'Replace task', taskOptions = [], menuItems, pendingReplaceTask, onStageClick, onTaskAdd, onAddTaskFromToolbox, onTaskToolboxSearch, onTaskClick, onTaskGroupModification, onStageTitleChange, onTaskReorder, onReplaceTaskFromToolbox } = props;
23
- const taskWidth = width ? width - STAGE_CONTENT_INSET : void 0;
24
- const tasks = useMemo(()=>stageDetails?.tasks || [], [
25
- stageDetails?.tasks
26
- ]);
27
- const flatTasks = useMemo(()=>tasks.flat(), [
28
- tasks
29
- ]);
30
- const taskIds = useMemo(()=>flatTasks.map((task)=>task.id), [
31
- flatTasks
54
+ const { dragging, selected, id, nodeType = 'stage', width, execution, stageDetails, addTaskLabel = 'Add task', addTaskLoading = false, replaceTaskLabel = 'Replace task', taskOptions = [], menuItems, pendingReplaceTask, onStageClick, onTaskAdd, onAddTaskFromToolbox, onTaskToolboxSearch, onReplaceTaskFromToolbox, replaceTaskTarget, onReplaceTaskTargetChange, onTaskClick, onTaskSelect, onStageTitleChange } = props;
55
+ const taskIds = useMemo(()=>stageDetails?.taskIds || [], [
56
+ stageDetails?.taskIds
32
57
  ]);
33
58
  const isException = stageDetails?.isException;
34
59
  const isReadOnly = !!stageDetails?.isReadOnly;
35
60
  const icon = stageDetails?.icon;
36
- const selectedTasks = stageDetails?.selectedTasks;
37
61
  const defaultContent = stageDetails?.defaultContent || 'Add first task';
38
62
  const status = execution?.stageStatus?.status;
39
63
  const statusLabel = execution?.stageStatus?.label;
40
64
  const stageDuration = execution?.stageStatus?.duration;
41
- const reGroupTaskFunction = useMemo(()=>onTaskGroupModification || (()=>{}), [
42
- onTaskGroupModification
43
- ]);
44
65
  const isStageTitleEditable = !!onStageTitleChange && !isReadOnly;
45
66
  const [isHovered, setIsHovered] = useState(false);
46
67
  const [label, setLabel] = useState(props.stageDetails.label);
68
+ const [toolboxMode, setToolboxMode] = useState(null);
69
+ const replaceTaskRef = useRef(null);
70
+ const [isStageTitleEditing, setIsStageTitleEditing] = useState(false);
71
+ const stageTitleRef = useRef(null);
47
72
  useEffect(()=>{
48
73
  setLabel(props.stageDetails.label);
49
74
  }, [
50
75
  props.stageDetails.label
51
76
  ]);
52
- const [isStageTitleEditing, setIsStageTitleEditing] = useState(false);
53
- const stageTitleRef = useRef(null);
54
- const taskStateReference = useRef({
55
- isParallel: false,
56
- groupIndex: -1,
57
- taskIndex: -1
58
- });
59
77
  const isConnecting = useStore((state)=>!!state.connectionClickStartHandle);
60
78
  const connectedHandleIds = useConnectedHandles(id);
61
- const [isAddingTask, setIsAddingTask] = useState(false);
62
- const [isReplacingTask, setIsReplacingTask] = useState(false);
63
- useEffect(()=>{
64
- if (pendingReplaceTask?.groupIndex != null && pendingReplaceTask?.taskIndex != null) {
65
- const taskGroup = tasks[pendingReplaceTask.groupIndex];
66
- taskStateReference.current = {
67
- isParallel: (taskGroup?.length ?? 0) > 1,
68
- groupIndex: pendingReplaceTask.groupIndex,
69
- taskIndex: pendingReplaceTask.taskIndex
70
- };
71
- setIsReplacingTask(true);
72
- }
73
- }, [
74
- pendingReplaceTask,
75
- tasks
76
- ]);
77
- const [activeDragId, setActiveDragId] = useState(null);
78
- const [offsetLeft, setOffsetLeft] = useState(0);
79
- const [overId, setOverId] = useState(null);
80
- const activeTask = useMemo(()=>flatTasks.find((t)=>t.id === activeDragId), [
81
- flatTasks,
82
- activeDragId
83
- ]);
84
- const isActiveTaskParallel = useMemo(()=>{
85
- if (!activeDragId) return false;
86
- const group = tasks.find((g)=>g.some((t)=>t.id === activeDragId));
87
- return group ? group.length > 1 : false;
88
- }, [
89
- tasks,
90
- activeDragId
91
- ]);
92
- const { zoom } = useViewport();
93
- const projected = useMemo(()=>{
94
- if (!activeDragId || !overId) return null;
95
- return getProjection(tasks, activeDragId, overId, offsetLeft);
96
- }, [
97
- tasks,
98
- activeDragId,
99
- overId,
100
- offsetLeft
101
- ]);
102
79
  useEffect(()=>{
103
80
  if (false === selected) {
104
- setIsAddingTask(false);
105
- setIsReplacingTask(false);
81
+ setToolboxMode(null);
82
+ replaceTaskRef.current = null;
106
83
  }
107
84
  }, [
108
85
  selected
@@ -127,19 +104,6 @@ const StageNodeComponent = (props)=>{
127
104
  setIsStageTitleEditing(true);
128
105
  setLabel(e.target.value);
129
106
  }, []);
130
- const handleStageTitleClickToSave = useCallback((e)=>{
131
- if (isStageTitleEditing && !stageTitleRef.current?.contains(e.target)) {
132
- setIsStageTitleEditing(false);
133
- if (onStageTitleChange) {
134
- if ('' === label.trim()) setLabel('Untitled Stage');
135
- onStageTitleChange(label);
136
- }
137
- }
138
- }, [
139
- isStageTitleEditing,
140
- onStageTitleChange,
141
- label
142
- ]);
143
107
  const handleStageTitleBlurToSave = useCallback(()=>{
144
108
  if (isStageTitleEditing) {
145
109
  setIsStageTitleEditing(false);
@@ -162,50 +126,17 @@ const StageNodeComponent = (props)=>{
162
126
  onStageTitleChange,
163
127
  label
164
128
  ]);
165
- useEffect(()=>{
166
- if (isStageTitleEditing) document.addEventListener('click', handleStageTitleClickToSave);
167
- return ()=>{
168
- document.removeEventListener('click', handleStageTitleClickToSave);
169
- };
170
- }, [
171
- handleStageTitleClickToSave,
172
- isStageTitleEditing
173
- ]);
174
- const contextMenuItems = useCallback((isParallel, groupIndex, taskIndex, tasksLength, taskGroupLength, isAboveParallel, isBelowParallel)=>{
175
- const items = [];
176
- if (onReplaceTaskFromToolbox) items.push(getMenuItem('replace-task', 'Replace Task', ()=>setIsReplacingTask(true)));
177
- if (onTaskGroupModification) {
178
- const reGroupOptions = getContextMenuItems(isParallel, groupIndex, tasksLength, taskIndex, taskGroupLength, isAboveParallel, isBelowParallel, reGroupTaskFunction);
179
- return [
180
- ...items,
181
- ...reGroupOptions
182
- ];
183
- }
184
- return items;
185
- }, [
186
- onReplaceTaskFromToolbox,
187
- onTaskGroupModification,
188
- reGroupTaskFunction
189
- ]);
190
129
  const { setSelectedNodeId } = useNodeSelection();
191
130
  const handleStageClick = useCallback(()=>{
192
131
  onStageClick?.();
193
132
  }, [
194
133
  onStageClick
195
134
  ]);
196
- const handleTaskClick = useCallback((e, taskElementId)=>{
197
- e.stopPropagation();
198
- onTaskClick?.(taskElementId);
199
- setSelectedNodeId(id);
200
- }, [
201
- onTaskClick,
202
- setSelectedNodeId,
203
- id
204
- ]);
205
135
  const handleTaskAddClick = useCallback((event)=>{
206
136
  event.stopPropagation();
137
+ replaceTaskRef.current = null;
207
138
  if (onTaskAdd) onTaskAdd();
208
- else if (onAddTaskFromToolbox) setIsAddingTask(true);
139
+ else if (onAddTaskFromToolbox) setToolboxMode('add');
209
140
  setSelectedNodeId(id);
210
141
  }, [
211
142
  onTaskAdd,
@@ -213,25 +144,54 @@ const StageNodeComponent = (props)=>{
213
144
  setSelectedNodeId,
214
145
  id
215
146
  ]);
216
- const handleAddTaskToolboxItemSelected = useCallback((item)=>{
217
- onAddTaskFromToolbox?.(item);
218
- setIsAddingTask(false);
219
- setSelectedNodeId(id);
147
+ useEffect(()=>{
148
+ if (replaceTaskTarget) {
149
+ replaceTaskRef.current = replaceTaskTarget;
150
+ setToolboxMode('replace');
151
+ }
220
152
  }, [
221
- onAddTaskFromToolbox,
222
- setSelectedNodeId,
223
- id
153
+ replaceTaskTarget
154
+ ]);
155
+ useEffect(()=>{
156
+ if (pendingReplaceTask?.groupIndex != null && pendingReplaceTask?.taskIndex != null) {
157
+ replaceTaskRef.current = {
158
+ groupIndex: pendingReplaceTask.groupIndex,
159
+ taskIndex: pendingReplaceTask.taskIndex
160
+ };
161
+ setToolboxMode('replace');
162
+ }
163
+ }, [
164
+ pendingReplaceTask
224
165
  ]);
225
- const handleReplaceTaskToolboxItemSelected = useCallback((item)=>{
226
- setIsReplacingTask(true);
227
- onReplaceTaskFromToolbox?.(item, taskStateReference.current.groupIndex, taskStateReference.current.taskIndex);
228
- setIsReplacingTask(false);
166
+ const handleToolboxItemSelected = useCallback((item)=>{
167
+ if ('replace' === toolboxMode && replaceTaskRef.current && onReplaceTaskFromToolbox) onReplaceTaskFromToolbox(item, replaceTaskRef.current.groupIndex, replaceTaskRef.current.taskIndex);
168
+ else if ('add' === toolboxMode) onAddTaskFromToolbox?.(item);
169
+ setToolboxMode(null);
170
+ replaceTaskRef.current = null;
171
+ onReplaceTaskTargetChange?.(null);
229
172
  setSelectedNodeId(id);
230
173
  }, [
174
+ toolboxMode,
231
175
  onReplaceTaskFromToolbox,
176
+ onAddTaskFromToolbox,
177
+ onReplaceTaskTargetChange,
232
178
  setSelectedNodeId,
233
179
  id
234
180
  ]);
181
+ const handleToolboxClose = useCallback(()=>{
182
+ setToolboxMode(null);
183
+ replaceTaskRef.current = null;
184
+ onReplaceTaskTargetChange?.(null);
185
+ }, [
186
+ onReplaceTaskTargetChange
187
+ ]);
188
+ const taskWidth = width ? width - STAGE_CONTENT_INSET : void 0;
189
+ const taskWidthStyle = useMemo(()=>taskWidth ? {
190
+ '--stage-task-width': `${taskWidth}px`,
191
+ '--stage-task-width-parallel': `${taskWidth - INDENTATION_WIDTH}px`
192
+ } : void 0, [
193
+ taskWidth
194
+ ]);
235
195
  const handleConfigurations = useMemo(()=>isException ? [] : [
236
196
  {
237
197
  position: Position.Left,
@@ -298,292 +258,277 @@ const StageNodeComponent = (props)=>{
298
258
  nodeId: id,
299
259
  selected
300
260
  });
301
- const sensors = useSensors(useSensor(PointerSensor, {
302
- activationConstraint: {
303
- distance: 3
304
- }
305
- }), useSensor(KeyboardSensor, {
306
- coordinateGetter: sortableKeyboardCoordinates
307
- }));
308
- const resetState = useCallback(()=>{
309
- setActiveDragId(null);
310
- setOffsetLeft(0);
311
- setOverId(null);
312
- }, []);
313
- const handleDragStart = useCallback((event)=>{
314
- setActiveDragId(event.active.id);
315
- }, []);
316
- const handleDragMove = useCallback((event)=>{
317
- setOffsetLeft(event.delta.x / zoom);
318
- }, [
319
- zoom
261
+ const taskNodeContextValue = useMemo(()=>({
262
+ stageId: id,
263
+ stageNodeType: nodeType,
264
+ taskIds,
265
+ isReadOnly,
266
+ onTaskClick,
267
+ onTaskSelect
268
+ }), [
269
+ id,
270
+ nodeType,
271
+ taskIds,
272
+ isReadOnly,
273
+ onTaskClick,
274
+ onTaskSelect
320
275
  ]);
321
- const handleDragOver = useCallback((event)=>{
322
- setOverId(event.over?.id ?? null);
323
- }, []);
324
- const handleDragEnd = useCallback((event)=>{
325
- const { active, over } = event;
326
- const currentOffsetLeft = offsetLeft;
327
- resetState();
328
- if (!over || !onTaskReorder) return;
329
- const projection = getProjection(tasks, active.id, over.id, currentOffsetLeft);
330
- if (!projection) return;
331
- if (active.id === over.id) {
332
- const flattened = flattenTasks(tasks);
333
- const activeTask = flattened.find((t)=>t.id === active.id);
334
- if (activeTask && activeTask.depth === projection.depth) return;
276
+ const dragState = useCrossStageDragState();
277
+ const displayTaskIds = useMemo(()=>{
278
+ if (dragState?.isDragging && dragState.taskId) {
279
+ if (dragState.targetStageId === id && dragState.dropPosition) {
280
+ const { groupIndex, taskIndex, isParallel } = dragState.dropPosition;
281
+ const tempTaskIds = taskIds.map((g)=>[
282
+ ...g
283
+ ]);
284
+ for(let gi = 0; gi < tempTaskIds.length; gi++){
285
+ const group = tempTaskIds[gi];
286
+ if (!group) continue;
287
+ const idx = group.indexOf(dragState.taskId);
288
+ if (-1 !== idx) group.splice(idx, 1);
289
+ }
290
+ const filtered = tempTaskIds.filter((g)=>g && g.length > 0);
291
+ if (groupIndex >= filtered.length) filtered.push([
292
+ '__placeholder__'
293
+ ]);
294
+ else if (isParallel && filtered[groupIndex]) filtered[groupIndex].splice(taskIndex, 0, '__placeholder__');
295
+ else filtered.splice(groupIndex, 0, [
296
+ '__placeholder__'
297
+ ]);
298
+ return filtered;
299
+ }
300
+ if (dragState.sourceStageId === id && dragState.targetStageId !== id) {
301
+ const tempTaskIds = taskIds.map((g)=>[
302
+ ...g
303
+ ]);
304
+ for(let gi = 0; gi < tempTaskIds.length; gi++){
305
+ const group = tempTaskIds[gi];
306
+ if (!group) continue;
307
+ const idx = group.indexOf(dragState.taskId);
308
+ if (-1 !== idx) group.splice(idx, 1);
309
+ }
310
+ return tempTaskIds.filter((g)=>g && g.length > 0);
311
+ }
335
312
  }
336
- const newTasks = reorderTasks(tasks, active.id, over.id, projection.depth);
337
- onTaskReorder(newTasks);
313
+ return taskIds;
338
314
  }, [
339
- tasks,
340
- onTaskReorder,
341
- offsetLeft,
342
- resetState
315
+ taskIds,
316
+ dragState,
317
+ id
343
318
  ]);
344
- const handleDragCancel = useCallback(()=>{
345
- resetState();
319
+ const taskNodes = useStore((state)=>state.nodes.filter((n)=>'task' === n.type && n.parentId === id));
320
+ const taskExecutionData = useMemo(()=>{
321
+ const data = {};
322
+ for (const node of taskNodes)data[node.id] = {
323
+ execution: node.data?.execution
324
+ };
325
+ return data;
346
326
  }, [
347
- resetState
327
+ taskNodes
348
328
  ]);
349
- const taskWidthStyle = useMemo(()=>taskWidth ? {
350
- '--stage-task-width': `${taskWidth}px`,
351
- '--stage-task-width-parallel': `${taskWidth - INDENTATION_WIDTH}px`
352
- } : void 0, [
353
- taskWidth
329
+ const parallelGroups = useMemo(()=>{
330
+ const hasStageExecution = !!stageDuration;
331
+ return displayTaskIds.map((group, index)=>{
332
+ const isParallel = group.length > 1;
333
+ if (!isParallel) return null;
334
+ const y = calculateParallelGroupY(index, displayTaskIds, hasStageExecution, taskExecutionData);
335
+ const height = calculateParallelGroupHeight(group, taskExecutionData);
336
+ return {
337
+ index,
338
+ y,
339
+ height
340
+ };
341
+ }).filter((g)=>null !== g);
342
+ }, [
343
+ displayTaskIds,
344
+ stageDuration,
345
+ taskExecutionData
354
346
  ]);
355
- const dragOverlayStyle = useMemo(()=>({
356
- transform: `scale(${zoom})`,
357
- transformOrigin: 'top left'
358
- }), [
359
- zoom
347
+ const contentHeight = useMemo(()=>{
348
+ if (0 === displayTaskIds.length) return 60;
349
+ return calculateStageContentHeight(displayTaskIds, taskNodes);
350
+ }, [
351
+ displayTaskIds,
352
+ taskNodes,
353
+ execution
360
354
  ]);
361
- return /*#__PURE__*/ jsxs("div", {
362
- "data-testid": `stage-${id}`,
363
- style: {
364
- position: 'relative'
365
- },
366
- onClick: handleStageClick,
367
- onMouseEnter: handleMouseEnter,
368
- onMouseLeave: handleMouseLeave,
369
- children: [
370
- /*#__PURE__*/ jsxs(StageContainer, {
371
- selected: selected,
372
- status: status,
373
- width: width,
374
- style: taskWidthStyle,
375
- children: [
376
- /*#__PURE__*/ jsxs(StageHeader, {
377
- isException: isException,
355
+ return /*#__PURE__*/ jsx(TaskNodeProvider, {
356
+ value: taskNodeContextValue,
357
+ children: /*#__PURE__*/ jsxs("div", {
358
+ "data-testid": `stage-${id}`,
359
+ style: {
360
+ position: 'relative',
361
+ ...taskWidthStyle
362
+ },
363
+ onClick: handleStageClick,
364
+ onMouseEnter: handleMouseEnter,
365
+ onMouseLeave: handleMouseLeave,
366
+ children: [
367
+ parallelGroups.map(({ index, y, height })=>{
368
+ const absoluteY = y;
369
+ const absoluteX = DEFAULT_TASK_POSITION_CONFIG.contentPaddingX + DEFAULT_TASK_POSITION_CONFIG.parallelIndent;
370
+ const bracketX = absoluteX - 12 - 4 - 12;
371
+ return /*#__PURE__*/ jsxs(Row, {
372
+ gap: Spacing.SpacingS,
373
+ style: {
374
+ position: 'absolute',
375
+ top: absoluteY,
376
+ left: bracketX,
377
+ height: height,
378
+ pointerEvents: 'none',
379
+ zIndex: 1
380
+ },
378
381
  children: [
379
- /*#__PURE__*/ jsxs(Row, {
380
- gap: Spacing.SpacingMicro,
381
- align: "center",
382
- children: [
383
- icon,
384
- /*#__PURE__*/ jsxs(Column, {
385
- py: 2,
386
- children: [
387
- /*#__PURE__*/ jsx(ApTypography, {
388
- variant: isStageTitleEditing ? FontVariantToken.fontSizeM : FontVariantToken.fontSizeMBold,
389
- color: "var(--uix-canvas-foreground)",
390
- children: /*#__PURE__*/ jsx(ApTooltip, {
391
- content: label,
392
- placement: "top",
393
- delay: true,
394
- children: /*#__PURE__*/ jsx(StageTitleContainer, {
395
- isEditing: isStageTitleEditing,
396
- children: /*#__PURE__*/ jsx(StageTitleInput, {
397
- name: "Stage Title",
398
- isStageTitleEditable: isStageTitleEditable,
399
- value: label,
400
- ref: stageTitleRef,
382
+ /*#__PURE__*/ jsx(StageParallelBracket, {}),
383
+ /*#__PURE__*/ jsx("div", {
384
+ style: {
385
+ position: 'relative',
386
+ width: 0,
387
+ height: '100%'
388
+ },
389
+ children: /*#__PURE__*/ jsx(StageParallelLabel, {
390
+ children: /*#__PURE__*/ jsx(ApTypography, {
391
+ variant: FontVariantToken.fontSizeS,
392
+ children: "Parallel"
393
+ })
394
+ })
395
+ })
396
+ ]
397
+ }, `parallel-${index}`);
398
+ }),
399
+ /*#__PURE__*/ jsxs(StageContainer, {
400
+ selected: selected,
401
+ status: status,
402
+ width: width,
403
+ style: {
404
+ minHeight: contentHeight + (execution?.stageStatus?.duration ? DEFAULT_TASK_POSITION_CONFIG.headerHeight + DEFAULT_TASK_POSITION_CONFIG.headerExecutionDescriptionHeight : DEFAULT_TASK_POSITION_CONFIG.headerHeight) + 2 * DEFAULT_TASK_POSITION_CONFIG.stageBorderThickness
405
+ },
406
+ children: [
407
+ /*#__PURE__*/ jsxs(StageHeader, {
408
+ isException: isException,
409
+ children: [
410
+ /*#__PURE__*/ jsxs(Row, {
411
+ gap: Spacing.SpacingMicro,
412
+ align: "center",
413
+ children: [
414
+ icon,
415
+ /*#__PURE__*/ jsxs(Column, {
416
+ py: 2,
417
+ children: [
418
+ /*#__PURE__*/ jsx(ApTypography, {
419
+ variant: isStageTitleEditing ? FontVariantToken.fontSizeM : FontVariantToken.fontSizeMBold,
420
+ color: "var(--uix-canvas-foreground)",
421
+ children: /*#__PURE__*/ jsx(ApTooltip, {
422
+ content: label,
423
+ placement: "top",
424
+ delay: true,
425
+ children: /*#__PURE__*/ jsx(StageTitleContainer, {
401
426
  isEditing: isStageTitleEditing,
402
- ...onStageTitleChange && {
403
- onFocus: ()=>setIsStageTitleEditing(true),
404
- onInput: handleStageTitleChange,
405
- onKeyDown: handleStageTitleKeyDown,
406
- onBlur: handleStageTitleBlurToSave
407
- },
408
- readOnly: !isStageTitleEditable
427
+ children: /*#__PURE__*/ jsx(StageTitleInput, {
428
+ name: "Stage Title",
429
+ isStageTitleEditable: isStageTitleEditable,
430
+ value: label,
431
+ ref: stageTitleRef,
432
+ isEditing: isStageTitleEditing,
433
+ ...onStageTitleChange && {
434
+ onFocus: ()=>setIsStageTitleEditing(true),
435
+ onInput: handleStageTitleChange,
436
+ onKeyDown: handleStageTitleKeyDown,
437
+ onBlur: handleStageTitleBlurToSave
438
+ },
439
+ readOnly: !isStageTitleEditable
440
+ })
409
441
  })
410
442
  })
443
+ }),
444
+ stageDuration && /*#__PURE__*/ jsx(ApTypography, {
445
+ variant: FontVariantToken.fontSizeS,
446
+ color: "var(--uix-canvas-foreground-de-emp)",
447
+ children: stageDuration
411
448
  })
412
- }),
413
- stageDuration && /*#__PURE__*/ jsx(ApTypography, {
414
- variant: FontVariantToken.fontSizeS,
415
- color: "var(--uix-canvas-foreground-de-emp)",
416
- children: stageDuration
417
- })
418
- ]
419
- })
420
- ]
421
- }),
422
- /*#__PURE__*/ jsxs(Row, {
423
- gap: Spacing.SpacingMicro,
424
- align: isReadOnly ? 'start' : 'center',
425
- py: Padding.PadS,
426
- children: [
427
- status && /*#__PURE__*/ jsx(ApTooltip, {
428
- content: statusLabel,
429
- placement: "top",
430
- children: /*#__PURE__*/ jsx(ApIconButton, {
431
- size: "small",
432
- children: /*#__PURE__*/ jsx(ExecutionStatusIcon, {
433
- status: status,
434
- size: 20
435
- })
449
+ ]
436
450
  })
437
- }),
438
- (onTaskAdd || onAddTaskFromToolbox) && !isReadOnly && /*#__PURE__*/ jsx(ApTooltip, {
439
- content: addTaskLoading ? 'Loading...' : addTaskLabel,
440
- placement: "top",
441
- children: /*#__PURE__*/ jsx("span", {
451
+ ]
452
+ }),
453
+ /*#__PURE__*/ jsxs(Row, {
454
+ gap: Spacing.SpacingMicro,
455
+ align: isReadOnly ? 'start' : 'center',
456
+ py: Padding.PadS,
457
+ children: [
458
+ status && /*#__PURE__*/ jsx(ApTooltip, {
459
+ content: statusLabel,
460
+ placement: "top",
442
461
  children: /*#__PURE__*/ jsx(ApIconButton, {
443
- onClick: handleTaskAddClick,
444
462
  size: "small",
445
- disabled: addTaskLoading,
446
- label: addTaskLabel,
447
- children: addTaskLoading ? /*#__PURE__*/ jsx(ApCircularProgress, {
463
+ children: /*#__PURE__*/ jsx(ExecutionStatusIcon, {
464
+ status: status,
448
465
  size: 20
449
- }) : /*#__PURE__*/ jsx(ApIcon, {
450
- name: "add",
451
- size: "20px"
452
466
  })
453
467
  })
454
- })
455
- })
456
- ]
457
- })
458
- ]
459
- }),
460
- /*#__PURE__*/ jsx(StageContent, {
461
- children: tasks && 0 !== tasks.length ? /*#__PURE__*/ jsxs(DndContext, {
462
- collisionDetection: closestCenter,
463
- sensors: sensors,
464
- onDragStart: handleDragStart,
465
- onDragMove: handleDragMove,
466
- onDragOver: handleDragOver,
467
- onDragEnd: handleDragEnd,
468
- onDragCancel: handleDragCancel,
469
- children: [
470
- /*#__PURE__*/ jsx(SortableContext, {
471
- items: taskIds,
472
- strategy: verticalListSortingStrategy,
473
- children: /*#__PURE__*/ jsx(StageTaskList, {
474
- className: "nodrag nopan",
475
- children: tasks.map((taskGroup, groupIndex)=>{
476
- const isParallel = taskGroup.length > 1;
477
- return /*#__PURE__*/ jsxs(Row, {
478
- gap: Spacing.SpacingS,
479
- children: [
480
- isParallel && /*#__PURE__*/ jsx(StageParallelBracket, {}),
481
- /*#__PURE__*/ jsxs(StageTaskGroup, {
482
- isParallel: isParallel,
483
- children: [
484
- isParallel && /*#__PURE__*/ jsx(StageParallelLabel, {
485
- children: /*#__PURE__*/ jsx(ApTypography, {
486
- variant: FontVariantToken.fontSizeS,
487
- children: "Parallel"
488
- })
489
- }),
490
- taskGroup.map((task, taskIndex)=>{
491
- const taskExecution = execution?.taskStatus?.[task.id];
492
- return /*#__PURE__*/ jsx(DraggableTask, {
493
- task: task,
494
- taskExecution: taskExecution,
495
- isSelected: !!selectedTasks?.includes(task.id),
496
- isParallel: isParallel,
497
- contextMenuItems: contextMenuItems(isParallel, groupIndex, taskIndex, tasks.length, taskGroup.length, (tasks[groupIndex - 1]?.length ?? 0) > 1, (tasks[groupIndex + 1]?.length ?? 0) > 1),
498
- onTaskClick: handleTaskClick,
499
- projectedDepth: task.id === activeDragId && projected ? projected.depth : void 0,
500
- isDragDisabled: !onTaskReorder,
501
- zoom: zoom,
502
- ...(onTaskGroupModification || onReplaceTaskFromToolbox) && {
503
- onMenuOpen: ()=>{
504
- taskStateReference.current = {
505
- isParallel,
506
- groupIndex,
507
- taskIndex
508
- };
509
- }
510
- }
511
- }, task.id);
512
- })
513
- ]
468
+ }),
469
+ (onTaskAdd || onAddTaskFromToolbox) && !isReadOnly && /*#__PURE__*/ jsx(ApTooltip, {
470
+ content: addTaskLoading ? 'Loading...' : addTaskLabel,
471
+ placement: "top",
472
+ children: /*#__PURE__*/ jsx("span", {
473
+ children: /*#__PURE__*/ jsx(ApIconButton, {
474
+ onClick: handleTaskAddClick,
475
+ size: "small",
476
+ disabled: addTaskLoading,
477
+ label: addTaskLabel,
478
+ children: addTaskLoading ? /*#__PURE__*/ jsx(ApCircularProgress, {
479
+ size: 20
480
+ }) : /*#__PURE__*/ jsx(ApIcon, {
481
+ name: "add",
482
+ size: "20px"
514
483
  })
515
- ]
516
- }, `group-${groupIndex}`);
517
- })
518
- })
519
- }),
520
- /*#__PURE__*/ createPortal(/*#__PURE__*/ jsx(DragOverlay, {
521
- children: activeTask ? /*#__PURE__*/ jsx("div", {
522
- style: dragOverlayStyle,
523
- children: /*#__PURE__*/ jsx(StageTask, {
524
- selected: true,
525
- isParallel: isActiveTaskParallel,
526
- style: {
527
- cursor: 'grabbing',
528
- ...taskWidthStyle
529
- },
530
- children: /*#__PURE__*/ jsx(TaskContent, {
531
- task: activeTask,
532
- isDragging: true
484
+ })
533
485
  })
534
486
  })
535
- }) : null
536
- }), document.body)
487
+ ]
488
+ })
537
489
  ]
538
- }) : /*#__PURE__*/ jsx(Column, {
539
- py: 2,
540
- children: (onTaskAdd || onAddTaskFromToolbox) && !isReadOnly ? /*#__PURE__*/ jsx(ApLink, {
541
- onClick: addTaskLoading ? void 0 : handleTaskAddClick,
542
- variant: FontVariantToken.fontSizeS,
543
- style: {
544
- maxWidth: 'fit-content',
545
- pointerEvents: addTaskLoading ? 'none' : void 0
546
- },
547
- children: defaultContent
548
- }) : /*#__PURE__*/ jsx(ApTypography, {
549
- variant: FontVariantToken.fontSizeS,
550
- color: "var(--uix-canvas-foreground-de-emp)",
551
- children: defaultContent
490
+ }),
491
+ /*#__PURE__*/ jsx(StageContent, {
492
+ children: displayTaskIds && 0 !== displayTaskIds.length ? /*#__PURE__*/ jsx(StageTaskList, {
493
+ className: "nodrag nopan"
494
+ }) : /*#__PURE__*/ jsx(Column, {
495
+ py: 2,
496
+ children: (onTaskAdd || onAddTaskFromToolbox) && !isReadOnly ? /*#__PURE__*/ jsx(ApLink, {
497
+ onClick: addTaskLoading ? void 0 : handleTaskAddClick,
498
+ variant: FontVariantToken.fontSizeS,
499
+ style: {
500
+ maxWidth: 'fit-content',
501
+ pointerEvents: addTaskLoading ? 'none' : void 0
502
+ },
503
+ children: defaultContent
504
+ }) : /*#__PURE__*/ jsx(ApTypography, {
505
+ variant: FontVariantToken.fontSizeS,
506
+ color: "var(--uix-canvas-foreground-de-emp)",
507
+ children: defaultContent
508
+ })
552
509
  })
553
510
  })
511
+ ]
512
+ }),
513
+ /*#__PURE__*/ jsx(FloatingCanvasPanel, {
514
+ open: null !== toolboxMode,
515
+ nodeId: id,
516
+ offset: 15,
517
+ children: /*#__PURE__*/ jsx(Toolbox, {
518
+ title: 'replace' === toolboxMode ? replaceTaskLabel : addTaskLabel,
519
+ initialItems: taskOptions,
520
+ onClose: handleToolboxClose,
521
+ onItemSelect: handleToolboxItemSelected,
522
+ onSearch: onTaskToolboxSearch
554
523
  })
555
- ]
556
- }),
557
- onAddTaskFromToolbox && /*#__PURE__*/ jsx(FloatingCanvasPanel, {
558
- open: isAddingTask,
559
- nodeId: id,
560
- offset: 15,
561
- children: /*#__PURE__*/ jsx(Toolbox, {
562
- title: addTaskLabel,
563
- initialItems: taskOptions,
564
- onClose: ()=>setIsAddingTask(false),
565
- onItemSelect: handleAddTaskToolboxItemSelected,
566
- onSearch: onTaskToolboxSearch
567
- })
568
- }),
569
- onReplaceTaskFromToolbox && /*#__PURE__*/ jsx(FloatingCanvasPanel, {
570
- open: isReplacingTask,
571
- nodeId: id,
572
- offset: 15,
573
- children: /*#__PURE__*/ jsx(Toolbox, {
574
- title: replaceTaskLabel,
575
- initialItems: taskOptions,
576
- onClose: ()=>setIsReplacingTask(false),
577
- onItemSelect: handleReplaceTaskToolboxItemSelected,
578
- onSearch: onTaskToolboxSearch
579
- })
580
- }),
581
- menuItems && !dragging && /*#__PURE__*/ jsx(NodeContextMenu, {
582
- menuItems: menuItems,
583
- isVisible: shouldShowMenu
584
- }),
585
- handleElements
586
- ]
524
+ }),
525
+ menuItems && !dragging && /*#__PURE__*/ jsx(NodeContextMenu, {
526
+ menuItems: menuItems,
527
+ isVisible: shouldShowMenu
528
+ }),
529
+ handleElements
530
+ ]
531
+ })
587
532
  });
588
533
  };
589
534
  const StageNode = /*#__PURE__*/ memo(StageNodeComponent);