MDL-57690 js: fix missing requirement before using M.core.dialogue
[moodle.git] / lib / amd / src / permissionmanager.js
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  * @package    core
17  * @class      permissionmanager
18  * @copyright  2015 Martin Mastny <mastnym@vscht.cz>
19  * @since      3.0
20  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21  */
23  /**
24   * @module admin/permissionmanager
25   */
26 define(['jquery', 'core/config', 'core/notification', 'core/templates'], function($, config, notification, templates) {
28      /**
29       * Used CSS selectors
30       * @access private
31       */
32     var SELECTORS = {
33         ADDROLE: 'a.allowlink, a.prohibitlink',
34         REMOVEROLE: 'a.preventlink, a.unprohibitlink',
35         UNPROHIBIT: 'a.unprohibitlink'
36         };
37     var rolesloadedevent = $.Event('rolesloaded');
38     var contextid;
39     var contextname;
40     var adminurl;
41     var overideableroles;
42     var panel = null;
44     /**
45      * Load all possible roles, which could be assigned from server
46      *
47      * @access private
48      * @method loadOverideableRoles
49      */
50     var loadOverideableRoles = function() {
51         var params = {
52             contextid: contextid,
53             getroles: 1,
54             sesskey: config.sesskey
55         };
57         // Need to tell jQuery to expect JSON as the content type may not be correct (MDL-55041).
58         $.post(adminurl + 'roles/ajax.php', params, null, 'json')
59             .done(function(data) {
60               try {
61                   overideableroles = data;
62                   loadOverideableRoles = function() {
63                       $('body').trigger(rolesloadedevent);
64                   };
65                   loadOverideableRoles();
66               } catch (err) {
67                   notification.exception(err);
68               }
69             })
70             .fail(function(jqXHR, status, error) {
71                 notification.exception(error);
72             });
73     };
75     /**
76      * Perform the UI changes after server change
77      *
78      * @access private
79      * @method changePermissions
80      * @param {JQuery} row
81      * @param {int} roleid
82      * @param {string} action
83      */
84     var changePermissions = function(row, roleid, action) {
85         var params = {
86             contextid: contextid,
87             roleid: roleid,
88             sesskey: M.cfg.sesskey,
89             action: action,
90             capability: row.data('name')
91         };
92         $.post(adminurl + 'roles/ajax.php', params, null, 'json')
93         .done(function(data) {
94             var action = data;
95             try {
96                 var templatedata = {rolename: overideableroles[roleid],
97                                     roleid: roleid,
98                                     adminurl: adminurl,
99                                     imageurl: M.util.image_url('t/delete', 'moodle')
100                                     };
101                 switch (action) {
102                     case 'allow':
103                         templatedata.spanclass = 'allowed';
104                         templatedata.linkclass = 'preventlink';
105                         templatedata.action = 'prevent';
106                         break;
107                     case 'prohibit':
108                         templatedata.spanclass = 'forbidden';
109                         templatedata.linkclass = 'unprohibitlink';
110                         templatedata.action = 'unprohibit';
111                         break;
112                     case 'prevent':
113                         row.find('a[data-role-id="' + roleid + '"]').first().closest('.allowed').remove();
114                         return;
115                     case 'unprohibit':
116                         row.find('a[data-role-id="' + roleid + '"]').first().closest('.forbidden').remove();
117                         return;
118                     default:
119                         return;
120                 }
121                 templates.render('core/permissionmanager_role', templatedata)
122                 .done(function(content) {
123                     if (action == 'allow') {
124                         $(content).insertBefore(row.find('.allowmore:first'));
125                     } else if (action == 'prohibit') {
126                         $(content).insertBefore(row.find('.prohibitmore:first'));
127                         // Remove allowed link
128                         var allowedLink = row.find('.allowedroles').first().find('a[data-role-id="' + roleid + '"]');
129                         if (allowedLink) {
130                             allowedLink.first().closest('.allowed').remove();
131                         }
132                     }
133                     panel.hide();
134                 })
135                 .fail(notification.exception);
136             } catch (err) {
137                 notification.exception(err);
138             }
139         })
140         .fail(function(jqXHR, status, error) {
141             notification.exception(error);
142         });
143     };
145     /**
146      * Prompts user for selecting a role which is permitted
147      *
148      * @access private
149      * @method handleAddRole
150      * @param {event} e
151      */
152     var handleAddRole = function(e) {
153         e.preventDefault();
155         $('body').one('rolesloaded', function() {
156             var link = $(e.currentTarget);
157             var action = link.data('action');
158             var row = link.closest('tr.rolecap');
159             var confirmationDetails = {
160                 cap: row.data('humanname'),
161                 context: contextname
162             };
163             var message = M.util.get_string('role' + action + 'info', 'core_role', confirmationDetails);
164             if (panel === null) {
165                 panel = new M.core.dialogue({
166                     draggable: true,
167                     modal: true,
168                     closeButton: true,
169                     width: '450px'
170                 });
171             }
172             panel.set('headerContent', M.util.get_string('role' + action + 'header', 'core_role'));
174             var i, existingrolelinks;
176             var roles = [];
177             switch (action) {
178                 case 'allow':
179                     existingrolelinks = row.find(SELECTORS.REMOVEROLE);
180                     break;
181                 case 'prohibit':
182                     existingrolelinks = row.find(SELECTORS.UNPROHIBIT);
183                     break;
184             }
185             for (i in overideableroles) {
186                 var disabled = '';
187                 var disable = existingrolelinks.filter("[data-role-id='" + i + "']").length;
188                 if (disable) {
189                     disabled = 'disabled';
190                 }
191                 var roledetails = {roleid: i, rolename: overideableroles[i], disabled: disabled};
192                 roles.push(roledetails);
193             }
195             templates.render('core/permissionmanager_panelcontent', {message: message, roles: roles})
196             .done(function(content) {
197                 panel.set('bodyContent', content);
198                 panel.show();
199                 $('div.role_buttons').delegate('input', 'click', function(e) {
200                     var roleid = $(e.currentTarget).data('role-id');
201                     changePermissions(row, roleid, action);
202                 });
203             })
204             .fail(notification.exception);
206         });
207         loadOverideableRoles();
208     };
210     /**
211      * Prompts user when removing permission
212      *
213      * @access private
214      * @method handleRemoveRole
215      * @param {event} e
216      */
217     var handleRemoveRole = function(e) {
218         e.preventDefault();
219         $('body').one('rolesloaded', function() {
220             var link = $(e.currentTarget);
221             var action = link.data('action');
222             var roleid = link.data('role-id');
223             var row = link.closest('tr.rolecap');
224             var questionDetails = {
225                 role: overideableroles[roleid],
226                 cap: row.data('humanname'),
227                 context: contextname
228             };
230             notification.confirm(M.util.get_string('confirmunassigntitle', 'core_role'),
231                 M.util.get_string('confirmrole' + action, 'core_role', questionDetails),
232                 M.util.get_string('confirmunassignyes', 'core_role'),
233                 M.util.get_string('confirmunassignno', 'core_role'),
234                 function() {
235                    changePermissions(row, roleid, action);
236                 }
237             );
238          });
239         loadOverideableRoles();
240     };
242     return /** @alias module:core/permissionmanager */ {
243         /**
244          * Initialize permissionmanager
245          * @access public
246          * @param {Object} args
247          */
248         initialize: function(args) {
249             contextid = args.contextid;
250             contextname = args.contextname;
251             adminurl = args.adminurl;
252             var body = $('body');
253             body.delegate(SELECTORS.ADDROLE, 'click', handleAddRole);
254             body.delegate(SELECTORS.REMOVEROLE, 'click', handleRemoveRole);
255         }
256     };
257 });