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