* feat: Show functional name in str(Room) * feat: Show func name in edit_timeslots.html * test: Update test_location_options
243 lines
13 KiB
HTML
243 lines
13 KiB
HTML
{% extends "base.html" %}
|
|
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
|
{% load origin %}
|
|
{% load agenda_custom_tags misc_filters static %}
|
|
{% block title %}IETF {{ meeting.number }} Meeting Agenda: Timeslots and Room Availability{% endblock %}
|
|
{% block morecss %}
|
|
{% comment %}
|
|
FIXME: These should move to an SCSS file that imports the relevant Bootstrap5 definitions.
|
|
Put scrollbars on the editor table. Requires fixed height so the scroll bars appear on the div, not the page body.
|
|
Note that 100vh is viewport height. Using that minus 25rem seems to leave space for the page header/footer.
|
|
{% endcomment %}
|
|
.timeslot-edit { overflow: auto; height: max(30rem, calc(100vh - 25rem));}
|
|
.tstable { width: 100%; border-collapse: separate; } {# "separate" to ensure sticky cells keep their borders #}
|
|
.tstable thead { position: sticky; top: 0; z-index: 3; background-color: white;}
|
|
.tstable th:first-child, .tstable td:first-child {
|
|
background-color: white; {# needs to match the lighter of the striped-table colors! #}
|
|
position: sticky;
|
|
left: 0;
|
|
z-index: 2; {# render above other cells / borders but below thead (z-index 3, above) #}
|
|
}
|
|
.tstable tbody > tr:nth-of-type(odd) > th:first-child {
|
|
background-color: rgb(249, 249, 249); {# needs to match the darker of the striped-table colors! #}
|
|
}
|
|
.tstable th { white-space: nowrap;}
|
|
.tstable td { white-space: nowrap;}
|
|
.capacity { font-size:80%; font-weight: normal;}
|
|
a.new-timeslot-link { color: lightgray; font-size: large;}
|
|
{% endblock %}
|
|
{% block content %}
|
|
{% origin %}
|
|
<h1>
|
|
IETF {{ meeting.number }} Meeting Agenda
|
|
<br>
|
|
<small class="text-body-secondary">Timeslots and Room Availability</small>
|
|
</h1>
|
|
<div class="my-3">
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.meeting.views.create_timeslot" num=meeting.number %}{% if "sched" in request.GET %}?sched={{ request.GET.sched }}{% endif %}">
|
|
New timeslot
|
|
</a>
|
|
{% if meeting.schedule %}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=meeting.schedule.name %}">
|
|
Edit rooms
|
|
</a>
|
|
{% else %}
|
|
{# secr app room view requires a schedule - show something for now (should try to avoid this possibility) #}
|
|
<span title="Must create meeting schedule to edit rooms">Edit rooms</span>
|
|
{% endif %}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.meeting.views.list_schedules" num=meeting.number %}">
|
|
Agenda list
|
|
</a>
|
|
{% if schedule_edit_url %}
|
|
<a class="btn btn-secondary" href="{{ schedule_edit_url }}">Back to agenda</a>
|
|
{% endif %}
|
|
</div>
|
|
<div class="timeslot-edit">
|
|
{% if rooms|length == 0 %}
|
|
<p class="alert alert-info my-3">
|
|
No rooms exist for this meeting yet.
|
|
</p>
|
|
{% if meeting.schedule %}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.secr.meetings.views.rooms" meeting_id=meeting.number schedule_name=meeting.schedule.name %}">
|
|
Create rooms
|
|
</a>
|
|
{% else %}
|
|
{# provide as helpful a link we can if we don't have an official schedule #}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.secr.meetings.views.view" meeting_id=meeting.number %}">
|
|
Create rooms through the secr app
|
|
</a>
|
|
{% endif %}
|
|
{% else %}
|
|
<table id="timeslot-table" class="tstable table table-striped table-sm">
|
|
{% with have_no_timeslots=time_slices|length_is:0 %}
|
|
<thead>
|
|
<tr>
|
|
{% if have_no_timeslots %}
|
|
<th scope="col"></th>
|
|
<th scope="col"></th>
|
|
{% else %}
|
|
<th scope="col"></th>
|
|
{% for day in time_slices %}
|
|
<th scope="col" class="day-label" colspan="{{ date_slices|colWidth:day }}">
|
|
{{ day|date:'D' }} ({{ day }})
|
|
<i class="bi bi-trash delete-button"
|
|
title="Delete all on this day"
|
|
data-delete-scope="day"
|
|
data-date-id="{{ day.isoformat }}">
|
|
</i>
|
|
</th>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</tr>
|
|
<tr>
|
|
{% if have_no_timeslots %}
|
|
<th scope="col"></th>
|
|
<th scope="col"></th>
|
|
{% else %}
|
|
<th scope="col"></th>
|
|
{% for day in time_slices %}
|
|
{% for slot in slot_slices|lookup:day %}
|
|
<th scope="col" class="time-label">
|
|
{{ slot.time|date:'H:i' }}-{{ slot.end_time|date:'H:i' }}
|
|
<i class="bi bi-trash delete-button"
|
|
data-delete-scope="column"
|
|
data-date-id="{{ day.isoformat }}"
|
|
data-col-id="{{ day.isoformat }}T{{ slot.time|date:'H:i' }}-{{ slot.end_time|date:'H:i' }}"
|
|
title="Delete all in this column">
|
|
</i>
|
|
</th>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for room in rooms %}
|
|
<tr>
|
|
<th scope="row">
|
|
<span class="room-heading">{{ room.name }}
|
|
{% if room.functional_name and room.name != room.functional_name %} - {{ room.functional_name }}{% endif %}
|
|
{% if room.capacity %}<span class="capacity">({{ room.capacity }})</span>{% endif %}
|
|
</span>
|
|
</th>
|
|
{% if have_no_timeslots and forloop.first %}
|
|
<td rowspan="{{ rooms|length }}">
|
|
<p>
|
|
No timeslots exist for this meeting yet.
|
|
</p>
|
|
<a href="{% url "ietf.meeting.views.create_timeslot" num=meeting.number %}{% if "sched" in request.GET %}?sched={{ request.GET.sched }}{% endif %}">
|
|
Create a timeslot.
|
|
</a>
|
|
</td>
|
|
{% else %}
|
|
{% for day in time_slices %}
|
|
{% with slots=slot_slices|lookup:day %}
|
|
{% for slice in date_slices|lookup:day %}
|
|
{% with cell_ts=ts_list.popleft slot=slots|index:forloop.counter0 %}
|
|
<!-- [html-validate-disable-block no-dup-class -- FIXME: loop below generates duplicate classes] -->
|
|
<td class="tscell {% if cell_ts|length > 1 %}timeslot-collision{% endif %}{% for ts in cell_ts %} tstype_{{ ts.type.slug }}{% endfor %}">
|
|
{% if cell_ts %}
|
|
{% for ts in cell_ts %}
|
|
{% include 'meeting/timeslot_edit_timeslot.html' with ts=ts in_use=ts_with_any_assignments in_official_use=ts_with_official_assignments request=request only %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
<a class="new-timeslot-link text-reset text-decoration-none {% if cell_ts %}hidden{% endif %}" aria-label="+"
|
|
href="{% url 'ietf.meeting.views.create_timeslot' num=meeting.number %}?day={{ day.toordinal }}&date={{ day|date:'Y-m-d' }}&location={{ room.pk }}&time={{ slot.time|date:'H:i' }}&duration={{ slot.duration }}{% if "sched" in request.GET %}&sched={{ request.GET.sched }}{% endif %}">
|
|
<i class="bi bi-plus-square"></i>
|
|
</a>
|
|
</td>
|
|
{% endwith %}
|
|
{% endfor %}
|
|
{% endwith %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
{% endwith %}
|
|
</table>
|
|
{% endif %}
|
|
{# Modal to confirm timeslot deletion #}
|
|
<div id="delete-modal" class="modal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<p class="h5 modal-title text-danger">Confirm Delete</p>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>
|
|
<span class="ts-singular">The following timeslot</span>
|
|
<span class="ts-plural"><span class="ts-count"></span> timeslots</span>
|
|
will be deleted:
|
|
</p>
|
|
<dl class="dl-horizontal">
|
|
<dt>
|
|
Name
|
|
</dt>
|
|
<dd>
|
|
<span class="ts-name"></span>
|
|
</dd>
|
|
<dt>
|
|
Date
|
|
</dt>
|
|
<dd>
|
|
<span class="ts-date"></span>
|
|
</dd>
|
|
<dt>
|
|
Time
|
|
</dt>
|
|
<dd>
|
|
<span class="ts-time"></span>
|
|
</dd>
|
|
<dt>
|
|
Location
|
|
</dt>
|
|
<dd>
|
|
<span class="ts-location"></span>
|
|
</dd>
|
|
</dl>
|
|
<p class="unofficial-use-warning">
|
|
The official schedule will not be affected, but sessions in
|
|
unofficial schedules currently assigned to
|
|
<span class="ts-singular">this timeslot</span>
|
|
<span class="ts-plural">any of these timeslots</span>
|
|
will become unassigned.
|
|
</p>
|
|
<p class="official-use-warning">
|
|
The official schedule will be affected.
|
|
Sessions currently assigned to
|
|
<span class="ts-singular">this timeslot</span>
|
|
<span class="ts-plural">any of these timeslots</span>
|
|
will become unassigned.
|
|
</p>
|
|
<p>
|
|
<span class="text-danger ts-singular">Are you sure you want to delete this timeslot?</span>
|
|
<span class="text-danger ts-plural">Are you sure you want to delete these <span class="ts-count"></span> timeslots?</span>
|
|
</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
Cancel
|
|
</button>
|
|
<button type="button" id="confirm-delete-button" class="btn btn-danger">
|
|
Delete
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
{% block js %}
|
|
<script src="{% static "ietf/js/timeslot_edit.js" %}">
|
|
</script>
|
|
{% endblock %} |