@kestra-io/ui-libs 0.0.301 → 0.0.302
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/VueFlowUtils-Cck2rgf6.cjs +2 -0
- package/dist/VueFlowUtils-Cck2rgf6.cjs.map +1 -0
- package/dist/{VueFlowUtils-Ca_LeFFY.js → VueFlowUtils-l5Oh8tEj.js} +753 -751
- package/dist/VueFlowUtils-l5Oh8tEj.js.map +1 -0
- package/dist/components/nodes/TaskNode.vue.d.ts +17 -7
- package/dist/components/nodes/TaskNode.vue.d.ts.map +1 -1
- package/dist/components/topology/Topology.vue.d.ts +11 -5
- package/dist/components/topology/Topology.vue.d.ts.map +1 -1
- package/dist/components/topology/injectionKeys.d.ts +2 -1
- package/dist/components/topology/injectionKeys.d.ts.map +1 -1
- package/dist/kestra-index.cjs +15 -15
- package/dist/kestra-index.cjs.map +1 -1
- package/dist/kestra-index.mjs +3935 -3850
- package/dist/kestra-index.mjs.map +1 -1
- package/dist/kestra-vueflowutils.cjs +1 -1
- package/dist/kestra-vueflowutils.mjs +1 -1
- package/dist/ui-libs.css +1 -1
- package/dist/utils/VueFlowUtils.d.ts +1 -1
- package/dist/utils/VueFlowUtils.d.ts.map +1 -1
- package/dist/utils/constants.d.ts +3 -1
- package/dist/utils/constants.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/nodes/TaskNode.vue +115 -23
- package/src/components/topology/Topology.vue +112 -16
- package/src/components/topology/injectionKeys.ts +3 -2
- package/src/components/topology/topology.scss +38 -1
- package/src/utils/VueFlowUtils.ts +3 -2
- package/src/utils/constants.ts +3 -1
- package/dist/VueFlowUtils-Ca_LeFFY.js.map +0 -1
- package/dist/VueFlowUtils-CscPDexP.cjs +0 -2
- package/dist/VueFlowUtils-CscPDexP.cjs.map +0 -1
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
:playground-enabled="playgroundEnabled"
|
|
32
32
|
:playground-ready-to-start="playgroundReadyToStart"
|
|
33
33
|
:custom-actions="customActions"
|
|
34
|
+
:show-details="showDetails"
|
|
34
35
|
@edit="emit(EVENTS.EDIT, $event)"
|
|
35
36
|
@delete="emit(EVENTS.DELETE, $event)"
|
|
36
37
|
@run-task="emit(EVENTS.RUN_TASK, $event)"
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
@show-description="emit(EVENTS.SHOW_DESCRIPTION, $event)"
|
|
41
42
|
@show-condition="emit(EVENTS.SHOW_CONDITION, $event)"
|
|
42
43
|
@show-custom-action="emit(EVENTS.SHOW_CUSTOM_ACTION, $event)"
|
|
44
|
+
@show-details="emit(EVENTS.SHOW_DETAILS, $event)"
|
|
43
45
|
@mouseover="onMouseOver($event)"
|
|
44
46
|
@mouseleave="onMouseLeave()"
|
|
45
47
|
@add-error="emit('on-add-flowable-error', $event)"
|
|
@@ -89,11 +91,17 @@
|
|
|
89
91
|
/>
|
|
90
92
|
</template>
|
|
91
93
|
|
|
92
|
-
<Controls v-if="controlsShown" :show-interactive="false">
|
|
94
|
+
<Controls v-if="controlsShown" :show-interactive="false" :show-fit-view="false">
|
|
95
|
+
<ControlButton @click="showExtraDetails = !showExtraDetails" :class="{'active': showExtraDetails}">
|
|
96
|
+
<Information />
|
|
97
|
+
</ControlButton>
|
|
98
|
+
<ControlButton @click="fitView()">
|
|
99
|
+
<svg viewBox="0 0 32 32" style="width:12px;height:12px"><path d="M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0 0 27.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94a.919.919 0 0 1-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z" fill="currentColor" /></svg>
|
|
100
|
+
</ControlButton>
|
|
93
101
|
<ControlButton @click="emit('toggle-orientation', $event)" v-if="toggleOrientationButton">
|
|
94
102
|
<component :is="isHorizontal ? SplitCellsHorizontal : SplitCellsVertical" />
|
|
95
103
|
</ControlButton>
|
|
96
|
-
<ControlButton @click="toggleDropdown">
|
|
104
|
+
<ControlButton @click="toggleDropdown">
|
|
97
105
|
<Download />
|
|
98
106
|
</ControlButton>
|
|
99
107
|
<ul v-if="isDropdownOpen" class="exporting">
|
|
@@ -128,13 +136,14 @@
|
|
|
128
136
|
// @ts-expect-error no types for internals necessary
|
|
129
137
|
import SplitCellsHorizontal from "../../assets/icons/SplitCellsHorizontal.vue";
|
|
130
138
|
import Download from "vue-material-design-icons/Download.vue";
|
|
139
|
+
import Information from "vue-material-design-icons/Information.vue";
|
|
131
140
|
import {cssVariable} from "../../utils/global";
|
|
132
|
-
import {CLUSTER_PREFIX,
|
|
141
|
+
import {CLUSTER_PREFIX, EVENTS, NODE_SIZES, ShowDetailsConfig} from "../../utils/constants"
|
|
133
142
|
import Utils from "../../utils/Utils"
|
|
134
143
|
import * as VueFlowUtils from "../../utils/VueFlowUtils";
|
|
135
144
|
import {isParentChildrenRelation, swapBlocks} from "../../utils/FlowYamlUtils";
|
|
136
145
|
import {useScreenshot} from "./export/useScreenshot";
|
|
137
|
-
import {EXECUTION_INJECTION_KEY, SUBFLOWS_EXECUTIONS_INJECTION_KEY} from "./injectionKeys";
|
|
146
|
+
import {EXECUTION_INJECTION_KEY, SUBFLOWS_EXECUTIONS_INJECTION_KEY, SHOW_EXTRA_DETAILS_INJECTION_KEY} from "./injectionKeys";
|
|
138
147
|
import BasicNode from "../nodes/BasicNode.vue";
|
|
139
148
|
|
|
140
149
|
const props = withDefaults(defineProps<{
|
|
@@ -156,7 +165,9 @@
|
|
|
156
165
|
playgroundEnabled?: boolean;
|
|
157
166
|
playgroundReadyToStart?: boolean;
|
|
158
167
|
getNodeDimensions?: (node: any, getNodeWidth: (node: any) => number, getNodeHeight: (node: any) => number) => { width: number, height: number };
|
|
159
|
-
customActions?: Record<string,
|
|
168
|
+
customActions?: Record<string, ShowDetailsConfig>;
|
|
169
|
+
showDetails?: Record<string, ShowDetailsConfig>;
|
|
170
|
+
animated?: boolean;
|
|
160
171
|
}>(), {
|
|
161
172
|
isHorizontal: true,
|
|
162
173
|
isReadOnly: true,
|
|
@@ -173,10 +184,53 @@
|
|
|
173
184
|
playgroundReadyToStart: false,
|
|
174
185
|
subflowsExecutions: () => ({}),
|
|
175
186
|
getNodeDimensions: undefined,
|
|
176
|
-
customActions: () => ({})
|
|
187
|
+
customActions: () => ({}),
|
|
188
|
+
showDetails: () => ({}),
|
|
189
|
+
animated: true
|
|
177
190
|
});
|
|
178
191
|
|
|
179
192
|
const dragging = ref(false);
|
|
193
|
+
const showExtraDetails = ref(false);
|
|
194
|
+
const HOVERED_NODE_CLASS = "topology-node-hovered";
|
|
195
|
+
const DROP_TARGET_NODE_CLASS = "topology-node-drop-target";
|
|
196
|
+
const effectiveGetNodeDimensions = computed(() => {
|
|
197
|
+
return (node: any, getNodeWidth: (node: any) => number, getNodeHeight: (node: any) => number) => {
|
|
198
|
+
const baseHeight = getNodeHeight(node);
|
|
199
|
+
const dimensions = props.getNodeDimensions
|
|
200
|
+
? props.getNodeDimensions(node, getNodeWidth, getNodeHeight)
|
|
201
|
+
: {
|
|
202
|
+
width: getNodeWidth(node),
|
|
203
|
+
height: baseHeight
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
if (!showExtraDetails.value && VueFlowUtils.isTaskNode(node)) {
|
|
207
|
+
return {
|
|
208
|
+
...dimensions,
|
|
209
|
+
height: baseHeight
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (showExtraDetails.value && VueFlowUtils.isTaskNode(node)) {
|
|
214
|
+
const taskType = node?.task?.type as string | undefined;
|
|
215
|
+
const hasDetailsAction = Boolean(
|
|
216
|
+
(taskType && props.customActions?.[taskType]) ||
|
|
217
|
+
(taskType && props.showDetails?.[taskType])
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
if (hasDetailsAction) {
|
|
221
|
+
return {
|
|
222
|
+
...dimensions,
|
|
223
|
+
height: Math.max(
|
|
224
|
+
dimensions.height,
|
|
225
|
+
NODE_SIZES.TASK_EXPANDED_FALLBACK_HEIGHT
|
|
226
|
+
)
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return dimensions;
|
|
232
|
+
};
|
|
233
|
+
});
|
|
180
234
|
const lastPosition = ref<XYPosition | null>()
|
|
181
235
|
const {getNodes, onNodeDrag, onNodeDragStart, onNodeDragStop, fitView, setElements, vueFlowRef} = useVueFlow(props.id);
|
|
182
236
|
const edgeReplacer = ref({});
|
|
@@ -187,6 +241,7 @@
|
|
|
187
241
|
|
|
188
242
|
provide(EXECUTION_INJECTION_KEY, computed(() => props.execution));
|
|
189
243
|
provide(SUBFLOWS_EXECUTIONS_INJECTION_KEY, computed(() => props.subflowsExecutions));
|
|
244
|
+
provide(SHOW_EXTRA_DETAILS_INJECTION_KEY, showExtraDetails);
|
|
190
245
|
|
|
191
246
|
|
|
192
247
|
const emit = defineEmits(
|
|
@@ -206,7 +261,8 @@
|
|
|
206
261
|
"message",
|
|
207
262
|
"expand-subflow",
|
|
208
263
|
EVENTS.SHOW_CONDITION,
|
|
209
|
-
EVENTS.SHOW_CUSTOM_ACTION
|
|
264
|
+
EVENTS.SHOW_CUSTOM_ACTION,
|
|
265
|
+
EVENTS.SHOW_DETAILS
|
|
210
266
|
]
|
|
211
267
|
)
|
|
212
268
|
|
|
@@ -223,6 +279,10 @@
|
|
|
223
279
|
generateGraph();
|
|
224
280
|
})
|
|
225
281
|
|
|
282
|
+
watch(showExtraDetails, () => {
|
|
283
|
+
generateGraph();
|
|
284
|
+
})
|
|
285
|
+
|
|
226
286
|
const generateGraph = () => {
|
|
227
287
|
VueFlowUtils.cleanGraph(props.id);
|
|
228
288
|
|
|
@@ -250,7 +310,8 @@
|
|
|
250
310
|
props.isReadOnly,
|
|
251
311
|
props.isAllowedEdit,
|
|
252
312
|
props.enableSubflowInteraction,
|
|
253
|
-
|
|
313
|
+
effectiveGetNodeDimensions.value,
|
|
314
|
+
props.animated
|
|
254
315
|
);
|
|
255
316
|
|
|
256
317
|
if(elements) {
|
|
@@ -266,8 +327,8 @@
|
|
|
266
327
|
if (!dragging.value) {
|
|
267
328
|
VueFlowUtils.linkedElements(props.id, node.uid).forEach((n) => {
|
|
268
329
|
if (n?.type === "task") {
|
|
269
|
-
n.style = {...n.style,
|
|
270
|
-
n
|
|
330
|
+
n.style = {...n.style, opacity: "1", outline: "none"}
|
|
331
|
+
setNodeInteractionClass(n, HOVERED_NODE_CLASS, true);
|
|
271
332
|
}
|
|
272
333
|
});
|
|
273
334
|
}
|
|
@@ -282,7 +343,7 @@
|
|
|
282
343
|
getNodes.value.filter(n => n.type === "task" || n.type === "trigger")
|
|
283
344
|
.forEach(n => {
|
|
284
345
|
n.style = {...n.style, opacity: "1", outline: "none"}
|
|
285
|
-
n
|
|
346
|
+
clearNodeInteractionClasses(n);
|
|
286
347
|
})
|
|
287
348
|
}
|
|
288
349
|
|
|
@@ -352,15 +413,50 @@
|
|
|
352
413
|
if (e.intersections && !checkIntersections(e.intersections, e.node) && e.intersections.filter((n:any) => n.type === "task").length === 1) {
|
|
353
414
|
e.intersections.forEach((n:any) => {
|
|
354
415
|
if (n.type === "task") {
|
|
355
|
-
n.style = {...n.style, outline: "
|
|
356
|
-
n
|
|
416
|
+
n.style = {...n.style, outline: "none"}
|
|
417
|
+
setNodeInteractionClass(n, DROP_TARGET_NODE_CLASS, true);
|
|
357
418
|
}
|
|
358
419
|
})
|
|
359
|
-
e.node.style = {...e.node.style, outline: "
|
|
360
|
-
e.node
|
|
420
|
+
e.node.style = {...e.node.style, outline: "none"}
|
|
421
|
+
setNodeInteractionClass(e.node, DROP_TARGET_NODE_CLASS, true);
|
|
361
422
|
}
|
|
362
423
|
})
|
|
363
424
|
|
|
425
|
+
const normalizeNodeClasses = (value: unknown): string[] => {
|
|
426
|
+
if (typeof value === "string") {
|
|
427
|
+
return value.split(/\s+/).filter(Boolean);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (Array.isArray(value)) {
|
|
431
|
+
return value.flatMap((entry) => normalizeNodeClasses(entry));
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (value && typeof value === "object") {
|
|
435
|
+
return Object.entries(value as Record<string, boolean>)
|
|
436
|
+
.filter(([, enabled]) => Boolean(enabled))
|
|
437
|
+
.map(([className]) => className);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return [];
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
const setNodeInteractionClass = (node: any, className: string, enabled: boolean) => {
|
|
444
|
+
const classes = new Set(normalizeNodeClasses(node.class));
|
|
445
|
+
|
|
446
|
+
if (enabled) {
|
|
447
|
+
classes.add(className);
|
|
448
|
+
} else {
|
|
449
|
+
classes.delete(className);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
node.class = Array.from(classes).join(" ");
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
const clearNodeInteractionClasses = (node: any) => {
|
|
456
|
+
setNodeInteractionClass(node, HOVERED_NODE_CLASS, false);
|
|
457
|
+
setNodeInteractionClass(node, DROP_TARGET_NODE_CLASS, false);
|
|
458
|
+
};
|
|
459
|
+
|
|
364
460
|
const checkIntersections = (intersections:any, node:any) => {
|
|
365
461
|
const tasksMeet = intersections.filter((n:any) => n.type === "task").map((n:any) => Utils.afterLastDot(n.id));
|
|
366
462
|
if (tasksMeet.length > 1) {
|
|
@@ -489,4 +585,4 @@
|
|
|
489
585
|
}
|
|
490
586
|
}
|
|
491
587
|
}
|
|
492
|
-
</style>
|
|
588
|
+
</style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {ComputedRef, InjectionKey} from "vue"
|
|
1
|
+
import type {ComputedRef, InjectionKey, Ref} from "vue"
|
|
2
2
|
|
|
3
3
|
export const EXECUTION_INJECTION_KEY = Symbol("execution-injection-key") as InjectionKey<ComputedRef<any>>
|
|
4
|
-
export const SUBFLOWS_EXECUTIONS_INJECTION_KEY = Symbol("subflows-executions-injection-key") as InjectionKey<ComputedRef<Record<string, any[]>>>
|
|
4
|
+
export const SUBFLOWS_EXECUTIONS_INJECTION_KEY = Symbol("subflows-executions-injection-key") as InjectionKey<ComputedRef<Record<string, any[]>>>
|
|
5
|
+
export const SHOW_EXTRA_DETAILS_INJECTION_KEY = Symbol("show-extra-details-injection-key") as InjectionKey<Ref<boolean>>
|
|
@@ -31,6 +31,10 @@ $node-colors: (
|
|
|
31
31
|
font-size: 0.66rem;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
.vue-flow__panel.vue-flow__controls {
|
|
35
|
+
z-index: 200001;
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
.vue-flow__controls {
|
|
35
39
|
border: 1px solid var(--ks-border-primary);
|
|
36
40
|
border-radius: var(--bs-border-radius);
|
|
@@ -40,10 +44,26 @@ $node-colors: (
|
|
|
40
44
|
color: var(--bs-black);
|
|
41
45
|
border-bottom-color: var(--bs-border-color);
|
|
42
46
|
|
|
47
|
+
.material-design-icon {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
line-height: 0;
|
|
52
|
+
|
|
53
|
+
svg {
|
|
54
|
+
width: 12px;
|
|
55
|
+
height: 12px;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
43
59
|
svg {
|
|
44
60
|
fill: var(--bs-black);
|
|
45
61
|
}
|
|
46
62
|
|
|
63
|
+
&.active svg {
|
|
64
|
+
fill: var(--ks-content-link);
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
html.dark & {
|
|
48
68
|
background: var(--ks-background-card);
|
|
49
69
|
color: var(--bs-white);
|
|
@@ -51,6 +71,10 @@ $node-colors: (
|
|
|
51
71
|
svg {
|
|
52
72
|
fill: var(--bs-white);
|
|
53
73
|
}
|
|
74
|
+
|
|
75
|
+
&.active svg {
|
|
76
|
+
fill: var(--ks-content-link);
|
|
77
|
+
}
|
|
54
78
|
}
|
|
55
79
|
}
|
|
56
80
|
|
|
@@ -59,6 +83,19 @@ $node-colors: (
|
|
|
59
83
|
}
|
|
60
84
|
|
|
61
85
|
.vue-flow__container {
|
|
86
|
+
.vue-flow__node.topology-node-hovered,
|
|
87
|
+
.vue-flow__node.topology-node-drop-target {
|
|
88
|
+
outline: none !important;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.vue-flow__node.topology-node-hovered .node-wrapper {
|
|
92
|
+
border-color: var(--bs-gray-900) !important;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.vue-flow__node.topology-node-drop-target .node-wrapper {
|
|
96
|
+
border-color: var(--bs-primary) !important;
|
|
97
|
+
}
|
|
98
|
+
|
|
62
99
|
.top-button-div {
|
|
63
100
|
position: absolute;
|
|
64
101
|
top: -0.5rem;
|
|
@@ -97,4 +134,4 @@ $node-colors: (
|
|
|
97
134
|
.circle-button {
|
|
98
135
|
display: none !important;
|
|
99
136
|
}
|
|
100
|
-
}
|
|
137
|
+
}
|
|
@@ -436,7 +436,8 @@ export function generateGraph(
|
|
|
436
436
|
= (node, getNodeWidth, getNodeHeight) => ({
|
|
437
437
|
width: getNodeWidth(node),
|
|
438
438
|
height: getNodeHeight(node)
|
|
439
|
-
})
|
|
439
|
+
}),
|
|
440
|
+
animated: boolean = true
|
|
440
441
|
): Elements | undefined {
|
|
441
442
|
const elements: Elements = [];
|
|
442
443
|
|
|
@@ -699,7 +700,7 @@ export function generateGraph(
|
|
|
699
700
|
style: {
|
|
700
701
|
zIndex: 10,
|
|
701
702
|
},
|
|
702
|
-
animated:
|
|
703
|
+
animated: animated,
|
|
703
704
|
});
|
|
704
705
|
}
|
|
705
706
|
}
|
package/src/utils/constants.ts
CHANGED
|
@@ -20,9 +20,10 @@ export const EVENTS = {
|
|
|
20
20
|
SHOW_CONDITION: "showCondition",
|
|
21
21
|
RUN_TASK: "runTask",
|
|
22
22
|
SHOW_CUSTOM_ACTION: "showCustomAction",
|
|
23
|
+
SHOW_DETAILS: "showDetails",
|
|
23
24
|
} as const;
|
|
24
25
|
|
|
25
|
-
export interface
|
|
26
|
+
export interface ShowDetailsConfig {
|
|
26
27
|
label: string;
|
|
27
28
|
taskProp: string;
|
|
28
29
|
lang: string;
|
|
@@ -33,6 +34,7 @@ export const CLUSTER_PREFIX = "cluster_";
|
|
|
33
34
|
export const NODE_SIZES = {
|
|
34
35
|
TASK_WIDTH: 184,
|
|
35
36
|
TASK_HEIGHT: 44,
|
|
37
|
+
TASK_EXPANDED_FALLBACK_HEIGHT: 140,
|
|
36
38
|
TRIGGER_WIDTH: 184,
|
|
37
39
|
TRIGGER_HEIGHT: 44,
|
|
38
40
|
DOT_WIDTH: 5,
|