From a70ece9a34793864b9e0034fbe5d40bd5e35744f Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Fri, 19 Jun 2020 17:50:55 +0000 Subject: [PATCH] Hint when a timeslot is unsuitable because the room is too small. Expand test to cover the timeslot hints too. - Legacy-Id: 18019 --- ietf/meeting/tests_js.py | 33 +++++++++++----- ietf/static/ietf/css/ietf.css | 2 +- ietf/static/ietf/js/edit-meeting-schedule.js | 41 +++++++++++++------- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py index 9412670c9..4c6d04f34 100644 --- a/ietf/meeting/tests_js.py +++ b/ietf/meeting/tests_js.py @@ -89,15 +89,23 @@ class EditMeetingScheduleTests(IetfLiveServerTestCase): type_id='regular', location=room2, duration=datetime.timedelta(hours=2), - time=slot1.time - datetime.timedelta(seconds=10 * 60), + time=slot1.time - datetime.timedelta(minutes=10), ) + slot3 = TimeSlot.objects.create( + meeting=meeting, + type_id='regular', + location=room2, + duration=datetime.timedelta(hours=2), + time=max(slot1.end_time(), slot2.end_time()) + datetime.timedelta(minutes=10), + ) + s1, s2 = Session.objects.filter(meeting=meeting, type='regular') s2.requested_duration = slot2.duration + datetime.timedelta(minutes=10) s2.save() SchedTimeSessAssignment.objects.filter(session=s1).delete() - s2_b = Session.objects.create(meeting=meeting, group=s2.group, attendees=10, requested_duration=datetime.timedelta(minutes=60), type_id='regular') + s2b = Session.objects.create(meeting=meeting, group=s2.group, attendees=10, requested_duration=datetime.timedelta(minutes=60), type_id='regular') Constraint.objects.create( meeting=meeting, @@ -124,7 +132,7 @@ class EditMeetingScheduleTests(IetfLiveServerTestCase): # deselect self.driver.find_element_by_css_selector('.scheduling-panel').click() - self.assertEqual(self.driver.find_elements_by_css_selector('.session-info-container .title'), []) + self.assertEqual(session_info_container.find_elements_by_css_selector(".title"), []) # unschedule @@ -150,19 +158,19 @@ class EditMeetingScheduleTests(IetfLiveServerTestCase): self.assertEqual(list(SchedTimeSessAssignment.objects.filter(session=s2, schedule=schedule)), []) # sorting unassigned - sorted_pks = [s.pk for s in sorted([s1, s2, s2_b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))] + sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))] self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=name]').click() self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{} + #session{}'.format(*sorted_pks))) - sorted_pks = [s.pk for s in sorted([s1, s2, s2_b], key=lambda s: (s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] + sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=parent]').click() self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) - sorted_pks = [s.pk for s in sorted([s1, s2, s2_b], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym, s.pk))] + sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym, s.pk))] self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=duration]').click() self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) - sorted_pks = [s.pk for s in sorted([s1, s2, s2_b], key=lambda s: (int(bool(s.comments)), s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] + sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (int(bool(s.comments)), s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=comments]').click() self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) @@ -174,6 +182,15 @@ class EditMeetingScheduleTests(IetfLiveServerTestCase): assignment = SchedTimeSessAssignment.objects.get(session=s2, schedule=schedule) self.assertEqual(assignment.timeslot, slot1) + # timeslot constraint hints when selected + s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk)) + s1_element.click() + + # violated due to constraints + self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot1.pk))) + # violated due to missing capacity + self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot3.pk))) + # reschedule self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot2.pk)) @@ -189,9 +206,7 @@ class EditMeetingScheduleTests(IetfLiveServerTestCase): self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.overfull'.format(slot2.pk))) # constraint hints - s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk)) s1_element.click() - constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].would-violate-hint".format(s1.pk)) self.assertTrue(constraint_element.is_displayed()) diff --git a/ietf/static/ietf/css/ietf.css b/ietf/static/ietf/css/ietf.css index 311494b4b..ea9ba2def 100644 --- a/ietf/static/ietf/css/ietf.css +++ b/ietf/static/ietf/css/ietf.css @@ -1276,7 +1276,7 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container { .edit-meeting-schedule .scheduling-panel .session-info-container { padding-left: 0.5em; flex: 0 0 25em; - max-height: 25em; + height: 20em; font-size: 14px; overflow-y: auto; } diff --git a/ietf/static/ietf/js/edit-meeting-schedule.js b/ietf/static/ietf/js/edit-meeting-schedule.js index e47f21481..13ca65d4c 100644 --- a/ietf/static/ietf/js/edit-meeting-schedule.js +++ b/ietf/static/ietf/js/edit-meeting-schedule.js @@ -43,7 +43,7 @@ jQuery(document).ready(function () { sessions.not(element).removeClass("selected"); jQuery(element).addClass("selected"); - showConstraintHints(element.id.slice("session".length)); + showConstraintHints(element); let sessionInfoContainer = content.find(".scheduling-panel .session-info-container"); sessionInfoContainer.html(jQuery(element).find(".session-info").html()); @@ -68,11 +68,11 @@ jQuery(document).ready(function () { } } - function showConstraintHints(sessionIdStr) { - let intervals = []; - + function showConstraintHints(selectedSession) { + let sessionId = selectedSession ? selectedSession.id.slice("session".length) : null; + // hints on the sessions sessions.find(".constraints > span").each(function () { - if (!sessionIdStr) { + if (!sessionId) { jQuery(this).removeClass("would-violate-hint"); return; } @@ -81,20 +81,31 @@ jQuery(document).ready(function () { if (!sessionIds) return; - let wouldViolate = sessionIds.split(",").indexOf(sessionIdStr) != -1; + let wouldViolate = sessionIds.split(",").indexOf(sessionId) != -1; jQuery(this).toggleClass("would-violate-hint", wouldViolate); - - if (wouldViolate) { - let timeslot = jQuery(this).closest(".timeslot"); - if (timeslot.length > 0) - intervals.push([timeslot.data("start"), timeslot.data("end")]); - } }); + // hints on timeslots timeslots.removeClass("would-violate-hint"); - let overlappingTimeslots = findTimeslotsOverlapping(intervals); - for (let i = 0; i < overlappingTimeslots.length; ++i) - overlappingTimeslots[i].addClass("would-violate-hint"); + if (selectedSession) { + let intervals = []; + timeslots.filter(":has(.session .constraints > span.would-violate-hint)").each(function () { + intervals.push([this.dataset.start, this.dataset.end]); + }); + + let overlappingTimeslots = findTimeslotsOverlapping(intervals); + for (let i = 0; i < overlappingTimeslots.length; ++i) + overlappingTimeslots[i].addClass("would-violate-hint"); + + // check room sizes + let attendees = +selectedSession.dataset.attendees; + if (attendees) { + timeslots.not(".would-violate-hint").each(function () { + if (attendees > +jQuery(this).closest(".timeslots").data("roomcapacity")) + jQuery(this).addClass("would-violate-hint"); + }); + } + } } content.on("click", function (event) {