From 85a5f05b80e4869ec929cf6b60d4da06ddcba09b Mon Sep 17 00:00:00 2001 From: theerayut Date: Wed, 23 Jul 2025 22:10:44 +0700 Subject: [PATCH] feat: Add action confirm on Workflow imp: move Action Confirmation into transitions level --- frappe/public/js/frappe/form/workflow.js | 50 ++++++++++++------- .../components/Properties.vue | 2 +- .../workflow/doctype/workflow/workflow.json | 2 +- .../workflow_transition.json | 10 +++- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/frappe/public/js/frappe/form/workflow.js b/frappe/public/js/frappe/form/workflow.js index e3532fddc8..3306ce2aac 100644 --- a/frappe/public/js/frappe/form/workflow.js +++ b/frappe/public/js/frappe/form/workflow.js @@ -102,25 +102,14 @@ frappe.ui.form.States = class FormStates { if (frappe.user_roles.includes(d.allowed) && has_approval_access(d)) { added = true; me.frm.page.add_action_item(__(d.action), function () { - // set the workflow_action for use in form scripts - frappe.dom.freeze(); - me.frm.selected_workflow_action = d.action; - me.frm.script_manager.trigger("before_workflow_action").then(() => { - frappe - .xcall("frappe.model.workflow.apply_workflow", { - doc: me.frm.doc, - action: d.action, - }) - .then((doc) => { - frappe.model.sync(doc); - me.frm.refresh(); - me.frm.selected_workflow_action = null; - me.frm.script_manager.trigger("after_workflow_action"); - }) - .finally(() => { - frappe.dom.unfreeze(); - }); - }); + if (d.enable_action_confirmation) { + frappe.confirm( + __("Are you sure you want to {0}?", [d.action]), + () => me.handle_workflow_action(d) + ); + } else { + me.handle_workflow_action(d); + } }); } }); @@ -129,6 +118,29 @@ frappe.ui.form.States = class FormStates { }); } + handle_workflow_action(transition) { + var me = this; + // set the workflow_action for use in form scripts + frappe.dom.freeze(); + me.frm.selected_workflow_action = transition.action; + me.frm.script_manager.trigger("before_workflow_action").then(() => { + frappe + .xcall("frappe.model.workflow.apply_workflow", { + doc: me.frm.doc, + action: transition.action, + }) + .then((doc) => { + frappe.model.sync(doc); + me.frm.refresh(); + me.frm.selected_workflow_action = null; + me.frm.script_manager.trigger("after_workflow_action"); + }) + .finally(() => { + frappe.dom.unfreeze(); + }); + }); + } + setup_btn(action_added) { if (action_added) { this.frm.page.btn_primary.addClass("hide"); diff --git a/frappe/public/js/workflow_builder/components/Properties.vue b/frappe/public/js/workflow_builder/components/Properties.vue index 7c505dee56..8f14d18ba5 100644 --- a/frappe/public/js/workflow_builder/components/Properties.vue +++ b/frappe/public/js/workflow_builder/components/Properties.vue @@ -18,7 +18,7 @@ let properties = computed(() => { if (store.workflow.selected && "action" in store.workflow.selected.data) { title.value = __("Transition Properties"); return store.transitionfields.filter((df) => - ["action", "allowed", "allow_self_approval", "condition"].includes(df.fieldname) + ["action", "allowed", "allow_self_approval", "action_confirm", "condition"].includes(df.fieldname) ); } else if (store.workflow.selected && "state" in store.workflow.selected.data) { title.value = __("State Properties"); diff --git a/frappe/workflow/doctype/workflow/workflow.json b/frappe/workflow/doctype/workflow/workflow.json index 58761f1fe5..27394315c4 100644 --- a/frappe/workflow/doctype/workflow/workflow.json +++ b/frappe/workflow/doctype/workflow/workflow.json @@ -126,4 +126,4 @@ "sort_order": "DESC", "states": [], "track_changes": 1 -} \ No newline at end of file +} diff --git a/frappe/workflow/doctype/workflow_transition/workflow_transition.json b/frappe/workflow/doctype/workflow_transition/workflow_transition.json index 74139320f4..d78732d5e2 100644 --- a/frappe/workflow/doctype/workflow_transition/workflow_transition.json +++ b/frappe/workflow/doctype/workflow_transition/workflow_transition.json @@ -12,6 +12,7 @@ "allowed", "allow_self_approval", "send_email_to_creator", + "enable_action_confirmation", "conditions", "condition", "column_break_7", @@ -99,7 +100,14 @@ "fieldname": "send_email_to_creator", "fieldtype": "Check", "label": "Send Email To Creator" - } + }, + { + "default": "0", + "description": "If checked, action confirmation will be required before performing workflow actions", + "fieldname": "enable_action_confirmation", + "fieldtype": "Check", + "label": "Enable Action Confirmation" + } ], "idx": 1, "istable": 1,