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:
Robert Sparks 2020-03-27 22:47:38 +00:00
parent 8e9d65e7e0
commit e9756d8987
6 changed files with 97 additions and 192 deletions

View file

@ -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):

View file

@ -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

View file

@ -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'),

View file

@ -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' %}

View file

@ -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 %}&nbsp;&nbsp;<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' %}&nbsp;&nbsp;<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 %}

View 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__