Remove the not-quite-working customization widgets from /meeting/upcoming and /meeting/past. Simplify those views. Correct the list of sessions on those pages when one interim has more than one session. Fixes #2938. Partially addresses #2937. Commit ready for merge.
- Legacy-Id: 17555
This commit is contained in:
parent
8e9d65e7e0
commit
e9756d8987
|
@ -1321,13 +1321,14 @@ class InterimTests(TestCase):
|
|||
today = datetime.date.today()
|
||||
last_week = today - datetime.timedelta(days=7)
|
||||
ietf = SessionFactory(meeting__type_id='ietf',meeting__date=last_week,group__state_id='active',group__parent=GroupFactory(state_id='active'))
|
||||
interim = SessionFactory(meeting__type_id='interim',meeting__date=last_week,status_id='canceled',group__state_id='active',group__parent=GroupFactory(state_id='active'))
|
||||
SessionFactory(meeting__type_id='interim',meeting__date=last_week,status_id='canceled',group__state_id='active',group__parent=GroupFactory(state_id='active'))
|
||||
url = urlreverse('ietf.meeting.views.past')
|
||||
r = self.client.get(url)
|
||||
self.assertContains(r, 'IETF - %02d'%int(ietf.meeting.number))
|
||||
q = PyQuery(r.content)
|
||||
id="-%s" % interim.group.acronym
|
||||
self.assertIn('CANCELLED', q('[id*="'+id+'"]').text())
|
||||
#id="-%s" % interim.group.acronym
|
||||
#self.assertIn('CANCELLED', q('[id*="'+id+'"]').text())
|
||||
self.assertIn('CANCELLED', q('tr>td>a>span').text())
|
||||
|
||||
def test_upcoming(self):
|
||||
make_meeting_test_data()
|
||||
|
@ -1339,10 +1340,11 @@ class InterimTests(TestCase):
|
|||
r = self.client.get(url)
|
||||
self.assertContains(r, mars_interim.number)
|
||||
self.assertContains(r, ames_interim.number)
|
||||
self.assertContains(r, 'IETF - 72')
|
||||
self.assertContains(r, 'IETF 72')
|
||||
# cancelled session
|
||||
q = PyQuery(r.content)
|
||||
self.assertIn('CANCELLED', q('[id*="-ames"]').text())
|
||||
# self.assertIn('CANCELLED', q('[id*="-ames"]').text())
|
||||
self.assertIn('CANCELLED', q('tr>td>a>span').text())
|
||||
self.check_interim_tabs(url)
|
||||
|
||||
def test_upcoming_ical(self):
|
||||
|
|
|
@ -241,6 +241,26 @@ def only_sessions_that_can_meet(session_qs):
|
|||
|
||||
return qs
|
||||
|
||||
|
||||
# Keeping this as a note that might help when returning Customization to the /meetings/upcoming page
|
||||
#def group_parents_from_sessions(sessions):
|
||||
# group_parents = list()
|
||||
# parents = {}
|
||||
# for s in sessions:
|
||||
# if s.group.parent_id not in parents:
|
||||
# parent = s.group.parent
|
||||
# parent.group_list = set()
|
||||
# group_parents.append(parent)
|
||||
# parents[s.group.parent_id] = parent
|
||||
# parent.group_list.add(s.group)
|
||||
#
|
||||
# for p in parents.values():
|
||||
# p.group_list = list(p.group_list)
|
||||
# p.group_list.sort(key=lambda g: g.acronym)
|
||||
#
|
||||
# return group_parents
|
||||
|
||||
|
||||
def data_for_meetings_overview(meetings, interim_status=None):
|
||||
"""Return filtered meetings with sessions and group hierarchy (for the
|
||||
interim menu)."""
|
||||
|
@ -276,32 +296,12 @@ def data_for_meetings_overview(meetings, interim_status=None):
|
|||
if not m.type_id == 'interim' or not all(s.current_status in ['apprw', 'scheda', 'canceledpa'] for s in m.sessions)
|
||||
]
|
||||
|
||||
# group hierarchy
|
||||
ietf_group = Group.objects.get(acronym='ietf')
|
||||
|
||||
group_hierarchy = [ietf_group]
|
||||
|
||||
parents = {}
|
||||
for m in meetings:
|
||||
if m.type_id == 'interim' and m.sessions:
|
||||
for s in m.sessions:
|
||||
parent = parents.get(s.group.parent_id)
|
||||
if not parent:
|
||||
parent = s.group.parent
|
||||
parent.group_list = set()
|
||||
group_hierarchy.append(parent)
|
||||
parents[s.group.parent_id] = parent
|
||||
|
||||
parent.group_list.add(s.group)
|
||||
|
||||
for p in parents.values():
|
||||
p.group_list = list(p.group_list)
|
||||
p.group_list.sort(key=lambda g: g.acronym)
|
||||
|
||||
# set some useful attributes
|
||||
for m in meetings:
|
||||
m.end = m.date + datetime.timedelta(days=m.days)
|
||||
m.responsible_group = (m.sessions[0].group if m.sessions else None) if m.type_id == 'interim' else ietf_group
|
||||
m.interim_meeting_cancelled = m.type_id == 'interim' and all(s.current_status == 'canceled' for s in m.sessions)
|
||||
|
||||
return meetings, group_hierarchy
|
||||
return meetings
|
||||
|
|
|
@ -1920,7 +1920,7 @@ def ajax_get_utc(request):
|
|||
@role_required('Secretariat',)
|
||||
def interim_announce(request):
|
||||
'''View which shows interim meeting requests awaiting announcement'''
|
||||
meetings, _ = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='scheda')
|
||||
meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='scheda')
|
||||
menu_entries = get_interim_menu_entries(request)
|
||||
selected_menu_entry = 'announce'
|
||||
|
||||
|
@ -1983,7 +1983,7 @@ def interim_skip_announcement(request, number):
|
|||
@role_required('Area Director', 'Secretariat', 'IRTF Chair', 'WG Chair', 'RG Chair')
|
||||
def interim_pending(request):
|
||||
'''View which shows interim meeting requests pending approval'''
|
||||
meetings, group_parents = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='apprw')
|
||||
meetings = data_for_meetings_overview(Meeting.objects.filter(type='interim').order_by('date'), interim_status='apprw')
|
||||
|
||||
menu_entries = get_interim_menu_entries(request)
|
||||
selected_menu_entry = 'pending'
|
||||
|
@ -2225,20 +2225,31 @@ def past(request):
|
|||
'''List of past meetings'''
|
||||
today = datetime.datetime.today()
|
||||
|
||||
meetings, group_parents = data_for_meetings_overview(Meeting.objects.filter(date__lte=today).order_by('-date'))
|
||||
meetings = data_for_meetings_overview(Meeting.objects.filter(date__lte=today).order_by('-date'))
|
||||
|
||||
return render(request, 'meeting/past.html', {
|
||||
'meetings': meetings,
|
||||
'group_parents': group_parents})
|
||||
})
|
||||
|
||||
def upcoming(request):
|
||||
'''List of upcoming meetings'''
|
||||
today = datetime.date.today()
|
||||
|
||||
# Get ietf meetings starting 7 days ago, and interim meetings starting today
|
||||
query = Q(type_id='ietf', date__gte=today-datetime.timedelta(days=7)) | Q(type_id='interim', date__gte=today)
|
||||
meetings = Meeting.objects.filter(query).order_by('date')
|
||||
meetings, group_parents = data_for_meetings_overview(meetings)
|
||||
ietf_meetings = Meeting.objects.filter(type_id='ietf', date__gte=today-datetime.timedelta(days=7))
|
||||
for m in ietf_meetings:
|
||||
m.end = m.date+datetime.timedelta(days=m.days)
|
||||
interim_sessions = add_event_info_to_session_qs(
|
||||
Session.objects.filter(
|
||||
meeting__type_id='interim',
|
||||
timeslotassignments__schedule=F('meeting__schedule'),
|
||||
timeslotassignments__timeslot__time__gte=today
|
||||
)
|
||||
).filter(current_status__in=('sched','canceled'))
|
||||
|
||||
entries = list(ietf_meetings)
|
||||
entries.extend(list(interim_sessions))
|
||||
entries.sort(key = lambda o: pytz.utc.localize(datetime.datetime.combine(o.date, datetime.datetime.min.time())) if isinstance(o,Meeting) else o.official_timeslotassignment().timeslot.utc_start_time())
|
||||
|
||||
# add menu entries
|
||||
menu_entries = get_interim_menu_entries(request)
|
||||
|
@ -2253,11 +2264,11 @@ def upcoming(request):
|
|||
reverse('ietf.meeting.views.upcoming_ical')))
|
||||
|
||||
return render(request, 'meeting/upcoming.html', {
|
||||
'meetings': meetings,
|
||||
'entries': entries,
|
||||
'menu_actions': actions,
|
||||
'menu_entries': menu_entries,
|
||||
'selected_menu_entry': selected_menu_entry,
|
||||
'group_parents': group_parents})
|
||||
})
|
||||
|
||||
|
||||
def upcoming_ical(request):
|
||||
|
@ -2266,7 +2277,7 @@ def upcoming_ical(request):
|
|||
today = datetime.date.today()
|
||||
|
||||
# get meetings starting 7 days ago -- we'll filter out sessions in the past further down
|
||||
meetings, _ = data_for_meetings_overview(Meeting.objects.filter(date__gte=today-datetime.timedelta(days=7)).order_by('date'))
|
||||
meetings = data_for_meetings_overview(Meeting.objects.filter(date__gte=today-datetime.timedelta(days=7)).order_by('date'))
|
||||
|
||||
assignments = list(SchedTimeSessAssignment.objects.filter(
|
||||
schedule__meeting__schedule=F('schedule'),
|
||||
|
|
|
@ -19,68 +19,6 @@
|
|||
|
||||
<h1>Past Meetings</h1>
|
||||
|
||||
<div class="panel-group" id="accordion">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#customize">
|
||||
<span class="fa fa-caret-down"></span> Customize the meeting list...
|
||||
</a>
|
||||
</h4>
|
||||
</div> <!-- panel-heading -->
|
||||
|
||||
<div id="customize" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
You can customize the list to show only selected groups
|
||||
by clicking on groups and areas in the table below.
|
||||
To be able to return to the customized view later, bookmark the resulting URL.
|
||||
</p>
|
||||
|
||||
{% if group_parents|length %}
|
||||
<p>Groups displayed in <b><i>italics</i></b> are BOFs.</p>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for p in group_parents %}
|
||||
<th style="width:{% widthratio 1 group_parents|length 100 %}%">
|
||||
<button class="btn btn-default btn-block pickview {{p.acronym|lower}}">{{p.acronym|upper}}</button>
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{% for p in group_parents %}
|
||||
<td class="view {{p.acronym|lower}}">
|
||||
<div class="btn-group-vertical btn-block">
|
||||
{% for group in p.group_list %}
|
||||
<div class="btn-group btn-group-xs btn-group-justified">
|
||||
<button class="btn btn-default pickview {{group.acronym}}">
|
||||
{% if group.is_bof %}
|
||||
<i>{{group.acronym}}</i>
|
||||
{% else %}
|
||||
{{group.acronym}}
|
||||
{% endif %}
|
||||
</button>
|
||||
</div> <!-- button-group -->
|
||||
{% endfor %}
|
||||
</div> <!-- button-group-vertical -->
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<blockquote><i>No past meetings are available.</i></blockquote>
|
||||
{% endif %}
|
||||
|
||||
</div> <!-- panel-body -->
|
||||
</div> <!-- panel-collapse -->
|
||||
</div> <!-- panel -->
|
||||
</div> <!-- panel-group -->
|
||||
|
||||
{% if meetings %}
|
||||
<h3></h3>
|
||||
<table class="table table-condensed table-striped tablesorter">
|
||||
|
@ -93,7 +31,7 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{% for meeting in meetings %}
|
||||
<tr id="row-{{ forloop.counter }}{% if meeting.responsible_group.parent %}-{{ meeting.responsible_group.parent.acronym }}{% endif %}-{{ meeting.responsible_group.acronym }}">
|
||||
<tr>
|
||||
<td>{{ meeting.date }}</td>
|
||||
<td>
|
||||
{% if meeting.responsible_group.type_id != 'ietf' %}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% load ietf_filters staticfiles %}
|
||||
{% load ietf_filters staticfiles classname %}
|
||||
|
||||
{% block pagehead %}
|
||||
<link rel="stylesheet" href="{% static "jquery.tablesorter/css/theme.bootstrap.min.css" %}">
|
||||
|
@ -23,67 +23,6 @@
|
|||
<h1>Upcoming Meetings</h1>
|
||||
|
||||
<p>For more on regular IETF meetings see <a href="https://www.ietf.org/meeting/upcoming.html">here</a></p>
|
||||
<div class="panel-group" id="accordion">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" data-parent="#accordion" href="#customize">
|
||||
<span class="fa fa-caret-down"></span> Customize the meeting list...
|
||||
</a>
|
||||
</h4>
|
||||
</div> <!-- panel-heading -->
|
||||
|
||||
<div id="customize" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<p>
|
||||
You can customize the list to show only selected groups
|
||||
by clicking on groups and areas in the table below.
|
||||
To be able to return to the customized view later, bookmark the resulting URL.
|
||||
</p>
|
||||
|
||||
{% if group_parents|length %}
|
||||
<p>Groups displayed in <b><i>italics</i></b> are BOFs.</p>
|
||||
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for p in group_parents %}
|
||||
<th style="width:{% widthratio 1 group_parents|length 100 %}%">
|
||||
<button class="btn btn-default btn-block pickview {{p.acronym|lower}}">{{p.acronym|upper}}</button>
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{% for p in group_parents %}
|
||||
<td class="view {{p.acronym|lower}}">
|
||||
<div class="btn-group-vertical btn-block">
|
||||
{% for group in p.group_list %}
|
||||
<div class="btn-group btn-group-xs btn-group-justified">
|
||||
<button class="btn btn-default pickview {{group.acronym}}">
|
||||
{% if group.is_bof %}
|
||||
<i>{{group.acronym}}</i>
|
||||
{% else %}
|
||||
{{group.acronym}}
|
||||
{% endif %}
|
||||
</button>
|
||||
</div> <!-- button-group -->
|
||||
{% endfor %}
|
||||
</div> <!-- button-group-vertical -->
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<blockquote><i>No meetings have been scheduled yet.</i></blockquote>
|
||||
{% endif %}
|
||||
|
||||
</div> <!-- panel-body -->
|
||||
</div> <!-- panel-collapse -->
|
||||
</div> <!-- panel -->
|
||||
</div> <!-- panel-group -->
|
||||
|
||||
{% if menu_entries %}
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
|
@ -103,7 +42,7 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if meetings %}
|
||||
{% if entries %}
|
||||
<table class="table table-condensed table-striped tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -113,17 +52,23 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for meeting in meetings %}
|
||||
<tr id="row-{{ forloop.counter }}{% if meeting.responsible_group.parent %}-{{ meeting.responsible_group.parent.acronym }}{% endif %}-{{ meeting.responsible_group.acronym }}">
|
||||
<td>{{ meeting.date }}</td>
|
||||
<td>{{ meeting.responsible_group.acronym }}</td>
|
||||
<td>
|
||||
{% if meeting.type_id == "interim" %}
|
||||
<a href="{% url 'ietf.meeting.views.session_details' num=meeting.number acronym=meeting.session_set.all.0.group.acronym %}">{{ meeting.number }}{% if meeting.interim_meeting_cancelled %} <span class="label label-warning">CANCELLED</span>{% endif %}</a>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
{% if entry|classname == 'Meeting' %}
|
||||
{% with meeting=entry %}
|
||||
<td>{{ meeting.date }} - {{ meeting.end }}</td>
|
||||
<td>ietf</td>
|
||||
<td><a href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}">IETF {{ meeting.number }}</a></td>
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
<a href="{% url 'ietf.meeting.views.agenda' num=meeting.number %}">IETF - {{ meeting.number }}</a>
|
||||
{% with session=entry %}
|
||||
<td>{{ session.official_timeslotassignment.timeslot.utc_start_time | date:"Y-m-d H:i"}} - {{ session.official_timeslotassignment.timeslot.utc_end_time | date:"H:i e" }}</td>
|
||||
<td>{{ session.group.acronym }}</td>
|
||||
<td>
|
||||
<a href="{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}">{{ session.meeting.number }}{% if session.current_status == 'canceled' %} <span class="label label-warning">CANCELLED</span>{% endif %}</a>
|
||||
</td>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -139,7 +84,6 @@
|
|||
|
||||
{% block js %}
|
||||
<script src="{% static "jquery.tablesorter/js/jquery.tablesorter.combined.min.js" %}"></script>
|
||||
<script src="{% static 'ietf/js/toggle-visibility.js' %}"></script>
|
||||
<script src="{% static 'fullcalendar/core/main.js' %}"></script>
|
||||
<script src="{% static 'fullcalendar/daygrid/main.js' %}"></script>
|
||||
<script>
|
||||
|
@ -152,26 +96,25 @@
|
|||
plugins: [ 'dayGrid' ],
|
||||
displayEventTime: false,
|
||||
events: [
|
||||
{% for meeting in meetings %}
|
||||
{% if meeting.type_id == 'ietf' %}
|
||||
{
|
||||
title: 'IETF {{ meeting.number }}',
|
||||
start: '{{meeting.date}}',
|
||||
end: '{{meeting.end}}',
|
||||
url: '{% url 'ietf.meeting.views.agenda' num=meeting.number %}'
|
||||
}{% if not forloop.last %}, {% endif %}
|
||||
{% else %}
|
||||
{% for session in meeting.session_set.all %}
|
||||
{% for tsa in session.timeslotassignments.all %}
|
||||
{
|
||||
title: '{{session.group.acronym}} : {{tsa.timeslot.utc_start_time|date:"H:i"}} - {{tsa.timeslot.utc_end_time|date:"H:i"}} UTC',
|
||||
start: '{{tsa.timeslot.utc_start_time | date:"Y-m-d H:i"}}',
|
||||
end: '{{tsa.timeslot.utc_end_time | date:"Y-m-d H:i"}}',
|
||||
url: '{% url 'ietf.meeting.views.session_details' num=meeting.number acronym=session.group.acronym %}'
|
||||
}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% for entry in entries %}
|
||||
{% if entry|classname == 'Meeting' %}
|
||||
{% with meeting=entry %}
|
||||
{
|
||||
title: 'IETF {{ meeting.number }}',
|
||||
start: '{{meeting.date}}',
|
||||
end: '{{meeting.end}}',
|
||||
url: '{% url 'ietf.meeting.views.agenda' num=meeting.number %}'
|
||||
}{% if not forloop.last %}, {% endif %}
|
||||
{% endwith %}
|
||||
{% else %} {# if it's not a Meeting, it's a Session #}
|
||||
{% with session=entry %}
|
||||
{
|
||||
title: '{{session.group.acronym}} : {{session.official_timeslotassignment.timeslot.utc_start_time|date:"H:i"}} - {{session.official_timeslotassignment.timeslot.utc_end_time|date:"H:i"}} UTC',
|
||||
start: '{{session.official_timeslotassignment.timeslot.utc_start_time | date:"Y-m-d H:i"}}',
|
||||
end: '{{session.official_timeslotassignment.timeslot.utc_end_time | date:"Y-m-d H:i"}}',
|
||||
url: '{% url 'ietf.meeting.views.session_details' num=session.meeting.number acronym=session.group.acronym %}'
|
||||
}
|
||||
{% endwith %}
|
||||
{% if not forloop.last %}, {% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
11
ietf/utils/templatetags/classname.py
Normal file
11
ietf/utils/templatetags/classname.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Copyright The IETF Trust 2020, All Rights Reserved
|
||||
|
||||
|
||||
from django import template
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter
|
||||
def classname(obj):
|
||||
return obj.__class__.__name__
|
Loading…
Reference in a new issue