solid_queue_tui 0.1.2 → 0.2.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.
@@ -4,62 +4,29 @@ module SolidQueueTui
4
4
  module Views
5
5
  class ScheduledView
6
6
  include Filterable
7
-
8
-
9
- LOAD_THRESHOLD = 10
7
+ include Confirmable
8
+ include Paginatable
9
+ include FormattingHelpers
10
10
 
11
11
  def initialize(tui)
12
12
  @tui = tui
13
- @table_state = RatatuiRuby::TableState.new(nil)
14
- @table_state.select(0)
15
- @selected_row = 0
16
- @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(jobs:)
24
- @jobs = jobs
25
- @all_loaded = jobs.size < SolidQueueTui.page_size
26
- @selected_row = @selected_row.clamp(0, [@jobs.size - 1, 0].max)
27
- @table_state.select(@selected_row)
19
+ update_items(jobs)
28
20
  end
29
21
 
30
22
  def append(jobs:)
31
- @jobs.concat(jobs)
32
- @all_loaded = 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
- @jobs.size
41
- end
42
-
43
- def reset_pagination!
44
- @jobs = []
45
- @total_count = nil
46
- @all_loaded = false
47
- @selected_row = 0
48
- @table_state.select(0)
23
+ append_items(jobs)
49
24
  end
50
25
 
51
26
  def render(frame, area)
52
- if @confirm_action
53
- confirm_area, content_area = @tui.layout_split(
54
- area,
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_table(frame, content_area)
27
+ if confirm_mode?
28
+ render_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 @confirm_action
47
+ if confirm_mode?
81
48
  handle_confirm_input(event)
82
49
  elsif filter_mode?
83
50
  handle_filter_input(event)
@@ -86,21 +53,13 @@ module SolidQueueTui
86
53
  end
87
54
  end
88
55
 
89
- def selected_item
90
- return nil if @jobs.empty? || @selected_row >= @jobs.size
91
- @jobs[@selected_row]
92
- end
93
-
94
56
  def capturing_input?
95
- filter_mode? || @confirm_action
57
+ filter_mode? || confirm_mode?
96
58
  end
97
59
 
98
60
  def bindings
99
- if @confirm_action
100
- [
101
- { key: "y", action: "Confirm" },
102
- { key: "n/Esc", action: "Cancel" }
103
- ]
61
+ if confirm_mode?
62
+ confirm_bindings
104
63
  elsif filter_mode?
105
64
  filter_bindings
106
65
  else
@@ -108,10 +67,11 @@ module SolidQueueTui
108
67
  { key: "j/k", action: "Navigate" },
109
68
  { key: "Enter", action: "Detail" },
110
69
  { key: "/", action: "Filter" },
70
+ clear_filter_binding,
111
71
  { key: "N", action: "Run Now" },
112
72
  { key: "D", action: "Discard" },
113
73
  { key: "G/g", action: "Bottom/Top" }
114
- ]
74
+ ].compact
115
75
  end
116
76
  end
117
77
 
@@ -121,10 +81,6 @@ module SolidQueueTui
121
81
 
122
82
  private
123
83
 
124
- def needs_more?
125
- !@all_loaded && @selected_row >= @jobs.size - LOAD_THRESHOLD
126
- end
127
-
128
84
  def handle_normal_input(event)
129
85
  case event
130
86
  in { type: :key, code: "j" } | { type: :key, code: "up" }
@@ -146,55 +102,37 @@ module SolidQueueTui
146
102
  in { type: :key, code: "/" }
147
103
  enter_filter_mode
148
104
  nil
149
- in { type: :key, code: "esc" }
105
+ in { type: :key, code: "c" }
150
106
  clear_filter
151
107
  else
152
108
  nil
153
109
  end
154
110
  end
155
111
 
156
- def handle_confirm_input(event)
157
- case event
158
- in { type: :key, code: "y" }
159
- action = @confirm_action
160
- @confirm_action = nil
161
- case action
162
- when :run_now
163
- item = selected_item
164
- return nil unless item
165
- Actions::DispatchScheduledJob.call(item.id)
166
- :refresh
167
- when :discard
168
- item = selected_item
169
- return nil unless item
170
- Actions::DiscardScheduledJob.call(item.id)
171
- :refresh
172
- end
173
- in { type: :key, code: "n" } | { type: :key, code: "esc" }
174
- @confirm_action = nil
175
- nil
176
- else
177
- nil
112
+ def confirm_message
113
+ case @confirm_action
114
+ when :run_now
115
+ job = selected_item
116
+ "Run job ##{job&.id} (#{job&.class_name}) now? [y/n]"
117
+ when :discard
118
+ job = selected_item
119
+ "Discard job ##{job&.id} (#{job&.class_name})? This cannot be undone. [y/n]"
178
120
  end
179
121
  end
180
122
 
181
- def move_selection(delta)
182
- return if @jobs.empty?
183
- @selected_row = (@selected_row + delta).clamp(0, @jobs.size - 1)
184
- @table_state.select(@selected_row)
185
- :load_more if needs_more?
186
- end
187
-
188
- def jump_to_top
189
- @selected_row = 0
190
- @table_state.select(0)
191
- end
192
-
193
- def jump_to_bottom
194
- return if @jobs.empty?
195
- @selected_row = @jobs.size - 1
196
- @table_state.select(@selected_row)
197
- return :load_more if needs_more?
123
+ def execute_confirm_action(action)
124
+ case action
125
+ when :run_now
126
+ item = selected_item
127
+ return nil unless item
128
+ Actions::DispatchScheduledJob.call(item.id)
129
+ :refresh
130
+ when :discard
131
+ item = selected_item
132
+ return nil unless item
133
+ Actions::DiscardScheduledJob.call(item.id)
134
+ :refresh
135
+ end
198
136
  end
199
137
 
200
138
  def render_table(frame, area)
@@ -209,7 +147,7 @@ module SolidQueueTui
209
147
  ]
210
148
 
211
149
  now = Time.now.utc
212
- rows = @jobs.map do |job|
150
+ rows = items.map do |job|
213
151
  delayed = job.scheduled_at && job.scheduled_at < now
214
152
  {
215
153
  id: job.id,
@@ -235,47 +173,6 @@ module SolidQueueTui
235
173
  table.render(frame, area, @table_state)
236
174
  end
237
175
 
238
- def render_confirm(frame, area)
239
- message = case @confirm_action
240
- when :run_now
241
- job = selected_item
242
- "Run job ##{job&.id} (#{job&.class_name}) now? [y/n]"
243
- when :discard
244
- job = selected_item
245
- "Discard job ##{job&.id} (#{job&.class_name})? This cannot be undone. [y/n]"
246
- end
247
-
248
- frame.render_widget(
249
- @tui.paragraph(
250
- text: " #{message}",
251
- style: @tui.style(fg: :yellow, modifiers: [:bold]),
252
- block: @tui.block(
253
- title: " Confirm ",
254
- title_style: @tui.style(fg: :red, modifiers: [:bold]),
255
- borders: [:all],
256
- border_type: :rounded,
257
- border_style: @tui.style(fg: :red)
258
- )
259
- ),
260
- area
261
- )
262
- end
263
-
264
- def format_time(time)
265
- return "n/a" unless time
266
- time.strftime("%Y-%m-%d %H:%M:%S")
267
- end
268
-
269
- def time_ago(time)
270
- return "n/a" unless time
271
- seconds = (Time.now.utc - time).to_i
272
- case seconds
273
- when 0..59 then "#{seconds}s ago"
274
- when 60..3599 then "#{seconds / 60}m ago"
275
- when 3600..86399 then "#{seconds / 3600}h ago"
276
- else "#{seconds / 86400}d ago"
277
- end
278
- end
279
176
  end
280
177
  end
281
178
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "solid_queue_tui/version"
4
+ require_relative "solid_queue_tui/formatting_helpers"
4
5
 
5
6
  # Data layer
6
7
  require_relative "solid_queue_tui/data/stats"
8
+ require_relative "solid_queue_tui/data/hourly_stats_query"
7
9
  require_relative "solid_queue_tui/data/jobs_query"
8
10
  require_relative "solid_queue_tui/data/queues_query"
9
11
  require_relative "solid_queue_tui/data/processes_query"
@@ -25,6 +27,8 @@ require_relative "solid_queue_tui/components/help_bar"
25
27
 
26
28
  # View concerns
27
29
  require_relative "solid_queue_tui/views/concerns/filterable"
30
+ require_relative "solid_queue_tui/views/concerns/confirmable"
31
+ require_relative "solid_queue_tui/views/concerns/paginatable"
28
32
 
29
33
  # Views
30
34
  require_relative "solid_queue_tui/views/dashboard_view"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_queue_tui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shiva Reddy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-21 00:00:00.000000000 Z
11
+ date: 2026-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ratatui_ruby
@@ -84,11 +84,13 @@ description: Real-time terminal dashboard to monitor and manage Solid Queue jobs
84
84
  Built with ratatui_ruby for native Rust rendering performance.
85
85
  email:
86
86
  executables:
87
+ - qtop
87
88
  - sqtui
88
89
  extensions: []
89
90
  extra_rdoc_files: []
90
91
  files:
91
92
  - LICENSE.txt
93
+ - exe/qtop
92
94
  - exe/sqtui
93
95
  - lib/solid_queue_tui.rb
94
96
  - lib/solid_queue_tui/actions/discard_job.rb
@@ -103,16 +105,20 @@ files:
103
105
  - lib/solid_queue_tui/components/help_bar.rb
104
106
  - lib/solid_queue_tui/components/job_table.rb
105
107
  - lib/solid_queue_tui/data/failed_query.rb
108
+ - lib/solid_queue_tui/data/hourly_stats_query.rb
106
109
  - lib/solid_queue_tui/data/jobs_query.rb
107
110
  - lib/solid_queue_tui/data/processes_query.rb
108
111
  - lib/solid_queue_tui/data/queues_query.rb
109
112
  - lib/solid_queue_tui/data/recurring_tasks_query.rb
110
113
  - lib/solid_queue_tui/data/stats.rb
111
114
  - lib/solid_queue_tui/dev_reloader.rb
115
+ - lib/solid_queue_tui/formatting_helpers.rb
112
116
  - lib/solid_queue_tui/railtie.rb
113
117
  - lib/solid_queue_tui/version.rb
114
118
  - lib/solid_queue_tui/views/blocked_view.rb
119
+ - lib/solid_queue_tui/views/concerns/confirmable.rb
115
120
  - lib/solid_queue_tui/views/concerns/filterable.rb
121
+ - lib/solid_queue_tui/views/concerns/paginatable.rb
116
122
  - lib/solid_queue_tui/views/dashboard_view.rb
117
123
  - lib/solid_queue_tui/views/failed_view.rb
118
124
  - lib/solid_queue_tui/views/finished_view.rb
@@ -135,7 +141,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
141
  requirements:
136
142
  - - ">="
137
143
  - !ruby/object:Gem::Version
138
- version: 3.2.0
144
+ version: 3.2.9
139
145
  required_rubygems_version: !ruby/object:Gem::Requirement
140
146
  requirements:
141
147
  - - ">="