queen-mq 0.1.5 → 0.2.0

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 (135) hide show
  1. package/README.md +467 -1775
  2. package/package.json +12 -14
  3. package/src/client/client.js +664 -5
  4. package/src/managers/queueManagerOptimized.js +250 -47
  5. package/src/routes/ack.js +3 -3
  6. package/src/server.js +131 -3
  7. package/src/test/advanced-client-tests.js +761 -0
  8. package/src/test/advanced-pattern-tests.js +2 -2
  9. package/src/test/bus-mode-tests.js +6 -6
  10. package/src/test/core-tests.js +1 -1
  11. package/src/test/edge-case-tests.js +2 -2
  12. package/src/test/test-new.js +36 -1
  13. package/src/webapp-dist/assets/Analytics-DJrE4Rz2.css +1 -0
  14. package/src/webapp-dist/assets/Analytics-HEMXKmfJ.js +1 -0
  15. package/src/webapp-dist/assets/ConfirmDialog-YEoCdE7x.js +1 -0
  16. package/src/webapp-dist/assets/ConsumerGroups-CC5VJywp.css +1 -0
  17. package/src/webapp-dist/assets/ConsumerGroups-D8Z20HhZ.js +1 -0
  18. package/src/webapp-dist/assets/Dashboard-BRFOz6it.css +1 -0
  19. package/src/webapp-dist/assets/Dashboard-Bpx9I32h.js +1 -0
  20. package/src/webapp-dist/assets/LoadingSpinner-BPttXcbs.js +1 -0
  21. package/src/webapp-dist/assets/Messages-BOfVHKma.css +1 -0
  22. package/src/webapp-dist/assets/Messages-EKURCbLl.js +1 -0
  23. package/src/webapp-dist/assets/QueueDetail-BXXA7xoZ.css +1 -0
  24. package/src/webapp-dist/assets/QueueDetail-Bmxg0KiA.js +1 -0
  25. package/src/webapp-dist/assets/Queues-CvrJkrZT.css +1 -0
  26. package/src/webapp-dist/assets/Queues-yUx9_3-9.js +1 -0
  27. package/src/webapp-dist/assets/StatusBadge-C1bBtXHh.css +1 -0
  28. package/src/webapp-dist/assets/StatusBadge-C6N84XmO.js +1 -0
  29. package/src/webapp-dist/assets/analytics-BapTekLM.js +1 -0
  30. package/src/webapp-dist/assets/colors-5z6Q_kUr.js +18 -0
  31. package/src/webapp-dist/assets/index-B7w2bKT6.css +1 -0
  32. package/src/webapp-dist/assets/index-CUSnwYTH.js +31 -0
  33. package/src/webapp-dist/assets/messages-CRV6E-xU.js +1 -0
  34. package/src/webapp-dist/assets/queues-BdUbxfBC.js +1 -0
  35. package/src/webapp-dist/assets/resources-Bs9U-ceF.js +1 -0
  36. package/{webapp → src/webapp-dist}/index.html +2 -1
  37. package/API.md +0 -1226
  38. package/AUTH.md +0 -2044
  39. package/CHANGELOG_STATIC_SERVING.md +0 -213
  40. package/DEPLOYMENT.md +0 -425
  41. package/PROGRAMMATIC_SERVER.md +0 -239
  42. package/WEBAPP.md +0 -1889
  43. package/assets/dashboard-01.png +0 -0
  44. package/assets/dashboard.png +0 -0
  45. package/examples/batch-processing.js +0 -58
  46. package/examples/bus-mode.js +0 -239
  47. package/examples/continuous-consumer-optimized.js +0 -215
  48. package/examples/continuous-consumer.js +0 -159
  49. package/examples/continuous-producer.js +0 -343
  50. package/examples/mixed-mode.js +0 -277
  51. package/examples/multi-server-test.js +0 -305
  52. package/examples/programmatic-server.js +0 -58
  53. package/examples/server-with-frontend.js +0 -46
  54. package/examples/single.js +0 -64
  55. package/examples/smartchat-dealyed.js +0 -42
  56. package/examples/smartchat.js +0 -52
  57. package/examples/test-cache-invalidation.js +0 -119
  58. package/examples/test-cache-multi-server.js +0 -245
  59. package/examples/test-complete-client.js +0 -260
  60. package/examples/test-connection-recovery.js +0 -66
  61. package/examples/test-dashboard-api.js +0 -200
  62. package/examples/test-minimal-client.js +0 -112
  63. package/examples/test-queue-creation-policy.js +0 -137
  64. package/examples/test-traceid.js +0 -147
  65. package/server.log +0 -1
  66. package/test-keepalive-v2.sh +0 -22
  67. package/webapp/COLOR_GUIDE.md +0 -118
  68. package/webapp/README.md +0 -143
  69. package/webapp/package-lock.json +0 -3184
  70. package/webapp/package.json +0 -25
  71. package/webapp/postcss.config.js +0 -7
  72. package/webapp/public/assets/queen-logo-blue.svg +0 -210
  73. package/webapp/public/assets/queen-logo-cyan.svg +0 -210
  74. package/webapp/public/assets/queen-logo-indigo.svg +0 -210
  75. package/webapp/public/assets/queen-logo-orange.svg +0 -210
  76. package/webapp/public/assets/queen-logo-pink.svg +0 -210
  77. package/webapp/public/assets/queen-logo-purple.svg +0 -210
  78. package/webapp/public/assets/queen-logo-rose.svg +0 -239
  79. package/webapp/public/assets/queen-logo.svg +0 -263
  80. package/webapp/src/App.vue +0 -19
  81. package/webapp/src/api/analytics.js +0 -10
  82. package/webapp/src/api/client.js +0 -34
  83. package/webapp/src/api/consumers.js +0 -52
  84. package/webapp/src/api/health.js +0 -7
  85. package/webapp/src/api/messages.js +0 -26
  86. package/webapp/src/api/queues.js +0 -14
  87. package/webapp/src/api/resources.js +0 -8
  88. package/webapp/src/assets/styles/main.css +0 -357
  89. package/webapp/src/components/analytics/AnalyticsFilters.vue +0 -87
  90. package/webapp/src/components/analytics/AnalyticsMetrics.vue +0 -57
  91. package/webapp/src/components/analytics/MessageDistributionChart.vue +0 -111
  92. package/webapp/src/components/analytics/MessageFlowChart.vue +0 -173
  93. package/webapp/src/components/analytics/TimeRangeSelector.vue +0 -27
  94. package/webapp/src/components/analytics/TopQueuesChart.vue +0 -132
  95. package/webapp/src/components/common/ConfirmDialog.vue +0 -56
  96. package/webapp/src/components/common/LoadingSpinner.vue +0 -6
  97. package/webapp/src/components/common/MetricCard.vue +0 -43
  98. package/webapp/src/components/common/StatusBadge.vue +0 -45
  99. package/webapp/src/components/dashboard/MessageStatusCard.vue +0 -50
  100. package/webapp/src/components/dashboard/PerformanceCard.vue +0 -38
  101. package/webapp/src/components/dashboard/ThroughputChart.vue +0 -182
  102. package/webapp/src/components/dashboard/TopQueuesTable.vue +0 -53
  103. package/webapp/src/components/layout/AppLayout.vue +0 -110
  104. package/webapp/src/components/layout/AppSidebar.vue +0 -304
  105. package/webapp/src/components/messages/MessageDetailPanel.vue +0 -242
  106. package/webapp/src/components/messages/MessageFilters.vue +0 -101
  107. package/webapp/src/components/queue-detail/PartitionList.vue +0 -79
  108. package/webapp/src/components/queue-detail/PushMessageModal.vue +0 -175
  109. package/webapp/src/components/queue-detail/QueueConfig.vue +0 -63
  110. package/webapp/src/components/queue-detail/QueueDetailHeader.vue +0 -53
  111. package/webapp/src/components/queue-detail/RecentMessages.vue +0 -76
  112. package/webapp/src/components/queues/CreateQueueModal.vue +0 -193
  113. package/webapp/src/components/queues/QueueFilters.vue +0 -90
  114. package/webapp/src/composables/useApi.js +0 -34
  115. package/webapp/src/composables/useTheme.js +0 -36
  116. package/webapp/src/main.js +0 -11
  117. package/webapp/src/router/index.js +0 -42
  118. package/webapp/src/utils/colors.js +0 -96
  119. package/webapp/src/utils/formatters.js +0 -49
  120. package/webapp/src/views/Analytics.vue +0 -377
  121. package/webapp/src/views/ConsumerGroups.vue +0 -433
  122. package/webapp/src/views/Dashboard.vue +0 -418
  123. package/webapp/src/views/Messages.vue +0 -363
  124. package/webapp/src/views/QueueDetail.vue +0 -582
  125. package/webapp/src/views/Queues.vue +0 -496
  126. package/webapp/tailwind.config.js +0 -25
  127. package/webapp/vite.config.js +0 -10
  128. /package/{assets → src/webapp-dist/assets}/queen-logo-blue.svg +0 -0
  129. /package/{assets → src/webapp-dist/assets}/queen-logo-cyan.svg +0 -0
  130. /package/{assets → src/webapp-dist/assets}/queen-logo-indigo.svg +0 -0
  131. /package/{assets → src/webapp-dist/assets}/queen-logo-orange.svg +0 -0
  132. /package/{assets → src/webapp-dist/assets}/queen-logo-pink.svg +0 -0
  133. /package/{assets → src/webapp-dist/assets}/queen-logo-purple.svg +0 -0
  134. /package/{assets → src/webapp-dist/assets}/queen-logo-rose.svg +0 -0
  135. /package/{assets → src/webapp-dist/assets}/queen-logo.svg +0 -0
@@ -1,357 +0,0 @@
1
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
2
-
3
- @tailwind base;
4
- @tailwind components;
5
- @tailwind utilities;
6
-
7
- @layer base {
8
- * {
9
- @apply border-gray-200 dark:border-gray-700;
10
- }
11
-
12
- body {
13
- @apply bg-gray-100 dark:bg-[#0d1117] text-gray-900 dark:text-gray-100 text-sm antialiased;
14
- }
15
-
16
- h1 {
17
- @apply text-xl font-semibold tracking-tight;
18
- }
19
-
20
- h2 {
21
- @apply text-lg font-semibold tracking-tight;
22
- }
23
-
24
- h3 {
25
- @apply text-base font-semibold tracking-tight;
26
- }
27
- }
28
-
29
- @layer components {
30
- .card {
31
- @apply bg-white dark:bg-slate-800 rounded-xl shadow-sm border p-4 sm:p-5
32
- transition-all duration-200 hover:shadow-md;
33
- background: linear-gradient(to bottom, white, white) padding-box,
34
- linear-gradient(to bottom, transparent, transparent) border-box;
35
- }
36
-
37
- .dark .card {
38
- background: linear-gradient(to bottom, rgb(30, 41, 59), rgb(30, 41, 59)) padding-box,
39
- linear-gradient(to bottom, rgba(248, 113, 113, 0.1), rgba(168, 85, 247, 0.1)) border-box;
40
- }
41
-
42
- /* Metric cards with top accent */
43
- .metric-card {
44
- @apply card relative;
45
- }
46
-
47
- .metric-card:hover {
48
- @apply shadow-lg;
49
- transform: translateY(-2px);
50
- }
51
-
52
- .btn {
53
- @apply px-4 py-2 rounded-lg font-medium transition-all duration-200 text-sm
54
- inline-flex items-center justify-center gap-2;
55
- }
56
-
57
- .btn:active {
58
- @apply scale-95;
59
- }
60
-
61
- .btn-primary {
62
- @apply bg-gradient-to-br from-rose-600 to-rose-700 hover:from-rose-700 hover:to-rose-800
63
- active:from-rose-800 active:to-rose-900 text-white shadow-sm hover:shadow-md
64
- disabled:opacity-50 disabled:cursor-not-allowed;
65
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05), 0 0 0 1px rgb(244 63 94 / 0.1);
66
- }
67
-
68
- .btn-primary:hover {
69
- box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1),
70
- 0 0 0 1px rgb(244 63 94 / 0.2);
71
- }
72
-
73
- .btn-secondary {
74
- @apply bg-gray-100 hover:bg-gray-200 active:bg-gray-300
75
- dark:bg-slate-700 dark:hover:bg-slate-600 dark:active:bg-slate-500
76
- text-gray-900 dark:text-gray-100 disabled:opacity-50;
77
- }
78
-
79
- .btn-danger {
80
- @apply bg-gradient-to-br from-red-600 to-red-700 hover:from-red-700 hover:to-red-800
81
- text-white shadow-sm hover:shadow-md disabled:opacity-50;
82
- }
83
-
84
- .btn-ghost {
85
- @apply hover:bg-gray-100 active:bg-gray-200 dark:hover:bg-slate-700
86
- dark:active:bg-slate-600 text-gray-700 dark:text-gray-300;
87
- }
88
-
89
- .badge {
90
- @apply inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium;
91
- transition: all 0.2s ease;
92
- }
93
-
94
- .badge-success {
95
- @apply bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400
96
- ring-1 ring-green-600/20 dark:ring-green-400/20;
97
- box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
98
- }
99
-
100
- .badge-success:hover {
101
- box-shadow: 0 0 8px 0 rgba(16, 185, 129, 0.3);
102
- }
103
-
104
- .badge-warning {
105
- @apply bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400
106
- ring-1 ring-yellow-600/20 dark:ring-yellow-400/20;
107
- box-shadow: 0 0 0 0 rgba(245, 158, 11, 0);
108
- }
109
-
110
- .badge-warning:hover {
111
- box-shadow: 0 0 8px 0 rgba(245, 158, 11, 0.3);
112
- }
113
-
114
- .badge-danger {
115
- @apply bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400
116
- ring-1 ring-red-600/20 dark:ring-red-400/20;
117
- box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
118
- }
119
-
120
- .badge-danger:hover {
121
- box-shadow: 0 0 8px 0 rgba(239, 68, 68, 0.3);
122
- }
123
-
124
- .badge-info {
125
- @apply bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400
126
- ring-1 ring-purple-600/20 dark:ring-purple-400/20;
127
- box-shadow: 0 0 0 0 rgba(168, 85, 247, 0);
128
- }
129
-
130
- .badge-info:hover {
131
- box-shadow: 0 0 8px 0 rgba(168, 85, 247, 0.3);
132
- }
133
-
134
- .input {
135
- @apply w-full px-3 py-2 text-sm border rounded-lg bg-white dark:bg-slate-800
136
- focus:outline-none focus:ring-2 focus:ring-rose-500 focus:border-transparent
137
- transition-all duration-200;
138
- }
139
-
140
- .input:focus {
141
- box-shadow: 0 0 0 3px rgba(244, 63, 94, 0.1);
142
- }
143
-
144
- /* Table styles */
145
- .table-container {
146
- @apply overflow-x-auto -mx-4 sm:mx-0 rounded-lg;
147
- }
148
-
149
- .table {
150
- @apply w-full text-sm;
151
- }
152
-
153
- .table thead {
154
- @apply text-xs text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700;
155
- background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.02));
156
- }
157
-
158
- .dark .table thead {
159
- background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.02));
160
- }
161
-
162
- .table th {
163
- @apply pb-3 font-semibold text-left px-4 sm:px-3 first:pl-4 last:pr-4
164
- uppercase tracking-wider;
165
- }
166
-
167
- .table tbody tr {
168
- @apply border-b border-gray-100 dark:border-gray-700/50 last:border-b-0
169
- transition-all duration-150;
170
- }
171
-
172
- .table tbody tr:nth-child(even) {
173
- @apply bg-gray-50/50 dark:bg-slate-700/20;
174
- }
175
-
176
- .table tbody tr:hover {
177
- @apply bg-gradient-to-r from-rose-50/50 to-purple-50/50
178
- dark:from-rose-900/10 dark:to-purple-900/10;
179
- box-shadow: inset 3px 0 0 0 rgb(244, 63, 94, 0.5);
180
- }
181
-
182
- .table td {
183
- @apply py-3.5 px-4 sm:px-3 first:pl-4 last:pr-4;
184
- }
185
-
186
- /* Metric card specific */
187
- .metric-value {
188
- @apply text-2xl sm:text-3xl font-bold mt-1.5;
189
- background: linear-gradient(135deg, #f43f5e 0%, #ec4899 50%, #a855f7 100%);
190
- -webkit-background-clip: text;
191
- -webkit-text-fill-color: transparent;
192
- background-clip: text;
193
- letter-spacing: -0.02em;
194
- }
195
-
196
- .metric-label {
197
- @apply text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider font-semibold;
198
- }
199
-
200
- /* Chart container */
201
- .chart-container {
202
- @apply h-64 sm:h-72 md:h-80 w-full relative;
203
- }
204
-
205
- /* Status indicators */
206
- .status-dot {
207
- @apply w-2 h-2 rounded-full;
208
- animation: pulse-glow 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
209
- }
210
-
211
- .status-dot.healthy {
212
- @apply bg-green-500;
213
- box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
214
- }
215
-
216
- .status-dot.unhealthy {
217
- @apply bg-red-500;
218
- box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
219
- }
220
-
221
- @keyframes pulse-glow {
222
- 0%, 100% {
223
- box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
224
- }
225
- 50% {
226
- box-shadow: 0 0 0 4px rgba(16, 185, 129, 0);
227
- }
228
- }
229
- }
230
-
231
- /* Scrollbar styling */
232
- @layer utilities {
233
- .scrollbar-thin::-webkit-scrollbar {
234
- width: 6px;
235
- height: 6px;
236
- }
237
-
238
- .scrollbar-thin::-webkit-scrollbar-track {
239
- @apply bg-gray-100 dark:bg-slate-800 rounded-full;
240
- }
241
-
242
- .scrollbar-thin::-webkit-scrollbar-thumb {
243
- @apply bg-gradient-to-b from-rose-400 to-purple-400 rounded-full;
244
- }
245
-
246
- .scrollbar-thin::-webkit-scrollbar-thumb:hover {
247
- @apply from-rose-500 to-purple-500;
248
- }
249
-
250
- /* Custom utilities */
251
- .text-balance {
252
- text-wrap: balance;
253
- }
254
-
255
- /* Smooth scrolling */
256
- .smooth-scroll {
257
- scroll-behavior: smooth;
258
- }
259
-
260
- /* Glassmorphism */
261
- .glass {
262
- background: rgba(255, 255, 255, 0.8);
263
- backdrop-filter: blur(10px);
264
- -webkit-backdrop-filter: blur(10px);
265
- }
266
-
267
- .dark .glass {
268
- background: rgba(30, 41, 59, 0.8);
269
- }
270
- }
271
-
272
- /* Custom animations */
273
- @keyframes fadeIn {
274
- from {
275
- opacity: 0;
276
- transform: translateY(10px);
277
- }
278
- to {
279
- opacity: 1;
280
- transform: translateY(0);
281
- }
282
- }
283
-
284
- @keyframes slideIn {
285
- from {
286
- opacity: 0;
287
- transform: translateX(-10px);
288
- }
289
- to {
290
- opacity: 1;
291
- transform: translateX(0);
292
- }
293
- }
294
-
295
- @keyframes scaleIn {
296
- from {
297
- opacity: 0;
298
- transform: scale(0.95);
299
- }
300
- to {
301
- opacity: 1;
302
- transform: scale(1);
303
- }
304
- }
305
-
306
- .animate-fade-in {
307
- animation: fadeIn 0.3s ease-out;
308
- }
309
-
310
- .animate-slide-in {
311
- animation: slideIn 0.3s ease-out;
312
- }
313
-
314
- .animate-scale-in {
315
- animation: scaleIn 0.2s ease-out;
316
- }
317
-
318
- /* Focus visible for accessibility */
319
- :focus-visible {
320
- @apply outline-2 outline-offset-2 outline-rose-500 rounded;
321
- }
322
-
323
- /* Selection color */
324
- ::selection {
325
- @apply bg-rose-200 dark:bg-rose-800/50 text-gray-900 dark:text-gray-100;
326
- }
327
-
328
- /* Gradient text utility */
329
- .gradient-text {
330
- background: linear-gradient(135deg, #f43f5e 0%, #ec4899 50%, #a855f7 100%);
331
- -webkit-background-clip: text;
332
- -webkit-text-fill-color: transparent;
333
- background-clip: text;
334
- }
335
-
336
- /* Card with gradient border */
337
- .card-gradient-border {
338
- position: relative;
339
- background: white;
340
- border-radius: 0.75rem;
341
- padding: 1px;
342
- background: linear-gradient(135deg, rgba(244, 63, 94, 0.2), rgba(168, 85, 247, 0.2));
343
- }
344
-
345
- .dark .card-gradient-border {
346
- background: linear-gradient(135deg, rgba(244, 63, 94, 0.3), rgba(168, 85, 247, 0.3));
347
- }
348
-
349
- .card-gradient-border > * {
350
- background: white;
351
- border-radius: 0.7rem;
352
- padding: 1rem 1.25rem;
353
- }
354
-
355
- .dark .card-gradient-border > * {
356
- background: rgb(30, 41, 59);
357
- }
@@ -1,87 +0,0 @@
1
- <template>
2
- <div>
3
- <div class="flex flex-col sm:flex-row gap-3">
4
- <!-- Time Range -->
5
- <div class="flex items-center gap-2">
6
- <label class="text-sm font-medium text-gray-700 dark:text-gray-300 whitespace-nowrap">Time Range:</label>
7
- <select
8
- :value="timeRange"
9
- @change="$emit('update:timeRange', $event.target.value)"
10
- class="input w-32"
11
- >
12
- <option value="1h">Last Hour</option>
13
- <option value="6h">6 Hours</option>
14
- <option value="24h">24 Hours</option>
15
- <option value="7d">7 Days</option>
16
- </select>
17
- </div>
18
-
19
- <!-- Queue Filter -->
20
- <select
21
- :value="queue"
22
- @change="$emit('update:queue', $event.target.value)"
23
- class="input flex-1 sm:w-48"
24
- >
25
- <option value="">All Queues</option>
26
- <option v-for="q in queues" :key="q.id" :value="q.name">
27
- {{ q.name }}
28
- </option>
29
- </select>
30
-
31
- <!-- Namespace Filter -->
32
- <select
33
- :value="namespace"
34
- @change="$emit('update:namespace', $event.target.value)"
35
- class="input sm:w-40"
36
- >
37
- <option value="">All Namespaces</option>
38
- <option v-for="ns in namespaces" :key="ns.namespace" :value="ns.namespace">
39
- {{ ns.namespace }}
40
- </option>
41
- </select>
42
-
43
- <!-- Task Filter -->
44
- <select
45
- :value="task"
46
- @change="$emit('update:task', $event.target.value)"
47
- class="input sm:w-40"
48
- >
49
- <option value="">All Tasks</option>
50
- <option v-for="t in tasks" :key="t.task" :value="t.task">
51
- {{ t.task }}
52
- </option>
53
- </select>
54
-
55
- <!-- Clear Filters -->
56
- <button
57
- v-if="queue || namespace || task"
58
- @click="clearFilters"
59
- class="btn btn-secondary whitespace-nowrap"
60
- >
61
- Clear Filters
62
- </button>
63
- </div>
64
- </div>
65
- </template>
66
-
67
-
68
- <script setup>
69
- defineProps({
70
- timeRange: String,
71
- queue: String,
72
- namespace: String,
73
- task: String,
74
- queues: Array,
75
- namespaces: Array,
76
- tasks: Array,
77
- });
78
-
79
- const emit = defineEmits(['update:timeRange', 'update:queue', 'update:namespace', 'update:task']);
80
-
81
- function clearFilters() {
82
- emit('update:queue', '');
83
- emit('update:namespace', '');
84
- emit('update:task', '');
85
- }
86
- </script>
87
-
@@ -1,57 +0,0 @@
1
- <template>
2
- <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
3
- <div class="card">
4
- <p class="metric-label">Avg Throughput</p>
5
- <p class="metric-value">{{ avgThroughput }}</p>
6
- <p class="text-xs text-gray-500 dark:text-gray-400 mt-1.5">messages/sec</p>
7
- </div>
8
-
9
- <div class="card">
10
- <p class="metric-label">Total Processed</p>
11
- <p class="metric-value">{{ formatNumber(totalProcessed) }}</p>
12
- <p class="text-xs text-gray-500 dark:text-gray-400 mt-1.5">in time range</p>
13
- </div>
14
-
15
- <div class="card">
16
- <p class="metric-label">Error Rate</p>
17
- <p class="metric-value">{{ errorRate }}%</p>
18
- <p class="text-xs text-gray-500 dark:text-gray-400 mt-1.5">failed / total</p>
19
- </div>
20
- </div>
21
- </template>
22
-
23
- <script setup>
24
- import { computed } from 'vue';
25
- import { formatNumber } from '../../utils/formatters';
26
-
27
- const props = defineProps({
28
- data: Object,
29
- messages: Object,
30
- });
31
-
32
- const avgThroughput = computed(() => {
33
- if (!props.data?.throughput?.length) return '0.00';
34
-
35
- const throughput = props.data.throughput;
36
- const total = throughput.reduce((sum, t) => sum + (t.processedPerSecond || t.processed || 0), 0);
37
- const avg = total / throughput.length;
38
-
39
- return avg.toFixed(2);
40
- });
41
-
42
- const totalProcessed = computed(() => {
43
- return props.messages?.completed || 0;
44
- });
45
-
46
- const errorRate = computed(() => {
47
- const failed = props.messages?.failed || 0;
48
- const dlq = props.messages?.deadLetter || 0;
49
- const total = props.messages?.total || 0;
50
-
51
- if (total === 0) return '0.00';
52
-
53
- const rate = ((failed + dlq) / total) * 100;
54
- return rate.toFixed(2);
55
- });
56
- </script>
57
-
@@ -1,111 +0,0 @@
1
- <template>
2
- <div class="h-80 flex items-center justify-center">
3
- <div class="w-full max-w-sm">
4
- <Doughnut v-if="chartData" :data="chartData" :options="chartOptions" />
5
- <div v-else class="text-center text-gray-500 text-sm">
6
- No message data available
7
- </div>
8
- </div>
9
- </div>
10
- </template>
11
-
12
- <script setup>
13
- import { computed } from 'vue';
14
- import { Doughnut } from 'vue-chartjs';
15
- import {
16
- Chart as ChartJS,
17
- ArcElement,
18
- Tooltip,
19
- Legend,
20
- } from 'chart.js';
21
- import { getStatusColors } from '../../utils/colors';
22
-
23
- ChartJS.register(
24
- ArcElement,
25
- Tooltip,
26
- Legend
27
- );
28
-
29
- const props = defineProps({
30
- messages: Object,
31
- });
32
-
33
- const chartData = computed(() => {
34
- if (!props.messages) return null;
35
-
36
- const data = [
37
- props.messages.pending || 0,
38
- props.messages.processing || 0,
39
- props.messages.completed || 0,
40
- props.messages.failed || 0,
41
- props.messages.deadLetter || 0,
42
- ];
43
-
44
- // Only show chart if there's data
45
- if (data.every(v => v === 0)) return null;
46
-
47
- return {
48
- labels: ['Pending', 'Processing', 'Completed', 'Failed', 'Dead Letter'],
49
- datasets: [
50
- {
51
- data: data,
52
- backgroundColor: [
53
- 'rgba(236, 72, 153, 0.8)', // Pink - Pending
54
- 'rgba(168, 85, 247, 0.8)', // Purple - Processing
55
- 'rgba(139, 92, 246, 0.8)', // Violet - Completed
56
- 'rgba(244, 63, 94, 0.8)', // Rose - Failed
57
- 'rgba(192, 132, 252, 0.7)', // Light Purple - Dead Letter
58
- ],
59
- borderColor: [
60
- 'rgb(236, 72, 153)',
61
- 'rgb(168, 85, 247)',
62
- 'rgb(139, 92, 246)',
63
- 'rgb(244, 63, 94)',
64
- 'rgb(192, 132, 252)',
65
- ],
66
- borderWidth: 2,
67
- },
68
- ],
69
- };
70
- });
71
-
72
- const chartOptions = {
73
- responsive: true,
74
- maintainAspectRatio: true,
75
- plugins: {
76
- legend: {
77
- position: 'bottom',
78
- labels: {
79
- padding: 15,
80
- font: {
81
- size: 12,
82
- },
83
- color: '#6b7280',
84
- usePointStyle: true,
85
- pointStyle: 'circle',
86
- },
87
- },
88
- tooltip: {
89
- backgroundColor: 'rgba(0, 0, 0, 0.9)',
90
- padding: 12,
91
- cornerRadius: 8,
92
- titleFont: {
93
- size: 13,
94
- },
95
- bodyFont: {
96
- size: 12,
97
- },
98
- callbacks: {
99
- label: (context) => {
100
- const label = context.label || '';
101
- const value = context.parsed || 0;
102
- const total = context.dataset.data.reduce((a, b) => a + b, 0);
103
- const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : 0;
104
- return ` ${label}: ${value.toLocaleString()} (${percentage}%)`;
105
- },
106
- },
107
- },
108
- },
109
- };
110
- </script>
111
-