Browse Source

Merge pull request #466 from communitiesuk/composable_filter_scopes

Allow OR filters within scope categories and AND filters across them
pull/464/head
baarkerlounger 3 years ago committed by GitHub
parent
commit
9517479130
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      app/controllers/case_logs_controller.rb
  2. 8
      app/models/case_log.rb
  3. 4
      app/views/case_logs/_log_filters.erb
  4. 2
      app/views/filters/_checkbox_filter.html.erb
  5. 32
      spec/models/case_log_spec.rb
  6. 8
      spec/requests/case_logs_controller_spec.rb

14
app/controllers/case_logs_controller.rb

@ -121,23 +121,21 @@ private
end
def filtered_case_logs
user_case_logs = current_user.case_logs
query = CaseLog.for_organisation(current_user.organisation)
if session[:case_logs_filters].present?
filters = JSON.parse(session[:case_logs_filters])
filters.each do |category, values|
next if values.reject(&:empty?).blank?
%w[status year].each do |category|
if filters[category]
filtered_by_category = filters[category].select(&:present?).map { |filter| user_case_logs.public_send("filter_by_#{category}", filter) }.flatten
user_case_logs = CaseLog.where(id: filtered_by_category.map(&:id))
query = query.public_send("filter_by_#{category}", values)
end
end
end
user_case_logs
query.all.includes(:owning_organisation, :managing_organisation)
end
def set_session_filters
new_filters = session[:case_logs_filters].present? ? JSON.parse(session[:case_logs_filters]) : {}
%i[status year].each { |filter| new_filters[filter] = params[filter] if params[filter].present? }
%i[status years].each { |filter| new_filters[filter] = params[filter] if params[filter].present? }
session[:case_logs_filters] = new_filters.to_json
end
end

8
app/models/case_log.rb

@ -35,7 +35,13 @@ class CaseLog < ApplicationRecord
scope :for_organisation, ->(org) { where(owning_organisation: org).or(where(managing_organisation: org)) }
scope :filter_by_status, ->(status) { where status: status }
scope :filter_by_year, ->(year) { where(startdate: Time.zone.local(year, 4, 1)...Time.zone.local(year.to_i + 1, 4, 1)) }
scope :filter_by_years, lambda { |years|
first_year = years.shift
query = filter_by_year(first_year)
years.each { |year| query = query.or(filter_by_year(year)) }
query.all
}
scope :filter_by_year, ->(year) { where(startdate: Time.utc(year.to_i, 4, 1)...Time.utc(year.to_i + 1, 4, 1)) }
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at].freeze
OPTIONAL_FIELDS = %w[postcode_known la_known first_time_property_let_as_social_housing tenant_code propcode].freeze

4
app/views/case_logs/_log_filters.erb

@ -14,8 +14,8 @@
<div class="govuk-form-group app-filter__group">
<%= form_with url: "/logs", html: { method: :get } do |f| %>
<% years = {"2021": "2021/22", "2022": "2022/23"} %>
<%= render partial: "filters/checkbox_filter", locals: {f: f, options: years, label: "Collection year", category: "year" } %>
<%= render partial: "filters/checkbox_filter", locals: {f: f, options: status_filters, label: "Status", category: "status" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: years, label: "Collection year", category: "years" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: status_filters, label: "Status", category: "status" } %>
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-top-4" %>
<% end %>
</div>

2
app/views/filters/_checkbox_filter.html.erb

@ -1,4 +1,4 @@
<%= f.govuk_check_boxes_fieldset :year, legend: { text: label, size: "s"} do %>
<%= f.govuk_check_boxes_fieldset category.to_sym, legend: { text: label, size: "s"} do %>
<div class="govuk-checkboxes govuk-checkboxes--small" data-module="govuk-checkboxes">
<% options.map do |key, option| %>
<%= f.govuk_check_box category, "#{key}",

32
spec/models/case_log_spec.rb

@ -1825,4 +1825,36 @@ RSpec.describe CaseLog do
end
end
end
describe "scopes" do
before do
FactoryBot.create(:case_log, :in_progress, startdate: Time.utc(2021, 5, 3))
FactoryBot.create(:case_log, :completed, startdate: Time.utc(2021, 5, 3))
FactoryBot.create(:case_log, startdate: Time.utc(2022, 6, 3))
end
context "when filtering by year" do
it "allows filtering on a single year" do
expect(described_class.filter_by_years(%w[2021]).count).to eq(2)
end
it "allows filtering by multiple years using OR" do
expect(described_class.filter_by_years(%w[2021 2022]).count).to eq(3)
end
it "can filter by year(s) AND status" do
expect(described_class.filter_by_years(%w[2021 2022]).filter_by_status("completed").count).to eq(1)
end
end
context "when filtering on status" do
it "allows filtering on a single status" do
expect(described_class.filter_by_status(%w[in_progress]).count).to eq(2)
end
it "allows filtering on multiple statuses" do
expect(described_class.filter_by_status(%w[in_progress completed]).count).to eq(3)
end
end
end
end

8
spec/requests/case_logs_controller_spec.rb

@ -225,13 +225,13 @@ RSpec.describe CaseLogsController, type: :request do
end
it "shows case logs for multiple selected years" do
get "/logs?year[]=2021&year[]=2022", headers: headers, params: {}
get "/logs?years[]=2021&years[]=2022", headers: headers, params: {}
expect(page).to have_link(case_log_2021.id.to_s)
expect(page).to have_link(case_log_2022.id.to_s)
end
it "shows case logs for one selected year" do
get "/logs?year[]=2021", headers: headers, params: {}
get "/logs?years[]=2021", headers: headers, params: {}
expect(page).to have_link(case_log_2021.id.to_s)
expect(page).not_to have_link(case_log_2022.id.to_s)
end
@ -260,14 +260,14 @@ RSpec.describe CaseLogsController, type: :request do
end
it "shows case logs for multiple selected statuses and years" do
get "/logs?year[]=2021&year[]=2022&status[]=in_progress&status[]=completed", headers: headers, params: {}
get "/logs?years[]=2021&years[]=2022&status[]=in_progress&status[]=completed", headers: headers, params: {}
expect(page).to have_link(case_log_2021.id.to_s)
expect(page).to have_link(case_log_2022.id.to_s)
expect(page).to have_link(case_log_2022_in_progress.id.to_s)
end
it "shows case logs for one selected status" do
get "/logs?year[]=2022&status[]=in_progress", headers: headers, params: {}
get "/logs?years[]=2022&status[]=in_progress", headers: headers, params: {}
expect(page).to have_link(case_log_2022_in_progress.id.to_s)
expect(page).not_to have_link(case_log_2021.id.to_s)
expect(page).not_to have_link(case_log_2022.id.to_s)

Loading…
Cancel
Save