blob: 130e5385d18b19c6401dd7102fa5d6a70aad7cdd [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 });
66 },
67 render: function(data) {
68 if(data.file_list) {
Rushabh Mehta1572adf2012-02-29 15:19:20 +053069 data.imgsrc = 'files/' + data.file_list.split('\n')[0].split(',')[1];
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053070 } else {
Rushabh Mehta79ae1652012-02-29 15:23:25 +053071 data.imgsrc = 'lib/images/ui/no_img_' + (data.gender=='Female' ? 'f' : 'm') + '.gif';
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053072 }
Rushabh Mehta204e77d2012-02-29 19:09:20 +053073 data.fullname = wn.user_info(data.name).fullname;
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +053074 data.delete_html = '';
75 if(!data.enabled)
76 data.delete_html = '<a class="close" title="delete">&times;</a>';
77
78 $('.users-area').append(repl('<div class="user-card" data-name="%(name)s">\
79 %(delete_html)s\
80 <img src="%(imgsrc)s">\
81 <div class="user-info">\
82 <b class="user-fullname">%(fullname)s</b><br>\
83 %(name)s<br>\
84 <button class="btn btn-small user-roles"><i class="icon-user"></i> Roles</button>\
85 <button class="btn btn-small user-settings"><i class="icon-cog"></i> Settings</button>\
86 </div>\
87 </div>', data));
88
89 if(!data.enabled) {
90 $('.users-area .user-card:last')
91 .addClass('disabled')
92 .find('.user-fullname').html('Disabled');
93 }
94 },
95 show_settings: function(uid) {
96 var me = wn.pages.users;
97 if(!me.settings_dialog)
98 me.make_settings_dialog();
99
100 var p = me.profiles[uid];
101 me.uid = uid;
102
103 me.settings_dialog.set_values({
104 restrict_ip: p.restrict_ip || '',
105 login_before: p.login_before || '',
106 login_after: p.login_after || '',
107 enabled: p.enabled || 0,
108 new_password: ''
109 });
110
111 me.settings_dialog.show();
112
113 },
114 make_settings_dialog: function() {
115 var me = wn.pages.users;
116 me.settings_dialog = new wn.widgets.Dialog({
117 title: 'Set User Security',
118 width: 500,
119 fields: [
120 {
121 label:'Enabled',
122 description: 'Uncheck to disable',
123 fieldtype: 'Check', fieldname: 'enabled'
124 },
125 {
126 label:'IP Address',
127 description: 'Restrict user login by IP address, partial ips (111.111.111), \
128 multiple addresses (separated by commas) allowed',
129 fieldname:'restrict_ip', fieldtype:'Data'
130 },
131 {
132 label:'Login After',
133 description: 'User can only login after this hour (0-24)',
134 fieldtype: 'Int', fieldname: 'login_after'
135 },
136 {
137 label:'Login Before',
138 description: 'User can only login before this hour (0-24)',
139 fieldtype: 'Int', fieldname: 'login_before'
140 },
141 {
142 label:'New Password',
143 description: 'Update the current user password',
144 fieldtype: 'Data', fieldname: 'new_password'
145 },
146 {
147 label:'Update', fieldtype:'Button', fieldname:'update'
148 }
149 ]
150 });
151
152 this.settings_dialog.fields_dict.update.input.onclick = function() {
153 var btn = this;
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530154 var args = me.settings_dialog.get_values();
155 args.user = me.uid;
156
157 if (args.new_password) {
158 me.get_password(btn, args);
159 } else {
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530160 me.update_security(btn, args);
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530161 }
162 };
163
164 },
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530165 update_security: function(btn, args) {
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530166 var me = wn.pages.users;
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530167 $(btn).set_working();
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530168 $c_page('utilities', 'users', 'update_security', JSON.stringify(args), function(r,rt) {
Rushabh Mehtaffb25fc2012-03-01 11:29:22 +0530169 $(btn).done_working();
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530170 if(r.exc) {
171 msgprint(r.exc);
172 return;
173 }
174 me.settings_dialog.hide();
175 $.extend(me.profiles[me.uid], me.settings_dialog.get_values());
176 me.refresh();
177 });
178 },
179 get_password: function(btn, args) {
180 var me = wn.pages.users;
181 var pass_d = new wn.widgets.Dialog({
182 title: 'Your Password',
183 width: 300,
184 fields: [
185 {
186 label: 'Please Enter <b style="color: black">Your Password</b>',
187 description: "Your password is required to update the user's password",
188 fieldtype: 'Password', fieldname: 'sys_admin_pwd', reqd: 1
189 },
190 {
191 label: 'Continue', fieldtype: 'Button', fieldname: 'continue'
192 }
193 ]
194 });
195
196 pass_d.fields_dict.continue.input.onclick = function() {
197 btn.pwd_dialog.hide();
198 args.sys_admin_pwd = btn.pwd_dialog.get_values().sys_admin_pwd;
199 btn.set_working();
Anand Doshiecd8df82012-03-02 12:18:47 +0530200 me.update_security(btn, args);
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530201 btn.done_working();
202 }
203
204 pass_d.show();
205 btn.pwd_dialog = pass_d;
206 btn.done_working();
207 },
208 add_user: function() {
209 var me = wn.pages.users;
210 var d = new wn.widgets.Dialog({
211 title: 'Add User',
212 width: 400,
213 fields: [{
214 fieldtype: 'Data', fieldname: 'user', reqd: 1,
215 label: 'Email Id of the user to add'
216 }, {
217 fieldtype: 'Data', fieldname: 'first_name', reqd: 1, label: 'First Name'
218 }, {
219 fieldtype: 'Data', fieldname: 'last_name', label: 'Last Name'
220 }, {
221 fieldtype: 'Data', fieldname: 'password', reqd: 1, label: 'Password'
222 }, {
223 fieldtype: 'Button', label: 'Add', fieldname: 'add'
224 }]
225 });
226
227 d.make();
228 d.fields_dict.add.input.onclick = function() {
229 v = d.get_values();
230 if(v) {
231 d.fields_dict.add.input.set_working();
232 $c_page('utilities', 'users', 'add_user', v, function(r,rt) {
233 if(r.exc) { msgprint(r.exc); return; }
234 else {
Rushabh Mehta204e77d2012-02-29 19:09:20 +0530235 wn.boot.user_info[v.user] = {fullname:v.first_name + ' ' + v.last_name};
Rushabh Mehtaaaf86ba2012-02-28 17:40:13 +0530236 d.hide();
237 me.refresh();
238 }
239 })
240 }
241 }
242 d.show();
243 }
244});
245
246erpnext.RoleEditor = Class.extend({
247 init: function() {
248 this.dialog = new wn.widgets.Dialog({
249 title: 'Set Roles'
250 });
251 var me = this;
252 $(this.dialog.body).html('<div class="help">Loading...</div>')
253 wn.call({
254 method:'utilities.page.users.users.get_roles',
255 callback: function(r) {
256 me.roles = r.message;
257 me.show_roles();
258 }
259 });
260 },
261 show_roles: function() {
262 var me = this;
263 $(this.dialog.body).empty();
264 for(var i in this.roles) {
265 $(this.dialog.body).append(repl('<div class="user-role" \
266 data-user-role="%(role)s">\
267 <input type="checkbox"> \
268 <a href="#"><i class="icon-question-sign"></i></a> %(role)s\
269 </div>', {role: this.roles[i]}));
270 }
271 $(this.dialog.body).append('<div style="clear: both">\
272 <button class="btn btn-small btn-primary">Save</button></div>');
273 $(this.dialog.body).find('button.btn-primary').click(function() {
274 me.save();
275 });
276 $(this.dialog.body).find('.user-role a').click(function() {
277 me.show_permissions($(this).parent().attr('data-user-role'))
278 return false;
279 })
280 },
281 show: function(uid) {
282 var me = this;
283 this.uid = uid;
284 this.dialog.show();
285 // set user roles
286 wn.call({
287 method:'utilities.page.users.users.get_user_roles',
288 args: {uid:uid},
289 callback: function(r, rt) {
290 $(me.dialog.body).find('input[type="checkbox"]').attr('checked', false);
291 for(var i in r.message) {
292 $(me.dialog.body)
293 .find('[data-user-role="'+r.message[i]
294 +'"] input[type="checkbox"]').attr('checked',true);
295 }
296 }
297 })
298 },
299 save: function() {
300 var set_roles = [];
301 var unset_roles = [];
302 $(this.dialog.body).find('[data-user-role]').each(function() {
303 var $check = $(this).find('input[type="checkbox"]');
304 if($check.attr('checked')) {
305 set_roles.push($(this).attr('data-user-role'));
306 } else {
307 unset_roles.push($(this).attr('data-user-role'));
308 }
309 })
310 wn.call({
311 method:'utilities.page.users.users.update_roles',
312 args: {
313 set_roles: JSON.stringify(set_roles),
314 unset_roles: JSON.stringify(unset_roles),
315 uid: this.uid
316 },
317 btn: $(this.dialog.body).find('.btn-primary').get(0),
318 callback: function() {
319
320 }
321 })
322 },
323 show_permissions: function(role) {
324 // show permissions for a role
325 var me = this;
326 if(!this.perm_dialog)
327 this.make_perm_dialog()
328 $(this.perm_dialog.body).empty();
329 wn.call({
330 method:'utilities.page.users.users.get_perm_info',
331 args: {role: role},
332 callback: function(r) {
333 var $body = $(me.perm_dialog.body);
334 $body.append('<table class="user-perm"><tbody><tr>\
335 <th style="text-align: left">Document Type</th>\
336 <th>Level</th>\
337 <th>Read</th>\
338 <th>Write</th>\
339 <th>Submit</th>\
340 <th>Cancel</th>\
341 <th>Amend</th></tr></tbody></table>');
342 for(var i in r.message) {
343 var perm = r.message[i];
344
345 // if permission -> icon
346 for(key in perm) {
347 if(key!='parent' && key!='permlevel') {
348 if(perm[key]) {
349 perm[key] = '<i class="icon-ok"></i>';
350 } else {
351 perm[key] = '';
352 }
353 }
354 }
355
356 $body.find('tbody').append(repl('<tr>\
357 <td style="text-align: left">%(parent)s</td>\
358 <td>%(permlevel)s</td>\
359 <td>%(read)s</td>\
360 <td>%(write)s</td>\
361 <td>%(submit)s</td>\
362 <td>%(cancel)s</td>\
363 <td>%(amend)s</td>\
364 </tr>', perm))
365 }
366
367 me.perm_dialog.show();
368 }
369 });
370
371 },
372 make_perm_dialog: function() {
373 this.perm_dialog = new wn.widgets.Dialog({
374 title:'Role Permissions',
375 width: 500
376 });
377 }
378})