pgbus 0.17.1 → 0.17.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -0
- data/README.md +83 -13
- data/Rakefile +26 -0
- data/app/assets/javascripts/pgbus/stream_source_element.js +34 -2
- data/app/assets/javascripts/pgbus/stream_source_element.min.js +6 -0
- data/app/assets/javascripts/pgbus/stream_source_element.min.js.map +1 -0
- data/app/controllers/concerns/pgbus/job_listing.rb +37 -0
- data/app/controllers/concerns/pgbus/process_listing.rb +17 -0
- data/app/controllers/pgbus/application_controller.rb +5 -2
- data/app/controllers/pgbus/batches_controller.rb +4 -1
- data/app/controllers/pgbus/dashboard_controller.rb +20 -6
- data/app/controllers/pgbus/dead_letter_controller.rb +27 -3
- data/app/controllers/pgbus/events_controller.rb +52 -3
- data/app/controllers/pgbus/frontends_controller.rb +25 -11
- data/app/controllers/pgbus/insights_controller.rb +19 -1
- data/app/controllers/pgbus/jobs_controller.rb +45 -26
- data/app/controllers/pgbus/locks_controller.rb +7 -2
- data/app/controllers/pgbus/outbox_controller.rb +4 -1
- data/app/controllers/pgbus/processes_controller.rb +3 -1
- data/app/controllers/pgbus/queues_controller.rb +16 -4
- data/app/controllers/pgbus/recurring_tasks_controller.rb +5 -7
- data/app/frontend/pgbus/application.min.js +2 -0
- data/app/frontend/pgbus/application.min.js.map +1 -0
- data/app/frontend/pgbus/modules/charts.js +137 -77
- data/app/frontend/pgbus/modules/charts.min.js +2 -0
- data/app/frontend/pgbus/modules/charts.min.js.map +1 -0
- data/app/frontend/pgbus/style.css +1 -1
- data/app/frontend/pgbus/tailwind.css +18 -0
- data/app/frontend/pgbus/vendor/turbo.min.js +54 -0
- data/app/frontend/pgbus/vendor/turbo.min.js.map +1 -0
- data/app/helpers/pgbus/application_helper.rb +155 -113
- data/app/helpers/pgbus/button_helper.rb +88 -0
- data/app/helpers/pgbus/dashboard_helper.rb +157 -0
- data/app/helpers/pgbus/events_helper.rb +40 -0
- data/app/helpers/pgbus/insights_helper.rb +39 -0
- data/app/helpers/pgbus/processes_helper.rb +79 -0
- data/app/views/layouts/pgbus/application.html.erb +0 -1
- data/app/views/pgbus/batches/_batches_table.html.erb +16 -13
- data/app/views/pgbus/batches/show.html.erb +3 -4
- data/app/views/pgbus/dashboard/_processes_table.html.erb +11 -11
- data/app/views/pgbus/dashboard/_queue_health.html.erb +42 -51
- data/app/views/pgbus/dashboard/_queues_table.html.erb +18 -16
- data/app/views/pgbus/dashboard/_recent_failures.html.erb +16 -12
- data/app/views/pgbus/dashboard/_stats_cards.html.erb +70 -36
- data/app/views/pgbus/dashboard/show.html.erb +1 -1
- data/app/views/pgbus/dead_letter/_error.html.erb +13 -0
- data/app/views/pgbus/dead_letter/_messages_table.html.erb +37 -96
- data/app/views/pgbus/dead_letter/_row.html.erb +75 -0
- data/app/views/pgbus/dead_letter/index.html.erb +6 -9
- data/app/views/pgbus/dead_letter/show.html.erb +37 -21
- data/app/views/pgbus/events/_list.html.erb +55 -0
- data/app/views/pgbus/events/_processed_table.html.erb +45 -0
- data/app/views/pgbus/events/_replay.html.erb +10 -0
- data/app/views/pgbus/events/_row.html.erb +162 -0
- data/app/views/pgbus/events/_tabs.html.erb +13 -0
- data/app/views/pgbus/events/index.html.erb +27 -48
- data/app/views/pgbus/events/show.html.erb +25 -7
- data/app/views/pgbus/insights/_chart_card.html.erb +21 -0
- data/app/views/pgbus/insights/_latency_table.html.erb +20 -0
- data/app/views/pgbus/insights/_status_table.html.erb +19 -0
- data/app/views/pgbus/insights/_throughput_table.html.erb +18 -0
- data/app/views/pgbus/insights/show.html.erb +83 -100
- data/app/views/pgbus/jobs/_list.html.erb +64 -0
- data/app/views/pgbus/jobs/_row.html.erb +107 -0
- data/app/views/pgbus/jobs/_tabs.html.erb +14 -0
- data/app/views/pgbus/jobs/index.html.erb +10 -10
- data/app/views/pgbus/jobs/show.html.erb +18 -20
- data/app/views/pgbus/locks/_concurrency.html.erb +25 -23
- data/app/views/pgbus/locks/_uniqueness.html.erb +20 -22
- data/app/views/pgbus/outbox/index.html.erb +30 -27
- data/app/views/pgbus/processes/_processes_table.html.erb +6 -25
- data/app/views/pgbus/processes/_row.html.erb +48 -0
- data/app/views/pgbus/processes/_status.html.erb +4 -0
- data/app/views/pgbus/queues/_queues_list.html.erb +28 -32
- data/app/views/pgbus/queues/show.html.erb +69 -118
- data/app/views/pgbus/recurring_tasks/_tasks_table.html.erb +75 -76
- data/app/views/pgbus/recurring_tasks/index.html.erb +1 -1
- data/app/views/pgbus/recurring_tasks/show.html.erb +45 -51
- data/app/views/pgbus/shared/_empty_row.html.erb +2 -0
- data/app/views/pgbus/shared/_pager.html.erb +34 -0
- data/config/i18n-tasks.yml +11 -2
- data/config/locales/da.yml +405 -113
- data/config/locales/de.yml +405 -113
- data/config/locales/en.yml +405 -113
- data/config/locales/es.yml +404 -112
- data/config/locales/fi.yml +404 -112
- data/config/locales/fr.yml +406 -114
- data/config/locales/it.yml +405 -113
- data/config/locales/ja.yml +405 -113
- data/config/locales/nb.yml +405 -113
- data/config/locales/nl.yml +405 -113
- data/config/locales/pt.yml +406 -114
- data/config/locales/sv.yml +404 -112
- data/config/routes.rb +1 -1
- data/lib/generators/pgbus/add_presence_generator.rb +2 -1
- data/lib/generators/pgbus/add_presence_seats_generator.rb +45 -0
- data/lib/generators/pgbus/templates/add_presence.rb.erb +32 -7
- data/lib/generators/pgbus/templates/add_presence_seats.rb.erb +38 -0
- data/lib/generators/pgbus/templates/initializer.rb.erb +4 -0
- data/lib/pgbus/active_job/executor.rb +16 -6
- data/lib/pgbus/cli/dlq.rb +32 -5
- data/lib/pgbus/client.rb +4 -2
- data/lib/pgbus/configuration/presence_settings.rb +103 -0
- data/lib/pgbus/configuration.rb +51 -2
- data/lib/pgbus/dead_letter_header.rb +129 -0
- data/lib/pgbus/doctor.rb +8 -4
- data/lib/pgbus/engine.rb +13 -7
- data/lib/pgbus/event_bus/handler.rb +18 -11
- data/lib/pgbus/event_bus/registry.rb +6 -0
- data/lib/pgbus/failed_event_recorder.rb +34 -0
- data/lib/pgbus/generators/migration_detector.rb +9 -1
- data/lib/pgbus/instrumentation.rb +2 -1
- data/lib/pgbus/mcp/base_tool.rb +25 -0
- data/lib/pgbus/mcp/tools/concurrency_tool.rb +23 -4
- data/lib/pgbus/mcp/tools/dlq_detail_tool.rb +4 -2
- data/lib/pgbus/mcp/tools/dlq_tool.rb +10 -4
- data/lib/pgbus/mcp/tools/locks_tool.rb +23 -5
- data/lib/pgbus/mcp/tools/recurring_tool.rb +33 -4
- data/lib/pgbus/outbox/poller.rb +1 -1
- data/lib/pgbus/process/consumer.rb +53 -3
- data/lib/pgbus/process/dispatcher.rb +1 -1
- data/lib/pgbus/process/supervisor.rb +32 -11
- data/lib/pgbus/process/worker.rb +45 -8
- data/lib/pgbus/recurring/scheduler.rb +2 -1
- data/lib/pgbus/streams/presence.rb +317 -81
- data/lib/pgbus/version.rb +1 -1
- data/lib/pgbus/web/data_source/dashboard_signals.rb +170 -0
- data/lib/pgbus/web/data_source/dead_letter.rb +142 -0
- data/lib/pgbus/web/data_source/event_list.rb +161 -0
- data/lib/pgbus/web/data_source/job_list.rb +323 -0
- data/lib/pgbus/web/data_source/list_counts.rb +80 -0
- data/lib/pgbus/web/data_source/process_list.rb +69 -0
- data/lib/pgbus/web/data_source/queue_summary.rb +122 -0
- data/lib/pgbus/web/data_source.rb +132 -254
- data/lib/pgbus/web/dead_letter_reason.rb +81 -0
- data/lib/pgbus/web/event_state.rb +71 -0
- data/lib/pgbus/web/health_app.rb +7 -3
- data/lib/pgbus/web/health_verdict.rb +78 -0
- data/lib/pgbus/web/insights_charts.rb +84 -0
- data/lib/pgbus/web/job_state.rb +111 -0
- data/lib/pgbus/web/process_activity.rb +97 -0
- data/lib/pgbus/web/process_state.rb +187 -0
- data/lib/pgbus/web/queue_summary.rb +104 -0
- data/lib/pgbus/web/stream_app.rb +18 -6
- data/lib/pgbus/web/streamer/connection.rb +7 -1
- data/lib/pgbus/web/streamer/falcon_connection.rb +7 -1
- data/lib/pgbus/web/streamer/heartbeat.rb +9 -3
- data/lib/pgbus/web/streamer/instance.rb +2 -1
- data/lib/pgbus/web/streamer/presence_tracker.rb +155 -0
- data/lib/pgbus/web/streamer/stream_event_dispatcher.rb +8 -37
- data/lib/pgbus/web/time_format.rb +128 -0
- metadata +55 -4
- data/app/views/pgbus/events/_pending_table.html.erb +0 -169
- data/app/views/pgbus/jobs/_enqueued_table.html.erb +0 -118
- data/app/views/pgbus/jobs/_failed_table.html.erb +0 -76
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgbus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.17.
|
|
4
|
+
version: 0.17.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mikael Henriksson
|
|
@@ -123,6 +123,10 @@ files:
|
|
|
123
123
|
- README.md
|
|
124
124
|
- Rakefile
|
|
125
125
|
- app/assets/javascripts/pgbus/stream_source_element.js
|
|
126
|
+
- app/assets/javascripts/pgbus/stream_source_element.min.js
|
|
127
|
+
- app/assets/javascripts/pgbus/stream_source_element.min.js.map
|
|
128
|
+
- app/controllers/concerns/pgbus/job_listing.rb
|
|
129
|
+
- app/controllers/concerns/pgbus/process_listing.rb
|
|
126
130
|
- app/controllers/pgbus/api/insights_controller.rb
|
|
127
131
|
- app/controllers/pgbus/api/metrics_controller.rb
|
|
128
132
|
- app/controllers/pgbus/api/stats_controller.rb
|
|
@@ -141,12 +145,23 @@ files:
|
|
|
141
145
|
- app/controllers/pgbus/queues_controller.rb
|
|
142
146
|
- app/controllers/pgbus/recurring_tasks_controller.rb
|
|
143
147
|
- app/frontend/pgbus/application.js
|
|
148
|
+
- app/frontend/pgbus/application.min.js
|
|
149
|
+
- app/frontend/pgbus/application.min.js.map
|
|
144
150
|
- app/frontend/pgbus/modules/charts.js
|
|
151
|
+
- app/frontend/pgbus/modules/charts.min.js
|
|
152
|
+
- app/frontend/pgbus/modules/charts.min.js.map
|
|
145
153
|
- app/frontend/pgbus/style.css
|
|
146
154
|
- app/frontend/pgbus/tailwind.css
|
|
147
155
|
- app/frontend/pgbus/vendor/apexcharts.js
|
|
148
156
|
- app/frontend/pgbus/vendor/turbo.js
|
|
157
|
+
- app/frontend/pgbus/vendor/turbo.min.js
|
|
158
|
+
- app/frontend/pgbus/vendor/turbo.min.js.map
|
|
149
159
|
- app/helpers/pgbus/application_helper.rb
|
|
160
|
+
- app/helpers/pgbus/button_helper.rb
|
|
161
|
+
- app/helpers/pgbus/dashboard_helper.rb
|
|
162
|
+
- app/helpers/pgbus/events_helper.rb
|
|
163
|
+
- app/helpers/pgbus/insights_helper.rb
|
|
164
|
+
- app/helpers/pgbus/processes_helper.rb
|
|
150
165
|
- app/helpers/pgbus/streams_helper.rb
|
|
151
166
|
- app/models/pgbus/application_record.rb
|
|
152
167
|
- app/models/pgbus/batch_entry.rb
|
|
@@ -174,15 +189,26 @@ files:
|
|
|
174
189
|
- app/views/pgbus/dashboard/_recent_failures.html.erb
|
|
175
190
|
- app/views/pgbus/dashboard/_stats_cards.html.erb
|
|
176
191
|
- app/views/pgbus/dashboard/show.html.erb
|
|
192
|
+
- app/views/pgbus/dead_letter/_error.html.erb
|
|
177
193
|
- app/views/pgbus/dead_letter/_messages_table.html.erb
|
|
194
|
+
- app/views/pgbus/dead_letter/_row.html.erb
|
|
178
195
|
- app/views/pgbus/dead_letter/index.html.erb
|
|
179
196
|
- app/views/pgbus/dead_letter/show.html.erb
|
|
180
|
-
- app/views/pgbus/events/
|
|
197
|
+
- app/views/pgbus/events/_list.html.erb
|
|
198
|
+
- app/views/pgbus/events/_processed_table.html.erb
|
|
199
|
+
- app/views/pgbus/events/_replay.html.erb
|
|
200
|
+
- app/views/pgbus/events/_row.html.erb
|
|
201
|
+
- app/views/pgbus/events/_tabs.html.erb
|
|
181
202
|
- app/views/pgbus/events/index.html.erb
|
|
182
203
|
- app/views/pgbus/events/show.html.erb
|
|
204
|
+
- app/views/pgbus/insights/_chart_card.html.erb
|
|
205
|
+
- app/views/pgbus/insights/_latency_table.html.erb
|
|
206
|
+
- app/views/pgbus/insights/_status_table.html.erb
|
|
207
|
+
- app/views/pgbus/insights/_throughput_table.html.erb
|
|
183
208
|
- app/views/pgbus/insights/show.html.erb
|
|
184
|
-
- app/views/pgbus/jobs/
|
|
185
|
-
- app/views/pgbus/jobs/
|
|
209
|
+
- app/views/pgbus/jobs/_list.html.erb
|
|
210
|
+
- app/views/pgbus/jobs/_row.html.erb
|
|
211
|
+
- app/views/pgbus/jobs/_tabs.html.erb
|
|
186
212
|
- app/views/pgbus/jobs/index.html.erb
|
|
187
213
|
- app/views/pgbus/jobs/show.html.erb
|
|
188
214
|
- app/views/pgbus/locks/_concurrency.html.erb
|
|
@@ -190,6 +216,8 @@ files:
|
|
|
190
216
|
- app/views/pgbus/locks/index.html.erb
|
|
191
217
|
- app/views/pgbus/outbox/index.html.erb
|
|
192
218
|
- app/views/pgbus/processes/_processes_table.html.erb
|
|
219
|
+
- app/views/pgbus/processes/_row.html.erb
|
|
220
|
+
- app/views/pgbus/processes/_status.html.erb
|
|
193
221
|
- app/views/pgbus/processes/index.html.erb
|
|
194
222
|
- app/views/pgbus/queues/_queues_list.html.erb
|
|
195
223
|
- app/views/pgbus/queues/index.html.erb
|
|
@@ -197,6 +225,8 @@ files:
|
|
|
197
225
|
- app/views/pgbus/recurring_tasks/_tasks_table.html.erb
|
|
198
226
|
- app/views/pgbus/recurring_tasks/index.html.erb
|
|
199
227
|
- app/views/pgbus/recurring_tasks/show.html.erb
|
|
228
|
+
- app/views/pgbus/shared/_empty_row.html.erb
|
|
229
|
+
- app/views/pgbus/shared/_pager.html.erb
|
|
200
230
|
- config/i18n-tasks.yml
|
|
201
231
|
- config/locales/da.yml
|
|
202
232
|
- config/locales/de.yml
|
|
@@ -222,6 +252,7 @@ files:
|
|
|
222
252
|
- lib/generators/pgbus/add_job_stats_queue_index_generator.rb
|
|
223
253
|
- lib/generators/pgbus/add_outbox_generator.rb
|
|
224
254
|
- lib/generators/pgbus/add_presence_generator.rb
|
|
255
|
+
- lib/generators/pgbus/add_presence_seats_generator.rb
|
|
225
256
|
- lib/generators/pgbus/add_processed_event_completion_generator.rb
|
|
226
257
|
- lib/generators/pgbus/add_queue_states_generator.rb
|
|
227
258
|
- lib/generators/pgbus/add_recurring_generator.rb
|
|
@@ -239,6 +270,7 @@ files:
|
|
|
239
270
|
- lib/generators/pgbus/templates/add_job_stats_queue_index.rb.erb
|
|
240
271
|
- lib/generators/pgbus/templates/add_outbox.rb.erb
|
|
241
272
|
- lib/generators/pgbus/templates/add_presence.rb.erb
|
|
273
|
+
- lib/generators/pgbus/templates/add_presence_seats.rb.erb
|
|
242
274
|
- lib/generators/pgbus/templates/add_processed_event_completion.rb.erb
|
|
243
275
|
- lib/generators/pgbus/templates/add_queue_states.rb.erb
|
|
244
276
|
- lib/generators/pgbus/templates/add_recurring_tables.rb.erb
|
|
@@ -283,8 +315,10 @@ files:
|
|
|
283
315
|
- lib/pgbus/concurrency/semaphore.rb
|
|
284
316
|
- lib/pgbus/configuration.rb
|
|
285
317
|
- lib/pgbus/configuration/capsule_dsl.rb
|
|
318
|
+
- lib/pgbus/configuration/presence_settings.rb
|
|
286
319
|
- lib/pgbus/current_attributes.rb
|
|
287
320
|
- lib/pgbus/database_tasks_guard.rb
|
|
321
|
+
- lib/pgbus/dead_letter_header.rb
|
|
288
322
|
- lib/pgbus/dedicated_connection.rb
|
|
289
323
|
- lib/pgbus/dedup_cache.rb
|
|
290
324
|
- lib/pgbus/doctor.rb
|
|
@@ -409,11 +443,26 @@ files:
|
|
|
409
443
|
- lib/pgbus/visibility_heartbeat.rb
|
|
410
444
|
- lib/pgbus/web/authentication.rb
|
|
411
445
|
- lib/pgbus/web/data_source.rb
|
|
446
|
+
- lib/pgbus/web/data_source/dashboard_signals.rb
|
|
447
|
+
- lib/pgbus/web/data_source/dead_letter.rb
|
|
448
|
+
- lib/pgbus/web/data_source/event_list.rb
|
|
449
|
+
- lib/pgbus/web/data_source/job_list.rb
|
|
450
|
+
- lib/pgbus/web/data_source/list_counts.rb
|
|
451
|
+
- lib/pgbus/web/data_source/process_list.rb
|
|
452
|
+
- lib/pgbus/web/data_source/queue_summary.rb
|
|
453
|
+
- lib/pgbus/web/dead_letter_reason.rb
|
|
454
|
+
- lib/pgbus/web/event_state.rb
|
|
412
455
|
- lib/pgbus/web/health_app.rb
|
|
413
456
|
- lib/pgbus/web/health_server.rb
|
|
457
|
+
- lib/pgbus/web/health_verdict.rb
|
|
458
|
+
- lib/pgbus/web/insights_charts.rb
|
|
414
459
|
- lib/pgbus/web/job_context.rb
|
|
460
|
+
- lib/pgbus/web/job_state.rb
|
|
415
461
|
- lib/pgbus/web/metrics_serializer.rb
|
|
416
462
|
- lib/pgbus/web/payload_filter.rb
|
|
463
|
+
- lib/pgbus/web/process_activity.rb
|
|
464
|
+
- lib/pgbus/web/process_state.rb
|
|
465
|
+
- lib/pgbus/web/queue_summary.rb
|
|
417
466
|
- lib/pgbus/web/stream_app.rb
|
|
418
467
|
- lib/pgbus/web/streamer.rb
|
|
419
468
|
- lib/pgbus/web/streamer/connection.rb
|
|
@@ -428,9 +477,11 @@ files:
|
|
|
428
477
|
- lib/pgbus/web/streamer/master_hub.rb
|
|
429
478
|
- lib/pgbus/web/streamer/master_hub_boot.rb
|
|
430
479
|
- lib/pgbus/web/streamer/outbound_pump.rb
|
|
480
|
+
- lib/pgbus/web/streamer/presence_tracker.rb
|
|
431
481
|
- lib/pgbus/web/streamer/registry.rb
|
|
432
482
|
- lib/pgbus/web/streamer/stream_counter.rb
|
|
433
483
|
- lib/pgbus/web/streamer/stream_event_dispatcher.rb
|
|
484
|
+
- lib/pgbus/web/time_format.rb
|
|
434
485
|
- lib/puma/plugin/pgbus_streams.rb
|
|
435
486
|
- lib/tasks/pgbus_autovacuum.rake
|
|
436
487
|
- lib/tasks/pgbus_doctor.rake
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
<turbo-frame id="pending-events">
|
|
2
|
-
<%# Bulk form outside table to avoid nested form issues %>
|
|
3
|
-
<form id="bulk-discard-events-form" action="<%= pgbus.discard_selected_events_path %>" method="post" data-turbo-frame="_top" class="hidden">
|
|
4
|
-
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
|
5
|
-
</form>
|
|
6
|
-
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700" data-bulk-scope="events">
|
|
7
|
-
<table class="pgbus-table min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
8
|
-
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
9
|
-
<tr>
|
|
10
|
-
<% if @pending.any? %>
|
|
11
|
-
<th class="w-10 px-4 py-3">
|
|
12
|
-
<input type="checkbox" data-bulk-select-all
|
|
13
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_all") %>"
|
|
14
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
|
15
|
-
</th>
|
|
16
|
-
<% end %>
|
|
17
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.events.index.pending_headers.id") %></th>
|
|
18
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.events.index.pending_headers.routing_key") %></th>
|
|
19
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.events.index.pending_headers.handler_queue") %></th>
|
|
20
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.events.index.pending_headers.enqueued") %></th>
|
|
21
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.events.index.pending_headers.reads") %></th>
|
|
22
|
-
</tr>
|
|
23
|
-
</thead>
|
|
24
|
-
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
|
|
25
|
-
<% @pending.each do |m| %>
|
|
26
|
-
<%# Preserve the raw message so corrupt payloads stay visible in the
|
|
27
|
-
edit textarea and full-JSON panel. pgbus_parse_message swallows
|
|
28
|
-
JSON::ParserError and returns {}, which would otherwise hide
|
|
29
|
-
exactly the data the operator is trying to inspect/repair.
|
|
30
|
-
Also coerce scalar JSON values (numbers, booleans, nil, arrays)
|
|
31
|
-
to {} for hash-style access below — otherwise payload["foo"]
|
|
32
|
-
raises NoMethodError. %>
|
|
33
|
-
<% payload_raw = pgbus_parse_message(m[:message]) %>
|
|
34
|
-
<% payload = payload_raw.is_a?(Hash) ? payload_raw : {} %>
|
|
35
|
-
<% parse_ok = m[:message].blank? || payload_raw != {} || m[:message].to_s.strip == "{}" %>
|
|
36
|
-
<tr>
|
|
37
|
-
<td class="w-10 px-4 py-3 align-top">
|
|
38
|
-
<input type="checkbox" data-bulk-item data-pgbus-action="bulk-row-toggle"
|
|
39
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_row", id: m[:msg_id]) %>"
|
|
40
|
-
data-queue-name="<%= m[:queue_name] %>" data-msg-id="<%= m[:msg_id] %>"
|
|
41
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 mt-1">
|
|
42
|
-
<input type="hidden" name="messages[][queue_name]" value="<%= m[:queue_name] %>" form="bulk-discard-events-form" disabled>
|
|
43
|
-
<input type="hidden" name="messages[][msg_id]" value="<%= m[:msg_id] %>" form="bulk-discard-events-form" disabled>
|
|
44
|
-
</td>
|
|
45
|
-
<td colspan="5" class="p-0">
|
|
46
|
-
<details class="group">
|
|
47
|
-
<summary class="flex cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 dark:bg-gray-900 list-none">
|
|
48
|
-
<span class="w-16 shrink-0 px-4 py-3 text-sm font-mono text-gray-900 dark:text-white"><%= m[:msg_id] %></span>
|
|
49
|
-
<span class="flex-1 px-4 py-3 text-sm font-mono text-indigo-600 truncate"><%= payload["routing_key"] || payload["event_id"] || "—" %></span>
|
|
50
|
-
<span class="w-40 shrink-0 px-4 py-3 text-sm text-gray-700"><%= m[:queue_name] %></span>
|
|
51
|
-
<span class="w-28 shrink-0 px-4 py-3 text-sm text-gray-500"><%= pgbus_time_ago(m[:enqueued_at]) %></span>
|
|
52
|
-
<span class="w-16 shrink-0 px-4 py-3 text-sm text-gray-500"><%= m[:read_ct] %></span>
|
|
53
|
-
</summary>
|
|
54
|
-
<div class="px-4 pb-4 bg-gray-50 dark:bg-gray-900 border-t border-gray-100">
|
|
55
|
-
<div class="flex items-center justify-between mt-3 mb-3">
|
|
56
|
-
<span class="text-xs font-mono text-gray-400"><%= t("pgbus.events.pending_table.event_id") %> <%= payload["event_id"] %></span>
|
|
57
|
-
<div class="flex space-x-2">
|
|
58
|
-
<%# Mark Handled — handler_class is resolved server-side
|
|
59
|
-
from the subscriber registry, so we only send queue_name. %>
|
|
60
|
-
<%= button_to t("pgbus.events.pending_table.mark_handled"),
|
|
61
|
-
pgbus.mark_handled_event_path(m[:msg_id], queue_name: m[:queue_name]),
|
|
62
|
-
method: :post,
|
|
63
|
-
class: "rounded-md bg-green-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-green-500",
|
|
64
|
-
data: { turbo_confirm: t("pgbus.events.pending_table.mark_handled_confirm"), turbo_frame: "_top" } %>
|
|
65
|
-
<%# Reroute — dropdown with available handlers %>
|
|
66
|
-
<details class="relative inline-block">
|
|
67
|
-
<summary class="rounded-md bg-yellow-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-yellow-500 cursor-pointer list-none">
|
|
68
|
-
<%= t("pgbus.events.pending_table.reroute") %>
|
|
69
|
-
</summary>
|
|
70
|
-
<div class="absolute right-0 z-10 mt-1 w-64 rounded-md bg-white dark:bg-gray-800 shadow-lg ring-1 ring-gray-200 dark:ring-gray-700 p-2">
|
|
71
|
-
<p class="text-xs text-gray-500 mb-2"><%= t("pgbus.events.pending_table.reroute_label") %></p>
|
|
72
|
-
<% @subscribers.each do |s| %>
|
|
73
|
-
<% next if s[:physical_queue_name] == m[:queue_name] %>
|
|
74
|
-
<%= button_to s[:handler_class],
|
|
75
|
-
pgbus.reroute_event_path(m[:msg_id], queue_name: m[:queue_name], target_queue: s[:physical_queue_name]),
|
|
76
|
-
method: :post,
|
|
77
|
-
class: "block w-full text-left rounded px-2 py-1 text-xs text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700",
|
|
78
|
-
data: { turbo_confirm: t("pgbus.events.pending_table.reroute_confirm"), turbo_frame: "_top" } %>
|
|
79
|
-
<% end %>
|
|
80
|
-
</div>
|
|
81
|
-
</details>
|
|
82
|
-
<%# Discard %>
|
|
83
|
-
<%= button_to t("pgbus.events.pending_table.discard"),
|
|
84
|
-
pgbus.discard_event_path(m[:msg_id], queue_name: m[:queue_name]),
|
|
85
|
-
method: :post,
|
|
86
|
-
class: "rounded-md bg-red-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-red-500",
|
|
87
|
-
data: { turbo_confirm: t("pgbus.events.pending_table.discard_confirm"), turbo_frame: "_top" } %>
|
|
88
|
-
</div>
|
|
89
|
-
</div>
|
|
90
|
-
<%# Payload display %>
|
|
91
|
-
<div class="grid grid-cols-2 gap-4 mb-3">
|
|
92
|
-
<div>
|
|
93
|
-
<span class="text-xs font-medium text-gray-500"><%= t("pgbus.events.pending_table.arguments") %></span>
|
|
94
|
-
<pre class="text-xs text-gray-700 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto max-h-40"><%= parse_ok ? (JSON.pretty_generate(payload["payload"] || payload_raw) rescue "—") : m[:message] %></pre>
|
|
95
|
-
</div>
|
|
96
|
-
<div>
|
|
97
|
-
<span class="text-xs font-medium text-gray-500"><%= t("pgbus.events.pending_table.metadata") %></span>
|
|
98
|
-
<div class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 space-y-1">
|
|
99
|
-
<% if m[:read_ct] %><p><strong><%= t("pgbus.events.pending_table.metadata_labels.read_count") %></strong> <%= m[:read_ct] %></p><% end %>
|
|
100
|
-
<% if m[:vt] %><p><strong><%= t("pgbus.events.pending_table.metadata_labels.visible_at") %></strong> <%= m[:vt] %></p><% end %>
|
|
101
|
-
<% if m[:last_read_at] %><p><strong><%= t("pgbus.events.pending_table.metadata_labels.last_read") %></strong> <%= m[:last_read_at] %></p><% end %>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
<%# Persisted Current attributes (issue #431) %>
|
|
106
|
-
<% if (event_context = pgbus_job_context(m[:message])) %>
|
|
107
|
-
<div class="mb-3" data-testid="job-context">
|
|
108
|
-
<span class="text-xs font-medium text-gray-500"><%= t("pgbus.events.pending_table.context") %></span>
|
|
109
|
-
<div class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 space-y-2">
|
|
110
|
-
<% event_context.each do |klass_name, attrs| %>
|
|
111
|
-
<div>
|
|
112
|
-
<p class="font-semibold text-gray-700 dark:text-gray-300 font-mono"><%= klass_name %></p>
|
|
113
|
-
<dl class="grid grid-cols-1 gap-x-4 gap-y-0.5 sm:grid-cols-2">
|
|
114
|
-
<% attrs.each do |name, value| %>
|
|
115
|
-
<div class="flex gap-2">
|
|
116
|
-
<dt class="text-gray-500 font-mono"><%= name %></dt>
|
|
117
|
-
<dd class="text-gray-900 dark:text-white font-mono break-all"><%= value %></dd>
|
|
118
|
-
</div>
|
|
119
|
-
<% end %>
|
|
120
|
-
</dl>
|
|
121
|
-
</div>
|
|
122
|
-
<% end %>
|
|
123
|
-
</div>
|
|
124
|
-
</div>
|
|
125
|
-
<% end %>
|
|
126
|
-
<%# Edit Payload form %>
|
|
127
|
-
<details class="mt-2">
|
|
128
|
-
<summary class="text-xs font-medium text-indigo-600 cursor-pointer hover:text-indigo-500"><%= t("pgbus.events.pending_table.edit_payload") %></summary>
|
|
129
|
-
<div class="mt-2 p-3 bg-white dark:bg-gray-800 rounded ring-1 ring-gray-200 dark:ring-gray-700">
|
|
130
|
-
<%= form_with url: pgbus.edit_payload_event_path(m[:msg_id]), method: :post, local: true, data: { turbo_frame: "_top" } do |f| %>
|
|
131
|
-
<%= hidden_field_tag :queue_name, m[:queue_name] %>
|
|
132
|
-
<label class="text-xs font-medium text-gray-500"><%= t("pgbus.events.pending_table.edit_payload_label") %></label>
|
|
133
|
-
<textarea name="payload" rows="6"
|
|
134
|
-
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-900 dark:text-white text-xs font-mono shadow-sm focus:border-indigo-500 focus:ring-indigo-500"><%= parse_ok ? (JSON.pretty_generate(payload_raw) rescue m[:message]) : m[:message] %></textarea>
|
|
135
|
-
<div class="mt-2 flex justify-end">
|
|
136
|
-
<button type="submit"
|
|
137
|
-
class="rounded-md bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-500"
|
|
138
|
-
data-turbo-confirm="<%= t("pgbus.events.pending_table.edit_payload_confirm") %>">
|
|
139
|
-
<%= t("pgbus.events.pending_table.edit_payload") %>
|
|
140
|
-
</button>
|
|
141
|
-
</div>
|
|
142
|
-
<% end %>
|
|
143
|
-
</div>
|
|
144
|
-
</details>
|
|
145
|
-
<%# Full JSON %>
|
|
146
|
-
<details class="mt-2">
|
|
147
|
-
<summary class="text-xs font-medium text-gray-500 cursor-pointer hover:text-gray-700"><%= t("pgbus.events.pending_table.full_json_payload") %></summary>
|
|
148
|
-
<pre class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto max-h-96"><%= parse_ok ? (JSON.pretty_generate(payload_raw) rescue m[:message]) : m[:message] %></pre>
|
|
149
|
-
</details>
|
|
150
|
-
<% if m[:headers] %>
|
|
151
|
-
<details class="mt-2">
|
|
152
|
-
<summary class="text-xs font-medium text-gray-500 cursor-pointer hover:text-gray-700"><%= t("pgbus.events.pending_table.headers_section") %></summary>
|
|
153
|
-
<pre class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto"><%= JSON.pretty_generate(JSON.parse(m[:headers])) rescue m[:headers] %></pre>
|
|
154
|
-
</details>
|
|
155
|
-
<% end %>
|
|
156
|
-
</div>
|
|
157
|
-
</details>
|
|
158
|
-
</td>
|
|
159
|
-
</tr>
|
|
160
|
-
<% end %>
|
|
161
|
-
<% if @pending.empty? %>
|
|
162
|
-
<%# Header only renders the bulk-select column when rows are present,
|
|
163
|
-
so the empty-state colspan must match (5 without, 6 with). %>
|
|
164
|
-
<tr><td colspan="5" class="px-4 py-8 text-center text-sm text-gray-400"><%= t("pgbus.events.index.pending_empty") %></td></tr>
|
|
165
|
-
<% end %>
|
|
166
|
-
</tbody>
|
|
167
|
-
</table>
|
|
168
|
-
</div>
|
|
169
|
-
</turbo-frame>
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
<turbo-frame id="jobs-enqueued" data-auto-refresh data-src="<%= pgbus.jobs_path(request.query_parameters.merge(frame: 'enqueued')) %>">
|
|
2
|
-
<div data-bulk-page>
|
|
3
|
-
<div class="flex items-center justify-between mb-3">
|
|
4
|
-
<h2 class="text-lg font-semibold text-gray-900 dark:text-white"><%= t("pgbus.jobs.enqueued_table.title") %></h2>
|
|
5
|
-
<% if @jobs.any? %>
|
|
6
|
-
<div class="flex items-center space-x-2">
|
|
7
|
-
<div data-bulk-actions class="hidden flex items-center space-x-2">
|
|
8
|
-
<span class="text-sm text-gray-500 dark:text-gray-400"><span data-bulk-count>0</span> <%= t("pgbus.helpers.bulk_selected") %></span>
|
|
9
|
-
<button type="submit" form="bulk-discard-enqueued-form"
|
|
10
|
-
class="rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white hover:bg-red-500"
|
|
11
|
-
data-turbo-confirm="<%= t("pgbus.jobs.index.discard_selected_confirm") %>">
|
|
12
|
-
<%= t("pgbus.jobs.index.discard_selected") %>
|
|
13
|
-
</button>
|
|
14
|
-
</div>
|
|
15
|
-
<%= button_to t("pgbus.jobs.enqueued_table.discard_all"), pgbus.discard_all_enqueued_jobs_path, method: :post,
|
|
16
|
-
class: "rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white hover:bg-red-500",
|
|
17
|
-
data: { turbo_confirm: t("pgbus.jobs.enqueued_table.discard_all_confirm"), turbo_frame: "_top" } %>
|
|
18
|
-
</div>
|
|
19
|
-
<% end %>
|
|
20
|
-
</div>
|
|
21
|
-
<%# Bulk form outside table to avoid nested form issues %>
|
|
22
|
-
<form id="bulk-discard-enqueued-form" action="<%= pgbus.discard_selected_enqueued_jobs_path %>" method="post" data-turbo-frame="_top" class="hidden">
|
|
23
|
-
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
|
24
|
-
</form>
|
|
25
|
-
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700" data-bulk-scope="enqueued">
|
|
26
|
-
<table class="pgbus-table min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
27
|
-
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
28
|
-
<tr>
|
|
29
|
-
<% if @jobs.any? %>
|
|
30
|
-
<th class="w-10 px-4 py-3">
|
|
31
|
-
<input type="checkbox" data-bulk-select-all
|
|
32
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_all") %>"
|
|
33
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
|
34
|
-
</th>
|
|
35
|
-
<% end %>
|
|
36
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.enqueued_table.headers.id") %></th>
|
|
37
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.enqueued_table.headers.job_class") %></th>
|
|
38
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.enqueued_table.headers.queue") %></th>
|
|
39
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.enqueued_table.headers.enqueued") %></th>
|
|
40
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.enqueued_table.headers.reads") %></th>
|
|
41
|
-
</tr>
|
|
42
|
-
</thead>
|
|
43
|
-
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
|
|
44
|
-
<% @jobs.each do |j| %>
|
|
45
|
-
<% payload = pgbus_parse_message(j[:message]) %>
|
|
46
|
-
<tr>
|
|
47
|
-
<td class="w-10 px-4 py-3 align-top">
|
|
48
|
-
<input type="checkbox" data-bulk-item data-pgbus-action="bulk-row-toggle"
|
|
49
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_row", id: j[:msg_id]) %>"
|
|
50
|
-
data-queue-name="<%= j[:queue_name] %>" data-msg-id="<%= j[:msg_id] %>"
|
|
51
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 mt-1">
|
|
52
|
-
<input type="hidden" name="messages[][queue_name]" value="<%= j[:queue_name] %>" form="bulk-discard-enqueued-form" disabled>
|
|
53
|
-
<input type="hidden" name="messages[][msg_id]" value="<%= j[:msg_id] %>" form="bulk-discard-enqueued-form" disabled>
|
|
54
|
-
</td>
|
|
55
|
-
<td colspan="5" class="p-0">
|
|
56
|
-
<details class="group">
|
|
57
|
-
<summary class="flex cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700/50 dark:bg-gray-900 list-none">
|
|
58
|
-
<span class="w-16 shrink-0 px-4 py-3 text-sm font-mono text-gray-900 dark:text-white"><%= j[:msg_id] %></span>
|
|
59
|
-
<span class="flex-1 px-4 py-3 text-sm font-medium text-gray-900 dark:text-white"><%= payload["job_class"] || "—" %></span>
|
|
60
|
-
<span class="w-40 shrink-0 px-4 py-3 text-sm text-gray-700"><%= j[:queue_name] %></span>
|
|
61
|
-
<span class="w-28 shrink-0 px-4 py-3 text-sm text-gray-500"><%= pgbus_time_ago(j[:enqueued_at]) %></span>
|
|
62
|
-
<span class="w-16 shrink-0 px-4 py-3 text-sm text-gray-500"><%= j[:read_ct] %></span>
|
|
63
|
-
</summary>
|
|
64
|
-
<div class="px-4 pb-4 bg-gray-50 dark:bg-gray-900 border-t border-gray-100">
|
|
65
|
-
<div class="flex items-center mt-3 mb-3">
|
|
66
|
-
<span class="text-xs font-mono text-gray-400"><%= t("pgbus.jobs.enqueued_table.job_id") %> <%= payload["job_id"] %></span>
|
|
67
|
-
</div>
|
|
68
|
-
<div class="grid grid-cols-2 gap-4 mb-3">
|
|
69
|
-
<div>
|
|
70
|
-
<span class="text-xs font-medium text-gray-500"><%= t("pgbus.jobs.enqueued_table.arguments") %></span>
|
|
71
|
-
<pre class="text-xs text-gray-700 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto max-h-40"><%= JSON.pretty_generate(payload["arguments"] || []) rescue "—" %></pre>
|
|
72
|
-
</div>
|
|
73
|
-
<div>
|
|
74
|
-
<span class="text-xs font-medium text-gray-500"><%= t("pgbus.jobs.enqueued_table.metadata") %></span>
|
|
75
|
-
<div class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 space-y-1">
|
|
76
|
-
<% if payload["queue_name"] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.queue") %></strong> <%= payload["queue_name"] %></p><% end %>
|
|
77
|
-
<% if payload["priority"] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.priority") %></strong> <%= payload["priority"] %></p><% end %>
|
|
78
|
-
<% if payload["locale"] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.locale") %></strong> <%= payload["locale"] %></p><% end %>
|
|
79
|
-
<% if payload["timezone"] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.timezone") %></strong> <%= payload["timezone"] %></p><% end %>
|
|
80
|
-
<% if payload["scheduled_at"] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.scheduled") %></strong> <%= payload["scheduled_at"] %></p><% end %>
|
|
81
|
-
<% if j[:vt] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.visible_at") %></strong> <%= j[:vt] %></p><% end %>
|
|
82
|
-
<% if j[:last_read_at] %><p><strong><%= t("pgbus.jobs.enqueued_table.metadata_labels.last_read") %></strong> <%= j[:last_read_at] %></p><% end %>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
</div>
|
|
86
|
-
<details class="mt-2">
|
|
87
|
-
<summary class="text-xs font-medium text-gray-500 cursor-pointer hover:text-gray-700"><%= t("pgbus.jobs.enqueued_table.full_json_payload") %></summary>
|
|
88
|
-
<pre class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto max-h-96"><%= JSON.pretty_generate(payload) rescue j[:message] %></pre>
|
|
89
|
-
</details>
|
|
90
|
-
<% if j[:headers] %>
|
|
91
|
-
<details class="mt-2">
|
|
92
|
-
<summary class="text-xs font-medium text-gray-500 cursor-pointer hover:text-gray-700"><%= t("pgbus.jobs.enqueued_table.headers_section") %></summary>
|
|
93
|
-
<pre class="text-xs text-gray-600 bg-white dark:bg-gray-800 rounded p-2 mt-1 overflow-x-auto"><%= JSON.pretty_generate(JSON.parse(j[:headers])) rescue j[:headers] %></pre>
|
|
94
|
-
</details>
|
|
95
|
-
<% end %>
|
|
96
|
-
<div class="flex space-x-2 mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
|
97
|
-
<%= button_to t("pgbus.jobs.enqueued_table.retry"), pgbus.retry_message_queue_path(name: j[:queue_name], msg_id: j[:msg_id]),
|
|
98
|
-
method: :post,
|
|
99
|
-
class: "rounded-md bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-500",
|
|
100
|
-
data: { turbo_confirm: t("pgbus.jobs.enqueued_table.retry_confirm"), turbo_frame: "_top" } %>
|
|
101
|
-
<%= button_to t("pgbus.jobs.enqueued_table.discard"), pgbus.discard_message_queue_path(name: j[:queue_name], msg_id: j[:msg_id]),
|
|
102
|
-
method: :post,
|
|
103
|
-
class: "rounded-md bg-red-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-red-500",
|
|
104
|
-
data: { turbo_confirm: t("pgbus.jobs.enqueued_table.discard_confirm"), turbo_frame: "_top" } %>
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
</details>
|
|
108
|
-
</td>
|
|
109
|
-
</tr>
|
|
110
|
-
<% end %>
|
|
111
|
-
<% if @jobs.empty? %>
|
|
112
|
-
<tr><td colspan="6" class="px-4 py-8 text-center text-sm text-gray-400"><%= t("pgbus.jobs.enqueued_table.empty") %></td></tr>
|
|
113
|
-
<% end %>
|
|
114
|
-
</tbody>
|
|
115
|
-
</table>
|
|
116
|
-
</div>
|
|
117
|
-
</div>
|
|
118
|
-
</turbo-frame>
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
<turbo-frame id="jobs-failed" data-auto-refresh data-src="<%= pgbus.jobs_path(frame: 'failed') %>">
|
|
2
|
-
<div class="mb-8" data-bulk-page>
|
|
3
|
-
<div class="flex items-center justify-between mb-3">
|
|
4
|
-
<h2 class="text-lg font-semibold text-gray-900 dark:text-white"><%= t("pgbus.jobs.failed_table.title") %></h2>
|
|
5
|
-
<% if @failed.any? %>
|
|
6
|
-
<div class="flex items-center space-x-2">
|
|
7
|
-
<div data-bulk-actions class="hidden flex items-center space-x-2">
|
|
8
|
-
<span class="text-sm text-gray-500 dark:text-gray-400"><span data-bulk-count>0</span> <%= t("pgbus.helpers.bulk_selected") %></span>
|
|
9
|
-
<button type="submit" form="bulk-discard-failed-form"
|
|
10
|
-
class="rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-white hover:bg-red-500"
|
|
11
|
-
data-turbo-confirm="<%= t("pgbus.jobs.index.discard_selected_confirm") %>">
|
|
12
|
-
<%= t("pgbus.jobs.index.discard_selected") %>
|
|
13
|
-
</button>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
<% end %>
|
|
17
|
-
</div>
|
|
18
|
-
<%# Bulk form outside table to avoid nested form issues %>
|
|
19
|
-
<form id="bulk-discard-failed-form" action="<%= pgbus.discard_selected_failed_jobs_path %>" method="post" data-turbo-frame="_top" class="hidden">
|
|
20
|
-
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
|
|
21
|
-
</form>
|
|
22
|
-
<div class="overflow-hidden rounded-lg bg-white dark:bg-gray-800 shadow ring-1 ring-gray-200 dark:ring-gray-700" data-bulk-scope="failed">
|
|
23
|
-
<table class="pgbus-table min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
24
|
-
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
25
|
-
<tr>
|
|
26
|
-
<% if @failed.any? %>
|
|
27
|
-
<th class="w-10 px-4 py-3">
|
|
28
|
-
<input type="checkbox" data-bulk-select-all
|
|
29
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_all") %>"
|
|
30
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
|
31
|
-
</th>
|
|
32
|
-
<% end %>
|
|
33
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.id") %></th>
|
|
34
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.queue") %></th>
|
|
35
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.error") %></th>
|
|
36
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.retries") %></th>
|
|
37
|
-
<th class="px-4 py-3 text-left text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.failed") %></th>
|
|
38
|
-
<th class="px-4 py-3 text-right text-xs font-medium uppercase text-gray-500"><%= t("pgbus.jobs.failed_table.headers.actions") %></th>
|
|
39
|
-
</tr>
|
|
40
|
-
</thead>
|
|
41
|
-
<tbody class="divide-y divide-gray-100 dark:divide-gray-700">
|
|
42
|
-
<% @failed.each do |f| %>
|
|
43
|
-
<tr class="hover:bg-gray-50 dark:hover:bg-gray-700/50 dark:bg-gray-900">
|
|
44
|
-
<td class="w-10 px-4 py-3">
|
|
45
|
-
<input type="checkbox" name="ids[]" value="<%= f["id"] %>" form="bulk-discard-failed-form"
|
|
46
|
-
aria-label="<%= t("pgbus.helpers.bulk_select_row", id: f["id"]) %>"
|
|
47
|
-
data-bulk-item
|
|
48
|
-
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600">
|
|
49
|
-
</td>
|
|
50
|
-
<td data-label="ID" class="px-4 py-3 text-sm font-mono text-gray-900 dark:text-white">
|
|
51
|
-
<%= link_to f["id"], pgbus.job_path(f["id"]), class: "text-indigo-600 hover:text-indigo-500", data: { turbo_frame: "_top" } %>
|
|
52
|
-
</td>
|
|
53
|
-
<td data-label="Queue" class="px-4 py-3 text-sm text-gray-700"><%= f["queue_name"] %></td>
|
|
54
|
-
<td data-label="Error" class="px-4 py-3 text-sm text-red-600 max-w-sm truncate" title="<%= f["error_class"] %>: <%= f["error_message"] %>">
|
|
55
|
-
<span class="font-medium"><%= f["error_class"] %></span>: <%= truncate(f["error_message"].to_s, length: 80) %>
|
|
56
|
-
</td>
|
|
57
|
-
<td data-label="Retries" class="px-4 py-3 text-sm text-gray-500"><%= f["retry_count"] %></td>
|
|
58
|
-
<td data-label="Failed" class="px-4 py-3 text-sm text-gray-500"><%= pgbus_time_ago(f["failed_at"]) %></td>
|
|
59
|
-
<td data-label="Actions" class="px-4 py-3 text-sm text-right space-x-2">
|
|
60
|
-
<%= button_to t("pgbus.jobs.failed_table.retry"), pgbus.retry_job_path(f["id"]), method: :post,
|
|
61
|
-
class: "text-xs text-indigo-600 hover:text-indigo-800 font-medium",
|
|
62
|
-
data: { turbo_frame: "_top" } %>
|
|
63
|
-
<%= button_to t("pgbus.jobs.failed_table.discard"), pgbus.discard_job_path(f["id"]), method: :post,
|
|
64
|
-
class: "text-xs text-red-600 hover:text-red-800 font-medium",
|
|
65
|
-
data: { turbo_confirm: t("pgbus.jobs.failed_table.discard_confirm"), turbo_frame: "_top" } %>
|
|
66
|
-
</td>
|
|
67
|
-
</tr>
|
|
68
|
-
<% end %>
|
|
69
|
-
<% if @failed.empty? %>
|
|
70
|
-
<tr><td colspan="7" class="px-4 py-8 text-center text-sm text-gray-400"><%= t("pgbus.jobs.failed_table.empty") %></td></tr>
|
|
71
|
-
<% end %>
|
|
72
|
-
</tbody>
|
|
73
|
-
</table>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</turbo-frame>
|