@kestra-io/ui-libs 0.0.227 → 0.0.229
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/{FlowYamlUtils-MCAmyY3D.js → FlowYamlUtils-BrY8bEv7.js} +24 -17
- package/dist/{FlowYamlUtils-MCAmyY3D.js.map → FlowYamlUtils-BrY8bEv7.js.map} +1 -1
- package/dist/{FlowYamlUtils-DAm_-0Qh.cjs → FlowYamlUtils-DvtepVr2.cjs} +3 -2
- package/dist/{FlowYamlUtils-DAm_-0Qh.cjs.map → FlowYamlUtils-DvtepVr2.cjs.map} +1 -1
- package/dist/VueFlowUtils-BhTB7zMW.cjs +2 -0
- package/dist/VueFlowUtils-BhTB7zMW.cjs.map +1 -0
- package/dist/{VueFlowUtils-A_7_qgxS.js → VueFlowUtils-BmNdCDFy.js} +461 -452
- package/dist/VueFlowUtils-BmNdCDFy.js.map +1 -0
- package/dist/assets/icons/RotatingDots.vue.d.ts +6 -0
- package/dist/assets/icons/RotatingDots.vue.d.ts.map +1 -0
- package/dist/components/misc/Collapsible.vue.d.ts.map +1 -1
- package/dist/components/misc/ExecutionInformations.vue.d.ts +1 -0
- package/dist/components/misc/ExecutionInformations.vue.d.ts.map +1 -1
- package/dist/components/nodes/BasicNode.vue.d.ts +44 -113
- package/dist/components/nodes/BasicNode.vue.d.ts.map +1 -1
- package/dist/components/nodes/EdgeNode.vue.d.ts +5 -7
- package/dist/components/nodes/EdgeNode.vue.d.ts.map +1 -1
- package/dist/components/nodes/TaskNode.vue.d.ts +48 -240
- package/dist/components/nodes/TaskNode.vue.d.ts.map +1 -1
- package/dist/components/plugins/PluginIndex.vue.d.ts +2 -8
- package/dist/components/plugins/PluginIndex.vue.d.ts.map +1 -1
- package/dist/components/topology/Topology.vue.d.ts +13 -4
- package/dist/components/topology/Topology.vue.d.ts.map +1 -1
- package/dist/components/topology/injectionKeys.d.ts +0 -1
- package/dist/components/topology/injectionKeys.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kestra-flowyamlutils.cjs.js +1 -1
- package/dist/kestra-flowyamlutils.es.js +1 -1
- package/dist/kestra-index.cjs.js +15 -15
- package/dist/kestra-index.cjs.js.map +1 -1
- package/dist/kestra-index.es.js +3611 -3656
- package/dist/kestra-index.es.js.map +1 -1
- package/dist/kestra-vueflowutils.cjs.js +1 -1
- package/dist/kestra-vueflowutils.es.js +7 -7
- package/dist/ui-libs.css +1 -1
- package/dist/utils/FlowYamlUtils.d.ts.map +1 -1
- package/dist/utils/Utils.d.ts +14 -7
- package/dist/utils/Utils.d.ts.map +1 -1
- package/dist/utils/state.d.ts +1 -0
- package/dist/utils/state.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/assets/icons/RotatingDots.vue +25 -0
- package/src/components/misc/Collapsible.vue +2 -5
- package/src/components/misc/Duration.vue +2 -2
- package/src/components/misc/ExecutionInformations.vue +6 -36
- package/src/components/nodes/BasicNode.vue +121 -152
- package/src/components/nodes/TaskNode.vue +265 -189
- package/src/components/topology/Topology.vue +8 -3
- package/src/components/topology/injectionKeys.ts +1 -2
- package/src/index.ts +1 -0
- package/src/utils/FlowYamlUtils.test.ts +11 -0
- package/src/utils/FlowYamlUtils.ts +16 -5
- package/src/utils/Utils.ts +48 -34
- package/src/utils/state.ts +4 -0
- package/dist/VueFlowUtils-A_7_qgxS.js.map +0 -1
- package/dist/VueFlowUtils-CL70qtJ4.cjs +0 -2
- package/dist/VueFlowUtils-CL70qtJ4.cjs.map +0 -1
|
@@ -7,26 +7,52 @@
|
|
|
7
7
|
:class="classes"
|
|
8
8
|
:icons="icons"
|
|
9
9
|
:icon-component="iconComponent"
|
|
10
|
-
@show-description="
|
|
11
|
-
@expand="
|
|
12
|
-
@open-link="
|
|
13
|
-
@mouseover="
|
|
14
|
-
@mouseleave="
|
|
10
|
+
@show-description="emit(EVENTS.SHOW_DESCRIPTION, $event)"
|
|
11
|
+
@expand="emit(EVENTS.EXPAND, expandData)"
|
|
12
|
+
@open-link="emit(EVENTS.OPEN_LINK, $event)"
|
|
13
|
+
@mouseover="emit(EVENTS.MOUSE_OVER, $event)"
|
|
14
|
+
@mouseleave="emit(EVENTS.MOUSE_LEAVE)"
|
|
15
15
|
>
|
|
16
16
|
<template #content>
|
|
17
|
-
<execution-informations
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
<execution-informations
|
|
18
|
+
v-if="taskExecution"
|
|
19
|
+
:execution="taskExecution"
|
|
20
|
+
:task="data.node.task"
|
|
21
|
+
:color="color"
|
|
22
|
+
:uid="data.node.uid"
|
|
23
|
+
:state="state"
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
<template v-if="data.node.task">
|
|
27
|
+
<button v-if="playgroundEnabled && playgroundReadyToStart" type="button" class="playground-button" @click="emit(EVENTS.RUN_TASK, {task: data.node.task})">
|
|
28
|
+
<tooltip style="display: flex;" :title="$t('run task in playground')">
|
|
29
|
+
<PlayIcon class="button-play-icon" :alt="$t('run task in playground')" />
|
|
30
|
+
</tooltip>
|
|
31
|
+
</button>
|
|
32
|
+
<div
|
|
33
|
+
v-else
|
|
34
|
+
class="playground-button"
|
|
35
|
+
:style="{
|
|
36
|
+
color: `var(--ks-content-${state?.toLowerCase()})`,
|
|
37
|
+
backgroundColor: `var(--ks-background-${state?.toLowerCase()})`
|
|
38
|
+
}"
|
|
39
|
+
>
|
|
40
|
+
<tooltip style="display: flex;" :title="$t(iconAlt)">
|
|
41
|
+
<RotatingDots v-if="state === State.RUNNING" :alt="$t(iconAlt)" />
|
|
42
|
+
<CheckIcon v-else-if="state === State.SUCCESS" :alt="$t(iconAlt)" />
|
|
43
|
+
<AlertIcon v-else-if="state === State.WARNING" :alt="$t(iconAlt)" />
|
|
44
|
+
<SkipForwardIcon v-else-if="state === State.SKIPPED" :alt="$t(iconAlt)" />
|
|
45
|
+
<AlertCircleIcon v-else-if="state === State.FAILED" :alt="$t(iconAlt)" />
|
|
46
|
+
</tooltip>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
23
49
|
</template>
|
|
24
50
|
<template #badge-button-before>
|
|
25
51
|
<span
|
|
26
52
|
v-if="data.node.task && data.node.task.runIf"
|
|
27
53
|
class="circle-button"
|
|
28
54
|
:class="[`bg-warning`]"
|
|
29
|
-
@click="
|
|
55
|
+
@click="emit(EVENTS.SHOW_CONDITION, {id: taskId, task: data.node.task, section: SECTIONS.TASKS})"
|
|
30
56
|
>
|
|
31
57
|
<tooltip :title="$t('show task condition')">
|
|
32
58
|
<SendLock class="button-icon" alt="Show condition" />
|
|
@@ -36,7 +62,7 @@
|
|
|
36
62
|
v-if="taskExecution"
|
|
37
63
|
class="circle-button"
|
|
38
64
|
:class="[`bg-${color}`]"
|
|
39
|
-
@click="
|
|
65
|
+
@click="emit(EVENTS.SHOW_LOGS, {id: taskId, execution: taskExecution, taskRuns})"
|
|
40
66
|
>
|
|
41
67
|
<tooltip :title="$t('show task logs')">
|
|
42
68
|
<TextBoxSearch class="button-icon" alt="Show logs" />
|
|
@@ -46,7 +72,7 @@
|
|
|
46
72
|
v-if="!taskExecution && !data.isReadOnly && data.isFlowable"
|
|
47
73
|
class="circle-button"
|
|
48
74
|
:class="[`bg-${color}`]"
|
|
49
|
-
@click="
|
|
75
|
+
@click="emit(EVENTS.ADD_ERROR, {task: data.node.task})"
|
|
50
76
|
>
|
|
51
77
|
<tooltip :title="$t('add error handler')">
|
|
52
78
|
<AlertOutline class="button-icon" alt="Add error handler" />
|
|
@@ -56,7 +82,7 @@
|
|
|
56
82
|
v-if="!taskExecution && !data.isReadOnly"
|
|
57
83
|
class="circle-button"
|
|
58
84
|
:class="[`bg-${color}`]"
|
|
59
|
-
@click="
|
|
85
|
+
@click="emit(EVENTS.EDIT, {task: data.node.task, section: SECTIONS.TASKS})"
|
|
60
86
|
>
|
|
61
87
|
<tooltip :title="$t('edit')">
|
|
62
88
|
<Pencil class="button-icon" alt="Edit task" />
|
|
@@ -66,7 +92,7 @@
|
|
|
66
92
|
v-if="!taskExecution && !data.isReadOnly"
|
|
67
93
|
class="circle-button"
|
|
68
94
|
:class="[`bg-${color}`]"
|
|
69
|
-
@click="
|
|
95
|
+
@click="emit(EVENTS.DELETE, {id: taskId, section: SECTIONS.TASKS})"
|
|
70
96
|
>
|
|
71
97
|
<tooltip :title="$t('delete')">
|
|
72
98
|
<Delete class="button-icon" alt="Delete task" />
|
|
@@ -76,190 +102,235 @@
|
|
|
76
102
|
</basic-node>
|
|
77
103
|
<Handle type="target" :position="targetPosition" />
|
|
78
104
|
</template>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
import {Handle} from "@vue-flow/core";
|
|
105
|
+
|
|
106
|
+
<script setup lang="ts">
|
|
107
|
+
import {computed, inject} from "vue";
|
|
108
|
+
import {Handle, Position} from "@vue-flow/core";
|
|
84
109
|
import State from "../../utils/state";
|
|
85
110
|
import {EVENTS, SECTIONS} from "../../utils/constants";
|
|
86
111
|
import ExecutionInformations from "../misc/ExecutionInformations.vue";
|
|
87
|
-
import
|
|
88
|
-
import Delete from "vue-material-design-icons/Delete.vue";
|
|
89
|
-
import TextBoxSearch from "vue-material-design-icons/TextBoxSearch.vue";
|
|
90
|
-
import AlertOutline from "vue-material-design-icons/AlertOutline.vue"
|
|
91
|
-
import PlayIcon from "vue-material-design-icons/Play.vue";
|
|
92
|
-
import SendLock from "vue-material-design-icons/SendLock.vue"
|
|
93
|
-
import Tooltip from "../misc/Tooltip.vue"
|
|
112
|
+
import Tooltip from "../misc/Tooltip.vue";
|
|
94
113
|
import Utils from "../../utils/Utils";
|
|
114
|
+
import BasicNode from "./BasicNode.vue";
|
|
95
115
|
import {
|
|
96
|
-
EXECUTION_INJECTION_KEY,
|
|
116
|
+
EXECUTION_INJECTION_KEY,
|
|
97
117
|
SUBFLOWS_EXECUTIONS_INJECTION_KEY,
|
|
98
|
-
PLAYGROUND_ENABLED_INJECTION_KEY
|
|
99
118
|
} from "../topology/injectionKeys";
|
|
100
119
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
},
|
|
113
|
-
inheritAttrs: false,
|
|
114
|
-
inject: {
|
|
115
|
-
execution: {
|
|
116
|
-
from: EXECUTION_INJECTION_KEY,
|
|
117
|
-
},
|
|
118
|
-
subflowsExecutions: {
|
|
119
|
-
from: SUBFLOWS_EXECUTIONS_INJECTION_KEY,
|
|
120
|
-
},
|
|
121
|
-
playgroundEnabled: {
|
|
122
|
-
from: PLAYGROUND_ENABLED_INJECTION_KEY,
|
|
123
|
-
}
|
|
124
|
-
},
|
|
125
|
-
computed: {
|
|
126
|
-
SECTIONS() {
|
|
127
|
-
return SECTIONS
|
|
128
|
-
},
|
|
129
|
-
EVENTS() {
|
|
130
|
-
return EVENTS
|
|
131
|
-
},
|
|
132
|
-
color() {
|
|
133
|
-
return this.data.color ?? "primary"
|
|
134
|
-
},
|
|
135
|
-
taskId() {
|
|
136
|
-
return Utils.afterLastDot(this.id);
|
|
137
|
-
},
|
|
138
|
-
taskRunList() {
|
|
139
|
-
return this.taskExecution && this.taskExecution.taskRunList ? this.taskExecution.taskRunList : []
|
|
140
|
-
},
|
|
141
|
-
taskExecution() {
|
|
142
|
-
const executionId = this.data.executionId;
|
|
143
|
-
if(executionId) {
|
|
144
|
-
return executionId === this.execution?.id ? this.execution
|
|
145
|
-
: Object.values(this.subflowsExecutions).filter(execution => execution.id === this.data.executionId)?.[0];
|
|
146
|
-
}
|
|
120
|
+
import Pencil from "vue-material-design-icons/Pencil.vue";
|
|
121
|
+
import Delete from "vue-material-design-icons/Delete.vue";
|
|
122
|
+
import TextBoxSearch from "vue-material-design-icons/TextBoxSearch.vue";
|
|
123
|
+
import AlertOutline from "vue-material-design-icons/AlertOutline.vue";
|
|
124
|
+
import SendLock from "vue-material-design-icons/SendLock.vue";
|
|
125
|
+
import PlayIcon from "vue-material-design-icons/Play.vue";
|
|
126
|
+
import CheckIcon from "vue-material-design-icons/Check.vue";
|
|
127
|
+
import AlertCircleIcon from "vue-material-design-icons/AlertCircle.vue";
|
|
128
|
+
import AlertIcon from "vue-material-design-icons/Alert.vue";
|
|
129
|
+
import SkipForwardIcon from "vue-material-design-icons/SkipForward.vue";
|
|
130
|
+
import RotatingDots from "../../assets/icons/RotatingDots.vue";
|
|
147
131
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
132
|
+
// Define types
|
|
133
|
+
interface TaskType {
|
|
134
|
+
id: string;
|
|
135
|
+
type: object;
|
|
136
|
+
default: null;
|
|
137
|
+
runIf?: unknown;
|
|
138
|
+
subflowId?: {
|
|
139
|
+
namespace: string;
|
|
140
|
+
flowId: string;
|
|
141
|
+
};
|
|
142
|
+
namespace?: string;
|
|
143
|
+
flowId?: string;
|
|
144
|
+
}
|
|
157
145
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
146
|
+
interface NodeData {
|
|
147
|
+
node: {
|
|
148
|
+
uid: string;
|
|
149
|
+
type?: string;
|
|
150
|
+
task: TaskType;
|
|
151
|
+
};
|
|
152
|
+
executionId?: string;
|
|
153
|
+
color?: string;
|
|
154
|
+
isReadOnly?: boolean;
|
|
155
|
+
isFlowable?: boolean;
|
|
156
|
+
link?: {
|
|
157
|
+
namespace: string;
|
|
158
|
+
id: string;
|
|
159
|
+
executionId?: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
161
162
|
|
|
162
|
-
|
|
163
|
+
interface TaskRun {
|
|
164
|
+
taskId: string;
|
|
165
|
+
state: {
|
|
166
|
+
current: [string, string]; // [state, stateText]
|
|
167
|
+
};
|
|
168
|
+
outputs?: {
|
|
169
|
+
executionId?: string;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
163
172
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
State.KILLING,
|
|
169
|
-
State.RUNNING,
|
|
170
|
-
State.SUCCESS,
|
|
171
|
-
State.RESTARTED,
|
|
172
|
-
State.CREATED,
|
|
173
|
-
];
|
|
173
|
+
interface ExpandData {
|
|
174
|
+
id: string;
|
|
175
|
+
type: string;
|
|
176
|
+
}
|
|
174
177
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
178
|
+
const props = withDefaults(defineProps<{
|
|
179
|
+
data: NodeData;
|
|
180
|
+
sourcePosition?: Position;
|
|
181
|
+
targetPosition?: Position;
|
|
182
|
+
id: string;
|
|
183
|
+
icons?: Record<string, unknown>;
|
|
184
|
+
iconComponent?: object;
|
|
185
|
+
enableSubflowInteraction?: boolean;
|
|
186
|
+
playgroundEnabled: boolean;
|
|
187
|
+
playgroundReadyToStart: boolean;
|
|
188
|
+
}>(), {
|
|
189
|
+
sourcePosition: Position.Right,
|
|
190
|
+
targetPosition: Position.Left,
|
|
191
|
+
enableSubflowInteraction: true,
|
|
192
|
+
icons: undefined,
|
|
193
|
+
iconComponent: undefined,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
defineOptions({
|
|
197
|
+
name: "TaskNode",
|
|
198
|
+
inheritAttrs: false
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Define emits
|
|
202
|
+
const emit = defineEmits<{
|
|
203
|
+
(event: typeof EVENTS.EXPAND, data: any): void;
|
|
204
|
+
(event: typeof EVENTS.OPEN_LINK, data: any): void;
|
|
205
|
+
(event: typeof EVENTS.SHOW_LOGS, data: any): void;
|
|
206
|
+
(event: typeof EVENTS.MOUSE_OVER, data: any): void;
|
|
207
|
+
(event: typeof EVENTS.MOUSE_LEAVE): void;
|
|
208
|
+
(event: typeof EVENTS.ADD_ERROR, data: { task: any }): void;
|
|
209
|
+
(event: typeof EVENTS.EDIT, data: any) :void;
|
|
210
|
+
(event: typeof EVENTS.DELETE, data: any) :void;
|
|
211
|
+
(event: typeof EVENTS.ADD_TASK, data: any) :void;
|
|
212
|
+
(event: typeof EVENTS.SHOW_CONDITION, data: any) :void;
|
|
213
|
+
(event: typeof EVENTS.SHOW_DESCRIPTION, data: any) :void;
|
|
214
|
+
(event: typeof EVENTS.RUN_TASK, data: { task: any }) :void;
|
|
215
|
+
}>();
|
|
216
|
+
|
|
217
|
+
// Inject dependencies
|
|
218
|
+
const execution = inject(EXECUTION_INJECTION_KEY);
|
|
219
|
+
const subflowsExecutions = inject(SUBFLOWS_EXECUTIONS_INJECTION_KEY);
|
|
220
|
+
|
|
221
|
+
// Computed properties
|
|
222
|
+
const color = computed(() => props.data.color ?? "primary");
|
|
223
|
+
|
|
224
|
+
const taskId = computed(() => Utils.afterLastDot(props.id));
|
|
225
|
+
|
|
226
|
+
const taskExecution = computed(() => {
|
|
227
|
+
const executionId = props.data.executionId;
|
|
228
|
+
if (executionId) {
|
|
229
|
+
return executionId === execution?.value?.id
|
|
230
|
+
? execution?.value
|
|
231
|
+
: Object.values(subflowsExecutions?.value || {})
|
|
232
|
+
.find((exec: any) => exec.id === executionId);
|
|
233
|
+
}
|
|
234
|
+
return undefined;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const taskRunList = computed(() => {
|
|
238
|
+
return taskExecution.value && taskExecution.value.taskRunList
|
|
239
|
+
? taskExecution.value.taskRunList
|
|
240
|
+
: [];
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const taskRuns = computed(() => {
|
|
244
|
+
return taskRunList.value.filter(
|
|
245
|
+
(t: TaskRun) => t.taskId === Utils.afterLastDot(props.data.node.uid)
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const state = computed(() => {
|
|
250
|
+
if (!taskRuns.value?.length) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (taskRuns.value.length === 1) {
|
|
255
|
+
return taskRuns.value[0].state.current;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const allStates = taskRuns.value.map((t: TaskRun) => t.state.current);
|
|
259
|
+
|
|
260
|
+
// Create a copy of SORT_STATUS array to avoid modifying the original
|
|
261
|
+
const SORT_STATUS = [
|
|
262
|
+
State.FAILED,
|
|
263
|
+
State.KILLED,
|
|
264
|
+
State.WARNING,
|
|
265
|
+
State.SKIPPED,
|
|
266
|
+
State.KILLING,
|
|
267
|
+
State.RUNNING,
|
|
268
|
+
State.SUCCESS,
|
|
269
|
+
State.RESTARTED,
|
|
270
|
+
State.CREATED,
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
// Sort states based on priority
|
|
274
|
+
const result = allStates
|
|
275
|
+
.map((item: [string, string]) => {
|
|
276
|
+
const n = SORT_STATUS.indexOf(item[1]);
|
|
277
|
+
// Handle sorting without modifying the original array
|
|
278
|
+
return [n, item] as [number, [string, string]];
|
|
279
|
+
})
|
|
280
|
+
.sort()
|
|
281
|
+
.map((j: [number, [string, string]]) => j[1]);
|
|
282
|
+
|
|
283
|
+
return result[0];
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const classes = computed(() => ({
|
|
287
|
+
"execution-no-taskrun":
|
|
288
|
+
Boolean(taskExecution.value && taskRuns.value && taskRuns.value.length === 0)
|
|
289
|
+
}));
|
|
290
|
+
|
|
291
|
+
const expandData = computed<ExpandData>(() => ({
|
|
292
|
+
id: props.id,
|
|
293
|
+
type: String(props.data.node.task.type)
|
|
294
|
+
}));
|
|
295
|
+
|
|
296
|
+
const dataWithLink = computed(() => {
|
|
297
|
+
if (props.data.node.type?.endsWith("SubflowGraphTask") && props.enableSubflowInteraction) {
|
|
298
|
+
const subflowIdContainer = props.data.node.task.subflowId ?? props.data.node.task;
|
|
299
|
+
return {
|
|
300
|
+
...props.data,
|
|
301
|
+
link: {
|
|
302
|
+
namespace: subflowIdContainer.namespace,
|
|
303
|
+
id: subflowIdContainer.flowId,
|
|
304
|
+
executionId: taskExecution.value?.taskRunList
|
|
305
|
+
.filter((taskRun: TaskRun) =>
|
|
306
|
+
taskRun.taskId === props.data.node.task.id &&
|
|
307
|
+
taskRun.outputs?.executionId
|
|
308
|
+
)
|
|
309
|
+
?.[0]?.outputs?.executionId
|
|
210
310
|
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return props.data;
|
|
314
|
+
});
|
|
211
315
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
emits: [
|
|
216
|
-
EVENTS.EXPAND,
|
|
217
|
-
EVENTS.OPEN_LINK,
|
|
218
|
-
EVENTS.SHOW_LOGS,
|
|
219
|
-
EVENTS.MOUSE_OVER,
|
|
220
|
-
EVENTS.MOUSE_LEAVE,
|
|
221
|
-
EVENTS.ADD_ERROR,
|
|
222
|
-
EVENTS.EDIT,
|
|
223
|
-
EVENTS.DELETE,
|
|
224
|
-
EVENTS.ADD_TASK,
|
|
225
|
-
EVENTS.SHOW_CONDITION
|
|
226
|
-
],
|
|
227
|
-
props: {
|
|
228
|
-
data: {
|
|
229
|
-
type: Object,
|
|
230
|
-
required: true,
|
|
231
|
-
},
|
|
232
|
-
sourcePosition: {
|
|
233
|
-
type: String,
|
|
234
|
-
required: true
|
|
235
|
-
},
|
|
236
|
-
targetPosition: {
|
|
237
|
-
type: String,
|
|
238
|
-
required: true
|
|
239
|
-
},
|
|
240
|
-
id: {
|
|
241
|
-
type: String,
|
|
242
|
-
required: true
|
|
243
|
-
},
|
|
244
|
-
icons: {
|
|
245
|
-
type: Object,
|
|
246
|
-
default: undefined
|
|
247
|
-
},
|
|
248
|
-
iconComponent: {
|
|
249
|
-
type: Object,
|
|
250
|
-
default: undefined
|
|
251
|
-
},
|
|
252
|
-
enableSubflowInteraction: {
|
|
253
|
-
type: Boolean,
|
|
254
|
-
default: true
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
methods: {
|
|
258
|
-
forwardEvent(event, payload) {
|
|
259
|
-
this.$emit(event, payload)
|
|
260
|
-
},
|
|
316
|
+
const iconAlt = computed(() => {
|
|
317
|
+
if(state.value === State.RUNNING){
|
|
318
|
+
return "task is running";
|
|
261
319
|
}
|
|
262
|
-
|
|
320
|
+
if(state.value === State.SUCCESS){
|
|
321
|
+
return "task was successful";
|
|
322
|
+
}
|
|
323
|
+
if(state.value === State.WARNING){
|
|
324
|
+
return "task sent a warning";
|
|
325
|
+
}
|
|
326
|
+
if(state.value === State.SKIPPED){
|
|
327
|
+
return "task was skipped";
|
|
328
|
+
}
|
|
329
|
+
if(state.value === State.FAILED){
|
|
330
|
+
return "task failed";
|
|
331
|
+
}
|
|
332
|
+
return "";
|
|
333
|
+
});
|
|
263
334
|
</script>
|
|
264
335
|
|
|
265
336
|
<style lang="scss" scoped>
|
|
@@ -271,13 +342,18 @@
|
|
|
271
342
|
right: 0;
|
|
272
343
|
z-index: 1;
|
|
273
344
|
border: none;
|
|
274
|
-
background:
|
|
275
|
-
background-color: _color-palette.$base-blue-500;
|
|
276
|
-
color: _color-palette.$base-white;
|
|
345
|
+
background-color: var(--ks-background-card);
|
|
277
346
|
border-radius: 3px;
|
|
278
347
|
height: 1rem;
|
|
279
348
|
width: 1rem;
|
|
280
|
-
padding:
|
|
281
|
-
margin: 6px
|
|
349
|
+
padding: .1rem;
|
|
350
|
+
margin: 6px;
|
|
351
|
+
font-size: .8rem;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
button.playground-button,
|
|
355
|
+
.dark button.playground-button {
|
|
356
|
+
color: _color-palette.$base-white;
|
|
357
|
+
background-color: _color-palette.$base-blue-400;
|
|
282
358
|
}
|
|
283
359
|
</style>
|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
v-bind="taskProps"
|
|
29
29
|
:icons="icons"
|
|
30
30
|
:icon-component="iconComponent"
|
|
31
|
+
:playground-enabled="playgroundEnabled"
|
|
32
|
+
:playground-ready-to-start="playgroundReadyToStart"
|
|
31
33
|
@edit="emit(EVENTS.EDIT, $event)"
|
|
32
34
|
@delete="emit(EVENTS.DELETE, $event)"
|
|
33
35
|
@run-task="emit(EVENTS.RUN_TASK, $event)"
|
|
@@ -91,6 +93,7 @@
|
|
|
91
93
|
</Controls>
|
|
92
94
|
</VueFlow>
|
|
93
95
|
</template>
|
|
96
|
+
|
|
94
97
|
<script lang="ts" setup>
|
|
95
98
|
import {computed, nextTick, onMounted, PropType, provide, ref, watch} from "vue";
|
|
96
99
|
import {useVueFlow, VueFlow, XYPosition} from "@vue-flow/core";
|
|
@@ -102,7 +105,6 @@
|
|
|
102
105
|
import DotNode from "../nodes/DotNode.vue";
|
|
103
106
|
// @ts-expect-error no types for internals necessary
|
|
104
107
|
import EdgeNode from "../nodes/EdgeNode.vue";
|
|
105
|
-
// @ts-expect-error no types for internals necessary
|
|
106
108
|
import TaskNode from "../nodes/TaskNode.vue";
|
|
107
109
|
// @ts-expect-error no types for internals necessary
|
|
108
110
|
import TriggerNode from "../nodes/TriggerNode.vue"
|
|
@@ -119,7 +121,7 @@
|
|
|
119
121
|
import * as VueFlowUtils from "../../utils/VueFlowUtils";
|
|
120
122
|
import {isParentChildrenRelation, swapBlocks} from "../../utils/FlowYamlUtils";
|
|
121
123
|
import {useScreenshot} from "./export/useScreenshot";
|
|
122
|
-
import {EXECUTION_INJECTION_KEY, SUBFLOWS_EXECUTIONS_INJECTION_KEY
|
|
124
|
+
import {EXECUTION_INJECTION_KEY, SUBFLOWS_EXECUTIONS_INJECTION_KEY} from "./injectionKeys";
|
|
123
125
|
|
|
124
126
|
const props = defineProps({
|
|
125
127
|
id: {
|
|
@@ -186,6 +188,10 @@
|
|
|
186
188
|
playgroundEnabled: {
|
|
187
189
|
type: Boolean,
|
|
188
190
|
default: false
|
|
191
|
+
},
|
|
192
|
+
playgroundReadyToStart: {
|
|
193
|
+
type: Boolean,
|
|
194
|
+
default: false
|
|
189
195
|
}
|
|
190
196
|
});
|
|
191
197
|
|
|
@@ -200,7 +206,6 @@
|
|
|
200
206
|
|
|
201
207
|
provide(EXECUTION_INJECTION_KEY, computed(() => props.execution));
|
|
202
208
|
provide(SUBFLOWS_EXECUTIONS_INJECTION_KEY, computed(() => props.subflowsExecutions));
|
|
203
|
-
provide(PLAYGROUND_ENABLED_INJECTION_KEY, computed(() => props.playgroundEnabled));
|
|
204
209
|
|
|
205
210
|
|
|
206
211
|
const emit = defineEmits(
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type {ComputedRef, InjectionKey} 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[]>>>
|
|
5
|
-
export const PLAYGROUND_ENABLED_INJECTION_KEY = Symbol("playground-enabled-injection-key") as InjectionKey<ComputedRef<boolean>>
|
|
4
|
+
export const SUBFLOWS_EXECUTIONS_INJECTION_KEY = Symbol("subflows-executions-injection-key") as InjectionKey<ComputedRef<Record<string, any[]>>>
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export {default as getMDCParser} from "./composables/getMDCParser";
|
|
|
7
7
|
export * from "./utils/constants";
|
|
8
8
|
export * from "./utils/url";
|
|
9
9
|
export * from "./utils/plugins";
|
|
10
|
+
export {default as RotatingDotsIcon} from "./assets/icons/RotatingDots.vue";
|
|
10
11
|
|
|
11
12
|
export type {YamlElement} from "./utils/YamlUtilsLegacy";
|
|
12
13
|
export type {Plugin} from "./utils/plugins";
|
|
@@ -1634,4 +1634,15 @@ describe("get lines infos", () => {
|
|
|
1634
1634
|
expect(tasksLines).to.containSubset({when_true: {start: 7, end: 9}});
|
|
1635
1635
|
expect(tasksLines).to.containSubset({when_false: {start: 11, end: 13}});
|
|
1636
1636
|
})
|
|
1637
|
+
test("if a task ends on the last line, it should be included", () => {
|
|
1638
|
+
const yamlString = `# this count as an empty line
|
|
1639
|
+
tasks:
|
|
1640
|
+
- id: plugin1
|
|
1641
|
+
type: type1
|
|
1642
|
+
name: Plugin 1
|
|
1643
|
+
extrafield: Extra field 1`;
|
|
1644
|
+
|
|
1645
|
+
const tasksLines = YamlUtils.getTasksLines(yamlString);
|
|
1646
|
+
expect(tasksLines).to.containSubset({plugin1: {start: 3, end: 6}});
|
|
1647
|
+
})
|
|
1637
1648
|
});
|
|
@@ -1223,9 +1223,13 @@ export function getChartAtPosition(source: string, position: { lineNumber: numbe
|
|
|
1223
1223
|
export function getTasksLines(
|
|
1224
1224
|
source: string
|
|
1225
1225
|
):Record<string, {start: number, end: number}> {
|
|
1226
|
-
|
|
1226
|
+
// if a task ends on the last line of the YAML,
|
|
1227
|
+
// its end range will be one line off.
|
|
1228
|
+
// To avoid this specific case, we add a newline at the end of the source.
|
|
1229
|
+
const paddedSource = source + "\n";
|
|
1230
|
+
const yamlDoc = parseDocument(paddedSource) as any;
|
|
1227
1231
|
const lineCounter = new LineCounter();
|
|
1228
|
-
parseDocument(
|
|
1232
|
+
parseDocument(paddedSource, {lineCounter});
|
|
1229
1233
|
|
|
1230
1234
|
let tasksLines: Record<string, {start: number, end: number}> = {};
|
|
1231
1235
|
visit(yamlDoc, {
|
|
@@ -1237,7 +1241,10 @@ export function getTasksLines(
|
|
|
1237
1241
|
for (const task of item.value.items) {
|
|
1238
1242
|
if(isMap(task)){
|
|
1239
1243
|
const foundChilTasksLines = getTasksAndFlowableLines(lineCounter, task);
|
|
1240
|
-
tasksLines = {
|
|
1244
|
+
tasksLines = {
|
|
1245
|
+
...tasksLines,
|
|
1246
|
+
...foundChilTasksLines
|
|
1247
|
+
}
|
|
1241
1248
|
}
|
|
1242
1249
|
}
|
|
1243
1250
|
}
|
|
@@ -1249,12 +1256,16 @@ export function getTasksLines(
|
|
|
1249
1256
|
});
|
|
1250
1257
|
return tasksLines;
|
|
1251
1258
|
}
|
|
1252
|
-
|
|
1259
|
+
|
|
1260
|
+
function getTasksAndFlowableLines(lineCounter: LineCounter, task: YAMLMap) {
|
|
1253
1261
|
let tasksLines: Record<string, {start: number, end: number}> = {};
|
|
1254
1262
|
const taskId = task.get("id") as string | undefined;
|
|
1255
1263
|
if(taskId){
|
|
1256
1264
|
if(task.range) {
|
|
1257
|
-
tasksLines[taskId] = {
|
|
1265
|
+
tasksLines[taskId] = {
|
|
1266
|
+
start: lineCounter.linePos(task.range[0]).line,
|
|
1267
|
+
end: lineCounter.linePos(task.range[1]).line - 1
|
|
1268
|
+
}
|
|
1258
1269
|
}
|
|
1259
1270
|
const childTasks = new YAMLSeq<YAMLMap>();
|
|
1260
1271
|
const tasksChilds = task.get("tasks") as YAMLSeq<YAMLMap> | undefined;
|