solid_queue_monitor 1.0.0 → 1.1.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.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/app/controllers/solid_queue_monitor/base_controller.rb +34 -2
  4. data/app/controllers/solid_queue_monitor/failed_jobs_controller.rb +7 -3
  5. data/app/controllers/solid_queue_monitor/in_progress_jobs_controller.rb +7 -3
  6. data/app/controllers/solid_queue_monitor/overview_controller.rb +7 -3
  7. data/app/controllers/solid_queue_monitor/queues_controller.rb +21 -8
  8. data/app/controllers/solid_queue_monitor/ready_jobs_controller.rb +7 -3
  9. data/app/controllers/solid_queue_monitor/recurring_jobs_controller.rb +7 -3
  10. data/app/controllers/solid_queue_monitor/scheduled_jobs_controller.rb +7 -3
  11. data/app/controllers/solid_queue_monitor/search_controller.rb +12 -0
  12. data/app/controllers/solid_queue_monitor/workers_controller.rb +7 -4
  13. data/app/presenters/solid_queue_monitor/base_presenter.rb +47 -5
  14. data/app/presenters/solid_queue_monitor/failed_jobs_presenter.rb +6 -6
  15. data/app/presenters/solid_queue_monitor/in_progress_jobs_presenter.rb +5 -4
  16. data/app/presenters/solid_queue_monitor/jobs_presenter.rb +5 -4
  17. data/app/presenters/solid_queue_monitor/queue_details_presenter.rb +4 -3
  18. data/app/presenters/solid_queue_monitor/queues_presenter.rb +4 -3
  19. data/app/presenters/solid_queue_monitor/ready_jobs_presenter.rb +6 -5
  20. data/app/presenters/solid_queue_monitor/recurring_jobs_presenter.rb +6 -5
  21. data/app/presenters/solid_queue_monitor/scheduled_jobs_presenter.rb +5 -4
  22. data/app/presenters/solid_queue_monitor/search_results_presenter.rb +190 -0
  23. data/app/presenters/solid_queue_monitor/workers_presenter.rb +4 -3
  24. data/app/services/solid_queue_monitor/html_generator.rb +23 -2
  25. data/app/services/solid_queue_monitor/search_service.rb +126 -0
  26. data/app/services/solid_queue_monitor/stylesheet_generator.rb +614 -0
  27. data/config/routes.rb +1 -0
  28. data/lib/solid_queue_monitor/version.rb +1 -1
  29. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80a07917e201c33bfb207f22490ca2a3afdeb22a8c842b1a33f3c187afc4f28e
4
- data.tar.gz: d773d2950d4be0f2b3852512a0bfd2e450206d5a6562eef4fa926cff7e7b32c5
3
+ metadata.gz: 1014e5b1b9afceff146efc3a81849dd12866578198b8172452d9b6edf42d7786
4
+ data.tar.gz: 0b2c11f5ba47a7e977c93cdb7a048c91d092b9ea97d72af27e908f6f24387fbf
5
5
  SHA512:
6
- metadata.gz: fedc69f3858f7b5834ac3c0cbad61693fd1428800f3ff5a6d9be0d74473adc2695105594c2633168e42f328ec6f2298d15ea81e5e3dbf811984ce00c54a360b1
7
- data.tar.gz: 41095950dce1063081f219558f8297e58c0346ffe034d36c991d51433697165465756e1468ebbcab25cff48b6337f65908f5968eea64fc5fc1714877b1f76354
6
+ metadata.gz: 58bf74bb26fbb518d58e555d1a22695d3175b0ea683529685b4cec6322091722fd7a8eb912bb0fbbfa0fce391663777fc69cde137bf4a4cb0fb1e1cf9d16bbf2
7
+ data.tar.gz: 59be98bcc8ee044ac0eac816cab397534c79da53cb98cfb670da1e0747552425f33eaf6dce51e2f906c44f9053b4097a8a79e3f2d6fe30534ddbad6e7f3d3d70
data/README.md CHANGED
@@ -35,6 +35,8 @@ A lightweight, zero-dependency web interface for monitoring Solid Queue backgrou
35
35
  - **Failed Jobs**: Track and debug failed jobs, with the ability to retry or discard them
36
36
  - **Queue Management**: View and filter jobs by queue with pause/resume controls
37
37
  - **Pause/Resume Queues**: Temporarily stop processing jobs on specific queues for incident response
38
+ - **Global Search**: Search across all job types by class name, queue, arguments, job ID, and error messages
39
+ - **Sortable Columns**: Click column headers to sort job tables by any column with ascending/descending toggle
38
40
  - **Advanced Job Filtering**: Filter jobs by class name, queue, status, and job arguments
39
41
  - **Quick Actions**: Retry or discard failed jobs, execute or reject scheduled jobs directly from any view
40
42
  - **Performance Optimized**: Designed for high-volume applications with smart pagination
@@ -70,7 +72,7 @@ A lightweight, zero-dependency web interface for monitoring Solid Queue backgrou
70
72
  Add this line to your application's Gemfile:
71
73
 
72
74
  ```ruby
73
- gem 'solid_queue_monitor', '~> 1.0'
75
+ gem 'solid_queue_monitor', '~> 1.1'
74
76
  ```
75
77
 
76
78
  Then execute:
@@ -6,7 +6,7 @@ module SolidQueueMonitor
6
6
  PaginationService.new(relation, current_page, per_page).paginate
7
7
  end
8
8
 
9
- def render_page(title, content)
9
+ def render_page(title, content, search_query: nil)
10
10
  # Get flash message from instance variable (set by set_flash_message) or session
11
11
  message = @flash_message
12
12
  message_type = @flash_type
@@ -27,7 +27,8 @@ module SolidQueueMonitor
27
27
  title: title,
28
28
  content: content,
29
29
  message: message,
30
- message_type: message_type
30
+ message_type: message_type,
31
+ search_query: search_query
31
32
  ).generate
32
33
 
33
34
  render html: html.html_safe
@@ -201,5 +202,36 @@ module SolidQueueMonitor
201
202
  status: params[:status]
202
203
  }
203
204
  end
205
+
206
+ def sort_params
207
+ {
208
+ sort_by: params[:sort_by],
209
+ sort_direction: params[:sort_direction]
210
+ }
211
+ end
212
+
213
+ def apply_sorting(relation, allowed_columns, default_column, default_direction = :desc)
214
+ column = sort_params[:sort_by]
215
+ direction = sort_params[:sort_direction]
216
+ column = default_column unless allowed_columns.include?(column)
217
+ direction = %w[asc desc].include?(direction) ? direction.to_sym : default_direction
218
+ relation.order(column => direction)
219
+ end
220
+
221
+ def apply_execution_sorting(relation, allowed_columns, default_column, default_direction = :desc)
222
+ column = sort_params[:sort_by]
223
+ direction = sort_params[:sort_direction]
224
+ column = default_column unless allowed_columns.include?(column)
225
+ direction = %w[asc desc].include?(direction) ? direction.to_sym : default_direction
226
+
227
+ # Columns that exist on the jobs table, not on execution tables
228
+ job_table_columns = %w[class_name queue_name]
229
+
230
+ if job_table_columns.include?(column)
231
+ relation.joins(:job).order("solid_queue_jobs.#{column}" => direction)
232
+ else
233
+ relation.order(column => direction)
234
+ end
235
+ end
204
236
  end
205
237
  end
@@ -2,14 +2,18 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class FailedJobsController < BaseController
5
+ SORTABLE_COLUMNS = %w[class_name queue_name created_at].freeze
6
+
5
7
  def index
6
- base_query = SolidQueue::FailedExecution.includes(:job).order(created_at: :desc)
7
- @failed_jobs = paginate(filter_failed_jobs(base_query))
8
+ base_query = SolidQueue::FailedExecution.includes(:job)
9
+ sorted_query = apply_execution_sorting(filter_failed_jobs(base_query), SORTABLE_COLUMNS, 'created_at', :desc)
10
+ @failed_jobs = paginate(sorted_query)
8
11
 
9
12
  render_page('Failed Jobs', SolidQueueMonitor::FailedJobsPresenter.new(@failed_jobs[:records],
10
13
  current_page: @failed_jobs[:current_page],
11
14
  total_pages: @failed_jobs[:total_pages],
12
- filters: filter_params).render)
15
+ filters: filter_params,
16
+ sort: sort_params).render)
13
17
  end
14
18
 
15
19
  def retry
@@ -2,14 +2,18 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class InProgressJobsController < BaseController
5
+ SORTABLE_COLUMNS = %w[class_name queue_name created_at].freeze
6
+
5
7
  def index
6
- base_query = SolidQueue::ClaimedExecution.includes(:job).order(created_at: :desc)
7
- @in_progress_jobs = paginate(filter_in_progress_jobs(base_query))
8
+ base_query = SolidQueue::ClaimedExecution.includes(:job)
9
+ sorted_query = apply_execution_sorting(filter_in_progress_jobs(base_query), SORTABLE_COLUMNS, 'created_at', :desc)
10
+ @in_progress_jobs = paginate(sorted_query)
8
11
 
9
12
  render_page('In Progress Jobs', SolidQueueMonitor::InProgressJobsPresenter.new(@in_progress_jobs[:records],
10
13
  current_page: @in_progress_jobs[:current_page],
11
14
  total_pages: @in_progress_jobs[:total_pages],
12
- filters: filter_params).render)
15
+ filters: filter_params,
16
+ sort: sort_params).render)
13
17
  end
14
18
 
15
19
  private
@@ -2,12 +2,15 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class OverviewController < BaseController
5
+ SORTABLE_COLUMNS = %w[class_name queue_name created_at].freeze
6
+
5
7
  def index
6
8
  @stats = SolidQueueMonitor::StatsCalculator.calculate
7
9
  @chart_data = SolidQueueMonitor::ChartDataService.new(time_range: time_range_param).calculate
8
10
 
9
- recent_jobs_query = SolidQueue::Job.order(created_at: :desc).limit(100)
10
- @recent_jobs = paginate(filter_jobs(recent_jobs_query))
11
+ recent_jobs_query = SolidQueue::Job.limit(100)
12
+ sorted_query = apply_sorting(filter_jobs(recent_jobs_query), SORTABLE_COLUMNS, 'created_at', :desc)
13
+ @recent_jobs = paginate(sorted_query)
11
14
 
12
15
  preload_job_statuses(@recent_jobs[:records])
13
16
 
@@ -31,7 +34,8 @@ module SolidQueueMonitor
31
34
  SolidQueueMonitor::JobsPresenter.new(@recent_jobs[:records],
32
35
  current_page: @recent_jobs[:current_page],
33
36
  total_pages: @recent_jobs[:total_pages],
34
- filters: filter_params).render
37
+ filters: filter_params,
38
+ sort: sort_params).render
35
39
  end
36
40
  end
37
41
  end
@@ -2,13 +2,16 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class QueuesController < BaseController
5
+ SORTABLE_COLUMNS = %w[queue_name job_count].freeze
6
+ QUEUE_DETAILS_SORTABLE_COLUMNS = %w[class_name created_at].freeze
7
+
5
8
  def index
6
- @queues = SolidQueue::Job.group(:queue_name)
7
- .select('queue_name, COUNT(*) as job_count')
8
- .order('job_count DESC')
9
+ base_query = SolidQueue::Job.group(:queue_name)
10
+ .select('queue_name, COUNT(*) as job_count')
11
+ @queues = apply_queue_sorting(base_query)
9
12
  @paused_queues = QueuePauseService.paused_queues
10
13
 
11
- render_page('Queues', SolidQueueMonitor::QueuesPresenter.new(@queues, @paused_queues).render)
14
+ render_page('Queues', SolidQueueMonitor::QueuesPresenter.new(@queues, @paused_queues, sort: sort_params).render)
12
15
  end
13
16
 
14
17
  def show
@@ -16,9 +19,9 @@ module SolidQueueMonitor
16
19
  @paused = QueuePauseService.paused_queues.include?(@queue_name)
17
20
 
18
21
  # Get all jobs for this queue with filtering and pagination
19
- base_query = SolidQueue::Job.where(queue_name: @queue_name).order(created_at: :desc)
20
- filtered_query = filter_queue_jobs(base_query)
21
- @jobs = paginate(filtered_query)
22
+ base_query = SolidQueue::Job.where(queue_name: @queue_name)
23
+ sorted_query = apply_sorting(filter_queue_jobs(base_query), QUEUE_DETAILS_SORTABLE_COLUMNS, 'created_at', :desc)
24
+ @jobs = paginate(sorted_query)
22
25
  preload_job_statuses(@jobs[:records])
23
26
 
24
27
  @counts = calculate_queue_counts(@queue_name)
@@ -31,7 +34,8 @@ module SolidQueueMonitor
31
34
  counts: @counts,
32
35
  current_page: @jobs[:current_page],
33
36
  total_pages: @jobs[:total_pages],
34
- filters: queue_filter_params
37
+ filters: queue_filter_params,
38
+ sort: sort_params
35
39
  ).render)
36
40
  end
37
41
 
@@ -97,5 +101,14 @@ module SolidQueueMonitor
97
101
  status: params[:status]
98
102
  }
99
103
  end
104
+
105
+ def apply_queue_sorting(relation)
106
+ column = sort_params[:sort_by]
107
+ direction = sort_params[:sort_direction]
108
+ column = 'job_count' unless SORTABLE_COLUMNS.include?(column)
109
+ direction = 'desc' unless %w[asc desc].include?(direction)
110
+
111
+ relation.order("#{column} #{direction}")
112
+ end
100
113
  end
101
114
  end
@@ -2,14 +2,18 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class ReadyJobsController < BaseController
5
+ SORTABLE_COLUMNS = %w[class_name queue_name priority created_at].freeze
6
+
5
7
  def index
6
- base_query = SolidQueue::ReadyExecution.includes(:job).order(created_at: :desc)
7
- @ready_jobs = paginate(filter_ready_jobs(base_query))
8
+ base_query = SolidQueue::ReadyExecution.includes(:job)
9
+ sorted_query = apply_execution_sorting(filter_ready_jobs(base_query), SORTABLE_COLUMNS, 'created_at', :desc)
10
+ @ready_jobs = paginate(sorted_query)
8
11
 
9
12
  render_page('Ready Jobs', SolidQueueMonitor::ReadyJobsPresenter.new(@ready_jobs[:records],
10
13
  current_page: @ready_jobs[:current_page],
11
14
  total_pages: @ready_jobs[:total_pages],
12
- filters: filter_params).render)
15
+ filters: filter_params,
16
+ sort: sort_params).render)
13
17
  end
14
18
  end
15
19
  end
@@ -2,14 +2,18 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class RecurringJobsController < BaseController
5
+ SORTABLE_COLUMNS = %w[key class_name queue_name priority].freeze
6
+
5
7
  def index
6
- base_query = filter_recurring_jobs(SolidQueue::RecurringTask.order(:key))
7
- @recurring_jobs = paginate(base_query)
8
+ base_query = filter_recurring_jobs(SolidQueue::RecurringTask.all)
9
+ sorted_query = apply_sorting(base_query, SORTABLE_COLUMNS, 'key', :asc)
10
+ @recurring_jobs = paginate(sorted_query)
8
11
 
9
12
  render_page('Recurring Jobs', SolidQueueMonitor::RecurringJobsPresenter.new(@recurring_jobs[:records],
10
13
  current_page: @recurring_jobs[:current_page],
11
14
  total_pages: @recurring_jobs[:total_pages],
12
- filters: filter_params).render)
15
+ filters: filter_params,
16
+ sort: sort_params).render)
13
17
  end
14
18
  end
15
19
  end
@@ -2,14 +2,18 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class ScheduledJobsController < BaseController
5
+ SORTABLE_COLUMNS = %w[class_name queue_name scheduled_at].freeze
6
+
5
7
  def index
6
- base_query = SolidQueue::ScheduledExecution.includes(:job).order(scheduled_at: :asc)
7
- @scheduled_jobs = paginate(filter_scheduled_jobs(base_query))
8
+ base_query = SolidQueue::ScheduledExecution.includes(:job)
9
+ sorted_query = apply_execution_sorting(filter_scheduled_jobs(base_query), SORTABLE_COLUMNS, 'scheduled_at', :asc)
10
+ @scheduled_jobs = paginate(sorted_query)
8
11
 
9
12
  render_page('Scheduled Jobs', SolidQueueMonitor::ScheduledJobsPresenter.new(@scheduled_jobs[:records],
10
13
  current_page: @scheduled_jobs[:current_page],
11
14
  total_pages: @scheduled_jobs[:total_pages],
12
- filters: filter_params).render)
15
+ filters: filter_params,
16
+ sort: sort_params).render)
13
17
  end
14
18
 
15
19
  def create
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidQueueMonitor
4
+ class SearchController < BaseController
5
+ def index
6
+ query = params[:q]
7
+ results = SearchService.new(query).search
8
+
9
+ render_page('Search', SearchResultsPresenter.new(query, results).render, search_query: query)
10
+ end
11
+ end
12
+ end
@@ -2,16 +2,19 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class WorkersController < BaseController
5
+ SORTABLE_COLUMNS = %w[hostname last_heartbeat_at].freeze
6
+
5
7
  def index
6
- base_query = SolidQueue::Process.order(created_at: :desc)
7
- filtered_query = filter_workers(base_query)
8
- @processes = paginate(filtered_query)
8
+ base_query = SolidQueue::Process.all
9
+ sorted_query = apply_sorting(filter_workers(base_query), SORTABLE_COLUMNS, 'last_heartbeat_at', :desc)
10
+ @processes = paginate(sorted_query)
9
11
 
10
12
  render_page('Workers', SolidQueueMonitor::WorkersPresenter.new(
11
13
  @processes[:records],
12
14
  current_page: @processes[:current_page],
13
15
  total_pages: @processes[:total_pages],
14
- filters: worker_filter_params
16
+ filters: worker_filter_params,
17
+ sort: sort_params
15
18
  ).render)
16
19
  end
17
20
 
@@ -118,6 +118,34 @@ module SolidQueueMonitor
118
118
  "<a href=\"#{queue_details_path(queue_name: queue_name)}\" class=\"#{classes}\">#{queue_name}</a>"
119
119
  end
120
120
 
121
+ def sortable_header(column, label)
122
+ return "<th>#{label}</th>" unless @sort
123
+
124
+ column_str = column.to_s
125
+ is_active = @sort[:sort_by] == column_str
126
+ next_direction = is_active && @sort[:sort_direction] == 'asc' ? 'desc' : 'asc'
127
+ arrow = sort_arrow(is_active)
128
+ css_class = is_active ? 'sortable-header active' : 'sortable-header'
129
+
130
+ "<th><a href=\"?sort_by=#{column}&sort_direction=#{next_direction}#{filter_query_string}\" class=\"#{css_class}\">#{label}#{arrow}</a></th>"
131
+ end
132
+
133
+ def sort_arrow(is_active)
134
+ return ' &udarr;' unless is_active
135
+
136
+ @sort[:sort_direction] == 'asc' ? ' &uarr;' : ' &darr;'
137
+ end
138
+
139
+ def filter_query_string
140
+ params = []
141
+ params << "class_name=#{@filters[:class_name]}" if @filters && @filters[:class_name].present?
142
+ params << "queue_name=#{@filters[:queue_name]}" if @filters && @filters[:queue_name].present?
143
+ params << "arguments=#{@filters[:arguments]}" if @filters && @filters[:arguments].present?
144
+ params << "status=#{@filters[:status]}" if @filters && @filters[:status].present?
145
+
146
+ params.empty? ? '' : "&#{params.join('&')}"
147
+ end
148
+
121
149
  def request_path
122
150
  if defined?(controller) && controller.respond_to?(:request)
123
151
  controller.request.path
@@ -138,14 +166,28 @@ module SolidQueueMonitor
138
166
  private
139
167
 
140
168
  def query_params
141
- params = []
142
- params << "class_name=#{@filters[:class_name]}" if @filters && @filters[:class_name].present?
143
- params << "queue_name=#{@filters[:queue_name]}" if @filters && @filters[:queue_name].present?
144
- params << "status=#{@filters[:status]}" if @filters && @filters[:status].present?
145
-
169
+ params = build_filter_params + build_sort_params
146
170
  params.empty? ? '' : "&#{params.join('&')}"
147
171
  end
148
172
 
173
+ def build_filter_params
174
+ return [] unless @filters
175
+
176
+ filter_keys = %i[class_name queue_name status]
177
+ filter_keys.filter_map do |key|
178
+ "#{key}=#{@filters[key]}" if @filters[key].present?
179
+ end
180
+ end
181
+
182
+ def build_sort_params
183
+ return [] unless @sort
184
+
185
+ sort_keys = %i[sort_by sort_direction]
186
+ sort_keys.filter_map do |key|
187
+ "#{key}=#{@sort[key]}" if @sort[key].present?
188
+ end
189
+ end
190
+
149
191
  def full_path(route_name, *args)
150
192
  SolidQueueMonitor::Engine.routes.url_helpers.send(route_name, *args)
151
193
  rescue NoMethodError
@@ -5,11 +5,12 @@ module SolidQueueMonitor
5
5
  include Rails.application.routes.url_helpers
6
6
  include SolidQueueMonitor::Engine.routes.url_helpers
7
7
 
8
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
8
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
9
9
  @jobs = jobs
10
10
  @current_page = current_page
11
11
  @total_pages = total_pages
12
12
  @filters = filters
13
+ @sort = sort
13
14
  end
14
15
 
15
16
  def render
@@ -60,10 +61,11 @@ module SolidQueueMonitor
60
61
  <thead>
61
62
  <tr>
62
63
  <th><input type="checkbox" id="select-all" class="select-all-checkbox"></th>
63
- <th>Job</th>
64
- <th>Queue</th>
64
+ #{sortable_header('class_name', 'Job')}
65
+ #{sortable_header('queue_name', 'Queue')}
65
66
  <th>Error</th>
66
67
  <th>Arguments</th>
68
+ #{sortable_header('created_at', 'Failed At')}
67
69
  <th>Actions</th>
68
70
  </tr>
69
71
  </thead>
@@ -261,11 +263,9 @@ module SolidQueueMonitor
261
263
  </td>
262
264
  <td>
263
265
  <div class="error-message">#{error[:message].to_s.truncate(100)}</div>
264
- <div class="job-meta">
265
- <span class="job-timestamp">Failed at: #{format_datetime(failed_execution.created_at)}</span>
266
- </div>
267
266
  </td>
268
267
  <td>#{format_arguments(job.arguments)}</td>
268
+ <td>#{format_datetime(failed_execution.created_at)}</td>
269
269
  <td class="actions-cell">
270
270
  <div class="job-actions">
271
271
  <a href="javascript:void(0)"#{' '}
@@ -4,11 +4,12 @@ module SolidQueueMonitor
4
4
  class InProgressJobsPresenter < BasePresenter
5
5
  include SolidQueueMonitor::Engine.routes.url_helpers
6
6
 
7
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
7
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
8
8
  @jobs = jobs
9
9
  @current_page = current_page
10
10
  @total_pages = total_pages
11
11
  @filters = filters
12
+ @sort = sort
12
13
  end
13
14
 
14
15
  def render
@@ -47,10 +48,10 @@ module SolidQueueMonitor
47
48
  <table>
48
49
  <thead>
49
50
  <tr>
50
- <th>Job</th>
51
- <th>Queue</th>
51
+ #{sortable_header('class_name', 'Job')}
52
+ #{sortable_header('queue_name', 'Queue')}
52
53
  <th>Arguments</th>
53
- <th>Started At</th>
54
+ #{sortable_header('created_at', 'Started At')}
54
55
  <th>Process ID</th>
55
56
  </tr>
56
57
  </thead>
@@ -5,11 +5,12 @@ module SolidQueueMonitor
5
5
  include Rails.application.routes.url_helpers
6
6
  include SolidQueueMonitor::Engine.routes.url_helpers
7
7
 
8
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
8
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
9
9
  @jobs = jobs
10
10
  @current_page = current_page
11
11
  @total_pages = total_pages
12
12
  @filters = filters
13
+ @sort = sort
13
14
  end
14
15
 
15
16
  def render
@@ -73,11 +74,11 @@ module SolidQueueMonitor
73
74
  <thead>
74
75
  <tr>
75
76
  <th>ID</th>
76
- <th>Job</th>
77
- <th>Queue</th>
77
+ #{sortable_header('class_name', 'Job')}
78
+ #{sortable_header('queue_name', 'Queue')}
78
79
  <th>Arguments</th>
79
80
  <th>Status</th>
80
- <th>Created At</th>
81
+ #{sortable_header('created_at', 'Created At')}
81
82
  <th>Actions</th>
82
83
  </tr>
83
84
  </thead>
@@ -2,7 +2,7 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class QueueDetailsPresenter < BasePresenter
5
- def initialize(queue_name:, paused:, jobs:, counts:, current_page: 1, total_pages: 1, filters: {})
5
+ def initialize(queue_name:, paused:, jobs:, counts:, current_page: 1, total_pages: 1, filters: {}, sort: {})
6
6
  @queue_name = queue_name
7
7
  @paused = paused
8
8
  @jobs = jobs
@@ -10,6 +10,7 @@ module SolidQueueMonitor
10
10
  @current_page = current_page
11
11
  @total_pages = total_pages
12
12
  @filters = filters
13
+ @sort = sort
13
14
  end
14
15
 
15
16
  def render
@@ -129,10 +130,10 @@ module SolidQueueMonitor
129
130
  <thead>
130
131
  <tr>
131
132
  <th>ID</th>
132
- <th>Job</th>
133
+ #{sortable_header('class_name', 'Job')}
133
134
  <th>Arguments</th>
134
135
  <th>Status</th>
135
- <th>Created At</th>
136
+ #{sortable_header('created_at', 'Created At')}
136
137
  <th>Actions</th>
137
138
  </tr>
138
139
  </thead>
@@ -2,9 +2,10 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class QueuesPresenter < BasePresenter
5
- def initialize(records, paused_queues = [])
5
+ def initialize(records, paused_queues = [], sort: {})
6
6
  @records = records
7
7
  @paused_queues = paused_queues
8
+ @sort = sort
8
9
  end
9
10
 
10
11
  def render
@@ -19,9 +20,9 @@ module SolidQueueMonitor
19
20
  <table>
20
21
  <thead>
21
22
  <tr>
22
- <th>Queue Name</th>
23
+ #{sortable_header('queue_name', 'Queue Name')}
23
24
  <th>Status</th>
24
- <th>Total Jobs</th>
25
+ #{sortable_header('job_count', 'Total Jobs')}
25
26
  <th>Ready Jobs</th>
26
27
  <th>Scheduled Jobs</th>
27
28
  <th>Failed Jobs</th>
@@ -2,11 +2,12 @@
2
2
 
3
3
  module SolidQueueMonitor
4
4
  class ReadyJobsPresenter < BasePresenter
5
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
5
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
6
6
  @jobs = jobs
7
7
  @current_page = current_page
8
8
  @total_pages = total_pages
9
9
  @filters = filters
10
+ @sort = sort
10
11
  end
11
12
 
12
13
  def render
@@ -50,11 +51,11 @@ module SolidQueueMonitor
50
51
  <table>
51
52
  <thead>
52
53
  <tr>
53
- <th>Job</th>
54
- <th>Queue</th>
55
- <th>Priority</th>
54
+ #{sortable_header('class_name', 'Job')}
55
+ #{sortable_header('queue_name', 'Queue')}
56
+ #{sortable_header('priority', 'Priority')}
56
57
  <th>Arguments</th>
57
- <th>Created At</th>
58
+ #{sortable_header('created_at', 'Created At')}
58
59
  </tr>
59
60
  </thead>
60
61
  <tbody>
@@ -5,11 +5,12 @@ module SolidQueueMonitor
5
5
  include Rails.application.routes.url_helpers
6
6
  include SolidQueueMonitor::Engine.routes.url_helpers
7
7
 
8
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
8
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
9
9
  @jobs = jobs
10
10
  @current_page = current_page
11
11
  @total_pages = total_pages
12
12
  @filters = filters
13
+ @sort = sort
13
14
  end
14
15
 
15
16
  def render
@@ -48,11 +49,11 @@ module SolidQueueMonitor
48
49
  <table>
49
50
  <thead>
50
51
  <tr>
51
- <th>Key</th>
52
- <th>Job</th>
52
+ #{sortable_header('key', 'Key')}
53
+ #{sortable_header('class_name', 'Job')}
53
54
  <th>Schedule</th>
54
- <th>Queue</th>
55
- <th>Priority</th>
55
+ #{sortable_header('queue_name', 'Queue')}
56
+ #{sortable_header('priority', 'Priority')}
56
57
  <th>Last Updated</th>
57
58
  </tr>
58
59
  </thead>
@@ -5,11 +5,12 @@ module SolidQueueMonitor
5
5
  include Rails.application.routes.url_helpers
6
6
  include SolidQueueMonitor::Engine.routes.url_helpers
7
7
 
8
- def initialize(jobs, current_page: 1, total_pages: 1, filters: {})
8
+ def initialize(jobs, current_page: 1, total_pages: 1, filters: {}, sort: {})
9
9
  @jobs = jobs
10
10
  @current_page = current_page
11
11
  @total_pages = total_pages
12
12
  @filters = filters
13
+ @sort = sort
13
14
  end
14
15
 
15
16
  def render
@@ -140,9 +141,9 @@ module SolidQueueMonitor
140
141
  <thead>
141
142
  <tr>
142
143
  <th width="50"><input type="checkbox"></th>
143
- <th>Job</th>
144
- <th>Queue</th>
145
- <th>Scheduled At</th>
144
+ #{sortable_header('class_name', 'Job')}
145
+ #{sortable_header('queue_name', 'Queue')}
146
+ #{sortable_header('scheduled_at', 'Scheduled At')}
146
147
  <th>Arguments</th>
147
148
  </tr>
148
149
  </thead>