diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index 0f4332a91a..d77481f8b9 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -42,6 +42,8 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.body = this.$body.get(0); this.$message = $('
').appendTo(this.modal_body); this.header = this.$wrapper.find(".modal-header"); + this.buttons = this.header.find('.buttons'); + this.set_indicator(); // make fields (if any) super.make(); @@ -164,6 +166,11 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { set_title(t) { this.$wrapper.find(".modal-title").html(t); } + set_indicator() { + if (this.indicator) { + this.header.find('.indicator').removeClass().addClass('indicator ' + this.indicator); + } + } show() { // show it if ( this.animate ) { diff --git a/frappe/public/js/frappe/ui/messages.js b/frappe/public/js/frappe/ui/messages.js index c6bc994a9d..ab20feeedd 100644 --- a/frappe/public/js/frappe/ui/messages.js +++ b/frappe/public/js/frappe/ui/messages.js @@ -53,6 +53,33 @@ frappe.confirm = function(message, ifyes, ifno) { return d; } +frappe.warn = function(title, message_html, proceed_action, primary_label) { + const d = new frappe.ui.Dialog({ + title: title, + indicator: 'red', + fields: [ + { + fieldtype: 'HTML', + fieldname: 'warning_message', + options: `` + } + ], + primary_action_label: primary_label, + primary_action: () => { + if (proceed_action) proceed_action(); + d.hide(); + }, + secondary_action_label: __("Cancel"), + }); + + d.buttons.find('.btn-primary').removeClass('btn-primary').addClass('btn-danger'); + const modal_footer = $(``).insertAfter($(d.modal_body)); + modal_footer.html(d.buttons); + + d.show(); + return d; +}; + frappe.prompt = function(fields, callback, title, primary_label) { if (typeof fields === "string") { fields = [{ diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js index 24fa946fc4..f4dde5804f 100644 --- a/frappe/public/js/frappe/utils/utils.js +++ b/frappe/public/js/frappe/utils/utils.js @@ -292,6 +292,25 @@ Object.assign(frappe.utils, { return frappe.utils.guess_style(text, null, true); }, + get_indicator_color: function(state) { + return frappe.db.get_list('Workflow State', {filters: {name: state}, fields: ['name', 'style']}).then(res => { + const state = res[0]; + if (!state.style) { + return frappe.utils.guess_colour(state.name); + } + const style = state.style; + const colour_map = { + "Success": "green", + "Warning": "orange", + "Danger": "red", + "Primary": "blue", + }; + + return colour_map[style]; + }); + + }, + sort: function(list, key, compare_type, reverse) { if(!list || list.length < 2) return list || []; diff --git a/frappe/workflow/doctype/workflow/workflow.js b/frappe/workflow/doctype/workflow/workflow.js index 6e12f5fa46..aba6f6fe48 100644 --- a/frappe/workflow/doctype/workflow/workflow.js +++ b/frappe/workflow/doctype/workflow/workflow.js @@ -5,7 +5,35 @@ frappe.ui.form.on("Workflow", { frm.set_query("document_type", {"issingle": 0, "istable": 0}); }, refresh: function(frm) { + if (frm.doc.document_type) { + frm.add_custom_button(__('Go to {0} List', [frm.doc.document_type]), () => { + frappe.set_route('List', frm.doc.document_type); + }); + } + frm.events.update_field_options(frm); + frm.ignore_warning = frm.is_new() ? true : false; + + if (frm.is_new()) { + return; + } + + frm.states = null; + frm.trigger('make_state_table'); + frm.trigger('get_orphaned_states_and_count').then(() => { + frm.trigger('render_state_table'); + }); + }, + validate: (frm) => { + if (frm.ignore_warning) { + return; + } + return frm.trigger('get_orphaned_states_and_count').then(() => { + if (frm.states && frm.states.length) { + frappe.validated = false; + frm.trigger('create_warning_dialog'); + } + }); }, document_type: function(frm) { frm.events.update_field_options(frm); @@ -19,6 +47,101 @@ frappe.ui.form.on("Workflow", { frappe.meta.get_docfield("Workflow Document State", "update_field", frm.doc.name).options = [""].concat(resp); }) } - } -}) + }, + create_warning_dialog: function(frm) { + const warning_html = + `+ ${__('Are you sure you want to save this document?')} +
+${__(`There are documents which have workflow states that do not exist in this Workflow. + It is recommended that you add these states to the Workflow and change their states + before removing these states.`)} +
`; + const message_html = warning_html + frm.state_table_html; + let proceed_action = () => { + frm.ignore_warning = true; + frm.save(); + }; + + frappe.warn(__(`Worflow States Don't Exist`), message_html, proceed_action, __(`Save Anyway`)); + }, + set_table_html: function(frm) { + + const promises = frm.states.map(r => { + const state = r[frm.doc.workflow_state_field]; + return frappe.utils.get_indicator_color(state).then(color => { + return `| ${__('State')} | +${__('Count')} | +
|---|
+ ${'Document States that do not exist in your Workflow'} +
+ ${frm.state_table_html} +