From e7ddcd30570c24c6d69771bc26b76d3d1d939580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Fri, 10 Jan 2025 09:34:22 +0100 Subject: [PATCH 1/5] =?UTF-8?q?Utiliser=20deux=20selects=20pour=20s=C3=A9l?= =?UTF-8?q?ectionner=20l'heure=20de=20d=C3=A9but=20(plages=20et=20indispon?= =?UTF-8?q?ibilit=C3=A9s)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/common/_recurrence.html.slim | 4 ++-- config/initializers/tod.rb | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 config/initializers/tod.rb diff --git a/app/views/common/_recurrence.html.slim b/app/views/common/_recurrence.html.slim index 07dd4caca2..f5c1406d5f 100644 --- a/app/views/common/_recurrence.html.slim +++ b/app/views/common/_recurrence.html.slim @@ -7,8 +7,8 @@ = date_input(f, :end_day) .row - .col = f.input :start_time, as: :select, collection: every_5_minutes_of_the_day, selected: model.start_time&.strftime("%H:%M"), include_blank: false - .col = f.input :end_time, as: :select, collection: every_5_minutes_of_the_day, selected: model.end_time&.strftime("%H:%M"), include_blank: false + .col = f.input :start_time, as: :time, ignore_date: true, minute_step: 5 + .col = f.input :end_time, as: :time, ignore_date: true, minute_step: 5 = f.input :recurrence, as: :hidden, input_html: { value: model.recurrence ? model.recurrence.as_json.to_json : "", "data-target": "recurrence.recurrenceComputed", class: "js-recurrence-computed" } diff --git a/config/initializers/tod.rb b/config/initializers/tod.rb new file mode 100644 index 0000000000..b43f61cd15 --- /dev/null +++ b/config/initializers/tod.rb @@ -0,0 +1,13 @@ +module TodNilFix + def initialize(h, m = 0, s = 0) # rubocop:disable Naming/MethodParameterName + # En utilisant les helpers de formulaire Rails pour choisir heure et minute, + # la valeur passée pour les secondes est alors `nil` et ce constructeur crashe. + # On évite ici le crash en permettant au constructeur de recevoir des valeurs `nil`. + m ||= 0 + s ||= 0 + + super + end +end + +Tod::TimeOfDay.prepend(TodNilFix) From 0df34f2c777aee5a9a8bf0e5af8d9fadd959cd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Tue, 14 Jan 2025 12:39:57 +0100 Subject: [PATCH 2/5] Use Tod::TimeOfDayType (type registered by gem) --- Gemfile | 2 +- Gemfile.lock | 4 ++-- app/models/concerns/recurrence_concern.rb | 12 ++++++------ config/initializers/tod.rb | 13 ------------- 4 files changed, 9 insertions(+), 22 deletions(-) delete mode 100644 config/initializers/tod.rb diff --git a/Gemfile b/Gemfile index 5b2829a1d6..5667bd5c99 100644 --- a/Gemfile +++ b/Gemfile @@ -143,7 +143,7 @@ gem "rubyzip" # zip export files # Recurring events in Ruby gem "montrose" # Supplies TimeOfDay and Shift class -gem "tod", "~> 2.2" +gem "tod" # A ruby implementation of the iCalendar specification (RFC-5545). gem "icalendar", "~> 2.5" diff --git a/Gemfile.lock b/Gemfile.lock index e140fef294..c5bc5c9fe0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -663,7 +663,7 @@ GEM thread_safe (0.3.6) tilt (2.5.0) timeout (0.4.1) - tod (2.2.0) + tod (3.1.2) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) @@ -816,7 +816,7 @@ DEPENDENCIES sprockets-rails stackprof strong_migrations - tod (~> 2.2) + tod turbolinks (~> 5) typhoeus wannabe_bool diff --git a/app/models/concerns/recurrence_concern.rb b/app/models/concerns/recurrence_concern.rb index a3b81a95cb..13bf578e92 100644 --- a/app/models/concerns/recurrence_concern.rb +++ b/app/models/concerns/recurrence_concern.rb @@ -3,8 +3,8 @@ module RecurrenceConcern included do serialize :recurrence, coder: Montrose::Recurrence - serialize :start_time, coder: Tod::TimeOfDay - serialize :end_time, coder: Tod::TimeOfDay + attribute :start_time, :time_only # uses Tod::TimeOfDayType + attribute :end_time, :time_only # uses Tod::TimeOfDayType before_save :clear_empty_recurrence, :set_recurrence_ends_at @@ -22,8 +22,8 @@ module RecurrenceConcern class_methods do def serialize_for_active_job(record) manually_serialized_attrs = { - start_time: Tod::TimeOfDay.dump(record.start_time), - end_time: Tod::TimeOfDay.dump(record.end_time), + start_time: record.start_time.to_s, + end_time: record.end_time.to_s, recurrence: Montrose::Recurrence.dump(record.recurrence), } record.attributes.merge(manually_serialized_attrs.stringify_keys) @@ -32,8 +32,8 @@ def serialize_for_active_job(record) def deserialize_for_active_job(hash) hash = hash.symbolize_keys manually_deserialized_attrs = { - start_time: Tod::TimeOfDay.load(hash[:start_time]), - end_time: Tod::TimeOfDay.load(hash[:end_time]), + start_time: Tod::TimeOfDay.parse(hash[:start_time]), + end_time: Tod::TimeOfDay.parse(hash[:end_time]), recurrence: Montrose::Recurrence.load(hash[:recurrence]), } new(hash.merge(manually_deserialized_attrs)) diff --git a/config/initializers/tod.rb b/config/initializers/tod.rb deleted file mode 100644 index b43f61cd15..0000000000 --- a/config/initializers/tod.rb +++ /dev/null @@ -1,13 +0,0 @@ -module TodNilFix - def initialize(h, m = 0, s = 0) # rubocop:disable Naming/MethodParameterName - # En utilisant les helpers de formulaire Rails pour choisir heure et minute, - # la valeur passée pour les secondes est alors `nil` et ce constructeur crashe. - # On évite ici le crash en permettant au constructeur de recevoir des valeurs `nil`. - m ||= 0 - s ||= 0 - - super - end -end - -Tod::TimeOfDay.prepend(TodNilFix) From 83c14a2c287d546c2ea9e99079c28344db2c7dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Tue, 14 Jan 2025 12:57:34 +0100 Subject: [PATCH 3/5] Remove unused helper --- app/helpers/plage_ouvertures_helper.rb | 13 ------------- spec/helpers/plage_ouvertures_helper_spec.rb | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/app/helpers/plage_ouvertures_helper.rb b/app/helpers/plage_ouvertures_helper.rb index f9b7495746..694e591216 100644 --- a/app/helpers/plage_ouvertures_helper.rb +++ b/app/helpers/plage_ouvertures_helper.rb @@ -1,17 +1,4 @@ module PlageOuverturesHelper - # Generates ["00:00", "00:05", "00:10", ... "23:50", "23:55"] - EVERY_5_MINUTES_OF_THE_DAY = (0..23).flat_map do |h| - padded_h = format("%02i", h) - (0..55).step(5).map do |m| - padded_min = format("%02i", m) - "#{padded_h}:#{padded_min}" - end - end.freeze - - def every_5_minutes_of_the_day - EVERY_5_MINUTES_OF_THE_DAY - end - def display_recurrence(plage_ouverture) every_part = display_every(plage_ouverture) diff --git a/spec/helpers/plage_ouvertures_helper_spec.rb b/spec/helpers/plage_ouvertures_helper_spec.rb index 027ecd87c1..254217d248 100644 --- a/spec/helpers/plage_ouvertures_helper_spec.rb +++ b/spec/helpers/plage_ouvertures_helper_spec.rb @@ -5,16 +5,6 @@ travel_to(now) end - describe "#every_5_minutes_of_the_day" do - it "return 288 entries for all times of the day by 5 minutes increment" do - expect(every_5_minutes_of_the_day.count).to eq(288) - expect(every_5_minutes_of_the_day.first).to eq("00:00") - expect(every_5_minutes_of_the_day.last).to eq("23:55") - expect(every_5_minutes_of_the_day[12 * 18]).to eq("18:00") - expect(every_5_minutes_of_the_day[(12 * 18) + 5]).to eq("18:25") - end - end - describe "#display_recurrence" do it "with a weekly recurrence" do plage_ouverture = build(:plage_ouverture, recurrence: Montrose.every(:week)) From 40c7283b09c0c2fcf8b9556157b242ed60740fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Tue, 14 Jan 2025 16:02:40 +0100 Subject: [PATCH 4/5] =?UTF-8?q?Permettre=20d'observer=20la=20s=C3=A9rialis?= =?UTF-8?q?ation=20d'une=20recurrence=20montrose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/controllers/admin/absences_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/admin/absences_controller_spec.rb b/spec/controllers/admin/absences_controller_spec.rb index bd02234301..a2f3732e71 100644 --- a/spec/controllers/admin/absences_controller_spec.rb +++ b/spec/controllers/admin/absences_controller_spec.rb @@ -168,7 +168,7 @@ end describe "DELETE #destroy" do - let!(:absence) { create(:absence, agent_id: agent.id) } + let!(:absence) { create(:absence, :once_a_week, agent_id: agent.id) } it "destroys the requested absence" do expect do From 153351c251887f1fe138a3b3dde18316a0607e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Ferrandis?= Date: Tue, 14 Jan 2025 16:02:59 +0100 Subject: [PATCH 5/5] =?UTF-8?q?Ajouter=20une=20spec=20sur=20la=20s=C3=A9le?= =?UTF-8?q?ction=20d'horaire=20d'une=20plage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent_can_crud_plage_ouvertures_spec.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/features/agents/agent_can_crud_plage_ouvertures_spec.rb b/spec/features/agents/agent_can_crud_plage_ouvertures_spec.rb index 51b6c8dd16..d201a9f9a4 100644 --- a/spec/features/agents/agent_can_crud_plage_ouvertures_spec.rb +++ b/spec/features/agents/agent_can_crud_plage_ouvertures_spec.rb @@ -218,4 +218,22 @@ expect(PlageOuverture.last.motifs).to contain_exactly(motif_1_service_avocat, motif_2_service_avocat) end end + + describe "selecting a time range" do + it "works" do + visit new_admin_organisation_agent_plage_ouverture_path(organisation, agent) + check motif.name + select(lieu.full_name, from: "plage_ouverture_lieu_id") + + # Set start time at 10:30 + select "10", from: "plage_ouverture_start_time_4i" + select "30", from: "plage_ouverture_start_time_5i" + # Set start time at 13:45 + select "13", from: "plage_ouverture_end_time_4i" + select "45", from: "plage_ouverture_end_time_5i" + + expect { click_on "Créer la plage d'ouverture" }.to change(PlageOuverture, :count).by(1) + expect(PlageOuverture.last).to have_attributes(start_time: Tod::TimeOfDay.new(10, 30), end_time: Tod::TimeOfDay.new(13, 45)) + end + end end