@nvent-addon/app 0.5.14 → 1.0.0-alpha.1

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 (95) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +3 -2
  3. package/dist/runtime/app/components/DashboardCard.d.vue.ts +1 -1
  4. package/dist/runtime/app/components/DashboardCard.vue.d.ts +1 -1
  5. package/dist/runtime/app/composables/useWorkers.d.ts +57 -0
  6. package/dist/runtime/app/composables/useWorkers.js +42 -0
  7. package/dist/runtime/app/pages/dashboard.vue +1 -654
  8. package/dist/runtime/app/pages/index.vue +25 -41
  9. package/dist/runtime/app/pages/workers.vue +458 -0
  10. package/dist/runtime/server/api/_workers/index.get.d.ts +8 -0
  11. package/dist/runtime/server/api/_workers/index.get.js +14 -0
  12. package/package.json +12 -11
  13. package/dist/runtime/app/components/ComponentRouter.d.vue.ts +0 -46
  14. package/dist/runtime/app/components/ComponentRouter.vue +0 -26
  15. package/dist/runtime/app/components/ComponentRouter.vue.d.ts +0 -46
  16. package/dist/runtime/app/components/ComponentShell.d.vue.ts +0 -23
  17. package/dist/runtime/app/components/ComponentShell.vue +0 -97
  18. package/dist/runtime/app/components/ComponentShell.vue.d.ts +0 -23
  19. package/dist/runtime/app/components/ConfirmDialog.d.vue.ts +0 -33
  20. package/dist/runtime/app/components/ConfirmDialog.vue +0 -120
  21. package/dist/runtime/app/components/ConfirmDialog.vue.d.ts +0 -33
  22. package/dist/runtime/app/composables/useComponentRouter.d.ts +0 -46
  23. package/dist/runtime/app/composables/useComponentRouter.js +0 -248
  24. package/dist/runtime/app/pages/flows/[name].vue +0 -750
  25. package/dist/runtime/app/pages/flows/index.d.vue.ts +0 -3
  26. package/dist/runtime/app/pages/flows/index.vue +0 -381
  27. package/dist/runtime/app/pages/flows/index.vue.d.ts +0 -3
  28. package/dist/runtime/app/pages/queues/index.d.vue.ts +0 -3
  29. package/dist/runtime/app/pages/queues/index.vue +0 -236
  30. package/dist/runtime/app/pages/queues/index.vue.d.ts +0 -3
  31. package/dist/runtime/app/pages/queues/job.d.vue.ts +0 -3
  32. package/dist/runtime/app/pages/queues/job.vue +0 -261
  33. package/dist/runtime/app/pages/queues/job.vue.d.ts +0 -3
  34. package/dist/runtime/app/pages/queues/jobs.d.vue.ts +0 -3
  35. package/dist/runtime/app/pages/queues/jobs.vue +0 -595
  36. package/dist/runtime/app/pages/queues/jobs.vue.d.ts +0 -3
  37. package/dist/runtime/app/pages/settings/scheduler.d.vue.ts +0 -3
  38. package/dist/runtime/app/pages/settings/scheduler.vue +0 -310
  39. package/dist/runtime/app/pages/settings/scheduler.vue.d.ts +0 -3
  40. package/dist/runtime/app/pages/triggers/[name]/edit.d.vue.ts +0 -3
  41. package/dist/runtime/app/pages/triggers/[name]/edit.vue +0 -429
  42. package/dist/runtime/app/pages/triggers/[name]/edit.vue.d.ts +0 -3
  43. package/dist/runtime/app/pages/triggers/[name].d.vue.ts +0 -3
  44. package/dist/runtime/app/pages/triggers/[name].vue +0 -870
  45. package/dist/runtime/app/pages/triggers/[name].vue.d.ts +0 -3
  46. package/dist/runtime/app/pages/triggers/index.d.vue.ts +0 -3
  47. package/dist/runtime/app/pages/triggers/index.vue +0 -525
  48. package/dist/runtime/app/pages/triggers/index.vue.d.ts +0 -3
  49. package/dist/runtime/app/pages/triggers/new.d.vue.ts +0 -3
  50. package/dist/runtime/app/pages/triggers/new.vue +0 -610
  51. package/dist/runtime/app/pages/triggers/new.vue.d.ts +0 -3
  52. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.d.ts +0 -10
  53. package/dist/runtime/server/api/_flows/[name]/clear-history.delete.js +0 -49
  54. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.d.ts +0 -2
  55. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/cancel.post.js +0 -21
  56. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/restart.post.d.ts +0 -2
  57. package/dist/runtime/server/api/_flows/[name]/runs/[runId]/restart.post.js +0 -21
  58. package/dist/runtime/server/api/_flows/[name]/runs.get.d.ts +0 -17
  59. package/dist/runtime/server/api/_flows/[name]/runs.get.js +0 -64
  60. package/dist/runtime/server/api/_flows/[name]/start.post.d.ts +0 -2
  61. package/dist/runtime/server/api/_flows/[name]/start.post.js +0 -9
  62. package/dist/runtime/server/api/_flows/index.get.d.ts +0 -7
  63. package/dist/runtime/server/api/_flows/index.get.js +0 -5
  64. package/dist/runtime/server/api/_flows/recent-runs.get.d.ts +0 -15
  65. package/dist/runtime/server/api/_flows/recent-runs.get.js +0 -67
  66. package/dist/runtime/server/api/_flows/ws.d.ts +0 -80
  67. package/dist/runtime/server/api/_flows/ws.js +0 -309
  68. package/dist/runtime/server/api/_queues/[name]/job/[id].get.d.ts +0 -2
  69. package/dist/runtime/server/api/_queues/[name]/job/[id].get.js +0 -14
  70. package/dist/runtime/server/api/_queues/[name]/job/index.get.d.ts +0 -2
  71. package/dist/runtime/server/api/_queues/[name]/job/index.get.js +0 -39
  72. package/dist/runtime/server/api/_queues/index.get.d.ts +0 -2
  73. package/dist/runtime/server/api/_queues/index.get.js +0 -106
  74. package/dist/runtime/server/api/_queues/ws.d.ts +0 -48
  75. package/dist/runtime/server/api/_queues/ws.js +0 -215
  76. package/dist/runtime/server/api/_scheduler/jobs.get.d.ts +0 -19
  77. package/dist/runtime/server/api/_scheduler/jobs.get.js +0 -36
  78. package/dist/runtime/server/api/_triggers/[name]/events.get.d.ts +0 -6
  79. package/dist/runtime/server/api/_triggers/[name]/events.get.js +0 -43
  80. package/dist/runtime/server/api/_triggers/[name]/index.get.d.ts +0 -6
  81. package/dist/runtime/server/api/_triggers/[name]/index.get.js +0 -76
  82. package/dist/runtime/server/api/_triggers/[name].delete.d.ts +0 -7
  83. package/dist/runtime/server/api/_triggers/[name].delete.js +0 -37
  84. package/dist/runtime/server/api/_triggers/[name].patch.d.ts +0 -7
  85. package/dist/runtime/server/api/_triggers/[name].patch.js +0 -117
  86. package/dist/runtime/server/api/_triggers/index.get.d.ts +0 -6
  87. package/dist/runtime/server/api/_triggers/index.get.js +0 -44
  88. package/dist/runtime/server/api/_triggers/index.post.d.ts +0 -7
  89. package/dist/runtime/server/api/_triggers/index.post.js +0 -124
  90. package/dist/runtime/server/api/_triggers/stats.get.d.ts +0 -6
  91. package/dist/runtime/server/api/_triggers/stats.get.js +0 -41
  92. package/dist/runtime/server/api/_triggers/ws.d.ts +0 -74
  93. package/dist/runtime/server/api/_triggers/ws.js +0 -315
  94. /package/dist/runtime/app/pages/{flows/[name].d.vue.ts → workers.d.vue.ts} +0 -0
  95. /package/dist/runtime/app/pages/{flows/[name].vue.d.ts → workers.vue.d.ts} +0 -0
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;
@@ -1,381 +0,0 @@
1
- <template>
2
- <div class="h-full flex flex-col overflow-hidden">
3
- <!-- Header -->
4
- <div class="border-b border-gray-200 dark:border-gray-800 px-6 py-3 shrink-0">
5
- <div class="flex items-center justify-between">
6
- <div class="flex items-center gap-4">
7
- <h1 class="text-lg font-semibold">
8
- Flows
9
- </h1>
10
- </div>
11
- <LiveIndicator
12
- :is-connected="flowWs.connected.value"
13
- :is-reconnecting="flowWs.reconnecting.value"
14
- />
15
- </div>
16
- </div>
17
-
18
- <!-- Main Content -->
19
- <div class="flex-1 min-h-0 overflow-y-auto">
20
- <div class="max-w-7xl mx-auto p-6">
21
- <!-- Stats Overview -->
22
- <div class="grid grid-cols-2 md:grid-cols-6 gap-4 mb-6">
23
- <StatCard
24
- icon="i-lucide-git-branch"
25
- :count="flows?.length || 0"
26
- label="Total Flows"
27
- variant="gray"
28
- />
29
- <StatCard
30
- icon="i-lucide-play"
31
- :count="totalRuns"
32
- label="Total Runs"
33
- variant="blue"
34
- />
35
- <StatCard
36
- icon="i-lucide-check-circle"
37
- :count="totalSuccess"
38
- label="Success"
39
- variant="emerald"
40
- />
41
- <StatCard
42
- icon="i-lucide-x-circle"
43
- :count="totalFailure"
44
- label="Failures"
45
- variant="red"
46
- />
47
- <StatCard
48
- icon="i-lucide-loader"
49
- :count="totalRunning"
50
- label="Running"
51
- variant="purple"
52
- />
53
- <StatCard
54
- icon="i-lucide-pause"
55
- :count="totalAwaiting"
56
- label="Awaiting"
57
- variant="amber"
58
- />
59
- </div>
60
-
61
- <!-- Filters -->
62
- <div class="mb-4">
63
- <UInput
64
- v-model="searchQuery"
65
- icon="i-lucide-search"
66
- placeholder="Search flows..."
67
- size="sm"
68
- />
69
- </div>
70
-
71
- <!-- Flows List -->
72
- <div
73
- v-if="!filteredFlows || filteredFlows.length === 0"
74
- class="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 p-8 text-center text-gray-500"
75
- >
76
- <div v-if="searchQuery">
77
- <UIcon
78
- name="i-lucide-search-x"
79
- class="w-12 h-12 animate-spin mx-auto mb-3 opacity-50"
80
- />
81
- <p>No flows match your search</p>
82
- <UButton
83
- size="xs"
84
- color="neutral"
85
- variant="ghost"
86
- class="mt-2"
87
- @click="searchQuery = ''"
88
- >
89
- Clear Search
90
- </UButton>
91
- </div>
92
- <div v-else>
93
- <UIcon
94
- name="i-lucide-git-branch"
95
- class="w-12 h-12 mx-auto mb-3 opacity-50"
96
- />
97
- <p>No flows found</p>
98
- </div>
99
- </div>
100
- <div
101
- v-else
102
- class="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 overflow-hidden"
103
- >
104
- <div class="divide-y divide-gray-100 dark:divide-gray-800">
105
- <div
106
- v-for="flow in filteredFlows"
107
- :key="flow.id"
108
- class="px-6 py-4 hover:bg-gray-50 dark:hover:bg-gray-900/50 transition-colors cursor-pointer"
109
- @click="openFlow(flow.id)"
110
- >
111
- <div class="flex items-start justify-between gap-4">
112
- <!-- Left: Flow Info -->
113
- <div class="flex-1 min-w-0">
114
- <div class="flex items-center gap-2 mb-2">
115
- <UIcon
116
- name="i-lucide-git-branch"
117
- class="w-4 h-4 shrink-0 text-blue-500"
118
- />
119
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 truncate">
120
- {{ flow.id }}
121
- </h3>
122
- <UBadge
123
- v-if="flow.hasAwait"
124
- label="await"
125
- color="purple"
126
- variant="subtle"
127
- size="xs"
128
- >
129
- <template #leading>
130
- <UIcon
131
- name="i-lucide-pause"
132
- class="w-3 h-3"
133
- />
134
- </template>
135
- </UBadge>
136
- </div>
137
-
138
- <div class="flex items-center gap-4 text-xs text-gray-500 dark:text-gray-400">
139
- <div class="flex items-center gap-1">
140
- <UIcon
141
- name="i-lucide-layers"
142
- class="w-3 h-3"
143
- />
144
- <span>{{ getStepCount(flow) }} step{{ getStepCount(flow) === 1 ? "" : "s" }}</span>
145
- </div>
146
- <div class="flex items-center gap-1">
147
- <UIcon
148
- name="i-lucide-bar-chart-3"
149
- class="w-3 h-3"
150
- />
151
- <span>{{ getLevelCount(flow) }} level{{ getLevelCount(flow) === 1 ? "" : "s" }}</span>
152
- </div>
153
- <div
154
- v-if="flow.stats && flow.stats.total > 0"
155
- class="flex items-center gap-2"
156
- >
157
- <div class="flex items-center gap-1">
158
- <UIcon
159
- name="i-lucide-play"
160
- class="w-3 h-3"
161
- />
162
- <span>{{ flow.stats.total }}</span>
163
- </div>
164
- <div
165
- v-if="flow.stats.running > 0"
166
- class="flex items-center gap-1 text-purple-600 dark:text-purple-400"
167
- >
168
- <UIcon
169
- name="i-lucide-loader"
170
- class="w-3 h-3"
171
- />
172
- <span>{{ flow.stats.running }}</span>
173
- </div>
174
- </div>
175
- <div
176
- v-if="flow.timeout"
177
- class="flex items-center gap-1"
178
- >
179
- <UIcon
180
- name="i-lucide-clock"
181
- class="w-3 h-3"
182
- />
183
- <span>{{ formatTimeout(flow.timeout) }} timeout</span>
184
- </div>
185
- <!-- Runtime Badges -->
186
- <div
187
- v-if="getRuntimes(flow).length > 0"
188
- class="flex items-center gap-1"
189
- >
190
- <UIcon
191
- name="i-lucide-cpu"
192
- class="w-3 h-3"
193
- />
194
- <span>{{ getRuntimes(flow).join(", ") }}</span>
195
- </div>
196
- </div>
197
- </div>
198
-
199
- <!-- Right: Action -->
200
- <UButton
201
- icon="i-lucide-arrow-right"
202
- size="xs"
203
- color="neutral"
204
- variant="ghost"
205
- square
206
- />
207
- </div>
208
- </div>
209
- </div>
210
- </div>
211
-
212
- <!-- Footer Info -->
213
- <div
214
- v-if="filteredFlows && filteredFlows.length > 0"
215
- class="mt-4 text-center text-sm text-gray-500 dark:text-gray-400"
216
- >
217
- Showing {{ filteredFlows.length }} flow{{ filteredFlows.length === 1 ? "" : "s" }}
218
- </div>
219
- </div>
220
- </div>
221
- </div>
222
- </template>
223
-
224
- <script setup>
225
- import { ref, computed, onMounted, onBeforeUnmount } from "#imports";
226
- import { useComponentRouter } from "../../composables/useComponentRouter";
227
- import { useFlowWebSocket } from "../../composables/useFlowWebSocket";
228
- import StatCard from "../../components/StatCard.vue";
229
- import LiveIndicator from "../../components/LiveIndicator.vue";
230
- const router = useComponentRouter();
231
- const flows = ref([]);
232
- const loading = ref(true);
233
- const flowWs = useFlowWebSocket();
234
- async function fetchAnalyzedFlows() {
235
- try {
236
- const data = await $fetch("/api/_flows");
237
- const analyzedFlows = data;
238
- flows.value = analyzedFlows.map((flow) => ({
239
- id: flow.id,
240
- entry: flow.entry,
241
- steps: flow.analyzed?.steps || flow.steps || {},
242
- levels: flow.analyzed?.levels || [],
243
- maxLevel: flow.analyzed?.maxLevel || 0,
244
- stallTimeout: flow.analyzed?.stallTimeout,
245
- awaitPatterns: flow.analyzed?.awaitPatterns,
246
- hasAwait: flow.analyzed?.awaitPatterns?.steps?.length > 0 || false,
247
- timeout: flow.timeout,
248
- stats: { total: 0, success: 0, failure: 0, cancel: 0, running: 0, awaiting: 0 }
249
- }));
250
- } catch (err) {
251
- console.error("Error fetching analyzed flows:", err);
252
- }
253
- }
254
- function updateFlowStats(data) {
255
- const flowId = data?.id;
256
- if (!flowId || !flows.value)
257
- return;
258
- const flowIndex = flows.value.findIndex((f) => f.id === flowId);
259
- if (flowIndex === -1) {
260
- console.warn("[Flow Stats] Flow not found in list:", flowId);
261
- return;
262
- }
263
- const metadata = data?.metadata;
264
- if (!metadata) {
265
- console.warn("[Flow Stats] No metadata in update:", data);
266
- return;
267
- }
268
- const stats = metadata.stats || {
269
- total: metadata["stats.total"] || 0,
270
- success: metadata["stats.success"] || 0,
271
- failure: metadata["stats.failure"] || 0,
272
- cancel: metadata["stats.cancel"] || 0,
273
- running: metadata["stats.running"] || 0,
274
- awaiting: metadata["stats.awaiting"] || 0
275
- };
276
- const flow = flows.value[flowIndex];
277
- flow.stats = {
278
- total: stats.total || 0,
279
- success: stats.success || 0,
280
- failure: stats.failure || 0,
281
- cancel: stats.cancel || 0,
282
- running: stats.running || 0,
283
- awaiting: stats.awaiting || 0
284
- };
285
- flow.lastRunAt = metadata.lastRunAt;
286
- flow.lastCompletedAt = metadata.lastCompletedAt;
287
- }
288
- onMounted(async () => {
289
- await fetchAnalyzedFlows();
290
- if (import.meta.client) {
291
- flowWs.subscribeStats(
292
- {
293
- onInitial: (data) => {
294
- updateFlowStats(data);
295
- },
296
- onUpdate: (data) => {
297
- updateFlowStats(data);
298
- }
299
- },
300
- {
301
- autoReconnect: true,
302
- onOpen: () => {
303
- loading.value = false;
304
- },
305
- onError: (err) => {
306
- console.error("[Flow Stats] Error:", err);
307
- }
308
- }
309
- );
310
- }
311
- });
312
- onBeforeUnmount(() => {
313
- flowWs.unsubscribeStats();
314
- flowWs.stop();
315
- });
316
- const searchQuery = ref("");
317
- const filteredFlows = computed(() => {
318
- if (!flows.value)
319
- return [];
320
- if (searchQuery.value) {
321
- const query = searchQuery.value.toLowerCase();
322
- return flows.value.filter(
323
- (flow) => flow.id.toLowerCase().includes(query)
324
- );
325
- }
326
- return flows.value;
327
- });
328
- const totalRuns = computed(() => {
329
- if (!flows.value)
330
- return 0;
331
- return flows.value.reduce((acc, flow) => acc + (flow.stats?.total || 0), 0);
332
- });
333
- const totalSuccess = computed(() => {
334
- if (!flows.value)
335
- return 0;
336
- return flows.value.reduce((acc, flow) => acc + (flow.stats?.success || 0), 0);
337
- });
338
- const totalFailure = computed(() => {
339
- if (!flows.value)
340
- return 0;
341
- return flows.value.reduce((acc, flow) => acc + (flow.stats?.failure || 0), 0);
342
- });
343
- const totalRunning = computed(() => {
344
- if (!flows.value)
345
- return 0;
346
- return flows.value.reduce((acc, flow) => acc + (flow.stats?.running || 0), 0);
347
- });
348
- const totalAwaiting = computed(() => {
349
- if (!flows.value)
350
- return 0;
351
- return flows.value.reduce((acc, flow) => acc + (flow.stats?.awaiting || 0), 0);
352
- });
353
- const getStepCount = (flow) => {
354
- if (!flow.steps) return 0;
355
- return Object.keys(flow.steps).length;
356
- };
357
- const getLevelCount = (flow) => {
358
- if (!flow.levels) return 0;
359
- return Array.isArray(flow.levels) ? flow.levels.length : 0;
360
- };
361
- const getRuntimes = (flow) => {
362
- const runtimes = /* @__PURE__ */ new Set();
363
- if (!flow.steps) return [];
364
- for (const step of Object.values(flow.steps)) {
365
- if (step.runtime) {
366
- runtimes.add(step.runtime);
367
- }
368
- }
369
- return Array.from(runtimes);
370
- };
371
- function formatTimeout(ms) {
372
- if (ms < 1e3)
373
- return `${ms}ms`;
374
- if (ms < 6e4)
375
- return `${ms / 1e3}s`;
376
- return `${ms / 6e4}m`;
377
- }
378
- function openFlow(flowId) {
379
- router.push(`/flows/${flowId}`);
380
- }
381
- </script>
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;
@@ -1,236 +0,0 @@
1
- <template>
2
- <div class="h-full flex flex-col overflow-hidden">
3
- <!-- Header -->
4
- <div class="border-b border-gray-200 dark:border-gray-800 px-6 py-3 shrink-0">
5
- <div class="flex items-center justify-between">
6
- <div class="flex items-center gap-4">
7
- <h1 class="text-lg font-semibold">
8
- Queues
9
- </h1>
10
- </div>
11
- <LiveIndicator
12
- :is-connected="isConnected"
13
- :is-reconnecting="isReconnecting"
14
- />
15
- </div>
16
- </div>
17
-
18
- <!-- Main Content -->
19
- <div class="flex-1 min-h-0 overflow-y-auto">
20
- <div class="max-w-7xl mx-auto p-6">
21
- <!-- Stats Overview -->
22
- <div class="grid grid-cols-2 md:grid-cols-5 gap-4 mb-6">
23
- <StatCard
24
- icon="i-lucide-inbox"
25
- :count="queuesWithLive?.length || 0"
26
- label="Total Queues"
27
- variant="gray"
28
- />
29
- <StatCard
30
- icon="i-lucide-clock"
31
- :count="totalWaiting"
32
- label="Waiting"
33
- variant="blue"
34
- />
35
- <StatCard
36
- icon="i-lucide-loader-2"
37
- :count="totalActive"
38
- label="Active"
39
- variant="amber"
40
- />
41
- <StatCard
42
- icon="i-lucide-check-circle"
43
- :count="totalCompleted"
44
- label="Completed"
45
- variant="emerald"
46
- />
47
- <StatCard
48
- icon="i-lucide-x-circle"
49
- :count="totalFailed"
50
- label="Failed"
51
- variant="red"
52
- />
53
- </div>
54
-
55
- <!-- Queues List -->
56
- <div
57
- v-if="!queuesWithLive || queuesWithLive.length === 0"
58
- class="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 p-8 text-center text-gray-500"
59
- >
60
- <UIcon
61
- name="i-lucide-inbox"
62
- class="w-12 h-12 mx-auto mb-3 opacity-50"
63
- />
64
- <div>No queues found</div>
65
- </div>
66
- <div
67
- v-else
68
- class="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-800 overflow-hidden"
69
- >
70
- <div class="divide-y divide-gray-100 dark:divide-gray-800">
71
- <div
72
- v-for="queue in paginatedQueues"
73
- :key="queue.name"
74
- class="px-6 py-4 hover:bg-gray-50 dark:hover:bg-gray-900/50 transition-colors cursor-pointer"
75
- @click="selectQueue(queue.name)"
76
- >
77
- <div class="flex items-start justify-between gap-4">
78
- <!-- Left: Queue Info -->
79
- <div class="flex-1 min-w-0">
80
- <div class="flex items-center gap-2 mb-2">
81
- <UIcon
82
- name="i-lucide-inbox"
83
- class="w-4 h-4 shrink-0 text-blue-500"
84
- />
85
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 truncate">
86
- {{ queue.name }}
87
- </h3>
88
- <UBadge
89
- :label="queue.isPaused ? 'Paused' : 'Running'"
90
- :color="queue.isPaused ? 'warning' : 'success'"
91
- variant="subtle"
92
- size="xs"
93
- />
94
- </div>
95
-
96
- <div class="flex items-center gap-4 text-xs">
97
- <div
98
- class="flex items-center gap-1"
99
- :class="queue.counts.waiting > 0 ? 'text-blue-600 dark:text-blue-400' : 'text-gray-400 dark:text-gray-600'"
100
- >
101
- <UIcon
102
- name="i-lucide-clock"
103
- class="w-3 h-3"
104
- />
105
- <span>{{ queue.counts.waiting }} waiting</span>
106
- </div>
107
- <div
108
- class="flex items-center gap-1"
109
- :class="queue.counts.active > 0 ? 'text-amber-600 dark:text-amber-400' : 'text-gray-400 dark:text-gray-600'"
110
- >
111
- <UIcon
112
- name="i-lucide-loader-2"
113
- class="w-3 h-3"
114
- />
115
- <span>{{ queue.counts.active }} active</span>
116
- </div>
117
- <div
118
- class="flex items-center gap-1"
119
- :class="queue.counts.completed > 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-gray-400 dark:text-gray-600'"
120
- >
121
- <UIcon
122
- name="i-lucide-check-circle"
123
- class="w-3 h-3"
124
- />
125
- <span>{{ queue.counts.completed }} completed</span>
126
- </div>
127
- <div
128
- class="flex items-center gap-1"
129
- :class="queue.counts.failed > 0 ? 'text-red-600 dark:text-red-400' : 'text-gray-400 dark:text-gray-600'"
130
- >
131
- <UIcon
132
- name="i-lucide-x-circle"
133
- class="w-3 h-3"
134
- />
135
- <span>{{ queue.counts.failed }} failed</span>
136
- </div>
137
- <div
138
- class="flex items-center gap-1"
139
- :class="queue.counts.delayed > 0 ? 'text-purple-600 dark:text-purple-400' : 'text-gray-400 dark:text-gray-600'"
140
- >
141
- <UIcon
142
- name="i-lucide-timer"
143
- class="w-3 h-3"
144
- />
145
- <span>{{ queue.counts.delayed }} delayed</span>
146
- </div>
147
- </div>
148
- </div>
149
-
150
- <!-- Right: Actions -->
151
- <div class="flex items-center gap-3">
152
- <!-- Arrow Button -->
153
- <UButton
154
- icon="i-lucide-arrow-right"
155
- size="xs"
156
- color="neutral"
157
- variant="ghost"
158
- square
159
- />
160
- </div>
161
- </div>
162
- </div>
163
- </div>
164
-
165
- <!-- Pagination -->
166
- <div
167
- v-if="totalPages > 1"
168
- class="border-t border-gray-200 dark:border-gray-800 px-6 py-4 flex items-center justify-center"
169
- >
170
- <UPagination
171
- v-model="currentPage"
172
- :total="queuesWithLive.length"
173
- :items-per-page="itemsPerPage"
174
- />
175
- </div>
176
- </div>
177
-
178
- <!-- Footer Info -->
179
- <div
180
- v-if="queuesWithLive && queuesWithLive.length > 0"
181
- class="mt-4 text-center text-sm text-gray-500 dark:text-gray-400"
182
- >
183
- Showing {{ startIndex + 1 }}-{{ endIndex }} of {{ queuesWithLive.length }} queue{{ queuesWithLive.length === 1 ? "" : "s" }}
184
- </div>
185
- </div>
186
- </div>
187
- </div>
188
- </template>
189
-
190
- <script setup>
191
- import { ref, computed } from "#imports";
192
- import { useQueues } from "../../composables/useQueues";
193
- import { useQueuesLive } from "../../composables/useQueuesLive";
194
- import { useComponentRouter } from "../../composables/useComponentRouter";
195
- import StatCard from "../../components/StatCard.vue";
196
- import LiveIndicator from "../../components/LiveIndicator.vue";
197
- const { queues } = useQueues();
198
- const { queues: queuesWithLive, isConnected, isReconnecting } = useQueuesLive(queues);
199
- const router = useComponentRouter();
200
- const selectQueue = (queueName) => {
201
- router.push(`/queues/${queueName}/jobs`);
202
- };
203
- const currentPage = ref(1);
204
- const itemsPerPage = 10;
205
- const totalPages = computed(() => {
206
- if (!queuesWithLive.value) return 0;
207
- return Math.ceil(queuesWithLive.value.length / itemsPerPage);
208
- });
209
- const startIndex = computed(() => {
210
- return (currentPage.value - 1) * itemsPerPage;
211
- });
212
- const endIndex = computed(() => {
213
- if (!queuesWithLive.value) return 0;
214
- return Math.min(startIndex.value + itemsPerPage, queuesWithLive.value.length);
215
- });
216
- const paginatedQueues = computed(() => {
217
- if (!queuesWithLive.value) return [];
218
- return queuesWithLive.value.slice(startIndex.value, endIndex.value);
219
- });
220
- const totalWaiting = computed(() => {
221
- if (!queuesWithLive.value) return 0;
222
- return queuesWithLive.value.reduce((sum, q) => sum + q.counts.waiting, 0);
223
- });
224
- const totalActive = computed(() => {
225
- if (!queuesWithLive.value) return 0;
226
- return queuesWithLive.value.reduce((sum, q) => sum + q.counts.active, 0);
227
- });
228
- const totalCompleted = computed(() => {
229
- if (!queuesWithLive.value) return 0;
230
- return queuesWithLive.value.reduce((sum, q) => sum + q.counts.completed, 0);
231
- });
232
- const totalFailed = computed(() => {
233
- if (!queuesWithLive.value) return 0;
234
- return queuesWithLive.value.reduce((sum, q) => sum + q.counts.failed, 0);
235
- });
236
- </script>
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;