Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions app/queries/sponsors_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,18 @@ def by_name
end

def by_chapter
if chapter.present?
@sponsors = sponsors.joins(:workshops).where('workshops.chapter_id' => chapter).group('sponsors.id')
return if chapter.blank?

chapter_id = chapter.to_s.match?(/\A\d+\z/) ? chapter : lookup_chapter_id
if chapter_id
@sponsors = sponsors.joins(:workshops).where('workshops.chapter_id' => chapter_id).group('sponsors.id')
else
errors.add(:chapter, :not_found, message: 'no chapter with that name')
@sponsors = Sponsor.none
end
end

def lookup_chapter_id
Chapter.find_by('LOWER(name) = LOWER(?)', chapter.strip)&.id
end
end
38 changes: 29 additions & 9 deletions app/views/admin/sponsors/index.html.haml
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
- title 'Sponsors'
%style= ".form-control::placeholder { opacity: 0.7; }"

.container.py-4.py-lg-5
.row.mb-4
.col-12
%nav{'aria-label': 'breadcrumb'}
%ol.breadcrumb.ms-0
%li.breadcrumb-item.active= t('admin.shared.sponsors')
%li.breadcrumb-item= link_to 'Admin', admin_root_path
%li.breadcrumb-item.active Sponsors

.col-12
%h1.mb-3 Sponsors

.col-12
.row.row-cols-md-auto.align-items-center
= simple_form_for @sponsors_search, url: admin_sponsors_path, method: :get, wrapper: :inline_form, html: { class: 'row row-cols-1 row-cols-md-auto align-items-center' } do |f|
= f.collection_select :chapter, @chapters, :id, :name, { include_blank: true, prompt: 'Select a chapter' }, { class: 'chosen-select'}
= f.input :name, required: false, label: false, placeholder: 'Filter by sponsor name', input_html: { class: 'my-2 my-md-0' }
= f.button :button, 'Filter', class: 'btn btn-primary'
= link_to 'Reset form', admin_sponsors_path
= form_with model: @sponsors_search, url: admin_sponsors_path, method: :get do |f|
%fieldset.border.rounded.bg-light.p-3
%legend Filter sponsors
.row.row-cols-1.row-cols-md-auto.align-items-start.gap-1
- chapter_error = @sponsors_search.errors[:chapter].any?
.col
= f.label :chapter, 'Chapter', class: 'form-label'
= f.text_field :chapter, list: 'chapter-options', placeholder: 'ex: London', class: "form-control w-auto #{'is-invalid' if chapter_error}"
- if chapter_error
.invalid-feedback.d-block= @sponsors_search.errors[:chapter].join(', ')
%datalist#chapter-options
- @chapters.each do |chapter|
%option{ value: chapter.name }
.col
= f.label :name, 'Sponsor name', class: 'form-label'
= f.text_field :name, placeholder: 'ex: Google', class: 'form-control w-auto'
.col
.form-label.invisible  
= f.button 'Filter', class: 'btn btn-primary'
= link_to 'Reset form', admin_sponsors_path

= render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'sponsor' }

Expand All @@ -25,7 +47,7 @@
%th
Level
%th
Chapter(s)
Chapters
%th
Sponsorships
%tbody
Expand All @@ -40,5 +62,3 @@
= link_to chapter.name, admin_chapter_path(chapter)
%td
= sponsor.sponsorships_count

= render partial: 'shared/pagination', locals: { pagy: @pagy, model: 'sponsor' }
2 changes: 1 addition & 1 deletion app/views/shared/_pagination.html.haml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.row.align-items-center.justify-content-between
.col-auto
%p.mb-3
!= pagy.info_tag(item_name: model)
!= pagy.info_tag(item_name: model.pluralize(pagy.count))
.col-auto
!= pagy.series_nav(:bootstrap) if pagy.pages > 1
20 changes: 20 additions & 0 deletions spec/features/admin/filtering_sponsors_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,25 @@
expect(page).to have_text(sponsors.first.name)
end
end

describe 'when filtering by chapter' do
let!(:chapter) { Fabricate(:chapter, name: 'London') }
let!(:workshop) { Fabricate(:workshop_no_sponsor, chapter: chapter) }
let!(:matching_sponsor) { Fabricate(:sponsor) }

before do
Fabricate(:workshop_sponsor, workshop: workshop, sponsor: matching_sponsor)
Fabricate(:sponsor)
visit admin_sponsors_path
end

scenario 'only sponsors for that chapter are displayed' do
fill_in 'sponsors_search[chapter]', with: 'London'
click_on 'Filter'

expect(page).to have_css('.sponsor', count: 1)
expect(page).to have_text(matching_sponsor.name)
end
end
end
end
33 changes: 33 additions & 0 deletions spec/queries/sponsors_search_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@
expect(results).to contain_exactly(matching)
end

it 'filters by chapter name' do
chapter = Fabricate(:chapter, name: 'London')
matching = Fabricate(:sponsor)
Fabricate(:workshop_sponsor, workshop: Fabricate(:workshop_no_sponsor, chapter: chapter), sponsor: matching)
Fabricate(:sponsor)

results = described_class.new(name: nil, chapter: 'London').call

expect(results).to contain_exactly(matching)
end

it 'is case insensitive when filtering by chapter name' do
chapter = Fabricate(:chapter, name: 'London')
matching = Fabricate(:sponsor)
Fabricate(:workshop_sponsor, workshop: Fabricate(:workshop_no_sponsor, chapter: chapter), sponsor: matching)

results = described_class.new(name: nil, chapter: 'london').call
expect(results).to contain_exactly(matching)

results = described_class.new(name: nil, chapter: 'LONDON').call
expect(results).to contain_exactly(matching)
end

it 'filters by chapter' do
chapter = Fabricate(:chapter)
matching = Fabricate(:sponsor)
Expand All @@ -67,6 +90,16 @@
expect(results).to contain_exactly(matching)
end

it 'returns an empty relation when chapter does not exist' do
Fabricate(:sponsor)
search = described_class.new(name: nil, chapter: 'Nonexistent')

results = search.call

expect(results).to be_empty
expect(search.errors[:chapter]).to include('no chapter with that name')
end

it 'returns an empty relation when nothing matches' do
Fabricate(:sponsor, name: 'Apple Inc')

Expand Down