good_job 3.0.2 → 3.3.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.
@@ -1,122 +1,151 @@
1
- <div class="my-3">
2
- <div class="table-responsive">
3
- <%= form_with(url: mass_update_jobs_path(filter.to_params), method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
4
- <table class="table table-hover table-sm mb-0 table-jobs">
5
- <thead>
6
- <tr>
7
- <th><%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %></th>
8
- <th>ActiveJob ID</th>
9
- <th>State</th>
10
- <th>Job Class</th>
11
- <th>Queue</th>
12
- <th>Scheduled At</th>
13
- <th>Executions</th>
14
- <th>Error</th>
15
- <th>
16
- ActiveJob Params&nbsp;
17
- <%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
18
- data: { bs_toggle: "collapse", bs_target: ".job-params" },
19
- aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") }
20
- %>
21
- </th>
22
- <th>
23
- Actions<br>
1
+ <%= form_with(url: mass_update_jobs_path(filter.to_params), method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
2
+ <div class="my-3 card" data-gj-poll-replace id="jobs-table">
3
+ <div class="list-group list-group-flush text-nowrap table-jobs" role="table">
4
+ <header class="list-group-item bg-light">
5
+ <div class="row small text-muted text-uppercase align-items-center">
6
+ <div class="col-auto">
7
+ <%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %>
8
+ </div>
9
+ <div class="col-4">
10
+ <%= form.button type: 'submit', name: 'mass_action', value: 'reschedule', class: 'btn btn-sm btn-outline-secondary', title: "Reschedule all", data: { confirm: "Are you sure you want to reschedule the selected jobs?", disable: true } do %>
11
+ <span class="me-1"><%= render_icon "skip_forward" %></span> Reschedule
12
+ <% end %>
24
13
 
25
- <div class="d-inline text-nowrap">
26
- <%= form.button type: 'submit', name: 'mass_action', value: 'reschedule', class: 'btn btn-sm btn-outline-primary', title: "Reschedule all", data: { confirm: "Confirm reschedule all", disable: true } do %>
27
- <%= render_icon "skip_forward" %> All
28
- <% end %>
14
+ <%= form.button type: 'submit', name: 'mass_action', value: 'retry', class: 'btn btn-sm btn-outline-secondary', title: "Retry all", data: { confirm: "Are you sure you want to retry the selected jobs?", disable: true } do %>
15
+ <span class="me-1"><%= render_icon "arrow_clockwise" %></span> Retry
16
+ <% end %>
29
17
 
30
- <%= form.button type: 'submit', name: 'mass_action', value: 'discard', class: 'btn btn-sm btn-outline-primary', title: "Discard all", data: { confirm: "Confirm discard all", disable: true } do %>
31
- <%= render_icon "stop" %> All
18
+ <div class="btn-group" role="group">
19
+ <%= form.button type: 'submit', name: 'mass_action', value: 'discard', class: 'btn btn-sm btn-outline-secondary', title: "Discard all", data: { confirm: "Are you usure you want to discard the selected jobs?", disable: true } do %>
20
+ <span class="me-1"><%= render_icon "stop" %></span> Discard
21
+ <% end %>
22
+ <button id="destroy-dropdown-toggle" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
23
+ <span class="visually-hidden">Toggle Actions</span>
24
+ </button>
25
+ <div class="dropdown-menu" aria-labelledby="destroy-dropdown-toggle">
26
+ <li>
27
+ <%= form.button type: 'submit', name: 'mass_action', value: 'destroy', class: 'btn', title: "Destroy all", data: { confirm: "Are you sure you want to destroy the selected jobs?", disable: true } do %>
28
+ <span class="me-1"><%= render_icon "trash" %></span> Destroy
32
29
  <% end %>
30
+ </li>
31
+ </div>
32
+ </div>
33
33
 
34
- <%= form.button type: 'submit', name: 'mass_action', value: 'retry', class: 'btn btn-sm btn-outline-primary', title: "Retry all", data: { confirm: "Confirm retry all", disable: true } do %>
35
- <%= render_icon "arrow_clockwise" %> All
36
- <% end %>
34
+ </div>
35
+ <div class="col-1">Queue</div>
36
+ <div class="col-1">Priority</div>
37
+ <div class="col-1 text-end">Attempts</div>
38
+ <div class="col text-end">
39
+ <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
40
+ data: { bs_toggle: "collapse", bs_target: ".job-params" },
41
+ aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") } do %>
42
+ <%= render_icon "info" %>
43
+ <span class="visually-hidden">Inspect</span>
44
+ <% end %>
45
+ </div>
46
+ </div>
47
+ </header>
48
+ <label role="row" class="list-group-item list-group-item-warning list-group-item-action py-3 d-none" data-checkbox-toggle-show="job_ids">
49
+ <div class="row">
50
+ <div class="col-auto">
51
+ <%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids"} %>
52
+ </div>
53
+ <div class="col-auto">
54
+ Apply to all <%= filter.filtered_count %> <%= "job".pluralize(filter.filtered_count) %>.
55
+ </div>
56
+ </div>
57
+ </label>
37
58
 
38
- <%= form.button type: 'submit', name: 'mass_action', value: 'destroy', class: 'btn btn-sm btn-outline-primary', title: "Destroy all", data: { confirm: "Confirm destroy all", disable: true } do %>
39
- <%= render_icon "trash" %> All
40
- <% end %>
41
- </div>
42
- </th>
43
- </tr>
44
- <tr class="d-none" data-checkbox-toggle-show="job_ids">
45
- <td class="text-center table-warning" colspan="10">
46
- <label>
47
- <%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids"} %>
48
- Apply to all <%= filter.filtered_count %> <%= "job".pluralize(filter.filtered_count) %>.
49
- </label>
50
- </td>
51
- </tr>
52
- </thead>
53
- <tbody>
54
- <% if jobs.present? %>
55
- <% jobs.each do |job| %>
56
- <tr class="<%= dom_class(job) %>" id="<%= dom_id(job) %>">
57
- <td><%= check_box_tag 'job_ids[]', job.id, false, data: { "checkbox-toggle-each": "job_ids" } %></td>
58
- <td>
59
- <%= link_to job_path(job.id) do %>
60
- <code><%= job.id %></code>
61
- <% end %>
62
- </td>
63
- <td><%= status_badge(job.status) %></td>
64
- <td><%= job.job_class %></td>
65
- <td><%= job.queue_name %></td>
66
- <td><%= relative_time(job.scheduled_at || job.created_at) %></td>
67
- <td><%= job.executions_count %></td>
68
- <td class="text-break"><%= truncate(job.recent_error, length: 1_000) %></td>
69
- <td>
70
- <%= tag.button "Inspect", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
71
- data: { bs_toggle: "collapse", bs_target: "##{dom_id(job, 'params')}" },
72
- aria: { expanded: false, controls: dom_id(job, "params") }
73
- %>
74
- <%= tag.pre JSON.pretty_generate(job.serialized_params), id: dom_id(job, "params"), class: "collapse job-params" %>
75
- </td>
76
- <td>
77
- <div class="text-nowrap">
78
- <% if job.status.in? [:scheduled, :retried, :queued] %>
79
- <%= link_to reschedule_job_path(job.id), method: :put, class: "btn btn-sm btn-outline-primary", title: "Reschedule job", data: { confirm: "Confirm reschedule", disable: true } do %>
80
- <%= render_icon "skip_forward" %>
81
- <% end %>
82
- <% else %>
83
- <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "skip_forward" %></button>
59
+ <% if jobs.present? %>
60
+ <% jobs.each do |job| %>
61
+ <%= label_tag dom_id(job, :checkbox), id: dom_id(job), role: "row", class: "list-group-item list-group-item-action py-3" do %>
62
+ <div class="row align-items-center">
63
+ <div class="col-auto">
64
+ <%= check_box_tag 'job_ids[]', job.id, false, id: dom_id(job, :checkbox), data: { "checkbox-toggle-each": "job_ids" } %>
65
+ </div>
66
+ <div class="col-4">
67
+ <%= tag.code link_to(job.id, job_path(job), class: "small text-muted text-decoration-none") %>
68
+ <%= tag.h5 tag.code(link_to(job.job_class, job_path(job), class: "text-reset text-decoration-none")), class: "text-reset mb-0" %>
69
+ </div>
70
+ <div class="col-1">
71
+ <span class="badge bg-primary bg-opacity-25 text-dark font-monospace"><%= job.queue_name %></span>
72
+ </div>
73
+ <div class="col-1 small text-center">
74
+ <span class="font-monospace fw-bold"><%= job.priority %></span>
75
+ </div>
76
+ <div class="col-1 text-center">
77
+ <% if job.executions_count > 0 && job.status != :finished %>
78
+ <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger", data: {
79
+ bs_toggle: "popover",
80
+ bs_trigger: "hover focus click",
81
+ bs_placement: "bottom",
82
+ bs_content: job.recent_error
83
+ } %>
84
+ <% else %>
85
+ <span class="badge bg-secondary bg-opacity-50 rounded-pill"><%= job.executions_count %></span>
86
+ <% end %>
87
+ </div>
88
+ <div class="col d-flex gap-3 align-items-center justify-content-end">
89
+ <%= tag.span relative_time(job.last_status_at), class: "small" %>
90
+ <%= status_badge job.status %>
91
+ </div>
92
+ <div class="col-auto">
93
+ <div class="dropdown float-end">
94
+ <button class="d-flex align-items-center btn btn-sm" type="button" id="<%= dom_id(job, :actions) %>" data-bs-toggle="dropdown" aria-expanded="false">
95
+ <%= render "good_job/shared/icons/dots" %>
96
+ <span class="visually-hidden">Actions</span>
97
+ </button>
98
+ <ul class="dropdown-menu shadow" aria-labelledby="<%= dom_id(job, :actions) %>">
99
+ <li>
100
+ <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
101
+ <%= link_to reschedule_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_reschedulable}", title: "Reschedule job", data: { confirm: "Confirm reschedule", disable: true } do %>
102
+ <%= render "good_job/shared/icons/skip_forward" %>
103
+ Reschedule
84
104
  <% end %>
85
-
86
- <% if job.status.in? [:scheduled, :retried, :queued] %>
87
- <%= link_to discard_job_path(job.id), method: :put, class: "btn btn-sm btn-outline-primary", title: "Discard job", data: { confirm: "Confirm discard", disable: true } do %>
88
- <%= render_icon "stop" %>
89
- <% end %>
90
- <% else %>
91
- <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "stop" %></button>
105
+ </li>
106
+ <li>
107
+ <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
108
+ <%= link_to discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_discardable}", title: "Discard job", data: { confirm: "Confirm discard", disable: true } do %>
109
+ <%= render "good_job/shared/icons/stop" %>
110
+ Discard
92
111
  <% end %>
93
-
94
- <% if job.status == :discarded %>
95
- <%= link_to retry_job_path(job.id), method: :put, class: "btn btn-sm btn-outline-primary", title: "Retry job", data: { confirm: "Confirm retry", disable: true } do %>
96
- <%= render_icon "arrow_clockwise" %>
97
- <% end %>
98
- <% else %>
99
- <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "arrow_clockwise" %></button>
112
+ </li>
113
+ <li>
114
+ <%= link_to retry_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job.status == :discarded}", title: "Retry job", data: { confirm: "Confirm retry", disable: true } do %>
115
+ <%= render "good_job/shared/icons/arrow_clockwise" %>
116
+ Retry
117
+ <% end %>
118
+ </li>
119
+ <li>
120
+ <%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :finished]}", title: "Destroy job", data: { confirm: "Confirm destroy", disable: true } do %>
121
+ <%= render_icon "trash" %>
122
+ Destroy
100
123
  <% end %>
124
+ </li>
101
125
 
102
- <% if job.status.in? [:discarded, :finished] %>
103
- <%= link_to job_path(job.id), method: :delete, class: "btn btn-sm btn-outline-primary", title: "Destroy job", data: { confirm: "Confirm destroy", disable: true } do %>
104
- <%= render_icon "trash" %>
105
- <% end %>
106
- <% else %>
107
- <button class="btn btn-sm btn-outline-secondary" disabled><%= render_icon "trash" %></button>
126
+ <li>
127
+ <%= link_to "##{dom_id(job, 'params')}",
128
+ class: "dropdown-item",
129
+ data: { bs_toggle: "collapse" },
130
+ aria: { expanded: false, controls: dom_id(job, "params") } do %>
131
+ <%= render_icon "info" %>
132
+ Inspect
108
133
  <% end %>
109
- </div>
110
- </td>
111
- </tr>
112
- <% end %>
113
- <% else %>
114
- <tr>
115
- <td colspan="10" class="py-2 text-center text-muted">No jobs found.</td>
116
- </tr>
117
- <% end %>
118
- </tbody>
119
- </table>
134
+ </li>
135
+ </ul>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ <% end %>
140
+ <%= tag.div id: dom_id(job, "params"), class: "job-params list-group-item collapse small bg-dark text-light" do %>
141
+ <%= tag.pre JSON.pretty_generate(job.display_serialized_params) %>
142
+ <% end %>
143
+ <% end %>
144
+ <% else %>
145
+ <div class="list-group-item py-4 text-center text-muted">
146
+ No jobs found.
147
+ </div>
120
148
  <% end %>
121
149
  </div>
122
150
  </div>
151
+ <% end %>
@@ -1,48 +1,57 @@
1
1
  <div class="break-out bg-light border-bottom py-2 mb-3">
2
2
  <div class="container-fluid pt-2">
3
- <div class="d-flex align-items-center">
4
- <div class="flex-fill">
3
+ <div class="row align-items-center">
4
+ <div class="col-5">
5
5
  <nav aria-label="breadcrumb">
6
6
  <ol class="breadcrumb small mb-0">
7
7
  <li class="breadcrumb-item"><%= link_to "Jobs", jobs_path %></li>
8
- <li class="breadcrumb-item active" aria-current="page">ActiveJob ID: <%= tag.code @job.id %></li>
8
+ <li class="breadcrumb-item active" aria-current="page"><%= tag.code @job.id, class: "text-muted" %></li>
9
9
  </ol>
10
10
  </nav>
11
- <h2 class="mb-1"><%= tag.code @job.job_class %></h2>
12
- <div class="text-muted small d-flex gap-2">
13
- <div>Queue: <%= tag.strong @job.queue_name %></div>
14
-
15
- <div>Priority: <%= tag.strong @job.priority %></div>
11
+ <h2 class="mb-0"><%= tag.code @job.job_class %></h2>
12
+ </div>
13
+ <div class="col-2">
14
+ <div class="small text-muted text-uppercase">Queue</div>
15
+ <div class="badge bg-primary bg-opacity-25 text-dark font-monospace my-2">
16
+ <%= tag.strong @job.queue_name %>
16
17
  </div>
17
18
  </div>
18
- <div>
19
- <% job_reschedulable = @job.status.in? [:scheduled, :retried, :queued] %>
20
- <%= button_to reschedule_job_path(@job.id), method: :put,
21
- class: "btn btn-sm #{job_reschedulable ? 'btn-outline-primary' : 'btn-outline-secondary'}",
22
- form_class: "d-inline-block",
23
- disabled: !job_reschedulable,
24
- aria: { label: "Reschedule job" },
25
- title: "Reschedule job",
26
- data: { confirm: "Confirm reschedule" } do %>
27
- <%= render_icon "skip_forward" %>
28
- Reschedule
19
+ <div class="col-2">
20
+ <div class="small text-muted text-uppercase">Priority</div>
21
+ <div class="font-monospace fw-bold small my-2"><%= tag.strong @job.priority %></div>
22
+ </div>
23
+ <div class="col text-end">
24
+ <% if @job.status.in? [:scheduled, :retried, :queued] %>
25
+ <%= button_to reschedule_job_path(@job.id), method: :put,
26
+ class: "btn btn-sm btn-outline-primary",
27
+ form_class: "d-inline-block",
28
+ aria: { label: "Reschedule job" },
29
+ title: "Reschedule job",
30
+ data: { confirm: "Confirm reschedule" } do %>
31
+ <%= render_icon "skip_forward" %>
32
+ Reschedule
33
+ <% end %>
29
34
  <% end %>
30
35
 
31
- <% job_discardable = @job.status.in? [:scheduled, :retried, :queued] %>
32
- <%= button_to discard_job_path(@job.id), method: :put, class: "btn btn-sm #{job_discardable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_discardable, aria: { label: "Discard job" }, title: "Discard job", data: { confirm: "Confirm discard" } do %>
33
- <%= render_icon "stop" %>
34
- Discard
36
+ <% if @job.status.in? [:scheduled, :retried, :queued] %>
37
+ <%= button_to discard_job_path(@job.id), method: :put, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Discard job" }, title: "Discard job", data: { confirm: "Confirm discard" } do %>
38
+ <%= render_icon "stop" %>
39
+ Discard
40
+ <% end %>
35
41
  <% end %>
36
42
 
37
- <%= button_to retry_job_path(@job.id), method: :put, class: "btn btn-sm #{@job.status == :discarded ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: @job.status != :discarded, aria: { label: "Retry job" }, title: "Retry job", data: { confirm: "Confirm retry" } do %>
38
- <%= render_icon "arrow_clockwise" %>
39
- Retry
43
+ <% if @job.status == :discarded %>
44
+ <%= button_to retry_job_path(@job.id), method: :put, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Retry job" }, title: "Retry job", data: { confirm: "Confirm retry" } do %>
45
+ <%= render_icon "arrow_clockwise" %>
46
+ Retry
47
+ <% end %>
40
48
  <% end %>
41
49
 
42
- <% job_destroyable = @job.status.in? [:discarded, :finished] %>
43
- <%= button_to job_path(@job.id), method: :delete, class: "btn btn-sm #{job_destroyable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_destroyable, aria: { label: "Destroy job" }, title: "Destroy job", data: { confirm: "Confirm destroy" } do %>
44
- <%= render_icon "trash" %>
45
- Destroy
50
+ <% if @job.status.in? [:discarded, :finished] %>
51
+ <%= button_to job_path(@job.id), method: :delete, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Destroy job" }, title: "Destroy job", data: { confirm: "Confirm destroy" } do %>
52
+ <%= render_icon "trash" %>
53
+ Destroy
54
+ <% end %>
46
55
  <% end %>
47
56
  </div>
48
57
  </div>
@@ -51,7 +60,7 @@
51
60
 
52
61
  <div class="my-4">
53
62
  <h5>Arguments</h5>
54
- <%= tag.pre @job.serialized_params["arguments"].map(&:inspect).join(', ') %>
63
+ <%= tag.pre @job.serialized_params["arguments"].map(&:inspect).join(', '), class: 'text-wrap text-break' %>
55
64
  </div>
56
65
 
57
- <%= render 'executions', executions: @job.executions.reverse %>
66
+ <%= render 'executions', executions: @job.executions.includes_advisory_locks.reverse %>
@@ -1,38 +1,66 @@
1
- <div class="my-3 flex">
2
- <h2>Processes</h2>
1
+ <div class="bg-light break-out border-bottom">
2
+ <h2 class="container-fluid pt-3 pb-2">Processes</h2>
3
3
  </div>
4
4
 
5
- <div data-live-poll-region="processes">
6
- <% if @processes.present? %>
7
- <div class="card my-3">
8
- <div class="table-responsive">
9
- <table class="table card-table table-bordered table-hover table-sm mb-0">
10
- <thead>
11
- <tr>
12
- <th>Process UUID</th>
13
- <th>Created At</th></th>
14
- <th>State</th>
15
- </tr>
16
- </thead>
17
- <tbody>
18
- <% @processes.each do |process| %>
19
- <tr class="<%= dom_class(process) %>" id="<%= dom_id(process) %>">
20
- <td><%= process.id %></td>
21
- <td><%= relative_time(process.created_at) %></td>
22
- <td><%= tag.pre JSON.pretty_generate(process.state) %></td>
23
- </tr>
5
+ <div class="card my-3" data-live-poll-region="processes">
6
+ <div class="list-group list-group-flush text-nowrap" role="table">
7
+ <header class="list-group-item bg-light">
8
+ <div class="row small text-muted text-uppercase align-items-center">
9
+ <div class="col">Process</div>
10
+ <div class="col">Schedulers</div>
11
+ <div class="col-2 d-flex gap-2">
12
+ <span>Started</span>
13
+ </div>
14
+ <div class="col-auto">
15
+ <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
16
+ data: { bs_toggle: "collapse", bs_target: ".process-state" },
17
+ aria: { expanded: false, controls: @processes.map { |process| "##{dom_id(process, 'state')}" }.join(" ") } do %>
18
+ <%= render_icon "info" %>
19
+ <span class="visually-hidden">Inspect</span>
24
20
  <% end %>
25
- </tbody>
26
- </table>
21
+ </div>
27
22
  </div>
28
- </div>
29
- <% else %>
30
- <div class="card my-3">
31
- <div class="card-body">
32
- <p class="card-text">
33
- <em>No GoodJob processes found.</em>
34
- </p>
23
+ </header>
24
+ <% @processes.each do |process| %>
25
+ <div id="<%= dom_id(process) %>" class="<%= dom_class(process) %> list-group-item py-3" role="row">
26
+ <div class="row align-items-center">
27
+ <div class="col">
28
+ <code class="font-monospace">
29
+ <span class="text-muted opacity-50">$</span>
30
+ <%= process.state["proctitle"] %>
31
+ </code>
32
+ <div>
33
+ <span class="text-muted small">PID</span>
34
+ <span class="badge rounded-pill bg-light text-dark"><%= process.state["pid"] %></span>
35
+ <span class="text-muted small">@</span>
36
+ <span class="badge rounded-pill bg-light text-dark"><%= process.state["hostname"] %></span>
37
+ </div>
38
+ </div>
39
+ <div class="col">
40
+ <% process.state["schedulers"].each do |scheduler| %>
41
+ <pre class="mb-0"><%= scheduler %></pre>
42
+ <% end %>
43
+ </div>
44
+ <div class="col-2 small"><%= relative_time(process.created_at) %></div>
45
+ <div class="col-auto">
46
+ <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
47
+ title: "Inspect",
48
+ data: { bs_toggle: "collapse", bs_target: "##{dom_id(process, 'state')}" },
49
+ aria: { expanded: false, controls: dom_id(process, "state") } do %>
50
+ <%= render_icon "info" %>
51
+ <span class="visually-hidden">Inspect</span>
52
+ <% end %>
53
+ </div>
54
+ </div>
35
55
  </div>
36
- </div>
37
- <% end %>
56
+ <%= tag.div id: dom_id(process, "state"), class: "process-state list-group-item collapse small bg-dark text-light" do %>
57
+ <%= tag.pre JSON.pretty_generate(process.state) %>
58
+ <% end %>
59
+ <% end %>
60
+ <% if @processes.empty? %>
61
+ <div class="list-group-item py-4 text-center text-muted">
62
+ No GoodJob processes found.
63
+ </div>
64
+ <% end %>
65
+ </div>
38
66
  </div>
@@ -11,7 +11,7 @@
11
11
  <li class="nav-item">
12
12
  <%= link_to url_for({state: name}), class: "nav-link #{"active" if params[:state] == name}" do %>
13
13
  <%= t(name, scope: 'good_job.status') %>
14
- <span class="badge bg-primary rounded-pill <%= "bg-secondary" if count == 0 %>"><%= count %></span>
14
+ <span class="badge bg-primary rounded-pill <%= "bg-secondary" if count == 0 %>"><%= number_with_delimiter(count) %></span>
15
15
  <% end %>
16
16
  </li>
17
17
  <% end %>
@@ -8,13 +8,25 @@
8
8
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
9
9
  <ul class="navbar-nav me-auto">
10
10
  <li class="nav-item">
11
- <%= link_to t(".jobs"), jobs_path, class: ["nav-link", ("active" if controller_name == 'jobs')] %>
11
+ <%= link_to jobs_path, class: ["nav-link", ("active" if controller_name == 'jobs')] do %>
12
+ <%= t(".jobs") %>
13
+ <% jobs_count = GoodJob::Job.count %>
14
+ <span class="badge bg-secondary rounded-pill"><%= number_to_human(jobs_count) %></span>
15
+ <% end %>
12
16
  </li>
13
17
  <li class="nav-item">
14
- <%= link_to t(".cron_schedules"), cron_entries_path, class: ["nav-link", ("active" if controller_name == 'cron_entries')] %>
18
+ <%= link_to cron_entries_path, class: ["nav-link", ("active" if controller_name == 'cron_entries')] do %>
19
+ <%= t(".cron_schedules") %>
20
+ <% cron_entries_count = GoodJob::CronEntry.all.size %>
21
+ <span class="badge bg-secondary rounded-pill"><%= cron_entries_count %></span>
22
+ <% end %>
15
23
  </li>
16
24
  <li class="nav-item">
17
- <%= link_to t(".processes"), processes_path, class: ["nav-link", ("active" if controller_name == 'processes')] %>
25
+ <%= link_to processes_path, class: ["nav-link", ("active" if controller_name == 'processes')] do %>
26
+ <%= t(".processes") %>
27
+ <% processes_count = GoodJob::Process.count %>
28
+ <span class="badge bg-secondary rounded-pill <%= "bg-danger" if processes_count == 0 %>"><%= processes_count %></span>
29
+ <% end %>
18
30
  </li>
19
31
  </ul>
20
32
  <div class="nav-item pe-2">
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
2
+ <path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
2
+ <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
3
+ <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
4
+ </svg>
@@ -63,3 +63,22 @@ en:
63
63
  retried: Retried
64
64
  running: Running
65
65
  scheduled: Scheduled
66
+ number:
67
+ format:
68
+ delimiter: ","
69
+ separator: "."
70
+ human:
71
+ decimal_units:
72
+ format: "%n%u"
73
+ units:
74
+ billion: B
75
+ hundred: ''
76
+ million: M
77
+ quadrillion: Q
78
+ thousand: K
79
+ trillion: T
80
+ unit: ''
81
+ format:
82
+ delimiter: ","
83
+ precision: 3
84
+ separator: "."
@@ -63,3 +63,22 @@ es:
63
63
  retried: reintentado
64
64
  running: Corriendo
65
65
  scheduled: Programado
66
+ number:
67
+ format:
68
+ delimiter: " "
69
+ separator: ","
70
+ human:
71
+ decimal_units:
72
+ format: "%n%u"
73
+ units:
74
+ billion: B
75
+ hundred: ''
76
+ million: M
77
+ quadrillion: q
78
+ thousand: k
79
+ trillion: T
80
+ unit: ''
81
+ format:
82
+ delimiter: " "
83
+ precision: 3
84
+ separator: ","
@@ -63,3 +63,22 @@ nl:
63
63
  retried: Opnieuw geprobeerd
64
64
  running: Rennen
65
65
  scheduled: Gepland
66
+ number:
67
+ format:
68
+ delimiter: "."
69
+ separator: ","
70
+ human:
71
+ decimal_units:
72
+ format: "%n%u"
73
+ units:
74
+ billion: B
75
+ hundred: ''
76
+ million: M
77
+ quadrillion: Q
78
+ thousand: K
79
+ trillion: T
80
+ unit: ''
81
+ format:
82
+ delimiter: "."
83
+ precision: 3
84
+ separator: ","
@@ -87,3 +87,22 @@ ru:
87
87
  retried: Повторная попытка
88
88
  running: Бег
89
89
  scheduled: по расписанию
90
+ number:
91
+ format:
92
+ delimiter: " "
93
+ separator: ","
94
+ human:
95
+ decimal_units:
96
+ format: "%n%u"
97
+ units:
98
+ billion: Б
99
+ hundred: ''
100
+ million: М
101
+ quadrillion: Q
102
+ thousand: К
103
+ trillion: Т
104
+ unit: ''
105
+ format:
106
+ delimiter: " "
107
+ precision: 3
108
+ separator: ","