From 1ab0f725012e8aa3c15d22ba27c5f706021efaab Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Wed, 7 Oct 2026 13:06:37 +0900 Subject: [PATCH 3/4] Show the names of non-working dates in the calendar Non-working dates are grayed out in the calendar, but users other than administrators had no way to find out why a given day was non-working. The name given to a non-working date is now displayed next to the day number in the calendar. A name that does not fit in the cell is truncated, and the full name is available as a tooltip. Co-Authored-By: Claude Opus 5.5 --- app/assets/stylesheets/application.css | 13 +++++++++++++ app/assets/stylesheets/responsive.css | 6 ++++++ app/models/non_working_date.rb | 19 ++++++++++++------- app/views/common/_calendar.html.erb | 3 +++ lib/redmine/utils/date_calculation.rb | 2 +- test/functional/calendars_controller_test.rb | 7 +++++-- 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 88b6afc7c..6f4961f0d 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1695,6 +1695,19 @@ ul.cal { height: 1.5em; } .cal .calbody .abbr-day {display:none} +.cal .calbody .non-working-date-name { + float: inline-start; + /* Take the space left by the day number without widening the column */ + inline-size: 0; + min-inline-size: calc(100% - 2.5em); + overflow: hidden; + font-size: 0.8em; + line-height: 1.875; + color: var(--oc-gray-6); + text-align: start; + text-overflow: ellipsis; + white-space: nowrap; +} .cal .calbody.this-month {background-color:var(--oc-white);} .cal .calbody.other-month {background-color:var(--oc-gray-1);} .cal .calbody.other-month p.day-num {color: var(--oc-gray-5);} diff --git a/app/assets/stylesheets/responsive.css b/app/assets/stylesheets/responsive.css index baa3854e3..258998919 100644 --- a/app/assets/stylesheets/responsive.css +++ b/app/assets/stylesheets/responsive.css @@ -829,6 +829,12 @@ display: inline; } + .cal .calbody .non-working-date-name { + float: none; + margin-inline-start: 0.5em; + white-space: normal; + } + .cal .week-number { border: 1px solid var(--oc-gray-4); text-align: start; diff --git a/app/models/non_working_date.rb b/app/models/non_working_date.rb index 79ee918ee..35c91271c 100644 --- a/app/models/non_working_date.rb +++ b/app/models/non_working_date.rb @@ -21,7 +21,7 @@ class NonWorkingDate < ApplicationRecord include Redmine::SafeAttributes class Current < ActiveSupport::CurrentAttributes - attribute :sorted_dates, :dates + attribute :names_by_date, :sorted_dates end after_save {self.class.clear_dates_cache} @@ -38,16 +38,21 @@ class NonWorkingDate < ApplicationRecord safe_attributes 'date', 'name' - # Returns the registered dates as a sorted Array. + # Returns a Hash of the registered dates and their names, ordered by date. # The result is cached for the duration of the current request. - def self.sorted_dates - Current.sorted_dates ||= order(:date).pluck(:date) + def self.names_by_date + Current.names_by_date ||= order(:date).pluck(:date, :name).to_h + end + + # Returns the name registered for the given date + def self.name_for(date) + names_by_date[date].presence end - # Returns the registered dates as a Set. + # Returns the registered dates as a sorted Array. # The result is cached for the duration of the current request. - def self.dates - Current.dates ||= sorted_dates.to_set + def self.sorted_dates + Current.sorted_dates ||= names_by_date.keys end def self.clear_dates_cache diff --git a/app/views/common/_calendar.html.erb b/app/views/common/_calendar.html.erb index 4ff2d0339..0c2f567b9 100644 --- a/app/views/common/_calendar.html.erb +++ b/app/views/common/_calendar.html.erb @@ -14,6 +14,9 @@

<%= day.day %> (<%= abbr_day_name(day.cwday) %>) + <% if (name = NonWorkingDate.name_for(day)) %> + <%= name %> + <% end %>

<% calendar.events_on(day).each do |i| %> <% if i.is_a? Issue %> diff --git a/lib/redmine/utils/date_calculation.rb b/lib/redmine/utils/date_calculation.rb index 4c375e7ae..89c0b843a 100644 --- a/lib/redmine/utils/date_calculation.rb +++ b/lib/redmine/utils/date_calculation.rb @@ -64,7 +64,7 @@ module Redmine # Returns true if the given date is a non working day def non_working_day?(date) - non_working_week_days.include?(date.cwday) || NonWorkingDate.dates.include?(date) + non_working_week_days.include?(date.cwday) || NonWorkingDate.names_by_date.key?(date) end # Adds working days to the given date, diff --git a/test/functional/calendars_controller_test.rb b/test/functional/calendars_controller_test.rb index 38560ad02..780f154db 100644 --- a/test/functional/calendars_controller_test.rb +++ b/test/functional/calendars_controller_test.rb @@ -279,7 +279,7 @@ class CalendarsControllerTest < Redmine::ControllerTest end def test_show_calendar_should_mark_non_working_dates - NonWorkingDate.create!(:date => '2016-12-29') + NonWorkingDate.create!(:date => '2016-12-29', :name => 'Year-end Shutdown') get( :show, :params => { @@ -290,6 +290,9 @@ class CalendarsControllerTest < Redmine::ControllerTest assert_response :success assert_select 'li.nwday', 11 - assert_select 'li.nwday', :text => /^29/ + assert_select 'li.nwday', :text => /^29/ do + assert_select 'span.non-working-date-name', :text => 'Year-end Shutdown' + end + assert_select 'span.non-working-date-name', 1 end end -- 2.55.0