pgbus 0.17.0 → 0.17.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/README.md +69 -14
- data/Rakefile +7 -1
- 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/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/modules/charts.js +119 -77
- data/app/frontend/pgbus/style.css +1 -1
- data/app/frontend/pgbus/tailwind.css +18 -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/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/lib/generators/pgbus/templates/initializer.rb.erb +4 -0
- data/lib/pgbus/active_job/executor.rb +36 -17
- data/lib/pgbus/cli/dlq.rb +32 -5
- data/lib/pgbus/client.rb +7 -2
- data/lib/pgbus/configuration.rb +93 -2
- data/lib/pgbus/dead_letter_header.rb +129 -0
- data/lib/pgbus/doctor.rb +37 -5
- 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 +51 -0
- 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/claim_buffer.rb +115 -0
- data/lib/pgbus/process/consumer.rb +94 -17
- data/lib/pgbus/process/dispatcher.rb +1 -1
- data/lib/pgbus/process/supervisor.rb +35 -12
- data/lib/pgbus/process/worker.rb +91 -25
- data/lib/pgbus/recurring/scheduler.rb +2 -1
- data/lib/pgbus/ruby_jit.rb +21 -0
- data/lib/pgbus/version.rb +1 -1
- data/lib/pgbus/visibility_heartbeat.rb +38 -3
- 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/time_format.rb +128 -0
- metadata +45 -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
|
@@ -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>
|