Merged in [19133] from jennifer@painless-security.com:
Indicate session and timeslot conflicts more prominently in schedule editor. Fixes #3221.
- Legacy-Id: 19142
Note: SVN reference [19133] has been migrated to Git commit 1d12391c5c
This commit is contained in:
commit
a6e08f1120
|
@ -171,10 +171,31 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk))
|
||||
s1_element.click()
|
||||
|
||||
# violated due to constraints
|
||||
# violated due to constraints - both the timeslot and its timeslot label
|
||||
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot1.pk)))
|
||||
# Find the timeslot label for slot1 - it's the first timeslot in the first room group
|
||||
slot1_roomgroup_elt = self.driver.find_element_by_css_selector(
|
||||
'.day-flow .day:first-child .room-group:nth-child(2)' # count from 2 - first-child is the day label
|
||||
)
|
||||
self.assertTrue(
|
||||
slot1_roomgroup_elt.find_elements_by_css_selector(
|
||||
'.time-header > .time-label.would-violate-hint:first-child'
|
||||
),
|
||||
'Timeslot header label should show a would-violate hint for a constraint violation'
|
||||
)
|
||||
|
||||
# violated due to missing capacity
|
||||
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot3.pk)))
|
||||
# Find the timeslot label for slot3 - it's the second timeslot in the second room group
|
||||
slot3_roomgroup_elt = self.driver.find_element_by_css_selector(
|
||||
'.day-flow .day:first-child .room-group:nth-child(3)' # count from 2 - first-child is the day label
|
||||
)
|
||||
self.assertFalse(
|
||||
slot3_roomgroup_elt.find_elements_by_css_selector(
|
||||
'.time-header > .time-label.would-violate-hint:nth-child(2)'
|
||||
),
|
||||
'Timeslot header label should not show a would-violate hint for room capacity violation'
|
||||
)
|
||||
|
||||
# reschedule
|
||||
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot2.pk))
|
||||
|
@ -192,6 +213,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
|
||||
# constraint hints
|
||||
s1_element.click()
|
||||
self.assertIn('would-violate-hint', s2_element.get_attribute('class'))
|
||||
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())
|
||||
|
||||
|
|
|
@ -1084,6 +1084,11 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .edit-grid .time-header .time-label.would-violate-hint {
|
||||
background-color: #ffe0e0;
|
||||
outline: #ffe0e0 solid 0.4em;
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .edit-grid .time-header .time-label span {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
@ -1128,11 +1133,12 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
|
|||
}
|
||||
|
||||
.edit-meeting-schedule .edit-grid .timeslot.overfull {
|
||||
border-right: 2px dashed #fff; /* cut-off illusion */
|
||||
border-right: 0.3em dashed #f55000; /* cut-off illusion */
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .edit-grid .timeslot.would-violate-hint {
|
||||
background-color: #ffe0e0;
|
||||
outline: #ffe0e0 solid 0.4em;
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .constraints .encircled,
|
||||
|
@ -1181,6 +1187,11 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
|
|||
background-color: #f3f3f3;
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .session.would-violate-hint {
|
||||
outline: 0.3em solid #F55000;
|
||||
z-index: 1; /* raise up so the outline is not overdrawn */
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .session.highlight .session-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -1263,6 +1274,7 @@ a.fc-event, .fc-event, .fc-content, .fc-title, .fc-event-container {
|
|||
margin-bottom: 2em;
|
||||
background-color: #fff;
|
||||
opacity: 0.95;
|
||||
z-index: 5; /* raise above edit-grid items */
|
||||
}
|
||||
|
||||
.edit-meeting-schedule .scheduling-panel .unassigned-container {
|
||||
|
|
|
@ -10,6 +10,7 @@ jQuery(document).ready(function () {
|
|||
|
||||
let sessions = content.find(".session").not(".readonly");
|
||||
let timeslots = content.find(".timeslot");
|
||||
let timeslotLabels = content.find(".time-label");
|
||||
let days = content.find(".day-flow .day");
|
||||
|
||||
// hack to work around lack of position sticky support in old browsers, see https://caniuse.com/#feat=css-sticky
|
||||
|
@ -68,25 +69,74 @@ jQuery(document).ready(function () {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark or unmark a session that conflicts with the selected session
|
||||
*
|
||||
* @param constraintElt The element corresponding to the specific constraint
|
||||
* @param wouldViolate True to mark or false to unmark
|
||||
*/
|
||||
function setSessionWouldViolate(constraintElt, wouldViolate) {
|
||||
constraintElt = jQuery(constraintElt);
|
||||
let constraintDiv = constraintElt.closest('div.session'); // find enclosing session div
|
||||
constraintDiv.toggleClass('would-violate-hint', wouldViolate); // mark the session container
|
||||
constraintElt.toggleClass('would-violate-hint', wouldViolate); // and the specific constraint
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark or unmark a timeslot that conflicts with the selected session
|
||||
*
|
||||
* If wholeInterval is true, marks the entire column in addition to the timeslot.
|
||||
* This currently works by setting the class for the timeslot and the time-label
|
||||
* in its column. Because this is called for every timeslot in the interval, the
|
||||
* overall effect is to highlight the entire column.
|
||||
*
|
||||
* @param timeslotElt Timeslot element to be marked/unmarked
|
||||
* @param wouldViolate True to mark or false to unmark
|
||||
* @param wholeInterval Should the entire time interval be flagged or just the timeslot?
|
||||
*/
|
||||
function setTimeslotWouldViolate(timeslotElt, wouldViolate, wholeInterval) {
|
||||
timeslotElt = jQuery(timeslotElt);
|
||||
timeslotElt.toggleClass('would-violate-hint', wouldViolate);
|
||||
if (wholeInterval) {
|
||||
let index = timeslotElt.index(); // position of this timeslot relative to its container
|
||||
let label = timeslotElt
|
||||
.closest('div.room-group')
|
||||
.find('div.time-header .time-label')
|
||||
.get(index); // get time-label corresponding to this timeslot
|
||||
jQuery(label).toggleClass('would-violate-hint', wouldViolate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all would-violate-hint classes on timeslots
|
||||
*/
|
||||
function resetTimeslotsWouldViolate() {
|
||||
timeslots.removeClass("would-violate-hint");
|
||||
timeslotLabels.removeClass("would-violate-hint");
|
||||
}
|
||||
|
||||
function showConstraintHints(selectedSession) {
|
||||
let sessionId = selectedSession ? selectedSession.id.slice("session".length) : null;
|
||||
// hints on the sessions
|
||||
sessions.find(".constraints > span").each(function () {
|
||||
if (!sessionId) {
|
||||
jQuery(this).removeClass("would-violate-hint");
|
||||
return;
|
||||
let wouldViolate = false;
|
||||
let applyChange = true;
|
||||
if (sessionId) {
|
||||
let sessionIds = this.dataset.sessions;
|
||||
if (!sessionIds) {
|
||||
applyChange = False;
|
||||
} else {
|
||||
wouldViolate = sessionIds.split(",").indexOf(sessionId) !== -1;
|
||||
}
|
||||
}
|
||||
|
||||
let sessionIds = this.dataset.sessions;
|
||||
if (!sessionIds)
|
||||
return;
|
||||
|
||||
let wouldViolate = sessionIds.split(",").indexOf(sessionId) != -1;
|
||||
jQuery(this).toggleClass("would-violate-hint", wouldViolate);
|
||||
if (applyChange) {
|
||||
setSessionWouldViolate(this, wouldViolate);
|
||||
}
|
||||
});
|
||||
|
||||
// hints on timeslots
|
||||
timeslots.removeClass("would-violate-hint");
|
||||
resetTimeslotsWouldViolate();
|
||||
if (selectedSession) {
|
||||
let intervals = [];
|
||||
timeslots.filter(":has(.session .constraints > span.would-violate-hint)").each(function () {
|
||||
|
@ -94,15 +144,17 @@ jQuery(document).ready(function () {
|
|||
});
|
||||
|
||||
let overlappingTimeslots = findTimeslotsOverlapping(intervals);
|
||||
for (let i = 0; i < overlappingTimeslots.length; ++i)
|
||||
overlappingTimeslots[i].addClass("would-violate-hint");
|
||||
for (let i = 0; i < overlappingTimeslots.length; ++i) {
|
||||
setTimeslotWouldViolate(overlappingTimeslots[i], true, true);
|
||||
}
|
||||
|
||||
// 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");
|
||||
if (attendees > +jQuery(this).closest(".timeslots").data("roomcapacity")) {
|
||||
setTimeslotWouldViolate(this, true, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue