diff --git a/Gemfile b/Gemfile
index c050aba..e3665cb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -43,6 +43,7 @@ gem 'whenever', require: false
gem 'octicons'
gem 'kaminari'
+gem 'has_scope'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 7468329..5e091d7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -131,6 +131,9 @@ GEM
guard-minitest (2.4.6)
guard-compat (~> 1.2)
minitest (>= 3.0)
+ has_scope (0.7.2)
+ actionpack (>= 4.1)
+ activesupport (>= 4.1)
i18n (1.0.1)
concurrent-ruby (~> 1.0)
io-like (0.3.0)
@@ -350,6 +353,7 @@ DEPENDENCIES
factory_bot_rails
guard
guard-minitest
+ has_scope
jbuilder (~> 2.5)
kaminari
launchy
diff --git a/app/controllers/checks_controller.rb b/app/controllers/checks_controller.rb
index b592408..fff3482 100644
--- a/app/controllers/checks_controller.rb
+++ b/app/controllers/checks_controller.rb
@@ -4,8 +4,11 @@ class ChecksController < ApplicationController
after_action :verify_authorized, except: :index
after_action :verify_policy_scoped, only: :index
+ has_scope :kind
+ has_scope :by_domain
+
def index
- @checks = policy_scope(Check).order(:domain_expires_at).page(params[:page])
+ @checks = apply_scopes(policy_scope(Check)).order(current_sort).page(params[:page])
end
def new
@@ -79,4 +82,22 @@ class ChecksController < ApplicationController
def build_empty_notification
@check.notifications.build
end
+
+ def current_sort
+ @current_sort ||= clean_sort || Check.default_sort
+ end
+ helper_method :current_sort
+
+ def clean_sort
+ return unless params[:sort].present?
+ field, _, direction = params[:sort].rpartition("_").map(&:to_sym)
+
+ valid_fields = [:domain, :domain_expires_at]
+ valid_directions = [:asc, :desc]
+
+ return unless valid_fields.include?(field)
+ return unless valid_directions.include?(direction)
+
+ { field => direction }
+ end
end
diff --git a/app/helpers/checks_helper.rb b/app/helpers/checks_helper.rb
index ae82a4c..84bf8e0 100644
--- a/app/helpers/checks_helper.rb
+++ b/app/helpers/checks_helper.rb
@@ -11,4 +11,22 @@ module ChecksHelper
return "table-danger" if expiry_date <= 2.weeks.from_now
return "table-warning" if expiry_date <= 30.days.from_now
end
+
+ def checks_sort_links(field)
+ current_sort_str = current_sort.to_a.join("_")
+
+ %i[asc desc].map { |direction|
+ sort = "#{field}_#{direction}"
+
+ icon = direction == :asc ? "chevron-up" : "chevron-down"
+ html = Octicons::Octicon.new(icon).to_svg.html_safe
+
+ filter_params = current_criterias.merge(sort: sort)
+ link_to_unless sort == current_sort_str, html, checks_path(filter_params)
+ }.join
+ end
+
+ def current_criterias
+ current_scopes.merge(sort: params[:sort])
+ end
end
diff --git a/app/models/check.rb b/app/models/check.rb
index 115119b..6d214a6 100644
--- a/app/models/check.rb
+++ b/app/models/check.rb
@@ -58,6 +58,13 @@ class Check < ApplicationRecord
OR (last_success_at <= DATE_SUB(last_run_at, INTERVAL 5 MINUTE))")
}
+ scope :kind, ->(kind) { where(kind: kind) }
+ scope :by_domain, ->(domain) { where("domain LIKE ?", "%#{domain}%") }
+
+ def self.default_sort
+ { domain_expires_at: :asc }
+ end
+
private
def domain_created_at_past
diff --git a/app/views/checks/_table.html.erb b/app/views/checks/_table.html.erb
index a0f05b0..94531a1 100644
--- a/app/views/checks/_table.html.erb
+++ b/app/views/checks/_table.html.erb
@@ -3,9 +3,15 @@
- Domain
- Expiry date
- Edit
+
+ <%= t(".domain") %>
+ <%== checks_sort_links(:domain) %>
+
+
+ <%= t(".expiry_date") %>
+ <%== checks_sort_links(:domain_expires_at) %>
+
+ <%= t(".edit") %>