* feat: add session recordings * feat: add session recordings * feat: deleting recordings * feat: deleting recordings and initial form values * feat: use meeting date rather than today for initial title field. Fix delete recording * feat: confirm delete recordings modal. fix server utils delete recording * fix: removing debug console.log * feat: change button name from 'Ok' to 'Delete' for confirm deletion to be clearer * feat: UTC time in string and delete modal text * fix: django html validation tests * fix: django html validation tests * fix: django html validation tests * refactor: Work with SessionPresentations * fix: better ordering * chore: drop rev, hide table when empty * test: test delete_recordings method * fix: debug delete_recordings * test: test add_session_recordings view * fix: better permissions handling * fix: only delete recordings for selected session * refactor: inline script -> js module * chore: remove accidental import *shakes fist at pycharm* * fix: consistent timestamp format plus slight rephrase * style: Black * chore: remove comment * test: update test to match * fix: reversible url pattern for materials Tests were perturbed in a way that led to a test getting an interim instead of an IETF meeting. This exposed a bug reversing the URL for the materials_document() view. This splits it into two patterns that are equivalent to the original. --------- Co-authored-by: Jennifer Richards <jennifer@staff.ietf.org>
381 lines
20 KiB
HTML
381 lines
20 KiB
HTML
{% load origin ietf_filters textfilters tz dateformat %}
|
|
{% origin %}
|
|
{% for session in sessions %}
|
|
{% with item=session.official_timeslotassignment %} {% with timeslot=item.timeslot %}
|
|
<div class="mt-4">
|
|
{% if not session.cancelled %}
|
|
<div class="regular ms-3 float-end">
|
|
{# see note in the included templates re: show_agenda parameter and required JS import #}
|
|
{% if meeting.type.slug == 'interim' %}
|
|
{% include "meeting/interim_session_buttons.html" with show_agenda=False show_empty=False %}
|
|
{% else %}
|
|
{% include "meeting/session_buttons_include.html" with show_agenda=False item=session.official_timeslotassignment %}
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
<h3 class="" id="session_{{ session.pk }}">
|
|
{% if sessions|length > 1 %}Session {{ forloop.counter }} :{% endif %}
|
|
{% for time in session.times %}
|
|
{% if not forloop.first %},{% endif %}
|
|
<span class="session-time date me-3" data-start-utc="{{ timeslot.time|utc|date:'Y-m-d H:i' }}" data-end-utc="{{ timeslot.end_time|utc|date:'Y-m-d H:i' }}"></span>
|
|
{% include "meeting/tz-display.html" with meeting_timezone=session.meeting.time_zone id_suffix=session.pk minimal=True only %}
|
|
{% endfor %}
|
|
{% if session.cancelled %}
|
|
<small class="badge rounded-pill text-bg-warning">Cancelled</small>
|
|
{% else %}
|
|
{{ session.status }}
|
|
{% endif %}
|
|
{% if session.name %}: {{ session.name }}{% endif %}
|
|
</h3>
|
|
</div>
|
|
{% if session.agenda_note %}<h3 class="mt-4">{{ session.agenda_note }}</h3>{% endif %}
|
|
{% if can_manage_materials %}
|
|
{% if session.current_status == 'sched' or session.current_status == 'schedw' %}
|
|
<div class="buttonlist">
|
|
{% if can_view_request %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.interim_request_details' number=meeting.number %}">
|
|
Meeting details
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
{% if not session.type_counter.agenda %}
|
|
<div class="alert alert-warning my-3">This session does not yet have an agenda.</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if meeting.type.slug == 'interim' and session.remote_instructions %}
|
|
<div class="my-3">
|
|
<b>Remote instructions:</b>
|
|
{% if session.agenda_note|first_url|conference_url %}
|
|
<a href="{{ session.agenda_note|first_url }}" title="Online conference">
|
|
<i class="bi bi-beople"></i>
|
|
</a>
|
|
{% elif session.remote_instructions|first_url|conference_url %}
|
|
<a href="{{ session.remote_instructions|first_url }}"
|
|
title="Online conference">
|
|
<i class="bi bi-people"></i>
|
|
</a>
|
|
{% endif %}
|
|
{{ session.remote_instructions|linkify }}
|
|
</div>
|
|
{% endif %}
|
|
<h3 class="mt-4">Agenda, Minutes, and Bluesheets</h3>
|
|
<table class="table table-sm table-striped">
|
|
{% if session.filtered_artifacts or session.bluesheet_title %}
|
|
<tbody>
|
|
{% for pres in session.filtered_artifacts %}
|
|
<tr>
|
|
{% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %}
|
|
<td>
|
|
<a href="{{ pres.document.get_href }}">{{ pres.document.title }}</a>
|
|
<a href="{{ url }}">({{ pres.document.name }})</a>
|
|
{% if user|has_role:"Secretariat" or can_manage_materials %}
|
|
{% if pres.document.type.slug == 'minutes' %}
|
|
{% url 'ietf.meeting.views.upload_session_minutes' session_id=session.pk num=session.meeting.number as upload_url %}
|
|
{% elif pres.document.type.slug == 'narrativeminutes' %}
|
|
{% url 'ietf.meeting.views.upload_session_narrativeminutes' session_id=session.pk num=session.meeting.number as upload_url %}
|
|
{% elif pres.document.type.slug == 'agenda' %}
|
|
{% url 'ietf.meeting.views.upload_session_agenda' session_id=session.pk num=session.meeting.number as upload_url %}
|
|
{% else %}
|
|
{% url 'ietf.meeting.views.upload_session_bluesheets' session_id=session.pk num=session.meeting.number as upload_url %}
|
|
{% endif %}
|
|
{% if pres.document.type.slug != 'bluesheets' or user|has_role:"Secretariat" or meeting.type.slug == 'interim' and can_manage_materials %}
|
|
{% if pres.document.type.slug == 'minutes' %}
|
|
<a class="btn btn-primary btn-sm float-end ms-1" href="{% url 'ietf.meeting.views.import_session_minutes' num=session.meeting.number session_id=session.pk %}">Import from notes.ietf.org</a>
|
|
{% endif %}
|
|
<a class="btn btn-primary btn-sm float-end ms-1" href="{{ upload_url }}">Upload revision</a>
|
|
{% endif %}
|
|
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% if session.bluesheet_title %}
|
|
<tr><td>
|
|
<a href="{% url 'ietf.meeting.views.session_attendance' session_id=session.pk num=session.meeting.number %}">
|
|
{{ session.bluesheet_title }}
|
|
</a>
|
|
</td></tr>
|
|
{% endif %}
|
|
</tbody>
|
|
{% endif %}
|
|
</table>
|
|
{% if can_manage_materials %}
|
|
{% if not session.type_counter.agenda %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.upload_session_agenda' session_id=session.pk num=session.meeting.number %}">
|
|
Upload agenda
|
|
</a>
|
|
{% endif %}
|
|
{% if not session.type_counter.minutes %}
|
|
<a class="btn btn-primary" href="{% url 'ietf.meeting.views.import_session_minutes' num=session.meeting.number session_id=session.pk %}">Import minutes from notes.ietf.org</a>
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.upload_session_minutes' session_id=session.pk num=session.meeting.number %}">
|
|
Upload minutes
|
|
</a>
|
|
{% endif %}
|
|
{% if not session.type_counter.narrativeminutes and session.group.acronym == "iesg" %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.upload_session_narrativeminutes' session_id=session.pk num=session.meeting.number %}">
|
|
Upload narrative minutes
|
|
</a>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if user|has_role:"Secretariat" and not session.type_counter.bluesheets or meeting.type.slug == 'interim' and can_manage_materials and not session.type_counter.bluesheets %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.upload_session_bluesheets' session_id=session.pk num=session.meeting.number %}">
|
|
Upload bluesheets
|
|
</a>
|
|
{% endif %}
|
|
{% if session.filtered_chatlog_and_polls %}
|
|
<h3 class="mt-4">Chatlog and polls</h3>
|
|
<table class="table table-sm table-striped chatlog-and-polls"
|
|
id="chatlog_and_polls_{{ session.pk }}">
|
|
<tbody data-session="{{ session.pk }}">
|
|
{% for pres in session.filtered_chatlog_and_polls %}
|
|
<tr data-name="{{ pres.document.name }}">
|
|
{% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %}
|
|
<td>
|
|
<a href="{{ url }}">{{ pres.document.title }}</a>
|
|
<a href="{{ pres.document.get_href }}">( as json )</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
{% endif %}
|
|
<h3 class="mt-4">Slides</h3>
|
|
<table class="table table-sm table-striped slides"
|
|
id="slides_{{ session.pk }}">
|
|
{% if session.filtered_slides %}
|
|
<tbody data-session="{{ session.pk }}"
|
|
data-add-to-session="{% url 'ietf.meeting.views.ajax_add_slides_to_session' session_id=session.pk num=session.meeting.number %}"
|
|
data-remove-from-session="{% url 'ietf.meeting.views.ajax_remove_slides_from_session' session_id=session.pk num=session.meeting.number %}"
|
|
data-reorder-in-session="{% url 'ietf.meeting.views.ajax_reorder_slides_in_session' session_id=session.pk num=session.meeting.number %}">
|
|
{% for pres in session.filtered_slides %}
|
|
<tr data-name="{{ pres.document.name }}" {% if can_manage_materials %} class="draggable" {% endif %}>
|
|
{% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %}
|
|
{% if can_manage_materials %}
|
|
<td>
|
|
<i class="bi bi-grip-vertical drag-handle" title="Drag to reorder"></i>
|
|
</td>
|
|
{% endif %}
|
|
<td>
|
|
{% if can_manage_materials %}
|
|
<a class="btn btn-primary btn-sm float-end ms-1"
|
|
href="{% url 'ietf.meeting.views.upload_session_slides' session_id=session.pk num=session.meeting.number name=pres.document.name %}">
|
|
Upload revision
|
|
</a>
|
|
<a class="btn btn-danger btn-sm float-end ms-1"
|
|
href="{% url 'ietf.meeting.views.remove_sessionpresentation' session_id=session.pk num=session.meeting.number name=pres.document.name %}">
|
|
Remove
|
|
</a>
|
|
{% endif %}
|
|
<a href="{{ pres.document.get_href }}">{{ pres.document.title }}</a>
|
|
<a href="{{ url }}">({{ pres.document.name }})</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
{% endif %}
|
|
</table>
|
|
{% if can_manage_materials %}
|
|
<a class="btn btn-primary uploadslides"
|
|
href="{% url 'ietf.meeting.views.upload_session_slides' session_id=session.pk num=session.meeting.number %}">
|
|
Upload new slides
|
|
</a>
|
|
{% elif request.user.is_authenticated and not session.is_material_submission_cutoff %}
|
|
<a class="btn btn-primary proposeslides"
|
|
href="{% url 'ietf.meeting.views.upload_session_slides' session_id=session.pk num=session.meeting.number %}">
|
|
Propose slides
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% if can_manage_materials %}<div class="form-text">Drag-and-drop to reorder slides</div>{% endif %}
|
|
<h3 class="mt-4">Internet-Drafts</h3>
|
|
<table class="table table-sm table-striped">
|
|
{% if session.filtered_drafts %}
|
|
<tbody>
|
|
{% for pres in session.filtered_drafts %}
|
|
<tr>
|
|
<td>
|
|
{% url 'ietf.doc.views_doc.document_main' name=pres.document.name as url %}
|
|
<a href="{{ url }}">
|
|
{{ pres.document.title }} ({{ pres.document.name }})
|
|
{% if pres.rev %}Version {{ pres.rev }}{% endif %}
|
|
</a>
|
|
</td>
|
|
<td>
|
|
{% if can_manage_materials %}
|
|
<a class="btn btn-primary btn-sm"
|
|
href="{% url 'ietf.meeting.views.remove_sessionpresentation' session_id=session.pk num=session.meeting.number name=pres.document.name %}">
|
|
Remove
|
|
</a>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
{% endif %}
|
|
</table>
|
|
{% if can_manage_materials %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.add_session_drafts' session_id=session.pk num=session.meeting.number %}">
|
|
Link additional I-Ds to session
|
|
</a>
|
|
{% endif %}
|
|
{% if timezone_now < timeslot.end_time %}{# show meeting tools until the session ends #}
|
|
<h3 class="mt-4">Meeting tools</h3>
|
|
<table class="table table-sm table-striped meeting-tools"
|
|
id="meeting_tools_{{ session.pk }}">
|
|
<tbody>
|
|
{% if meeting.uses_notes %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.notes_url }}">
|
|
<i class="bi bi-journal-text"></i> Notepad for note-takers
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{# chat #}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.chat_room_url }}">
|
|
<i class="bi bi-chat"></i> Chat room
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{# Video stream (meetecho) #}
|
|
{% if session.video_stream_url and timezone_now < timeslot.end_time %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.video_stream_url }}">
|
|
<i class="bi bi-camera-video"></i> Video stream
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{# Onsite tool (meetecho_onsite) #}
|
|
{% if session.onsite_tool_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.onsite_tool_url }}">
|
|
<i class="bi bi-phone"></i> Onsite tool
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{# Audio stream #}
|
|
{% if session.audio_stream_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.audio_stream_url }}">
|
|
<i class="bi bi-headphones"></i> Audio stream
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{# Remote call-in #}
|
|
{% if session.agenda_note|first_url|conference_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.agenda_note|first_url }}">
|
|
<i class="bi bi-people"></i> Online conference
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% elif session.remote_instructions|first_url|conference_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.remote_instructions|first_url }}">
|
|
<i class="bi bi-people"></i> Online conference
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% elif timeslot.location.webex_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ timeslot.location.webex_url|format:session }}">
|
|
<i class="bi bi-people"></i> Webex session
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
{% else %}{# session is in the past #}
|
|
<h3 class="mt-4">Notes and recordings</h3>
|
|
<table class="table table-sm table-striped meeting-tools"
|
|
id="notes_and_recordings_{{ session.pk }}">
|
|
<tbody>
|
|
{% if session.uses_notes %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.notes_url }}">
|
|
<i class="bi bi-journal-text"></i> Notepad for note-takers
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{# Recordings #}
|
|
{% with session.recordings as recordings %}
|
|
{% if recordings %}
|
|
{# There's no guaranteed order, so this is a bit messy: #}
|
|
{# First, the audio recordings, if any #}
|
|
{% for r in recordings %}
|
|
{% if r.get_href and 'audio' in r.get_href %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ r.get_href }}"><i class="bi bi-file-play"></i> {{ r.title }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{# Then the youtube recordings #}
|
|
{% for r in recordings %}
|
|
{% if r.get_href and 'youtu' in r.get_href %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ r.get_href }}"><i class="bi bi-file-slides"></i> {{ r.title }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{# Finally, any other recordings #}
|
|
{% for r in recordings %}
|
|
{% if r.get_href and not 'audio' in r.get_href and not 'youtu' in r.get_href %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ r.get_href }}"><i class="bi bi-file-play"></i> {{ r.title }}</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
{% if session.session_recording_url %}
|
|
<tr>
|
|
<td>
|
|
<a href="{{ session.session_recording_url }}">
|
|
<i class="bi bi-file-slides"></i>
|
|
Meetecho session recording
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
{% endif %}
|
|
|
|
{% if can_manage_materials %}
|
|
<a class="btn btn-primary"
|
|
href="{% url 'ietf.meeting.views.add_session_recordings' session_id=session.pk num=session.meeting.number %}">
|
|
Link additional recordings to session
|
|
</a>
|
|
{% endif %}
|
|
|
|
{% endwith %}{% endwith %}
|
|
{% endfor %}
|