From 3c7c1388b6e2f6e617757a8259af47f10cd27656 Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 10:13:33 +0530 Subject: [PATCH 1/8] Dollar signs used before commands without showing output --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e1330308a..e72a63df7 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla - By default, GoodJob separates job enqueuing from job execution so that jobs can be scaled independently of the web server. Use the GoodJob command-line tool to execute jobs: ```bash - $ bundle exec good_job start + bundle exec good_job start ``` Ideally the command-line tool should be run on a separate machine or container from the web process. For example, on Heroku: @@ -133,8 +133,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla - GoodJob can also be configured to execute jobs within the web server process to save on resources. This is useful for low-workloads when economy is paramount. - ``` - $ GOOD_JOB_EXECUTION_MODE=async rails server + ```bash + GOOD_JOB_EXECUTION_MODE=async rails server ``` Additional configuration is likely necessary, see the reference below for configuration. @@ -470,7 +470,7 @@ To perform upgrades to the GoodJob database tables: Optional: If using Rails' multiple databases with the `migrations_paths` configuration option, use the `--database` option: ```bash - $ bin/rails g good_job:update --database animals + bin/rails g good_job:update --database animals ``` 1. Run the database migration locally @@ -703,7 +703,7 @@ GoodJob can execute jobs "async" in the same process as the web server (e.g. `bi - Or, with environment variables: ```bash - $ GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server + GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server ``` Depending on your application configuration, you may need to take additional steps: @@ -821,7 +821,7 @@ It is also necessary to delete these preserved jobs from the database after a ce - For example, using the `good_job` command-line utility: ```bash - $ bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400 + bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400 ``` ### PgBouncer compatibility From c2174a5703ccb8998de60486231c000420cbb8fc Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 10:29:07 +0530 Subject: [PATCH 2/8] markdown lint fixes --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index e72a63df7..8afe0ebd7 100644 --- a/README.md +++ b/README.md @@ -33,33 +33,33 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla - [Set up](#set-up) - [Compatibility](#compatibility) - [Configuration](#configuration) - - [Command-line options](#command-line-options) - - [`good_job start`](#good_job-start) - - [`good_job cleanup_preserved_jobs`](#good_job-cleanup_preserved_jobs) - - [Configuration options](#configuration-options) - - [Global options](#global-options) - - [Dashboard](#dashboard) - - [ActiveJob concurrency](#activejob-concurrency) - - [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs) - - [Updating](#updating) - - [Upgrading minor versions](#upgrading-minor-versions) - - [Upgrading v1 to v2](#upgrading-v1-to-v2) + - [Command-line options](#command-line-options) + - [`good_job start`](#good_job-start) + - [`good_job cleanup_preserved_jobs`](#good_job-cleanup_preserved_jobs) + - [Configuration options](#configuration-options) + - [Global options](#global-options) + - [Dashboard](#dashboard) + - [ActiveJob concurrency](#activejob-concurrency) + - [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs) + - [Updating](#updating) + - [Upgrading minor versions](#upgrading-minor-versions) + - [Upgrading v1 to v2](#upgrading-v1-to-v2) - [Go deeper](#go-deeper) - - [Exceptions, retries, and reliability](#exceptions-retries-and-reliability) - - [Exceptions](#exceptions) - - [Retries](#retries) - - [ActionMailer retries](#actionmailer-retries) - - [Timeouts](#timeouts) - - [Optimize queues, threads, and processes](#optimize-queues-threads-and-processes) - - [Database connections](#database-connections) - - [Execute jobs async / in-process](#execute-jobs-async--in-process) - - [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend) - - [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs) - - [PgBouncer compatibility](#pgbouncer-compatibility) - - [CLI HTTP health check probes](#cli-http-health-check-probes) + - [Exceptions, retries, and reliability](#exceptions-retries-and-reliability) + - [Exceptions](#exceptions) + - [Retries](#retries) + - [ActionMailer retries](#actionmailer-retries) + - [Timeouts](#timeouts) + - [Optimize queues, threads, and processes](#optimize-queues-threads-and-processes) + - [Database connections](#database-connections) + - [Execute jobs async / in-process](#execute-jobs-async--in-process) + - [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend) + - [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs) + - [PgBouncer compatibility](#pgbouncer-compatibility) + - [CLI HTTP health check probes](#cli-http-health-check-probes) - [Contribute](#contribute) - - [Gem development](#gem-development) - - [Release](#release) + - [Gem development](#gem-development) + - [Release](#release) - [License](#license) ## Set up @@ -260,10 +260,10 @@ end Available configuration options are: - `execution_mode` (symbol) specifies how and where jobs should be executed. You can also set this with the environment variable `GOOD_JOB_EXECUTION_MODE`. It can be any one of: - - `:inline` executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments. - - `:external` causes the adapter to enqueue jobs, but not execute them. When using this option (the default for production environments), you’ll need to use the command-line tool to actually execute your jobs. - - `:async` (or `:async_server`) executes jobs in separate threads within the Rails web server process (`bundle exec rails server`). It can be more economical for small workloads because you don’t need a separate machine or environment for running your jobs, but if your web server is under heavy load or your jobs require a lot of resources, you should choose `:external` instead. When not in the Rails web server, jobs will execute in `:external` mode to ensure jobs are not executed within `rails console`, `rails db:migrate`, `rails assets:prepare`, etc. - - `:async_all` executes jobs in separate threads in _any_ Rails process. + - `:inline` executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments. + - `:external` causes the adapter to enqueue jobs, but not execute them. When using this option (the default for production environments), you’ll need to use the command-line tool to actually execute your jobs. + - `:async` (or `:async_server`) executes jobs in separate threads within the Rails web server process (`bundle exec rails server`). It can be more economical for small workloads because you don’t need a separate machine or environment for running your jobs, but if your web server is under heavy load or your jobs require a lot of resources, you should choose `:external` instead. When not in the Rails web server, jobs will execute in `:external` mode to ensure jobs are not executed within `rails console`, `rails db:migrate`, `rails assets:prepare`, etc. + - `:async_all` executes jobs in separate threads in _any_ Rails process. - `max_threads` (integer) sets the maximum number of threads to use when `execution_mode` is set to `:async`. You can also set this with the environment variable `GOOD_JOB_MAX_THREADS`. - `queues` (string) determines which queues to execute jobs from when `execution_mode` is set to `:async`. See the description of `good_job start` for more details on the format of this string. You can also set this with the environment variable `GOOD_JOB_QUEUES`. - `poll_interval` (integer) sets the number of seconds between polls for jobs when `execution_mode` is set to `:async`. You can also set this with the environment variable `GOOD_JOB_POLL_INTERVAL`. A poll interval of `-1` disables polling completely. @@ -618,8 +618,8 @@ By default, GoodJob creates a single thread execution pool that will execute job A pool is configured with the following syntax `:`: - - ``: either `queue1,queue2` (only those queues), `*` (all) or `-queue1,queue2` (all except those queues). - - ``: a count overriding for this specific pool the global `max-threads`. + - ``: either `queue1,queue2` (only those queues), `*` (all) or `-queue1,queue2` (all except those queues). + - ``: a count overriding for this specific pool the global `max-threads`. Pool configurations are separated with a semicolon (;) in the `queues` configuration From 68a5fc0b9a1c47213dd6f506d6e269401e84429f Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 12:50:48 +0530 Subject: [PATCH 3/8] added missing response meta tag --- engine/app/views/layouts/good_job/base.html.erb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/app/views/layouts/good_job/base.html.erb b/engine/app/views/layouts/good_job/base.html.erb index a3e4fddc5..503a11cb3 100644 --- a/engine/app/views/layouts/good_job/base.html.erb +++ b/engine/app/views/layouts/good_job/base.html.erb @@ -2,6 +2,8 @@ Good Job Dashboard + + <%= csrf_meta_tags %> <%= csp_meta_tag %> From 3c572c8c0fe7e95ec61cf664bb23d1b264855142 Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 12:52:44 +0530 Subject: [PATCH 4/8] mobile friendly filter + added dropdowns for job_class, queue_name, and state --- engine/app/views/good_job/shared/_filter.erb | 84 ++++++-------------- 1 file changed, 26 insertions(+), 58 deletions(-) diff --git a/engine/app/views/good_job/shared/_filter.erb b/engine/app/views/good_job/shared/_filter.erb index 92abd2156..74dbbfdaa 100644 --- a/engine/app/views/good_job/shared/_filter.erb +++ b/engine/app/views/good_job/shared/_filter.erb @@ -1,66 +1,34 @@
-
-
- Filter by job class -
- <% filter.job_classes.each do |name, count| %> - <% if params[:job_class] == name %> - <%= link_to(filter.to_params(job_class: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> - <%= name %> (<%= count %>) - <% end %> - <% else %> - <%= link_to(filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> - <%= name %> (<%= count %>) - <% end %> - <% end %> - <% end %> -
+
-
- Filter by state -
- <% filter.states.each do |name, count| %> - <% if params[:state] == name %> - <%= link_to(filter.to_params(state: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> - <%= name %> (<%= count %>) - <% end %> - <% else %> - <%= link_to(filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> - <%= name %> (<%= count %>) - <% end %> - <% end %> - <% end %> -
+ <%= form_with(method: :get, local: true, class: 'row') do |form| %> +
+ + <%= form.select :job_class, filter.job_classes.collect { |t| [ format('%s (%d)', t[0], t[1]), t[0] ]}, { include_blank: true, selected: params[:job_class] }, { class: 'form-select form-select-sm' } %> +
-
- Filter by queue -
- <% filter.queues.each do |name, count| %> - <% if params[:queue_name] == name %> - <%= link_to(filter.to_params(queue_name: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> - <%= name %> (<%= count %>) - <% end %> - <% else %> - <%= link_to(filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> - <%= name %> (<%= count %>) - <% end %> - <% end %> - <% end %> -
+
+ + <%= form.select :queue_name, filter.queues.collect { |t| [ format('%s (%d)', t[0].titleize, t[1]), t[0] ]}, { include_blank: true, selected: params[:queue_name] }, { class: 'form-select form-select-sm' } %> +
-
- <%= form_with(url: "", method: :get, local: true) do |form| %> - <% filter.to_params(query: nil).each do |key, value| %> - <%= form.hidden_field(key.to_sym, value: value) %> - <% end %> +
+ + <%= form.select :state, filter.states.collect { |t| [ format('%s (%d)', t[0].titleize, t[1]), t[0] ]}, { include_blank: true, selected: params[:state] }, { class: 'form-select form-select-sm' } %> +
- <%= form.label :query, "Search" %> -
- <%= form.search_field :query, value: params[:query], class: "form-control" %> - <%= form.button "Search", type: "submit", name: nil, class: "btn btn-sm btn-outline-secondary" %> - <%= link_to "Clear", filter.to_params(query: nil), class: "btn btn-sm btn-outline-secondary" %> +
+ + <%= form.search_field :query, value: params[:query], class: "form-control form-control-sm" %> +
+ +
+ +
+ <%= form.button "Search", type: "submit", name: nil, class: "btn btn-sm btn-outline-secondary form-control" %> + <%= link_to "Clear", nil, class: "btn btn-sm btn-outline-secondary" %>
- <% end %> -
+
+ <% end %>
From 244e3dd1acae1211d745e1c65512d1a3e6267fea Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 13:06:02 +0530 Subject: [PATCH 5/8] erb lint corrections --- engine/app/views/layouts/good_job/base.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/app/views/layouts/good_job/base.html.erb b/engine/app/views/layouts/good_job/base.html.erb index 503a11cb3..33ad40210 100644 --- a/engine/app/views/layouts/good_job/base.html.erb +++ b/engine/app/views/layouts/good_job/base.html.erb @@ -2,8 +2,8 @@ Good Job Dashboard - - + + <%= csrf_meta_tags %> <%= csp_meta_tag %> From 3744653c09f60d14527d6b771d57291159168c57 Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 13:15:17 +0530 Subject: [PATCH 6/8] restored the list indentation --- README.md | 62 +++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 8afe0ebd7..e72a63df7 100644 --- a/README.md +++ b/README.md @@ -33,33 +33,33 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla - [Set up](#set-up) - [Compatibility](#compatibility) - [Configuration](#configuration) - - [Command-line options](#command-line-options) - - [`good_job start`](#good_job-start) - - [`good_job cleanup_preserved_jobs`](#good_job-cleanup_preserved_jobs) - - [Configuration options](#configuration-options) - - [Global options](#global-options) - - [Dashboard](#dashboard) - - [ActiveJob concurrency](#activejob-concurrency) - - [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs) - - [Updating](#updating) - - [Upgrading minor versions](#upgrading-minor-versions) - - [Upgrading v1 to v2](#upgrading-v1-to-v2) + - [Command-line options](#command-line-options) + - [`good_job start`](#good_job-start) + - [`good_job cleanup_preserved_jobs`](#good_job-cleanup_preserved_jobs) + - [Configuration options](#configuration-options) + - [Global options](#global-options) + - [Dashboard](#dashboard) + - [ActiveJob concurrency](#activejob-concurrency) + - [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs) + - [Updating](#updating) + - [Upgrading minor versions](#upgrading-minor-versions) + - [Upgrading v1 to v2](#upgrading-v1-to-v2) - [Go deeper](#go-deeper) - - [Exceptions, retries, and reliability](#exceptions-retries-and-reliability) - - [Exceptions](#exceptions) - - [Retries](#retries) - - [ActionMailer retries](#actionmailer-retries) - - [Timeouts](#timeouts) - - [Optimize queues, threads, and processes](#optimize-queues-threads-and-processes) - - [Database connections](#database-connections) - - [Execute jobs async / in-process](#execute-jobs-async--in-process) - - [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend) - - [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs) - - [PgBouncer compatibility](#pgbouncer-compatibility) - - [CLI HTTP health check probes](#cli-http-health-check-probes) + - [Exceptions, retries, and reliability](#exceptions-retries-and-reliability) + - [Exceptions](#exceptions) + - [Retries](#retries) + - [ActionMailer retries](#actionmailer-retries) + - [Timeouts](#timeouts) + - [Optimize queues, threads, and processes](#optimize-queues-threads-and-processes) + - [Database connections](#database-connections) + - [Execute jobs async / in-process](#execute-jobs-async--in-process) + - [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend) + - [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs) + - [PgBouncer compatibility](#pgbouncer-compatibility) + - [CLI HTTP health check probes](#cli-http-health-check-probes) - [Contribute](#contribute) - - [Gem development](#gem-development) - - [Release](#release) + - [Gem development](#gem-development) + - [Release](#release) - [License](#license) ## Set up @@ -260,10 +260,10 @@ end Available configuration options are: - `execution_mode` (symbol) specifies how and where jobs should be executed. You can also set this with the environment variable `GOOD_JOB_EXECUTION_MODE`. It can be any one of: - - `:inline` executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments. - - `:external` causes the adapter to enqueue jobs, but not execute them. When using this option (the default for production environments), you’ll need to use the command-line tool to actually execute your jobs. - - `:async` (or `:async_server`) executes jobs in separate threads within the Rails web server process (`bundle exec rails server`). It can be more economical for small workloads because you don’t need a separate machine or environment for running your jobs, but if your web server is under heavy load or your jobs require a lot of resources, you should choose `:external` instead. When not in the Rails web server, jobs will execute in `:external` mode to ensure jobs are not executed within `rails console`, `rails db:migrate`, `rails assets:prepare`, etc. - - `:async_all` executes jobs in separate threads in _any_ Rails process. + - `:inline` executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments. + - `:external` causes the adapter to enqueue jobs, but not execute them. When using this option (the default for production environments), you’ll need to use the command-line tool to actually execute your jobs. + - `:async` (or `:async_server`) executes jobs in separate threads within the Rails web server process (`bundle exec rails server`). It can be more economical for small workloads because you don’t need a separate machine or environment for running your jobs, but if your web server is under heavy load or your jobs require a lot of resources, you should choose `:external` instead. When not in the Rails web server, jobs will execute in `:external` mode to ensure jobs are not executed within `rails console`, `rails db:migrate`, `rails assets:prepare`, etc. + - `:async_all` executes jobs in separate threads in _any_ Rails process. - `max_threads` (integer) sets the maximum number of threads to use when `execution_mode` is set to `:async`. You can also set this with the environment variable `GOOD_JOB_MAX_THREADS`. - `queues` (string) determines which queues to execute jobs from when `execution_mode` is set to `:async`. See the description of `good_job start` for more details on the format of this string. You can also set this with the environment variable `GOOD_JOB_QUEUES`. - `poll_interval` (integer) sets the number of seconds between polls for jobs when `execution_mode` is set to `:async`. You can also set this with the environment variable `GOOD_JOB_POLL_INTERVAL`. A poll interval of `-1` disables polling completely. @@ -618,8 +618,8 @@ By default, GoodJob creates a single thread execution pool that will execute job A pool is configured with the following syntax `:`: - - ``: either `queue1,queue2` (only those queues), `*` (all) or `-queue1,queue2` (all except those queues). - - ``: a count overriding for this specific pool the global `max-threads`. + - ``: either `queue1,queue2` (only those queues), `*` (all) or `-queue1,queue2` (all except those queues). + - ``: a count overriding for this specific pool the global `max-threads`. Pool configurations are separated with a semicolon (;) in the `queues` configuration From 1da9a6e56326f4d22a41b222b7b5f33cac27e964 Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 14:50:06 +0530 Subject: [PATCH 7/8] spec adjustment as per new ui changes --- engine/app/views/good_job/shared/_filter.erb | 2 +- spec/system/dashboard_spec.rb | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engine/app/views/good_job/shared/_filter.erb b/engine/app/views/good_job/shared/_filter.erb index 74dbbfdaa..4408063b5 100644 --- a/engine/app/views/good_job/shared/_filter.erb +++ b/engine/app/views/good_job/shared/_filter.erb @@ -1,7 +1,7 @@
- <%= form_with(method: :get, local: true, class: 'row') do |form| %> + <%= form_with(method: :get, local: true, class: 'row', id: 'JobFilterForm') do |form| %>
<%= form.select :job_class, filter.job_classes.collect { |t| [ format('%s (%d)', t[0], t[1]), t[0] ]}, { include_blank: true, selected: params[:job_class] }, { class: 'form-select form-select-sm' } %> diff --git a/spec/system/dashboard_spec.rb b/spec/system/dashboard_spec.rb index e382e6195..c06d9c79e 100644 --- a/spec/system/dashboard_spec.rb +++ b/spec/system/dashboard_spec.rb @@ -33,13 +33,17 @@ ExampleJob.perform_later visit '/good_job' - click_link 'unfinished' + within '#JobFilterForm' do + find_field('state').find("option[value='unfinished']").select_option + find('button[type="submit"]').click + end + expect(page).to have_content 'ExampleJob' click_button('Delete execution') expect(page).to have_content 'Job execution deleted' expect(page).not_to have_content 'ExampleJob' - expect(current_url).to match %r{/good_job/\?state=unfinished} + expect(current_url).to include('state=unfinished') end end From ae6f6c0700e5a58981ba4846b5aace878e4fc5ec Mon Sep 17 00:00:00 2001 From: zeevy Date: Sun, 23 Jan 2022 23:23:54 +0530 Subject: [PATCH 8/8] moving the filter changes to another PR --- engine/app/views/good_job/shared/_filter.erb | 84 ++++++++++++++------ spec/system/dashboard_spec.rb | 8 +- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/engine/app/views/good_job/shared/_filter.erb b/engine/app/views/good_job/shared/_filter.erb index 4408063b5..92abd2156 100644 --- a/engine/app/views/good_job/shared/_filter.erb +++ b/engine/app/views/good_job/shared/_filter.erb @@ -1,34 +1,66 @@
-
+
+
+ Filter by job class +
+ <% filter.job_classes.each do |name, count| %> + <% if params[:job_class] == name %> + <%= link_to(filter.to_params(job_class: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> + <%= name %> (<%= count %>) + <% end %> + <% else %> + <%= link_to(filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> + <%= name %> (<%= count %>) + <% end %> + <% end %> + <% end %> +
- <%= form_with(method: :get, local: true, class: 'row', id: 'JobFilterForm') do |form| %> -
- - <%= form.select :job_class, filter.job_classes.collect { |t| [ format('%s (%d)', t[0], t[1]), t[0] ]}, { include_blank: true, selected: params[:job_class] }, { class: 'form-select form-select-sm' } %> -
+
+ Filter by state +
+ <% filter.states.each do |name, count| %> + <% if params[:state] == name %> + <%= link_to(filter.to_params(state: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> + <%= name %> (<%= count %>) + <% end %> + <% else %> + <%= link_to(filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> + <%= name %> (<%= count %>) + <% end %> + <% end %> + <% end %> +
-
- - <%= form.select :queue_name, filter.queues.collect { |t| [ format('%s (%d)', t[0].titleize, t[1]), t[0] ]}, { include_blank: true, selected: params[:queue_name] }, { class: 'form-select form-select-sm' } %> -
+
+ Filter by queue +
+ <% filter.queues.each do |name, count| %> + <% if params[:queue_name] == name %> + <%= link_to(filter.to_params(queue_name: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %> + <%= name %> (<%= count %>) + <% end %> + <% else %> + <%= link_to(filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %> + <%= name %> (<%= count %>) + <% end %> + <% end %> + <% end %> +
-
- - <%= form.select :state, filter.states.collect { |t| [ format('%s (%d)', t[0].titleize, t[1]), t[0] ]}, { include_blank: true, selected: params[:state] }, { class: 'form-select form-select-sm' } %> -
+
+ <%= form_with(url: "", method: :get, local: true) do |form| %> + <% filter.to_params(query: nil).each do |key, value| %> + <%= form.hidden_field(key.to_sym, value: value) %> + <% end %> -
- - <%= form.search_field :query, value: params[:query], class: "form-control form-control-sm" %> -
- -
- -
- <%= form.button "Search", type: "submit", name: nil, class: "btn btn-sm btn-outline-secondary form-control" %> - <%= link_to "Clear", nil, class: "btn btn-sm btn-outline-secondary" %> + <%= form.label :query, "Search" %> +
+ <%= form.search_field :query, value: params[:query], class: "form-control" %> + <%= form.button "Search", type: "submit", name: nil, class: "btn btn-sm btn-outline-secondary" %> + <%= link_to "Clear", filter.to_params(query: nil), class: "btn btn-sm btn-outline-secondary" %>
-
- <% end %> + <% end %> +
diff --git a/spec/system/dashboard_spec.rb b/spec/system/dashboard_spec.rb index c06d9c79e..e382e6195 100644 --- a/spec/system/dashboard_spec.rb +++ b/spec/system/dashboard_spec.rb @@ -33,17 +33,13 @@ ExampleJob.perform_later visit '/good_job' - within '#JobFilterForm' do - find_field('state').find("option[value='unfinished']").select_option - find('button[type="submit"]').click - end - + click_link 'unfinished' expect(page).to have_content 'ExampleJob' click_button('Delete execution') expect(page).to have_content 'Job execution deleted' expect(page).not_to have_content 'ExampleJob' - expect(current_url).to include('state=unfinished') + expect(current_url).to match %r{/good_job/\?state=unfinished} end end