From 85a5f05b80e4869ec929cf6b60d4da06ddcba09b Mon Sep 17 00:00:00 2001 From: theerayut Date: Wed, 23 Jul 2025 22:10:44 +0700 Subject: [PATCH 1/5] 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, From bf4472865ef54555d023bf5bb040f81661c2e473 Mon Sep 17 00:00:00 2001 From: theerayut Date: Thu, 31 Jul 2025 13:55:36 +0700 Subject: [PATCH 2/5] refactor: change field's description --- .../doctype/workflow_transition/workflow_transition.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/workflow/doctype/workflow_transition/workflow_transition.json b/frappe/workflow/doctype/workflow_transition/workflow_transition.json index b90a0332ff..3e2edba5ad 100644 --- a/frappe/workflow/doctype/workflow_transition/workflow_transition.json +++ b/frappe/workflow/doctype/workflow_transition/workflow_transition.json @@ -104,7 +104,7 @@ }, { "default": "0", - "description": "If checked, action confirmation will be required before performing workflow actions", + "description": "If checked, a confirmation will be required before performing workflow actions.", "fieldname": "enable_action_confirmation", "fieldtype": "Check", "label": "Enable Action Confirmation" From 2b1d5c61e2f3ca4ec2e09f5898952557e4af5510 Mon Sep 17 00:00:00 2001 From: theerayut Date: Thu, 31 Jul 2025 14:00:07 +0700 Subject: [PATCH 3/5] style: run pre-commit --- frappe/public/js/frappe/form/workflow.js | 5 ++--- .../public/js/workflow_builder/components/Properties.vue | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/form/workflow.js b/frappe/public/js/frappe/form/workflow.js index 3306ce2aac..26b8fedc7d 100644 --- a/frappe/public/js/frappe/form/workflow.js +++ b/frappe/public/js/frappe/form/workflow.js @@ -103,9 +103,8 @@ frappe.ui.form.States = class FormStates { added = true; me.frm.page.add_action_item(__(d.action), function () { if (d.enable_action_confirmation) { - frappe.confirm( - __("Are you sure you want to {0}?", [d.action]), - () => me.handle_workflow_action(d) + frappe.confirm(__("Are you sure you want to {0}?", [d.action]), () => + me.handle_workflow_action(d) ); } else { me.handle_workflow_action(d); diff --git a/frappe/public/js/workflow_builder/components/Properties.vue b/frappe/public/js/workflow_builder/components/Properties.vue index d63badbf3e..79402deacb 100644 --- a/frappe/public/js/workflow_builder/components/Properties.vue +++ b/frappe/public/js/workflow_builder/components/Properties.vue @@ -18,7 +18,14 @@ 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", "enable_action_confirmation", "condition", "transition_tasks"].includes(df.fieldname) + [ + "action", + "allowed", + "allow_self_approval", + "enable_action_confirmation", + "condition", + "transition_tasks", + ].includes(df.fieldname) ); } else if (store.workflow.selected && "state" in store.workflow.selected.data) { title.value = __("State Properties"); From ac3ae547e85858fe09bf250a2c0d2d37c82790df Mon Sep 17 00:00:00 2001 From: theerayut Date: Tue, 2 Sep 2025 09:28:58 +0700 Subject: [PATCH 4/5] feat: add enable_action_confirmation on workflow doctype --- frappe/public/js/frappe/form/workflow.js | 2 +- frappe/workflow/doctype/workflow/workflow.json | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/workflow.js b/frappe/public/js/frappe/form/workflow.js index 26b8fedc7d..0d2d83886c 100644 --- a/frappe/public/js/frappe/form/workflow.js +++ b/frappe/public/js/frappe/form/workflow.js @@ -102,7 +102,7 @@ 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 () { - if (d.enable_action_confirmation) { + if (d.enable_action_confirmation || me.frm.enable_action_confirmation) { frappe.confirm(__("Are you sure you want to {0}?", [d.action]), () => me.handle_workflow_action(d) ); diff --git a/frappe/workflow/doctype/workflow/workflow.json b/frappe/workflow/doctype/workflow/workflow.json index 27394315c4..238cd2d364 100644 --- a/frappe/workflow/doctype/workflow/workflow.json +++ b/frappe/workflow/doctype/workflow/workflow.json @@ -13,6 +13,7 @@ "is_active", "override_status", "send_email_alert", + "enable_action_confirmation", "states_head", "states", "transition_rules", @@ -60,6 +61,13 @@ "fieldtype": "Check", "label": "Send Email Alert" }, + { + "default": "0", + "description": "If checked, a confirmation will be required before performing workflow actions.", + "fieldname": "enable_action_confirmation", + "fieldtype": "Check", + "label": "Enable Action Confirmation" + }, { "description": "Different \"States\" this document can exist in. Like \"Open\", \"Pending Approval\" etc.", "fieldname": "states_head", From 18a83f426ba65a5d3561d71d9c346b0bf7df93f9 Mon Sep 17 00:00:00 2001 From: theerayut Date: Fri, 5 Sep 2025 07:42:24 +0700 Subject: [PATCH 5/5] fix: remove enable_action_confirmation on workflow transition --- frappe/public/js/frappe/form/workflow.js | 23 +++++++++++++------ .../components/Properties.vue | 11 +++------ .../workflow_transition.json | 16 ++++--------- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/frappe/public/js/frappe/form/workflow.js b/frappe/public/js/frappe/form/workflow.js index 0d2d83886c..72e50feb0a 100644 --- a/frappe/public/js/frappe/form/workflow.js +++ b/frappe/public/js/frappe/form/workflow.js @@ -102,13 +102,22 @@ 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 () { - if (d.enable_action_confirmation || me.frm.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); - } + frappe.db + .get_value( + "Workflow", + { document_type: me.frm.doctype }, + "enable_action_confirmation" + ) + .then((r) => { + if (r.message.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); + } + }); }); } }); diff --git a/frappe/public/js/workflow_builder/components/Properties.vue b/frappe/public/js/workflow_builder/components/Properties.vue index 79402deacb..12b3f4371e 100644 --- a/frappe/public/js/workflow_builder/components/Properties.vue +++ b/frappe/public/js/workflow_builder/components/Properties.vue @@ -18,14 +18,9 @@ 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", - "enable_action_confirmation", - "condition", - "transition_tasks", - ].includes(df.fieldname) + ["action", "allowed", "allow_self_approval", "condition", "transition_tasks"].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_transition/workflow_transition.json b/frappe/workflow/doctype/workflow_transition/workflow_transition.json index 3e2edba5ad..c169596c95 100644 --- a/frappe/workflow/doctype/workflow_transition/workflow_transition.json +++ b/frappe/workflow/doctype/workflow_transition/workflow_transition.json @@ -12,7 +12,6 @@ "allowed", "allow_self_approval", "send_email_to_creator", - "enable_action_confirmation", "transition_tasks", "conditions", "condition", @@ -103,17 +102,10 @@ "label": "Send Email To Creator" }, { - "default": "0", - "description": "If checked, a confirmation will be required before performing workflow actions.", - "fieldname": "enable_action_confirmation", - "fieldtype": "Check", - "label": "Enable Action Confirmation" - }, - { - "fieldname": "transition_tasks", - "fieldtype": "Link", - "label": "Transition Tasks", - "options": "Workflow Transition Tasks" + "fieldname": "transition_tasks", + "fieldtype": "Link", + "label": "Transition Tasks", + "options": "Workflow Transition Tasks" } ], "idx": 1,