{# The shared shape a plan is drawn from. Imported by each board/plan/_.html.twig, so the per-type partials carry geometry only and free/taken/yours looks identical everywhere. Clicking always opens a modal: the create modal when free, the edit modal when it is yours (which is where changing the times and releasing live). Nothing else is clickable, so the SVG carries no confirm dialogs or inline CSRF tokens. #} {% macro spot(resource, geometry, width, height, bookings, selected_date, is_past, time_params) %} {% set own = bookings|filter(b => b.user.id == app.user.id)|first|default(null) %} {% set mine = own is not null %} {% if mine %} {% set fill = 'fill-primary' %}{% set stroke = 'stroke-primary-dark' %}{% set text = 'fill-white' %} {% elseif bookings is not empty %} {% set fill = 'fill-gray-200' %}{% set stroke = 'stroke-gray-400' %}{% set text = 'fill-gray-600' %} {% else %} {% set fill = 'fill-emerald-50' %}{% set stroke = 'stroke-emerald-500' %}{% set text = 'fill-emerald-900' %} {% endif %} {% set interactive = not is_past and (mine or bookings is empty) %} {# Several bookings can overlap the board's span once part-day bookings exist, so the shape counts them and the tooltip spells them out. #} {% if mine %} {% set caption = own.timeRange.allDay ? 'du' : 'du ' ~ own.timeRange %} {% elseif bookings|length > 1 %} {% set caption = bookings|length ~ ' Buchungen' %} {% elseif bookings is not empty %} {% set caption = bookings|first.user.name %} {% else %} {% set caption = null %} {% endif %} ; closing it is Stimulus, not htmx. #} hx-get="{{ path('app_booking_new', { id: resource.id, date: selected_date|date('Y-m-d') }|merge(time_params)) }}" hx-target="body" hx-swap="beforeend" {%- endif %}> {{- resource.label }} {%- if bookings is empty %} — frei {%- else %} {%- for booking in bookings %} — {{ booking.user.id == app.user.id ? 'du' : booking.user.name }} {{ booking.timeRange }}{% endfor %} {%- endif -%} {{ resource.label }} {% if caption %} {{ caption }} {% endif %} {% endmacro %}