From 29b92475bb3fc4ba639f51acd608cf10cfa8a9db Mon Sep 17 00:00:00 2001 From: Du Peng Date: Mon, 2 Jan 2023 19:20:02 +0100 Subject: [PATCH] (feat) Ability to filter uniq slots reserved in admin calendar --- app/controllers/api/availabilities_controller.rb | 13 +++++++++++-- .../src/javascript/controllers/admin/calendar.js | 12 ++++++++---- .../src/javascript/controllers/calendar.js | 4 +++- app/frontend/templates/calendar/filter.html | 14 ++++++++++++++ app/models/availability.rb | 7 ++++++- app/models/slot.rb | 8 ++++++++ config/locales/app.shared.en.yml | 1 + config/locales/app.shared.fr.yml | 1 + test/models/availability_test.rb | 8 ++++++++ 9 files changed, 60 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/availabilities_controller.rb b/app/controllers/api/availabilities_controller.rb index 73f890e30..c059fe0dc 100644 --- a/app/controllers/api/availabilities_controller.rb +++ b/app/controllers/api/availabilities_controller.rb @@ -163,10 +163,19 @@ class API::AvailabilitiesController < API::ApiController end def filter_availabilites(availabilities) - availabilities.delete_if(&method(:remove_full?)) + availabilities_filterd = availabilities + availabilities_filterd = availabilities.delete_if(&method(:remove_full?)) if params[:dispo] == 'false' + + availabilities_filterd = availabilities.delete_if(&method(:remove_empty?)) if params[:reserved] == 'true' + + availabilities_filterd end def remove_full?(availability) - params[:dispo] == 'false' && (availability.is_reserved || (availability.try(:full?) && availability.full?)) + availability.try(:full?) && availability.full? + end + + def remove_empty?(availability) + availability.try(:empty?) && availability.empty? end end diff --git a/app/frontend/src/javascript/controllers/admin/calendar.js b/app/frontend/src/javascript/controllers/admin/calendar.js index 36565d417..cb290a790 100644 --- a/app/frontend/src/javascript/controllers/admin/calendar.js +++ b/app/frontend/src/javascript/controllers/admin/calendar.js @@ -376,7 +376,8 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state machines: isSelectAll('machines', scope), spaces: isSelectAll('spaces', scope), evt: filter.evt, - dispo: filter.dispo + dispo: filter.dispo, + reserved: filter.reserved }); scope.machinesGroupByCategory.forEach(c => c.checked = _.every(c.machines, 'checked')); // remove all @@ -395,7 +396,8 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state machines: isSelectAll('machines', $scope), spaces: isSelectAll('spaces', $scope), evt: true, - dispo: true + dispo: true, + reserved: false }; // toggle to select all formation/machine @@ -444,7 +446,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state return $scope.filterAvailabilities; } }, - controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'machinesGroupByCategory', 'spaces', 'filter', 'toggleFilter', 'filterAvailabilities', function ($scope, $uibModalInstance, trainings, machines, machinesGroupByCategory, spaces, filter, toggleFilter, filterAvailabilities) { + controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'machinesGroupByCategory', 'spaces', 'filter', 'toggleFilter', 'filterAvailabilities', 'AuthService', function ($scope, $uibModalInstance, trainings, machines, machinesGroupByCategory, spaces, filter, toggleFilter, filterAvailabilities, AuthService) { $scope.trainings = trainings; $scope.machines = machines; $scope.machinesGroupByCategory = machinesGroupByCategory; @@ -464,6 +466,8 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state $scope.filterAvailabilities = filter => filterAvailabilities(filter, $scope); + $scope.isAuthorized = AuthService.isAuthorized; + return $scope.close = function (e) { $uibModalInstance.dismiss(); return e.stopPropagation(); @@ -476,7 +480,7 @@ Application.Controllers.controller('AdminCalendarController', ['$scope', '$state const t = $scope.trainings.filter(t => t.checked).map(t => t.id); const m = $scope.machines.filter(m => m.checked).map(m => m.id); const s = $scope.spaces.filter(s => s.checked).map(s => s.id); - return { t, m, s, evt: $scope.filter.evt, dispo: $scope.filter.dispo }; + return { t, m, s, evt: $scope.filter.evt, dispo: $scope.filter.dispo, reserved: $scope.filter.reserved }; }; const availabilitySourceUrl = () => `/api/availabilities?${$.param(getFilter())}`; diff --git a/app/frontend/src/javascript/controllers/calendar.js b/app/frontend/src/javascript/controllers/calendar.js index 743da2999..78933ec11 100644 --- a/app/frontend/src/javascript/controllers/calendar.js +++ b/app/frontend/src/javascript/controllers/calendar.js @@ -159,7 +159,7 @@ Application.Controllers.controller('CalendarController', ['$scope', '$state', '$ return $scope.filterAvailabilities; } }, - controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'machinesGroupByCategory', 'spaces', 'externals', 'filter', 'toggleFilter', 'filterAvailabilities', function ($scope, $uibModalInstance, trainings, machines, machinesGroupByCategory, spaces, externals, filter, toggleFilter, filterAvailabilities) { + controller: ['$scope', '$uibModalInstance', 'trainings', 'machines', 'machinesGroupByCategory', 'spaces', 'externals', 'filter', 'toggleFilter', 'filterAvailabilities', 'AuthService', function ($scope, $uibModalInstance, trainings, machines, machinesGroupByCategory, spaces, externals, filter, toggleFilter, filterAvailabilities, AuthService) { $scope.trainings = trainings; $scope.machines = machines; $scope.machinesGroupByCategory = machinesGroupByCategory; @@ -180,6 +180,8 @@ Application.Controllers.controller('CalendarController', ['$scope', '$state', '$ $scope.filterAvailabilities = filter => filterAvailabilities(filter, $scope); + $scope.isAuthorized = AuthService.isAuthorized; + return $scope.close = function (e) { $uibModalInstance.dismiss(); return e.stopPropagation(); diff --git a/app/frontend/templates/calendar/filter.html b/app/frontend/templates/calendar/filter.html index a88ffd769..61253b790 100644 --- a/app/frontend/templates/calendar/filter.html +++ b/app/frontend/templates/calendar/filter.html @@ -1,3 +1,17 @@ +
+

{{ 'app.shared.calendar.show_reserved_uniq' }}

+
+ +
+

{{ 'app.shared.calendar.show_unavailables' }}

diff --git a/app/models/availability.rb b/app/models/availability.rb index 29ca94313..addc96f7d 100644 --- a/app/models/availability.rb +++ b/app/models/availability.rb @@ -115,7 +115,7 @@ class Availability < ApplicationRecord # check if the reservations are complete? # if a nb_total_places hasn't been defined, then places are unlimited def full? - return false if nb_total_places.blank? + return false if nb_total_places.blank? && available_type != 'machines' if available_type == 'event' event.nb_free_places.zero? @@ -124,6 +124,11 @@ class Availability < ApplicationRecord end end + # check availability don't have any reservation + def empty? + slots.map(&:empty?).reduce(:&) + end + def available_places_per_slot(reservable = nil) case available_type when 'training' diff --git a/app/models/slot.rb b/app/models/slot.rb index 7cce52b6a..f6fc13178 100644 --- a/app/models/slot.rb +++ b/app/models/slot.rb @@ -23,6 +23,14 @@ class Slot < ApplicationRecord end end + def empty?(reservable = nil) + if reservable.nil? + slots_reservations.where(canceled_at: nil).count.zero? + else + slots_reservations.includes(:reservation).where(canceled_at: nil).where('reservations.reservable': reservable).count.zero? + end + end + def duration (end_at - start_at).seconds end diff --git a/config/locales/app.shared.en.yml b/config/locales/app.shared.en.yml index c923aa750..d784640b0 100644 --- a/config/locales/app.shared.en.yml +++ b/config/locales/app.shared.en.yml @@ -536,5 +536,6 @@ en: spaces: "Spaces" events: "Events" externals: "Other calendars" + show_reserved_uniq: "Show reserved slots only" machine: machine_uncategorized: "Uncategorized machines" diff --git a/config/locales/app.shared.fr.yml b/config/locales/app.shared.fr.yml index e7d3d0bdb..8b950558e 100644 --- a/config/locales/app.shared.fr.yml +++ b/config/locales/app.shared.fr.yml @@ -536,5 +536,6 @@ fr: spaces: "Espaces" events: "Événements" externals: "Autres calendriers" + show_reserved_uniq: "Voir les créneaux réservés uniquement" machine: machine_uncategorized: "Machines non classés" diff --git a/test/models/availability_test.rb b/test/models/availability_test.rb index 3d2b07c65..ab264e0f5 100644 --- a/test/models/availability_test.rb +++ b/test/models/availability_test.rb @@ -15,4 +15,12 @@ class AvailabilityTest < ActiveSupport::TestCase assert a.invalid? assert a.errors.key?(:machine_ids) end + + test 'return empty = true if availability dont have any reservation' do + not_reserved = Availability.find(1) + assert not_reserved.empty? + + reserved = Availability.find(13) + assert_not reserved.empty? + end end