This repository has been archived by the owner on Dec 28, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New admin regional holidays index page (#489)
* add regional_holiday_decorator.rb * add new admin regional holidays index page * add query object for regional holidays * accept filter params in new_admin/regional_holidays_controller.rb * add filters to the new admin regional holidays index page * add translations and i18n * add specs for NewAdmin::RegionalHolidaysController * add message for when no regional holiday is found * add feature specs for new admin regional holidays index page * rename method in new admin regional holidays controller --------- Co-authored-by: Alessandro Dias Batista <alessandro.dias@codeminer42.com>
- Loading branch information
1 parent
ba2c46e
commit 6125ea8
Showing
15 changed files
with
603 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
module NewAdmin | ||
class RegionalHolidaysController < ApplicationController | ||
layout 'new_admin' | ||
|
||
before_action :load_cities_with_holidays, only: :index | ||
|
||
def index | ||
@regional_holidays = RegionalHolidaysQuery.new(**filter_params).call.decorate | ||
end | ||
|
||
private | ||
|
||
def filter_params | ||
params.permit( | ||
:regional_holiday_id, | ||
:month, | ||
city_ids: [] | ||
).to_h | ||
end | ||
|
||
def load_cities_with_holidays | ||
@cities_with_holidays = City.joins(:regional_holidays).distinct.order('cities.name ASC') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# frozen_string_literal: true | ||
|
||
class RegionalHolidayDecorator < Draper::Decorator | ||
delegate_all | ||
|
||
def cities | ||
model.cities.map(&:name).join(', ') | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# frozen_string_literal: true | ||
|
||
class RegionalHolidaysQuery | ||
def initialize(**options) | ||
@regional_holiday_id = options[:regional_holiday_id] | ||
@city_ids = options[:city_ids] | ||
@month = options[:month] | ||
end | ||
|
||
def call | ||
query = RegionalHoliday.joins(:cities) | ||
merge_options!(query) | ||
|
||
query.distinct | ||
end | ||
|
||
private | ||
|
||
attr_reader :regional_holiday_id, :city_ids, :month | ||
|
||
def merge_options!(query) | ||
query.merge!(by_regional_holiday(query)) | ||
query.merge!(by_cities(query)) | ||
query.merge!(by_month(query)) | ||
end | ||
|
||
def by_regional_holiday(query) | ||
return query unless regional_holiday_id.present? | ||
|
||
query.where(id: regional_holiday_id) | ||
end | ||
|
||
def by_cities(query) | ||
return query unless city_ids.present? && city_ids.reject(&:blank?).present? | ||
|
||
query.where(cities: { id: city_ids }) | ||
end | ||
|
||
def by_month(query) | ||
return query unless month.present? | ||
|
||
query.where(month: month) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
app/views/new_admin/regional_holidays/_regional_holidays_filters.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<div class="px-4 py-3 w-fit h-fit dark:bg-gray-800"> | ||
<h3 class="text-xs py-1 font-semibold tracking-wide text-left uppercase border-b dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800"> | ||
<%= t('regional_holidays.filters') %> | ||
</h3> | ||
<%= form_with url: new_admin_regional_holidays_url, method: :get do |form| %> | ||
<div class="mt-2 space-y-2"> | ||
<div class="mt-2 space-y-2"> | ||
<div class="flex flex-col space-y-2"> | ||
<%= form.label :name, t('regional_holidays.name'), class: 'text-xs font-semibold tracking-wide text-left text-gray-500 uppercase' %> | ||
<%= form.collection_select :regional_holiday_id, RegionalHoliday.order(:name), :id, :name, { prompt: t('regional_holidays.any'), selected: params[:regional_holiday_id] }, { class: 'w-full font-semibold rounded-lg text-sm dark:bg-slate-700 dark:text-gray-400' } %> | ||
</div> | ||
</div> | ||
<div class="mt-2 space-y-2"> | ||
<div class="flex flex-col space-y-2"> | ||
<%= form.label :city, t('regional_holidays.city'), class: 'text-xs font-semibold tracking-wide text-left text-gray-500 uppercase' %> | ||
<%= form.collection_select :city_ids, @cities_with_holidays, :id, :name, { selected: params[:city_ids] }, { multiple: true, class: 'w-full font-semibold rounded-lg text-sm dark:bg-slate-700 dark:text-gray-400' } %> | ||
</div> | ||
</div> | ||
<div class="mt-2 space-y-2"> | ||
<div class="flex flex-col space-y-2"> | ||
<%= form.label :month, t('regional_holidays.month'), class: 'text-xs font-semibold tracking-wide text-left text-gray-500 uppercase' %> | ||
<%= select_month(params[:month]&.to_i, { prompt: t('regional_holidays.any') }, { name: 'month', class: 'w-full font-semibold rounded-lg text-sm dark:bg-slate-700 dark:text-gray-400' }) %> | ||
</div> | ||
</div> | ||
<div class="mt-4 mb-2"> | ||
<div class="flex flex-row"> | ||
<%= form.submit t('regional_holidays.filter'), formmethod: :get, class: "px-4 py-2 mr-2 cursor-pointer font-semibold text-sm text-white transition-colors duration-150 rounded-lg bg-primary-600 hover:bg-primary-700" %> | ||
<%= link_to t('regional_holidays.clear_filters'), new_admin_regional_holidays_url, class: "px-4 py-2 cursor-pointer font-semibold text-sm text-white transition-colors duration-150 rounded-lg bg-slate-700 hover:bg-gray-600" %> | ||
</div> | ||
</div> | ||
<% end %> | ||
</div> |
53 changes: 53 additions & 0 deletions
53
app/views/new_admin/regional_holidays/_regional_holidays_table.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<table class="table-auto w-full h-fit" id="index_table_regional_holidays"> | ||
<thead> | ||
<tr class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800"> | ||
<th class="px-4 py-3"><%= RegionalHoliday.human_attribute_name('name') %></th> | ||
<th class="px-4 py-3"><%= RegionalHoliday.human_attribute_name('day') %></th> | ||
<th class="px-4 py-3"><%= RegionalHoliday.human_attribute_name('month') %></th> | ||
<th class="px-4 py-3"><%= RegionalHoliday.human_attribute_name('cities') %></th> | ||
<th class="px-4 py-3"></th> | ||
</tr> | ||
</thead> | ||
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800 text-sm text-start"> | ||
<% regional_holidays.each do |holiday| %> | ||
<tr id=<%= "regional_holiday_#{holiday.id}" %> class="text-gray-700 dark:text-gray-400"> | ||
<td class="px-4 py-3"> | ||
<div> | ||
<%= holiday.name %> | ||
</div> | ||
</td> | ||
<td class="px-4 py-3"> | ||
<div> | ||
<%= holiday.day %> | ||
</div> | ||
</td> | ||
<td class="px-4 py-3"> | ||
<div> | ||
<%= holiday.month %> | ||
</div> | ||
</td> | ||
<td class="px-4 py-3"> | ||
<div> | ||
<%= holiday.cities %> | ||
</div> | ||
</td> | ||
<td class="px-4 py-3"> | ||
<div class="space-x-4"> | ||
<%= link_to t('view'), | ||
nil, | ||
class: 'font-semibold transition-colors duration-150 underline dark:hover:text-white hover:text-gray-900' | ||
%> | ||
<%= link_to t('edit'), | ||
nil, | ||
class: 'font-semibold transition-colors duration-150 underline dark:hover:text-white hover:text-gray-900' | ||
%> | ||
<%= link_to t('delete'), | ||
nil, | ||
class: 'font-semibold transition-colors duration-150 underline dark:hover:text-white hover:text-gray-900' | ||
%> | ||
</div> | ||
</td> | ||
</tr> | ||
<% end %> | ||
</tbody> | ||
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<% content_for :page_title do %> | ||
<%= t('regional_holidays.title') %> | ||
<% end %> | ||
|
||
<div data-tab-id="regional_holidays" class="overflow-hidden rounded-lg ring-1 ring-black ring-opacity-5"> | ||
<div class="flex justify-between gap-4"> | ||
<% if @regional_holidays.any? %> | ||
<%= render 'regional_holidays_table', regional_holidays: @regional_holidays %> | ||
<% else %> | ||
<h3 class="text-xs font-semibold text-left uppercase dark:text-gray-400"> | ||
<%= t('regional_holidays.empty') %> | ||
</h3> | ||
<% end %> | ||
<div id="filters_sidebar_section"> | ||
<%= render 'regional_holidays_filters' %> | ||
</div> | ||
<div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
spec/controllers/new_admin/regional_holidays_controller_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'rails_helper' | ||
|
||
RSpec.describe NewAdmin::RegionalHolidaysController do | ||
describe 'GET #index' do | ||
let!(:new_york) { create(:city, name: 'New York') } | ||
let!(:los_angeles) { create(:city, name: 'Los Angeles') } | ||
let!(:miami) { create(:city, name: 'Miami') } | ||
let!(:chicago) { create(:city, name: 'Chicago') } | ||
let!(:fresno) { create(:city, name: 'San Diego') } | ||
|
||
let!(:new_york_holiday) do | ||
create(:regional_holiday, cities: [new_york], day: 4, month: 7, name: 'Independence Day') | ||
end | ||
let!(:la_holiday) do | ||
create(:regional_holiday, cities: [los_angeles], day: 1, month: 1, name: 'New Year') | ||
end | ||
let!(:miami_holiday) do | ||
create(:regional_holiday, cities: [miami], day: 25, month: 12, name: 'Christmas') | ||
end | ||
let!(:chicago_holiday) do | ||
create(:regional_holiday, cities: [chicago], month: 11, name: 'Thanksgiving Day') | ||
end | ||
|
||
it 'renders the index template' do | ||
get :index | ||
|
||
expect(response).to render_template(:index) | ||
end | ||
|
||
it 'assigns all cities with holidays to @cities_with_holidays' do | ||
get :index | ||
|
||
expect(assigns(:cities_with_holidays)).to contain_exactly(new_york, los_angeles, miami, chicago) | ||
end | ||
|
||
context 'when no filter options are provided' do | ||
it 'assigns all regional holidays correctly' do | ||
get :index | ||
|
||
expect(assigns(:regional_holidays)).to contain_exactly(new_york_holiday, la_holiday, miami_holiday, chicago_holiday) | ||
end | ||
end | ||
|
||
context 'when using regional_holiday_id option' do | ||
it 'returns the specified regional holiday' do | ||
get :index, params: { regional_holiday_id: new_york_holiday.id } | ||
|
||
expect(assigns(:regional_holidays)).to contain_exactly(new_york_holiday) | ||
end | ||
|
||
it 'returns empty list when the provided regional holiday id does not exist' do | ||
get :index, params: { regional_holiday_id: -1 } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
end | ||
|
||
context 'when using city_ids option' do | ||
it 'returns regional holidays from the specified cities' do | ||
get :index, params: { city_ids: [miami.id, los_angeles.id] } | ||
|
||
expect(assigns(:regional_holidays)).to contain_exactly(miami_holiday, la_holiday) | ||
end | ||
|
||
it 'returns empty list when the provided cities do not have any regional holiday' do | ||
get :index, params: { city_ids: [fresno.id] } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
end | ||
|
||
context 'when using month option' do | ||
it 'returns all regional holidays from the specified month' do | ||
get :index, params: { month: 12 } | ||
|
||
expect(assigns(:regional_holidays)).to contain_exactly(miami_holiday) | ||
end | ||
|
||
it 'returns empty list when the month does not have any regional holiday' do | ||
get :index, params: { month: 13 } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
end | ||
|
||
context 'when using multiple options' do | ||
it 'returns regional holidays matching all options' do | ||
get :index, params: { city_ids: [new_york.id], month: 7 } | ||
|
||
expect(assigns(:regional_holidays)).to contain_exactly(new_york_holiday) | ||
end | ||
|
||
it 'returns empty list when no regional holidays match all filter options' do | ||
get :index, params: { city_ids: [los_angeles.id], month: 7 } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
end | ||
|
||
context 'when using invalid option values' do | ||
it 'returns empty list for invalid regional_holiday_id' do | ||
get :index, params: { regional_holiday_id: 'invalid_id' } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
|
||
it 'returns empty list for invalid month' do | ||
get :index, params: { month: 'invalid_month' } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
|
||
it 'returns empty list for invalid city_ids' do | ||
get :index, params: { city_ids: ['invalid_city_id'] } | ||
|
||
expect(assigns(:regional_holidays)).to be_empty | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.