Files
redmine_qbo_calendar/app/views/common/_calendar.html.erb
T

156 lines
4.8 KiB
ERB

<%
# Get Redmine's configured non-working week days (e.g., ["6", "7"] for Sat/Sun)
non_working_days = Setting.non_working_week_days || []
# Safely collect all unique CustomerAppointments across the entire calendar date range
all_appointments = (calendar.startdt..calendar.enddt).flat_map { |date|
calendar.events_on(date)
}.select { |e| e.is_a?(CustomerAppointment) }.uniq
# Lambda to determine if an appointment should render on a specific calendar day
appointment_occurs_on = lambda do |appointment, current_day|
return false if appointment.start_date.nil?
start_date = appointment.start_date.to_date
target_date = current_day.to_date
return false if target_date < start_date
# Skip rendering on Redmine non-working days
return false if non_working_days.include?(target_date.cwday.to_s)
duration = [appointment.duration.to_i, 1].max
date_cursor = start_date
working_days_count = 0
while date_cursor <= target_date
unless non_working_days.include?(date_cursor.cwday.to_s)
working_days_count += 1
end
if date_cursor == target_date
return working_days_count <= duration
end
date_cursor += 1 # Pure Ruby Date increment stays a Date object
end
false
end
%>
<%= form_tag({}, data: { cm_url: issues_context_menu_path }) do %>
<%= hidden_field_tag 'back_url', url_for(params: request.query_parameters), id: nil %>
<ul class="cal">
<li scope="col" title="<%= l(:label_week) %>" class="calhead week-number"></li>
<% 7.times do |i| %>
<li scope="col" class="calhead">
<%= day_name((calendar.first_wday + i) % 7) %>
</li>
<% end %>
<% calendar.format_month.each_slice(7) do |week| %>
<li class="week-number">
<span class="label-week"><%= l(:label_week) %></span>
<%= calendar.week_number(week.first) %>
</li>
<% week.each do |day| %>
<li class="<%= calendar.day_css_classes(day) %> calbody">
<p class="day-num">
<span class="day-value"><%= day.day %></span>
<span class="abbr-day">(<%= abbr_day_name(day.cwday) %>)</span>
<%= link_to sprite_icon('add'),
new_customer_appointment_path(start_date: day),
class: 'icon-only icon-add',
title: l(:label_appointment_new, default: 'New Appointment') %>
</p>
<%
# Non-appointment events (Issues, Versions, etc.)
standard_events = calendar.events_on(day).reject { |e| e.is_a?(CustomerAppointment) }
# Appointments matching duration on this working day
matching_appointments = all_appointments.select { |app| appointment_occurs_on.call(app, day) }
%>
<% (standard_events + matching_appointments).each do |event| %>
<% if event.is_a?(Issue) %>
<% starting = (day == event.start_date) %>
<% ending = (day == event.due_date) %>
<%= tag.div class: [
event.css_classes,
'tooltip',
'hascontextmenu',
('starting' if starting),
('ending' if ending)
].compact do %>
<%= "#{event.project} -" unless @project && @project == event.project %>
<%= sprite_icon('bullet-go', rtl: true) if starting && !ending %>
<%= sprite_icon('bullet-end', rtl: true) if ending && !starting %>
<%= sprite_icon('bullet-go-end') if starting && ending %>
<%= link_to_issue(event, truncate: 30) %>
<span class="tip">
<%= render_issue_tooltip(event) %>
</span>
<%= check_box_tag 'ids[]',
event.id,
false,
style: 'display:none;',
id: nil %>
<% end %>
<% elsif event.is_a?(Version) %>
<span class="icon icon-package">
<%= sprite_icon 'package' %>
<%= "#{event.project} -" unless @project && @project == event.project %>
<%= link_to_version(event) %>
</span>
<% elsif event.is_a?(CustomerAppointment) %>
<%= render partial: 'customer_appointments/calendar_event',
locals: {
appointment: event,
day: day,
project: @project
} %>
<% else %>
<% Rails.logger.warn("Unknown calendar event: #{event.class}") %>
<% end %>
<% end %>
</li>
<% end %>
<% end %>
</ul>
<% end %>
<%= context_menu %>