Skip to content

Commit ba7d468

Browse files
feat: show meeting requests beyond rg/wg groups (ietf-tools#4134)
* feat: show session requests for all "has_meetings" groups * test: test changes to groups whose session requests are shown Note the change in capitalization for the 'active' group state fixes the test but does not seem to affect production (which I guess uses case insensitive matching?) * test: remove leftover debug statement * feature: exclude admin/social sessions from meeting requests view * test: test exclusion of admin/social sessions from meeting requests view * feat: group all non-area groups as "other" on meeting requests page * fix: prevent doubling of first section header * test: verify that more of the sreqs are / are not linked
1 parent aa8e4e6 commit ba7d468

3 files changed

Lines changed: 115 additions & 17 deletions

File tree

ietf/meeting/tests_views.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6398,17 +6398,86 @@ class SessionTests(TestCase):
63986398

63996399
def test_meeting_requests(self):
64006400
meeting = MeetingFactory(type_id='ietf')
6401+
6402+
# a couple non-wg group types, confirm that their has_meetings features are as expected
6403+
group_type_with_meetings = 'adhoc'
6404+
self.assertTrue(GroupFeatures.objects.get(pk=group_type_with_meetings).has_meetings)
6405+
group_type_without_meetings = 'editorial'
6406+
self.assertFalse(GroupFeatures.objects.get(pk=group_type_without_meetings).has_meetings)
6407+
64016408
area = GroupFactory(type_id='area')
64026409
requested_session = SessionFactory(meeting=meeting,group__parent=area,status_id='schedw',add_to_schedule=False)
64036410
conflicting_session = SessionFactory(meeting=meeting,group__parent=area,status_id='schedw',add_to_schedule=False)
64046411
ConstraintFactory(name_id='key_participant',meeting=meeting,source=requested_session.group,target=conflicting_session.group)
64056412
not_meeting = SessionFactory(meeting=meeting,group__parent=area,status_id='notmeet',add_to_schedule=False)
6413+
has_meetings = SessionFactory(
6414+
meeting=meeting,
6415+
group__type_id=group_type_with_meetings,
6416+
status_id='schedw',
6417+
add_to_schedule=False,
6418+
)
6419+
has_meetings_not_meeting = SessionFactory(
6420+
meeting=meeting,
6421+
group__type_id=group_type_with_meetings,
6422+
status_id='notmeet',
6423+
add_to_schedule=False,
6424+
)
6425+
# admin and social sessions are not to be shown on the requests page
6426+
has_meetings_admin_session = SessionFactory(
6427+
meeting=meeting,
6428+
group__type_id=group_type_with_meetings,
6429+
status_id='schedw',
6430+
purpose_id='admin',
6431+
type_id='other',
6432+
add_to_schedule=False,
6433+
)
6434+
has_meetings_social_session = SessionFactory(
6435+
meeting=meeting,
6436+
group__type_id=group_type_with_meetings,
6437+
status_id='schedw',
6438+
purpose_id='social',
6439+
type_id='break',
6440+
add_to_schedule=False,
6441+
)
6442+
not_has_meetings = SessionFactory(
6443+
meeting=meeting,
6444+
group__type_id=group_type_without_meetings,
6445+
status_id='schedw',
6446+
add_to_schedule=False,
6447+
)
6448+
6449+
def _sreq_edit_link(sess):
6450+
return urlreverse(
6451+
'ietf.secr.sreq.views.edit',
6452+
kwargs={
6453+
'num': meeting.number,
6454+
'acronym': sess.group.acronym,
6455+
},
6456+
)
6457+
64066458
url = urlreverse('ietf.meeting.views.meeting_requests',kwargs={'num':meeting.number})
64076459
r = self.client.get(url)
6460+
# requested_session group should be listed with a link to the request
64086461
self.assertContains(r, requested_session.group.acronym)
6462+
self.assertContains(r, _sreq_edit_link(requested_session)) # link to the session request
64096463
self.assertContains(r, not_meeting.group.acronym)
6464+
# The admin/social session groups should be listed under "no timeslot request received"; it's easier
6465+
# to check that the group is listed but that there is no link to the session request than to try to
6466+
# parse the HTML. If the view is changed to link to the "no timeslot request received" session requests,
6467+
# then need to revisit.
6468+
self.assertContains(r, has_meetings_admin_session.group.acronym)
6469+
self.assertNotContains(r, _sreq_edit_link(has_meetings_admin_session)) # no link to the session request
6470+
self.assertContains(r, has_meetings_social_session.group.acronym)
6471+
self.assertNotContains(r, _sreq_edit_link(has_meetings_social_session)) # no link to the session request
64106472
self.assertContains(r, requested_session.constraints().first().name)
64116473
self.assertContains(r, conflicting_session.group.acronym)
6474+
self.assertContains(r, _sreq_edit_link(conflicting_session)) # link to the session request
6475+
self.assertContains(r, has_meetings.group.acronym)
6476+
self.assertContains(r, _sreq_edit_link(has_meetings)) # link to the session request
6477+
self.assertContains(r, has_meetings_not_meeting.group.acronym)
6478+
self.assertContains(r, _sreq_edit_link(has_meetings_not_meeting)) # link to the session request
6479+
self.assertNotContains(r, not_has_meetings.group.acronym)
6480+
self.assertNotContains(r, _sreq_edit_link(not_has_meetings)) # no link to the session request
64126481

64136482
def test_request_minutes(self):
64146483
meeting = MeetingFactory(type_id='ietf')

ietf/meeting/views.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,15 +2137,18 @@ def agenda_json(request, num=None):
21372137

21382138
def meeting_requests(request, num=None):
21392139
meeting = get_meeting(num)
2140-
sessions = Session.objects.requests().filter(
2141-
meeting__number=meeting.number,
2142-
group__parent__isnull=False
2143-
).with_current_status().with_requested_by().exclude(
2144-
requested_by=0
2145-
).order_by(
2146-
"group__parent__acronym", "current_status", "group__acronym"
2147-
).prefetch_related(
2148-
"group","group__ad_role__person"
2140+
groups_to_show = Group.objects.filter(state_id='active', type__features__has_meetings=True)
2141+
sessions = list(
2142+
Session.objects.requests().filter(
2143+
meeting__number=meeting.number,
2144+
group__in=groups_to_show,
2145+
).exclude(
2146+
purpose__in=('admin', 'social'),
2147+
).with_current_status().with_requested_by().exclude(
2148+
requested_by=0
2149+
).prefetch_related(
2150+
"group","group__ad_role__person"
2151+
)
21492152
)
21502153

21512154
status_names = {n.slug: n.name for n in SessionStatusName.objects.all()}
@@ -2154,12 +2157,34 @@ def meeting_requests(request, num=None):
21542157
for s in sessions:
21552158
s.current_status_name = status_names.get(s.current_status, s.current_status)
21562159
s.requested_by_person = session_requesters.get(s.requested_by)
2160+
if s.group.parent and s.group.parent.type.slug == 'area':
2161+
s.display_area = s.group.parent
2162+
else:
2163+
s.display_area = None
2164+
sessions.sort(
2165+
key=lambda s: (
2166+
s.display_area.acronym if s.display_area is not None else 'zzzz',
2167+
s.current_status,
2168+
s.group.acronym,
2169+
),
2170+
)
21572171

2158-
groups_not_meeting = Group.objects.filter(state='Active',type__in=['wg','rg','ag','rag','bof','program']).exclude(acronym__in = [session.group.acronym for session in sessions]).order_by("parent__acronym","acronym").prefetch_related("parent")
2172+
groups_not_meeting = groups_to_show.exclude(
2173+
acronym__in = [session.group.acronym for session in sessions]
2174+
).order_by(
2175+
"parent__acronym",
2176+
"acronym",
2177+
).prefetch_related("parent")
21592178

2160-
return render(request, "meeting/requests.html",
2161-
{"meeting": meeting, "sessions":sessions,
2162-
"groups_not_meeting": groups_not_meeting})
2179+
return render(
2180+
request,
2181+
"meeting/requests.html",
2182+
{
2183+
"meeting": meeting,
2184+
"sessions": sessions,
2185+
"groups_not_meeting": groups_not_meeting,
2186+
},
2187+
)
21632188

21642189

21652190
def get_sessions(num, acronym):

ietf/templates/meeting/requests.html

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@ <h1 class="title">
1515
{% if meeting.venue_name %}– {{ meeting.venue_name }}{% endif %}
1616
</small>
1717
</h1>
18-
{% regroup sessions by group.parent as area_sessions %}
18+
{% regroup sessions by display_area as area_sessions %}
1919
{% for area in area_sessions %}
20-
<h2 class="mt-5" id="{{ area.grouper.acronym }}">
21-
{{ area.grouper.acronym|upper }} <small class="text-muted">{{ area.grouper.name }}</small>
20+
<h2 class="mt-5" id="{% firstof area.grouper.acronym "other-groups" %}">
21+
{% if area.grouper is not None %}
22+
{{ area.grouper.acronym|upper }} <small class="text-muted">{{ area.grouper.name }}</small>
23+
{% else %}
24+
Other Groups
25+
{% endif %}
2226
</h2>
2327
<p class="alert alert-info my-3">
2428
<b>No timeslot request received for:</b>
@@ -39,7 +43,7 @@ <h2 class="mt-5" id="{{ area.grouper.acronym }}">
3943
</tr>
4044
</thead>
4145
{% for session in area.list %}
42-
{% ifchanged %}
46+
{% ifchanged session.current_status_name %}
4347
{% if not forloop.first %}</tbody>{% endif %}
4448
<tbody>
4549
<tr>

0 commit comments

Comments
 (0)