Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions ietf/meeting/tests_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3898,6 +3898,69 @@ def test_slot_to_the_right(self):
self.assertTrue(mars_slot.slot_to_the_right)
self.assertTrue(mars_scheduled.slot_to_the_right)

def test_updateview(self):
"""The updateview action should set visible timeslot types in the session"""
meeting = MeetingFactory(type_id='ietf')
url = urlreverse('ietf.meeting.views.edit_meeting_schedule', kwargs={'num': meeting.number})
types_to_enable = ['regular', 'reg', 'other']
r = self.client.post(
url,
{
'action': 'updateview',
'enabled_timeslot_types[]': types_to_enable,
},
)
self.assertEqual(r.status_code, 200)
session_data = self.client.session
self.assertIn('edit_meeting_schedule', session_data)
self.assertCountEqual(
session_data['edit_meeting_schedule']['enabled_timeslot_types'],
types_to_enable,
'Should set types requested',
)

r = self.client.post(
url,
{
'action': 'updateview',
'enabled_timeslot_types[]': types_to_enable + ['faketype'],
},
)
self.assertEqual(r.status_code, 200)
session_data = self.client.session
self.assertIn('edit_meeting_schedule', session_data)
self.assertCountEqual(
session_data['edit_meeting_schedule']['enabled_timeslot_types'],
types_to_enable,
'Should ignore unknown types',
)

def test_persistent_enabled_timeslot_types(self):
meeting = MeetingFactory(type_id='ietf')
TimeSlotFactory(meeting=meeting, type_id='other')
TimeSlotFactory(meeting=meeting, type_id='reg')

# test default behavior (only 'regular' enabled)
r = self.client.get(urlreverse('ietf.meeting.views.edit_meeting_schedule', kwargs={'num': meeting.number}))
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="regular"][checked]')), 1)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="other"]:not([checked])')), 1)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="reg"]:not([checked])')), 1)

# test with 'regular' and 'other' enabled via session store
client_session = self.client.session # must store as var, new session is created on access
client_session['edit_meeting_schedule'] = {
'enabled_timeslot_types': ['regular', 'other']
}
client_session.save()
r = self.client.get(urlreverse('ietf.meeting.views.edit_meeting_schedule', kwargs={'num': meeting.number}))
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="regular"][checked]')), 1)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="other"][checked]')), 1)
self.assertEqual(len(q('#timeslot-type-toggles-modal input[value="reg"]:not([checked])')), 1)


class SessionDetailsTests(TestCase):

Expand Down
25 changes: 22 additions & 3 deletions ietf/meeting/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,10 +728,18 @@ def _json_response(success, status=None, **extra_data):
return JsonResponse(data, status=status)

if request.method == 'POST':
if not can_edit:
permission_denied(request, "Can't edit this schedule.")

action = request.POST.get('action')
if action == 'updateview':
# allow updateview action even if can_edit is false, it affects only the user's session
sess_data = request.session.setdefault('edit_meeting_schedule', {})
enabled_types = [ts_type.slug for ts_type in TimeSlotTypeName.objects.filter(
used=True,
slug__in=request.POST.getlist('enabled_timeslot_types[]', [])
)]
sess_data['enabled_timeslot_types'] = enabled_types
return _json_response(True)
elif not can_edit:
permission_denied(request, "Can't edit this schedule.")

# Handle ajax requests. Most of these return JSON responses with at least a 'success' key.
# For the swapdays and swaptimeslots actions, the response is either a redirect to the
Expand Down Expand Up @@ -949,6 +957,16 @@ def cubehelix(i, total, hue=1.2, start_angle=0.5):
key=lambda tstype: tstype.name,
)

# extract view configuration from session store
session_data = request.session.get('edit_meeting_schedule', None)
if session_data is None:
enabled_timeslot_types = ['regular']
else:
enabled_timeslot_types = [
ts_type.slug for ts_type in timeslot_types
if ts_type.slug in session_data.get('enabled_timeslot_types', [])
]

return render(request, "meeting/edit_meeting_schedule.html", {
'meeting': meeting,
'schedule': schedule,
Expand All @@ -963,6 +981,7 @@ def cubehelix(i, total, hue=1.2, start_angle=0.5):
'timeslot_types': timeslot_types,
'hide_menu': True,
'lock_time': lock_time,
'enabled_timeslot_types': enabled_timeslot_types,
})


Expand Down
65 changes: 37 additions & 28 deletions ietf/static/js/edit-meeting-schedule.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ $(function () {
alert("Error: " + errorText);
}

function ajaxCall(action, data) {
const ajaxData = { action: action };
Object.assign(ajaxData, data);
return jQuery.ajax({
url: window.location.href,
method: "post",
timeout: 5 * 1000,
data: ajaxData,
});
}

/**
* Time to treat as current time for computing whether to lock timeslots
* @returns {*} Moment object equal to lockSeconds in the future
Expand Down Expand Up @@ -437,26 +448,20 @@ $(function () {
}

if (dropParent.hasClass("unassigned-sessions")) {
jQuery.ajax({
url: window.location.href,
method: "post",
timeout: 5 * 1000,
data: {
action: "unassign",
session: sessionElement.id.slice("session".length)
}
}).fail(failHandler).done(done);
ajaxCall(
"unassign",
{ session: sessionElement.id.slice('session'.length) }
).fail(failHandler)
.done(done);
} else {
jQuery.ajax({
url: window.location.href,
method: "post",
data: {
action: "assign",
ajaxCall(
"assign",
{
session: sessionElement.id.slice("session".length),
timeslot: dropParent.attr("id").slice("timeslot".length)
},
timeout: 5 * 1000
}).fail(failHandler).done(done);
}
).fail(failHandler)
.done(done);
}
});

Expand Down Expand Up @@ -759,16 +764,20 @@ $(function () {

// Toggling timeslot types
function updateTimeSlotTypeToggling() {
let checked = [];
timeSlotTypeInputs.filter(":checked").each(function () {
checked.push("[data-type=" + this.value + "]");
});
const checkedTypes = jQuery.map(timeSlotTypeInputs.filter(":checked"), elt => elt.value);
const checkedSelectors = checkedTypes.map(t => '[data-type="' + t + '"]').join(",");

sessions.filter(checked.join(",")).removeClass('hidden-timeslot-type');
sessions.not(checked.join(",")).addClass('hidden-timeslot-type');
timeslots.filter(checked.join(",")).removeClass('hidden-timeslot-type');
timeslots.not(checked.join(",")).addClass('hidden-timeslot-type');
sessions.filter(checkedSelectors).removeClass('hidden-timeslot-type');
sessions.not(checkedSelectors).addClass('hidden-timeslot-type');
timeslots.filter(checkedSelectors).removeClass('hidden-timeslot-type');
timeslots.not(checkedSelectors).addClass('hidden-timeslot-type');
updateGridVisibility();
return checkedTypes;
}

function updateTimeSlotTypeTogglingAndSave() {
const checkedTypes = updateTimeSlotTypeToggling();
ajaxCall('updateview', {enabled_timeslot_types: checkedTypes});
}

// Toggling session purposes
Expand All @@ -783,23 +792,23 @@ $(function () {
}

if (timeSlotTypeInputs.length > 0) {
timeSlotTypeInputs.on("change", updateTimeSlotTypeToggling);
timeSlotTypeInputs.on("change", updateTimeSlotTypeTogglingAndSave);
updateTimeSlotTypeToggling();
schedEditor.find('#timeslot-type-toggles-modal .timeslot-type-toggles .select-all')
.get(0)
.addEventListener(
'click',
function() {
timeSlotTypeInputs.prop('checked', true);
updateTimeSlotTypeToggling();
updateTimeSlotTypeTogglingAndSave();
});
schedEditor.find('#timeslot-type-toggles-modal .timeslot-type-toggles .clear-all')
.get(0)
.addEventListener(
'click',
function() {
timeSlotTypeInputs.prop('checked', false);
updateTimeSlotTypeToggling();
updateTimeSlotTypeTogglingAndSave();
});
}

Expand Down
2 changes: 1 addition & 1 deletion ietf/templates/meeting/edit_meeting_schedule.html
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ <h5 class="modal-title" id="timeslot-type-toggles-modal-title">Displayed types</
<label class="timeslot-type-{{ type.slug }}">
<input type="checkbox"
class="form-check-input"
{% if type.slug == 'regular' %}checked{% endif %}
{% if type.slug in enabled_timeslot_types %}checked{% endif %}
value="{{ type.slug }}">
{{ type }}
</label>
Expand Down