MDL-63352 block_timeline: Persist user preference on timeline
[moodle.git] / blocks / timeline / amd / src / view_nav.js
CommitLineData
1e44de35
RW
1// This file is part of Moodle - http://moodle.org/
2//
3// Moodle is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// Moodle is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
15
16/**
17 * Manage the timeline view navigation for the timeline block.
18 *
19 * @package block_timeline
20 * @copyright 2018 Ryan Wyllie <ryan@moodle.com>
21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24define(
25[
26 'jquery',
27 'core/custom_interaction_events',
9e95193e
P
28 'block_timeline/view',
29 'core/ajax',
30 'core/notification'
1e44de35
RW
31],
32function(
33 $,
34 CustomEvents,
9e95193e
P
35 View,
36 Ajax,
37 Notification
1e44de35
RW
38) {
39
40 var SELECTORS = {
41 TIMELINE_DAY_FILTER: '[data-region="day-filter"]',
42 TIMELINE_DAY_FILTER_OPTION: '[data-from]',
43 TIMELINE_VIEW_SELECTOR: '[data-region="view-selector"]',
44 DATA_DAYS_OFFSET: '[data-days-offset]',
45 DATA_DAYS_LIMIT: '[data-days-limit]',
46 };
47
9e95193e
P
48 /**
49 * Generic handler to persist user preferences
50 *
51 * @param {string} type The name of the attribute you're updating
52 * @param {string} value The value of the attribute you're updating
53 */
54 var updateUserPreferences = function(type, value) {
55 var request = {
56 methodname: 'core_user_update_user_preferences',
57 args: {
58 preferences: [
59 {
60 type: type,
61 value: value
62 }
63 ]
64 }
65 };
66
67 Ajax.call([request])[0]
68 .fail(Notification.exception);
69 };
70
1e44de35
RW
71 /**
72 * Event listener for the day selector ("Next 7 days", "Next 30 days", etc).
73 *
74 * @param {object} root The root element for the timeline block
75 * @param {object} timelineViewRoot The root element for the timeline view
76 */
77 var registerTimelineDaySelector = function(root, timelineViewRoot) {
78 var timelineDaySelectorContainer = root.find(SELECTORS.TIMELINE_DAY_FILTER);
79
80 CustomEvents.define(timelineDaySelectorContainer, [CustomEvents.events.activate]);
81 timelineDaySelectorContainer.on(
82 CustomEvents.events.activate,
83 SELECTORS.TIMELINE_DAY_FILTER_OPTION,
84 function(e, data) {
9e95193e
P
85 // Update the user preference
86 var filtername = $(e.currentTarget).data('filtername');
87 var type = 'block_timeline_user_filter_preference';
88 updateUserPreferences(type, filtername);
89
1e44de35
RW
90 var option = $(e.target).closest(SELECTORS.TIMELINE_DAY_FILTER_OPTION);
91
92 if (option.hasClass('active')) {
93 // If it's already active then we don't need to do anything.
94 return;
95 }
96
97 var daysOffset = option.attr('data-from');
98 var daysLimit = option.attr('data-to');
99 var elementsWithDaysOffset = root.find(SELECTORS.DATA_DAYS_OFFSET);
100
101 elementsWithDaysOffset.attr('data-days-offset', daysOffset);
102
103 if (daysLimit != undefined) {
104 elementsWithDaysOffset.attr('data-days-limit', daysLimit);
105 } else {
106 elementsWithDaysOffset.removeAttr('data-days-limit');
107 }
108
109 // Reset the views to reinitialise the event lists now that we've
110 // updated the day limits.
111 View.reset(timelineViewRoot);
112
113 data.originalEvent.preventDefault();
114 }
115 );
116 };
117
118 /**
119 * Event listener for the "sort" button in the timeline navigation that allows for
120 * changing between the timeline dates and courses views.
121 *
122 * On a view change we tell the timeline view module that the view has been shown
123 * so that it can handle how to display the appropriate view.
124 *
125 * @param {object} root The root element for the timeline block
126 * @param {object} timelineViewRoot The root element for the timeline view
127 */
128 var registerViewSelector = function(root, timelineViewRoot) {
9e95193e
P
129 var viewSelector = root.find(SELECTORS.TIMELINE_VIEW_SELECTOR);
130
1e44de35
RW
131 // Listen for when the user changes tab so that we can show the first set of courses
132 // and load their events when they request the sort by courses view for the first time.
9e95193e 133 viewSelector.on('shown shown.bs.tab', function() {
1e44de35
RW
134 View.shown(timelineViewRoot);
135 });
9e95193e
P
136
137 // Event selector for user_sort
138 CustomEvents.define(viewSelector, [CustomEvents.events.activate]);
139 viewSelector.on(CustomEvents.events.activate, "[data-toggle='tab']", function(e) {
140 var filtername = $(e.currentTarget).data('filtername');
141 var type = 'block_timeline_user_sort_preference';
142 updateUserPreferences(type, filtername);
143 });
1e44de35
RW
144 };
145
146 /**
147 * Initialise the timeline view navigation by adding event listeners to
148 * the navigation elements.
149 *
150 * @param {object} root The root element for the timeline block
151 * @param {object} timelineViewRoot The root element for the timeline view
152 */
153 var init = function(root, timelineViewRoot) {
154 root = $(root);
155 registerTimelineDaySelector(root, timelineViewRoot);
156 registerViewSelector(root, timelineViewRoot);
157 };
158
159 return {
160 init: init
161 };
162});