@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.
Files changed (30) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +9 -1
  3. package/dist/runtime/app/components/ComponentShell.d.vue.ts +1 -0
  4. package/dist/runtime/app/components/ComponentShell.vue +13 -3
  5. package/dist/runtime/app/components/ComponentShell.vue.d.ts +1 -0
  6. package/dist/runtime/app/components/DashboardCard.d.vue.ts +15 -0
  7. package/dist/runtime/app/components/DashboardCard.vue +76 -0
  8. package/dist/runtime/app/components/DashboardCard.vue.d.ts +15 -0
  9. package/dist/runtime/app/components/TimelineList.vue +222 -31
  10. package/dist/runtime/app/components/flow/AwaitNode.d.vue.ts +19 -2
  11. package/dist/runtime/app/components/flow/AwaitNode.vue +317 -29
  12. package/dist/runtime/app/components/flow/AwaitNode.vue.d.ts +19 -2
  13. package/dist/runtime/app/components/flow/Diagram.d.vue.ts +2 -1
  14. package/dist/runtime/app/components/flow/Diagram.vue +138 -74
  15. package/dist/runtime/app/components/flow/Diagram.vue.d.ts +2 -1
  16. package/dist/runtime/app/components/flow/NodeCard.d.vue.ts +14 -11
  17. package/dist/runtime/app/components/flow/NodeCard.vue +119 -35
  18. package/dist/runtime/app/components/flow/NodeCard.vue.d.ts +14 -11
  19. package/dist/runtime/app/components/flow/RunOverview.d.vue.ts +1 -0
  20. package/dist/runtime/app/components/flow/RunOverview.vue +85 -86
  21. package/dist/runtime/app/components/flow/RunOverview.vue.d.ts +1 -0
  22. package/dist/runtime/app/components/flow/RunTimeline.vue +51 -22
  23. package/dist/runtime/app/components/flow/StepSelector.vue +124 -46
  24. package/dist/runtime/app/composables/useFlowRunTimeline.d.ts +6 -0
  25. package/dist/runtime/app/composables/useFlowState.d.ts +8 -1
  26. package/dist/runtime/app/composables/useFlowState.js +34 -59
  27. package/dist/runtime/app/pages/dashboard.vue +51 -103
  28. package/dist/runtime/app/pages/flows/[name].vue +26 -3
  29. package/dist/runtime/app/pages/triggers/[name]/edit.vue +1 -1
  30. package/package.json +1 -1
@@ -5,7 +5,7 @@ import { type Ref } from '#imports';
5
5
  * Reduces an array of events from the flow timeline into current state.
6
6
  */
7
7
  export interface FlowState {
8
- status: 'running' | 'completed' | 'failed' | 'canceled' | 'stalled';
8
+ status: 'running' | 'completed' | 'failed' | 'canceled' | 'stalled' | 'awaiting';
9
9
  startedAt?: string;
10
10
  completedAt?: string;
11
11
  steps: Record<string, StepState>;
@@ -17,6 +17,7 @@ export interface StepState {
17
17
  attempt: number;
18
18
  startedAt?: string;
19
19
  completedAt?: string;
20
+ scheduledTriggerAt?: string;
20
21
  error?: string;
21
22
  awaitType?: 'time' | 'event' | 'trigger';
22
23
  awaitData?: any;
@@ -69,11 +70,13 @@ export declare function useFlowState(initialEvents?: EventRecord[]): {
69
70
  isFailed: import("vue").ComputedRef<boolean>;
70
71
  isCanceled: import("vue").ComputedRef<boolean>;
71
72
  isStalled: import("vue").ComputedRef<boolean>;
73
+ isAwaiting: import("vue").ComputedRef<boolean>;
72
74
  stepList: import("vue").ComputedRef<{
73
75
  status: "pending" | "running" | "completed" | "failed" | "retrying" | "waiting" | "timeout";
74
76
  attempt: number;
75
77
  startedAt?: string;
76
78
  completedAt?: string;
79
+ scheduledTriggerAt?: string;
77
80
  error?: string;
78
81
  awaitType?: "time" | "event" | "trigger";
79
82
  awaitData?: any;
@@ -85,6 +88,7 @@ export declare function useFlowState(initialEvents?: EventRecord[]): {
85
88
  attempt: number;
86
89
  startedAt?: string;
87
90
  completedAt?: string;
91
+ scheduledTriggerAt?: string;
88
92
  error?: string;
89
93
  awaitType?: "time" | "event" | "trigger";
90
94
  awaitData?: any;
@@ -96,6 +100,7 @@ export declare function useFlowState(initialEvents?: EventRecord[]): {
96
100
  attempt: number;
97
101
  startedAt?: string;
98
102
  completedAt?: string;
103
+ scheduledTriggerAt?: string;
99
104
  error?: string;
100
105
  awaitType?: "time" | "event" | "trigger";
101
106
  awaitData?: any;
@@ -107,6 +112,7 @@ export declare function useFlowState(initialEvents?: EventRecord[]): {
107
112
  attempt: number;
108
113
  startedAt?: string;
109
114
  completedAt?: string;
115
+ scheduledTriggerAt?: string;
110
116
  error?: string;
111
117
  awaitType?: "time" | "event" | "trigger";
112
118
  awaitData?: any;
@@ -118,6 +124,7 @@ export declare function useFlowState(initialEvents?: EventRecord[]): {
118
124
  attempt: number;
119
125
  startedAt?: string;
120
126
  completedAt?: string;
127
+ scheduledTriggerAt?: string;
121
128
  error?: string;
122
129
  awaitType?: "time" | "event" | "trigger";
123
130
  awaitData?: any;
@@ -16,6 +16,7 @@ export function reduceFlowState(events) {
16
16
  if (e.flowName) state.meta = { ...state.meta, flowName: e.flowName };
17
17
  if (e.data?.flowName) state.meta = { ...state.meta, flowName: e.data.flowName };
18
18
  if (e.data?.input) state.meta = { ...state.meta, input: e.data.input };
19
+ if (e.data?.stallTimeout) state.meta = { ...state.meta, stallTimeout: e.data.stallTimeout };
19
20
  if (e.data?.trigger) {
20
21
  state.meta = {
21
22
  ...state.meta,
@@ -43,7 +44,6 @@ export function reduceFlowState(events) {
43
44
  case "flow.stalled":
44
45
  state.status = "stalled";
45
46
  if (e.data?.lastActivityAt) state.meta = { ...state.meta, lastActivityAt: e.data.lastActivityAt };
46
- if (e.data?.stallTimeout) state.meta = { ...state.meta, stallTimeout: e.data.stallTimeout };
47
47
  break;
48
48
  case "step.started": {
49
49
  if (!stepKey) break;
@@ -128,60 +128,44 @@ export function reduceFlowState(events) {
128
128
  }
129
129
  case "await.registered": {
130
130
  if (!stepKey) break;
131
- const awaitKeyAfter = `${stepKey}:await-after`;
132
- const awaitKeyBefore = `${stepKey}:await-before`;
133
- if (!state.steps[awaitKeyAfter]) {
134
- state.steps[awaitKeyAfter] = { status: "waiting", attempt: 1 };
131
+ const position = e.data?.position || "after";
132
+ const awaitKey = `${stepKey}:await-${position}`;
133
+ if (!state.steps[awaitKey]) {
134
+ state.steps[awaitKey] = { status: "waiting", attempt: 1 };
135
135
  }
136
- state.steps[awaitKeyAfter].status = "waiting";
137
- state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
138
- state.steps[awaitKeyAfter].awaitData = e.data;
139
- if (!state.steps[awaitKeyBefore]) {
140
- state.steps[awaitKeyBefore] = { status: "waiting", attempt: 1 };
136
+ state.steps[awaitKey].status = "waiting";
137
+ state.steps[awaitKey].awaitType = e.data?.awaitType;
138
+ state.steps[awaitKey].awaitData = e.data;
139
+ const scheduledAt = e.data?.resolveAt || e.data?.nextOccurrence;
140
+ if (scheduledAt) {
141
+ state.steps[awaitKey].scheduledTriggerAt = new Date(scheduledAt).toISOString();
141
142
  }
142
- state.steps[awaitKeyBefore].status = "waiting";
143
- state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
144
- state.steps[awaitKeyBefore].awaitData = e.data;
145
143
  break;
146
144
  }
147
145
  case "await.resolved": {
148
146
  if (!stepKey) break;
149
- const awaitKeyAfter = `${stepKey}:await-after`;
150
- const awaitKeyBefore = `${stepKey}:await-before`;
151
- if (!state.steps[awaitKeyAfter]) {
152
- state.steps[awaitKeyAfter] = { status: "completed", attempt: 1 };
153
- }
154
- state.steps[awaitKeyAfter].status = "completed";
155
- state.steps[awaitKeyAfter].completedAt = e.ts;
156
- state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
157
- if (e.data?.triggerData) state.steps[awaitKeyAfter].result = e.data.triggerData;
158
- if (!state.steps[awaitKeyBefore]) {
159
- state.steps[awaitKeyBefore] = { status: "completed", attempt: 1 };
147
+ const position = e.data?.position || "after";
148
+ const awaitKey = `${stepKey}:await-${position}`;
149
+ if (!state.steps[awaitKey]) {
150
+ state.steps[awaitKey] = { status: "completed", attempt: 1 };
160
151
  }
161
- state.steps[awaitKeyBefore].status = "completed";
162
- state.steps[awaitKeyBefore].completedAt = e.ts;
163
- state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
164
- if (e.data?.triggerData) state.steps[awaitKeyBefore].result = e.data.triggerData;
152
+ state.steps[awaitKey].status = "completed";
153
+ state.steps[awaitKey].completedAt = e.ts;
154
+ state.steps[awaitKey].awaitType = e.data?.awaitType;
155
+ if (e.data?.triggerData) state.steps[awaitKey].result = e.data.triggerData;
165
156
  break;
166
157
  }
167
158
  case "await.timeout": {
168
159
  if (!stepKey) break;
169
- const awaitKeyAfter = `${stepKey}:await-after`;
170
- const awaitKeyBefore = `${stepKey}:await-before`;
171
- if (!state.steps[awaitKeyAfter]) {
172
- state.steps[awaitKeyAfter] = { status: "timeout", attempt: 1 };
160
+ const position = e.data?.position || "after";
161
+ const awaitKey = `${stepKey}:await-${position}`;
162
+ if (!state.steps[awaitKey]) {
163
+ state.steps[awaitKey] = { status: "timeout", attempt: 1 };
173
164
  }
174
- state.steps[awaitKeyAfter].status = "timeout";
175
- state.steps[awaitKeyAfter].error = `Await timeout`;
176
- state.steps[awaitKeyAfter].completedAt = e.ts;
177
- state.steps[awaitKeyAfter].awaitType = e.data?.awaitType;
178
- if (!state.steps[awaitKeyBefore]) {
179
- state.steps[awaitKeyBefore] = { status: "timeout", attempt: 1 };
180
- }
181
- state.steps[awaitKeyBefore].status = "timeout";
182
- state.steps[awaitKeyBefore].error = `Await timeout`;
183
- state.steps[awaitKeyBefore].completedAt = e.ts;
184
- state.steps[awaitKeyBefore].awaitType = e.data?.awaitType;
165
+ state.steps[awaitKey].status = "timeout";
166
+ state.steps[awaitKey].error = `Await timeout`;
167
+ state.steps[awaitKey].completedAt = e.ts;
168
+ state.steps[awaitKey].awaitType = e.data?.awaitType;
185
169
  break;
186
170
  }
187
171
  case "runner.log":
@@ -211,23 +195,12 @@ export function reduceFlowState(events) {
211
195
  state.startedAt = events[0].ts;
212
196
  }
213
197
  if (state.status === "running" && state.startedAt && Object.keys(state.steps).length > 0) {
214
- const hasRunningSteps = Object.values(state.steps).some(
215
- (s) => s.status === "running" || s.status === "retrying" || s.status === "waiting"
216
- );
217
- const hasFailedSteps = Object.values(state.steps).some((s) => s.status === "failed");
218
- const allStepsTerminal = Object.values(state.steps).every(
219
- (s) => s.status === "completed" || s.status === "failed" || s.status === "timeout"
198
+ const hasActiveRunningSteps = Object.values(state.steps).some(
199
+ (s) => s.status === "running" || s.status === "retrying"
220
200
  );
221
- if (!hasRunningSteps && allStepsTerminal) {
222
- if (hasFailedSteps) {
223
- state.status = "failed";
224
- } else {
225
- state.status = "completed";
226
- }
227
- const latestCompletion = Object.values(state.steps).map((s) => s.completedAt).filter(Boolean).sort().pop();
228
- if (latestCompletion) {
229
- state.completedAt = latestCompletion;
230
- }
201
+ const hasWaitingSteps = Object.values(state.steps).some((s) => s.status === "waiting");
202
+ if (hasWaitingSteps && !hasActiveRunningSteps) {
203
+ state.status = "awaiting";
231
204
  }
232
205
  }
233
206
  return state;
@@ -249,6 +222,7 @@ export function useFlowState(initialEvents = []) {
249
222
  const isFailed = computed(() => state.value.status === "failed");
250
223
  const isCanceled = computed(() => state.value.status === "canceled");
251
224
  const isStalled = computed(() => state.value.status === "stalled");
225
+ const isAwaiting = computed(() => state.value.status === "awaiting");
252
226
  const stepList = computed(() => {
253
227
  return Object.entries(state.value.steps).map(([key, step]) => ({
254
228
  key,
@@ -281,6 +255,7 @@ export function useFlowState(initialEvents = []) {
281
255
  isFailed,
282
256
  isCanceled,
283
257
  isStalled,
258
+ isAwaiting,
284
259
  stepList,
285
260
  runningSteps,
286
261
  waitingSteps,
@@ -27,109 +27,54 @@
27
27
  <!-- System Stats Overview -->
28
28
  <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
29
29
  <!-- Queues Card -->
30
- <div
31
- class="bg-gradient-to-br from-blue-500 to-blue-600 dark:from-blue-600 dark:to-blue-700 rounded-xl p-6 text-white shadow-lg hover:shadow-xl transition-shadow cursor-pointer"
32
- @click="navigateTo('/queues')"
33
- >
34
- <div class="flex items-center justify-between mb-4">
35
- <div class="p-3 bg-white/20 rounded-lg backdrop-blur-sm">
36
- <UIcon
37
- name="i-lucide-app-window"
38
- class="w-6 h-6"
39
- />
40
- </div>
41
- <UIcon
42
- name="i-lucide-arrow-right"
43
- class="w-5 h-5 opacity-60"
44
- />
45
- </div>
46
- <div class="text-3xl font-bold mb-1">
47
- {{ queuesStats?.total || 0 }}
48
- </div>
49
- <div class="text-sm opacity-90 mb-3">
50
- Active Queues
51
- </div>
52
- <div class="flex items-center gap-4 text-xs opacity-75">
53
- <div v-if="queuesStats?.pending > 0">
54
- <span class="font-semibold">{{ formatNumber(queuesStats?.pending || 0) }}</span> pending
55
- </div>
56
- <div>
57
- <span class="font-semibold">{{ formatNumber(queuesStats?.completed || 0) }}</span> completed
58
- </div>
59
- <div v-if="queuesStats?.failed > 0">
60
- <span class="font-semibold">{{ formatNumber(queuesStats?.failed || 0) }}</span> failed
61
- </div>
62
- </div>
63
- </div>
30
+ <NventDashboardCard
31
+ icon="i-lucide-app-window"
32
+ title="Active Queues"
33
+ color="blue"
34
+ :primary-stats="[
35
+ { value: formatNumber(queuesStats?.active || 0), label: 'active' },
36
+ { value: formatNumber((queuesStats?.waiting || 0) + (queuesStats?.delayed || 0)), label: 'waiting' },
37
+ ...queuesStats?.failed > 0 ? [{ value: formatNumber(queuesStats?.failed || 0), label: 'failed' }] : []
38
+ ]"
39
+ :secondary-stats="[
40
+ { value: queuesStats?.total || 0, label: 'queues' },
41
+ { value: formatNumber(queuesStats?.completed || 0), label: 'completed' }
42
+ ]"
43
+ :on-click="() => navigateTo('/queues')"
44
+ />
64
45
 
65
46
  <!-- Flows Card -->
66
- <div
67
- class="bg-gradient-to-br from-purple-500 to-purple-600 dark:from-purple-600 dark:to-purple-700 rounded-xl p-6 text-white shadow-lg hover:shadow-xl transition-shadow cursor-pointer"
68
- @click="navigateTo('/flows')"
69
- >
70
- <div class="flex items-center justify-between mb-4">
71
- <div class="p-3 bg-white/20 rounded-lg backdrop-blur-sm">
72
- <UIcon
73
- name="i-lucide-git-branch"
74
- class="w-6 h-6"
75
- />
76
- </div>
77
- <UIcon
78
- name="i-lucide-arrow-right"
79
- class="w-5 h-5 opacity-60"
80
- />
81
- </div>
82
- <div class="text-3xl font-bold mb-1">
83
- {{ flowsStats?.total || 0 }}
84
- </div>
85
- <div class="text-sm opacity-90 mb-3">
86
- Registered Flows
87
- </div>
88
- <div class="flex items-center gap-4 text-xs opacity-75">
89
- <div v-if="flowsStats?.running > 0">
90
- <span class="font-semibold">{{ flowsStats?.running }}</span> running
91
- </div>
92
- <div v-if="flowsStats?.awaiting > 0">
93
- <span class="font-semibold">{{ flowsStats?.awaiting }}</span> awaiting
94
- </div>
95
- <div>
96
- <span class="font-semibold">{{ formatNumber(flowsStats?.success || 0) }}</span> success
97
- </div>
98
- </div>
99
- </div>
47
+ <NventDashboardCard
48
+ icon="i-lucide-git-branch"
49
+ title="Registered Flows"
50
+ color="purple"
51
+ :primary-stats="[
52
+ ...flowsStats?.running > 0 ? [{ value: flowsStats?.running, label: 'running' }] : [],
53
+ ...flowsStats?.awaiting > 0 ? [{ value: flowsStats?.awaiting, label: 'awaiting' }] : [],
54
+ ...flowsStats?.success > 0 ? [{ value: formatNumber(flowsStats?.success), label: 'completed' }] : [],
55
+ ...flowsStats?.failure > 0 ? [{ value: formatNumber(flowsStats?.failure), label: 'failed' }] : []
56
+ ]"
57
+ :secondary-stats="[
58
+ { value: flowsStats?.total || 0, label: 'flows' },
59
+ { value: formatNumber(flowsStats?.totalRuns || 0), label: 'total runs' }
60
+ ]"
61
+ :on-click="() => navigateTo('/flows')"
62
+ />
100
63
 
101
64
  <!-- Triggers Card -->
102
- <div
103
- class="bg-gradient-to-br from-amber-500 to-amber-600 dark:from-amber-600 dark:to-amber-700 rounded-xl p-6 text-white shadow-lg hover:shadow-xl transition-shadow cursor-pointer"
104
- @click="navigateTo('/triggers')"
105
- >
106
- <div class="flex items-center justify-between mb-4">
107
- <div class="p-3 bg-white/20 rounded-lg backdrop-blur-sm">
108
- <UIcon
109
- name="i-lucide-zap"
110
- class="w-6 h-6"
111
- />
112
- </div>
113
- <UIcon
114
- name="i-lucide-arrow-right"
115
- class="w-5 h-5 opacity-60"
116
- />
117
- </div>
118
- <div class="text-3xl font-bold mb-1">
119
- {{ triggersStats?.total || 0 }}
120
- </div>
121
- <div class="text-sm opacity-90 mb-3">
122
- Active Triggers
123
- </div>
124
- <div class="flex items-center gap-4 text-xs opacity-75">
125
- <div>
126
- <span class="font-semibold">{{ formatNumber(triggersStats?.totalFires || 0) }}</span> fires
127
- </div>
128
- <div>
129
- <span class="font-semibold">{{ formatNumber(triggersStats?.totalFlowsStarted || 0) }}</span> flows started
130
- </div>
131
- </div>
132
- </div>
65
+ <NventDashboardCard
66
+ icon="i-lucide-zap"
67
+ title="Active Triggers"
68
+ color="amber"
69
+ :primary-stats="[
70
+ { value: formatNumber(triggersStats?.totalFires || 0), label: 'fires' }
71
+ ]"
72
+ :secondary-stats="[
73
+ { value: triggersStats?.total || 0, label: 'triggers' },
74
+ { value: formatNumber(triggersStats?.totalFlowsStarted || 0), label: 'flows started' }
75
+ ]"
76
+ :on-click="() => navigateTo('/triggers')"
77
+ />
133
78
  </div>
134
79
 
135
80
  <!-- Quick Actions & Recent Activity -->
@@ -649,14 +594,17 @@ function updateTriggerStats(data) {
649
594
  ];
650
595
  }
651
596
  const queuesStats = computed(() => {
652
- const pending = queues.value.reduce((sum, q) => {
653
- const counts = q.counts || {};
654
- return sum + (counts.active || 0) + (counts.waiting || 0) + (counts.delayed || 0);
655
- }, 0);
597
+ const active = queues.value.reduce((sum, q) => sum + (q.counts?.active || 0), 0);
598
+ const waiting = queues.value.reduce((sum, q) => sum + (q.counts?.waiting || 0), 0);
599
+ const delayed = queues.value.reduce((sum, q) => sum + (q.counts?.delayed || 0), 0);
600
+ const pending = active + waiting + delayed;
656
601
  const completed = queues.value.reduce((sum, q) => sum + (q.counts?.completed || 0), 0);
657
602
  const failed = queues.value.reduce((sum, q) => sum + (q.counts?.failed || 0), 0);
658
603
  return {
659
604
  total: queues.value.length,
605
+ active,
606
+ waiting,
607
+ delayed,
660
608
  pending,
661
609
  completed,
662
610
  failed
@@ -288,12 +288,13 @@
288
288
  :run-status="runSnapshot.status"
289
289
  :started-at="runSnapshot.startedAt"
290
290
  :completed-at="runSnapshot.completedAt"
291
- :steps="flowState.stepList.value"
291
+ :steps="enhancedStepList"
292
292
  :flow-name="selectedFlow || void 0"
293
293
  :run-id="selectedRunId || void 0"
294
294
  :trigger-name="flowState.state.value.meta?.triggerName"
295
295
  :trigger-type="flowState.state.value.meta?.triggerType"
296
296
  :flow-def="selectedFlowDef"
297
+ :stall-timeout="runSnapshot.stallTimeout"
297
298
  @select-step="handleSelectStep"
298
299
  @cancel-flow="handleCancelFlow"
299
300
  />
@@ -423,7 +424,7 @@ const selectedRunId = computed({
423
424
  const goBack = () => {
424
425
  componentRouter.push("/flows");
425
426
  };
426
- const mainTab = ref("diagram");
427
+ const mainTab = ref(route.query.run ? "timeline" : "diagram");
427
428
  const mainTabs = computed(() => [
428
429
  { label: "Diagram", value: "diagram", icon: "i-lucide-git-branch" },
429
430
  {
@@ -533,12 +534,15 @@ const formatDuration = (start, end) => {
533
534
  };
534
535
  const runSnapshot = computed(() => {
535
536
  const state = flowState.state.value;
537
+ const flowMeta = selectedFlowMeta.value;
536
538
  return {
537
539
  status: state.status,
538
540
  startedAt: state.startedAt,
539
541
  completedAt: state.completedAt,
540
542
  logsCount: state.logs.length,
541
- lastLogLevel: state.logs.length > 0 ? state.logs[state.logs.length - 1]?.level : void 0
543
+ lastLogLevel: state.logs.length > 0 ? state.logs[state.logs.length - 1]?.level : void 0,
544
+ // Use stallTimeout from event data if available, otherwise fall back to static flow definition
545
+ stallTimeout: state.meta?.stallTimeout || flowMeta?.analyzed?.stallTimeout
542
546
  };
543
547
  });
544
548
  const selectedStepKey = ref(null);
@@ -557,6 +561,25 @@ const selectedFlowMeta = computed(() => {
557
561
  if (!id) return null;
558
562
  return (flows.value || []).find((f) => f?.id === id) || null;
559
563
  });
564
+ const enhancedStepList = computed(() => {
565
+ const steps = flowState.stepList.value;
566
+ const flowMeta = selectedFlowMeta.value;
567
+ if (!flowMeta?.analyzed?.steps) return steps;
568
+ const stepTimeoutMap = /* @__PURE__ */ new Map();
569
+ for (const [stepName, analyzedStep] of Object.entries(flowMeta.analyzed.steps)) {
570
+ if (analyzedStep.stepTimeout !== void 0) {
571
+ stepTimeoutMap.set(stepName, analyzedStep.stepTimeout);
572
+ }
573
+ }
574
+ return steps.map((step) => {
575
+ const baseStepName = step.key.includes(":await-") ? step.key.split(":await-")[0] : step.key;
576
+ const staticTimeout = stepTimeoutMap.get(baseStepName);
577
+ if (staticTimeout !== void 0) {
578
+ return { ...step, stepTimeout: staticTimeout };
579
+ }
580
+ return step;
581
+ });
582
+ });
560
583
  const handleSelectStep = (stepKey) => {
561
584
  selectedStepKey.value = stepKey;
562
585
  };
@@ -314,7 +314,7 @@ const hasChanges = computed(() => {
314
314
  const saveError = ref(null);
315
315
  const saveSuccess = ref(false);
316
316
  const onSubmit = async (event) => {
317
- if (!trigger.value) return;
317
+ if (!trigger.value || isSaving.value) return;
318
318
  isSaving.value = true;
319
319
  saveError.value = null;
320
320
  saveSuccess.value = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nvent-addon/app",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "nvent app module for Nuxt.js",
5
5
  "repository": "DevJoghurt/nvent",
6
6
  "license": "MIT",