solid_queue_tui 0.1.2 → 0.1.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/exe/sqtui +19 -2
- data/lib/solid_queue_tui/application.rb +36 -4
- data/lib/solid_queue_tui/components/job_table.rb +2 -3
- data/lib/solid_queue_tui/data/jobs_query.rb +31 -0
- data/lib/solid_queue_tui/data/processes_query.rb +23 -0
- data/lib/solid_queue_tui/formatting_helpers.rb +63 -0
- data/lib/solid_queue_tui/version.rb +1 -1
- data/lib/solid_queue_tui/views/blocked_view.rb +6 -75
- data/lib/solid_queue_tui/views/concerns/confirmable.rb +53 -0
- data/lib/solid_queue_tui/views/concerns/paginatable.rb +79 -0
- data/lib/solid_queue_tui/views/dashboard_view.rb +2 -4
- data/lib/solid_queue_tui/views/failed_view.rb +45 -149
- data/lib/solid_queue_tui/views/finished_view.rb +9 -77
- data/lib/solid_queue_tui/views/in_progress_view.rb +6 -70
- data/lib/solid_queue_tui/views/job_detail_view.rb +179 -31
- data/lib/solid_queue_tui/views/processes_view.rb +2 -24
- data/lib/solid_queue_tui/views/queues_view.rb +223 -87
- data/lib/solid_queue_tui/views/recurring_tasks_view.rb +22 -69
- data/lib/solid_queue_tui/views/scheduled_view.rb +36 -140
- data/lib/solid_queue_tui.rb +3 -0
- metadata +6 -3
|
@@ -4,62 +4,29 @@ module SolidQueueTui
|
|
|
4
4
|
module Views
|
|
5
5
|
class FailedView
|
|
6
6
|
include Filterable
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
include Confirmable
|
|
8
|
+
include Paginatable
|
|
9
|
+
include FormattingHelpers
|
|
10
10
|
|
|
11
11
|
def initialize(tui)
|
|
12
12
|
@tui = tui
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@selected_row = 0
|
|
16
|
-
@failed_jobs = []
|
|
17
|
-
@total_count = nil
|
|
18
|
-
@all_loaded = false
|
|
19
|
-
@confirm_action = nil
|
|
13
|
+
init_pagination
|
|
14
|
+
init_confirm
|
|
20
15
|
init_filter
|
|
21
16
|
end
|
|
22
17
|
|
|
23
18
|
def update(failed_jobs:)
|
|
24
|
-
|
|
25
|
-
@all_loaded = failed_jobs.size < SolidQueueTui.page_size
|
|
26
|
-
@selected_row = @selected_row.clamp(0, [@failed_jobs.size - 1, 0].max)
|
|
27
|
-
@table_state.select(@selected_row)
|
|
19
|
+
update_items(failed_jobs)
|
|
28
20
|
end
|
|
29
21
|
|
|
30
22
|
def append(failed_jobs:)
|
|
31
|
-
|
|
32
|
-
@all_loaded = failed_jobs.size < SolidQueueTui.page_size
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def total_count=(count)
|
|
36
|
-
@total_count = count
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def current_offset
|
|
40
|
-
@failed_jobs.size
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def reset_pagination!
|
|
44
|
-
@failed_jobs = []
|
|
45
|
-
@total_count = nil
|
|
46
|
-
@all_loaded = false
|
|
47
|
-
@selected_row = 0
|
|
48
|
-
@table_state.select(0)
|
|
23
|
+
append_items(failed_jobs)
|
|
49
24
|
end
|
|
50
25
|
|
|
51
26
|
def render(frame, area)
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
direction: :vertical,
|
|
56
|
-
constraints: [
|
|
57
|
-
@tui.constraint_length(3),
|
|
58
|
-
@tui.constraint_fill(1)
|
|
59
|
-
]
|
|
60
|
-
)
|
|
61
|
-
render_confirm(frame, confirm_area)
|
|
62
|
-
render_failed_table(frame, content_area)
|
|
27
|
+
if confirm_mode?
|
|
28
|
+
render_failed_table(frame, area)
|
|
29
|
+
render_confirm_popup(frame, area)
|
|
63
30
|
elsif filter_mode?
|
|
64
31
|
filter_area, content_area = @tui.layout_split(
|
|
65
32
|
area,
|
|
@@ -77,7 +44,7 @@ module SolidQueueTui
|
|
|
77
44
|
end
|
|
78
45
|
|
|
79
46
|
def handle_input(event)
|
|
80
|
-
if
|
|
47
|
+
if confirm_mode?
|
|
81
48
|
handle_confirm_input(event)
|
|
82
49
|
elsif filter_mode?
|
|
83
50
|
handle_filter_input(event)
|
|
@@ -86,17 +53,9 @@ module SolidQueueTui
|
|
|
86
53
|
end
|
|
87
54
|
end
|
|
88
55
|
|
|
89
|
-
def selected_item
|
|
90
|
-
return nil if @failed_jobs.empty? || @selected_row >= @failed_jobs.size
|
|
91
|
-
@failed_jobs[@selected_row]
|
|
92
|
-
end
|
|
93
|
-
|
|
94
56
|
def bindings
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
{ key: "y", action: "Confirm" },
|
|
98
|
-
{ key: "n/Esc", action: "Cancel" }
|
|
99
|
-
]
|
|
57
|
+
if confirm_mode?
|
|
58
|
+
confirm_bindings
|
|
100
59
|
elsif filter_mode?
|
|
101
60
|
filter_bindings
|
|
102
61
|
else
|
|
@@ -112,7 +71,7 @@ module SolidQueueTui
|
|
|
112
71
|
end
|
|
113
72
|
|
|
114
73
|
def capturing_input?
|
|
115
|
-
filter_mode? ||
|
|
74
|
+
filter_mode? || confirm_mode?
|
|
116
75
|
end
|
|
117
76
|
|
|
118
77
|
def breadcrumb
|
|
@@ -121,10 +80,6 @@ module SolidQueueTui
|
|
|
121
80
|
|
|
122
81
|
private
|
|
123
82
|
|
|
124
|
-
def needs_more?
|
|
125
|
-
!@all_loaded && @selected_row >= @failed_jobs.size - LOAD_THRESHOLD
|
|
126
|
-
end
|
|
127
|
-
|
|
128
83
|
def handle_normal_input(event)
|
|
129
84
|
case event
|
|
130
85
|
in { type: :key, code: "j" } | { type: :key, code: "up" }
|
|
@@ -144,7 +99,7 @@ module SolidQueueTui
|
|
|
144
99
|
@confirm_action = :discard if selected_item
|
|
145
100
|
nil
|
|
146
101
|
in { type: :key, code: "A" }
|
|
147
|
-
@confirm_action = :retry_all unless
|
|
102
|
+
@confirm_action = :retry_all unless items.empty?
|
|
148
103
|
nil
|
|
149
104
|
in { type: :key, code: "/" }
|
|
150
105
|
enter_filter_mode
|
|
@@ -156,52 +111,38 @@ module SolidQueueTui
|
|
|
156
111
|
end
|
|
157
112
|
end
|
|
158
113
|
|
|
159
|
-
def
|
|
160
|
-
case
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
item = selected_item
|
|
172
|
-
return nil unless item
|
|
173
|
-
Actions::DiscardJob.call(item.id)
|
|
174
|
-
:refresh
|
|
175
|
-
when :retry_all
|
|
176
|
-
f = filters
|
|
177
|
-
Actions::RetryJob.retry_all(filter: f[:class_name], queue: f[:queue])
|
|
178
|
-
:refresh
|
|
179
|
-
end
|
|
180
|
-
in { type: :key, code: "n" } | { type: :key, code: "esc" }
|
|
181
|
-
@confirm_action = nil
|
|
182
|
-
nil
|
|
183
|
-
else
|
|
184
|
-
nil
|
|
114
|
+
def confirm_message
|
|
115
|
+
case @confirm_action
|
|
116
|
+
when :retry
|
|
117
|
+
job = selected_item
|
|
118
|
+
"Retry job ##{job&.job_id} (#{job&.class_name})? [y/n]"
|
|
119
|
+
when :discard
|
|
120
|
+
job = selected_item
|
|
121
|
+
"Discard job ##{job&.job_id} (#{job&.class_name})? This cannot be undone. [y/n]"
|
|
122
|
+
when :retry_all
|
|
123
|
+
count = @total_count || items.size
|
|
124
|
+
label = @filters.empty? ? "failed jobs" : "filtered failed jobs"
|
|
125
|
+
"Retry ALL #{count} #{label}? [y/n]"
|
|
185
126
|
end
|
|
186
127
|
end
|
|
187
128
|
|
|
188
|
-
def
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
129
|
+
def execute_confirm_action(action)
|
|
130
|
+
case action
|
|
131
|
+
when :retry
|
|
132
|
+
item = selected_item
|
|
133
|
+
return nil unless item
|
|
134
|
+
Actions::RetryJob.call(item.id)
|
|
135
|
+
:refresh
|
|
136
|
+
when :discard
|
|
137
|
+
item = selected_item
|
|
138
|
+
return nil unless item
|
|
139
|
+
Actions::DiscardJob.call(item.id)
|
|
140
|
+
:refresh
|
|
141
|
+
when :retry_all
|
|
142
|
+
f = filters
|
|
143
|
+
Actions::RetryJob.retry_all(filter: f[:class_name], queue: f[:queue])
|
|
144
|
+
:refresh
|
|
145
|
+
end
|
|
205
146
|
end
|
|
206
147
|
|
|
207
148
|
def render_failed_table(frame, area)
|
|
@@ -214,7 +155,7 @@ module SolidQueueTui
|
|
|
214
155
|
{ key: :failed_at, label: "FAILED", width: 12 }
|
|
215
156
|
]
|
|
216
157
|
|
|
217
|
-
rows =
|
|
158
|
+
rows = items.map do |job|
|
|
218
159
|
{
|
|
219
160
|
id: job.job_id,
|
|
220
161
|
class_name: job.class_name,
|
|
@@ -238,51 +179,6 @@ module SolidQueueTui
|
|
|
238
179
|
table.render(frame, area, @table_state)
|
|
239
180
|
end
|
|
240
181
|
|
|
241
|
-
def render_confirm(frame, area)
|
|
242
|
-
message = case @confirm_action
|
|
243
|
-
when :retry
|
|
244
|
-
job = selected_item
|
|
245
|
-
"Retry job ##{job&.job_id} (#{job&.class_name})? [y/n]"
|
|
246
|
-
when :discard
|
|
247
|
-
job = selected_item
|
|
248
|
-
"Discard job ##{job&.job_id} (#{job&.class_name})? This cannot be undone. [y/n]"
|
|
249
|
-
when :retry_all
|
|
250
|
-
count = @total_count || @failed_jobs.size
|
|
251
|
-
label = @filters.empty? ? "failed jobs" : "filtered failed jobs"
|
|
252
|
-
"Retry ALL #{count} #{label}? [y/n]"
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
frame.render_widget(
|
|
256
|
-
@tui.paragraph(
|
|
257
|
-
text: " #{message}",
|
|
258
|
-
style: @tui.style(fg: :yellow, modifiers: [:bold]),
|
|
259
|
-
block: @tui.block(
|
|
260
|
-
title: " Confirm ",
|
|
261
|
-
title_style: @tui.style(fg: :red, modifiers: [:bold]),
|
|
262
|
-
borders: [:all],
|
|
263
|
-
border_type: :rounded,
|
|
264
|
-
border_style: @tui.style(fg: :red)
|
|
265
|
-
)
|
|
266
|
-
),
|
|
267
|
-
area
|
|
268
|
-
)
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def truncate(str, max)
|
|
272
|
-
return "" unless str
|
|
273
|
-
str.length > max ? "#{str[0...max - 3]}..." : str
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def time_ago(time)
|
|
277
|
-
return "n/a" unless time
|
|
278
|
-
seconds = (Time.now.utc - time).to_i
|
|
279
|
-
case seconds
|
|
280
|
-
when 0..59 then "#{seconds}s ago"
|
|
281
|
-
when 60..3599 then "#{seconds / 60}m ago"
|
|
282
|
-
when 3600..86399 then "#{seconds / 3600}h ago"
|
|
283
|
-
else "#{seconds / 86400}d ago"
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
182
|
end
|
|
287
183
|
end
|
|
288
184
|
end
|
|
@@ -4,47 +4,21 @@ module SolidQueueTui
|
|
|
4
4
|
module Views
|
|
5
5
|
class FinishedView
|
|
6
6
|
include Filterable
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
LOAD_THRESHOLD = 10
|
|
7
|
+
include Paginatable
|
|
8
|
+
include FormattingHelpers
|
|
10
9
|
|
|
11
10
|
def initialize(tui)
|
|
12
11
|
@tui = tui
|
|
13
|
-
|
|
14
|
-
@table_state.select(0)
|
|
15
|
-
@selected_row = 0
|
|
16
|
-
@jobs = []
|
|
17
|
-
@total_count = nil
|
|
18
|
-
@all_loaded = false
|
|
12
|
+
init_pagination
|
|
19
13
|
init_filter
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
def update(jobs:)
|
|
23
|
-
|
|
24
|
-
@all_loaded = jobs.size < SolidQueueTui.page_size
|
|
25
|
-
@selected_row = @selected_row.clamp(0, [@jobs.size - 1, 0].max)
|
|
26
|
-
@table_state.select(@selected_row)
|
|
17
|
+
update_items(jobs)
|
|
27
18
|
end
|
|
28
19
|
|
|
29
20
|
def append(jobs:)
|
|
30
|
-
|
|
31
|
-
@all_loaded = jobs.size < SolidQueueTui.page_size
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def total_count=(count)
|
|
35
|
-
@total_count = count
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def current_offset
|
|
39
|
-
@jobs.size
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def reset_pagination!
|
|
43
|
-
@jobs = []
|
|
44
|
-
@total_count = nil
|
|
45
|
-
@all_loaded = false
|
|
46
|
-
@selected_row = 0
|
|
47
|
-
@table_state.select(0)
|
|
21
|
+
append_items(jobs)
|
|
48
22
|
end
|
|
49
23
|
|
|
50
24
|
def render(frame, area)
|
|
@@ -72,11 +46,6 @@ module SolidQueueTui
|
|
|
72
46
|
end
|
|
73
47
|
end
|
|
74
48
|
|
|
75
|
-
def selected_item
|
|
76
|
-
return nil if @jobs.empty? || @selected_row >= @jobs.size
|
|
77
|
-
@jobs[@selected_row]
|
|
78
|
-
end
|
|
79
|
-
|
|
80
49
|
def bindings
|
|
81
50
|
if filter_mode?
|
|
82
51
|
filter_bindings
|
|
@@ -101,10 +70,6 @@ module SolidQueueTui
|
|
|
101
70
|
|
|
102
71
|
private
|
|
103
72
|
|
|
104
|
-
def needs_more?
|
|
105
|
-
!@all_loaded && @selected_row >= @jobs.size - LOAD_THRESHOLD
|
|
106
|
-
end
|
|
107
|
-
|
|
108
73
|
def handle_normal_input(event)
|
|
109
74
|
case event
|
|
110
75
|
in { type: :key, code: "j" } | { type: :key, code: "up" }
|
|
@@ -127,25 +92,6 @@ module SolidQueueTui
|
|
|
127
92
|
end
|
|
128
93
|
end
|
|
129
94
|
|
|
130
|
-
def move_selection(delta)
|
|
131
|
-
return if @jobs.empty?
|
|
132
|
-
@selected_row = (@selected_row + delta).clamp(0, @jobs.size - 1)
|
|
133
|
-
@table_state.select(@selected_row)
|
|
134
|
-
:load_more if needs_more?
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def jump_to_top
|
|
138
|
-
@selected_row = 0
|
|
139
|
-
@table_state.select(0)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def jump_to_bottom
|
|
143
|
-
return if @jobs.empty?
|
|
144
|
-
@selected_row = @jobs.size - 1
|
|
145
|
-
@table_state.select(@selected_row)
|
|
146
|
-
return :load_more if needs_more?
|
|
147
|
-
end
|
|
148
|
-
|
|
149
95
|
def render_table(frame, area)
|
|
150
96
|
columns = [
|
|
151
97
|
{ key: :id, label: "ID", width: 8 },
|
|
@@ -156,14 +102,14 @@ module SolidQueueTui
|
|
|
156
102
|
{ key: :duration, label: "DURATION", width: 12 }
|
|
157
103
|
]
|
|
158
104
|
|
|
159
|
-
rows =
|
|
105
|
+
rows = items.map do |job|
|
|
160
106
|
{
|
|
161
107
|
id: job.id,
|
|
162
108
|
queue_name: job.queue_name,
|
|
163
109
|
class_name: job.class_name,
|
|
164
110
|
priority: job.priority,
|
|
165
111
|
finished_at: format_time(job.finished_at),
|
|
166
|
-
duration:
|
|
112
|
+
duration: job_duration(job.created_at, job.finished_at)
|
|
167
113
|
}
|
|
168
114
|
end
|
|
169
115
|
|
|
@@ -180,23 +126,9 @@ module SolidQueueTui
|
|
|
180
126
|
table.render(frame, area, @table_state)
|
|
181
127
|
end
|
|
182
128
|
|
|
183
|
-
def
|
|
184
|
-
return "n/a" unless time
|
|
185
|
-
time.strftime("%Y-%m-%d %H:%M:%S")
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def format_duration(created, finished)
|
|
129
|
+
def job_duration(created, finished)
|
|
189
130
|
return "n/a" unless created && finished
|
|
190
|
-
|
|
191
|
-
if seconds < 1
|
|
192
|
-
"<1s"
|
|
193
|
-
elsif seconds < 60
|
|
194
|
-
"#{seconds}s"
|
|
195
|
-
elsif seconds < 3600
|
|
196
|
-
"#{seconds / 60}m #{seconds % 60}s"
|
|
197
|
-
else
|
|
198
|
-
"#{seconds / 3600}h #{(seconds % 3600) / 60}m"
|
|
199
|
-
end
|
|
131
|
+
format_duration((finished - created).to_i)
|
|
200
132
|
end
|
|
201
133
|
end
|
|
202
134
|
end
|
|
@@ -4,47 +4,21 @@ module SolidQueueTui
|
|
|
4
4
|
module Views
|
|
5
5
|
class InProgressView
|
|
6
6
|
include Filterable
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
LOAD_THRESHOLD = 10
|
|
7
|
+
include Paginatable
|
|
8
|
+
include FormattingHelpers
|
|
10
9
|
|
|
11
10
|
def initialize(tui)
|
|
12
11
|
@tui = tui
|
|
13
|
-
|
|
14
|
-
@table_state.select(0)
|
|
15
|
-
@selected_row = 0
|
|
16
|
-
@jobs = []
|
|
17
|
-
@total_count = nil
|
|
18
|
-
@all_loaded = false
|
|
12
|
+
init_pagination
|
|
19
13
|
init_filter
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
def update(jobs:)
|
|
23
|
-
|
|
24
|
-
@all_loaded = jobs.size < SolidQueueTui.page_size
|
|
25
|
-
@selected_row = @selected_row.clamp(0, [@jobs.size - 1, 0].max)
|
|
26
|
-
@table_state.select(@selected_row)
|
|
17
|
+
update_items(jobs)
|
|
27
18
|
end
|
|
28
19
|
|
|
29
20
|
def append(jobs:)
|
|
30
|
-
|
|
31
|
-
@all_loaded = jobs.size < SolidQueueTui.page_size
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def total_count=(count)
|
|
35
|
-
@total_count = count
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def current_offset
|
|
39
|
-
@jobs.size
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def reset_pagination!
|
|
43
|
-
@jobs = []
|
|
44
|
-
@total_count = nil
|
|
45
|
-
@all_loaded = false
|
|
46
|
-
@selected_row = 0
|
|
47
|
-
@table_state.select(0)
|
|
21
|
+
append_items(jobs)
|
|
48
22
|
end
|
|
49
23
|
|
|
50
24
|
def render(frame, area)
|
|
@@ -72,11 +46,6 @@ module SolidQueueTui
|
|
|
72
46
|
end
|
|
73
47
|
end
|
|
74
48
|
|
|
75
|
-
def selected_item
|
|
76
|
-
return nil if @jobs.empty? || @selected_row >= @jobs.size
|
|
77
|
-
@jobs[@selected_row]
|
|
78
|
-
end
|
|
79
|
-
|
|
80
49
|
def bindings
|
|
81
50
|
if filter_mode?
|
|
82
51
|
filter_bindings
|
|
@@ -100,10 +69,6 @@ module SolidQueueTui
|
|
|
100
69
|
|
|
101
70
|
private
|
|
102
71
|
|
|
103
|
-
def needs_more?
|
|
104
|
-
!@all_loaded && @selected_row >= @jobs.size - LOAD_THRESHOLD
|
|
105
|
-
end
|
|
106
|
-
|
|
107
72
|
def handle_normal_input(event)
|
|
108
73
|
case event
|
|
109
74
|
in { type: :key, code: "j" } | { type: :key, code: "up" }
|
|
@@ -126,25 +91,6 @@ module SolidQueueTui
|
|
|
126
91
|
end
|
|
127
92
|
end
|
|
128
93
|
|
|
129
|
-
def move_selection(delta)
|
|
130
|
-
return if @jobs.empty?
|
|
131
|
-
@selected_row = (@selected_row + delta).clamp(0, @jobs.size - 1)
|
|
132
|
-
@table_state.select(@selected_row)
|
|
133
|
-
:load_more if needs_more?
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def jump_to_top
|
|
137
|
-
@selected_row = 0
|
|
138
|
-
@table_state.select(0)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def jump_to_bottom
|
|
142
|
-
return if @jobs.empty?
|
|
143
|
-
@selected_row = @jobs.size - 1
|
|
144
|
-
@table_state.select(@selected_row)
|
|
145
|
-
return :load_more if needs_more?
|
|
146
|
-
end
|
|
147
|
-
|
|
148
94
|
def render_table(frame, area)
|
|
149
95
|
columns = [
|
|
150
96
|
{ key: :id, label: "ID", width: 8 },
|
|
@@ -155,7 +101,7 @@ module SolidQueueTui
|
|
|
155
101
|
{ key: :started_at, label: "STARTED", width: 12 }
|
|
156
102
|
]
|
|
157
103
|
|
|
158
|
-
rows =
|
|
104
|
+
rows = items.map do |job|
|
|
159
105
|
{
|
|
160
106
|
id: job.id,
|
|
161
107
|
queue_name: job.queue_name,
|
|
@@ -179,16 +125,6 @@ module SolidQueueTui
|
|
|
179
125
|
table.render(frame, area, @table_state)
|
|
180
126
|
end
|
|
181
127
|
|
|
182
|
-
def time_ago(time)
|
|
183
|
-
return "n/a" unless time
|
|
184
|
-
seconds = (Time.now.utc - time).to_i
|
|
185
|
-
case seconds
|
|
186
|
-
when 0..59 then "#{seconds}s ago"
|
|
187
|
-
when 60..3599 then "#{seconds / 60}m ago"
|
|
188
|
-
when 3600..86399 then "#{seconds / 3600}h ago"
|
|
189
|
-
else "#{seconds / 86400}d ago"
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
128
|
end
|
|
193
129
|
end
|
|
194
130
|
end
|