diff --git a/frappe/public/js/workflow_builder/WorkflowBuilder.vue b/frappe/public/js/workflow_builder/WorkflowBuilder.vue
index 37130dbb6b..a3d47d9794 100644
--- a/frappe/public/js/workflow_builder/WorkflowBuilder.vue
+++ b/frappe/public/js/workflow_builder/WorkflowBuilder.vue
@@ -3,10 +3,12 @@ import { VueFlow, useVueFlow, Panel, PanelPosition } from "@vue-flow/core";
import { Background } from "@vue-flow/background";
import TransitionEdge from "./components/TransitionEdge.vue";
import StateNode from "./components/StateNode.vue";
+import ActionNode from "./components/ActionNode.vue";
+import ConnectionLine from "./components/ConnectionLine.vue";
import { useStore } from "./store";
let store = useStore();
-let { nodes, onConnect, addNodes, addEdges } = useVueFlow();
+let { nodes, findNode, onConnect, addNodes, addEdges } = useVueFlow();
function add_state() {
let state_id = (nodes.value.length + 1).toString();
@@ -20,10 +22,50 @@ function add_state() {
]);
}
-onConnect(params => {
- params.animated = true;
- params.type = "transition";
- addEdges([params]);
+onConnect(edge => {
+ let source_node = findNode(edge.source);
+ let target_node = findNode(edge.target);
+
+ let source_center = {
+ x: source_node.position.x + source_node.dimensions.width / 2,
+ y: source_node.position.y + source_node.dimensions.height / 2
+ };
+
+ let target_center = {
+ x: target_node.position.x + target_node.dimensions.width / 2,
+ y: target_node.position.y + target_node.dimensions.height / 2
+ };
+
+ let center_x = (source_center.x + target_center.x) / 2;
+ let center_y = source_center.y - 16;
+
+ const action_node = {
+ id: "action-" + frappe.utils.get_random(5),
+ type: "action",
+ label: "Approve",
+ position: { x: center_x, y: center_y }
+ };
+ addNodes([action_node]);
+
+ let action_edge = {
+ source: edge.source,
+ sourceHandle: edge.sourceHandle,
+ target: action_node.id,
+ targetHandle: "left",
+ type: "transition",
+ updatable: true,
+ animated: true
+ };
+ let state_edge = {
+ source: action_node.id,
+ sourceHandle: "right",
+ target: edge.target,
+ targetHandle: edge.targetHandle,
+ type: "transition",
+ updatable: true,
+ animated: true
+ };
+ addEdges([action_edge, state_edge]);
});
@@ -37,9 +79,15 @@ onConnect(params => {
+
+
+
+
+
+
diff --git a/frappe/public/js/workflow_builder/components/ActionNode.vue b/frappe/public/js/workflow_builder/components/ActionNode.vue
new file mode 100644
index 0000000000..becdfa817e
--- /dev/null
+++ b/frappe/public/js/workflow_builder/components/ActionNode.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
{{ node.label }}
+
{{ __("No Label") }}
+
+
+
+
+
diff --git a/frappe/public/js/workflow_builder/components/ConnectionLine.vue b/frappe/public/js/workflow_builder/components/ConnectionLine.vue
new file mode 100644
index 0000000000..f14e81f646
--- /dev/null
+++ b/frappe/public/js/workflow_builder/components/ConnectionLine.vue
@@ -0,0 +1,34 @@
+
+
+
+
diff --git a/frappe/public/js/workflow_builder/components/StateNode.vue b/frappe/public/js/workflow_builder/components/StateNode.vue
index 0d211eca82..8746ed23a6 100644
--- a/frappe/public/js/workflow_builder/components/StateNode.vue
+++ b/frappe/public/js/workflow_builder/components/StateNode.vue
@@ -1,5 +1,5 @@