blob: 704682eafcc3ef822f72f4c9dc37007fd1fce460 [file] [log] [blame]
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +05301// ERPNext - web based ERP (http://erpnext.com)
2// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17$.extend(wn.pages.users, {
18 onload: function(wrapper) {
19 wn.pages.users.profiles = {};
20 wn.pages.users.refresh();
21 wn.pages.users.setup();
22 wn.pages.users.role_editor = new erpnext.RoleEditor();
23 },
24 setup: function() {
25 // set roles
26 $('.users-area').on('click', '.btn.user-roles', function() {
27 var uid = $(this).parent().parent().attr('data-name');
28 wn.pages.users.role_editor.show(uid);
29 });
30
31 // settings
32 $('.users-area').on('click', '.btn.user-settings', function() {
33 var uid = $(this).parent().parent().attr('data-name');
34 wn.pages.users.show_settings(uid);
35 });
36
37 // delete
38 $('.users-area').on('click', 'a.close', function() {
39 $card = $(this).parent();
40 var uid = $card.attr('data-name');
41 $card.css('opacity', 0.6);
42 wn.call({
43 method: 'utilities.page.users.users.delete',
44 args: {'uid': uid},
45 callback: function(r,rt) {
46 if(!r.exc)
47 $card.fadeOut()
48 }
49 });
50 })
51
52 },
53 refresh: function() {
54 // make the list
55 wn.call({
56 method:'utilities.page.users.users.get',
57 callback: function(r, rt) {
58 $('.users-area').empty();
59 for(var i in r.message) {
60 var p = r.message[i];
61 wn.pages.users.profiles[p.name] = p;
62 wn.pages.users.render(p);
63 }
64 }
65 });
Anand Doshi1ed4ef12012-04-27 15:30:23 +053066 if(!$('.subscription-info').length && (wn.boot.max_users || wn.boot.expires_on)) {
67 var $sub_info = $('<div class="subscription-info-box"><div>').insertAfter('.help');
68 if(wn.boot.max_users) {
69 $sub_info.append(repl('\
70 <span class="subscription-info"> \
71 Max Users: <b>%(max_users)s</b> \
72 </span>', { max_users: wn.boot.max_users }));
73 }
74 if(wn.boot.expires_on) {
75 $sub_info.append(repl('\
76 <span class="subscription-info"> \
77 Expires On: <b>%(expires_on)s</b> \
78 </span>', { expires_on: dateutil.str_to_user(wn.boot.expires_on) }));
79 }
80 }
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053081 },
82 render: function(data) {
83 if(data.file_list) {
Rushabh Mehta1572adf2012-02-29 15:19:20 +053084 data.imgsrc = 'files/' + data.file_list.split('\n')[0].split(',')[1];
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053085 } else {
Rushabh Mehta79ae1652012-02-29 15:23:25 +053086 data.imgsrc = 'lib/images/ui/no_img_' + (data.gender=='Female' ? 'f' : 'm') + '.gif';
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053087 }
Rushabh Mehta204e77d2012-02-29 19:09:20 +053088 data.fullname = wn.user_info(data.name).fullname;
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053089 data.delete_html = '';
90 if(!data.enabled)
91 data.delete_html = '<a class="close" title="delete">&times;</a>';
92
93 $('.users-area').append(repl('<div class="user-card" data-name="%(name)s">\
94 %(delete_html)s\
95 <img src="%(imgsrc)s">\
96 <div class="user-info">\
97 <b class="user-fullname">%(fullname)s</b><br>\
98 %(name)s<br>\
99 <button class="btn btn-small user-roles"><i class="icon-user"></i> Roles</button>\
100 <button class="btn btn-small user-settings"><i class="icon-cog"></i> Settings</button>\
101 </div>\
102 </div>', data));
103
104 if(!data.enabled) {
105 $('.users-area .user-card:last')
106 .addClass('disabled')
107 .find('.user-fullname').html('Disabled');
108 }
109 },
110 show_settings: function(uid) {
111 var me = wn.pages.users;
112 if(!me.settings_dialog)
113 me.make_settings_dialog();
114
115 var p = me.profiles[uid];
116 me.uid = uid;
117
118 me.settings_dialog.set_values({
119 restrict_ip: p.restrict_ip || '',
120 login_before: p.login_before || '',
121 login_after: p.login_after || '',
122 enabled: p.enabled || 0,
123 new_password: ''
124 });
125
126 me.settings_dialog.show();
127
128 },
129 make_settings_dialog: function() {
130 var me = wn.pages.users;
131 me.settings_dialog = new wn.widgets.Dialog({
132 title: 'Set User Security',
133 width: 500,
134 fields: [
135 {
136 label:'Enabled',
137 description: 'Uncheck to disable',
138 fieldtype: 'Check', fieldname: 'enabled'
139 },
140 {
141 label:'IP Address',
142 description: 'Restrict user login by IP address, partial ips (111.111.111), \
143 multiple addresses (separated by commas) allowed',
144 fieldname:'restrict_ip', fieldtype:'Data'
145 },
146 {
147 label:'Login After',
148 description: 'User can only login after this hour (0-24)',
149 fieldtype: 'Int', fieldname: 'login_after'
150 },
151 {
152 label:'Login Before',
153 description: 'User can only login before this hour (0-24)',
154 fieldtype: 'Int', fieldname: 'login_before'
155 },
156 {
157 label:'New Password',
158 description: 'Update the current user password',
159 fieldtype: 'Data', fieldname: 'new_password'
160 },
161 {
162 label:'Update', fieldtype:'Button', fieldname:'update'
163 }
164 ]
165 });
166
167 this.settings_dialog.fields_dict.update.input.onclick = function() {
168 var btn = this;
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530169 var args = me.settings_dialog.get_values();
170 args.user = me.uid;
171
172 if (args.new_password) {
173 me.get_password(btn, args);
174 } else {
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530175 me.update_security(btn, args);
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530176 }
177 };
178
179 },
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530180 update_security: function(btn, args) {
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530181 var me = wn.pages.users;
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530182 $(btn).set_working();
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530183 $c_page('utilities', 'users', 'update_security', JSON.stringify(args), function(r,rt) {
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530184 $(btn).done_working();
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530185 if(r.exc) {
186 msgprint(r.exc);
187 return;
188 }
189 me.settings_dialog.hide();
190 $.extend(me.profiles[me.uid], me.settings_dialog.get_values());
191 me.refresh();
192 });
193 },
194 get_password: function(btn, args) {
195 var me = wn.pages.users;
196 var pass_d = new wn.widgets.Dialog({
197 title: 'Your Password',
198 width: 300,
199 fields: [
200 {
201 label: 'Please Enter <b style="color: black">Your Password</b>',
202 description: "Your password is required to update the user's password",
203 fieldtype: 'Password', fieldname: 'sys_admin_pwd', reqd: 1
204 },
205 {
206 label: 'Continue', fieldtype: 'Button', fieldname: 'continue'
207 }
208 ]
209 });
210
211 pass_d.fields_dict.continue.input.onclick = function() {
212 btn.pwd_dialog.hide();
213 args.sys_admin_pwd = btn.pwd_dialog.get_values().sys_admin_pwd;
214 btn.set_working();
Anand Doshiecd8df82012-03-02 12:18:47 +0530215 me.update_security(btn, args);
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530216 btn.done_working();
217 }
218
219 pass_d.show();
220 btn.pwd_dialog = pass_d;
221 btn.done_working();
222 },
223 add_user: function() {
224 var me = wn.pages.users;
Anand Doshi1ed4ef12012-04-27 15:30:23 +0530225 var active_users = $('.user-card:not(.disabled)');
226 if(wn.boot.max_users && (active_users.length >= wn.boot.max_users)) {
227 msgprint(repl("Alas! <br />\
228 You already have <b>%(active_users)s</b> active users, \
229 which is the maximum number that you are currently allowed to add. <br /><br /> \
230 So, to add more users, you can:<br /> \
231 1. <b>Upgrade to the unlimited users plan</b>, or<br /> \
232 2. <b>Disable one or more of your existing users and try again</b>",
233 {active_users: active_users.length}));
234 return;
235 }
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530236 var d = new wn.widgets.Dialog({
237 title: 'Add User',
238 width: 400,
239 fields: [{
240 fieldtype: 'Data', fieldname: 'user', reqd: 1,
241 label: 'Email Id of the user to add'
242 }, {
243 fieldtype: 'Data', fieldname: 'first_name', reqd: 1, label: 'First Name'
244 }, {
245 fieldtype: 'Data', fieldname: 'last_name', label: 'Last Name'
246 }, {
247 fieldtype: 'Data', fieldname: 'password', reqd: 1, label: 'Password'
248 }, {
249 fieldtype: 'Button', label: 'Add', fieldname: 'add'
250 }]
251 });
252
253 d.make();
254 d.fields_dict.add.input.onclick = function() {
255 v = d.get_values();
256 if(v) {
257 d.fields_dict.add.input.set_working();
258 $c_page('utilities', 'users', 'add_user', v, function(r,rt) {
259 if(r.exc) { msgprint(r.exc); return; }
260 else {
Anand Doshia6952c92012-03-07 19:37:23 +0530261 wn.boot.user_info[v.user] = {fullname:v.first_name + ' ' + (v.last_name || '')};
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530262 d.hide();
263 me.refresh();
264 }
265 })
266 }
267 }
268 d.show();
269 }
270});
271
272erpnext.RoleEditor = Class.extend({
273 init: function() {
274 this.dialog = new wn.widgets.Dialog({
275 title: 'Set Roles'
276 });
277 var me = this;
278 $(this.dialog.body).html('<div class="help">Loading...</div>')
279 wn.call({
280 method:'utilities.page.users.users.get_roles',
281 callback: function(r) {
282 me.roles = r.message;
283 me.show_roles();
284 }
285 });
286 },
287 show_roles: function() {
288 var me = this;
289 $(this.dialog.body).empty();
290 for(var i in this.roles) {
291 $(this.dialog.body).append(repl('<div class="user-role" \
292 data-user-role="%(role)s">\
293 <input type="checkbox"> \
294 <a href="#"><i class="icon-question-sign"></i></a> %(role)s\
295 </div>', {role: this.roles[i]}));
296 }
297 $(this.dialog.body).append('<div style="clear: both">\
Rushabh Mehtab9004bd2012-03-05 18:28:33 +0530298 <button class="btn btn-small btn-info">Save</button></div>');
299 $(this.dialog.body).find('button.btn-info').click(function() {
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530300 me.save();
301 });
302 $(this.dialog.body).find('.user-role a').click(function() {
303 me.show_permissions($(this).parent().attr('data-user-role'))
304 return false;
305 })
306 },
307 show: function(uid) {
308 var me = this;
309 this.uid = uid;
310 this.dialog.show();
311 // set user roles
312 wn.call({
313 method:'utilities.page.users.users.get_user_roles',
314 args: {uid:uid},
315 callback: function(r, rt) {
316 $(me.dialog.body).find('input[type="checkbox"]').attr('checked', false);
317 for(var i in r.message) {
318 $(me.dialog.body)
319 .find('[data-user-role="'+r.message[i]
320 +'"] input[type="checkbox"]').attr('checked',true);
321 }
322 }
323 })
324 },
325 save: function() {
326 var set_roles = [];
327 var unset_roles = [];
328 $(this.dialog.body).find('[data-user-role]').each(function() {
329 var $check = $(this).find('input[type="checkbox"]');
330 if($check.attr('checked')) {
331 set_roles.push($(this).attr('data-user-role'));
332 } else {
333 unset_roles.push($(this).attr('data-user-role'));
334 }
335 })
336 wn.call({
337 method:'utilities.page.users.users.update_roles',
338 args: {
339 set_roles: JSON.stringify(set_roles),
340 unset_roles: JSON.stringify(unset_roles),
341 uid: this.uid
342 },
Rushabh Mehtab9004bd2012-03-05 18:28:33 +0530343 btn: $(this.dialog.body).find('.btn-info').get(0),
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530344 callback: function() {
345
346 }
347 })
348 },
349 show_permissions: function(role) {
350 // show permissions for a role
351 var me = this;
352 if(!this.perm_dialog)
353 this.make_perm_dialog()
354 $(this.perm_dialog.body).empty();
355 wn.call({
356 method:'utilities.page.users.users.get_perm_info',
357 args: {role: role},
358 callback: function(r) {
359 var $body = $(me.perm_dialog.body);
360 $body.append('<table class="user-perm"><tbody><tr>\
361 <th style="text-align: left">Document Type</th>\
362 <th>Level</th>\
363 <th>Read</th>\
364 <th>Write</th>\
365 <th>Submit</th>\
366 <th>Cancel</th>\
367 <th>Amend</th></tr></tbody></table>');
368 for(var i in r.message) {
369 var perm = r.message[i];
370
371 // if permission -> icon
372 for(key in perm) {
373 if(key!='parent' && key!='permlevel') {
374 if(perm[key]) {
375 perm[key] = '<i class="icon-ok"></i>';
376 } else {
377 perm[key] = '';
378 }
379 }
380 }
381
382 $body.find('tbody').append(repl('<tr>\
383 <td style="text-align: left">%(parent)s</td>\
384 <td>%(permlevel)s</td>\
385 <td>%(read)s</td>\
386 <td>%(write)s</td>\
387 <td>%(submit)s</td>\
388 <td>%(cancel)s</td>\
389 <td>%(amend)s</td>\
390 </tr>', perm))
391 }
392
393 me.perm_dialog.show();
394 }
395 });
396
397 },
398 make_perm_dialog: function() {
399 this.perm_dialog = new wn.widgets.Dialog({
400 title:'Role Permissions',
401 width: 500
402 });
403 }
404})