@nvent-addon/app 0.5.15 → 1.0.0-alpha.2

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,595 +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
- <UButton
8
- icon="i-lucide-arrow-left"
9
- size="xs"
10
- color="neutral"
11
- variant="ghost"
12
- @click="back"
13
- />
14
- <div>
15
- <h1 class="text-lg font-semibold">
16
- {{ queueName }}
17
- </h1>
18
- <p class="text-xs text-gray-500">
19
- Queue Jobs
20
- </p>
21
- </div>
22
- </div>
23
- <div class="flex items-center gap-3">
24
- <div
25
- v-if="isConnected"
26
- class="flex items-center gap-1.5 text-xs text-emerald-600 dark:text-emerald-400"
27
- >
28
- <div class="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
29
- <span>Live</span>
30
- </div>
31
- <div
32
- v-else-if="isReconnecting"
33
- class="flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400"
34
- >
35
- <div class="w-2 h-2 rounded-full bg-amber-500 animate-pulse" />
36
- <span>Reconnecting...</span>
37
- </div>
38
- <UButton
39
- icon="i-lucide-settings"
40
- size="xs"
41
- color="neutral"
42
- variant="ghost"
43
- square
44
- title="View configuration"
45
- @click="showConfig = !showConfig"
46
- />
47
- </div>
48
- </div>
49
- </div>
50
-
51
- <!-- Main Content -->
52
- <div class="flex-1 min-h-0 overflow-hidden">
53
- <div class="h-full flex gap-px bg-gray-200 dark:bg-gray-800">
54
- <!-- Left: Jobs List -->
55
- <div class="w-1/3 min-w-0 flex-shrink-0 bg-white dark:bg-gray-950 flex flex-col min-h-0 overflow-hidden">
56
- <div class="px-4 py-3 border-b border-gray-200 dark:border-gray-800 flex items-center justify-between shrink-0">
57
- <h2 class="text-sm font-medium text-gray-900 dark:text-gray-100">
58
- Jobs
59
- </h2>
60
- <div class="flex items-center gap-2">
61
- <USelectMenu
62
- v-model="selectedStateOption"
63
- :items="stateOptions"
64
- placeholder="All States"
65
- size="xs"
66
- class="w-32"
67
- />
68
- </div>
69
- </div>
70
-
71
- <div
72
- v-if="!data || !data.jobs || data.jobs.length === 0"
73
- class="flex-1 flex items-center justify-center"
74
- >
75
- <div class="text-center">
76
- <UIcon
77
- name="i-lucide-inbox"
78
- class="w-8 h-8 mx-auto mb-2 text-gray-300 dark:text-gray-700"
79
- />
80
- <p class="text-sm text-gray-500 dark:text-gray-400">
81
- No jobs found
82
- </p>
83
- </div>
84
- </div>
85
-
86
- <div
87
- v-else
88
- class="flex-1 min-h-0 overflow-y-auto"
89
- >
90
- <div class="divide-y divide-gray-100 dark:divide-gray-800">
91
- <SelectableListItem
92
- v-for="job in paginatedJobs"
93
- :key="job.id"
94
- :selected="selectedJobId === job.id"
95
- :icon="getJobIcon(job.state)"
96
- :icon-class="getJobIconColor(job.state)"
97
- :title="job.name"
98
- :subtitle="truncateId(job.id)"
99
- :badge="job.state || 'unknown'"
100
- :badge-color="getStateBadgeColor(job.state)"
101
- @click="selectJob(job.id)"
102
- >
103
- <template #meta>
104
- <span v-if="job.timestamp">
105
- {{ formatTime(job.timestamp) }}
106
- </span>
107
- <span v-if="job.finishedOn && job.processedOn">
108
- • {{ formatDuration(job.processedOn, job.finishedOn) }}
109
- </span>
110
- </template>
111
- </SelectableListItem>
112
- </div>
113
- </div>
114
-
115
- <!-- Pagination Footer -->
116
- <div
117
- v-if="data && data.total > jobsPerPage"
118
- class="border-t border-gray-200 dark:border-gray-800 px-4 py-3 flex items-center justify-center shrink-0"
119
- >
120
- <UPagination
121
- v-model:page="currentPage"
122
- :items-per-page="jobsPerPage"
123
- :total="data.total"
124
- size="xs"
125
- />
126
- </div>
127
- </div>
128
-
129
- <!-- Right: Overview or Job Details -->
130
- <div class="flex-1 min-w-0 bg-white dark:bg-gray-950 flex flex-col min-h-0 overflow-hidden">
131
- <div class="px-4 py-2.5 border-b border-gray-200 dark:border-gray-800 shrink-0">
132
- <div class="flex items-center justify-between">
133
- <UTabs
134
- v-model="activeTab"
135
- :items="tabItems"
136
- size="xs"
137
- :ui="{
138
- root: 'gap-0',
139
- trigger: 'px-2 py-0.5'
140
- }"
141
- />
142
- </div>
143
- </div>
144
-
145
- <div class="flex-1 min-h-0 overflow-y-auto">
146
- <!-- Overview Tab -->
147
- <div
148
- v-if="activeTab === 'overview'"
149
- class="p-6 space-y-6"
150
- >
151
- <!-- Stats Cards -->
152
- <div>
153
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4">
154
- Queue Statistics
155
- </h3>
156
- <div class="grid grid-cols-2 gap-4">
157
- <StatCard
158
- icon="i-lucide-clock"
159
- :count="counts?.waiting || 0"
160
- label="Waiting"
161
- variant="blue"
162
- />
163
- <StatCard
164
- icon="i-lucide-loader-2"
165
- :count="counts?.active || 0"
166
- label="Active"
167
- variant="amber"
168
- />
169
- <StatCard
170
- icon="i-lucide-check-circle"
171
- :count="counts?.completed || 0"
172
- label="Completed"
173
- variant="emerald"
174
- />
175
- <StatCard
176
- icon="i-lucide-x-circle"
177
- :count="counts?.failed || 0"
178
- label="Failed"
179
- variant="red"
180
- />
181
- <StatCard
182
- icon="i-lucide-timer"
183
- :count="counts?.delayed || 0"
184
- label="Delayed"
185
- variant="purple"
186
- />
187
- <StatCard
188
- icon="i-lucide-pause-circle"
189
- :count="counts?.paused || 0"
190
- label="Paused"
191
- variant="gray"
192
- />
193
- </div>
194
- </div>
195
-
196
- <!-- Queue Configuration -->
197
- <div>
198
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4">
199
- Queue Configuration
200
- </h3>
201
- <div class="bg-gray-50 dark:bg-gray-900/50 rounded-lg p-4 space-y-3">
202
- <div class="flex items-center justify-between py-2 border-b border-gray-200 dark:border-gray-800">
203
- <span class="text-sm text-gray-600 dark:text-gray-400">Queue Name</span>
204
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100 font-mono">{{ queueName }}</span>
205
- </div>
206
- <div class="flex items-center justify-between py-2 border-b border-gray-200 dark:border-gray-800">
207
- <span class="text-sm text-gray-600 dark:text-gray-400">Total Jobs</span>
208
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ data?.jobs?.length || 0 }}</span>
209
- </div>
210
- <div class="flex items-center justify-between py-2">
211
- <span class="text-sm text-gray-600 dark:text-gray-400">Connection Status</span>
212
- <UBadge
213
- :label="isConnected ? 'Connected' : isReconnecting ? 'Reconnecting' : 'Disconnected'"
214
- :color="isConnected ? 'success' : isReconnecting ? 'warning' : 'error'"
215
- variant="subtle"
216
- size="xs"
217
- />
218
- </div>
219
- </div>
220
- </div>
221
- </div>
222
-
223
- <!-- Job Details Tab -->
224
- <div
225
- v-else-if="activeTab === 'details' && selectedJob"
226
- class="p-6 space-y-6"
227
- >
228
- <!-- Job Info -->
229
- <div>
230
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4 flex items-center gap-2">
231
- <UIcon
232
- :name="getJobIcon(selectedJob.state)"
233
- class="w-5 h-5"
234
- :class="getJobIconColor(selectedJob.state)"
235
- />
236
- <span>Job Information</span>
237
- </h3>
238
- <div class="bg-gray-50 dark:bg-gray-900/50 rounded-lg p-4 space-y-3">
239
- <div class="flex items-center justify-between py-2 border-b border-gray-200 dark:border-gray-800">
240
- <span class="text-sm text-gray-600 dark:text-gray-400">ID</span>
241
- <span class="text-xs font-mono text-gray-900 dark:text-gray-100">{{ selectedJob.id }}</span>
242
- </div>
243
- <div class="flex items-center justify-between py-2 border-b border-gray-200 dark:border-gray-800">
244
- <span class="text-sm text-gray-600 dark:text-gray-400">Name</span>
245
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ selectedJob.name }}</span>
246
- </div>
247
- <div class="flex items-center justify-between py-2">
248
- <span class="text-sm text-gray-600 dark:text-gray-400">State</span>
249
- <UBadge
250
- :label="selectedJob.state || 'unknown'"
251
- :color="getStateBadgeColor(selectedJob.state)"
252
- variant="subtle"
253
- size="xs"
254
- class="capitalize"
255
- />
256
- </div>
257
- </div>
258
- </div>
259
-
260
- <!-- Timing -->
261
- <div>
262
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4">
263
- Timing
264
- </h3>
265
- <div class="space-y-4">
266
- <div class="grid grid-cols-1 gap-3">
267
- <div class="flex items-center justify-between py-2 bg-gray-50 dark:bg-gray-900/50 rounded-lg px-4">
268
- <span class="text-sm text-gray-600 dark:text-gray-400">Created</span>
269
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ formatDate(selectedJob.timestamp) }}</span>
270
- </div>
271
- <div
272
- v-if="selectedJob.processedOn"
273
- class="flex items-center justify-between py-2 bg-gray-50 dark:bg-gray-900/50 rounded-lg px-4"
274
- >
275
- <span class="text-sm text-gray-600 dark:text-gray-400">Processed</span>
276
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ formatDate(selectedJob.processedOn) }}</span>
277
- </div>
278
- <div
279
- v-if="selectedJob.finishedOn"
280
- class="flex items-center justify-between py-2 bg-gray-50 dark:bg-gray-900/50 rounded-lg px-4"
281
- >
282
- <span class="text-sm text-gray-600 dark:text-gray-400">Finished</span>
283
- <span class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ formatDate(selectedJob.finishedOn) }}</span>
284
- </div>
285
- </div>
286
-
287
- <!-- Duration Cards -->
288
- <div
289
- v-if="selectedJobWaitDuration || selectedJobExecutionDuration"
290
- class="grid grid-cols-2 gap-3 pt-2"
291
- >
292
- <div
293
- v-if="selectedJobWaitDuration"
294
- class="bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800 rounded-lg p-4 text-center"
295
- >
296
- <p class="text-xs text-blue-600 dark:text-blue-400 mb-1">
297
- Wait Time
298
- </p>
299
- <p class="text-lg font-bold text-blue-700 dark:text-blue-300">
300
- {{ selectedJobWaitDuration }}
301
- </p>
302
- </div>
303
- <div
304
- v-if="selectedJobExecutionDuration"
305
- class="rounded-lg p-4 text-center border"
306
- :class="selectedJob.state === 'active' ? 'bg-amber-50 dark:bg-amber-950/30 border-amber-200 dark:border-amber-800' : 'bg-emerald-50 dark:bg-emerald-950/30 border-emerald-200 dark:border-emerald-800'"
307
- >
308
- <p
309
- class="text-xs mb-1"
310
- :class="selectedJob.state === 'active' ? 'text-amber-600 dark:text-amber-400' : 'text-emerald-600 dark:text-emerald-400'"
311
- >
312
- {{ selectedJob.state === "active" ? "Running" : "Execution" }}
313
- </p>
314
- <p
315
- class="text-lg font-bold"
316
- :class="selectedJob.state === 'active' ? 'text-amber-700 dark:text-amber-300' : 'text-emerald-700 dark:text-emerald-300'"
317
- >
318
- {{ selectedJobExecutionDuration }}
319
- </p>
320
- </div>
321
- </div>
322
- </div>
323
- </div>
324
-
325
- <!-- Job Data -->
326
- <div>
327
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4">
328
- Job Data
329
- </h3>
330
- <div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4 overflow-x-auto">
331
- <pre class="text-xs font-mono">{{ JSON.stringify(selectedJob.data, null, 2) }}</pre>
332
- </div>
333
- </div>
334
-
335
- <!-- Return Value -->
336
- <div v-if="selectedJob.returnvalue">
337
- <h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-4">
338
- Return Value
339
- </h3>
340
- <div class="bg-emerald-50 dark:bg-emerald-950/30 border border-emerald-200 dark:border-emerald-800 rounded-lg p-4 overflow-x-auto">
341
- <pre class="text-xs font-mono text-emerald-900 dark:text-emerald-100">{{ JSON.stringify(selectedJob.returnvalue, null, 2) }}</pre>
342
- </div>
343
- </div>
344
-
345
- <!-- Error -->
346
- <div v-if="selectedJob.failedReason">
347
- <h3 class="text-sm font-semibold text-red-600 dark:text-red-400 mb-4">
348
- Error
349
- </h3>
350
- <div class="bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 rounded-lg p-4">
351
- <p class="text-sm text-red-700 dark:text-red-300 whitespace-pre-wrap">
352
- {{ selectedJob.failedReason }}
353
- </p>
354
- </div>
355
- </div>
356
- </div>
357
- </div>
358
- </div>
359
- </div>
360
- </div>
361
-
362
- <!-- Configuration Slideover -->
363
- <USlideover
364
- v-model:open="showConfig"
365
- title="Queue Configuration"
366
- >
367
- <template #body>
368
- <QueueConfiguration
369
- :queue-name="queueName"
370
- :queue-config="queueInfo?.config?.queue"
371
- :worker-config="queueInfo?.config?.worker"
372
- />
373
- </template>
374
- </USlideover>
375
- </div>
376
- </template>
377
-
378
- <script setup>
379
- import { ref, computed, watch } from "#imports";
380
- import { useQueueJobs } from "../../composables/useQueueJobs";
381
- import { useQueueUpdates } from "../../composables/useQueueUpdates";
382
- import { useQueues } from "../../composables/useQueues";
383
- import { useComponentRouter } from "../../composables/useComponentRouter";
384
- import { useRoute, useRouter } from "#app";
385
- import StatCard from "../../components/StatCard.vue";
386
- import QueueConfiguration from "../../components/QueueConfiguration.vue";
387
- import SelectableListItem from "../../components/SelectableListItem.vue";
388
- const componentRouter = useComponentRouter();
389
- const router = useRouter();
390
- const route = useRoute();
391
- const queueName = computed(() => componentRouter.route.value?.params?.name || "");
392
- const stateOptions = [
393
- { label: "All States", value: null },
394
- { label: "Waiting", value: "waiting" },
395
- { label: "Active", value: "active" },
396
- { label: "Completed", value: "completed" },
397
- { label: "Failed", value: "failed" },
398
- { label: "Delayed", value: "delayed" },
399
- { label: "Paused", value: "paused" }
400
- ];
401
- const selectedState = computed({
402
- get: () => route.query.state || null,
403
- set: (value) => {
404
- router.push({
405
- query: {
406
- ...route.query,
407
- state: value || void 0,
408
- page: void 0
409
- // Reset page when filter changes
410
- }
411
- });
412
- }
413
- });
414
- const currentPage = computed({
415
- get: () => {
416
- const page = route.query.page;
417
- return page ? Number.parseInt(page, 10) : 1;
418
- },
419
- set: (value) => {
420
- router.push({
421
- query: {
422
- ...route.query,
423
- page: value > 1 ? value.toString() : void 0
424
- }
425
- });
426
- }
427
- });
428
- const selectedStateOption = computed({
429
- get: () => stateOptions.find((opt) => opt.value === selectedState.value) || stateOptions[0],
430
- set: (option) => {
431
- selectedState.value = option.value;
432
- }
433
- });
434
- const jobsPerPage = 20;
435
- const jobQueryOptions = computed(() => ({
436
- state: selectedState.value,
437
- limit: jobsPerPage,
438
- offset: (currentPage.value - 1) * jobsPerPage
439
- }));
440
- const { data, refresh } = useQueueJobs(queueName, jobQueryOptions);
441
- const { counts: liveCounts, isConnected, isReconnecting, shouldRefreshJobs, resetRefreshFlag } = useQueueUpdates(queueName);
442
- const { queues } = useQueues();
443
- const queueInfo = computed(() => {
444
- return queues.value?.find((q) => q.name === queueName.value);
445
- });
446
- const counts = computed(() => liveCounts.value || queueInfo.value?.counts || null);
447
- watch(shouldRefreshJobs, async (shouldRefresh) => {
448
- if (shouldRefresh) {
449
- await refresh();
450
- resetRefreshFlag();
451
- }
452
- });
453
- watch(() => jobQueryOptions.value, () => {
454
- refresh();
455
- }, { deep: true });
456
- const paginatedJobs = computed(() => {
457
- return data.value?.jobs || [];
458
- });
459
- const selectedJobId = ref(null);
460
- const selectedJob = computed(() => {
461
- if (!selectedJobId.value || !data.value?.jobs) return null;
462
- return data.value.jobs.find((job) => job.id === selectedJobId.value);
463
- });
464
- const showConfig = ref(false);
465
- const activeTab = ref("overview");
466
- const tabItems = computed(() => [
467
- { label: "Overview", value: "overview", icon: "i-lucide-bar-chart-3" },
468
- {
469
- label: "Job Details",
470
- value: "details",
471
- icon: "i-lucide-file-text",
472
- disabled: !selectedJobId.value
473
- }
474
- ]);
475
- watch(selectedJobId, (newId) => {
476
- if (newId) {
477
- activeTab.value = "details";
478
- showConfig.value = false;
479
- } else {
480
- activeTab.value = "overview";
481
- }
482
- });
483
- watch(showConfig, (show) => {
484
- if (show) {
485
- selectedJobId.value = null;
486
- }
487
- });
488
- const selectJob = (jobId) => {
489
- selectedJobId.value = jobId;
490
- };
491
- const back = () => {
492
- componentRouter.push("/queues");
493
- };
494
- const getJobIcon = (state) => {
495
- switch (state) {
496
- case "waiting":
497
- return "i-lucide-clock";
498
- case "active":
499
- return "i-lucide-loader-2";
500
- case "completed":
501
- return "i-lucide-check-circle";
502
- case "failed":
503
- return "i-lucide-x-circle";
504
- case "delayed":
505
- return "i-lucide-timer";
506
- case "paused":
507
- return "i-lucide-pause-circle";
508
- default:
509
- return "i-lucide-circle";
510
- }
511
- };
512
- const getJobIconColor = (state) => {
513
- switch (state) {
514
- case "waiting":
515
- return "text-blue-500";
516
- case "active":
517
- return "text-amber-500 animate-spin";
518
- case "completed":
519
- return "text-emerald-500";
520
- case "failed":
521
- return "text-red-500";
522
- case "delayed":
523
- return "text-purple-500";
524
- case "paused":
525
- return "text-gray-500";
526
- default:
527
- return "text-gray-400";
528
- }
529
- };
530
- const getStateBadgeColor = (state) => {
531
- switch (state) {
532
- case "waiting":
533
- return "info";
534
- case "active":
535
- return "warning";
536
- case "completed":
537
- return "success";
538
- case "failed":
539
- return "error";
540
- case "delayed":
541
- return "secondary";
542
- case "paused":
543
- return "warning";
544
- default:
545
- return "neutral";
546
- }
547
- };
548
- const truncateId = (id) => {
549
- if (id.length <= 16) return id;
550
- return `${id.substring(0, 8)}...${id.substring(id.length - 8)}`;
551
- };
552
- const formatTime = (timestamp) => {
553
- if (!timestamp) return "-";
554
- const date = new Date(timestamp);
555
- const now = /* @__PURE__ */ new Date();
556
- const diff = now.getTime() - date.getTime();
557
- const seconds = Math.floor(diff / 1e3);
558
- const minutes = Math.floor(seconds / 60);
559
- const hours = Math.floor(minutes / 60);
560
- const days = Math.floor(hours / 24);
561
- if (days > 0) return `${days}d ago`;
562
- if (hours > 0) return `${hours}h ago`;
563
- if (minutes > 0) return `${minutes}m ago`;
564
- if (seconds > 10) return `${seconds}s ago`;
565
- return "just now";
566
- };
567
- const formatDuration = (start, end) => {
568
- const diff = end - start;
569
- if (diff < 1e3) return `${diff}ms`;
570
- if (diff < 6e4) return `${(diff / 1e3).toFixed(2)}s`;
571
- if (diff < 36e5) return `${(diff / 6e4).toFixed(2)}m`;
572
- return `${(diff / 36e5).toFixed(2)}h`;
573
- };
574
- const formatDate = (timestamp) => {
575
- if (!timestamp) return "-";
576
- return new Date(timestamp).toLocaleString("de-DE", {
577
- timeZone: "Europe/Berlin",
578
- day: "2-digit",
579
- month: "2-digit",
580
- year: "numeric",
581
- hour: "2-digit",
582
- minute: "2-digit",
583
- second: "2-digit"
584
- });
585
- };
586
- const selectedJobWaitDuration = computed(() => {
587
- if (!selectedJob.value?.timestamp || !selectedJob.value?.processedOn) return null;
588
- return formatDuration(selectedJob.value.timestamp, selectedJob.value.processedOn);
589
- });
590
- const selectedJobExecutionDuration = computed(() => {
591
- if (!selectedJob.value?.processedOn) return null;
592
- const endTime = selectedJob.value.finishedOn || Date.now();
593
- return formatDuration(selectedJob.value.processedOn, endTime);
594
- });
595
- </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;