Skip to content

Commit a70ece9

Browse files
committed
Hint when a timeslot is unsuitable because the room is too small.
Expand test to cover the timeslot hints too. - Legacy-Id: 18019
1 parent 770341f commit a70ece9

3 files changed

Lines changed: 51 additions & 25 deletions

File tree

ietf/meeting/tests_js.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,23 @@ def test_edit_meeting_schedule(self):
8989
type_id='regular',
9090
location=room2,
9191
duration=datetime.timedelta(hours=2),
92-
time=slot1.time - datetime.timedelta(seconds=10 * 60),
92+
time=slot1.time - datetime.timedelta(minutes=10),
9393
)
9494

95+
slot3 = TimeSlot.objects.create(
96+
meeting=meeting,
97+
type_id='regular',
98+
location=room2,
99+
duration=datetime.timedelta(hours=2),
100+
time=max(slot1.end_time(), slot2.end_time()) + datetime.timedelta(minutes=10),
101+
)
102+
95103
s1, s2 = Session.objects.filter(meeting=meeting, type='regular')
96104
s2.requested_duration = slot2.duration + datetime.timedelta(minutes=10)
97105
s2.save()
98106
SchedTimeSessAssignment.objects.filter(session=s1).delete()
99107

100-
s2_b = Session.objects.create(meeting=meeting, group=s2.group, attendees=10, requested_duration=datetime.timedelta(minutes=60), type_id='regular')
108+
s2b = Session.objects.create(meeting=meeting, group=s2.group, attendees=10, requested_duration=datetime.timedelta(minutes=60), type_id='regular')
101109

102110
Constraint.objects.create(
103111
meeting=meeting,
@@ -124,7 +132,7 @@ def test_edit_meeting_schedule(self):
124132
# deselect
125133
self.driver.find_element_by_css_selector('.scheduling-panel').click()
126134

127-
self.assertEqual(self.driver.find_elements_by_css_selector('.session-info-container .title'), [])
135+
self.assertEqual(session_info_container.find_elements_by_css_selector(".title"), [])
128136

129137
# unschedule
130138

@@ -150,19 +158,19 @@ def test_edit_meeting_schedule(self):
150158
self.assertEqual(list(SchedTimeSessAssignment.objects.filter(session=s2, schedule=schedule)), [])
151159

152160
# sorting unassigned
153-
sorted_pks = [s.pk for s in sorted([s1, s2, s2_b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))]
161+
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))]
154162
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=name]').click()
155163
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{} + #session{}'.format(*sorted_pks)))
156164

157-
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))]
165+
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))]
158166
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=parent]').click()
159167
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
160168

161-
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))]
169+
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))]
162170
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=duration]').click()
163171
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
164172

165-
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))]
173+
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))]
166174
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=comments]').click()
167175
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
168176

@@ -174,6 +182,15 @@ def test_edit_meeting_schedule(self):
174182
assignment = SchedTimeSessAssignment.objects.get(session=s2, schedule=schedule)
175183
self.assertEqual(assignment.timeslot, slot1)
176184

185+
# timeslot constraint hints when selected
186+
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk))
187+
s1_element.click()
188+
189+
# violated due to constraints
190+
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot1.pk)))
191+
# violated due to missing capacity
192+
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot3.pk)))
193+
177194
# reschedule
178195
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot2.pk))
179196

@@ -189,9 +206,7 @@ def test_edit_meeting_schedule(self):
189206
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.overfull'.format(slot2.pk)))
190207

191208
# constraint hints
192-
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk))
193209
s1_element.click()
194-
195210
constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].would-violate-hint".format(s1.pk))
196211
self.assertTrue(constraint_element.is_displayed())
197212

ietf/static/ietf/css/ietf.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,7 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
12761276
.edit-meeting-schedule .scheduling-panel .session-info-container {
12771277
padding-left: 0.5em;
12781278
flex: 0 0 25em;
1279-
max-height: 25em;
1279+
height: 20em;
12801280
font-size: 14px;
12811281
overflow-y: auto;
12821282
}

ietf/static/ietf/js/edit-meeting-schedule.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jQuery(document).ready(function () {
4343
sessions.not(element).removeClass("selected");
4444
jQuery(element).addClass("selected");
4545

46-
showConstraintHints(element.id.slice("session".length));
46+
showConstraintHints(element);
4747

4848
let sessionInfoContainer = content.find(".scheduling-panel .session-info-container");
4949
sessionInfoContainer.html(jQuery(element).find(".session-info").html());
@@ -68,11 +68,11 @@ jQuery(document).ready(function () {
6868
}
6969
}
7070

71-
function showConstraintHints(sessionIdStr) {
72-
let intervals = [];
73-
71+
function showConstraintHints(selectedSession) {
72+
let sessionId = selectedSession ? selectedSession.id.slice("session".length) : null;
73+
// hints on the sessions
7474
sessions.find(".constraints > span").each(function () {
75-
if (!sessionIdStr) {
75+
if (!sessionId) {
7676
jQuery(this).removeClass("would-violate-hint");
7777
return;
7878
}
@@ -81,20 +81,31 @@ jQuery(document).ready(function () {
8181
if (!sessionIds)
8282
return;
8383

84-
let wouldViolate = sessionIds.split(",").indexOf(sessionIdStr) != -1;
84+
let wouldViolate = sessionIds.split(",").indexOf(sessionId) != -1;
8585
jQuery(this).toggleClass("would-violate-hint", wouldViolate);
86-
87-
if (wouldViolate) {
88-
let timeslot = jQuery(this).closest(".timeslot");
89-
if (timeslot.length > 0)
90-
intervals.push([timeslot.data("start"), timeslot.data("end")]);
91-
}
9286
});
9387

88+
// hints on timeslots
9489
timeslots.removeClass("would-violate-hint");
95-
let overlappingTimeslots = findTimeslotsOverlapping(intervals);
96-
for (let i = 0; i < overlappingTimeslots.length; ++i)
97-
overlappingTimeslots[i].addClass("would-violate-hint");
90+
if (selectedSession) {
91+
let intervals = [];
92+
timeslots.filter(":has(.session .constraints > span.would-violate-hint)").each(function () {
93+
intervals.push([this.dataset.start, this.dataset.end]);
94+
});
95+
96+
let overlappingTimeslots = findTimeslotsOverlapping(intervals);
97+
for (let i = 0; i < overlappingTimeslots.length; ++i)
98+
overlappingTimeslots[i].addClass("would-violate-hint");
99+
100+
// check room sizes
101+
let attendees = +selectedSession.dataset.attendees;
102+
if (attendees) {
103+
timeslots.not(".would-violate-hint").each(function () {
104+
if (attendees > +jQuery(this).closest(".timeslots").data("roomcapacity"))
105+
jQuery(this).addClass("would-violate-hint");
106+
});
107+
}
108+
}
98109
}
99110

100111
content.on("click", function (event) {

0 commit comments

Comments
 (0)