@tduniec/plugin-template-designer 0.1.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 +120 -0
- package/dist/api/scaffolderActions.esm.js +42 -0
- package/dist/api/scaffolderActions.esm.js.map +1 -0
- package/dist/components/DesignerFlow/DesignerFlow.esm.js +370 -0
- package/dist/components/DesignerFlow/DesignerFlow.esm.js.map +1 -0
- package/dist/components/DesignerFlow/flowConfig.esm.js +21 -0
- package/dist/components/DesignerFlow/flowConfig.esm.js.map +1 -0
- package/dist/components/DesignerFlow/handlers.esm.js +288 -0
- package/dist/components/DesignerFlow/handlers.esm.js.map +1 -0
- package/dist/components/DesignerFlow/model.esm.js +181 -0
- package/dist/components/DesignerFlow/model.esm.js.map +1 -0
- package/dist/components/DesignerFlow/nodeLayout.esm.js +138 -0
- package/dist/components/DesignerFlow/nodeLayout.esm.js.map +1 -0
- package/dist/components/DesignerFlow/parameterTransforms.esm.js +184 -0
- package/dist/components/DesignerFlow/parameterTransforms.esm.js.map +1 -0
- package/dist/components/Nodes/ActionNode.esm.js +437 -0
- package/dist/components/Nodes/ActionNode.esm.js.map +1 -0
- package/dist/components/Nodes/OutputNode.esm.js +368 -0
- package/dist/components/Nodes/OutputNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParameterInputNode.esm.js +310 -0
- package/dist/components/Nodes/ParameterInputNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParameterTitlesNode.esm.js +251 -0
- package/dist/components/Nodes/ParameterTitlesNode.esm.js.map +1 -0
- package/dist/components/Nodes/ParametersNode.esm.js +142 -0
- package/dist/components/Nodes/ParametersNode.esm.js.map +1 -0
- package/dist/components/Nodes/action/schema.esm.js +117 -0
- package/dist/components/Nodes/action/schema.esm.js.map +1 -0
- package/dist/components/Nodes/action/useActionInputs.esm.js +66 -0
- package/dist/components/Nodes/action/useActionInputs.esm.js.map +1 -0
- package/dist/components/Nodes/common/AutoWidthPopper.esm.js +22 -0
- package/dist/components/Nodes/common/AutoWidthPopper.esm.js.map +1 -0
- package/dist/components/Nodes/common/nodeInteraction.esm.js +9 -0
- package/dist/components/Nodes/common/nodeInteraction.esm.js.map +1 -0
- package/dist/components/Nodes/output/useOutputController.esm.js +191 -0
- package/dist/components/Nodes/output/useOutputController.esm.js.map +1 -0
- package/dist/components/Nodes/parameters/useParameterSections.esm.js +162 -0
- package/dist/components/Nodes/parameters/useParameterSections.esm.js.map +1 -0
- package/dist/components/Nodes/types.esm.js +8 -0
- package/dist/components/Nodes/types.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/TemplateDesigner.esm.js +115 -0
- package/dist/components/TemplateDesigner/TemplateDesigner.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js +32 -0
- package/dist/components/TemplateDesigner/components/FieldEditorDialog.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js +102 -0
- package/dist/components/TemplateDesigner/components/TemplateLanding.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js +200 -0
- package/dist/components/TemplateDesigner/components/TemplateWorkspace.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/index.esm.js +2 -0
- package/dist/components/TemplateDesigner/index.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/useFieldEditor.esm.js +96 -0
- package/dist/components/TemplateDesigner/useFieldEditor.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/useTemplateState.esm.js +391 -0
- package/dist/components/TemplateDesigner/useTemplateState.esm.js.map +1 -0
- package/dist/components/TemplateDesigner/utils.esm.js +46 -0
- package/dist/components/TemplateDesigner/utils.esm.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +19 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/utils/createSequentialEdges.esm.js +15 -0
- package/dist/utils/createSequentialEdges.esm.js.map +1 -0
- package/dist/utils/sampleTemplate.esm.js +40 -0
- package/dist/utils/sampleTemplate.esm.js.map +1 -0
- package/dist/utils/yamlJsonConversion.esm.js +47 -0
- package/dist/utils/yamlJsonConversion.esm.js.map +1 -0
- package/package.json +116 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { createSequentialEdges } from '../../utils/createSequentialEdges.esm.js';
|
|
2
|
+
import { normalizeParametersToSections, sanitizeSections, sectionsToParametersValue } from './parameterTransforms.esm.js';
|
|
3
|
+
import { alignNodes } from './nodeLayout.esm.js';
|
|
4
|
+
|
|
5
|
+
const orderNodes = (parameterNodes, actionNodes, outputNodes) => [...parameterNodes, ...actionNodes, ...outputNodes];
|
|
6
|
+
const createHandleAddNode = (setNodes, setEdges, options) => {
|
|
7
|
+
const {
|
|
8
|
+
fixedXPosition,
|
|
9
|
+
verticalSpacing,
|
|
10
|
+
nodeDefaults,
|
|
11
|
+
scaffolderActionIds,
|
|
12
|
+
scaffolderActionInputsById,
|
|
13
|
+
scaffolderActionOutputsById
|
|
14
|
+
} = options;
|
|
15
|
+
return (config) => {
|
|
16
|
+
const {
|
|
17
|
+
afterRfId,
|
|
18
|
+
type = "actionNode",
|
|
19
|
+
stepTemplate,
|
|
20
|
+
outputTemplate,
|
|
21
|
+
parametersTemplate
|
|
22
|
+
} = config;
|
|
23
|
+
const nodeType = type;
|
|
24
|
+
setNodes((nodes) => {
|
|
25
|
+
const parameterNodes = nodes.filter((n) => n.type === "parametersNode");
|
|
26
|
+
const actionNodes = nodes.filter((n) => n.type === "actionNode");
|
|
27
|
+
const outputNodes = nodes.filter((n) => n.type === "outputNode");
|
|
28
|
+
const composeAndAlign = (nextParameters, nextActions, nextOutputs) => {
|
|
29
|
+
const ordered = orderNodes(nextParameters, nextActions, nextOutputs);
|
|
30
|
+
const aligned = alignNodes(ordered, fixedXPosition, verticalSpacing);
|
|
31
|
+
setEdges(createSequentialEdges(aligned));
|
|
32
|
+
return aligned;
|
|
33
|
+
};
|
|
34
|
+
if (nodeType === "parametersNode") {
|
|
35
|
+
if (parameterNodes.length > 0) {
|
|
36
|
+
return composeAndAlign(parameterNodes, actionNodes, outputNodes);
|
|
37
|
+
}
|
|
38
|
+
const rfParametersId = "rf-parameters";
|
|
39
|
+
const initialParameters = parametersTemplate !== void 0 ? JSON.parse(
|
|
40
|
+
JSON.stringify(parametersTemplate)
|
|
41
|
+
) : void 0;
|
|
42
|
+
const parameterNode = {
|
|
43
|
+
id: rfParametersId,
|
|
44
|
+
type: "parametersNode",
|
|
45
|
+
position: { x: fixedXPosition, y: 0 },
|
|
46
|
+
data: {
|
|
47
|
+
rfId: rfParametersId,
|
|
48
|
+
parameters: initialParameters,
|
|
49
|
+
sections: [],
|
|
50
|
+
scaffolderActionIds,
|
|
51
|
+
scaffolderActionInputsById,
|
|
52
|
+
scaffolderActionOutputsById
|
|
53
|
+
},
|
|
54
|
+
...nodeDefaults
|
|
55
|
+
};
|
|
56
|
+
return composeAndAlign([parameterNode], actionNodes, outputNodes);
|
|
57
|
+
}
|
|
58
|
+
if (nodeType === "outputNode") {
|
|
59
|
+
if (outputNodes.length > 0) {
|
|
60
|
+
return composeAndAlign(parameterNodes, actionNodes, outputNodes);
|
|
61
|
+
}
|
|
62
|
+
const rfOutputId = "rf-output";
|
|
63
|
+
const initialOutput = outputTemplate !== void 0 && outputTemplate !== null ? JSON.parse(JSON.stringify(outputTemplate)) : {};
|
|
64
|
+
const outputNode = {
|
|
65
|
+
id: rfOutputId,
|
|
66
|
+
type: "outputNode",
|
|
67
|
+
position: { x: fixedXPosition, y: 0 },
|
|
68
|
+
data: {
|
|
69
|
+
rfId: rfOutputId,
|
|
70
|
+
output: initialOutput,
|
|
71
|
+
scaffolderActionIds,
|
|
72
|
+
scaffolderActionInputsById,
|
|
73
|
+
scaffolderActionOutputsById
|
|
74
|
+
},
|
|
75
|
+
...nodeDefaults
|
|
76
|
+
};
|
|
77
|
+
return composeAndAlign(parameterNodes, actionNodes, [
|
|
78
|
+
...outputNodes,
|
|
79
|
+
outputNode
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
82
|
+
const parametersPlaceholder = nodes.find(
|
|
83
|
+
(n) => n.type === "parametersNode"
|
|
84
|
+
);
|
|
85
|
+
const parametersNodeId = parametersPlaceholder?.id ?? null;
|
|
86
|
+
const parentIndex = actionNodes.findIndex((n) => n.id === afterRfId);
|
|
87
|
+
let insertIndex;
|
|
88
|
+
if (parentIndex >= 0) {
|
|
89
|
+
insertIndex = parentIndex + 1;
|
|
90
|
+
} else if (afterRfId === parametersNodeId) {
|
|
91
|
+
insertIndex = 0;
|
|
92
|
+
} else {
|
|
93
|
+
insertIndex = actionNodes.length;
|
|
94
|
+
}
|
|
95
|
+
const rfId = `rf-${Date.now()}`;
|
|
96
|
+
const stepDefaults = {
|
|
97
|
+
id: `step-${rfId}`,
|
|
98
|
+
name: "New Step",
|
|
99
|
+
action: "",
|
|
100
|
+
input: {}
|
|
101
|
+
};
|
|
102
|
+
const newStep = {
|
|
103
|
+
...stepDefaults,
|
|
104
|
+
...stepTemplate ?? {}
|
|
105
|
+
};
|
|
106
|
+
const newNode = {
|
|
107
|
+
id: rfId,
|
|
108
|
+
type: "actionNode",
|
|
109
|
+
position: { x: fixedXPosition, y: 0 },
|
|
110
|
+
data: {
|
|
111
|
+
rfId,
|
|
112
|
+
step: newStep,
|
|
113
|
+
scaffolderActionIds,
|
|
114
|
+
scaffolderActionInputsById,
|
|
115
|
+
scaffolderActionOutputsById
|
|
116
|
+
},
|
|
117
|
+
...nodeDefaults
|
|
118
|
+
};
|
|
119
|
+
const nextActionNodes = [
|
|
120
|
+
...actionNodes.slice(0, insertIndex),
|
|
121
|
+
newNode,
|
|
122
|
+
...actionNodes.slice(insertIndex)
|
|
123
|
+
];
|
|
124
|
+
return composeAndAlign(parameterNodes, nextActionNodes, outputNodes);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
const createHandleRemoveInputKey = (setNodes) => {
|
|
129
|
+
return (rfId, key) => {
|
|
130
|
+
setNodes(
|
|
131
|
+
(nds) => nds.map((n) => {
|
|
132
|
+
if (n.id !== rfId) {
|
|
133
|
+
return n;
|
|
134
|
+
}
|
|
135
|
+
const data = n.data;
|
|
136
|
+
if (!data.step) {
|
|
137
|
+
return n;
|
|
138
|
+
}
|
|
139
|
+
const nextInput = { ...data.step.input ?? {} };
|
|
140
|
+
delete nextInput[key];
|
|
141
|
+
const step = { ...data.step, input: nextInput };
|
|
142
|
+
return { ...n, data: { ...data, step } };
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
const createHandleReorderAndAlignNodes = (setNodes, setEdges, options) => {
|
|
148
|
+
const { fixedXPosition, verticalSpacing } = options;
|
|
149
|
+
return (updatedNode) => {
|
|
150
|
+
setNodes((prevNodes) => {
|
|
151
|
+
const updatedNodes = prevNodes.map(
|
|
152
|
+
(node) => node.id === updatedNode.id ? updatedNode : node
|
|
153
|
+
);
|
|
154
|
+
const parameterNodes = updatedNodes.filter((node) => node.type === "parametersNode").sort((a, b) => a.position.y - b.position.y);
|
|
155
|
+
const actionNodes = updatedNodes.filter((node) => node.type === "actionNode").sort((a, b) => a.position.y - b.position.y);
|
|
156
|
+
const outputNodes = updatedNodes.filter((node) => node.type === "outputNode").sort((a, b) => a.position.y - b.position.y);
|
|
157
|
+
const ordered = orderNodes(parameterNodes, actionNodes, outputNodes);
|
|
158
|
+
const aligned = alignNodes(ordered, fixedXPosition, verticalSpacing);
|
|
159
|
+
setEdges(createSequentialEdges(aligned));
|
|
160
|
+
return aligned;
|
|
161
|
+
});
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
const createHandleUpdateField = (setNodes) => {
|
|
165
|
+
return (rfId, field, value) => {
|
|
166
|
+
setNodes(
|
|
167
|
+
(nds) => nds.map((n) => {
|
|
168
|
+
if (n.id !== rfId) {
|
|
169
|
+
return n;
|
|
170
|
+
}
|
|
171
|
+
const data = n.data;
|
|
172
|
+
if (!data.step) {
|
|
173
|
+
return n;
|
|
174
|
+
}
|
|
175
|
+
const step = { ...data.step, [field]: value };
|
|
176
|
+
return { ...n, data: { ...data, step } };
|
|
177
|
+
})
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
const createHandleUpdateInput = (setNodes) => {
|
|
182
|
+
return (rfId, key, value) => {
|
|
183
|
+
setNodes(
|
|
184
|
+
(nds) => nds.map((n) => {
|
|
185
|
+
if (n.id !== rfId) {
|
|
186
|
+
return n;
|
|
187
|
+
}
|
|
188
|
+
const data = n.data;
|
|
189
|
+
if (!data.step) {
|
|
190
|
+
return n;
|
|
191
|
+
}
|
|
192
|
+
const nextInput = { ...data.step.input ?? {}, [key]: value };
|
|
193
|
+
const step = { ...data.step, input: nextInput };
|
|
194
|
+
return { ...n, data: { ...data, step } };
|
|
195
|
+
})
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
const collectStepOutputReferences = (nodes, parameterReferences) => {
|
|
200
|
+
const referencesByNode = {};
|
|
201
|
+
const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);
|
|
202
|
+
const accumulatedReferences = [...parameterReferences];
|
|
203
|
+
const accumulatedSet = new Set(parameterReferences);
|
|
204
|
+
sortedNodes.forEach((node) => {
|
|
205
|
+
referencesByNode[node.id] = [...accumulatedReferences];
|
|
206
|
+
const data = node.data;
|
|
207
|
+
if (!data || !data.step) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const { step, scaffolderActionOutputsById } = data;
|
|
211
|
+
const stepId = step && typeof step.id === "string" && step.id.trim().length > 0 ? step.id : null;
|
|
212
|
+
const actionId = step && typeof step.action === "string" && step.action.trim().length > 0 ? step.action : null;
|
|
213
|
+
if (!stepId || !actionId) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const outputKeys = /* @__PURE__ */ new Set();
|
|
217
|
+
const schemaOutputs = scaffolderActionOutputsById?.[actionId];
|
|
218
|
+
if (schemaOutputs && typeof schemaOutputs === "object") {
|
|
219
|
+
Object.keys(schemaOutputs).forEach((key) => {
|
|
220
|
+
if (key) {
|
|
221
|
+
outputKeys.add(key);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const stepOutput = step.output;
|
|
226
|
+
if (stepOutput && typeof stepOutput === "object") {
|
|
227
|
+
Object.keys(stepOutput).forEach((key) => {
|
|
228
|
+
if (key) {
|
|
229
|
+
outputKeys.add(key);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
outputKeys.forEach((outputKey) => {
|
|
234
|
+
const reference = `\${{ steps['${stepId}'].output.${outputKey} }}`;
|
|
235
|
+
if (!accumulatedSet.has(reference)) {
|
|
236
|
+
accumulatedSet.add(reference);
|
|
237
|
+
accumulatedReferences.push(reference);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
return referencesByNode;
|
|
242
|
+
};
|
|
243
|
+
const createHandleUpdateOutput = (setNodes) => {
|
|
244
|
+
return (rfId, updater) => {
|
|
245
|
+
setNodes(
|
|
246
|
+
(nodes) => nodes.map((node) => {
|
|
247
|
+
if (node.id !== rfId || node.type !== "outputNode") {
|
|
248
|
+
return node;
|
|
249
|
+
}
|
|
250
|
+
const data = node.data;
|
|
251
|
+
const nextOutput = updater(data.output ?? {});
|
|
252
|
+
return {
|
|
253
|
+
...node,
|
|
254
|
+
data: {
|
|
255
|
+
...data,
|
|
256
|
+
output: nextOutput
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
const createHandleUpdateSections = (setNodes) => {
|
|
264
|
+
return (rfId, updater) => {
|
|
265
|
+
setNodes(
|
|
266
|
+
(nodes) => nodes.map((node) => {
|
|
267
|
+
if (node.id !== rfId || node.type !== "parametersNode") {
|
|
268
|
+
return node;
|
|
269
|
+
}
|
|
270
|
+
const data = node.data;
|
|
271
|
+
const previousSections = data.sections ?? normalizeParametersToSections(data.parameters);
|
|
272
|
+
const nextSections = sanitizeSections(updater(previousSections));
|
|
273
|
+
const nextParameters = sectionsToParametersValue(nextSections);
|
|
274
|
+
return {
|
|
275
|
+
...node,
|
|
276
|
+
data: {
|
|
277
|
+
...data,
|
|
278
|
+
sections: nextSections,
|
|
279
|
+
parameters: nextParameters
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
};
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export { collectStepOutputReferences, createHandleAddNode, createHandleRemoveInputKey, createHandleReorderAndAlignNodes, createHandleUpdateField, createHandleUpdateInput, createHandleUpdateOutput, createHandleUpdateSections };
|
|
288
|
+
//# sourceMappingURL=handlers.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.esm.js","sources":["../../../src/components/DesignerFlow/handlers.ts"],"sourcesContent":["import type { Dispatch, SetStateAction } from \"react\";\nimport type { Edge, Node } from \"@xyflow/react\";\nimport type { TaskStep } from \"@backstage/plugin-scaffolder-common\";\n\n// Stateful handlers that mutate nodes/edges in response to user interactions.\nimport type {\n ActionNodeData,\n AddNodeConfig,\n DesignerNodeType,\n OutputNodeData,\n ParametersNodeData,\n ParameterSectionDisplay,\n TemplateParametersValue,\n} from \"../Nodes/types\";\nimport { createSequentialEdges } from \"../../utils/createSequentialEdges\";\nimport {\n normalizeParametersToSections,\n sanitizeSections,\n sectionsToParametersValue,\n} from \"./parameterTransforms\";\nimport { alignNodes } from \"./nodeLayout\";\n\ntype SetNodes = Dispatch<SetStateAction<Node[]>>;\ntype SetEdges = Dispatch<SetStateAction<Edge[]>>;\n\ninterface CreateHandleAddNodeOptions {\n fixedXPosition: number;\n verticalSpacing: number;\n nodeDefaults: Partial<Node>;\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n}\n\nconst orderNodes = (\n parameterNodes: Node[],\n actionNodes: Node[],\n outputNodes: Node[]\n) => [...parameterNodes, ...actionNodes, ...outputNodes];\n\nexport const createHandleAddNode = (\n setNodes: SetNodes,\n setEdges: SetEdges,\n options: CreateHandleAddNodeOptions\n) => {\n const {\n fixedXPosition,\n verticalSpacing,\n nodeDefaults,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n } = options;\n\n return (config: AddNodeConfig) => {\n const {\n afterRfId,\n type = \"actionNode\",\n stepTemplate,\n outputTemplate,\n parametersTemplate,\n } = config;\n const nodeType: DesignerNodeType = type;\n\n setNodes((nodes) => {\n const parameterNodes = nodes.filter((n) => n.type === \"parametersNode\");\n const actionNodes = nodes.filter((n) => n.type === \"actionNode\");\n const outputNodes = nodes.filter((n) => n.type === \"outputNode\");\n\n const composeAndAlign = (\n nextParameters: Node[],\n nextActions: Node[],\n nextOutputs: Node[]\n ) => {\n const ordered = orderNodes(nextParameters, nextActions, nextOutputs);\n const aligned = alignNodes(ordered, fixedXPosition, verticalSpacing);\n setEdges(createSequentialEdges(aligned));\n return aligned;\n };\n\n if (nodeType === \"parametersNode\") {\n if (parameterNodes.length > 0) {\n return composeAndAlign(parameterNodes, actionNodes, outputNodes);\n }\n\n const rfParametersId = \"rf-parameters\";\n const initialParameters =\n parametersTemplate !== undefined\n ? (JSON.parse(\n JSON.stringify(parametersTemplate)\n ) as TemplateParametersValue)\n : undefined;\n\n const parameterNode: Node = {\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: initialParameters,\n sections: [],\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n } satisfies ParametersNodeData,\n ...nodeDefaults,\n };\n\n return composeAndAlign([parameterNode], actionNodes, outputNodes);\n }\n\n if (nodeType === \"outputNode\") {\n if (outputNodes.length > 0) {\n return composeAndAlign(parameterNodes, actionNodes, outputNodes);\n }\n\n const rfOutputId = \"rf-output\";\n const initialOutput =\n outputTemplate !== undefined && outputTemplate !== null\n ? (JSON.parse(JSON.stringify(outputTemplate)) as Record<\n string,\n unknown\n >)\n : {};\n\n const outputNode: Node = {\n id: rfOutputId,\n type: \"outputNode\",\n position: { x: fixedXPosition, y: 0 },\n data: {\n rfId: rfOutputId,\n output: initialOutput,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n };\n\n return composeAndAlign(parameterNodes, actionNodes, [\n ...outputNodes,\n outputNode,\n ]);\n }\n\n const parametersPlaceholder = nodes.find(\n (n) => n.type === \"parametersNode\"\n );\n const parametersNodeId = parametersPlaceholder?.id ?? null;\n const parentIndex = actionNodes.findIndex((n) => n.id === afterRfId);\n let insertIndex: number;\n if (parentIndex >= 0) {\n insertIndex = parentIndex + 1;\n } else if (afterRfId === parametersNodeId) {\n insertIndex = 0;\n } else {\n insertIndex = actionNodes.length;\n }\n\n const rfId = `rf-${Date.now()}`;\n const stepDefaults: TaskStep = {\n id: `step-${rfId}`,\n name: \"New Step\",\n action: \"\",\n input: {},\n };\n\n const newStep: TaskStep = {\n ...stepDefaults,\n ...(stepTemplate ?? {}),\n };\n\n const newNode: Node = {\n id: rfId,\n type: \"actionNode\",\n position: { x: fixedXPosition, y: 0 },\n data: {\n rfId,\n step: newStep,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n };\n\n const nextActionNodes = [\n ...actionNodes.slice(0, insertIndex),\n newNode,\n ...actionNodes.slice(insertIndex),\n ];\n\n return composeAndAlign(parameterNodes, nextActionNodes, outputNodes);\n });\n };\n};\n\nexport const createHandleRemoveInputKey = (setNodes: SetNodes) => {\n return (rfId: string, key: string) => {\n setNodes((nds) =>\n nds.map((n) => {\n if (n.id !== rfId) {\n return n;\n }\n\n const data = n.data as Partial<ActionNodeData>;\n if (!data.step) {\n return n;\n }\n const nextInput = { ...(data.step.input ?? {}) };\n delete nextInput[key];\n const step = { ...data.step, input: nextInput };\n\n return { ...n, data: { ...data, step } };\n })\n );\n };\n};\n\nexport const createHandleReorderAndAlignNodes = (\n setNodes: SetNodes,\n setEdges: SetEdges,\n options: { fixedXPosition: number; verticalSpacing: number }\n) => {\n const { fixedXPosition, verticalSpacing } = options;\n\n return (updatedNode: Node) => {\n setNodes((prevNodes) => {\n const updatedNodes = prevNodes.map((node) =>\n node.id === updatedNode.id ? updatedNode : node\n );\n\n const parameterNodes = updatedNodes\n .filter((node) => node.type === \"parametersNode\")\n .sort((a, b) => a.position.y - b.position.y);\n const actionNodes = updatedNodes\n .filter((node) => node.type === \"actionNode\")\n .sort((a, b) => a.position.y - b.position.y);\n const outputNodes = updatedNodes\n .filter((node) => node.type === \"outputNode\")\n .sort((a, b) => a.position.y - b.position.y);\n\n const ordered = orderNodes(parameterNodes, actionNodes, outputNodes);\n const aligned = alignNodes(ordered, fixedXPosition, verticalSpacing);\n\n setEdges(createSequentialEdges(aligned));\n return aligned;\n });\n };\n};\n\nexport const createHandleUpdateField = (setNodes: SetNodes) => {\n return (rfId: string, field: keyof TaskStep, value: string) => {\n setNodes((nds) =>\n nds.map((n) => {\n if (n.id !== rfId) {\n return n;\n }\n\n const data = n.data as Partial<ActionNodeData>;\n if (!data.step) {\n return n;\n }\n const step = { ...data.step, [field]: value };\n\n return { ...n, data: { ...data, step } };\n })\n );\n };\n};\n\nexport const createHandleUpdateInput = (setNodes: SetNodes) => {\n return (rfId: string, key: string, value: unknown) => {\n setNodes((nds) =>\n nds.map((n) => {\n if (n.id !== rfId) {\n return n;\n }\n\n const data = n.data as Partial<ActionNodeData>;\n if (!data.step) {\n return n;\n }\n const nextInput = { ...(data.step.input ?? {}), [key]: value };\n const step = { ...data.step, input: nextInput };\n\n return { ...n, data: { ...data, step } };\n })\n );\n };\n};\n\nexport const collectStepOutputReferences = (\n nodes: Node[],\n parameterReferences: string[]\n): Record<string, string[]> => {\n const referencesByNode: Record<string, string[]> = {};\n const sortedNodes = [...nodes].sort((a, b) => a.position.y - b.position.y);\n const accumulatedReferences: string[] = [...parameterReferences];\n const accumulatedSet = new Set<string>(parameterReferences);\n\n sortedNodes.forEach((node) => {\n referencesByNode[node.id] = [...accumulatedReferences];\n\n const data = node.data as Partial<ActionNodeData> | undefined;\n if (!data || !data.step) {\n return;\n }\n\n const { step, scaffolderActionOutputsById } = data;\n const stepId =\n step && typeof step.id === \"string\" && step.id.trim().length > 0\n ? step.id\n : null;\n const actionId =\n step && typeof step.action === \"string\" && step.action.trim().length > 0\n ? step.action\n : null;\n\n if (!stepId || !actionId) {\n return;\n }\n\n const outputKeys = new Set<string>();\n const schemaOutputs = scaffolderActionOutputsById?.[actionId];\n if (schemaOutputs && typeof schemaOutputs === \"object\") {\n Object.keys(schemaOutputs).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n const stepOutput = (step as { output?: Record<string, unknown> }).output;\n if (stepOutput && typeof stepOutput === \"object\") {\n Object.keys(stepOutput).forEach((key) => {\n if (key) {\n outputKeys.add(key);\n }\n });\n }\n\n outputKeys.forEach((outputKey) => {\n const reference = `\\${{ steps['${stepId}'].output.${outputKey} }}`;\n if (!accumulatedSet.has(reference)) {\n accumulatedSet.add(reference);\n accumulatedReferences.push(reference);\n }\n });\n });\n\n return referencesByNode;\n};\n\nexport const createHandleUpdateOutput = (setNodes: SetNodes) => {\n return (\n rfId: string,\n updater: (prev: OutputNodeData[\"output\"]) => OutputNodeData[\"output\"]\n ) => {\n setNodes((nodes) =>\n nodes.map((node) => {\n if (node.id !== rfId || node.type !== \"outputNode\") {\n return node;\n }\n const data = node.data as OutputNodeData;\n const nextOutput = updater(data.output ?? {});\n return {\n ...node,\n data: {\n ...data,\n output: nextOutput,\n },\n };\n })\n );\n };\n};\n\nexport const createHandleUpdateSections = (setNodes: SetNodes) => {\n return (\n rfId: string,\n updater: (prev: ParameterSectionDisplay[]) => ParameterSectionDisplay[]\n ) => {\n setNodes((nodes) =>\n nodes.map((node) => {\n if (node.id !== rfId || node.type !== \"parametersNode\") {\n return node;\n }\n const data = node.data as ParametersNodeData;\n const previousSections =\n data.sections ?? normalizeParametersToSections(data.parameters);\n const nextSections = sanitizeSections(updater(previousSections));\n const nextParameters = sectionsToParametersValue(nextSections);\n return {\n ...node,\n data: {\n ...data,\n sections: nextSections,\n parameters: nextParameters,\n },\n };\n })\n );\n };\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { alignNodes } from './nodeLayout.esm.js';
|
|
2
|
+
import { normalizeParametersToSections } from './parameterTransforms.esm.js';
|
|
3
|
+
import { nodeDefaults, FLOW_LAYOUT } from './flowConfig.esm.js';
|
|
4
|
+
|
|
5
|
+
const sanitizeForRfId = (value) => value.replace(/[^a-zA-Z0-9-_.:]/g, "_");
|
|
6
|
+
const buildRfId = (step, index) => {
|
|
7
|
+
if (step && typeof step.id === "string" && step.id.trim().length > 0) {
|
|
8
|
+
return `rf-${sanitizeForRfId(step.id)}-${index}`;
|
|
9
|
+
}
|
|
10
|
+
return `rf-${index + 1}`;
|
|
11
|
+
};
|
|
12
|
+
const cloneStep = (step) => JSON.parse(JSON.stringify(step ?? {}));
|
|
13
|
+
const cloneOutput = (output) => JSON.parse(JSON.stringify(output ?? {}));
|
|
14
|
+
const cloneParameters = (parameters) => parameters === void 0 ? void 0 : JSON.parse(JSON.stringify(parameters));
|
|
15
|
+
const buildNodesFromModel = (steps, parameters, output, options) => {
|
|
16
|
+
const {
|
|
17
|
+
scaffolderActionIds,
|
|
18
|
+
scaffolderActionInputsById,
|
|
19
|
+
scaffolderActionOutputsById
|
|
20
|
+
} = options;
|
|
21
|
+
const parameterSections = normalizeParametersToSections(parameters);
|
|
22
|
+
const nodes = [];
|
|
23
|
+
const rfParametersId = "rf-parameters";
|
|
24
|
+
nodes.push({
|
|
25
|
+
id: rfParametersId,
|
|
26
|
+
type: "parametersNode",
|
|
27
|
+
position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },
|
|
28
|
+
data: {
|
|
29
|
+
rfId: rfParametersId,
|
|
30
|
+
parameters: cloneParameters(parameters),
|
|
31
|
+
sections: parameterSections,
|
|
32
|
+
scaffolderActionIds,
|
|
33
|
+
scaffolderActionInputsById,
|
|
34
|
+
scaffolderActionOutputsById
|
|
35
|
+
},
|
|
36
|
+
...nodeDefaults
|
|
37
|
+
});
|
|
38
|
+
const actionNodes = steps.map((step, index) => {
|
|
39
|
+
const rfId = buildRfId(step, index);
|
|
40
|
+
return {
|
|
41
|
+
id: rfId,
|
|
42
|
+
type: "actionNode",
|
|
43
|
+
position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },
|
|
44
|
+
data: {
|
|
45
|
+
rfId,
|
|
46
|
+
step: cloneStep(step),
|
|
47
|
+
scaffolderActionIds,
|
|
48
|
+
scaffolderActionInputsById,
|
|
49
|
+
scaffolderActionOutputsById
|
|
50
|
+
},
|
|
51
|
+
...nodeDefaults
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
nodes.push(...actionNodes);
|
|
55
|
+
if (output !== void 0 && output !== null) {
|
|
56
|
+
const rfOutputId = "rf-output";
|
|
57
|
+
nodes.push({
|
|
58
|
+
id: rfOutputId,
|
|
59
|
+
type: "outputNode",
|
|
60
|
+
position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },
|
|
61
|
+
data: {
|
|
62
|
+
rfId: rfOutputId,
|
|
63
|
+
output: cloneOutput(output),
|
|
64
|
+
scaffolderActionIds,
|
|
65
|
+
scaffolderActionInputsById,
|
|
66
|
+
scaffolderActionOutputsById
|
|
67
|
+
},
|
|
68
|
+
...nodeDefaults
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return alignNodes(
|
|
72
|
+
nodes,
|
|
73
|
+
FLOW_LAYOUT.fixedXPosition,
|
|
74
|
+
FLOW_LAYOUT.verticalSpacing
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
const collectParameterReferences = (parameters) => {
|
|
78
|
+
const refs = /* @__PURE__ */ new Set();
|
|
79
|
+
const extractProperties = (schema) => {
|
|
80
|
+
if (!schema || typeof schema !== "object") {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const record = schema;
|
|
84
|
+
if (record.properties && typeof record.properties === "object") {
|
|
85
|
+
Object.keys(record.properties).forEach(
|
|
86
|
+
(key) => {
|
|
87
|
+
if (key) {
|
|
88
|
+
refs.add(`\${{ parameters.${key} }}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
if (Array.isArray(record.steps)) {
|
|
94
|
+
record.steps.forEach((stepSchema) => {
|
|
95
|
+
if (!stepSchema || typeof stepSchema !== "object") {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
extractProperties(stepSchema.schema);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
if (Array.isArray(parameters)) {
|
|
103
|
+
parameters.forEach((item) => extractProperties(item));
|
|
104
|
+
} else {
|
|
105
|
+
extractProperties(parameters);
|
|
106
|
+
}
|
|
107
|
+
return Array.from(refs).sort();
|
|
108
|
+
};
|
|
109
|
+
const normalizeValueForStableStringify = (value) => {
|
|
110
|
+
if (Array.isArray(value)) {
|
|
111
|
+
return value.map(normalizeValueForStableStringify);
|
|
112
|
+
}
|
|
113
|
+
if (value && typeof value === "object") {
|
|
114
|
+
const entries = Object.entries(value).filter(([key]) => key !== void 0).sort(([a], [b]) => {
|
|
115
|
+
if (a > b) {
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
if (a < b) {
|
|
119
|
+
return -1;
|
|
120
|
+
}
|
|
121
|
+
return 0;
|
|
122
|
+
});
|
|
123
|
+
return entries.reduce((acc, [key, val]) => {
|
|
124
|
+
acc[key] = normalizeValueForStableStringify(val);
|
|
125
|
+
return acc;
|
|
126
|
+
}, {});
|
|
127
|
+
}
|
|
128
|
+
return value;
|
|
129
|
+
};
|
|
130
|
+
const stableStringify = (value) => JSON.stringify(normalizeValueForStableStringify(value));
|
|
131
|
+
const resolveNodeHeightForTracking = (node) => {
|
|
132
|
+
const measuredHeight = node.measured?.height;
|
|
133
|
+
if (typeof measuredHeight === "number" && measuredHeight > 0) {
|
|
134
|
+
return measuredHeight;
|
|
135
|
+
}
|
|
136
|
+
const explicitHeight = node.height;
|
|
137
|
+
if (typeof explicitHeight === "number" && explicitHeight > 0) {
|
|
138
|
+
return explicitHeight;
|
|
139
|
+
}
|
|
140
|
+
return void 0;
|
|
141
|
+
};
|
|
142
|
+
const sortNodesByY = (nodes) => [...nodes].sort((a, b) => a.position.y - b.position.y);
|
|
143
|
+
const extractStepsFromNodes = (nodes) => {
|
|
144
|
+
const sorted = sortNodesByY(nodes);
|
|
145
|
+
return sorted.map((node) => {
|
|
146
|
+
const data = node.data;
|
|
147
|
+
if (!data || !data.step) {
|
|
148
|
+
return void 0;
|
|
149
|
+
}
|
|
150
|
+
return cloneStep(data.step);
|
|
151
|
+
}).filter((step) => !!step);
|
|
152
|
+
};
|
|
153
|
+
const extractParametersFromNodes = (nodes) => {
|
|
154
|
+
const parametersNode = sortNodesByY(nodes).find(
|
|
155
|
+
(node) => node.type === "parametersNode"
|
|
156
|
+
);
|
|
157
|
+
if (!parametersNode) {
|
|
158
|
+
return void 0;
|
|
159
|
+
}
|
|
160
|
+
const data = parametersNode.data;
|
|
161
|
+
if (!data) {
|
|
162
|
+
return void 0;
|
|
163
|
+
}
|
|
164
|
+
return cloneParameters(data.parameters);
|
|
165
|
+
};
|
|
166
|
+
const extractOutputFromNodes = (nodes) => {
|
|
167
|
+
const outputNode = sortNodesByY(nodes).find(
|
|
168
|
+
(node) => node.type === "outputNode"
|
|
169
|
+
);
|
|
170
|
+
if (!outputNode) {
|
|
171
|
+
return void 0;
|
|
172
|
+
}
|
|
173
|
+
const data = outputNode.data;
|
|
174
|
+
if (!data) {
|
|
175
|
+
return void 0;
|
|
176
|
+
}
|
|
177
|
+
return cloneOutput(data.output);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export { buildNodesFromModel, cloneOutput, cloneParameters, cloneStep, collectParameterReferences, extractOutputFromNodes, extractParametersFromNodes, extractStepsFromNodes, resolveNodeHeightForTracking, stableStringify };
|
|
181
|
+
//# sourceMappingURL=model.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.esm.js","sources":["../../../src/components/DesignerFlow/model.ts"],"sourcesContent":["import type { Node } from \"@xyflow/react\";\n\n// Pure helpers for serializing/deserializing flow nodes and template models.\nimport type {\n TaskStep,\n ScaffolderTaskOutput,\n} from \"@backstage/plugin-scaffolder-common\";\nimport type {\n ActionNodeData,\n OutputNodeData,\n ParametersNodeData,\n TemplateParametersValue,\n} from \"../Nodes/types\";\nimport { alignNodes } from \"./nodeLayout\";\nimport { normalizeParametersToSections } from \"./parameterTransforms\";\nimport { FLOW_LAYOUT, nodeDefaults } from \"./flowConfig\";\n\nconst sanitizeForRfId = (value: string) =>\n value.replace(/[^a-zA-Z0-9-_.:]/g, \"_\");\n\nconst buildRfId = (step: TaskStep | undefined, index: number) => {\n if (step && typeof step.id === \"string\" && step.id.trim().length > 0) {\n return `rf-${sanitizeForRfId(step.id)}-${index}`;\n }\n return `rf-${index + 1}`;\n};\n\nexport const cloneStep = (step: TaskStep): TaskStep =>\n JSON.parse(JSON.stringify(step ?? {})) as TaskStep;\n\nexport const cloneOutput = (\n output: ScaffolderTaskOutput | undefined | null\n): ScaffolderTaskOutput =>\n JSON.parse(JSON.stringify(output ?? {})) as ScaffolderTaskOutput;\n\nexport const cloneParameters = (\n parameters: TemplateParametersValue\n): TemplateParametersValue =>\n parameters === undefined\n ? undefined\n : (JSON.parse(JSON.stringify(parameters)) as TemplateParametersValue);\n\nexport type BuildNodesFromModelOptions = {\n scaffolderActionIds: string[];\n scaffolderActionInputsById: Record<string, Record<string, unknown>>;\n scaffolderActionOutputsById: Record<string, Record<string, unknown>>;\n};\n\nexport const buildNodesFromModel = (\n steps: TaskStep[],\n parameters: TemplateParametersValue,\n output: ScaffolderTaskOutput | undefined | null,\n options: BuildNodesFromModelOptions\n) => {\n const {\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n } = options;\n\n const parameterSections = normalizeParametersToSections(parameters);\n const nodes: Node[] = [];\n\n const rfParametersId = \"rf-parameters\";\n nodes.push({\n id: rfParametersId,\n type: \"parametersNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfParametersId,\n parameters: cloneParameters(parameters),\n sections: parameterSections,\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n\n const actionNodes = steps.map((step, index) => {\n const rfId = buildRfId(step, index);\n return {\n id: rfId,\n type: \"actionNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId,\n step: cloneStep(step),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n } as Node;\n });\n\n nodes.push(...actionNodes);\n\n if (output !== undefined && output !== null) {\n const rfOutputId = \"rf-output\";\n nodes.push({\n id: rfOutputId,\n type: \"outputNode\",\n position: { x: FLOW_LAYOUT.fixedXPosition, y: 0 },\n data: {\n rfId: rfOutputId,\n output: cloneOutput(output),\n scaffolderActionIds,\n scaffolderActionInputsById,\n scaffolderActionOutputsById,\n },\n ...nodeDefaults,\n });\n }\n\n return alignNodes(\n nodes,\n FLOW_LAYOUT.fixedXPosition,\n FLOW_LAYOUT.verticalSpacing\n );\n};\n\nexport const collectParameterReferences = (\n parameters: TemplateParametersValue\n): string[] => {\n const refs = new Set<string>();\n\n const extractProperties = (schema: unknown) => {\n if (!schema || typeof schema !== \"object\") {\n return;\n }\n\n const record = schema as Record<string, unknown>;\n if (record.properties && typeof record.properties === \"object\") {\n Object.keys(record.properties as Record<string, unknown>).forEach(\n (key) => {\n if (key) {\n refs.add(`\\${{ parameters.${key} }}`);\n }\n }\n );\n }\n\n if (Array.isArray(record.steps)) {\n record.steps.forEach((stepSchema) => {\n if (!stepSchema || typeof stepSchema !== \"object\") {\n return;\n }\n extractProperties((stepSchema as Record<string, unknown>).schema);\n });\n }\n };\n\n if (Array.isArray(parameters)) {\n parameters.forEach((item) => extractProperties(item));\n } else {\n extractProperties(parameters);\n }\n\n return Array.from(refs).sort();\n};\n\nconst normalizeValueForStableStringify = (value: unknown): unknown => {\n if (Array.isArray(value)) {\n return value.map(normalizeValueForStableStringify);\n }\n if (value && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([key]) => key !== undefined)\n .sort(([a], [b]) => {\n if (a > b) {\n return 1;\n }\n if (a < b) {\n return -1;\n }\n return 0;\n });\n return entries.reduce<Record<string, unknown>>((acc, [key, val]) => {\n acc[key] = normalizeValueForStableStringify(val);\n return acc;\n }, {});\n }\n return value;\n};\n\nexport const stableStringify = (value: unknown): string =>\n JSON.stringify(normalizeValueForStableStringify(value));\n\nexport const resolveNodeHeightForTracking = (\n node: Node\n): number | undefined => {\n const measuredHeight = node.measured?.height;\n if (typeof measuredHeight === \"number\" && measuredHeight > 0) {\n return measuredHeight;\n }\n\n const explicitHeight = node.height;\n if (typeof explicitHeight === \"number\" && explicitHeight > 0) {\n return explicitHeight;\n }\n\n return undefined;\n};\n\nconst sortNodesByY = (nodes: Node[]) =>\n [...nodes].sort((a, b) => a.position.y - b.position.y);\n\nexport const extractStepsFromNodes = (nodes: Node[]): TaskStep[] => {\n const sorted = sortNodesByY(nodes);\n return sorted\n .map((node) => {\n const data = node.data as ActionNodeData | undefined;\n if (!data || !data.step) {\n return undefined;\n }\n return cloneStep(data.step as TaskStep);\n })\n .filter((step): step is TaskStep => !!step);\n};\n\nexport const extractParametersFromNodes = (\n nodes: Node[]\n): TemplateParametersValue | undefined => {\n const parametersNode = sortNodesByY(nodes).find(\n (node) => node.type === \"parametersNode\"\n );\n if (!parametersNode) {\n return undefined;\n }\n const data = parametersNode.data as ParametersNodeData | undefined;\n if (!data) {\n return undefined;\n }\n return cloneParameters(data.parameters);\n};\n\nexport const extractOutputFromNodes = (\n nodes: Node[]\n): ScaffolderTaskOutput | undefined => {\n const outputNode = sortNodesByY(nodes).find(\n (node) => node.type === \"outputNode\"\n );\n if (!outputNode) {\n return undefined;\n }\n const data = outputNode.data as OutputNodeData | undefined;\n if (!data) {\n return undefined;\n }\n return cloneOutput(data.output);\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { NODE_VERTICAL_SPACING } from '../Nodes/types.esm.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_NODE_HEIGHT = 320;
|
|
4
|
+
const MIN_VERTICAL_GAP = 48;
|
|
5
|
+
const parseNumericHeight = (value) => {
|
|
6
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
if (typeof value === "string") {
|
|
10
|
+
const parsed = Number.parseFloat(value);
|
|
11
|
+
if (!Number.isNaN(parsed) && parsed > 0) {
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return null;
|
|
16
|
+
};
|
|
17
|
+
const estimateParametersNodeHeight = (node) => {
|
|
18
|
+
if (node.type !== "parametersNode") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const data = node.data;
|
|
22
|
+
if (!data) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const sections = data.sections ?? [];
|
|
26
|
+
const PARAMETER_SHELL_HEIGHT = 300;
|
|
27
|
+
const PARAMETER_CARD_BASE = 220;
|
|
28
|
+
const SECTION_BASE = 180;
|
|
29
|
+
const FIELD_HEIGHT = 86;
|
|
30
|
+
if (!sections.length) {
|
|
31
|
+
return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + SECTION_BASE;
|
|
32
|
+
}
|
|
33
|
+
const sectionsHeight = sections.reduce((total, section) => {
|
|
34
|
+
const fieldCount = section.fields?.length ?? 0;
|
|
35
|
+
return total + SECTION_BASE + Math.max(fieldCount, 1) * FIELD_HEIGHT;
|
|
36
|
+
}, 0);
|
|
37
|
+
return PARAMETER_SHELL_HEIGHT + PARAMETER_CARD_BASE + sectionsHeight;
|
|
38
|
+
};
|
|
39
|
+
const estimateActionNodeHeight = (node) => {
|
|
40
|
+
if (node.type !== "actionNode") {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const data = node.data;
|
|
44
|
+
if (!data) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const base = NODE_VERTICAL_SPACING.actionNode ;
|
|
48
|
+
const rowHeight = 84;
|
|
49
|
+
const inputCount = Object.keys(data.step?.input ?? {}).length;
|
|
50
|
+
const displayedRows = Math.max(inputCount, 1);
|
|
51
|
+
const extraRows = Math.max(displayedRows - 1, 0);
|
|
52
|
+
return base + extraRows * rowHeight;
|
|
53
|
+
};
|
|
54
|
+
const BUILTIN_OUTPUT_KEYS = /* @__PURE__ */ new Set(["links", "text"]);
|
|
55
|
+
const estimateOutputNodeHeight = (node) => {
|
|
56
|
+
if (node.type !== "outputNode") {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const data = node.data;
|
|
60
|
+
if (!data) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const base = 240;
|
|
64
|
+
const linkHeight = 68;
|
|
65
|
+
const textHeight = 68;
|
|
66
|
+
const customHeight = 56;
|
|
67
|
+
const links = Array.isArray(data.output?.links) ? data.output.links : [];
|
|
68
|
+
const textEntries = Array.isArray(data.output?.text) ? data.output.text : [];
|
|
69
|
+
const customEntries = data.output && typeof data.output === "object" ? Object.entries(data.output).filter(
|
|
70
|
+
([key]) => !BUILTIN_OUTPUT_KEYS.has(key)
|
|
71
|
+
) : [];
|
|
72
|
+
return base + links.length * linkHeight + textEntries.length * textHeight + customEntries.length * customHeight;
|
|
73
|
+
};
|
|
74
|
+
const getEstimatedHeightForNode = (node) => {
|
|
75
|
+
const type = node.type;
|
|
76
|
+
if (!type) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const estimators = {
|
|
80
|
+
parametersNode: estimateParametersNodeHeight,
|
|
81
|
+
actionNode: estimateActionNodeHeight,
|
|
82
|
+
outputNode: estimateOutputNodeHeight
|
|
83
|
+
};
|
|
84
|
+
const estimated = estimators[type]?.(node);
|
|
85
|
+
if (typeof estimated === "number" && estimated > 0) {
|
|
86
|
+
return estimated;
|
|
87
|
+
}
|
|
88
|
+
const fallback = NODE_VERTICAL_SPACING[type];
|
|
89
|
+
return typeof fallback === "number" && fallback > 0 ? fallback : null;
|
|
90
|
+
};
|
|
91
|
+
const getNodeHeight = (node) => {
|
|
92
|
+
const measured = parseNumericHeight(node.measured?.height);
|
|
93
|
+
if (measured) {
|
|
94
|
+
return measured;
|
|
95
|
+
}
|
|
96
|
+
const explicitHeight = parseNumericHeight(node.height);
|
|
97
|
+
if (explicitHeight) {
|
|
98
|
+
return explicitHeight;
|
|
99
|
+
}
|
|
100
|
+
const styleHeight = parseNumericHeight(node.style?.height);
|
|
101
|
+
if (styleHeight) {
|
|
102
|
+
return styleHeight;
|
|
103
|
+
}
|
|
104
|
+
const estimatedHeight = getEstimatedHeightForNode(node);
|
|
105
|
+
if (estimatedHeight) {
|
|
106
|
+
return estimatedHeight;
|
|
107
|
+
}
|
|
108
|
+
return DEFAULT_NODE_HEIGHT;
|
|
109
|
+
};
|
|
110
|
+
const getSpacingBufferForNode = (node) => {
|
|
111
|
+
const type = node.type;
|
|
112
|
+
if (!type) {
|
|
113
|
+
return MIN_VERTICAL_GAP;
|
|
114
|
+
}
|
|
115
|
+
const buffer = NODE_VERTICAL_SPACING[type] ?? MIN_VERTICAL_GAP;
|
|
116
|
+
return buffer > MIN_VERTICAL_GAP ? buffer : MIN_VERTICAL_GAP;
|
|
117
|
+
};
|
|
118
|
+
const alignNodes = (nodes, fixedXPosition, verticalSpacing) => {
|
|
119
|
+
let currentY = 0;
|
|
120
|
+
return nodes.map((node) => {
|
|
121
|
+
const alignedNode = {
|
|
122
|
+
...node,
|
|
123
|
+
position: {
|
|
124
|
+
x: fixedXPosition,
|
|
125
|
+
y: currentY
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const nodeHeight = getNodeHeight(node);
|
|
129
|
+
const spacingBuffer = getSpacingBufferForNode(node);
|
|
130
|
+
const minDistance = nodeHeight + spacingBuffer;
|
|
131
|
+
const distanceToNext = Math.max(minDistance, verticalSpacing);
|
|
132
|
+
currentY += distanceToNext;
|
|
133
|
+
return alignedNode;
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export { alignNodes };
|
|
138
|
+
//# sourceMappingURL=nodeLayout.esm.js.map
|