first cut for lazy loading framework

This commit is contained in:
Rushabh Mehta
2011-09-05 18:43:09 +05:30
parent 09938bda69
commit 66ac2b018a
1512 changed files with 832 additions and 0 deletions

View File

View File

@@ -1,55 +0,0 @@
<div class="layout_wrapper">
<div id="di_header"></div>
<div style="margin: 8px">
<table style="border-collapse: collapse;" border="0">
<tbody>
<tr>
<td style="border: 1px solid #aaaaaa; padding: 4px; width: 60%;">
<form action="index.cgi" enctype="multipart/form-data" method="POST" target="ImportIFrame"> <input name="cmd" type="hidden" value="import_csv" />
<h3 style="background-color: #EEF; padding: 2px;">Step 1. Download Template</h3>
<select id="import_template" style="margin: 10px;"> <option>Select Master...</option> </select>
<div style="margin: 10px; margin-top: 0px;"><input name="overwrite" type="checkbox"/> Over-write records with same name?</div>
<div id="child_tab_lst"></div>
<h3 style="background-color: #EEF; padding: 2px;">Step 2. Upload and Import</h3>
<table style="width: 480px;" border="0" cellspacing="10px">
<tbody>
<tr>
<td width="200px">Select CSV File to be imported</td>
<td><input name="csv_file" type="file" /></td>
</tr>
<tr>
<td width="200px">Date format in source CSV</td>
<td><select name="dateformat"> <option value="yyyy-mm-dd">yyyy-mm-dd</option> <option value="mm/dd/yyyy">mm/dd/yyyy</option> <option value="mm/dd/yy">mm/dd/yy</option> <option value="dd-mm-yyyy">dd-mm-yyyy</option> <option value="dd/mm/yyyy">dd/mm/yyyy</option> </select></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<div id="import_btn"><input type="submit" value="Import" /></div>
</td>
</tr>
</tbody>
</table>
</form>
<div style="background-color: #FFE; padding: 13px; margin: 17px;">
<h3>Data Import Guide</h3>
<ol>
<li>Get the template of the DocType for which you want to import in CSV (Comma seperated values) format.</li>
<li>Fill in the data in the template. You can remove columns that are not relevant</li>
<li>Save the template in CSV format</li>
<li>Select the saved CSV file, identify the date format if any</li>
<li>Click on "Import"</li>
</ol></div>
</td>
<td style="border: 1px solid #AAA; padding: 4px;">
<h3>Import Log:</h3>
<div id="import_result_area">
<iframe src="blank1.html" name="ImportIFrame" style="border: 0px; height: 500px; width: 100%"></iframe>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -1,55 +0,0 @@
pscript['onload_Import Data'] = function() {
//alert(profile.can_get_report);
callback = function(r,rt) {
var h = new PageHeader('di_header','Import Data','Tool to download template and upload data');
var sel = $i('import_template');
if(r.message){
add_sel_options(sel, r.message);
// please collapse here when editing :)
sel.onchange=function(){
$i('child_tab_lst').innerHTML ='';
if(sel.value != 'Select Master...'){
$c_obj('Import Data Control','get_child_lst',sel.value,
function(r,rt){
var me = this;
$y($i('child_tab_lst'),{backgroundColor:'#EEEEEE', margin: '17px 17px', padding: '13px'})
var desc = $a($i('child_tab_lst'), 'div', '', {padding:'4px'});
desc.innerHTML = "<b>Download template(s) for importing "+sel_val(sel)+"</b>";
var parent = $a($i('child_tab_lst'), 'div');
var tab = make_table(parent,r.message.length,1,'100%',[],{padding:'3px',borderCollapse: 'collapse'});
for(var i=0;i<r.message.length;i++){
var dt= $a($td(tab,i,0), 'span', 'link_type');
dt.innerHTML = r.message[i];
dt.nm = r.message[i];
dt.onclick = function(){
var ovr = $('input[name="overwrite"]:checked').length;
window.location = outUrl + '?cmd=get_template&dt=' + this.nm + (ovr ? '&overwrite=1' : '');
}
}
}
);
}
}
}
// set the default (if given in url)
if(window.location.hash) {
var to_set = window.location.hash.split('/').slice(-1)[0];
if(in_list(r.message, to_set)) {
sel.value = to_set;
sel.onchange();
}
}
}
$c_obj('Import Data Control','get_master_lst','',callback);
}

View File

@@ -1,72 +0,0 @@
# Page, Import Data
[
# These values are common in all dictionaries
{
'creation': '2010-12-14 10:23:18',
'docstatus': 0,
'modified': '2010-12-24 11:43:02',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Setup',
'name': '__common__',
'page_name': 'Import Data',
'show_in_menu': 0,
'standard': 'Yes'
},
# These values are common for all Page Role
{
'doctype': 'Page Role',
'name': '__common__',
'parent': 'Import Data',
'parentfield': 'roles',
'parenttype': 'Page'
},
# Page, Import Data
{
'doctype': 'Page',
'name': 'Import Data'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 1,
'role': 'Administrator'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 2,
'role': 'System Manager'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 3,
'role': 'Sales Master Manager'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 4,
'role': 'Purchase Master Manager'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 5,
'role': 'Material Master Manager'
}
]

View File

@@ -1 +0,0 @@
<div id="crm_home"></div>

View File

@@ -1,32 +0,0 @@
//make tabs
pscript.onload_people = function() {
make_customer_tab($i('crm_home'));
}
function make_customer_tab(parent) {
new wn.widgets.DocColumnView('Customers', parent, ['Customer Group', 'Customer', 'Contact'], {
'Customer Group': {
show_fields : ['name'],
create_fields : ['name'],
search_fields : ['name'],
next_col: 'Customer'
},
'Customer': {
show_fields : ['name', 'customer_name'],
create_fields : ['name', 'customer_name'],
search_fields : ['customer_name'],
filter_by : ['Customer Group', 'customer_group'],
next_col: 'Contact'
},
'Contact': {
show_fields : ['name', 'first_name', 'last_name'],
create_fields : ['name','first_name', 'last_name'],
search_fields : ['first_name', 'last_name'],
conditions: ['is_customer=1'],
filter_by : ['Customer', 'customer']
},
})
}

View File

@@ -1,26 +0,0 @@
[
{
'content': None,
'creation': '2011-03-21 12:12:32',
'docstatus': 0,
'doctype': 'Page',
'icon': None,
'idx': None,
'menu_index': None,
'modified': '2011-03-21 12:13:39',
'modified_by': 'Administrator',
'module': 'Setup',
'name': 'people',
'owner': 'Administrator',
'page_name': 'People',
'parent': None,
'parent_node': None,
'parentfield': None,
'parenttype': None,
'script': None,
'show_in_menu': None,
'standard': 'Yes',
'static_content': None,
'style': None
}
]

View File

@@ -1,4 +0,0 @@
<div class="layout_wrapper">
<div id="pe_header"></div>
<div id="perm_engine_div" style="margin: 16px;"></div>
</div>

View File

@@ -1,525 +0,0 @@
pscript['onload_Permission Engine'] = function() {
// header and toolbar
var h = new PageHeader('pe_header','Permissions Manager','Set specific permissions for Roles')
if(!pscript.perm_engine) pscript.perm_engine = new pscript.PermEngine();
}
pscript.PermEngine = function() {
// create UI elements
this.wrapper = $i('perm_engine_div');
this.head = $a(this.wrapper, 'div');
this.body = $a(this.wrapper, 'div');
this.footer = $a(this.wrapper, 'div');
var lab = $a(this.body,'div', '', {backgroundColor:'#FFD', padding:'8px', margin:'16px 0px'});
lab.innerHTML = 'Please select the item for which you want to set permissions';
this.make_head();
this.load_options();
}
// Make Head
// -------------
pscript.PermEngine.prototype.make_head = function() {
var me = this;
var make_select = function(label) {
var w = $a(me.head, 'div', '', {margin:'8px 0px'});
var t = make_table(w,1,2,'300px',['50%','50%']);
$td(t,0,0).innerHTML = label;
var s = $a($td(t,0,1),'select','',{width:'140px'});
s.wrapper = w;
return s;
}
var make_button = function(label, parent, green) {
return $btn(parent, label, null, {margin:'8px 0px', display:'none'}, (green ? 'green' : null));
}
// Set Permissions for
this.type_select = make_select('Set Permissions For');
this.type_select.onchange = function() {
me.get_permissions();
}
// Update Button
this.add_button = make_button('+ Add A New Rule', this.head, 0);
this.add_button.onclick = function() {
me.add_permission();
}
// Update Button
this.update_button = make_button('Update', this.footer, 1);
this.update_button.onclick = function() {
me.update_permissions();
}
}
// Add Permissions
// -----------------
pscript.PermEngine.prototype.add_permission = function() {
var me = this;
if(!this.add_permission_dialog) {
// dialog
var d = new Dialog(400,400,'Add Permission');
d.make_body([['Select','Role'],['Select','Level'],['Button','Add']])
add_sel_options(d.widgets['Role'], this.roles, '');
add_sel_options(d.widgets['Level'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 0);
// add
d.widgets['Add'].onclick = function() {
if(!sel_val(d.widgets['Role'])) {
msgprint('Please select Role'); return;
}
var callback = function(r, rt) {
// reload
me.get_permissions();
d.hide();
}
$c_obj('Permission Control','add_permission',JSON.stringify([sel_val(me.type_select), sel_val(d.widgets['Role']), sel_val(d.widgets['Level'])]), callback);
}
this.add_permission_dialog = d;
}
this.add_permission_dialog.show();
}
// Hide Fields
// -----------------
pscript.PermEngine.prototype.hide_fields = function() {
$dh(this.role_select.wrapper);
this.type_select.disabled = false;
this.body.innerHTML = '';
}
// Load Roles And Modules
// -----------------------
pscript.PermEngine.prototype.load_options = function() {
var me = this;
$dh(me.update_button);
$dh(me.add_button);
$c_obj('Permission Control','get_doctype_list','', function(r,rt) {
me.roles = r.message.roles;
// Type
empty_select(me.type_select);
add_sel_options(me.type_select,add_lists([''], r.message.doctypes));
});
}
// Get DocType and Permissions related to module
// --------------------------------------------------
pscript.PermEngine.prototype.get_permissions = function() {
var me = this;
if(!sel_val(me.type_select)) {
msgprint('Please select a type first!'); return;
}
$c_obj('Permission Control','get_permissions',sel_val(me.type_select), function(r,rt) {
// Get permissions
if(r.message.perms.length)me.get_results(r.message);
else me.body.innerHTML = '<div style = "color : red; margin:8px 0px;">No Records Found</div>'
});
}
// Get Results
// ------------------
pscript.PermEngine.prototype.get_results = function(r){
var perms = r.perms;
var me = this;
var doctype = sel_val(me.type_select);
// show update button
$ds(me.update_button);
$ds(me.add_button);
this.body.innerHTML = ''
pscript.all_checkboxes = [];
pscript.all_matches = [];
var head = $a(this.body, 'h3'); head.innerHTML = 'Rules for ' + doctype;
var permt = make_table(me.body, perms.length+1,9,'80%',[],{border:'1px solid #AAA', padding:'3px', verticalAlign:'middle', height:'30px'});
// Create Grid for particular DocType
// ------------------------------------
// Columns
var col_labels = ['Role','Level','Read','Write','Create','Submit','Cancel','Amend','Restrict By']
for(var n = 0; n < col_labels.length; n++){
$y($td(permt,0,n), {backgroundColor:'#DDD', width:(n==0?'30%':(n==8?'21%':'7%'))})
$td(permt,0,n).innerHTML = col_labels[n];
$td(permt,0,n).fieldname = col_labels[n].toLowerCase();
}
// Rows for Column Level / Role
for(var j = 0; j < perms.length; j++){
var plevel = $a($td(permt,j+1,1), 'span', 'link_type');
plevel.innerHTML = perms[j].permlevel;
plevel.doctype = doctype;
plevel.value = perms[j].permlevel;
plevel.onclick = function() {me.get_fields(this.doctype, this.value)}
// role
$td(permt,j+1,0).innerHTML = perms[j].role;
}
// Get values
for(var l = 0; l < perms.length; l++){
for(var m = 0; m < 6; m++){ // (read,write,create,submit,cancel,amend)
var chk = $a_input($td(permt,l+1,m+2), 'checkbox');
var val = perms[l][$td(permt,0,m+2).fieldname];
if(val == 1) chk.checked = 1;
else chk.checked = 0;
chk.doctype = doctype;
chk.permlevel = perms[l].permlevel; chk.perm_type = col_labels[m+2].toLowerCase(); chk.role = perms[l].role;
pscript.all_checkboxes.push(chk);
}
}
// add selects for match
me.add_match_select(r, perms, permt, doctype);
}
// render selects for match
// --------------------------------------------
pscript.PermEngine.prototype.add_match_select = function(r, perms, permt, doctype) {
var me = this;
// add select for match
for(var i=0; i<perms.length; i++) {
if(perms[i].permlevel==0) {
// select
var sel = $a($td(permt,i+1,8),'select','',{width:'100%'});
add_sel_options(sel, r.fields);
sel.details = perms[i]; sel.details.parent = doctype;
sel.onchange = function() {
if(sel_val(this) && sel_val(this)!='owner') $ds(this.div);
else $dh(this.div); }
// link
var div = $a($td(permt,i+1,8),'div','link_type',{marginTop: '2px', fontSize:'10px', display:'none'});
div.onclick = function() { this.details.match = sel_val(this.sel); me.show_match_dialog(this.details); }
div.innerHTML = 'Set Users / Roles';
div.details = perms[i];
sel.div = div; div.sel = sel;
// set the value
if(perms[i].match) { sel.value = perms[i].match; $ds(div); }
pscript.all_matches.push(sel);
}
}
}
// match users Dialog
// =======================================================
pscript.PermEngine.prototype.show_match_dialog=function(details) {
if(!this.match_defaults_dialog) {
var d = new Dialog(750, 500, 'Permission Applies To');
d.make_body([['HTML','Body']]);
var w = d.widgets['Body'];
$y(w,{height:'350px', overflow:'auto'});
this.match_defaults_dialog = d;
}
// dialog
this.match_defaults_dialog.show();
// render the rules
var me = this;
var callback = function(r,rt) {
me.render_match_dialog(r, details);
}
// load the rules
$c_obj('Permission Control','get_defaults', details.match + '~~~' + (this.profiles ? 'No' : 'Yes'), callback);
}
// --------------------------------------------
pscript.PermEngine.prototype.render_match_dialog=function(r, details) {
var d = this.match_defaults_dialog;
var w = d.widgets['Body'];
w.innerHTML = '<div style="background-color:#FFD; padding: 4px; color: #440; margin-bottom:16px">Please Note: Any action will also affect other permissions with similar rules!</div>'
// header
var t=make_table($a(w,'div','',{borderBottom:'1px solid #AAA'}),1,3,'90%',['40%','40%','20%'],{fontWeight:'bold', padding:'3px', fontSize:'14px'});
$td(t,0,0).innerHTML = 'Who?'; $td(t,0,1).innerHTML = 'Is allowed if '+details.match+' equals';
// existing defaults
var dl = r.message.dl; this.options = r.message.ol;
if(!this.profiles) {
this.profiles = r.message.pl;
}
for(var i=0; i<dl.length; i++) {
new MatchDefaultValue(this, w, dl[i], details.match);
}
this.add_new_match_row(details.match);
}
pscript.PermEngine.prototype.add_new_match_row = function(fieldname) {
// add new default
new MatchDefaultValue(this, this.match_defaults_dialog.widgets['Body'], null, fieldname, 1);
}
// --------------------------------------------
MatchDefaultValue = function(pe, parent, details, fieldname, editable) {
this.pe = pe;
this.wrapper = $a(parent, 'div', '', {margin:'4px'});
this.clear();
this.details = details;
this.fieldname = fieldname;
this.render(editable);
}
// --------------------------------------------
MatchDefaultValue.prototype.clear = function() {
this.wrapper.innerHTML = '';
this.tab = make_table(this.wrapper, 1, 3, '90%', ['40%','40%','20%'], {verticalAlign:'middle', padding:'3px'});
}
// --------------------------------------------
MatchDefaultValue.prototype.render = function(editable) {
if(editable) {
this.render_editable();
} else {
this.render_static();
}
}
// --------------------------------------------
MatchDefaultValue.prototype.render_editable = function() {
var me = this;
// profile or role
this.profile_or_role = $a($td(this.tab,0,0), 'select', '', {width:'60px', marginRight:'8px'});
add_sel_options(this.profile_or_role,['Profile', 'Role'], 'Profile');
this.profile_or_role.onchange = function() {
if(sel_val(this)=='Profile') { $di(me.profile_sel); $dh(me.role_sel); }
else { $dh(me.profile_sel); $di(me.role_sel); }
}
// role sel
this.role_sel = $a($td(this.tab,0,0), 'select', '', {width:'100px',display:'none'});
add_sel_options(this.role_sel,this.pe.roles);
// profile sel
this.profile_sel = $a($td(this.tab,0,0), 'select', '', {width:'100px'});
add_sel_options(this.profile_sel,this.pe.profiles);
// options sel
this.options_sel = $a($td(this.tab,0,1), 'select', '', {width:'120px'});
add_sel_options(this.options_sel,this.pe.options);
// add
var span = $a($td(this.tab,0,2),'span','link_type',{marginLeft:'8px'});
span.innerHTML = 'Add'
span.onclick = function() { me.save(); }
}
// --------------------------------------------
MatchDefaultValue.prototype.render_static = function() {
var me = this;
$td(this.tab,0,0).innerHTML = this.details.parenttype;
$td(this.tab,0,0).innerHTML += '&nbsp;' + this.details.parent;
$td(this.tab,0,1).innerHTML = this.details.defvalue;
// delete
var span = $a($td(this.tab,0,2),'span','link_type',{marginLeft:'8px'});
span.innerHTML = 'Cancel'
span.onclick = function() { me.delete_def(); }
}
// --------------------------------------------
MatchDefaultValue.prototype.delete_def = function() {
var me = this;
this.wrapper.innerHTML = '<div style="color: #888; padding: 3px;">Deleting...</div>';
var callback = function(r,rt) {
$dh(me.wrapper);
if(r.exc) msgprint('There were errors!')
}
$c_obj('Permission Control','delete_default'
,[this.details.parent, this.fieldname, this.details.defvalue].join('~~~')
,callback)
}
// --------------------------------------------
MatchDefaultValue.prototype.save = function() {
var me= this;
var callback = function(r,rt) {
me.details = r.message;
me.clear();
me.render();
me.pe.add_new_match_row(me.fieldname);
}
// values
if(sel_val(this.profile_or_role)=='Profile') { var parent = sel_val(this.profile_sel); var parenttype = 'Profile'; }
else { var parent = sel_val(this.role_sel); var parenttype = 'Role'; }
if(!sel_val(this.options_sel) || !parent) { msgprint("Please select all values"); return; }
$c_obj('Permission Control','add_default'
,[parent, parenttype, this.fieldname, sel_val(this.options_sel)].join('~~~')
,callback);
this.wrapper.innerHTML = '<div style="color: #888; padding: 3px;">Adding...</div>';
}
// Make Dialog Box To Get Fields fro PermLevel
// =======================================================
pscript.PermEngine.prototype.make_fields_dialog=function(){
if(!pscript.get_field_dialog) {
pscript.get_field_dialog = new Dialog(750,500,'Fields');
pscript.get_field_dialog.make_body([['HTML','Fields','<div id="perm_engine_get_fields"></div>'],['Button','OK']]);
}
else $i('perm_engine_get_fields').innerHTML = '';
}
// Get Fields
// --------------------
pscript.PermEngine.prototype.get_fields = function(dt, permlevel) {
var me = this;
var callback = function(r,rt){
// Get Parent DocType Fields
var parent_fields_dict = r.message.parent_fields_dict;
// Get Child Table Fields if any
var table_fields_dict = r.message.table_fields_dict;
// Make Fields Dialog Box
me.make_fields_dialog();
me.make_fields_table(dt, parent_fields_dict, table_fields_dict, permlevel);
pscript.get_field_dialog.show();
pscript.get_field_dialog.widgets['OK'].onclick=function(){
pscript.get_field_dialog.hide();
}
}
var args = "{'dt':'"+dt+"','permlevel':"+permlevel+"}"
$c_obj('Permission Control','get_fields', args, callback);
}
// Make Table of Fields for Dialog Box
// --------------------------------------
pscript.PermEngine.prototype.make_fields_table = function(dt, parent_fields_dict, table_fields_dict, permlevel) {
var make_grid = function(table, fields_dict) {
var col_labels = ['Label','Fieldtype','Fieldname','Options'];
for(var n = 0; n < col_labels.length; n++){
$a_input(($td(table,0,n)), 'data');
$td(table,0,n).innerHTML = '<b>'+col_labels[n]+'</b>';
$td(table,0,n).fieldname = col_labels[n].toLowerCase();
}
// Add values
for(var i = 0; i < keys(fields_dict).length; i++){
for(var j = 0; j < 4; j++){
$a_input(($td(table,i+1,j)), 'data');
$td(table,i+1,j).innerHTML = cstr(fields_dict[i][$td(table,0,j).fieldname])
}
}
}
$i('perm_engine_get_fields').innerHTML = '<b>'+ dt + ' Fields at Level '+ permlevel +':</b><br><br>';
var parent_field_table = make_table('perm_engine_get_fields',keys(parent_fields_dict).length+1, 4,'100%',['25%','25%','25%','25%'],{border:'1px solid #AAA',padding:'2px'});
make_grid(parent_field_table, parent_fields_dict);
child_tables = keys(table_fields_dict)
if(child_tables.length > 0){
for(var k = 0; k < child_tables.length; k++){
var tab_fields_det = table_fields_dict[child_tables[k]];
if(keys(tab_fields_det).length > 0){
$i('perm_engine_get_fields').innerHTML += '<br><b>'+ child_tables[k] + ' Fields at Level '+ permlevel +':</b><br><br>'
var child_field_table = make_table('perm_engine_get_fields',keys(tab_fields_det).length+1, 4,'100%',['25%','25%','25%','25%'],{border:'1px solid #AAA',padding:'2px'});
make_grid(child_field_table, tab_fields_det);
}
}
}
}
// Update Permissions
// -----------------------
pscript.PermEngine.prototype.update_permissions = function() {
var me = this;
var out = {};
var add_to_out = function(doctype, permlevel, role, key, value) {
if(!out[doctype]) out[doctype] = {};
if(!out[doctype][permlevel]) out[doctype][permlevel] = {};
if(!out[doctype][permlevel][role]) out[doctype][permlevel][role] = {};
out[doctype][permlevel][role][key] = value;
}
// check boxes
for(i in pscript.all_checkboxes) {
c = pscript.all_checkboxes[i];
add_to_out(c.doctype, c.permlevel, c.role, c.perm_type, c.checked ? 1 : 0);
}
// matches
for(var i=0; i<pscript.all_matches.length; i++) {
var s = pscript.all_matches[i];
if(sel_val(s))
add_to_out(s.details.parent, s.details.permlevel, s.details.role, 'match', sel_val(s));
}
var args = "{'perm_dict': "+JSON.stringify(out)+"}"
$c_obj('Permission Control','update_permissions', args, function(r,rt) {});
}
// Update Page Roles
// ----------------------
pscript.PermEngine.prototype.update_page_roles = function() {
var me = this;
var out = {};
for(i in pscript.all_pg_checkboxes) {
c = pscript.all_pg_checkboxes[i];
out[c.page_name] = c.checked ? 1 : 0
}
var args = "{'page_role_dict': "+JSON.stringify(out)+", 'role': '"+sel_val(me.role_select)+"'}"
$c_obj('Permission Control','update_page_role', args, function(r,rt) {});
}
// Reset Permission Engine
// -------------------------
pscript.PermEngine.prototype.reset_perm_engine = function(){
this.type_select.selectedIndex = 0;
this.load_options();
}

View File

@@ -1,44 +0,0 @@
# Page, Permission Engine
[
# These values are common in all dictionaries
{
'creation': '2010-12-14 10:23:18',
'docstatus': 0,
'modified': '2011-01-04 13:11:17',
'modified_by': 'Administrator',
'owner': 'saumil@webnotestech.com'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Setup',
'name': '__common__',
'page_name': 'Permission Engine',
'show_in_menu': 1,
'standard': 'Yes'
},
# These values are common for all Page Role
{
'doctype': 'Page Role',
'idx': 1,
'name': '__common__',
'parent': 'Permission Engine',
'parentfield': 'roles',
'parenttype': 'Page',
'role': 'System Manager'
},
# Page, Permission Engine
{
'doctype': 'Page',
'name': 'Permission Engine'
},
# Page Role
{
'doctype': 'Page Role'
}
]

View File

@@ -1 +0,0 @@
<div id="setup_div" class="layout_wrapper"></div>

View File

@@ -1,253 +0,0 @@
pscript.onload_Setup = function() {
var parent = $i('setup_div');
add_space_holder(parent);
var callback = function(r,rt){
// header
parent.page_head = new PageHeader(parent,'Setup');
// sections
var setup_data = new SetupData(r.message);
pscript.setup_make_sections(setup_data);
remove_space_holder();
}
$c_obj('Setup Wizard Control','get_country','',callback);
}
pscript.setup_set_height = function() {
var parent = $i('setup_div');
$y(parent.tray.body, {height: get_window_height() - parent.page_head.wrapper.offsetHeight + 'px', overflow:'auto'})
}
// Make sections
// ===================================================
pscript.setup_make_sections = function(setup_data) {
var parent = $i('setup_div');
parent.tray = new TrayPage(parent)
// list of setup data
var lst = [setup_data.system, setup_data.general, setup_data.accounts, setup_data.selling, setup_data.buying, setup_data.stock, setup_data.hr, setup_data.maintenance, setup_data.production];
for(var s=0; s<lst.length; s++){
var lbl = keys(lst[s])[0];
var ti = parent.tray.add_item(lbl, null, null, 1)
new SetupItem(ti.body, lbl, lst[s][lbl]);
if(s==0) ti.expand();
}
setTimeout(pscript.setup_set_height, 100);
resize_observers.push(pscript.setup_set_height);
}
// Setup Item
// ===================================================
SetupItem = function(parent, lbl, link_list) {
this.icons = {'System':'back_img Setup', 'General':'back_img Home', 'Accounts':'back_img Accounts', 'Selling':'back_img Selling', 'Stock':'back_img Stock', 'Buying':'back_img Buying', 'Maintenance':'back_img Maintenance', 'Production':'back_img Production', 'HR':'back_img HR'};
this.make_item_body(parent, lbl, link_list);
}
// Make body for item in setup wizard
// ===================================================
SetupItem.prototype.make_item_body = function(parent, lbl, link_list){
// item link area
this.link_area = parent;
this.render_item_body(lbl, link_list);
}
// Render item body
// ===================================================
SetupItem.prototype.render_item_body = function(lbl, link_list) {
var me = this;
// set item header
link_list.sort(function(a, b) { return a[0] > b[0]; });
// show links for item
for(var i=0; i<link_list.length; i++){
var wrapper = $a(this.link_area, 'div','',{marginBottom:'4px', padding:'2px'});
$(wrapper).hover(
function() { $y(this,{backgroundColor:'#EEF'}) }
,function() { $y(this,{backgroundColor:''}) }
)
var tab = make_table($a(wrapper,'div'), 1, 2, '100%', [200/7+'%', 500/7+'%'])
var dt= $a($td(tab,0,0), 'span', 'link_type');
dt.innerHTML = link_list[i][0];
dt.label = link_list[i][0];
dt.arg = link_list[i][1];
dt.nm = link_list[i][2];
if(dt.arg == 1) dt.cn = link_list[i][3];
else if(dt.arg == 2) dt.cb=link_list[i][3];
// execute when link is clicked
dt.onclick = function(){
me.link_action(this)
}
// description
$y($td(tab,0,1), {color:'#777'});
$td(tab,0,1).innerHTML = link_list[i][4];
}
}
// Execute when link is clicked
// ----------------------------
SetupItem.prototype.link_action = function(obj) {
var me = this;
var obj = obj;
// if object links to a doc browser
if(obj.arg == 1){
if(in_list(profile.can_read, obj.nm)){
if(obj.cn !='')
loaddocbrowser(obj.nm, obj.nm, obj.cn);
else
loaddocbrowser(obj.nm);
}
else
msgprint('No read permission',1);
}
// if obj links to a page
else if(obj.arg == 2){
me.show_page(obj);
}
// if object links to a single doctype
else if(obj.arg == 3){
newdoc(obj.nm);
}
}
// Show page for corresponding link
// --------------------------------
SetupItem.prototype.show_page = function(obj) {
var me = obj;
var callback = function(r,rt)
{
if(r.message){
if(me.cb == '')
loadpage(me.nm);
else
show_chart_browser(me.nm,me.cb);
}
else
msgprint('No read permission',1);
}
$c_obj('Setup Wizard Control','get_page_lst',me.nm,callback);
}
// Setup Data
// =======================================================================================================================================================
SetupData = function(cnty){
// arg : 1 - Docbrowser, 2 - Page, 3 - DocType
//[label, arg, name, callback/col_name, description]
this.system = {'System':[['Global Defaults',3,'Manage Account','','Set global default values'],
['Manage Series',3,'Naming Series','','Manage numbering series for transactions'],
['Custom Field',1,'Custom Field','dt'+NEWLINE+'label'+NEWLINE+'fieldtype'+NEWLINE+'options','Add and manage custom fields on forms'],
['Email Settings',3,'Email Settings','','Outgoing email server and address'],
['Notification Settings',3,'Notification Control','','Automatic emails set at selected events'],
['Company',1,'Company','id'+NEWLINE+'is_active'+NEWLINE+'email','Manage list of companies'],
['Fiscal Year',1,'Fiscal Year','id'+NEWLINE+'company'+NEWLINE+'is_active'+NEWLINE+'year','Manage list of fiscal years'],
['Personalize',3,'Personalize','','Set your banner'],
['Manage Trash',2,'Trash','','Restore trashed items'],
['Import Data',2,'Import Data','','Import data from CSV files'],
['Manage Users',2,'My Company','','Add / remove users and manage their roles'],
['Web Forms',2,'Webforms','', 'Code to embed forms in yor website'],
['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool (beta)'],
['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
['Letter Head',1,'Letter Head','','Manage different letter heads for Prints'],
['SMS Settings',3,'SMS Settings','','Integrate your personalized SMS gateway which support http web service'],
['SMS Center',3,'SMS Center','','Send mass sms to your leads, contacts and partners']
]};
this.general = {'General':[['Authorization Rule',1,'Authorization Rule','','Set rules based on amounts'],
['Print Heading',1,'Print Heading','','Manage headings for printing transactions'],
['Term',1,'Term','','Manage template of standard Terms for order / invoices etc'],
['Currency',1,'Currency','','Manage list of currencies'],
['Country',1,'Country','','Country master'],
['State',1,'State','','State master'],
['Rename Tool',3,'Rename Tool','','Rename a record'],
['Bulk Rename Tool',3,'Bulk Rename Tool','','Rename multiple records at a time'],
['Activty Type',1,'Activity Type','','Types of activities that you can select in your Timesheet'],
['City',1,'City','','City master']]};
this.selling = {'Selling':[['Customer Group',2,'Sales Browser','Customer Group','Manage customer categories'],
['Territory',2,'Sales Browser','Territory','Manage sales territories'],
['Customer',1,'Customer','customer_group'+NEWLINE+'country','Customer master'],
['Sales Person',2,'Sales Browser','Sales Person','Manage sales persons'],
['Sales Partner',1,'Sales Partner','', 'Manage sales partners'],
['Campaign',1,'Campaign','id'+NEWLINE+'campaign_name'+NEWLINE+'description','Manage sales / marketing campaigns'],
['Sales BOM',1,'Sales BOM','id'+NEWLINE+'is_active'+NEWLINE+'new_item_name'+NEWLINE+'description'+NEWLINE+'item_group','Manage Sales Bill of Material (Main item + accessories)'],
['Price List',1,'Price List','','Price list master']]};
this.accounts = {'Accounts':[['Chart of Accounts',2,'Accounts Browser','Account','Manage chart of accounts'],
['Chart of Cost Centers',2,'Accounts Browser','Cost Center','Manage chart of cost centers'],
['POS Setting',1,'POS Setting','','Manage Point of Sales default Settings.']]};
// if country = india; show india related doctypes
//-------------------------------------------------
if(cnty == 'India'){
var lst1 = [['TDS Rate Chart',1,'TDS Rate Chart','', 'TDS rate master'],['TDS Category',1,'TDS Category','id'+NEWLINE+'module','TDS categories']];
for(var i =0; i<lst1.length;i++)
this.accounts['Accounts'].push(lst1[i]);
}
//--------------------------------------------------
var lst = [['Monthly Distribution',1,'Budget Distribution','id'+NEWLINE+'fiscal_year'+NEWLINE+'distribution_id','Manage budget distributions (seasonalities)'],
['Sales Other Charges',1,'Other Charges','','Manage your charge structures (taxes + charges) for sales'],
['Purchase Other Charges',1,'Purchase Other Charges','','Manage your charge structures (taxes + charges) for purchase'],
['Mode of Payment',1,'Mode of Payment','','Mode of payment master']];
for(var i =0; i<lst.length;i++)
this.accounts['Accounts'].push(lst[i]);
this.stock = {'Stock':[['Item Group',2,'Sales Browser','Item Group','Manage item classifications'],
['Item',1,'Item','name'+NEWLINE+'item_group'+NEWLINE+'description','Item master'],
['Brand',1,'Brand','id'+NEWLINE+'description','Brand master'],
['Batch',1,'Batch','name'+NEWLINE+'start_date'+NEWLINE+'item'+NEWLINE+'expiry_date','Manage batches'],
['Price List',1,'Price List','','Price list master'],
['UOM',1,'UOM','','Unit of measure (UOM) master'],
['Warehouse Type',1,'Warehouse Type','','Warehouse classifications'],
['Warehouse',1,'Warehouse','','Warehouse master']]};
this.buying = {'Buying':[['Supplier Type',1,'Supplier Type','','Manage supplier classifications'],
['Supplier',1,'Supplier','id'+NEWLINE+'supplier_type'+NEWLINE+'supplier_status'+NEWLINE+'company','Supplier master']]};
this.maintenance = {'Maintenance':[['Serial No',1,'Serial No','item_code'+NEWLINE+'status'+NEWLINE+'pr_no'+NEWLINE+'delivery_note_no'+NEWLINE+'customer_name','Manage unique serial numbers for items'],
['Purpose of Service',1,'Purpose of Service','','Purpose of service master']]};
this.production = {'Production':[['Bill of Materials',1,'Bill Of Materials','id'+NEWLINE+'item'+NEWLINE+'description'+NEWLINE+'operating_cost'+NEWLINE+'maintained_by','Muti-level bill of materials and operations'],
['Workstation',1,'Workstation','id'+NEWLINE+'workstation_name'+NEWLINE+'warehouse'+NEWLINE+'description','Workstation master']]};
this.hr = {'HR':[['Department',1,'Department','','Company department master'],
['Designation',1,'Designation','','Company designation master'],
['Branch',1,'Branch','','Manage branches for your company'],
['Grade',1,'Grade','','Manage employee grades'],
['Employment Type',1,'Employment Type','','Manage types of employment'],
['Employee',1,'Employee','employee_name'+NEWLINE+'employment_type'+NEWLINE+'status'+NEWLINE+'branch'+NEWLINE+'designation'+NEWLINE+'department'+NEWLINE+'grade'+NEWLINE+'reports_to','Employee master'],
['Earning Type',1,'Earning Type','taxable'+NEWLINE+'exemption_limit','Types of salary earning master'],
['Deduction Type',1,'Deduction Type','','Types of salary deduction master'],
['Expense Type',1,'Expense Type','', 'Types of expense master'],
['Salary Structure',1,'Salary Structure','employee'+NEWLINE+'is_active'+NEWLINE+'fiscal_year'+NEWLINE+'from_date'+NEWLINE+'ctc'+NEWLINE+'total_earning'+NEWLINE+'total_deduction'+NEWLINE+'total','Salary structure template'],
['Holiday List',1,'Holiday List','fiscal_year','List of holidays'],
['Leave Type',1,'Leave Type','max_days_allowed'+NEWLINE+'is_carry_forward'+NEWLINE+'is_encash','Leave type master'],
['KRA Template',1,'KRA Template','','Template of Key Result Areas (KRAs)']]};
}

View File

@@ -1,27 +0,0 @@
# Page, Setup
[
# These values are common in all dictionaries
{
'creation': '2010-12-16 23:46:03',
'docstatus': 0,
'modified': '2011-07-04 16:58:27',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Setup',
'name': '__common__',
'page_name': 'Setup',
'standard': 'Yes'
},
# Page, Setup
{
'doctype': 'Page',
'name': 'Setup'
}
]

View File

@@ -1 +0,0 @@
Setup

View File

@@ -1 +0,0 @@
<div id="setup_wizard_wrapper" class="layout_wrapper"></div>

View File

@@ -1,167 +0,0 @@
pscript['onload_Setup Wizard'] = function()
{
// header and toolbar
var h = new PageHeader('setup_wizard_wrapper','Setup Wizard','All important setup items in one place');
pscript.setup_wizard_callback();
}
// ==================================================================================================
pscript.setup_wizard_callback = function(){
var items = {};
items['Customer'] = new pscript.Setup_Wizard_Obj('Customer', 'customer_name', 0, '', 'Customer', 'Manage your customers',1);
items['Supplier'] = new pscript.Setup_Wizard_Obj('Supplier', 'supplier_name', 0, '', 'Supplier', 'Manage your supplier',1);
items['Item'] = new pscript.Setup_Wizard_Obj('Item', 'item_name', 0, '', 'Item', 'Create your items',1);
//items['Customer Group'] = new pscript.Setup_Wizard_Obj('Customer Group', 'group_name', 0, '', 'Customer Group', 'Organizes your customers for better analysis');
items['Price List'] = new pscript.Setup_Wizard_Obj('Price List', 'price_list_name', 0, '', 'Price List', 'Helps you maintain different prices for different customers, currencies etc.');
items['Supplier Type'] = new pscript.Setup_Wizard_Obj('Supplier Type', 'supplier_type', 0, '', 'Supplier Type', 'Organizes your suppliers for better analysis');
//items['Item Group'] = new pscript.Setup_Wizard_Obj('Item Group', 'group_name', 0, '', 'Item Group', 'Organizes your items for better analysis');
items['UoM'] = new pscript.Setup_Wizard_Obj('UOM', 'uom_name', 0, '', 'UOM', 'Maintain multiple Units of Measure (UOM)');
items['Warehouse Type'] = new pscript.Setup_Wizard_Obj('Warehouse Type', 'warehouse_type', 0, '', 'Warehouse Type', 'Define types of warehouses');
items['Warehouse'] = new pscript.Setup_Wizard_Obj('Warehouse', 'warehouse_name', 'warehouse_type', 'Warehouse Type', 'Warehouse', 'Manage stock across different warehouses');
items['Print Heading'] = new pscript.Setup_Wizard_Obj('Print Heading', 'print_heading', 'transaction', 'Transaction', 'Print Heading', 'Define print heading for various transaction.');
items['Warehouse Type'].onmake = function(){
items['Warehouse'].refresh_select('warehouse_type', 'Warehouse Type', 'Warehouse');
}
items['Print Heading'].onmake = function(){
items['Print Heading'].refresh_select('transaction', 'Transaction', 'Print Heading');
}
}
// ==================================================================================================
pscript.Setup_Wizard_Obj = function(lbl, name_field, opt_fieldname, opt_field_tbl, dt, desc, important)
{
this.lbl = lbl;
this.make_body(lbl, important);
if(lbl != 'Item')
this.make_input(name_field);
if(opt_fieldname){
this.make_select(opt_fieldname, opt_field_tbl, dt);
}
this.show_description(desc);
this.make_button();
this.create_doc_link(dt);
}
pscript.Setup_Wizard_Obj.prototype.make_body = function(lbl, important) {
var wrapper = $a($i('setup_wizard_wrapper'), 'div', '', {padding:'8px', borderBottom: '1px solid #AAA'});
if(important)$y(wrapper, {backgroundColor:'#FFD'});
this.tab = make_table(wrapper,1,3,'90%',['20%','50%','30%'], {padding:'2px 0px', verticalAlign:'middle'});
this.desc_area = $a(wrapper,'div','comment');
$td(this.tab,0,0).innerHTML = lbl.bold();
}
pscript.Setup_Wizard_Obj.prototype.make_input = function(name_field){
this.input = $a_input($td(this.tab,0,1), 'text');
this.name_field = name_field;
}
pscript.Setup_Wizard_Obj.prototype.make_select = function(fn, ft, dt){
this.select = $a($td(this.tab,0,1), 'select', '', {width:'120px', marginLeft:'8px'});
this.opt_field = fn;
this.sel_field = 'Select ' + ft + '...';
this.refresh_select(fn, ft, dt);
}
pscript.Setup_Wizard_Obj.prototype.refresh_select = function(fn, ft, dt){
var me = this;
if(ft == 'Transaction'){
empty_select(me.select);
add_sel_options(me.select, ['Select Transaction ...','Purchase Order','Sales Order','Service Order','Purchase Receipt','Delivery Note','Receivable Voucher','Payable Voucher','Journal Voucher']);
}
else{
$c_obj('Setup Wizard Control', 'get_master_lists','', function(r,rt){
var ft_lst = [];
if(r.message) ft_lst = r.message;
ft_lst.push('Select Warehouse Type ...');
empty_select(me.select);
add_sel_options(me.select, ft_lst.reverse(), 'Warehouse Type');
});
}
}
pscript.Setup_Wizard_Obj.prototype.make_button = function(){
var me = this;
var create = $a($td(this.tab,0,1), 'button', '', {marginLeft:'8px'});
create.innerHTML = 'Create';
create.onclick = function(){
me.create_record(this);
}
}
// show description
pscript.Setup_Wizard_Obj.prototype.show_description=function(desc){
this.desc_area.innerHTML = desc;
}
// create link to show listing of all records
pscript.Setup_Wizard_Obj.prototype.create_doc_link = function(doc_link){
this.obj_link = $a($td(this.tab,0,2), 'span', 'link_type',{marginLeft:'8px'});
this.obj_link.innerHTML = 'View ' + doc_link + ' list';
this.dt = doc_link;
this.obj_link.onclick = function(){
if(doc_link == 'Customer') doc_lst = 'customer_group'+NEWLINE+'country';
else if(doc_link == 'Supplier') doc_lst = 'supplier_type'+NEWLINE+'supplier_status'+NEWLINE+'company';
else if(doc_link == 'Item') doc_lst = 'item_group'+NEWLINE+'description';
if(doc_link == 'Customer' || doc_link == 'Supplier' || doc_link == 'Item')
loaddocbrowser(doc_link,doc_link, doc_lst);
else
loaddocbrowser(doc_link);
}
}
pscript.Setup_Wizard_Obj.prototype.create_record = function(cur_obj)
{
var me = this;
if(me.lbl == 'Item'){ me.create_master_rec(); }
else{
if(this.input.value) { //check for input value
if (this.select && (this.sel_field == this.select.value)){ //check for value is selected or not
alert('Please select '+this.select.value);
this.input.value = '';
}
else{
args = {};
args['Doctype'] = this.dt;
if(strip(this.input.value) == ''){ alert("Please enter proper name."); me.input.value = '';}
else{
if(me.lbl == 'Customer' || me.lbl == 'Supplier'){ this.create_master_rec(); }
else{
args[this.name_field] = this.input.value;
args[this.opt_field] = this.opt_field ? this.select.value : '';
$c_obj('Setup Wizard Control', 'create_record', JSON.stringify(args), function(r,rt){
alert(r.message);
me.input.value = '';
if(me.onmake) me.onmake();
});
}
}
}
}
else
alert("Please enter " +this.dt);
}
}
pscript.Setup_Wizard_Obj.prototype.create_master_rec = function(){
var me = this;
var fn = function(new_docname) {
var new_doc = locals[me.lbl][new_docname];
if(me.lbl == 'Customer')
new_doc.customer_name = me.input.value;
else if(me.lbl == 'Supplier')
new_doc.supplier_name = me.input.value;
}
new_doc(me.lbl, fn);
}

View File

@@ -1,44 +0,0 @@
# Page, Setup Wizard
[
# These values are common in all dictionaries
{
'creation': '2010-10-12 15:19:32',
'docstatus': 0,
'modified': '2010-09-25 00:00:00',
'modified_by': 'Administrator',
'owner': 'Administrator'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Setup',
'name': '__common__',
'page_name': 'Setup Wizard',
'show_in_menu': 0,
'standard': 'Yes'
},
# These values are common for all Page Role
{
'doctype': 'Page Role',
'idx': 1,
'name': '__common__',
'parent': 'Setup Wizard',
'parentfield': 'roles',
'parenttype': 'Page',
'role': 'System Manager'
},
# Page, Setup Wizard
{
'doctype': 'Page',
'name': 'Setup Wizard'
},
# Page Role
{
'doctype': 'Page Role'
}
]

View File

@@ -1 +0,0 @@
<div></div>

View File

@@ -1,13 +0,0 @@
<div class="layout_wrapper">
<div id="webform_div"></div>
<p><strong>Note : </strong>Copy and paste code provided below in your website wherever you want to show the form to capture details</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>Lead</strong></span></p>
<div id="lead_div"></div>
<p><span style="font-size: medium;"><strong>Customer Issue</strong></span></p>
<div id="cust_issue_div"></div>
<p><span style="font-size: medium;"><strong>Job Application</strong></span></p>
<div id="job_div"></div>
<p><span style="font-size: medium;"><strong>Ticket</strong></span></p>
<div id="ticket_div"></div>
</div>

View File

@@ -1,26 +0,0 @@
pscript.onload_Webforms = function(){
$c_obj('Home Control','get_acc_id','', function(r,rt) {
if(r.message) {
var acc_id = r.message;
var parent = $i('webform_div');
new PageHeader(parent,'Web Forms','');
var lead_dv = $a('lead_div','div', '', {border:'1px solid #AAA', padding:'8px', width:'90%'});
var cust_issue_dv = $a('cust_issue_div','div', '', {border:'1px solid #AAA', padding:'8px', width:'95%'});
var job_dv = $a('job_div','div', '', {border:'1px solid #AAA', padding:'8px', width:'95%'});
var ticket_dv = $a('ticket_div','div', '', {border:'1px solid #AAA', padding:'8px', width:'95%'});
// url
if(window.location.href.indexOf('?')!=-1)
var url = window.location.href.split('?')[0];
else
var url = window.location.href.split('#')[0];
lead_dv.innerHTML = '&lt;iframe src ="'+url+'?ac_name='+acc_id+'&embed=Lead" width ="400" height="800" frameborder="0"&gt;&lt;/iframe&gt;';
cust_issue_dv.innerHTML = '&lt;iframe src ="'+url+'?ac_name='+acc_id+'&embed=Customer Issue" width ="400" height="500" frameborder="0"&gt;&lt;/iframe&gt;';
job_dv.innerHTML = '&lt;iframe src ="'+url+'?ac_name='+acc_id+'&embed=Job Application" width ="400" height="800" frameborder="0""&gt;&lt;/iframe&gt;';
ticket_dv.innerHTML = '&lt;iframe src ="'+url+'?ac_name='+acc_id+'&embed=Support Ticket" width ="400" height="800" frameborder="0""&gt;&lt;/iframe&gt;';
}
});
}

View File

@@ -1,51 +0,0 @@
# Page, Webforms
[
# These values are common in all dictionaries
{
'creation': '2010-10-14 11:15:59',
'docstatus': 0,
'modified': '2011-01-04 13:19:54',
'modified_by': 'Administrator',
'owner': 'ashwini@webnotestech.com'
},
# These values are common for all Page
{
'doctype': 'Page',
'module': 'Setup',
'name': '__common__',
'page_name': 'Webforms',
'show_in_menu': 1,
'standard': 'Yes'
},
# These values are common for all Page Role
{
'doctype': 'Page Role',
'name': '__common__',
'parent': 'Webforms',
'parentfield': 'roles',
'parenttype': 'Page'
},
# Page, Webforms
{
'doctype': 'Page',
'name': 'Webforms'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 1,
'role': 'Administrator'
},
# Page Role
{
'doctype': 'Page Role',
'idx': 2,
'role': 'System Manager'
}
]

View File

@@ -1 +0,0 @@
webforms