Merge branch 'MDL-37350-m23' of git://github.com/andrewnicols/moodle into MOODLE_23_S...
[moodle.git] / enrol / yui / rolemanager / rolemanager.js
CommitLineData
a70eb30f
SH
1YUI.add('moodle-enrol-rolemanager', function(Y) {
2
3 var MOD_NAME = 'Moodle role manager',
4 MOD_USER = 'Moodle role user',
5 MOD_PANEL = 'Moodle role assignment panel',
6 USERIDS = 'userIds',
7 COURSEID = 'courseId',
8 USERID = 'userId',
9 CONTAINER = 'container',
10 CONTAINERID = 'containerId',
11 ASSIGNABLEROLES = 'assignableRoles',
12 ASSIGNROLELINK = 'assignRoleLink',
13 ASSIGNROLELINKSELECTOR = 'assignRoleLinkSelector',
14 UNASSIGNROLELINKS = 'unassignRoleLinks',
15 UNASSIGNROLELINKSSELECTOR = 'unassignRoleLinksSelector',
16 MANIPULATOR = 'manipulator',
9f15347e
SH
17 CURRENTROLES = 'currentroles',
18 OTHERUSERS = 'otherusers';
a70eb30f
SH
19
20 var ROLE = function(config) {
21 ROLE.superclass.constructor.apply(this, arguments);
8505d925 22 };
a70eb30f
SH
23 ROLE.NAME = MOD_NAME;
24 ROLE.ATTRS = {
25 containerId : {
26 validator: Y.Lang.isString
27 },
28 container : {
29 setter : function(node) {
30 var n = Y.one(node);
31 if (!n) {
32 Y.fail(MOD_NAME+': invalid container set');
33 }
34 return n;
35 }
36 },
37 courseId : {
38 value: 0,
39 setter : function(courseId) {
40 if (!(/^\d+$/.test(courseId))) {
41 Y.fail(MOD_NAME+': Invalid course id specified');
42 }
43 return courseId;
44 }
45 },
46 userIds : {
47 validator: Y.Lang.isArray
48 },
49 assignableRoles : {
50 value : []
9f15347e
SH
51 },
52 otherusers : {
53 value : false
a70eb30f 54 }
8505d925 55 };
a70eb30f
SH
56 Y.extend(ROLE, Y.Base, {
57 users : [],
58 roleAssignmentPanel : null,
a70eb30f
SH
59 rolesLoadedEvent : null,
60 escCloseEvent : null,
61 initializer : function(config) {
62 var i;
63 var container = Y.one('#'+this.get(CONTAINERID));
64 container.addClass('ajaxactive');
65 this.set(CONTAINER, container);
8505d925 66
a70eb30f
SH
67 var userids = this.get(USERIDS);
68 for (i in userids) {
69 this.users[userids[i]] = new ROLEUSER({userId:userids[i],manipulator:this}).wire();
70 }
71 },
72 addRole : function(e, user) {
73 e.halt();
74 this.rolesLoadedEvent = this.on('assignablerolesloaded', function(){
75 this.rolesLoadedEvent.detach();
76 var panel = this._getRoleAssignmentPanel();
f9681cff
ARN
77 panel.hide();
78 panel.submitevent = panel.on('submit', this.addRoleCallback, this);
79 panel.display(user);
a70eb30f
SH
80 }, this);
81 this._loadAssignableRoles();
82 },
83 addRoleCallback : function(e, roleid, userid) {
a70eb30f 84 var panel = this._getRoleAssignmentPanel();
f9681cff
ARN
85 panel.submitevent.detach();
86 panel.submitevent = null;
a70eb30f
SH
87 Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
88 method:'POST',
89 data:'id='+this.get(COURSEID)+'&action=assign&sesskey='+M.cfg.sesskey+'&roleid='+roleid+'&user='+userid,
90 on: {
91 complete: function(tid, outcome, args) {
92 try {
93 var o = Y.JSON.parse(outcome.responseText);
6db3eee0
SH
94 if (o.error) {
95 new M.core.ajaxException(o);
96 } else {
a1ead9a4 97 this.users[userid].addRoleToDisplay(args.roleid, this.get(ASSIGNABLEROLES)[args.roleid]);
a70eb30f
SH
98 }
99 } catch (e) {
6db3eee0 100 new M.core.exception(e);
a70eb30f
SH
101 }
102 panel.hide();
103 }
104 },
105 context:this,
106 arguments:{
107 roleid : roleid
108 }
109 });
110 },
111 removeRole : function(e, user, roleid) {
112 e.halt();
6db3eee0
SH
113 var event = this.on('assignablerolesloaded', function(){
114 event.detach();
115 var s = M.str.role, confirmation = {
116 lightbox : true,
117 title : s.confirmunassigntitle,
118 question : s.confirmunassign,
119 yesLabel : s.confirmunassignyes,
120 noLabel : s.confirmunassignno
8505d925 121 };
6db3eee0
SH
122 new M.core.confirm(confirmation).on('complete-yes', this.removeRoleCallback, this, user.get(USERID), roleid);
123 }, this);
124 this._loadAssignableRoles();
a70eb30f
SH
125 },
126 removeRoleCallback : function(e, userid, roleid) {
127 Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
128 method:'POST',
129 data:'id='+this.get(COURSEID)+'&action=unassign&sesskey='+M.cfg.sesskey+'&role='+roleid+'&user='+userid,
130 on: {
131 complete: function(tid, outcome, args) {
6db3eee0 132 var o;
a70eb30f 133 try {
6db3eee0
SH
134 o = Y.JSON.parse(outcome.responseText);
135 if (o.error) {
136 new M.core.ajaxException(o);
137 } else {
a70eb30f
SH
138 this.users[userid].removeRoleFromDisplay(args.roleid);
139 }
140 } catch (e) {
6db3eee0 141 new M.core.exception(e);
a70eb30f
SH
142 }
143 }
144 },
145 context:this,
146 arguments:{
147 roleid : roleid
148 }
149 });
150 },
151 _loadAssignableRoles : function() {
9f15347e
SH
152 var c = this.get(COURSEID), params = {
153 id : this.get(COURSEID),
154 otherusers : (this.get(OTHERUSERS))?'true':'false',
155 action : 'getassignable',
156 sesskey : M.cfg.sesskey
157 };
a70eb30f
SH
158 Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
159 method:'POST',
9f15347e 160 data:build_querystring(params),
a70eb30f
SH
161 on: {
162 complete: function(tid, outcome, args) {
163 try {
164 var roles = Y.JSON.parse(outcome.responseText);
165 this.set(ASSIGNABLEROLES, roles.response);
166 } catch (e) {
6db3eee0 167 new M.core.exception(e);
a70eb30f
SH
168 }
169 this._loadAssignableRoles = function() {
170 this.fire('assignablerolesloaded');
8505d925 171 };
a70eb30f
SH
172 this._loadAssignableRoles();
173 }
174 },
175 context:this
176 });
177 },
178 _getRoleAssignmentPanel : function() {
179 if (this.roleAssignmentPanel === null) {
180 this.roleAssignmentPanel = new ROLEPANEL({manipulator:this});
181 }
182 return this.roleAssignmentPanel;
183 }
184 });
185 Y.augment(ROLE, Y.EventTarget);
186
187 var ROLEUSER = function(config) {
188 ROLEUSER.superclass.constructor.apply(this, arguments);
8505d925 189 };
a70eb30f
SH
190 ROLEUSER.NAME = MOD_USER;
191 ROLEUSER.ATTRS = {
192 userId : {
193 validator: Y.Lang.isNumber
194 },
195 manipulator : {
196 validator: Y.Lang.isObject
197 },
198 container : {
199 setter : function(node) {
200 var n = Y.one(node);
201 if (!n) {
202 Y.fail(MOD_USER+': invalid container set '+node);
203 }
204 return n;
205 }
206 },
207 assignableroles : {
208 value : []
209 },
210 currentroles : {
211 value : [],
212 validator: Y.Lang.isArray
213 },
214 assignRoleLink : {
215 setter : function(node) {
216 if (node===false) {
217 return node;
218 }
219 var n = Y.one(node);
220 if (!n) {
221 Y.fail(MOD_NAME+': invalid assign role link given '+node);
222 }
223 return n;
224 },
225 value : false
226 },
227 assignRoleLinkSelector : {
228 value : '.assignrolelink',
229 validator : Y.Lang.isString
230 },
231 unassignRoleLinks : {
232 },
233 unassignRoleLinksSelector : {
234 value : '.unassignrolelink',
235 validator : Y.Lang.isString
236 }
8505d925 237 };
a70eb30f
SH
238 Y.extend(ROLEUSER, Y.Base, {
239 initializer : function() {
240 var container = this.get(MANIPULATOR).get(CONTAINER).one('#user_'+this.get(USERID));
241 this.set(CONTAINER, container);
242 var assignrole = container.one(this.get(ASSIGNROLELINKSELECTOR));
243 if (assignrole) {
244 this.set(ASSIGNROLELINK, assignrole.ancestor());
245 }
246 this.set(UNASSIGNROLELINKS , container.all(this.get(UNASSIGNROLELINKSSELECTOR)));
247 },
248 wire : function() {
249 var container = this.get(MANIPULATOR).get(CONTAINER).one('#user_'+this.get(USERID));
250 var arl = this.get(ASSIGNROLELINK);
251 var uarls = this.get(UNASSIGNROLELINKS);
252 var m = this.get(MANIPULATOR);
253 if (arl) {
254 arl.ancestor().on('click', m.addRole, m, this);
255 }
256 var currentroles = [];
257 if (uarls.size() > 0) {
258 uarls.each(function(link){
259 link.roleId = link.getAttribute('rel');
260 link.on('click', m.removeRole, m, this, link.roleId);
261 currentroles[link.roleId] = true;
262 }, this);
263 }
264 container.all('.role.unchangeable').each(function(node){
265 currentroles[node.getAttribute('rel')] = true;
266 }, this);
8505d925 267
a70eb30f
SH
268 this.set(CURRENTROLES, currentroles);
269 return this;
270 },
271 _checkIfHasAllRoles : function() {
272 var roles = this.get(MANIPULATOR).get(ASSIGNABLEROLES);
273 var current = this.get(CURRENTROLES);
274 var allroles = true, i = 0;
275 for (i in roles) {
276 if (!current[i]) {
277 allroles = false;
278 break;
279 }
280 }
281 var link = this.get(ASSIGNROLELINK);
282 if (allroles) {
283 this.get(CONTAINER).addClass('hasAllRoles');
284 } else {
285 if (!link) {
286 var m = this.get(MANIPULATOR);
6db3eee0
SH
287 link = Y.Node.create('<div class="addrole"></div>').append(
288 Y.Node.create('<img alt="" />').setAttribute('src', M.util.image_url('t/enroladd', 'moodle'))
289 );
a70eb30f
SH
290 link.on('click', m.addRole, m, this);
291 this.get(CONTAINER).one('.col_role').insert(link, 0);
292 this.set(ASSIGNROLELINK, link);
293 }
294 this.get(CONTAINER).removeClass('hasAllRoles');
295 }
296 },
297 addRoleToDisplay : function(roleId, roleTitle) {
298 var m = this.get(MANIPULATOR);
299 var container = this.get(CONTAINER);
300 var role = Y.Node.create('<div class="role role_'+roleId+'">'+roleTitle+'<a class="unassignrolelink"><img src="'+M.util.image_url('t/delete', 'moodle')+'" alt="" /></a></div>');
301 var link = role.one('.unassignrolelink');
302 link.roleId = roleId;
303 link.on('click', m.removeRole, m, this, link.roleId);
304 container.one('.col_role .roles').append(role);
305 this._toggleCurrentRole(link.roleId, true);
306 },
307 removeRoleFromDisplay : function(roleId) {
308 var container = this.get(CONTAINER);
309 container.all('.role_'+roleId).remove();
310 this._toggleCurrentRole(roleId, false);
311 },
312 _toggleCurrentRole : function(roleId, hasRole) {
313 var roles = this.get(CURRENTROLES);
314 if (hasRole) {
315 roles[roleId] = true;
316 } else {
317 roles[roleId] = false;
318 }
319 this.set(CURRENTROLES, roles);
320 this._checkIfHasAllRoles();
321 }
322 });
323
324 var ROLEPANEL = function(config) {
325 ROLEPANEL.superclass.constructor.apply(this, arguments);
8505d925 326 };
a70eb30f
SH
327 ROLEPANEL.NAME = MOD_PANEL;
328 ROLEPANEL.ATTRS = {
329 elementNode : {
330 setter : function(node) {
331 var n = Y.one(node);
332 if (!n) {
333 Y.fail(MOD_PANEL+': Invalid element node');
334 }
335 return n;
336 }
337 },
338 contentNode : {
339 setter : function(node) {
340 var n = Y.one(node);
341 if (!n) {
342 Y.fail(MOD_PANEL+': Invalid content node');
343 }
344 return n;
345 }
346 },
347 manipulator : {
348 validator: Y.Lang.isObject
349 }
8505d925 350 };
a70eb30f
SH
351 Y.extend(ROLEPANEL, Y.Base, {
352 user : null,
353 roles : [],
f9681cff 354 submitevent : null,
a70eb30f
SH
355 initializer : function() {
356 var i, m = this.get(MANIPULATOR);
357 var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.str.role.assignroles+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
358 var content = element.one('.content');
359 var roles = m.get(ASSIGNABLEROLES);
360 for (i in roles) {
361 var button = Y.Node.create('<input type="button" value="'+roles[i]+'" id="add_assignable_role_'+i+'" />');
362 button.on('click', this.submit, this, i);
363 content.append(button);
364 }
365 Y.one(document.body).append(element);
366 this.set('elementNode', element);
367 this.set('contentNode', content);
368 element.one('.header .close').on('click', this.hide, this);
369 },
370 display : function(user) {
9f15347e 371 var currentroles = user.get(CURRENTROLES), node = null;
a70eb30f
SH
372 for (var i in currentroles) {
373 if (currentroles[i] === true) {
9f15347e
SH
374 if (node = this.get('contentNode').one('#add_assignable_role_'+i)) {
375 node.setAttribute('disabled', 'disabled');
376 }
a70eb30f
SH
377 this.roles.push(i);
378 }
379 }
380 this.user = user;
381 var roles = this.user.get(CONTAINER).one('.col_role .roles');
382 var x = roles.getX() + 10;
6db3eee0
SH
383 var y = roles.getY() + this.user.get(CONTAINER).get('offsetHeight') - 10;
384 this.get('elementNode').setStyle('left', x).setStyle('top', y);
a70eb30f
SH
385 this.get('elementNode').addClass('visible');
386 this.escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
387 this.displayed = true;
388 },
389 hide : function() {
390 if (this._escCloseEvent) {
391 this._escCloseEvent.detach();
392 this._escCloseEvent = null;
393 }
9f15347e 394 var node = null;
a70eb30f 395 for (var i in this.roles) {
d099348e 396 if (node = this.get('contentNode').one('#add_assignable_role_'+this.roles[i])) {
9f15347e
SH
397 node.removeAttribute('disabled');
398 }
a70eb30f
SH
399 }
400 this.roles = [];
401 this.user = null;
402 this.get('elementNode').removeClass('visible');
f9681cff
ARN
403 if (this.submitevent) {
404 this.submitevent.detach();
405 this.submitevent = null;
406 }
a70eb30f
SH
407 this.displayed = false;
408 return this;
409 },
410 submit : function(e, roleid) {
411 this.fire('submit', roleid, this.user.get(USERID));
412 }
413 });
414 Y.augment(ROLEPANEL, Y.EventTarget);
415
416 M.enrol = M.enrol || {};
417 M.enrol.rolemanager = {
418 instance : null,
419 init : function(config) {
420 M.enrol.rolemanager.instance = new ROLE(config);
421 return M.enrol.rolemanager.instance;
422 }
423 }
8505d925 424
f9681cff 425}, '@VERSION@', {requires:['base','node','io-base','json-parse','test','moodle-enrol-notification']});