solid_queue_web 1.5.0 → 1.6.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.
- checksums.yaml +4 -4
- data/README.md +179 -5
- data/app/assets/stylesheets/solid_queue_web/_04_table.css +28 -0
- data/app/controllers/solid_queue_web/application_controller.rb +10 -0
- data/app/controllers/solid_queue_web/blocked_jobs_controller.rb +2 -2
- data/app/controllers/solid_queue_web/failed_jobs/arguments_controller.rb +3 -3
- data/app/controllers/solid_queue_web/failed_jobs/selections_controller.rb +4 -4
- data/app/controllers/solid_queue_web/failed_jobs_controller.rb +2 -2
- data/app/controllers/solid_queue_web/jobs/selections_controller.rb +3 -3
- data/app/controllers/solid_queue_web/jobs_controller.rb +4 -3
- data/app/controllers/solid_queue_web/queues/jobs_controller.rb +5 -5
- data/app/controllers/solid_queue_web/queues/pauses_controller.rb +4 -4
- data/app/controllers/solid_queue_web/recurring_tasks/runs_controller.rb +4 -4
- data/app/controllers/solid_queue_web/retry_failed_jobs_controller.rb +4 -5
- data/app/controllers/solid_queue_web/scheduled_jobs_controller.rb +5 -5
- data/app/views/layouts/solid_queue_web/application.html.erb +20 -17
- data/app/views/solid_queue_web/audit/index.html.erb +15 -15
- data/app/views/solid_queue_web/dashboard/index.html.erb +67 -46
- data/app/views/solid_queue_web/failed_jobs/errors/index.html.erb +7 -7
- data/app/views/solid_queue_web/failed_jobs/index.html.erb +31 -31
- data/app/views/solid_queue_web/history/index.html.erb +14 -14
- data/app/views/solid_queue_web/jobs/index.html.erb +42 -42
- data/app/views/solid_queue_web/jobs/show.html.erb +20 -20
- data/app/views/solid_queue_web/performance/index.html.erb +16 -14
- data/app/views/solid_queue_web/processes/index.html.erb +16 -16
- data/app/views/solid_queue_web/queues/index.html.erb +16 -16
- data/app/views/solid_queue_web/queues/jobs/index.html.erb +21 -21
- data/app/views/solid_queue_web/recurring_tasks/index.html.erb +15 -15
- data/app/views/solid_queue_web/search/index.html.erb +13 -13
- data/config/locales/en.yml +330 -0
- data/lib/solid_queue_web/engine.rb +1 -0
- data/lib/solid_queue_web/version.rb +1 -1
- data/lib/solid_queue_web.rb +13 -1
- metadata +2 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<div class="sqd-page-header">
|
|
2
2
|
<div>
|
|
3
3
|
<div class="sqd-breadcrumb">
|
|
4
|
-
<%= link_to "
|
|
4
|
+
<%= link_to t("solid_queue_web.queue_jobs.breadcrumb_queues"), queues_path %> › <%= @queue %>
|
|
5
5
|
</div>
|
|
6
|
-
<h1 class="sqd-page-title"
|
|
6
|
+
<h1 class="sqd-page-title"><%= t("solid_queue_web.queue_jobs.title") %></h1>
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
@@ -12,19 +12,19 @@
|
|
|
12
12
|
|
|
13
13
|
<div class="sqd-page-header">
|
|
14
14
|
<div class="sqd-filters">
|
|
15
|
-
<%= link_to "
|
|
16
|
-
<%= link_to "
|
|
17
|
-
<%= link_to "
|
|
18
|
-
<%= link_to "
|
|
19
|
-
<%= link_to "
|
|
15
|
+
<%= link_to t("solid_queue_web.queue_jobs.tab_ready"), queue_jobs_path(queue_name: @queue, status: "ready", q: @search), class: @status == "ready" ? "active" : "" %>
|
|
16
|
+
<%= link_to t("solid_queue_web.queue_jobs.tab_scheduled"), queue_jobs_path(queue_name: @queue, status: "scheduled", q: @search), class: @status == "scheduled" ? "active" : "" %>
|
|
17
|
+
<%= link_to t("solid_queue_web.queue_jobs.tab_running"), queue_jobs_path(queue_name: @queue, status: "claimed", q: @search), class: @status == "claimed" ? "active" : "" %>
|
|
18
|
+
<%= link_to t("solid_queue_web.queue_jobs.tab_blocked"), queue_jobs_path(queue_name: @queue, status: "blocked", q: @search), class: @status == "blocked" ? "active" : "" %>
|
|
19
|
+
<%= link_to t("solid_queue_web.queue_jobs.tab_failed"), queue_jobs_path(queue_name: @queue, status: "failed", q: @search), class: @status == "failed" ? "active" : "" %>
|
|
20
20
|
</div>
|
|
21
21
|
<% if discardable && @jobs.any? %>
|
|
22
22
|
<div class="sqd-actions">
|
|
23
|
-
<%= button_to "
|
|
23
|
+
<%= button_to t("solid_queue_web.queue_jobs.discard_all"), discard_all_queue_jobs_path(queue_name: @queue),
|
|
24
24
|
method: :post,
|
|
25
25
|
params: { status: @status },
|
|
26
26
|
class: "sqd-btn sqd-btn--danger",
|
|
27
|
-
data: { confirm: "
|
|
27
|
+
data: { confirm: t("solid_queue_web.queue_jobs.confirm_discard_all", count: @jobs.size, status: @status, queue: @queue) } %>
|
|
28
28
|
</div>
|
|
29
29
|
<% end %>
|
|
30
30
|
</div>
|
|
@@ -32,26 +32,26 @@
|
|
|
32
32
|
<form class="sqd-search" action="<%= queue_jobs_path(queue_name: @queue) %>" method="get" data-controller="search">
|
|
33
33
|
<input type="hidden" name="status" value="<%= @status %>">
|
|
34
34
|
<input class="sqd-search__input" type="search" name="q" value="<%= @search %>"
|
|
35
|
-
placeholder="
|
|
35
|
+
placeholder="<%= t("solid_queue_web.queue_jobs.placeholder_job_class") %>" autocomplete="off" aria-label="<%= t("solid_queue_web.queue_jobs.aria_filter_job_class") %>"
|
|
36
36
|
data-action="input->search#filter">
|
|
37
|
-
<button type="submit" class="sqd-btn sqd-btn--muted"
|
|
37
|
+
<button type="submit" class="sqd-btn sqd-btn--muted"><%= t("solid_queue_web.queue_jobs.search_button") %></button>
|
|
38
38
|
<% if @search.present? %>
|
|
39
|
-
<%= link_to "
|
|
39
|
+
<%= link_to t("solid_queue_web.shared.clear"), queue_jobs_path(queue_name: @queue, status: @status), class: "sqd-btn sqd-btn--muted" %>
|
|
40
40
|
<% end %>
|
|
41
41
|
</form>
|
|
42
42
|
|
|
43
43
|
<div class="sqd-card" id="jobs-list">
|
|
44
44
|
<% if @jobs.empty? %>
|
|
45
|
-
<div class="sqd-empty"
|
|
45
|
+
<div class="sqd-empty"><%= t("solid_queue_web.queue_jobs.no_jobs", status: @status, queue: @queue) %></div>
|
|
46
46
|
<% else %>
|
|
47
47
|
<table>
|
|
48
48
|
<thead>
|
|
49
49
|
<tr>
|
|
50
|
-
<th scope="col"
|
|
51
|
-
<th scope="col"
|
|
52
|
-
<th scope="col"
|
|
53
|
-
<th scope="col"
|
|
54
|
-
<% if discardable %><th scope="col"><span class="sqd-sr-only"
|
|
50
|
+
<th scope="col"><%= t("solid_queue_web.queue_jobs.col_job_class") %></th>
|
|
51
|
+
<th scope="col"><%= t("solid_queue_web.queue_jobs.col_priority") %></th>
|
|
52
|
+
<th scope="col"><%= t("solid_queue_web.queue_jobs.col_scheduled_at") %></th>
|
|
53
|
+
<th scope="col"><%= t("solid_queue_web.queue_jobs.col_enqueued_at") %></th>
|
|
54
|
+
<% if discardable %><th scope="col"><span class="sqd-sr-only"><%= t("solid_queue_web.queue_jobs.actions") %></span></th><% end %>
|
|
55
55
|
</tr>
|
|
56
56
|
</thead>
|
|
57
57
|
<tbody>
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
<td class="sqd-mono"><%= format_timestamp(job.created_at) %></td>
|
|
70
70
|
<% if discardable %>
|
|
71
71
|
<td class="sqd-row-actions">
|
|
72
|
-
<%= button_to "
|
|
72
|
+
<%= button_to t("solid_queue_web.queue_jobs.discard"), queue_job_path(queue_name: @queue, id: execution),
|
|
73
73
|
method: :delete,
|
|
74
74
|
params: { status: @status },
|
|
75
75
|
class: "sqd-btn sqd-btn--danger sqd-btn--sm",
|
|
76
|
-
data: { confirm: "
|
|
76
|
+
data: { confirm: t("solid_queue_web.queue_jobs.confirm_discard") } %>
|
|
77
77
|
</td>
|
|
78
78
|
<% end %>
|
|
79
79
|
</tr>
|
|
@@ -86,4 +86,4 @@
|
|
|
86
86
|
<% if @pagy.last > 1 %>
|
|
87
87
|
<%= @pagy.series_nav.html_safe %>
|
|
88
88
|
<% end %>
|
|
89
|
-
<% end %>
|
|
89
|
+
<% end %>
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
<h1 class="sqd-page-title"
|
|
1
|
+
<h1 class="sqd-page-title"><%= t("solid_queue_web.recurring_tasks.title") %></h1>
|
|
2
2
|
|
|
3
3
|
<div class="sqd-card" style="margin-top: 1.5rem;">
|
|
4
4
|
<% if @recurring_tasks.empty? %>
|
|
5
|
-
<div class="sqd-empty"
|
|
5
|
+
<div class="sqd-empty"><%= t("solid_queue_web.recurring_tasks.empty") %></div>
|
|
6
6
|
<% else %>
|
|
7
7
|
<table>
|
|
8
8
|
<thead>
|
|
9
9
|
<tr>
|
|
10
|
-
<th scope="col"
|
|
11
|
-
<th scope="col"
|
|
12
|
-
<th scope="col"
|
|
13
|
-
<th scope="col"
|
|
14
|
-
<th scope="col"
|
|
15
|
-
<th scope="col"
|
|
16
|
-
<th scope="col"
|
|
17
|
-
<th scope="col"><span class="sqd-sr-only"
|
|
10
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_key") %></th>
|
|
11
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_schedule") %></th>
|
|
12
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_job_command") %></th>
|
|
13
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_queue") %></th>
|
|
14
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_next_run") %></th>
|
|
15
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_last_run") %></th>
|
|
16
|
+
<th scope="col"><%= t("solid_queue_web.recurring_tasks.col_type") %></th>
|
|
17
|
+
<th scope="col"><span class="sqd-sr-only"><%= t("solid_queue_web.shared.actions") %></span></th>
|
|
18
18
|
</tr>
|
|
19
19
|
</thead>
|
|
20
20
|
<tbody>
|
|
@@ -56,20 +56,20 @@
|
|
|
56
56
|
</td>
|
|
57
57
|
<td>
|
|
58
58
|
<% if task.static? %>
|
|
59
|
-
<span class="sqd-badge sqd-badge--static"
|
|
59
|
+
<span class="sqd-badge sqd-badge--static"><%= t("solid_queue_web.recurring_tasks.type_static") %></span>
|
|
60
60
|
<% else %>
|
|
61
|
-
<span class="sqd-badge sqd-badge--dynamic"
|
|
61
|
+
<span class="sqd-badge sqd-badge--dynamic"><%= t("solid_queue_web.recurring_tasks.type_dynamic") %></span>
|
|
62
62
|
<% end %>
|
|
63
63
|
</td>
|
|
64
64
|
<td class="sqd-row-actions">
|
|
65
|
-
<%= button_to "
|
|
65
|
+
<%= button_to t("solid_queue_web.recurring_tasks.run_now"), recurring_task_run_path(task.key),
|
|
66
66
|
method: :post,
|
|
67
67
|
class: "sqd-btn sqd-btn--primary sqd-btn--sm",
|
|
68
|
-
data: { confirm: "
|
|
68
|
+
data: { confirm: t("solid_queue_web.recurring_tasks.confirm_run_now", key: task.key) } %>
|
|
69
69
|
</td>
|
|
70
70
|
</tr>
|
|
71
71
|
<% end %>
|
|
72
72
|
</tbody>
|
|
73
73
|
</table>
|
|
74
74
|
<% end %>
|
|
75
|
-
</div>
|
|
75
|
+
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h1 class="sqd-page-title" style="margin-bottom: 1.5rem;"
|
|
1
|
+
<h1 class="sqd-page-title" style="margin-bottom: 1.5rem;"><%= t("solid_queue_web.search.title") %></h1>
|
|
2
2
|
|
|
3
3
|
<datalist id="job-class-list">
|
|
4
4
|
<% @job_classes.each do |klass| %>
|
|
@@ -8,42 +8,42 @@
|
|
|
8
8
|
|
|
9
9
|
<form class="sqd-search sqd-search--global" action="<%= search_path %>" method="get" data-controller="search">
|
|
10
10
|
<input class="sqd-search__input sqd-search__input--lg" type="search" name="q"
|
|
11
|
-
value="<%= @query %>" placeholder="
|
|
11
|
+
value="<%= @query %>" placeholder="<%= t("solid_queue_web.search.placeholder") %>"
|
|
12
12
|
list="job-class-list" autocomplete="off"
|
|
13
|
-
aria-label="
|
|
13
|
+
aria-label="<%= t("solid_queue_web.search.aria_label") %>"
|
|
14
14
|
data-action="change->search#select">
|
|
15
15
|
<% if @query.present? %>
|
|
16
|
-
<%= link_to "
|
|
16
|
+
<%= link_to t("solid_queue_web.search.clear"), search_path, class: "sqd-btn sqd-btn--muted" %>
|
|
17
17
|
<% end %>
|
|
18
18
|
</form>
|
|
19
19
|
|
|
20
20
|
<% if @query.present? %>
|
|
21
21
|
<% if @results.empty? %>
|
|
22
|
-
<div class="sqd-empty" style="margin-top: 1rem;"
|
|
22
|
+
<div class="sqd-empty" style="margin-top: 1rem;"><%= t("solid_queue_web.search.no_results", query: @query) %></div>
|
|
23
23
|
<% else %>
|
|
24
24
|
<% @results.each do |status, data| %>
|
|
25
25
|
<div class="sqd-search-group">
|
|
26
26
|
<div class="sqd-search-group__header">
|
|
27
27
|
<span class="sqd-badge sqd-badge--<%= status %>"><%= status %></span>
|
|
28
28
|
<span class="sqd-muted-text">
|
|
29
|
-
<%=
|
|
29
|
+
<%= t("solid_queue_web.search.matches", count: data[:total]) %>
|
|
30
30
|
<% if data[:total] > SolidQueueWeb.search_results_limit %>
|
|
31
|
-
|
|
31
|
+
<%= t("solid_queue_web.search.showing_first", limit: SolidQueueWeb.search_results_limit) %>
|
|
32
32
|
<% end %>
|
|
33
33
|
</span>
|
|
34
34
|
<% if status == "failed" %>
|
|
35
|
-
<%= link_to "
|
|
35
|
+
<%= link_to t("solid_queue_web.search.view_all"), failed_jobs_path(q: @query), class: "sqd-btn sqd-btn--muted sqd-btn--sm" %>
|
|
36
36
|
<% else %>
|
|
37
|
-
<%= link_to "
|
|
37
|
+
<%= link_to t("solid_queue_web.search.view_all"), jobs_path(status: status, q: @query), class: "sqd-btn sqd-btn--muted sqd-btn--sm" %>
|
|
38
38
|
<% end %>
|
|
39
39
|
</div>
|
|
40
40
|
<div class="sqd-card">
|
|
41
41
|
<table>
|
|
42
42
|
<thead>
|
|
43
43
|
<tr>
|
|
44
|
-
<th scope="col"
|
|
45
|
-
<th scope="col"
|
|
46
|
-
<th scope="col"
|
|
44
|
+
<th scope="col"><%= t("solid_queue_web.search.col_job_class") %></th>
|
|
45
|
+
<th scope="col"><%= t("solid_queue_web.search.col_queue") %></th>
|
|
46
|
+
<th scope="col"><%= t("solid_queue_web.search.col_enqueued_at") %></th>
|
|
47
47
|
</tr>
|
|
48
48
|
</thead>
|
|
49
49
|
<tbody>
|
|
@@ -61,4 +61,4 @@
|
|
|
61
61
|
</div>
|
|
62
62
|
<% end %>
|
|
63
63
|
<% end %>
|
|
64
|
-
<% end %>
|
|
64
|
+
<% end %>
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
en:
|
|
2
|
+
solid_queue_web:
|
|
3
|
+
layout:
|
|
4
|
+
title: "Solid Queue Dashboard"
|
|
5
|
+
logo: "Solid Queue"
|
|
6
|
+
theme_toggle: "Switch to dark mode"
|
|
7
|
+
nav:
|
|
8
|
+
main_navigation: "Main navigation"
|
|
9
|
+
toggle: "Toggle navigation"
|
|
10
|
+
dashboard: "Dashboard"
|
|
11
|
+
queues: "Queues"
|
|
12
|
+
jobs: "Jobs"
|
|
13
|
+
history: "History"
|
|
14
|
+
performance: "Performance"
|
|
15
|
+
failed: "Failed"
|
|
16
|
+
recurring: "Recurring"
|
|
17
|
+
processes: "Processes"
|
|
18
|
+
search: "Search"
|
|
19
|
+
audit: "Audit"
|
|
20
|
+
shared:
|
|
21
|
+
actions: "Actions"
|
|
22
|
+
period_filter:
|
|
23
|
+
label: "Time period"
|
|
24
|
+
all: "All"
|
|
25
|
+
one_hour: "1h"
|
|
26
|
+
twenty_four_hours: "24h"
|
|
27
|
+
seven_days: "7d"
|
|
28
|
+
clear: "Clear"
|
|
29
|
+
export_csv: "Export CSV"
|
|
30
|
+
select_all: "Select all"
|
|
31
|
+
filtering_by_queue: "Filtering by queue:"
|
|
32
|
+
clear_filter: "Clear filter"
|
|
33
|
+
dashboard:
|
|
34
|
+
title: "Dashboard"
|
|
35
|
+
ready: "Ready"
|
|
36
|
+
scheduled: "Scheduled"
|
|
37
|
+
running: "Running"
|
|
38
|
+
blocked: "Blocked"
|
|
39
|
+
failed: "Failed"
|
|
40
|
+
queues: "Queues"
|
|
41
|
+
recurring: "Recurring"
|
|
42
|
+
processes: "Processes"
|
|
43
|
+
done_1h: "Done (1h)"
|
|
44
|
+
done_24h: "Done (24h)"
|
|
45
|
+
throughput_label: "Throughput — Last 12 Hours"
|
|
46
|
+
queue_depth_label: "Queue Depth — Last 12 Hours"
|
|
47
|
+
failures_label: "Failures — Last 12 Hours"
|
|
48
|
+
throughput_1h: "1h:"
|
|
49
|
+
throughput_24h: "24h:"
|
|
50
|
+
queue_depth_now: "Now:"
|
|
51
|
+
failures_total: "Total:"
|
|
52
|
+
no_completed_jobs: "No completed jobs in the last 24 hours"
|
|
53
|
+
no_active_jobs: "No active jobs in the last 12 hours"
|
|
54
|
+
no_failures: "No failures in the last 12 hours"
|
|
55
|
+
quick_links: "Quick Links"
|
|
56
|
+
view_ready_jobs: "View all ready jobs"
|
|
57
|
+
view_scheduled_jobs: "View scheduled jobs"
|
|
58
|
+
view_failed_jobs: "View failed jobs"
|
|
59
|
+
manage_queues: "Manage queues"
|
|
60
|
+
view_recurring_tasks: "View recurring tasks"
|
|
61
|
+
failed_jobs_card: "Failed Jobs"
|
|
62
|
+
need_attention:
|
|
63
|
+
one: "1 failed job needs attention."
|
|
64
|
+
other: "%{count} failed jobs need attention."
|
|
65
|
+
retry_all_failed: "Retry All Failed"
|
|
66
|
+
confirm_retry_all_failed:
|
|
67
|
+
one: "Retry all 1 failed job?"
|
|
68
|
+
other: "Retry all %{count} failed jobs?"
|
|
69
|
+
review: "Review →"
|
|
70
|
+
slow_jobs_card: "Slow Jobs"
|
|
71
|
+
slow_jobs_warning:
|
|
72
|
+
one: "1 job running longer than %{threshold}."
|
|
73
|
+
other: "%{count} jobs running longer than %{threshold}."
|
|
74
|
+
blocked_jobs_card: "Blocked Jobs"
|
|
75
|
+
blocked_jobs_count:
|
|
76
|
+
one: "1 blocked job."
|
|
77
|
+
other: "%{count} blocked jobs."
|
|
78
|
+
discard_all_blocked: "Discard All Blocked"
|
|
79
|
+
confirm_discard_all_blocked:
|
|
80
|
+
one: "Discard 1 blocked job? This cannot be undone."
|
|
81
|
+
other: "Discard all %{count} blocked jobs? This cannot be undone."
|
|
82
|
+
axis_now: "now"
|
|
83
|
+
jobs:
|
|
84
|
+
title: "Jobs"
|
|
85
|
+
export_csv: "Export CSV"
|
|
86
|
+
tab_ready: "Ready"
|
|
87
|
+
tab_scheduled: "Scheduled"
|
|
88
|
+
tab_running: "Running"
|
|
89
|
+
tab_blocked: "Blocked"
|
|
90
|
+
tab_failed: "Failed"
|
|
91
|
+
placeholder_job_class: "Filter by job class…"
|
|
92
|
+
aria_filter_job_class: "Filter by job class"
|
|
93
|
+
aria_filter_priority: "Filter by priority"
|
|
94
|
+
all_priorities: "All priorities"
|
|
95
|
+
priority_option: "Priority %{n}"
|
|
96
|
+
clear_search: "Clear"
|
|
97
|
+
col_job_class: "Job Class"
|
|
98
|
+
col_queue: "Queue"
|
|
99
|
+
col_priority: "Priority"
|
|
100
|
+
col_scheduled_at: "Scheduled At"
|
|
101
|
+
col_enqueued_at: "Enqueued At"
|
|
102
|
+
col_running_for: "Running For"
|
|
103
|
+
col_wait_time: "Wait Time"
|
|
104
|
+
actions: "Actions"
|
|
105
|
+
run_all_now: "Run All Now"
|
|
106
|
+
discard_all: "Discard All"
|
|
107
|
+
run_now: "Run Now"
|
|
108
|
+
discard: "Discard"
|
|
109
|
+
discard_selected: "Discard Selected"
|
|
110
|
+
confirm_run_all_now: "Run all %{count} scheduled jobs immediately?"
|
|
111
|
+
confirm_run_now: "Run this job immediately?"
|
|
112
|
+
confirm_discard: "Discard this job?"
|
|
113
|
+
confirm_discard_all: "Discard all %{count} %{status} jobs? This cannot be undone."
|
|
114
|
+
confirm_discard_selected: "Discard selected jobs? This cannot be undone."
|
|
115
|
+
no_jobs: "No %{status} jobs."
|
|
116
|
+
select_job: "Select job %{class_name}"
|
|
117
|
+
select_all_jobs: "Select all jobs"
|
|
118
|
+
selected_label: "selected"
|
|
119
|
+
jobs_show:
|
|
120
|
+
breadcrumb: "Jobs"
|
|
121
|
+
detail: "Detail"
|
|
122
|
+
section_details: "Details"
|
|
123
|
+
section_arguments: "Arguments"
|
|
124
|
+
section_error: "Error"
|
|
125
|
+
retry: "Retry"
|
|
126
|
+
discard: "Discard"
|
|
127
|
+
confirm_discard: "Discard this job?"
|
|
128
|
+
field_status: "Status"
|
|
129
|
+
field_queue: "Queue"
|
|
130
|
+
field_priority: "Priority"
|
|
131
|
+
field_active_job_id: "Active Job ID"
|
|
132
|
+
field_concurrency_key: "Concurrency Key"
|
|
133
|
+
field_blocked_until: "Blocked Until"
|
|
134
|
+
field_enqueued_at: "Enqueued At"
|
|
135
|
+
field_scheduled_at: "Scheduled At"
|
|
136
|
+
field_finished_at: "Finished At"
|
|
137
|
+
arguments_aria_label: "Job arguments JSON"
|
|
138
|
+
retry_with_args: "Retry with these arguments"
|
|
139
|
+
failed_jobs:
|
|
140
|
+
title: "Failed Jobs"
|
|
141
|
+
export_csv: "Export CSV"
|
|
142
|
+
error_summary: "Error Summary"
|
|
143
|
+
retry_all: "Retry All"
|
|
144
|
+
discard_all: "Discard All"
|
|
145
|
+
confirm_retry_all: "Retry all %{count} failed jobs?"
|
|
146
|
+
confirm_discard_all: "Discard all %{count} failed jobs? This cannot be undone."
|
|
147
|
+
confirm_discard: "Discard this job?"
|
|
148
|
+
confirm_discard_selected: "Discard selected jobs? This cannot be undone."
|
|
149
|
+
col_job_class: "Job Class"
|
|
150
|
+
col_queue: "Queue"
|
|
151
|
+
col_error: "Error"
|
|
152
|
+
col_failed_at: "Failed At"
|
|
153
|
+
retry: "Retry"
|
|
154
|
+
discard: "Discard"
|
|
155
|
+
retry_selected: "Retry Selected"
|
|
156
|
+
discard_selected: "Discard Selected"
|
|
157
|
+
select_all: "Select all failed jobs"
|
|
158
|
+
select_job: "Select job %{class_name}"
|
|
159
|
+
empty: "No failed jobs. All clear!"
|
|
160
|
+
stagger_title: "Retry all, staggered %{interval} apart"
|
|
161
|
+
confirm_stagger: "Retry %{count} failed jobs staggered %{interval} apart?"
|
|
162
|
+
failed_job_errors:
|
|
163
|
+
title: "Error Summary"
|
|
164
|
+
back: "← Failed Jobs"
|
|
165
|
+
col_error_class: "Error Class"
|
|
166
|
+
col_message: "Message"
|
|
167
|
+
col_count: "Count"
|
|
168
|
+
empty: "No failed jobs. All clear!"
|
|
169
|
+
queues:
|
|
170
|
+
title: "Queues"
|
|
171
|
+
col_name: "Name"
|
|
172
|
+
col_size: "Size"
|
|
173
|
+
col_latency: "Latency"
|
|
174
|
+
col_done_24h: "Done (24h)"
|
|
175
|
+
col_failed_24h: "Failed (24h)"
|
|
176
|
+
col_failure_rate: "Failure Rate (12h)"
|
|
177
|
+
col_status: "Status"
|
|
178
|
+
actions: "Actions"
|
|
179
|
+
status_paused: "Paused"
|
|
180
|
+
status_running: "Running"
|
|
181
|
+
pause: "Pause"
|
|
182
|
+
resume: "Resume"
|
|
183
|
+
confirm_pause: "Pause queue \"%{name}\"?"
|
|
184
|
+
empty: "No queues found."
|
|
185
|
+
failure_rate_aria: "Failure rate last 12 hours for %{queue}"
|
|
186
|
+
queue_jobs:
|
|
187
|
+
title: "Jobs"
|
|
188
|
+
breadcrumb_queues: "Queues"
|
|
189
|
+
tab_ready: "Ready"
|
|
190
|
+
tab_scheduled: "Scheduled"
|
|
191
|
+
tab_running: "Running"
|
|
192
|
+
tab_blocked: "Blocked"
|
|
193
|
+
tab_failed: "Failed"
|
|
194
|
+
discard_all: "Discard All"
|
|
195
|
+
confirm_discard_all: "Discard all %{count} %{status} jobs in %{queue}? This cannot be undone."
|
|
196
|
+
col_job_class: "Job Class"
|
|
197
|
+
col_priority: "Priority"
|
|
198
|
+
col_scheduled_at: "Scheduled At"
|
|
199
|
+
col_enqueued_at: "Enqueued At"
|
|
200
|
+
actions: "Actions"
|
|
201
|
+
discard: "Discard"
|
|
202
|
+
confirm_discard: "Discard this job?"
|
|
203
|
+
search_button: "Search"
|
|
204
|
+
placeholder_job_class: "Filter by job class…"
|
|
205
|
+
aria_filter_job_class: "Filter by job class"
|
|
206
|
+
no_jobs: "No %{status} jobs in %{queue}."
|
|
207
|
+
processes:
|
|
208
|
+
title: "Processes"
|
|
209
|
+
col_kind: "Kind"
|
|
210
|
+
col_name: "Name"
|
|
211
|
+
col_pid: "PID"
|
|
212
|
+
col_host: "Host"
|
|
213
|
+
col_details: "Details"
|
|
214
|
+
col_last_heartbeat: "Last Heartbeat"
|
|
215
|
+
col_status: "Status"
|
|
216
|
+
status_stale: "Stale"
|
|
217
|
+
status_healthy: "Healthy"
|
|
218
|
+
threads: "%{count} threads"
|
|
219
|
+
polling_interval: "every %{interval}s"
|
|
220
|
+
last_heartbeat_ago: "%{time} ago"
|
|
221
|
+
queues_title: "Queues"
|
|
222
|
+
empty: "No processes registered."
|
|
223
|
+
recurring_tasks:
|
|
224
|
+
title: "Recurring Tasks"
|
|
225
|
+
col_key: "Key"
|
|
226
|
+
col_schedule: "Schedule"
|
|
227
|
+
col_job_command: "Job / Command"
|
|
228
|
+
col_queue: "Queue"
|
|
229
|
+
col_next_run: "Next Run"
|
|
230
|
+
col_last_run: "Last Run"
|
|
231
|
+
col_type: "Type"
|
|
232
|
+
type_static: "Static"
|
|
233
|
+
type_dynamic: "Dynamic"
|
|
234
|
+
run_now: "Run Now"
|
|
235
|
+
confirm_run_now: "Run \"%{key}\" immediately?"
|
|
236
|
+
empty: "No recurring tasks configured."
|
|
237
|
+
history:
|
|
238
|
+
title: "Job History"
|
|
239
|
+
export_csv: "Export CSV"
|
|
240
|
+
col_job_class: "Job Class"
|
|
241
|
+
col_queue: "Queue"
|
|
242
|
+
col_duration: "Duration"
|
|
243
|
+
col_finished_at: "Finished At"
|
|
244
|
+
placeholder_filter: "Filter by job class…"
|
|
245
|
+
aria_filter: "Filter by job class"
|
|
246
|
+
clear: "Clear"
|
|
247
|
+
empty: "No finished jobs found."
|
|
248
|
+
performance:
|
|
249
|
+
title: "Performance"
|
|
250
|
+
col_job_class: "Job Class"
|
|
251
|
+
col_runs: "Runs"
|
|
252
|
+
col_avg: "Avg"
|
|
253
|
+
col_p50: "p50"
|
|
254
|
+
col_p95: "p95"
|
|
255
|
+
col_p99: "p99"
|
|
256
|
+
col_std_dev: "Std Dev"
|
|
257
|
+
col_min: "Min"
|
|
258
|
+
col_max: "Max"
|
|
259
|
+
empty: "No finished jobs found."
|
|
260
|
+
empty_with_period: "No finished jobs found in the last %{period}."
|
|
261
|
+
audit:
|
|
262
|
+
title: "Audit Log"
|
|
263
|
+
export_csv: "Export CSV"
|
|
264
|
+
all_actions: "All actions"
|
|
265
|
+
aria_filter_action: "Filter by action"
|
|
266
|
+
actor_label: "Actor:"
|
|
267
|
+
queue_label: "Queue:"
|
|
268
|
+
clear_all: "Clear"
|
|
269
|
+
col_time: "Time"
|
|
270
|
+
col_action: "Action"
|
|
271
|
+
col_actor: "Actor"
|
|
272
|
+
col_job_class: "Job Class"
|
|
273
|
+
col_queue: "Queue"
|
|
274
|
+
col_count: "Count"
|
|
275
|
+
empty: "No audit events recorded."
|
|
276
|
+
search:
|
|
277
|
+
title: "Search Jobs"
|
|
278
|
+
placeholder: "Search by job class name…"
|
|
279
|
+
aria_label: "Search all jobs by class name"
|
|
280
|
+
clear: "Clear"
|
|
281
|
+
no_results: "No jobs found matching \"%{query}\"."
|
|
282
|
+
matches:
|
|
283
|
+
one: "1 match"
|
|
284
|
+
other: "%{count} matches"
|
|
285
|
+
showing_first: "— showing first %{limit}"
|
|
286
|
+
view_all: "View all →"
|
|
287
|
+
col_job_class: "Job Class"
|
|
288
|
+
col_queue: "Queue"
|
|
289
|
+
col_enqueued_at: "Enqueued At"
|
|
290
|
+
flash:
|
|
291
|
+
job_discarded: "Job discarded."
|
|
292
|
+
jobs_discarded:
|
|
293
|
+
one: "1 job discarded."
|
|
294
|
+
other: "%{count} jobs discarded."
|
|
295
|
+
blocked_jobs_discarded:
|
|
296
|
+
one: "1 blocked job discarded."
|
|
297
|
+
other: "%{count} blocked jobs discarded."
|
|
298
|
+
job_run_immediately: "Job scheduled to run immediately."
|
|
299
|
+
jobs_run_immediately:
|
|
300
|
+
one: "1 job scheduled to run immediately."
|
|
301
|
+
other: "%{count} jobs scheduled to run immediately."
|
|
302
|
+
job_rescheduled: "Job rescheduled by +%{offset}."
|
|
303
|
+
jobs_retried:
|
|
304
|
+
one: "1 job queued for retry."
|
|
305
|
+
other: "%{count} jobs queued for retry."
|
|
306
|
+
jobs_retried_staggered:
|
|
307
|
+
one: "1 job queued for retry, staggered %{stagger} apart."
|
|
308
|
+
other: "%{count} jobs queued for retry, staggered %{stagger} apart."
|
|
309
|
+
arguments_updated: "Job arguments updated and queued for retry."
|
|
310
|
+
task_queued: "\"%{key}\" queued for immediate execution."
|
|
311
|
+
queue_paused: "Queue \"%{name}\" paused."
|
|
312
|
+
queue_resumed: "Queue \"%{name}\" resumed."
|
|
313
|
+
cannot_discard: "Cannot discard %{status} jobs."
|
|
314
|
+
cannot_discard_from_queue: "Cannot discard %{status} jobs from this page."
|
|
315
|
+
cannot_discard_job: "Could not discard job: %{error}"
|
|
316
|
+
cannot_discard_jobs: "Could not discard jobs: %{error}"
|
|
317
|
+
cannot_discard_blocked_jobs: "Could not discard blocked jobs: %{error}"
|
|
318
|
+
cannot_retry_jobs: "Could not retry jobs: %{error}"
|
|
319
|
+
cannot_retry_job: "Could not retry job: %{error}"
|
|
320
|
+
cannot_run_jobs: "Could not run jobs: %{error}"
|
|
321
|
+
cannot_reschedule_job: "Could not reschedule job: %{error}"
|
|
322
|
+
cannot_update_job: "Could not update job: %{error}"
|
|
323
|
+
cannot_pause_queue: "Could not pause queue: %{error}"
|
|
324
|
+
cannot_resume_queue: "Could not resume queue: %{error}"
|
|
325
|
+
cannot_enqueue_task: "Could not enqueue \"%{key}\" — it may have just run."
|
|
326
|
+
task_not_found: "Recurring task not found."
|
|
327
|
+
cannot_run_task: "Could not run task: %{error}"
|
|
328
|
+
invalid_json: "Invalid JSON: could not parse arguments."
|
|
329
|
+
invalid_offset: "Invalid offset."
|
|
330
|
+
invalid_stagger: "Invalid stagger interval."
|
|
@@ -8,6 +8,7 @@ module SolidQueueWeb
|
|
|
8
8
|
isolate_namespace SolidQueueWeb
|
|
9
9
|
|
|
10
10
|
config.i18n.load_path += Gem.find_files("pagy/locales/en.yml")
|
|
11
|
+
config.i18n.load_path += Dir[root.join("config/locales/*.yml").to_s]
|
|
11
12
|
|
|
12
13
|
initializer "solid_queue_web.assets" do |app|
|
|
13
14
|
if app.config.respond_to?(:assets)
|
data/lib/solid_queue_web.rb
CHANGED
|
@@ -7,7 +7,7 @@ module SolidQueueWeb
|
|
|
7
7
|
attr_writer :page_size, :dashboard_refresh_interval, :default_refresh_interval, :search_results_limit,
|
|
8
8
|
:slow_job_threshold, :alert_webhook_url, :alert_failure_threshold, :alert_webhook_cooldown,
|
|
9
9
|
:alert_queue_thresholds, :alert_slow_job_count_threshold, :alert_stale_process_threshold,
|
|
10
|
-
:connects_to, :time_zone
|
|
10
|
+
:connects_to, :time_zone, :available_locales, :nav_links, :dashboard_cards
|
|
11
11
|
|
|
12
12
|
def page_size
|
|
13
13
|
@page_size || 25
|
|
@@ -61,6 +61,18 @@ module SolidQueueWeb
|
|
|
61
61
|
@time_zone
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
def available_locales
|
|
65
|
+
@available_locales || %i[en]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def nav_links
|
|
69
|
+
@nav_links || []
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def dashboard_cards
|
|
73
|
+
@dashboard_cards || []
|
|
74
|
+
end
|
|
75
|
+
|
|
64
76
|
def configure
|
|
65
77
|
yield self
|
|
66
78
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: solid_queue_web
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chuck Smith
|
|
@@ -181,6 +181,7 @@ files:
|
|
|
181
181
|
- app/views/solid_queue_web/scheduled_jobs/update.turbo_stream.erb
|
|
182
182
|
- app/views/solid_queue_web/search/index.html.erb
|
|
183
183
|
- config/importmap.rb
|
|
184
|
+
- config/locales/en.yml
|
|
184
185
|
- config/routes.rb
|
|
185
186
|
- db/migrate/01_create_solid_queue_web_audit_events.rb
|
|
186
187
|
- lib/generators/solid_queue_web/install/migrations_generator.rb
|