blob: 517c3cf0cec68facb7c13e08d9bbdd848ec558e1 [file] [log] [blame]
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
$.extend(wn.pages.users, {
onload: function(wrapper) {
wn.pages.users.profiles = {};
wn.pages.users.refresh();
wn.pages.users.setup();
wn.pages.users.role_editor = new erpnext.RoleEditor();
},
setup: function() {
// set roles
$('.users-area').on('click', '.btn.user-roles', function() {
var uid = $(this).parent().parent().attr('data-name');
wn.pages.users.role_editor.show(uid);
});
// settings
$('.users-area').on('click', '.btn.user-settings', function() {
var uid = $(this).parent().parent().attr('data-name');
wn.pages.users.show_settings(uid);
});
// delete
$('.users-area').on('click', 'a.close', function() {
$card = $(this).parent();
var uid = $card.attr('data-name');
$card.css('opacity', 0.6);
wn.call({
method: 'utilities.page.users.users.delete',
args: {'uid': uid},
callback: function(r,rt) {
if(!r.exc)
$card.fadeOut()
}
});
})
},
refresh: function() {
// make the list
wn.call({
method:'utilities.page.users.users.get',
callback: function(r, rt) {
$('.users-area').empty();
for(var i in r.message) {
var p = r.message[i];
wn.pages.users.profiles[p.name] = p;
wn.pages.users.render(p);
}
}
});
if(!$('.subscription-info').length && (wn.boot.max_users || wn.boot.expires_on)) {
var $sub_info = $('<div class="subscription-info-box"><div>')
.insertAfter($(wn.pages.users).find('.help'));
if(wn.boot.max_users) {
$sub_info.append(repl('\
<span class="subscription-info"> \
Max Users: <b>%(max_users)s</b> \
</span>', { max_users: wn.boot.max_users }));
}
if(wn.boot.expires_on) {
$sub_info.append(repl('\
<span class="subscription-info"> \
Expires On: <b>%(expires_on)s</b> \
</span>', { expires_on: dateutil.str_to_user(wn.boot.expires_on) }));
}
}
},
render: function(data) {
if(data.file_list) {
data.imgsrc = 'files/' + data.file_list.split('\n')[0].split(',')[1];
} else {
data.imgsrc = 'images/lib/ui/no_img_' + (data.gender=='Female' ? 'f' : 'm') + '.gif';
}
data.fullname = wn.user_info(data.name).fullname;
data.delete_html = '';
if(!data.enabled)
data.delete_html = '<a class="close" title="delete">&times;</a>';
$('.users-area').append(repl('<div class="user-card" data-name="%(name)s">\
%(delete_html)s\
<img src="%(imgsrc)s">\
<div class="user-info">\
<b class="user-fullname">%(fullname)s</b><br>\
%(name)s<br>\
<button class="btn btn-small user-roles"><i class="icon-user"></i> Roles</button>\
<button class="btn btn-small user-settings"><i class="icon-cog"></i> Settings</button>\
</div>\
</div>', data));
if(!data.enabled) {
$('.users-area .user-card:last')
.addClass('disabled')
.find('.user-fullname').html('Disabled');
}
},
show_settings: function(uid) {
var me = wn.pages.users;
if(!me.settings_dialog)
me.make_settings_dialog();
var p = me.profiles[uid];
me.uid = uid;
me.settings_dialog.set_values({
restrict_ip: p.restrict_ip || '',
login_before: p.login_before || '',
login_after: p.login_after || '',
enabled: p.enabled || 0,
new_password: ''
});
me.settings_dialog.show();
},
make_settings_dialog: function() {
var me = wn.pages.users;
me.settings_dialog = new wn.widgets.Dialog({
title: 'Set User Security',
width: 500,
fields: [
{
label:'Enabled',
description: 'Uncheck to disable',
fieldtype: 'Check', fieldname: 'enabled'
},
{
label:'IP Address',
description: 'Restrict user login by IP address, partial ips (111.111.111), \
multiple addresses (separated by commas) allowed',
fieldname:'restrict_ip', fieldtype:'Data'
},
{
label:'Login After',
description: 'User can only login after this hour (0-24)',
fieldtype: 'Int', fieldname: 'login_after'
},
{
label:'Login Before',
description: 'User can only login before this hour (0-24)',
fieldtype: 'Int', fieldname: 'login_before'
},
{
label:'New Password',
description: 'Update the current user password',
fieldtype: 'Data', fieldname: 'new_password'
},
{
label:'Update', fieldtype:'Button', fieldname:'update'
}
]
});
this.settings_dialog.fields_dict.update.input.onclick = function() {
var btn = this;
var args = me.settings_dialog.get_values();
args.user = me.uid;
if (args.new_password) {
me.get_password(btn, args);
} else {
me.update_security(btn, args);
}
};
},
update_security: function(btn, args) {
var me = wn.pages.users;
$(btn).set_working();
$c_page('utilities', 'users', 'update_security', JSON.stringify(args), function(r,rt) {
$(btn).done_working();
if(r.exc) {
msgprint(r.exc);
return;
}
me.settings_dialog.hide();
$.extend(me.profiles[me.uid], me.settings_dialog.get_values());
me.refresh();
});
},
get_password: function(btn, args) {
var me = wn.pages.users;
var pass_d = new wn.widgets.Dialog({
title: 'Your Password',
width: 300,
fields: [
{
label: 'Please Enter <b style="color: black">Your Password</b>',
description: "Your password is required to update the user's password",
fieldtype: 'Password', fieldname: 'sys_admin_pwd', reqd: 1
},
{
label: 'Continue', fieldtype: 'Button', fieldname: 'continue'
}
]
});
pass_d.fields_dict.continue.input.onclick = function() {
btn.pwd_dialog.hide();
args.sys_admin_pwd = btn.pwd_dialog.get_values().sys_admin_pwd;
btn.set_working();
me.update_security(btn, args);
btn.done_working();
}
pass_d.show();
btn.pwd_dialog = pass_d;
btn.done_working();
},
add_user: function() {
var me = wn.pages.users;
var active_users = $('.user-card:not(.disabled)');
if(wn.boot.max_users && (active_users.length >= wn.boot.max_users)) {
msgprint(repl("Alas! <br />\
You already have <b>%(active_users)s</b> active users, \
which is the maximum number that you are currently allowed to add. <br /><br /> \
So, to add more users, you can:<br /> \
1. <b>Upgrade to the unlimited users plan</b>, or<br /> \
2. <b>Disable one or more of your existing users and try again</b>",
{active_users: active_users.length}));
return;
}
var d = new wn.widgets.Dialog({
title: 'Add User',
width: 400,
fields: [{
fieldtype: 'Data', fieldname: 'user', reqd: 1,
label: 'Email Id of the user to add'
}, {
fieldtype: 'Data', fieldname: 'first_name', reqd: 1, label: 'First Name'
}, {
fieldtype: 'Data', fieldname: 'last_name', label: 'Last Name'
}, {
fieldtype: 'Data', fieldname: 'password', reqd: 1, label: 'Password'
}, {
fieldtype: 'Button', label: 'Add', fieldname: 'add'
}]
});
d.make();
d.fields_dict.add.input.onclick = function() {
v = d.get_values();
if(v) {
d.fields_dict.add.input.set_working();
$c_page('utilities', 'users', 'add_user', v, function(r,rt) {
if(r.exc) { msgprint(r.exc); return; }
else {
wn.boot.user_info[v.user] = {fullname:v.first_name + ' ' + (v.last_name || '')};
d.hide();
me.refresh();
}
})
}
}
d.show();
}
});
erpnext.RoleEditor = Class.extend({
init: function() {
this.dialog = new wn.widgets.Dialog({
title: 'Set Roles'
});
var me = this;
$(this.dialog.body).html('<div class="help">Loading...</div>')
wn.call({
method:'utilities.page.users.users.get_roles',
callback: function(r) {
me.roles = r.message;
me.show_roles();
}
});
},
show_roles: function() {
var me = this;
$(this.dialog.body).empty();
for(var i in this.roles) {
$(this.dialog.body).append(repl('<div class="user-role" \
data-user-role="%(role)s">\
<input type="checkbox"> \
<a href="#"><i class="icon-question-sign"></i></a> %(role)s\
</div>', {role: this.roles[i]}));
}
$(this.dialog.body).append('<div style="clear: both">\
<button class="btn btn-small btn-info">Save</button></div>');
$(this.dialog.body).find('button.btn-info').click(function() {
me.save();
});
$(this.dialog.body).find('.user-role a').click(function() {
me.show_permissions($(this).parent().attr('data-user-role'))
return false;
})
},
show: function(uid) {
var me = this;
this.uid = uid;
this.dialog.show();
// set user roles
wn.call({
method:'utilities.page.users.users.get_user_roles',
args: {uid:uid},
callback: function(r, rt) {
$(me.dialog.body).find('input[type="checkbox"]').attr('checked', false);
for(var i in r.message) {
$(me.dialog.body)
.find('[data-user-role="'+r.message[i]
+'"] input[type="checkbox"]').attr('checked',true);
}
}
})
},
save: function() {
var set_roles = [];
var unset_roles = [];
$(this.dialog.body).find('[data-user-role]').each(function() {
var $check = $(this).find('input[type="checkbox"]');
if($check.attr('checked')) {
set_roles.push($(this).attr('data-user-role'));
} else {
unset_roles.push($(this).attr('data-user-role'));
}
})
wn.call({
method:'utilities.page.users.users.update_roles',
args: {
set_roles: JSON.stringify(set_roles),
unset_roles: JSON.stringify(unset_roles),
uid: this.uid
},
btn: $(this.dialog.body).find('.btn-info').get(0),
callback: function() {
}
})
},
show_permissions: function(role) {
// show permissions for a role
var me = this;
if(!this.perm_dialog)
this.make_perm_dialog()
$(this.perm_dialog.body).empty();
wn.call({
method:'utilities.page.users.users.get_perm_info',
args: {role: role},
callback: function(r) {
var $body = $(me.perm_dialog.body);
$body.append('<table class="user-perm"><tbody><tr>\
<th style="text-align: left">Document Type</th>\
<th>Level</th>\
<th>Read</th>\
<th>Write</th>\
<th>Submit</th>\
<th>Cancel</th>\
<th>Amend</th></tr></tbody></table>');
for(var i in r.message) {
var perm = r.message[i];
// if permission -> icon
for(key in perm) {
if(key!='parent' && key!='permlevel') {
if(perm[key]) {
perm[key] = '<i class="icon-ok"></i>';
} else {
perm[key] = '';
}
}
}
$body.find('tbody').append(repl('<tr>\
<td style="text-align: left">%(parent)s</td>\
<td>%(permlevel)s</td>\
<td>%(read)s</td>\
<td>%(write)s</td>\
<td>%(submit)s</td>\
<td>%(cancel)s</td>\
<td>%(amend)s</td>\
</tr>', perm))
}
me.perm_dialog.show();
}
});
},
make_perm_dialog: function() {
this.perm_dialog = new wn.widgets.Dialog({
title:'Role Permissions',
width: 500
});
}
})