From bd2eb529853a205d8ac5b1ab01273a03f932f91e Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 18 Mar 2022 18:29:02 -0300 Subject: [PATCH 1/3] feat: persist timeslot types made visible in the schedule editor This adds a POST action to the edit_meeting_schedule view that sets a list of currently visible timeslot types in the user's session. On display of the schedule editor, this is consulted before defaulting to show only 'regular' timeslots. An ajax request is made to update the session when changing the settings in the editor. --- ietf/meeting/views.py | 25 ++++++- ietf/static/js/edit-meeting-schedule.js | 65 +++++++++++-------- .../meeting/edit_meeting_schedule.html | 2 +- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index 04a54d9a102..3b0123e9401 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -728,10 +728,11 @@ def _json_response(success, status=None, **extra_data): return JsonResponse(data, status=status) if request.method == 'POST': - if not can_edit: + action = request.POST.get('action') + # allow updateview action even if can_edit is false, it affects only the user's session + if not (can_edit or action == 'updateview'): permission_denied(request, "Can't edit this schedule.") - action = request.POST.get('action') # 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 @@ -863,6 +864,15 @@ def _json_response(success, status=None, **extra_data): ) return HttpResponseRedirect(request.get_full_path()) + elif action == 'updateview': + 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) + return _json_response(False, error="Invalid parameters") # Show only rooms that have regular sessions @@ -949,6 +959,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, @@ -963,6 +983,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, }) diff --git a/ietf/static/js/edit-meeting-schedule.js b/ietf/static/js/edit-meeting-schedule.js index 0adc0133099..925c3252e32 100644 --- a/ietf/static/js/edit-meeting-schedule.js +++ b/ietf/static/js/edit-meeting-schedule.js @@ -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 @@ -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); } }); @@ -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 @@ -783,7 +792,7 @@ $(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) @@ -791,7 +800,7 @@ $(function () { 'click', function() { timeSlotTypeInputs.prop('checked', true); - updateTimeSlotTypeToggling(); + updateTimeSlotTypeTogglingAndSave(); }); schedEditor.find('#timeslot-type-toggles-modal .timeslot-type-toggles .clear-all') .get(0) @@ -799,7 +808,7 @@ $(function () { 'click', function() { timeSlotTypeInputs.prop('checked', false); - updateTimeSlotTypeToggling(); + updateTimeSlotTypeTogglingAndSave(); }); } diff --git a/ietf/templates/meeting/edit_meeting_schedule.html b/ietf/templates/meeting/edit_meeting_schedule.html index f073a66068f..a371ef1a9cb 100644 --- a/ietf/templates/meeting/edit_meeting_schedule.html +++ b/ietf/templates/meeting/edit_meeting_schedule.html @@ -312,7 +312,7 @@