feat: show meeting requests beyond rg/wg groups (#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
This commit is contained in:
parent
aa8e4e6e5e
commit
ba7d468a4d
|
@ -6398,17 +6398,86 @@ class SessionTests(TestCase):
|
|||
|
||||
def test_meeting_requests(self):
|
||||
meeting = MeetingFactory(type_id='ietf')
|
||||
|
||||
# a couple non-wg group types, confirm that their has_meetings features are as expected
|
||||
group_type_with_meetings = 'adhoc'
|
||||
self.assertTrue(GroupFeatures.objects.get(pk=group_type_with_meetings).has_meetings)
|
||||
group_type_without_meetings = 'editorial'
|
||||
self.assertFalse(GroupFeatures.objects.get(pk=group_type_without_meetings).has_meetings)
|
||||
|
||||
area = GroupFactory(type_id='area')
|
||||
requested_session = SessionFactory(meeting=meeting,group__parent=area,status_id='schedw',add_to_schedule=False)
|
||||
conflicting_session = SessionFactory(meeting=meeting,group__parent=area,status_id='schedw',add_to_schedule=False)
|
||||
ConstraintFactory(name_id='key_participant',meeting=meeting,source=requested_session.group,target=conflicting_session.group)
|
||||
not_meeting = SessionFactory(meeting=meeting,group__parent=area,status_id='notmeet',add_to_schedule=False)
|
||||
has_meetings = SessionFactory(
|
||||
meeting=meeting,
|
||||
group__type_id=group_type_with_meetings,
|
||||
status_id='schedw',
|
||||
add_to_schedule=False,
|
||||
)
|
||||
has_meetings_not_meeting = SessionFactory(
|
||||
meeting=meeting,
|
||||
group__type_id=group_type_with_meetings,
|
||||
status_id='notmeet',
|
||||
add_to_schedule=False,
|
||||
)
|
||||
# admin and social sessions are not to be shown on the requests page
|
||||
has_meetings_admin_session = SessionFactory(
|
||||
meeting=meeting,
|
||||
group__type_id=group_type_with_meetings,
|
||||
status_id='schedw',
|
||||
purpose_id='admin',
|
||||
type_id='other',
|
||||
add_to_schedule=False,
|
||||
)
|
||||
has_meetings_social_session = SessionFactory(
|
||||
meeting=meeting,
|
||||
group__type_id=group_type_with_meetings,
|
||||
status_id='schedw',
|
||||
purpose_id='social',
|
||||
type_id='break',
|
||||
add_to_schedule=False,
|
||||
)
|
||||
not_has_meetings = SessionFactory(
|
||||
meeting=meeting,
|
||||
group__type_id=group_type_without_meetings,
|
||||
status_id='schedw',
|
||||
add_to_schedule=False,
|
||||
)
|
||||
|
||||
def _sreq_edit_link(sess):
|
||||
return urlreverse(
|
||||
'ietf.secr.sreq.views.edit',
|
||||
kwargs={
|
||||
'num': meeting.number,
|
||||
'acronym': sess.group.acronym,
|
||||
},
|
||||
)
|
||||
|
||||
url = urlreverse('ietf.meeting.views.meeting_requests',kwargs={'num':meeting.number})
|
||||
r = self.client.get(url)
|
||||
# requested_session group should be listed with a link to the request
|
||||
self.assertContains(r, requested_session.group.acronym)
|
||||
self.assertContains(r, _sreq_edit_link(requested_session)) # link to the session request
|
||||
self.assertContains(r, not_meeting.group.acronym)
|
||||
# The admin/social session groups should be listed under "no timeslot request received"; it's easier
|
||||
# to check that the group is listed but that there is no link to the session request than to try to
|
||||
# parse the HTML. If the view is changed to link to the "no timeslot request received" session requests,
|
||||
# then need to revisit.
|
||||
self.assertContains(r, has_meetings_admin_session.group.acronym)
|
||||
self.assertNotContains(r, _sreq_edit_link(has_meetings_admin_session)) # no link to the session request
|
||||
self.assertContains(r, has_meetings_social_session.group.acronym)
|
||||
self.assertNotContains(r, _sreq_edit_link(has_meetings_social_session)) # no link to the session request
|
||||
self.assertContains(r, requested_session.constraints().first().name)
|
||||
self.assertContains(r, conflicting_session.group.acronym)
|
||||
self.assertContains(r, _sreq_edit_link(conflicting_session)) # link to the session request
|
||||
self.assertContains(r, has_meetings.group.acronym)
|
||||
self.assertContains(r, _sreq_edit_link(has_meetings)) # link to the session request
|
||||
self.assertContains(r, has_meetings_not_meeting.group.acronym)
|
||||
self.assertContains(r, _sreq_edit_link(has_meetings_not_meeting)) # link to the session request
|
||||
self.assertNotContains(r, not_has_meetings.group.acronym)
|
||||
self.assertNotContains(r, _sreq_edit_link(not_has_meetings)) # no link to the session request
|
||||
|
||||
def test_request_minutes(self):
|
||||
meeting = MeetingFactory(type_id='ietf')
|
||||
|
|
|
@ -2137,15 +2137,18 @@ def agenda_json(request, num=None):
|
|||
|
||||
def meeting_requests(request, num=None):
|
||||
meeting = get_meeting(num)
|
||||
sessions = Session.objects.requests().filter(
|
||||
meeting__number=meeting.number,
|
||||
group__parent__isnull=False
|
||||
).with_current_status().with_requested_by().exclude(
|
||||
requested_by=0
|
||||
).order_by(
|
||||
"group__parent__acronym", "current_status", "group__acronym"
|
||||
).prefetch_related(
|
||||
"group","group__ad_role__person"
|
||||
groups_to_show = Group.objects.filter(state_id='active', type__features__has_meetings=True)
|
||||
sessions = list(
|
||||
Session.objects.requests().filter(
|
||||
meeting__number=meeting.number,
|
||||
group__in=groups_to_show,
|
||||
).exclude(
|
||||
purpose__in=('admin', 'social'),
|
||||
).with_current_status().with_requested_by().exclude(
|
||||
requested_by=0
|
||||
).prefetch_related(
|
||||
"group","group__ad_role__person"
|
||||
)
|
||||
)
|
||||
|
||||
status_names = {n.slug: n.name for n in SessionStatusName.objects.all()}
|
||||
|
@ -2154,12 +2157,34 @@ def meeting_requests(request, num=None):
|
|||
for s in sessions:
|
||||
s.current_status_name = status_names.get(s.current_status, s.current_status)
|
||||
s.requested_by_person = session_requesters.get(s.requested_by)
|
||||
if s.group.parent and s.group.parent.type.slug == 'area':
|
||||
s.display_area = s.group.parent
|
||||
else:
|
||||
s.display_area = None
|
||||
sessions.sort(
|
||||
key=lambda s: (
|
||||
s.display_area.acronym if s.display_area is not None else 'zzzz',
|
||||
s.current_status,
|
||||
s.group.acronym,
|
||||
),
|
||||
)
|
||||
|
||||
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")
|
||||
groups_not_meeting = groups_to_show.exclude(
|
||||
acronym__in = [session.group.acronym for session in sessions]
|
||||
).order_by(
|
||||
"parent__acronym",
|
||||
"acronym",
|
||||
).prefetch_related("parent")
|
||||
|
||||
return render(request, "meeting/requests.html",
|
||||
{"meeting": meeting, "sessions":sessions,
|
||||
"groups_not_meeting": groups_not_meeting})
|
||||
return render(
|
||||
request,
|
||||
"meeting/requests.html",
|
||||
{
|
||||
"meeting": meeting,
|
||||
"sessions": sessions,
|
||||
"groups_not_meeting": groups_not_meeting,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def get_sessions(num, acronym):
|
||||
|
|
|
@ -15,10 +15,14 @@
|
|||
{% if meeting.venue_name %}– {{ meeting.venue_name }}{% endif %}
|
||||
</small>
|
||||
</h1>
|
||||
{% regroup sessions by group.parent as area_sessions %}
|
||||
{% regroup sessions by display_area as area_sessions %}
|
||||
{% for area in area_sessions %}
|
||||
<h2 class="mt-5" id="{{ area.grouper.acronym }}">
|
||||
{{ area.grouper.acronym|upper }} <small class="text-muted">{{ area.grouper.name }}</small>
|
||||
<h2 class="mt-5" id="{% firstof area.grouper.acronym "other-groups" %}">
|
||||
{% if area.grouper is not None %}
|
||||
{{ area.grouper.acronym|upper }} <small class="text-muted">{{ area.grouper.name }}</small>
|
||||
{% else %}
|
||||
Other Groups
|
||||
{% endif %}
|
||||
</h2>
|
||||
<p class="alert alert-info my-3">
|
||||
<b>No timeslot request received for:</b>
|
||||
|
@ -39,7 +43,7 @@
|
|||
</tr>
|
||||
</thead>
|
||||
{% for session in area.list %}
|
||||
{% ifchanged %}
|
||||
{% ifchanged session.current_status_name %}
|
||||
{% if not forloop.first %}</tbody>{% endif %}
|
||||
<tbody>
|
||||
<tr>
|
||||
|
|
Loading…
Reference in a new issue