@nvent-addon/app 0.5.4 → 0.5.6
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/module.json +1 -1
- package/dist/module.mjs +9 -1
- package/dist/runtime/app/components/ComponentShell.d.vue.ts +1 -0
- package/dist/runtime/app/components/ComponentShell.vue +13 -3
- package/dist/runtime/app/components/ComponentShell.vue.d.ts +1 -0
- package/dist/runtime/app/components/DashboardCard.d.vue.ts +15 -0
- package/dist/runtime/app/components/DashboardCard.vue +76 -0
- package/dist/runtime/app/components/DashboardCard.vue.d.ts +15 -0
- package/dist/runtime/app/components/TimelineList.vue +222 -31
- package/dist/runtime/app/components/flow/AwaitNode.d.vue.ts +19 -2
- package/dist/runtime/app/components/flow/AwaitNode.vue +317 -29
- package/dist/runtime/app/components/flow/AwaitNode.vue.d.ts +19 -2
- package/dist/runtime/app/components/flow/Diagram.d.vue.ts +2 -1
- package/dist/runtime/app/components/flow/Diagram.vue +138 -74
- package/dist/runtime/app/components/flow/Diagram.vue.d.ts +2 -1
- package/dist/runtime/app/components/flow/NodeCard.d.vue.ts +14 -11
- package/dist/runtime/app/components/flow/NodeCard.vue +119 -35
- package/dist/runtime/app/components/flow/NodeCard.vue.d.ts +14 -11
- package/dist/runtime/app/components/flow/RunOverview.d.vue.ts +1 -0
- package/dist/runtime/app/components/flow/RunOverview.vue +85 -86
- package/dist/runtime/app/components/flow/RunOverview.vue.d.ts +1 -0
- package/dist/runtime/app/components/flow/RunTimeline.vue +51 -22
- package/dist/runtime/app/components/flow/StepSelector.vue +124 -46
- package/dist/runtime/app/composables/useFlowRunTimeline.d.ts +6 -0
- package/dist/runtime/app/composables/useFlowState.d.ts +8 -1
- package/dist/runtime/app/composables/useFlowState.js +34 -59
- package/dist/runtime/app/pages/dashboard.vue +51 -103
- package/dist/runtime/app/pages/flows/[name].vue +26 -3
- package/dist/runtime/app/pages/triggers/[name]/edit.vue +1 -1
- package/package.json +1 -1
|
@@ -1,83 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="flex flex-col h-full w-full max-w-full min-w-0">
|
|
3
3
|
<!-- Fixed Header with Run Stats -->
|
|
4
|
-
<div class="px-6 py-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<div class="flex items-center gap-1.5">
|
|
9
|
-
<div
|
|
10
|
-
class="w-1.5 h-1.5 rounded-full"
|
|
11
|
-
:class="getStatusColor(runStatus)"
|
|
12
|
-
/>
|
|
13
|
-
<span class="text-gray-700 dark:text-gray-300 font-medium capitalize">
|
|
14
|
-
{{ runStatus || "unknown" }}
|
|
15
|
-
</span>
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<!-- Divider -->
|
|
19
|
-
<div class="w-px h-3 bg-gray-300 dark:bg-gray-700" />
|
|
20
|
-
|
|
21
|
-
<!-- Entry Trigger -->
|
|
4
|
+
<div class="h-[72px] px-6 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50 shrink-0">
|
|
5
|
+
<!-- Top Row: Status and Action -->
|
|
6
|
+
<div class="flex items-center justify-between gap-4 mb-2">
|
|
7
|
+
<div class="flex items-center gap-2">
|
|
22
8
|
<div
|
|
9
|
+
class="w-2 h-2 rounded-full"
|
|
10
|
+
:class="getStatusColor(runStatus)"
|
|
11
|
+
/>
|
|
12
|
+
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100 capitalize">
|
|
13
|
+
{{ runStatus || "unknown" }}
|
|
14
|
+
</span>
|
|
15
|
+
<span
|
|
23
16
|
v-if="triggerName"
|
|
24
|
-
class="
|
|
17
|
+
class="text-xs text-gray-500 dark:text-gray-400 ml-1"
|
|
25
18
|
>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class="w-3 h-3 text-gray-500"
|
|
29
|
-
/>
|
|
30
|
-
<span class="text-gray-700 dark:text-gray-300">
|
|
31
|
-
{{ triggerName }}
|
|
32
|
-
</span>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<!-- Divider -->
|
|
36
|
-
<div class="w-px h-3 bg-gray-300 dark:bg-gray-700" />
|
|
37
|
-
|
|
38
|
-
<!-- Total Steps -->
|
|
39
|
-
<div class="flex items-center gap-1.5">
|
|
40
|
-
<UIcon
|
|
41
|
-
name="i-lucide-layers"
|
|
42
|
-
class="w-3 h-3 text-gray-500"
|
|
43
|
-
/>
|
|
44
|
-
<span class="text-gray-700 dark:text-gray-300">
|
|
45
|
-
{{ steps.length }} {{ steps.length === 1 ? "step" : "steps" }}
|
|
46
|
-
</span>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<!-- Divider -->
|
|
50
|
-
<div class="w-px h-3 bg-gray-300 dark:bg-gray-700" />
|
|
51
|
-
|
|
52
|
-
<!-- Started -->
|
|
53
|
-
<div class="flex items-center gap-1.5">
|
|
54
|
-
<UIcon
|
|
55
|
-
name="i-lucide-clock"
|
|
56
|
-
class="w-3 h-3 text-gray-500"
|
|
57
|
-
/>
|
|
58
|
-
<span class="text-gray-600 dark:text-gray-400">
|
|
59
|
-
{{ startedAt ? formatTime(startedAt) : "Not started" }}
|
|
60
|
-
</span>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<!-- Divider -->
|
|
64
|
-
<div class="w-px h-3 bg-gray-300 dark:bg-gray-700" />
|
|
65
|
-
|
|
66
|
-
<!-- Duration -->
|
|
67
|
-
<div class="flex items-center gap-1.5">
|
|
68
|
-
<UIcon
|
|
69
|
-
name="i-lucide-timer"
|
|
70
|
-
class="w-3 h-3 text-gray-500"
|
|
71
|
-
/>
|
|
72
|
-
<span class="text-gray-600 dark:text-gray-400">
|
|
73
|
-
{{ getDuration(startedAt, completedAt) }}
|
|
74
|
-
</span>
|
|
75
|
-
</div>
|
|
19
|
+
via {{ triggerName }}
|
|
20
|
+
</span>
|
|
76
21
|
</div>
|
|
77
22
|
|
|
78
|
-
<!-- Cancel Button (only show for running flows) -->
|
|
23
|
+
<!-- Cancel Button (only show for running/awaiting flows) -->
|
|
79
24
|
<UButton
|
|
80
|
-
v-if="runStatus === 'running'"
|
|
25
|
+
v-if="runStatus === 'running' || runStatus === 'awaiting'"
|
|
81
26
|
color="neutral"
|
|
82
27
|
variant="ghost"
|
|
83
28
|
icon="i-lucide-x-circle"
|
|
@@ -86,6 +31,56 @@
|
|
|
86
31
|
@click="handleCancelFlow"
|
|
87
32
|
/>
|
|
88
33
|
</div>
|
|
34
|
+
|
|
35
|
+
<!-- Bottom Row: Compact Stats Grid -->
|
|
36
|
+
<div class="grid grid-cols-2 sm:grid-cols-4 gap-x-4 gap-y-1.5 text-xs">
|
|
37
|
+
<!-- Steps -->
|
|
38
|
+
<div class="flex items-center gap-1.5">
|
|
39
|
+
<UIcon
|
|
40
|
+
name="i-lucide-layers"
|
|
41
|
+
class="w-3.5 h-3.5 text-gray-400"
|
|
42
|
+
/>
|
|
43
|
+
<span class="text-gray-600 dark:text-gray-300">
|
|
44
|
+
{{ steps.length }} {{ steps.length === 1 ? "step" : "steps" }}
|
|
45
|
+
</span>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<!-- Started -->
|
|
49
|
+
<div class="flex items-center gap-1.5">
|
|
50
|
+
<UIcon
|
|
51
|
+
name="i-lucide-clock"
|
|
52
|
+
class="w-3.5 h-3.5 text-gray-400"
|
|
53
|
+
/>
|
|
54
|
+
<span class="text-gray-600 dark:text-gray-300">
|
|
55
|
+
{{ startedAt ? formatTime(startedAt) : "Not started" }}
|
|
56
|
+
</span>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<!-- Duration -->
|
|
60
|
+
<div class="flex items-center gap-1.5">
|
|
61
|
+
<UIcon
|
|
62
|
+
name="i-lucide-timer"
|
|
63
|
+
class="w-3.5 h-3.5 text-gray-400"
|
|
64
|
+
/>
|
|
65
|
+
<span class="text-gray-600 dark:text-gray-300">
|
|
66
|
+
{{ getDuration(startedAt, completedAt) }}
|
|
67
|
+
</span>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<!-- Stall Warning (for running/awaiting flows) -->
|
|
71
|
+
<div
|
|
72
|
+
v-if="(runStatus === 'running' || runStatus === 'awaiting') && stallTimeout"
|
|
73
|
+
class="flex items-center gap-1.5"
|
|
74
|
+
>
|
|
75
|
+
<UIcon
|
|
76
|
+
name="i-lucide-alert-triangle"
|
|
77
|
+
class="w-3.5 h-3.5 text-amber-500"
|
|
78
|
+
/>
|
|
79
|
+
<span class="text-gray-600 dark:text-gray-300">
|
|
80
|
+
Stall in {{ formatStallTimeout(startedAt, stallTimeout) }}
|
|
81
|
+
</span>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
89
84
|
</div>
|
|
90
85
|
|
|
91
86
|
<!-- Scrollable Steps List -->
|
|
@@ -122,14 +117,15 @@ const props = defineProps({
|
|
|
122
117
|
runId: { type: String, required: false },
|
|
123
118
|
triggerName: { type: String, required: false },
|
|
124
119
|
triggerType: { type: String, required: false },
|
|
125
|
-
flowDef: { type: null, required: false }
|
|
120
|
+
flowDef: { type: null, required: false },
|
|
121
|
+
stallTimeout: { type: Number, required: false }
|
|
126
122
|
});
|
|
127
123
|
const emit = defineEmits(["select-step", "cancel-flow"]);
|
|
128
124
|
const handleCancelFlow = () => {
|
|
129
125
|
emit("cancel-flow");
|
|
130
126
|
};
|
|
131
127
|
const selectedStep = ref("all-steps");
|
|
132
|
-
const firstStepKey = computed(() => props.steps[0]?.key);
|
|
128
|
+
const firstStepKey = computed(() => props.steps?.length > 0 ? props.steps[0]?.key : void 0);
|
|
133
129
|
watch(firstStepKey, (newKey, oldKey) => {
|
|
134
130
|
if (oldKey !== void 0 && newKey !== oldKey) {
|
|
135
131
|
selectedStep.value = "all-steps";
|
|
@@ -248,6 +244,8 @@ const getStatusColor = (status) => {
|
|
|
248
244
|
return "bg-red-500";
|
|
249
245
|
case "running":
|
|
250
246
|
return "bg-blue-500 animate-pulse";
|
|
247
|
+
case "awaiting":
|
|
248
|
+
return "bg-purple-500 animate-pulse";
|
|
251
249
|
case "canceled":
|
|
252
250
|
return "bg-orange-500";
|
|
253
251
|
case "stalled":
|
|
@@ -256,18 +254,19 @@ const getStatusColor = (status) => {
|
|
|
256
254
|
return "bg-gray-300";
|
|
257
255
|
}
|
|
258
256
|
};
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
257
|
+
const formatStallTimeout = (start, timeout) => {
|
|
258
|
+
if (!start || !timeout) return "\u2014";
|
|
259
|
+
const startTime = new Date(start).getTime();
|
|
260
|
+
const stallTime = startTime + timeout;
|
|
261
|
+
const remaining = stallTime - Date.now();
|
|
262
|
+
if (remaining <= 0) return "now";
|
|
263
|
+
const seconds = Math.floor(remaining / 1e3);
|
|
264
|
+
const minutes = Math.floor(seconds / 60);
|
|
265
|
+
const hours = Math.floor(minutes / 60);
|
|
266
|
+
const days = Math.floor(hours / 24);
|
|
267
|
+
if (days > 0) return `${days}d ${hours % 24}h`;
|
|
268
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m`;
|
|
269
|
+
if (minutes > 0) return `${minutes}m`;
|
|
270
|
+
return `${seconds}s`;
|
|
272
271
|
};
|
|
273
272
|
</script>
|
|
@@ -8,6 +8,7 @@ type __VLS_Props = {
|
|
|
8
8
|
triggerName?: string;
|
|
9
9
|
triggerType?: 'manual' | 'event' | 'webhook' | 'schedule';
|
|
10
10
|
flowDef?: any;
|
|
11
|
+
stallTimeout?: number;
|
|
11
12
|
};
|
|
12
13
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
14
|
"select-step": (stepKey: string | null) => any;
|
|
@@ -1,36 +1,65 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="flex flex-col h-full">
|
|
3
3
|
<!-- Filter Bar -->
|
|
4
|
-
<div class="
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
4
|
+
<div class="h-[72px] px-6 py-3 border-b border-gray-200 dark:border-gray-800 bg-gray-50 dark:bg-gray-900/50 shrink-0">
|
|
5
|
+
<!-- Top Row: Title and Action -->
|
|
6
|
+
<div class="flex items-center justify-between gap-4 mb-2">
|
|
7
|
+
<div class="flex items-center gap-2">
|
|
8
|
+
<UIcon
|
|
9
|
+
name="i-lucide-activity"
|
|
10
|
+
class="w-4 h-4 text-gray-400"
|
|
11
|
+
/>
|
|
12
|
+
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
13
|
+
Timeline & Logs
|
|
14
|
+
</span>
|
|
15
|
+
<span
|
|
16
|
+
v-if="isLive"
|
|
17
|
+
class="flex items-center gap-1.5 ml-2"
|
|
18
|
+
>
|
|
19
|
+
<div class="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse" />
|
|
20
|
+
<span class="text-xs text-gray-500 dark:text-gray-400">Live</span>
|
|
21
|
+
</span>
|
|
22
|
+
</div>
|
|
21
23
|
|
|
22
|
-
<div class="flex items-center gap-2 ml-auto">
|
|
23
24
|
<UButton
|
|
24
25
|
size="xs"
|
|
25
26
|
color="neutral"
|
|
26
|
-
variant="
|
|
27
|
+
variant="ghost"
|
|
28
|
+
icon="i-lucide-download"
|
|
27
29
|
:disabled="filteredItems.length === 0"
|
|
28
30
|
@click="$emit('export')"
|
|
29
31
|
>
|
|
30
|
-
Export
|
|
32
|
+
Export
|
|
31
33
|
</UButton>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Bottom Row: Filter and Count -->
|
|
37
|
+
<div class="flex items-center justify-between gap-4 text-[11px]">
|
|
38
|
+
<div class="flex items-center gap-1.5">
|
|
39
|
+
<span class="text-gray-500 dark:text-gray-400">Filter:</span>
|
|
40
|
+
<URadioGroup
|
|
41
|
+
v-model="filter"
|
|
42
|
+
:items="filterOptions"
|
|
43
|
+
orientation="horizontal"
|
|
44
|
+
size="xs"
|
|
45
|
+
variant="table"
|
|
46
|
+
indicator="hidden"
|
|
47
|
+
:ui="{
|
|
48
|
+
base: 'text-[9px]',
|
|
49
|
+
container: 'gap-0',
|
|
50
|
+
item: 'px-1 py-0'
|
|
51
|
+
}"
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="flex items-center gap-1.5">
|
|
56
|
+
<UIcon
|
|
57
|
+
name="i-lucide-list"
|
|
58
|
+
class="w-3.5 h-3.5 text-gray-400"
|
|
59
|
+
/>
|
|
60
|
+
<span class="text-gray-600 dark:text-gray-300">
|
|
61
|
+
{{ filteredItems.length }} {{ filteredItems.length === 1 ? "item" : "items" }}
|
|
62
|
+
</span>
|
|
34
63
|
</div>
|
|
35
64
|
</div>
|
|
36
65
|
</div>
|
|
@@ -78,6 +78,18 @@
|
|
|
78
78
|
>
|
|
79
79
|
{{ getAwaitPosition(item.step.key) }}
|
|
80
80
|
</UBadge>
|
|
81
|
+
<!-- Step Timeout Badge (only for regular steps, not await steps) -->
|
|
82
|
+
<span
|
|
83
|
+
v-if="item.step.stepTimeout && !isAwaitStep(item.step.key)"
|
|
84
|
+
class="flex items-center gap-1"
|
|
85
|
+
:title="`Step Execution Timeout: ${formatDuration(item.step.stepTimeout)}`"
|
|
86
|
+
>
|
|
87
|
+
<UIcon
|
|
88
|
+
name="i-lucide-hourglass"
|
|
89
|
+
class="w-3 h-3 opacity-60"
|
|
90
|
+
/>
|
|
91
|
+
<span>{{ formatDuration(item.step.stepTimeout) }}</span>
|
|
92
|
+
</span>
|
|
81
93
|
</div>
|
|
82
94
|
<div
|
|
83
95
|
v-else
|
|
@@ -141,7 +153,7 @@
|
|
|
141
153
|
|
|
142
154
|
<!-- Await Config Details -->
|
|
143
155
|
<div
|
|
144
|
-
v-if="item.step.awaitType"
|
|
156
|
+
v-if="item.step.awaitType && (item.step.awaitConfig || item.step.awaitData)"
|
|
145
157
|
class="mt-2 p-2.5 rounded-md border"
|
|
146
158
|
:class="getAwaitConfigBgClass(item.step.status)"
|
|
147
159
|
>
|
|
@@ -165,119 +177,174 @@
|
|
|
165
177
|
<div class="space-y-1.5 text-xs">
|
|
166
178
|
<!-- Webhook specific -->
|
|
167
179
|
<div
|
|
168
|
-
v-if="item.step.awaitType === 'webhook'
|
|
180
|
+
v-if="item.step.awaitType === 'webhook'"
|
|
169
181
|
class="space-y-1"
|
|
170
182
|
>
|
|
171
183
|
<div
|
|
172
|
-
v-if="item.step.awaitConfig.method"
|
|
184
|
+
v-if="item.step.awaitConfig?.method || item.step.awaitData?.method"
|
|
173
185
|
class="flex items-center gap-1.5"
|
|
174
186
|
>
|
|
175
187
|
<UIcon
|
|
176
|
-
name="i-lucide-
|
|
188
|
+
name="i-lucide-git-branch"
|
|
177
189
|
class="w-3 h-3 opacity-60"
|
|
178
190
|
/>
|
|
179
191
|
<span class="opacity-75">Method:</span>
|
|
180
192
|
<UBadge
|
|
181
193
|
size="xs"
|
|
182
|
-
:color="getMethodBadgeColor(item.step.awaitConfig
|
|
194
|
+
:color="getMethodBadgeColor(item.step.awaitData?.method || item.step.awaitConfig?.method)"
|
|
183
195
|
variant="subtle"
|
|
184
196
|
>
|
|
185
|
-
{{ item.step.awaitConfig
|
|
197
|
+
{{ item.step.awaitData?.method || item.step.awaitConfig?.method }}
|
|
186
198
|
</UBadge>
|
|
187
199
|
</div>
|
|
188
200
|
<div
|
|
189
|
-
v-if="item.step.
|
|
201
|
+
v-if="item.step.awaitData?.webhookUrl"
|
|
190
202
|
class="flex items-start gap-1.5"
|
|
191
203
|
>
|
|
192
204
|
<UIcon
|
|
193
205
|
name="i-lucide-link"
|
|
194
206
|
class="w-3 h-3 opacity-60 mt-0.5"
|
|
195
207
|
/>
|
|
196
|
-
<span class="opacity-75">
|
|
197
|
-
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px] flex-1">{{ item.step.awaitConfig.path }}</code>
|
|
198
|
-
</div>
|
|
199
|
-
<div
|
|
200
|
-
v-if="item.step.webhookUrl"
|
|
201
|
-
class="flex items-start gap-1.5 pt-1"
|
|
202
|
-
>
|
|
203
|
-
<UIcon
|
|
204
|
-
name="i-lucide-globe"
|
|
205
|
-
class="w-3 h-3 opacity-60 mt-1"
|
|
206
|
-
/>
|
|
207
|
-
<span class="opacity-75 mt-0.5">URL:</span>
|
|
208
|
+
<span class="opacity-75">URL:</span>
|
|
208
209
|
<div class="flex-1 flex items-start gap-1">
|
|
209
|
-
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px] flex-1 break-all">{{ item.step.webhookUrl }}</code>
|
|
210
|
+
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px] flex-1 break-all">{{ item.step.awaitData.webhookUrl }}</code>
|
|
210
211
|
<button
|
|
211
212
|
type="button"
|
|
212
213
|
class="flex-shrink-0 p-1 hover:bg-black/5 dark:hover:bg-white/5 rounded transition-colors"
|
|
213
|
-
:title="copiedUrl === item.step.webhookUrl ? 'Copied!' : 'Copy URL'"
|
|
214
|
-
@click.stop="copyToClipboard(item.step.webhookUrl)"
|
|
214
|
+
:title="copiedUrl === item.step.awaitData.webhookUrl ? 'Copied!' : 'Copy URL'"
|
|
215
|
+
@click.stop="copyToClipboard(item.step.awaitData.webhookUrl)"
|
|
215
216
|
>
|
|
216
217
|
<UIcon
|
|
217
|
-
:name="copiedUrl === item.step.webhookUrl ? 'i-lucide-check' : 'i-lucide-copy'"
|
|
218
|
+
:name="copiedUrl === item.step.awaitData.webhookUrl ? 'i-lucide-check' : 'i-lucide-copy'"
|
|
218
219
|
class="w-3 h-3"
|
|
219
|
-
:class="copiedUrl === item.step.webhookUrl ? 'text-emerald-600 dark:text-emerald-400' : 'opacity-60'"
|
|
220
|
+
:class="copiedUrl === item.step.awaitData.webhookUrl ? 'text-emerald-600 dark:text-emerald-400' : 'opacity-60'"
|
|
220
221
|
/>
|
|
221
222
|
</button>
|
|
222
223
|
</div>
|
|
223
224
|
</div>
|
|
225
|
+
<div
|
|
226
|
+
v-else-if="item.step.awaitConfig?.path"
|
|
227
|
+
class="flex items-start gap-1.5"
|
|
228
|
+
>
|
|
229
|
+
<UIcon
|
|
230
|
+
name="i-lucide-route"
|
|
231
|
+
class="w-3 h-3 opacity-60 mt-0.5"
|
|
232
|
+
/>
|
|
233
|
+
<span class="opacity-75">Path:</span>
|
|
234
|
+
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px] flex-1">{{ item.step.awaitConfig.path }}</code>
|
|
235
|
+
</div>
|
|
224
236
|
</div>
|
|
225
237
|
|
|
226
238
|
<!-- Event specific -->
|
|
227
239
|
<div
|
|
228
|
-
v-if="item.step.awaitType === 'event'
|
|
229
|
-
class="
|
|
240
|
+
v-if="item.step.awaitType === 'event'"
|
|
241
|
+
class="space-y-1"
|
|
230
242
|
>
|
|
231
|
-
<
|
|
232
|
-
|
|
233
|
-
class="
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
<div
|
|
244
|
+
v-if="item.step.awaitConfig?.event || item.step.awaitData?.eventName"
|
|
245
|
+
class="flex items-center gap-1.5"
|
|
246
|
+
>
|
|
247
|
+
<UIcon
|
|
248
|
+
name="i-lucide-zap"
|
|
249
|
+
class="w-3 h-3 opacity-60"
|
|
250
|
+
/>
|
|
251
|
+
<span class="opacity-75">Event:</span>
|
|
252
|
+
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px]">{{ item.step.awaitData?.eventName || item.step.awaitConfig?.event }}</code>
|
|
253
|
+
</div>
|
|
254
|
+
<div
|
|
255
|
+
v-if="item.step.awaitConfig?.filterKey || item.step.awaitData?.filterKey"
|
|
256
|
+
class="flex items-center gap-1.5"
|
|
257
|
+
>
|
|
258
|
+
<UIcon
|
|
259
|
+
name="i-lucide-filter"
|
|
260
|
+
class="w-3 h-3 opacity-60"
|
|
261
|
+
/>
|
|
262
|
+
<span class="opacity-75">Filter:</span>
|
|
263
|
+
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px]">{{ item.step.awaitData?.filterKey || item.step.awaitConfig?.filterKey }}</code>
|
|
264
|
+
</div>
|
|
237
265
|
</div>
|
|
238
266
|
|
|
239
267
|
<!-- Time specific -->
|
|
240
268
|
<div
|
|
241
269
|
v-if="item.step.awaitType === 'time' && item.step.awaitConfig?.delay"
|
|
242
|
-
class="
|
|
270
|
+
class="space-y-1"
|
|
243
271
|
>
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
272
|
+
<div class="flex items-center gap-1.5">
|
|
273
|
+
<UIcon
|
|
274
|
+
name="i-lucide-timer"
|
|
275
|
+
class="w-3 h-3 opacity-60"
|
|
276
|
+
/>
|
|
277
|
+
<span class="opacity-75">Delay:</span>
|
|
278
|
+
<span class="font-medium">{{ formatDuration(item.step.awaitConfig.delay) }}</span>
|
|
279
|
+
</div>
|
|
280
|
+
<div
|
|
281
|
+
v-if="item.step.scheduledTriggerAt"
|
|
282
|
+
class="flex items-center gap-1.5"
|
|
283
|
+
>
|
|
284
|
+
<UIcon
|
|
285
|
+
name="i-lucide-calendar-clock"
|
|
286
|
+
class="w-3 h-3 opacity-60"
|
|
287
|
+
/>
|
|
288
|
+
<span class="opacity-75">Triggers at:</span>
|
|
289
|
+
<span class="font-medium">{{ formatScheduledTime(item.step.scheduledTriggerAt) }}</span>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<!-- Schedule specific -->
|
|
294
|
+
<div
|
|
295
|
+
v-if="item.step.awaitType === 'schedule' && item.step.awaitConfig?.cron"
|
|
296
|
+
class="space-y-1"
|
|
297
|
+
>
|
|
298
|
+
<div class="flex items-center gap-1.5">
|
|
299
|
+
<UIcon
|
|
300
|
+
name="i-lucide-calendar-cog"
|
|
301
|
+
class="w-3 h-3 opacity-60"
|
|
302
|
+
/>
|
|
303
|
+
<span class="opacity-75">Cron:</span>
|
|
304
|
+
<code class="px-1.5 py-0.5 bg-black/5 dark:bg-white/5 rounded text-[10px]">{{ item.step.awaitConfig.cron }}</code>
|
|
305
|
+
</div>
|
|
306
|
+
<div
|
|
307
|
+
v-if="item.step.scheduledTriggerAt"
|
|
308
|
+
class="flex items-center gap-1.5"
|
|
309
|
+
>
|
|
310
|
+
<UIcon
|
|
311
|
+
name="i-lucide-calendar-check"
|
|
312
|
+
class="w-3 h-3 opacity-60"
|
|
313
|
+
/>
|
|
314
|
+
<span class="opacity-75">Next trigger:</span>
|
|
315
|
+
<span class="font-medium">{{ formatScheduledTime(item.step.scheduledTriggerAt) }}</span>
|
|
316
|
+
</div>
|
|
250
317
|
</div>
|
|
251
318
|
|
|
252
319
|
<!-- Timeout -->
|
|
253
320
|
<div
|
|
254
|
-
v-if="item.step.awaitConfig?.timeout"
|
|
321
|
+
v-if="item.step.awaitConfig?.timeout || item.step.awaitData?.timeout"
|
|
255
322
|
class="flex items-center gap-1.5"
|
|
256
323
|
>
|
|
257
324
|
<UIcon
|
|
258
|
-
name="i-lucide-
|
|
325
|
+
name="i-lucide-hourglass"
|
|
259
326
|
class="w-3 h-3 opacity-60"
|
|
260
327
|
/>
|
|
261
328
|
<span class="opacity-75">Timeout:</span>
|
|
262
|
-
<span class="font-medium">{{ formatDuration(item.step.awaitConfig
|
|
329
|
+
<span class="font-medium">{{ formatDuration(item.step.awaitData?.timeout || item.step.awaitConfig?.timeout) }}</span>
|
|
263
330
|
</div>
|
|
264
331
|
|
|
265
332
|
<!-- Timeout Action -->
|
|
266
333
|
<div
|
|
267
|
-
v-if="item.step.awaitConfig?.timeoutAction"
|
|
334
|
+
v-if="item.step.awaitConfig?.timeoutAction || item.step.awaitData?.timeoutAction"
|
|
268
335
|
class="flex items-center gap-1.5"
|
|
269
336
|
>
|
|
270
337
|
<UIcon
|
|
271
|
-
name="i-lucide-
|
|
338
|
+
name="i-lucide-shield-alert"
|
|
272
339
|
class="w-3 h-3 opacity-60"
|
|
273
340
|
/>
|
|
274
341
|
<span class="opacity-75">On Timeout:</span>
|
|
275
342
|
<UBadge
|
|
276
343
|
size="xs"
|
|
277
|
-
:color="getTimeoutActionColor(item.step.awaitConfig
|
|
344
|
+
:color="getTimeoutActionColor(item.step.awaitData?.timeoutAction || item.step.awaitConfig?.timeoutAction)"
|
|
278
345
|
variant="subtle"
|
|
279
346
|
>
|
|
280
|
-
{{ item.step.awaitConfig
|
|
347
|
+
{{ item.step.awaitData?.timeoutAction || item.step.awaitConfig?.timeoutAction }}
|
|
281
348
|
</UBadge>
|
|
282
349
|
</div>
|
|
283
350
|
</div>
|
|
@@ -549,4 +616,15 @@ const formatDuration = (ms) => {
|
|
|
549
616
|
}
|
|
550
617
|
return `${seconds}s`;
|
|
551
618
|
};
|
|
619
|
+
const formatScheduledTime = (timestamp) => {
|
|
620
|
+
const date = new Date(timestamp);
|
|
621
|
+
if (Number.isNaN(date.getTime())) return "No schedule";
|
|
622
|
+
return date.toLocaleString(void 0, {
|
|
623
|
+
month: "short",
|
|
624
|
+
day: "numeric",
|
|
625
|
+
hour: "2-digit",
|
|
626
|
+
minute: "2-digit",
|
|
627
|
+
timeZoneName: "short"
|
|
628
|
+
});
|
|
629
|
+
};
|
|
552
630
|
</script>
|
|
@@ -19,11 +19,13 @@ export declare function useFlowRunTimeline(flowId: Ref<string>, runId: Ref<strin
|
|
|
19
19
|
isFailed: import("vue").ComputedRef<boolean>;
|
|
20
20
|
isCanceled: import("vue").ComputedRef<boolean>;
|
|
21
21
|
isStalled: import("vue").ComputedRef<boolean>;
|
|
22
|
+
isAwaiting: import("vue").ComputedRef<boolean>;
|
|
22
23
|
stepList: import("vue").ComputedRef<{
|
|
23
24
|
status: "pending" | "running" | "completed" | "failed" | "retrying" | "waiting" | "timeout";
|
|
24
25
|
attempt: number;
|
|
25
26
|
startedAt?: string;
|
|
26
27
|
completedAt?: string;
|
|
28
|
+
scheduledTriggerAt?: string;
|
|
27
29
|
error?: string;
|
|
28
30
|
awaitType?: "time" | "event" | "trigger";
|
|
29
31
|
awaitData?: any;
|
|
@@ -35,6 +37,7 @@ export declare function useFlowRunTimeline(flowId: Ref<string>, runId: Ref<strin
|
|
|
35
37
|
attempt: number;
|
|
36
38
|
startedAt?: string;
|
|
37
39
|
completedAt?: string;
|
|
40
|
+
scheduledTriggerAt?: string;
|
|
38
41
|
error?: string;
|
|
39
42
|
awaitType?: "time" | "event" | "trigger";
|
|
40
43
|
awaitData?: any;
|
|
@@ -46,6 +49,7 @@ export declare function useFlowRunTimeline(flowId: Ref<string>, runId: Ref<strin
|
|
|
46
49
|
attempt: number;
|
|
47
50
|
startedAt?: string;
|
|
48
51
|
completedAt?: string;
|
|
52
|
+
scheduledTriggerAt?: string;
|
|
49
53
|
error?: string;
|
|
50
54
|
awaitType?: "time" | "event" | "trigger";
|
|
51
55
|
awaitData?: any;
|
|
@@ -57,6 +61,7 @@ export declare function useFlowRunTimeline(flowId: Ref<string>, runId: Ref<strin
|
|
|
57
61
|
attempt: number;
|
|
58
62
|
startedAt?: string;
|
|
59
63
|
completedAt?: string;
|
|
64
|
+
scheduledTriggerAt?: string;
|
|
60
65
|
error?: string;
|
|
61
66
|
awaitType?: "time" | "event" | "trigger";
|
|
62
67
|
awaitData?: any;
|
|
@@ -68,6 +73,7 @@ export declare function useFlowRunTimeline(flowId: Ref<string>, runId: Ref<strin
|
|
|
68
73
|
attempt: number;
|
|
69
74
|
startedAt?: string;
|
|
70
75
|
completedAt?: string;
|
|
76
|
+
scheduledTriggerAt?: string;
|
|
71
77
|
error?: string;
|
|
72
78
|
awaitType?: "time" | "event" | "trigger";
|
|
73
79
|
awaitData?: any;
|