424 lines
24 KiB
HTML
424 lines
24 KiB
HTML
{# bs5ok #}
|
|
{% extends "base.html" %}
|
|
{# Copyright The IETF Trust 2015-2020, All Rights Reserved #}
|
|
{% load origin %}
|
|
{% load static %}
|
|
{% load ietf_filters %}
|
|
{% block morecss %}
|
|
{# set the group colors with CSS here #}
|
|
{% for parent in session_parents %}
|
|
.parent-{{ parent.acronym }} { background-image: linear-gradient(to right, {{ parent.scheduling_color }} 0.4em, transparent 0.5em); }
|
|
.parent-{{ parent.acronym }}.hidden-parent { filter: blur(3px); }{# blur masks contents but keeps the parent color visible #}
|
|
.parent-{{ parent.acronym }}.selected { background-color: {{ parent.light_scheduling_color }}; }
|
|
.parent-{{ parent.acronym }}.other-session-selected { background-color: {{ parent.light_scheduling_color }}; }
|
|
{% endfor %}
|
|
{# style past sessions to indicate they are not editable #}
|
|
.edit-meeting-schedule .edit-grid .timeslot.past-hint { filter: brightness(0.9); }
|
|
.edit-meeting-schedule .past-flag { visibility: hidden; font-size: smaller; }
|
|
.edit-meeting-schedule .edit-grid .timeslot.past .past-flag { visibility: visible; color: #aaaaaa; }
|
|
{# style off-agenda sessions to indicate this #}
|
|
.edit-meeting-schedule .session.off-agenda { filter: brightness(0.9); }
|
|
{# type and purpose styling #}
|
|
.edit-meeting-schedule .edit-grid .timeslot.wrong-timeslot-type,
|
|
.edit-meeting-schedule .edit-grid .timeslot.hidden-timeslot-type { background-color: transparent; ); }
|
|
.edit-meeting-schedule .edit-grid .timeslot.wrong-timeslot-type .time-label,
|
|
.edit-meeting-schedule .edit-grid .timeslot.hidden-timeslot-type .time-label { color: transparent; ); }
|
|
.edit-meeting-schedule .session.hidden-purpose,
|
|
.edit-meeting-schedule .session.hidden-timeslot-type { filter: blur(3px); }
|
|
{% endblock %}
|
|
{% block title %}{{ schedule.name }}: IETF {{ meeting.number }} meeting agenda{% endblock %}
|
|
{% block js %}
|
|
<script src="{% static 'ietf/js/moment.js' %}"></script>
|
|
<script src="{% static 'ietf/js/moment-timezone-with-data-10-year-range.js' %}"></script>
|
|
<script src="{% static 'ietf/js/edit-meeting-schedule.js' %}"></script>
|
|
{% endblock %}
|
|
{% block content %}
|
|
{% origin %}
|
|
<div class="edit-meeting-schedule {% if schedule.is_official %}official-schedule{% endif %}"
|
|
data-timezone="{{ meeting.time_zone }}"
|
|
data-lock-seconds="{{ lock_time.total_seconds }}">
|
|
<h1>
|
|
Agenda name: {{ schedule.name }}
|
|
<br>
|
|
<small class="text-muted">Owner: {{ schedule.owner }}</small>
|
|
</h1>
|
|
<div class="my-3">
|
|
{% if can_edit_properties %}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.meeting.views.edit_schedule_properties" schedule.meeting.number schedule.owner_email schedule.name %}">
|
|
Edit properties
|
|
</a>
|
|
{% endif %}
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.meeting.views.new_meeting_schedule" num=meeting.number owner=schedule.owner_email name=schedule.name %}">
|
|
Copy agenda
|
|
</a>
|
|
<a class="btn btn-primary"
|
|
href="{% url "ietf.meeting.views.list_schedules" num=meeting.number %}">Other Agendas</a>
|
|
</div>
|
|
{% if not can_edit %}
|
|
<div class="alert alert-info my-3">
|
|
You can't edit this schedule.
|
|
{% if schedule.is_official_record %}This is the official schedule for a meeting in the past.{% endif %}
|
|
Make a
|
|
<a href="{% url "ietf.meeting.views.new_meeting_schedule" num=meeting.number owner=schedule.owner_email name=schedule.name %}">
|
|
new agenda from this
|
|
</a>
|
|
.
|
|
</div>
|
|
{% endif %}
|
|
<div class="edit-grid {% if not can_edit %}read-only{% endif %} my-3">
|
|
{# using the same markup in both room labels and the actual days ensures they are aligned #}
|
|
<div class="room-label-column">
|
|
{% for day_data in days.values %}
|
|
<div class="day">
|
|
<div class="day-label">
|
|
<strong> </strong>
|
|
<br>
|
|
|
|
</div>
|
|
{% for rgroup in day_data %}
|
|
<div class="room-group">
|
|
<div class="time-header">
|
|
<div class="time-label"></div>
|
|
</div>
|
|
{% for room_data in rgroup %}
|
|
{% with room_data.room as room %}
|
|
<div class="timeslots">
|
|
<div class="room-name">
|
|
<strong>{{ room.name }}</strong>
|
|
<br>
|
|
{% if room.capacity %}{{ room.capacity }} <i class="bi bi-person"></i>{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endwith %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="day-flow">
|
|
{% for day, day_data in days.items %}
|
|
<div class="day">
|
|
<div class="day-label">
|
|
<strong>{{ day|date:"l" }}</strong>
|
|
<i class="bi bi-arrow-left-right swap-days"
|
|
data-dayid="{{ day.isoformat }}"
|
|
data-start="{{ day.isoformat }}"></i>
|
|
<br>
|
|
{{ day|date:"N j, Y" }}
|
|
</div>
|
|
{% for rgroup in day_data %}
|
|
<div class="room-group"
|
|
data-index="{{ forloop.counter0 }}"
|
|
data-rooms="{% for r in rgroup %}{{ r.room.pk }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
|
<div class="time-header">
|
|
{# All rooms in a group have same timeslots; grab the first for the labels #}
|
|
{% for t in rgroup.0.timeslots %}
|
|
<div class="time-label" style="width: {{ t.layout_width }}rem">
|
|
<span>
|
|
{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}
|
|
<i class="bi bi-arrow-left-right swap-timeslot-col"
|
|
data-origin-label="{{ day|date:'l, N j' }}, {{ t.time|date:'G:i' }}-{{ t.end_time|date:'G:i' }}"
|
|
data-start="{{ t.utc_start_time.isoformat }}"
|
|
data-timeslot-pk="{{ t.pk }}"></i>
|
|
</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% for room_data in rgroup %}
|
|
{% with room_data.room as room %}
|
|
<div class="timeslots" data-roomcapacity="{{ room.capacity }}">
|
|
{% for t in room_data.timeslots %}
|
|
<div id="timeslot{{ t.pk }}"
|
|
class="timeslot {{ t.start_end_group }}"
|
|
data-start="{{ t.utc_start_time.isoformat }}"
|
|
data-end="{{ t.utc_end_time.isoformat }}"
|
|
data-duration="{{ t.duration.total_seconds }}"
|
|
data-scheduledatlabel="{{ t.time|date:'l G:i' }}-{{ t.end_time|date:'G:i' }}"
|
|
data-type="{{ t.type.slug }}"
|
|
style="width: {{ t.layout_width }}rem;">
|
|
<div class="time-label">
|
|
{# blank div keeps time centered vertically #}
|
|
<div class="past-flag"> </div>
|
|
<div>{{ t.time|date:"G:i" }} - {{ t.end_time|date:"G:i" }}</div>
|
|
<div class="past-flag">Past</div>
|
|
</div>
|
|
<div class="drop-target">
|
|
{% for assignment, session in t.session_assignments %}
|
|
{% include "meeting/edit_meeting_schedule_session.html" %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endwith %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<div class="scheduling-panel">
|
|
<div class="unassigned-container">
|
|
<div class="unassigned-sessions">
|
|
<div class="drop-target">
|
|
{% for session in unassigned_sessions %}
|
|
{% include "meeting/edit_meeting_schedule_session.html" %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<div class="preferences">
|
|
<span class="sort-unassigned">
|
|
Sort unassigned:
|
|
<select name="sort_unassigned" class="form-select">
|
|
<option value="name" selected="selected">
|
|
By name
|
|
</option>
|
|
<option value="parent">
|
|
By area
|
|
</option>
|
|
<option value="duration">
|
|
By duration
|
|
</option>
|
|
<option value="comments">
|
|
Special requests
|
|
</option>
|
|
</select>
|
|
</span>
|
|
<span class="toggle-inputs session-parent-toggles">
|
|
Show:
|
|
{% for p in session_parents %}
|
|
<label class="parent-{{ p.acronym }}">
|
|
<input type="checkbox"
|
|
class="form-check-input"
|
|
checked
|
|
value="{{ p.acronym }}">
|
|
{{ p.acronym }}
|
|
</label>
|
|
{% endfor %}
|
|
</span>
|
|
{% if session_purposes|length > 1 %}
|
|
<button id="session-toggle-modal-open"
|
|
class="btn btn-primary"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#session-toggles-modal">
|
|
<input type="checkbox" class="form-check-input" checked="checked" disabled>
|
|
Sessions
|
|
</button>
|
|
{% endif %}
|
|
<button id="timeslot-toggle-modal-open"
|
|
class="btn btn-primary"
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#timeslot-group-toggles-modal">
|
|
<i class="bi bi-check-all"></i>
|
|
Timeslots
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="session-info-container"></div>
|
|
</div>
|
|
<div id="timeslot-group-toggles-modal"
|
|
class="modal"
|
|
role="dialog"
|
|
aria-labelledby="timeslot-group-toggles-modal-title">
|
|
<div class="modal-dialog modal-xl" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="timeslot-group-toggles-modal-title">Displayed timeslots</h5>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="timeslot-group-buttons">
|
|
<button type="button" class="btn btn-primary select-all">Select all times</button>
|
|
<button type="button" class="btn btn-primary clear-all">Clear times</button>
|
|
</div>
|
|
<div class="individual-timeslots">
|
|
{% for day, t_groups in timeslot_groups %}
|
|
<div>
|
|
<div>
|
|
<strong>{{ day|date:"M. d" }}</strong>
|
|
</div>
|
|
{% for start, end, key in t_groups %}
|
|
<label>
|
|
<input type="checkbox"
|
|
class="form-check-input"
|
|
name="timeslot-group"
|
|
value="{{ key }}"
|
|
checked="checked">
|
|
{{ start|date:"H:i" }} - {{ end|date:"H:i" }}
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="timeslots-by-type timeslot-type-toggles">
|
|
Type:
|
|
{% for type in timeslot_types %}
|
|
<label class="timeslot-type-{{ type.slug }}">
|
|
<input type="checkbox"
|
|
class="form-check-input"
|
|
checked
|
|
value="{{ type.slug }}">
|
|
{{ type }}
|
|
</label>
|
|
{% endfor %}
|
|
<button type="button" class="btn btn-primary select-all">Select all types</button>
|
|
<button type="button" class="btn btn-primary clear-all">Clear types</button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="session-toggles-modal"
|
|
class="modal"
|
|
role="dialog"
|
|
aria-labelledby="session-toggles-modal-title">
|
|
<div class="modal-dialog modal-xl" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="session-toggles-modal-title">Displayed sessions</h5>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="session-purpose-toggles">
|
|
{% for purpose in session_purposes %}
|
|
<div>
|
|
<label class="purpose-{{ purpose.slug }}">
|
|
<input type="checkbox"
|
|
class="form-check-input"
|
|
checked
|
|
value="{% firstof purpose.slug 'none' %}">
|
|
{{ purpose }}
|
|
</label>
|
|
</div>
|
|
{% endfor %}
|
|
<button type="button" class="btn btn-primary select-all">
|
|
Select all
|
|
</button>
|
|
<button type="button" class="btn btn-primary clear-all">
|
|
Clear all
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">
|
|
Close
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="swap-days-modal"
|
|
class="modal"
|
|
role="dialog"
|
|
aria-labelledby="swap-days-modal-title">
|
|
<div class="modal-dialog modal-xl" role="document">
|
|
<form class="modal-content" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="swap-days-modal-title">
|
|
Swap <span class="day"></span> with
|
|
</h5>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close">
|
|
</button>
|
|
</div>
|
|
<input type="hidden" name="source_day" value="">
|
|
<div class="modal-body">
|
|
{% for day in days %}
|
|
<label>
|
|
<input type="radio"
|
|
class="form-check-input"
|
|
name="target_day"
|
|
data-start="{{ day.isoformat }}"
|
|
value="{{ day.isoformat }}">
|
|
{{ day|date:"l, N j, Y" }}
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
Close
|
|
</button>
|
|
<button type="submit" name="action" value="swapdays" class="btn btn-primary">
|
|
Swap days
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div id="swap-timeslot-col-modal"
|
|
class="modal"
|
|
role="dialog"
|
|
aria-labelledby="swap-timeslot-col-modal-title">
|
|
<div class="modal-dialog modal-xl" role="document">
|
|
<form class="modal-content" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="swap-timeslot-col-modal-title">
|
|
Swap <span class="origin-label"></span> with
|
|
</h5>
|
|
<button type="button"
|
|
class="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close">
|
|
</button>
|
|
</div>
|
|
<input type="hidden" name="origin_timeslot" value="">
|
|
<input type="hidden" name="rooms" value="">
|
|
<div class="modal-body">
|
|
<div class="day-options">
|
|
{% for day, day_data in days.items %}
|
|
{% for rgroup in day_data %}
|
|
<div class="room-group room-group-{{ forloop.counter0 }}">
|
|
{% if rgroup.0.timeslots|length > 0 %}
|
|
{{ day|date:"l, N j" }}
|
|
<div class="timeslot-options">
|
|
{% for t in rgroup.0.timeslots %}
|
|
<label>
|
|
<input type="radio"
|
|
class="form-check-input"
|
|
name="target_timeslot"
|
|
value="{{ t.pk }}"
|
|
data-start="{{ t.utc_start_time.isoformat }}">
|
|
{{ t.time|date:"G:i" }}-{{ t.end_time|date:"G:i" }}
|
|
</label>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
Close
|
|
</button>
|
|
<button type="submit"
|
|
name="action"
|
|
value="swaptimeslots"
|
|
class="btn btn-primary">
|
|
Swap timeslots
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|