added workflow help, fixed button primary action in form and refactored permissions
This commit is contained in:
parent
a0212091f0
commit
9e6e2fe4c7
10 changed files with 147 additions and 127 deletions
|
|
@ -25,7 +25,8 @@ wn.core.Workflow = wn.ui.form.Controller.extend({
|
|||
fieldtype: ["not in", wn.model.no_value_type]
|
||||
}),
|
||||
function(d) { return d.fieldname; });
|
||||
wn.meta.get_docfield("Workflow Document State", "update_field").options = fields;
|
||||
wn.meta.get_docfield("Workflow Document State", "update_field").options
|
||||
= [""].concat(fields);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@
|
|||
"lib/public/js/wn/model/sync.js",
|
||||
"lib/public/js/wn/model/create_new.js",
|
||||
"lib/public/js/wn/model/perm.js",
|
||||
"lib/public/js/wn/model/workflow.js",
|
||||
|
||||
"lib/public/js/wn/misc/user.js",
|
||||
"lib/public/js/wn/misc/utils.js",
|
||||
|
|
|
|||
|
|
@ -125,9 +125,6 @@ Field.prototype.set_description = function(txt) {
|
|||
}
|
||||
}
|
||||
|
||||
// Field Refresh
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
Field.prototype.get_status = function() {
|
||||
// if used in filters
|
||||
if(this.in_filter)
|
||||
|
|
@ -143,39 +140,51 @@ Field.prototype.get_status = function() {
|
|||
var ret;
|
||||
|
||||
// permission level
|
||||
if(cur_frm.editable && p && p[WRITE] && !this.df.disabled)ret='Write';
|
||||
else if(p && p[READ])ret='Read';
|
||||
else ret='None';
|
||||
|
||||
// binary
|
||||
if(this.df.fieldtype=='Binary')
|
||||
ret = 'None'; // no display for binary
|
||||
if(p && p[WRITE] && !this.df.disabled)
|
||||
ret='Write';
|
||||
else if(p && p[READ])
|
||||
ret='Read';
|
||||
else
|
||||
ret='None';
|
||||
|
||||
// hidden
|
||||
if(cint(this.df.hidden))
|
||||
if(cint(this.df.hidden)) {
|
||||
ret = 'None';
|
||||
}
|
||||
|
||||
// for submit
|
||||
if(ret=='Write' && cint(cur_frm.doc.docstatus) > 0) ret = 'Read';
|
||||
if(ret=='Write' && cint(cur_frm.doc.docstatus) > 0) {
|
||||
ret = 'Read';
|
||||
}
|
||||
|
||||
// allow on submit
|
||||
var a_o_s = cint(this.df.allow_on_submit);
|
||||
|
||||
if(a_o_s && (this.in_grid || (this.frm && this.frm.not_in_container))) {
|
||||
if(a_o_s && (this.in_grid || (this.frm && this.frm.meta.istable))) {
|
||||
// if grid is allow-on-submit, everything in it is too!
|
||||
a_o_s = null;
|
||||
if(this.in_grid) a_o_s = this.grid.field.df.allow_on_submit; // take from grid
|
||||
if(this.frm && this.frm.not_in_container) { a_o_s = cur_grid.field.df.allow_on_submit;} // take from grid
|
||||
}
|
||||
|
||||
if(cur_frm.editable && a_o_s && cint(cur_frm.doc.docstatus)>0 && !this.df.hidden) {
|
||||
tmp_perm = wn.perm.get_perm(cur_frm.doctype, cur_frm.docname, 1);
|
||||
if(tmp_perm[this.df.permlevel] && tmp_perm[this.df.permlevel][WRITE]) {
|
||||
ret='Write';
|
||||
if(this.in_grid)
|
||||
a_o_s = this.grid.field.df.allow_on_submit;
|
||||
if(this.frm.meta.istable) {
|
||||
a_o_s = cur_grid.field.df.allow_on_submit;
|
||||
}
|
||||
}
|
||||
|
||||
// make a field read_only if read_only is checked (disregards write permission)
|
||||
if(cint(this.df.read_only) && ret=="Write") ret = "Read";
|
||||
if(ret=="Read" && a_o_s && cint(cur_frm.doc.docstatus)==1 &&
|
||||
cur_frm.perm[this.df.permlevel][WRITE]) {
|
||||
ret='Write';
|
||||
}
|
||||
|
||||
// workflow state
|
||||
if(ret=="Write" && cur_frm.read_only) {
|
||||
ret = 'Read';
|
||||
}
|
||||
|
||||
// make a field read_only if read_only
|
||||
// is checked (disregards write permission)
|
||||
if(ret=="Write" && cint(this.df.read_only)) {
|
||||
ret = "Read";
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ _f.Frm = function(doctype, parent, in_form) {
|
|||
this.refresh_if_stale_for = 600;
|
||||
|
||||
var me = this;
|
||||
this.is_editable = {};
|
||||
this.last_view_is_edit = {};
|
||||
this.opendocs = {};
|
||||
this.sections = [];
|
||||
this.grids = [];
|
||||
|
|
@ -254,9 +254,9 @@ _f.Frm.prototype.rename_notify = function(dt, old, name) {
|
|||
else
|
||||
return;
|
||||
|
||||
// editable
|
||||
this.is_editable[name] = this.is_editable[old];
|
||||
delete this.is_editable[old];
|
||||
// view_is_edit
|
||||
this.last_view_is_edit[name] = this.last_view_is_edit[old];
|
||||
delete this.last_view_is_edit[old];
|
||||
|
||||
// cleanup
|
||||
if(this && this.opendocs[old]) {
|
||||
|
|
@ -458,16 +458,8 @@ _f.Frm.prototype.check_doc_perm = function() {
|
|||
var dt = this.parent_doctype?this.parent_doctype : this.doctype;
|
||||
var dn = this.parent_docname?this.parent_docname : this.docname;
|
||||
this.perm = wn.perm.get_perm(dt, dn);
|
||||
this.orig_perm = wn.perm.get_perm(dt, dn, 1);
|
||||
|
||||
if(!this.perm[0][READ]) {
|
||||
if(user=='Guest') {
|
||||
// allow temp access? via encryted akey
|
||||
if(_f.temp_access[dt] && _f.temp_access[dt][dn]) {
|
||||
this.perm = [[1,0,0]]
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
window.history.back();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -492,6 +484,9 @@ _f.Frm.prototype.refresh = function(docname) {
|
|||
// check permissions
|
||||
if(!this.check_doc_perm()) return;
|
||||
|
||||
// read only (workflow)
|
||||
this.read_only = wn.workflow.is_read_only(this.doctype, this.docname);
|
||||
|
||||
// set the doc
|
||||
this.doc = wn.model.get_doc(this.doctype, this.docname);
|
||||
|
||||
|
|
@ -519,20 +514,20 @@ _f.Frm.prototype.refresh = function(docname) {
|
|||
this.setnewdoc(this.docname);
|
||||
}
|
||||
|
||||
// editable
|
||||
// view_is_edit
|
||||
if(this.doc.__islocal)
|
||||
this.is_editable[this.docname] = 1; // new is editable
|
||||
this.last_view_is_edit[this.docname] = 1; // new is view_is_edit
|
||||
|
||||
this.editable = this.is_editable[this.docname];
|
||||
this.view_is_edit = this.last_view_is_edit[this.docname];
|
||||
|
||||
if(this.editable || (!this.editable && this.meta.istable)) {
|
||||
// show form layout (with fields etc)
|
||||
// ----------------------------------
|
||||
if(this.view_is_edit || (!this.view_is_edit && this.meta.istable)) {
|
||||
if(this.print_wrapper) {
|
||||
$dh(this.print_wrapper);
|
||||
$ds(this.page_layout.wrapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// header
|
||||
if(!this.meta.istable) {
|
||||
this.refresh_header();
|
||||
|
|
@ -570,8 +565,6 @@ _f.Frm.prototype.refresh = function(docname) {
|
|||
}
|
||||
|
||||
} else {
|
||||
// show print layout
|
||||
// ----------------------------------
|
||||
this.refresh_header();
|
||||
if(this.print_wrapper) {
|
||||
this.refresh_print_layout();
|
||||
|
|
@ -586,9 +579,10 @@ _f.Frm.prototype.refresh = function(docname) {
|
|||
_f.Frm.prototype.refresh_footer = function() {
|
||||
var f = this.page_layout.footer;
|
||||
if(f.save_area) {
|
||||
if(this.editable && (!this.meta.hide_toolbar) && (!this.meta.in_dialog || this.in_form)
|
||||
&& this.doc.docstatus==0 && !this.meta.istable && this.perm[0][WRITE]
|
||||
&& (this.fields && this.fields.length > 7) && !this.save_disabled) {
|
||||
// if save button is there in the header
|
||||
if(this.frm_head && this.frm_head.appframe.toolbar
|
||||
&& this.frm_head.appframe.toolbar.find(".btn-save").length && !this.save_disabled
|
||||
&& (this.fields && this.fields.length > 7)) {
|
||||
f.show_save();
|
||||
} else {
|
||||
f.hide_save();
|
||||
|
|
@ -729,15 +723,15 @@ _f.Frm.prototype.setnewdoc = function(docname) {
|
|||
// Client Script
|
||||
this.runclientscript('onload', this.doctype, this.docname);
|
||||
|
||||
this.is_editable[docname] = 1;
|
||||
if(cint(this.meta.read_only_onload)) this.is_editable[docname] = 0;
|
||||
this.last_view_is_edit[docname] = 1;
|
||||
if(cint(this.meta.read_only_onload)) this.last_view_is_edit[docname] = 0;
|
||||
|
||||
this.opendocs[docname] = true;
|
||||
}
|
||||
|
||||
_f.Frm.prototype.edit_doc = function() {
|
||||
// set fields
|
||||
this.is_editable[this.docname] = true;
|
||||
this.last_view_is_edit[this.docname] = true;
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
|
@ -996,7 +990,8 @@ _f.Frm.prototype.set_value_in_locals = function(dt, dn, fn, v) {
|
|||
}
|
||||
|
||||
_f.Frm.prototype.set_unsaved = function() {
|
||||
if(cur_frm.doc.__unsaved) return;
|
||||
if(cur_frm.doc.__unsaved)
|
||||
return;
|
||||
cur_frm.doc.__unsaved = 1;
|
||||
|
||||
var frm_head;
|
||||
|
|
|
|||
|
|
@ -207,29 +207,13 @@ _f.TableField.prototype.refresh = function() {
|
|||
this.df['default']='';
|
||||
|
||||
this.grid.can_add_rows = false;
|
||||
this.grid.can_edit = false
|
||||
this.grid.can_edit = false;
|
||||
|
||||
if(st=='Write') {
|
||||
if(cur_frm.editable && this.perm[this.df.permlevel] && this.perm[this.df.permlevel][WRITE]) {
|
||||
this.grid.can_edit = true;
|
||||
if(this.df['default'].toLowerCase()!='no toolbar')
|
||||
this.grid.can_add_rows = true;
|
||||
}
|
||||
this.grid.can_edit = true;
|
||||
if(this.df['default'].toLowerCase()!='no toolbar')
|
||||
this.grid.can_add_rows = true;
|
||||
|
||||
// submitted or cancelled
|
||||
if(cur_frm.editable && cur_frm.doc.docstatus > 0) {
|
||||
if(this.df.allow_on_submit && cur_frm.doc.docstatus==1) {
|
||||
this.grid.can_edit = true;
|
||||
if(this.df['default'].toLowerCase()=='no toolbar') {
|
||||
this.grid.can_add_rows = false;
|
||||
} else {
|
||||
this.grid.can_add_rows = true;
|
||||
}
|
||||
} else {
|
||||
this.grid.can_add_rows = false;
|
||||
this.grid.can_edit = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.df['default'].toLowerCase()=='no add rows') {
|
||||
this.grid.can_add_rows = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ _f.FrmHeader = Class.extend({
|
|||
cur_frm.save('Update', null, this);
|
||||
}, '')
|
||||
}
|
||||
|
||||
this.set_primary_button();
|
||||
},
|
||||
set_label: function(labinfo) {
|
||||
this.$w.find('.label').remove();
|
||||
|
|
@ -133,23 +135,19 @@ _f.FrmHeader = Class.extend({
|
|||
|
||||
// Edit
|
||||
if(cur_frm.meta.read_only_onload && !cur_frm.doc.__islocal) {
|
||||
if(!cur_frm.editable)
|
||||
this.appframe.add_button('Edit', function() {
|
||||
cur_frm.edit_doc();
|
||||
},'icon-pencil');
|
||||
else
|
||||
this.appframe.add_button('Print View', function() {
|
||||
cur_frm.is_editable[cur_frm.docname] = 0;
|
||||
cur_frm.refresh(); }, 'icon-print' );
|
||||
this.appframe.add_button('Print View', function() {
|
||||
cur_frm.last_view_is_edit[cur_frm.docname] = 0;
|
||||
cur_frm.refresh(); }, 'icon-print' );
|
||||
}
|
||||
|
||||
var docstatus = cint(cur_frm.doc.docstatus);
|
||||
|
||||
// Save
|
||||
if(docstatus==0 && p[WRITE]) {
|
||||
if(docstatus==0 && p[WRITE] && !cur_frm.read_only) {
|
||||
this.appframe.add_button('Save', function() {
|
||||
cur_frm.save('Save', null, this);}, 'icon-save');
|
||||
this.appframe.buttons['Save'].addClass('btn-info')
|
||||
.html("<i class='icon-save'></i> Save (Ctrl+S)");
|
||||
this.appframe.buttons['Save'].addClass("btn-save")
|
||||
.html("<i class='icon-save'></i> <u>S</u>ave");
|
||||
}
|
||||
|
||||
// Submit
|
||||
|
|
@ -168,11 +166,29 @@ _f.FrmHeader = Class.extend({
|
|||
this.appframe.add_button('Amend', function() {
|
||||
cur_frm.amend_doc() }, 'icon-pencil');
|
||||
}
|
||||
this.set_primary_button();
|
||||
},
|
||||
show: function() {
|
||||
},
|
||||
hide: function() {
|
||||
|
||||
set_primary_button: function() {
|
||||
if(!this.appframe.toolbar)
|
||||
return;
|
||||
|
||||
var buttons = this.appframe.buttons;
|
||||
|
||||
// highlight save
|
||||
this.appframe.toolbar.find("button").removeClass("btn-info");
|
||||
if(buttons["Save"]) {
|
||||
buttons["Save"].addClass("btn-info");
|
||||
}
|
||||
|
||||
// highlight submit button
|
||||
if(buttons["Submit"] && !cur_frm.doc.__unsaved) {
|
||||
this.appframe.toolbar.find("button").removeClass("btn-info");
|
||||
buttons["Submit"].addClass("btn-info");
|
||||
// highlight update button
|
||||
} else if(buttons["Update"] && cur_frm.doc.__unsaved) {
|
||||
this.appframe.toolbar.find("button").removeClass("btn-info");
|
||||
buttons["Update"].addClass("btn-info");
|
||||
}
|
||||
},
|
||||
hide_close: function() {
|
||||
this.$w.find('.close').toggle(false);
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ _f.Grid.prototype.set_cell_value = function(cell) {
|
|||
$y($td(t,0,0),{paddingLeft:'4px'});
|
||||
$td(t,0,0).innerHTML = cell.row.rowIndex + 1;
|
||||
|
||||
if(cur_frm.editable && this.can_edit) {
|
||||
if(this.can_edit) {
|
||||
$("<a title='Edit Row'><i class='icon-edit'></i></a>")
|
||||
.click(function() {
|
||||
_f.cur_grid = me;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,12 @@
|
|||
wn.ui.form.States = Class.extend({
|
||||
init: function(opts) {
|
||||
$.extend(this, opts);
|
||||
this.state_fieldname = wn.meta.get_state_fieldname(this.frm.doctype);
|
||||
this.state_fieldname = wn.workflow.get_state_fieldname(this.frm.doctype);
|
||||
|
||||
// no workflow?
|
||||
if(!this.state_fieldname)
|
||||
return;
|
||||
|
||||
this.make();
|
||||
this.bind_action();
|
||||
|
||||
|
|
@ -37,20 +42,47 @@ wn.ui.form.States = Class.extend({
|
|||
this.$wrapper = $('<div class="states" style="margin-bottom: 11px; height: 26px;">\
|
||||
<div class="btn-group">\
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">\
|
||||
<i class="icon-small"></i> <span class="state-text"></span> <span class="caret"></span></button>\
|
||||
<i class="icon-small"></i> <span class="state-text"></span> <span class="caret"></span>\
|
||||
</button>\
|
||||
<ul class="dropdown-menu">\
|
||||
</ul>\
|
||||
</div>\
|
||||
<button class="btn btn-help">?</button>\
|
||||
</div>').appendTo(this.frm.page_layout.body_header);
|
||||
this.$wrapper.toggle(false);
|
||||
this.setup_help();
|
||||
},
|
||||
|
||||
|
||||
setup_help: function() {
|
||||
var me = this;
|
||||
this.$wrapper.find(".btn-help").click(function() {
|
||||
wn.workflow.setup(me.frm.doctype);
|
||||
var state = me.get_state();
|
||||
var d = new wn.ui.Dialog({
|
||||
title: "Workflow: "
|
||||
+ wn.workflow.workflows[me.frm.doctype].name
|
||||
})
|
||||
var next_html = $.map(wn.workflow.get_transitions(me.frm.doctype, state),
|
||||
function(d) {
|
||||
return d.action.bold() + " by Role " + d.allowed;
|
||||
}).join(", ") || "None: End of Workflow".bold();
|
||||
|
||||
$(d.body).html("<p>Current status: " + state.bold() + "</p>"
|
||||
+ "<p>Document is only editable by users of role: " + wn.workflow.get_document_state(me.frm.doctype,
|
||||
state).allow_edit.bold() + "</p>"
|
||||
+ "<p>Next actions: "+ next_html +"</p>"
|
||||
+ (me.frm.doc.__islocal ? "<div class='alert'>Workflow will start after saving</div>" : "")
|
||||
+ "<p class='help'>Note: Other permission rules may also apply</p>"
|
||||
).css({padding: '15px'});
|
||||
d.show();
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
// hide if its not yet saved
|
||||
this.$wrapper.toggle(false);
|
||||
if(this.frm.doc.__islocal) {
|
||||
this.set_default_state();
|
||||
return;
|
||||
}
|
||||
|
||||
// state text
|
||||
|
|
@ -68,26 +100,25 @@ wn.ui.form.States = Class.extend({
|
|||
.addClass("icon-" + state_doc.icon);
|
||||
|
||||
// set the style
|
||||
this.$wrapper.find(".btn").removeClass()
|
||||
this.$wrapper.find(".btn:first").removeClass()
|
||||
.addClass("btn dropdown-toggle")
|
||||
.addClass("btn-" + state_doc.style.toLowerCase());
|
||||
|
||||
// show actions from that state
|
||||
this.show_actions(state);
|
||||
|
||||
// disable if not allowed
|
||||
if(!this.frm.doc.__islocal)
|
||||
this.$wrapper.toggle(true);
|
||||
this.$wrapper.toggle(true);
|
||||
if(this.frm.doc.__islocal) {
|
||||
this.$wrapper.find('.btn:first').attr('disabled', true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
show_actions: function(state) {
|
||||
var $ul = this.$wrapper.find("ul");
|
||||
$ul.empty();
|
||||
$.each(wn.model.get("Workflow Transition", {
|
||||
parent: this.frm.doctype,
|
||||
state: state,
|
||||
}), function(i, d) {
|
||||
|
||||
$.each(wn.workflow.get_transitions(this.frm.doctype, state), function(i, d) {
|
||||
if(in_list(user_roles, d.allowed)) {
|
||||
d.icon = wn.model.get("Workflow State", {name:d.next_state})[0].icon;
|
||||
|
||||
|
|
@ -96,21 +127,16 @@ wn.ui.form.States = Class.extend({
|
|||
.appendTo($ul);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// disable the button if user cannot change state
|
||||
this.$wrapper.find('.btn').attr('disabled', $ul.find("li").length ? false : true);
|
||||
this.$wrapper.find('.btn:first')
|
||||
.attr('disabled', $ul.find("li").length ? false : true);
|
||||
},
|
||||
|
||||
set_default_state: function() {
|
||||
var d = wn.model.get("Workflow Document State", {
|
||||
parent: this.frm.doctype,
|
||||
idx: 1
|
||||
});
|
||||
|
||||
if(d && d.length) {
|
||||
this.frm.set_value_in_locals(this.frm.doctype, this.frm.docname,
|
||||
this.state_fieldname, d[0].state);
|
||||
refresh_field(this.state_fieldname);
|
||||
var default_state = wn.workflow.get_default_state(this.frm.doctype);
|
||||
if(default_state) {
|
||||
this.frm.set_value(this.state_fieldname, default_state);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -125,19 +151,12 @@ wn.ui.form.States = Class.extend({
|
|||
var me = this;
|
||||
$(this.$wrapper).on("click", "[data-action]", function() {
|
||||
var action = $(this).attr("data-action");
|
||||
var next_state = wn.model.get("Workflow Transition", {
|
||||
parent: me.frm.doctype,
|
||||
state: me.frm.doc[me.state_fieldname],
|
||||
action: action,
|
||||
})[0].next_state;
|
||||
var next_state = wn.workflow.get_next_state(me.frm.doc,
|
||||
me.frm.doc[me.state_fieldname], action);
|
||||
|
||||
me.frm.doc[me.state_fieldname] = next_state;
|
||||
|
||||
var new_state = wn.model.get("Workflow Document State", {
|
||||
parent: me.frm.doctype,
|
||||
state: next_state
|
||||
})[0];
|
||||
|
||||
var new_state = wn.workflow.get_document_state(me.frm.doctype, next_state);
|
||||
var new_docstatus = new_state.doc_status;
|
||||
|
||||
// update field and value
|
||||
|
|
|
|||
|
|
@ -105,9 +105,4 @@ $.extend(wn.meta, {
|
|||
}
|
||||
},
|
||||
|
||||
get_state_fieldname: function(doctype) {
|
||||
var wf = wn.model.get("Workflow", {document_type: doctype});
|
||||
return wf.length ? wf[0].workflow_state_field : null;
|
||||
},
|
||||
|
||||
});
|
||||
|
|
@ -40,7 +40,7 @@ $.extend(wn.perm, {
|
|||
|
||||
return perms[doctype][level][type];
|
||||
},
|
||||
get_perm: function(doctype, dn, ignore_submit) {
|
||||
get_perm: function(doctype, dn) {
|
||||
var perm = [[0,0],];
|
||||
if(in_list(user_roles, 'Administrator'))
|
||||
perm[0][READ] = 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue