diff --git a/client/agenda/AgendaScheduleList.vue b/client/agenda/AgendaScheduleList.vue index a42315fc4b..3897e1d62b 100644 --- a/client/agenda/AgendaScheduleList.vue +++ b/client/agenda/AgendaScheduleList.vue @@ -257,16 +257,17 @@ const meetingEvents = computed(() => { acc.lastDate = itemDate.toISODate() // -> Add session header row - if (item.type === 'regular' && acc.lastTypeName !== `${item.type}-${item.name}`) { + const typeName = `${item.type}-${item.slotName}` + if (item.type === 'regular' && acc.lastTypeName !== typeName) { acc.result.push({ key: `sesshd-${item.id}`, displayType: 'session-head', timeslot: itemTimeSlot, - name: `${item.adjustedStart.toFormat('cccc')} ${item.name}`, + name: `${item.adjustedStart.toFormat('cccc')} ${item.slotName}`, cssClasses: 'agenda-table-display-session-head' + (isLive ? ' agenda-table-live' : '') }) } - acc.lastTypeName = `${item.type}-${item.name}` + acc.lastTypeName = typeName // -> Populate event links const links = [] diff --git a/ietf/meeting/migrations/0059_rename_sessions.py b/ietf/meeting/migrations/0059_rename_sessions.py new file mode 100644 index 0000000000..a9e56646b6 --- /dev/null +++ b/ietf/meeting/migrations/0059_rename_sessions.py @@ -0,0 +1,41 @@ +# Generated by Django 2.2.28 on 2023-02-06 22:20 +from django.db import migrations +from django.db.models import ExpressionWrapper, F, IntegerField + + +def forward(apps, schema_editor): + Meeting = apps.get_model('meeting', 'Meeting') + meetings = Meeting.objects.filter(type='ietf', schedule__isnull=False).annotate( + number_as_int=ExpressionWrapper(F('number'), output_field=IntegerField()) + ).order_by('date') + # print('session.pk,meeting.number,session.name,timeslot.name') + for m in meetings.filter(number_as_int__lt=91): + # until meeting 91, TimeSlots had the more descriptive names + for assignment in m.schedule.assignments.exclude(session__type='regular').exclude(session__name=F('timeslot__name')): + # print(f'{assignment.session.pk},{m.number},{assignment.session.name},{assignment.timeslot.name}') + assignment.session.name = assignment.timeslot.name + assignment.session.save() + + # meetings 91-98 had no differences or were better off with session names as they were + + for m in meetings.filter(number_as_int__gte=99): + # for meetings 99+, TimeSlots again had the better names + for assignment in m.schedule.assignments.exclude(session__type='regular').exclude(session__name=F('timeslot__name')): + # print(f'{assignment.session.pk},{m.number},{assignment.session.name},{assignment.timeslot.name}') + assignment.session.name = assignment.timeslot.name + assignment.session.save() + + +def reverse(apps, schema_editor): + pass # can't undo + + +class Migration(migrations.Migration): + + dependencies = [ + ('meeting', '0058_meeting_time_zone_not_blank'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 4ababfc9ca..f6f6a58b22 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -172,6 +172,42 @@ def test_agenda_extract_schedule_location(self): self.assertEqual(shown['room'], room.name) self.assertEqual(shown['location'], {'name': room.floorplan.name, 'short': room.floorplan.short}) + def test_agenda_extract_schedule_names(self): + meeting = MeetingFactory(type_id='ietf') + named_timeslots = TimeSlotFactory.create_batch(2, meeting=meeting, name='Timeslot Name') + unnamed_timeslots = TimeSlotFactory.create_batch(2, meeting=meeting, name='') + named_sessions = SessionFactory.create_batch(2, meeting=meeting, name='Session Name') + unnamed_sessions = SessionFactory.create_batch(2, meeting=meeting, name='') + pk_with = { + 'both named': named_sessions[0].timeslotassignments.create( + schedule=meeting.schedule, + timeslot=named_timeslots[0], + ).pk, + 'session named': named_sessions[1].timeslotassignments.create( + schedule=meeting.schedule, + timeslot=unnamed_timeslots[0], + ).pk, + 'timeslot named': unnamed_sessions[0].timeslotassignments.create( + schedule=meeting.schedule, + timeslot=named_timeslots[1], + ).pk, + 'neither named': unnamed_sessions[1].timeslotassignments.create( + schedule=meeting.schedule, + timeslot=unnamed_timeslots[1], + ).pk, + } + processed = preprocess_assignments_for_agenda(meeting.schedule.assignments.all(), meeting) + AgendaKeywordTagger(assignments=processed).apply() + extracted = {item.pk: agenda_extract_schedule(item) for item in processed} + self.assertEqual(extracted[pk_with['both named']]['name'], 'Session Name') + self.assertEqual(extracted[pk_with['both named']]['slotName'], 'Timeslot Name') + self.assertEqual(extracted[pk_with['session named']]['name'], 'Session Name') + self.assertEqual(extracted[pk_with['session named']]['slotName'], '') + self.assertEqual(extracted[pk_with['timeslot named']]['name'], '') + self.assertEqual(extracted[pk_with['timeslot named']]['slotName'], 'Timeslot Name') + self.assertEqual(extracted[pk_with['neither named']]['name'], '') + self.assertEqual(extracted[pk_with['neither named']]['slotName'], '') + class MeetingTests(BaseMeetingTestCase): def test_meeting_agenda(self): diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 6e96fa82a5..6c3d37d02a 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -1704,7 +1704,8 @@ def agenda_extract_schedule (item): } if (item.timeslot.show_location and item.timeslot.location and item.timeslot.location.floorplan) else {}, "acronym": item.acronym, "duration": item.timeslot.duration.seconds, - "name": item.timeslot.name, + "name": item.session.name, + "slotName": item.timeslot.name, "startDateTime": item.timeslot.time.isoformat(), "status": item.session.current_status, "type": item.session.type.slug, diff --git a/playwright/tests/meeting/agenda.spec.js b/playwright/tests/meeting/agenda.spec.js index 6fac4ddf60..1c5a82f186 100644 --- a/playwright/tests/meeting/agenda.spec.js +++ b/playwright/tests/meeting/agenda.spec.js @@ -213,7 +213,7 @@ test.describe('past - desktop', () => { const headerRow = page.locator(`#agenda-rowid-sesshd-${event.id}`) await expect(headerRow).toBeVisible() await expect(headerRow.locator('.agenda-table-cell-ts')).toContainText(eventTimeSlot) - await expect(headerRow.locator('.agenda-table-cell-name')).toContainText(`${DateTime.fromISO(event.startDateTime).toFormat('cccc')} ${event.name}`) + await expect(headerRow.locator('.agenda-table-cell-name')).toContainText(`${DateTime.fromISO(event.startDateTime).toFormat('cccc')} ${event.slotName}`) } // Timeslot await expect(row.locator('.agenda-table-cell-ts')).toContainText('—')