Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Request actions.
18
 *
19
 * @module     tool_dataprivacy/data_registry
20
 * @copyright  2018 David Monllao
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
define(['jquery', 'core/str', 'core/ajax', 'core/notification', 'core/templates',
24
    'core/fragment', 'tool_dataprivacy/add_purpose', 'tool_dataprivacy/add_category'],
25
    function($, Str, Ajax, Notification, Templates, Fragment, AddPurpose, AddCategory) {
26
 
27
        var SELECTORS = {
28
            TREE_NODES: '[data-context-tree-node=1]',
29
            FORM_CONTAINER: '#context-form-container',
30
        };
31
 
32
        var DataRegistry = function(systemContextId, initContextLevel, initContextId) {
33
            this.systemContextId = systemContextId;
34
            this.currentContextLevel = initContextLevel;
35
            this.currentContextId = initContextId;
36
            this.init();
37
        };
38
 
39
        /**
40
         * @var {int} systemContextId
41
         * @private
42
         */
43
        DataRegistry.prototype.systemContextId = 0;
44
 
45
        /**
46
         * @var {int} currentContextLevel
47
         * @private
48
         */
49
        DataRegistry.prototype.currentContextLevel = 0;
50
 
51
        /**
52
         * @var {int} currentContextId
53
         * @private
54
         */
55
        DataRegistry.prototype.currentContextId = 0;
56
 
57
        /**
58
         * @var {AddPurpose} addpurpose
59
         * @private
60
         */
61
        DataRegistry.prototype.addpurpose = null;
62
 
63
        /**
64
         * @var {AddCategory} addcategory
65
         * @private
66
         */
67
        DataRegistry.prototype.addcategory = null;
68
 
69
        DataRegistry.prototype.init = function() {
70
            // Add purpose and category modals always at system context.
71
            this.addpurpose = AddPurpose.getInstance(this.systemContextId);
72
            this.addcategory = AddCategory.getInstance(this.systemContextId);
73
 
74
            var stringKeys = [
75
                {
76
                    key: 'changessaved',
77
                    component: 'moodle'
78
                }, {
79
                    key: 'contextpurposecategorysaved',
80
                    component: 'tool_dataprivacy'
81
                }, {
82
                    key: 'noblockstoload',
83
                    component: 'tool_dataprivacy'
84
                }, {
85
                    key: 'noactivitiestoload',
86
                    component: 'tool_dataprivacy'
87
                }, {
88
                    key: 'nocoursestoload',
89
                    component: 'tool_dataprivacy'
90
                }
91
            ];
92
            this.strings = Str.get_strings(stringKeys);
93
 
94
            this.registerEventListeners();
95
 
96
            // Load the default context level form.
97
            if (this.currentContextId) {
98
                this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));
99
            } else {
100
                this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));
101
            }
102
        };
103
 
104
        DataRegistry.prototype.registerEventListeners = function() {
105
            $(SELECTORS.TREE_NODES).on('click', function(ev) {
106
                ev.preventDefault();
107
 
108
                var trigger = $(ev.currentTarget);
109
 
110
                // Active node.
111
                $(SELECTORS.TREE_NODES).removeClass('active');
112
                trigger.addClass('active');
113
 
114
                var contextLevel = trigger.data('contextlevel');
115
                var contextId = trigger.data('contextid');
116
                if (contextLevel) {
117
                    // Context level level.
118
 
119
                    window.history.pushState({}, null, '?contextlevel=' + contextLevel);
120
 
121
                    // Remove previous add purpose and category listeners to avoid memory leaks.
122
                    this.addpurpose.removeListeners();
123
                    this.addcategory.removeListeners();
124
 
125
                    // Load the context level form.
126
                    this.currentContextLevel = contextLevel;
127
                    this.loadForm('contextlevel_form', [this.currentContextLevel], this.submitContextLevelFormAjax.bind(this));
128
                } else if (contextId) {
129
                    // Context instance level.
130
 
131
                    window.history.pushState({}, null, '?contextid=' + contextId);
132
 
133
                    // Remove previous add purpose and category listeners to avoid memory leaks.
134
                    this.addpurpose.removeListeners();
135
                    this.addcategory.removeListeners();
136
 
137
                    // Load the context level form.
138
                    this.currentContextId = contextId;
139
                    this.loadForm('context_form', [this.currentContextId], this.submitContextFormAjax.bind(this));
140
                } else {
141
                    // Expandable nodes.
142
 
143
                    var expandContextId = trigger.data('expandcontextid');
144
                    var expandElement = trigger.data('expandelement');
145
                    var expanded = trigger.data('expanded');
146
 
147
                    // Extra checking that there is an expandElement because we remove it after loading 0 branches.
148
                    if (expandElement) {
149
 
150
                        if (!expanded) {
151
                            if (trigger.data('loaded') || !expandContextId || !expandElement) {
152
                                this.expand(trigger);
153
                            } else {
154
 
155
                                trigger.find('> i').removeClass('fa-plus');
156
                                trigger.find('> i').addClass('fa-circle-o-notch fa-spin');
157
                                this.loadExtra(trigger, expandContextId, expandElement);
158
                            }
159
                        } else {
160
                            this.collapse(trigger);
161
                        }
162
                    }
163
                }
164
 
165
            }.bind(this));
166
        };
167
 
168
        DataRegistry.prototype.removeListeners = function() {
169
            $(SELECTORS.TREE_NODES).off('click');
170
        };
171
 
172
        DataRegistry.prototype.loadForm = function(fragmentName, fragmentArgs, formSubmitCallback) {
173
 
174
            this.clearForm();
175
 
176
            var fragment = Fragment.loadFragment('tool_dataprivacy', fragmentName, this.systemContextId, fragmentArgs);
177
            fragment.done(function(html, js) {
178
 
179
                $(SELECTORS.FORM_CONTAINER).html(html);
180
                Templates.runTemplateJS(js);
181
 
182
                this.addpurpose.registerEventListeners();
183
                this.addcategory.registerEventListeners();
184
 
185
                // We also catch the form submit event and use it to submit the form with ajax.
186
                $(SELECTORS.FORM_CONTAINER).on('submit', 'form', formSubmitCallback);
187
 
188
            }.bind(this)).fail(Notification.exception);
189
        };
190
 
191
        DataRegistry.prototype.clearForm = function() {
192
            // Remove previous listeners.
193
            $(SELECTORS.FORM_CONTAINER).off('submit', 'form');
194
        };
195
 
196
        /**
197
         * This triggers a form submission, so that any mform elements can do final tricks before the form submission is processed.
198
         *
199
         * @method submitForm
200
         * @param {Event} e Form submission event.
201
         * @private
202
         */
203
        DataRegistry.prototype.submitForm = function(e) {
204
            e.preventDefault();
205
            $(SELECTORS.FORM_CONTAINER).find('form').submit();
206
        };
207
 
208
        DataRegistry.prototype.submitContextLevelFormAjax = function(e) {
209
            this.submitFormAjax(e, 'tool_dataprivacy_set_contextlevel_form');
210
        };
211
 
212
        DataRegistry.prototype.submitContextFormAjax = function(e) {
213
            this.submitFormAjax(e, 'tool_dataprivacy_set_context_form');
214
        };
215
 
216
        DataRegistry.prototype.submitFormAjax = function(e, saveMethodName) {
217
            // We don't want to do a real form submission.
218
            e.preventDefault();
219
 
220
            // Convert all the form elements values to a serialised string.
221
            var formData = $(SELECTORS.FORM_CONTAINER).find('form').serialize();
222
            return this.strings.then(function(strings) {
223
                Ajax.call([{
224
                    methodname: saveMethodName,
225
                    args: {jsonformdata: JSON.stringify(formData)},
226
                    done: function() {
227
                        Notification.alert(strings[0], strings[1]);
228
                    },
229
                    fail: Notification.exception
230
                }]);
231
                return;
232
            }).catch(Notification.exception);
233
 
234
        };
235
 
236
        DataRegistry.prototype.loadExtra = function(parentNode, expandContextId, expandElement) {
237
 
238
            Ajax.call([{
239
                methodname: 'tool_dataprivacy_tree_extra_branches',
240
                args: {
241
                    contextid: expandContextId,
242
                    element: expandElement,
243
                },
244
                done: function(data) {
245
                    if (data.branches.length == 0) {
246
                        this.noElements(parentNode, expandElement);
247
                        return;
248
                    }
249
                    Templates.render('tool_dataprivacy/context_tree_branches', data)
250
                        .then(function(html) {
251
                            parentNode.after(html);
252
                            this.removeListeners();
253
                            this.registerEventListeners();
254
                            this.expand(parentNode);
255
                            parentNode.data('loaded', 1);
256
                            return;
257
                        }.bind(this))
258
                        .fail(Notification.exception);
259
                }.bind(this),
260
                fail: Notification.exception
261
            }]);
262
        };
263
 
264
        DataRegistry.prototype.noElements = function(node, expandElement) {
265
            node.data('expandcontextid', '');
266
            node.data('expandelement', '');
267
            this.strings.then(function(strings) {
268
 
269
                // 2 = blocks, 3 = activities, 4 = courses (although courses is not likely really).
270
                var key = 2;
271
                if (expandElement == 'module') {
272
                    key = 3;
273
                } else if (expandElement == 'course') {
274
                    key = 4;
275
                }
276
                node.text(strings[key]);
277
                return;
278
            }).fail(Notification.exception);
279
        };
280
 
281
        DataRegistry.prototype.collapse = function(node) {
282
            node.data('expanded', 0);
283
            node.siblings('nav').addClass('hidden');
284
            node.find('> i').removeClass('fa-minus');
285
            node.find('> i').addClass('fa-plus');
286
        };
287
 
288
        DataRegistry.prototype.expand = function(node) {
289
            node.data('expanded', 1);
290
            node.siblings('nav').removeClass('hidden');
291
            node.find('> i').removeClass('fa-plus');
292
            // Also remove the spinning one if data was just loaded.
293
            node.find('> i').removeClass('fa-circle-o-notch fa-spin');
294
            node.find('> i').addClass('fa-minus');
295
        };
296
        return /** @alias module:tool_dataprivacy/data_registry */ {
297
 
298
            /**
299
             * Initialise the page.
300
             *
301
             * @param {Number} systemContextId
302
             * @param {Number} initContextLevel
303
             * @param {Number} initContextId
304
             * @return {DataRegistry}
305
             */
306
            init: function(systemContextId, initContextLevel, initContextId) {
307
                return new DataRegistry(systemContextId, initContextLevel, initContextId);
308
            }
309
        };
310
    }
311
);