seitime-frappe/frappe/public/js/workflow_builder/utils.js
Sambasiva Suda 53c795f4b8
fix: Workflow Builder not updating diagram with added states/transitions in table (#22429)
Co-authored-by: Shariq Ansari <sharique.rik@gmail.com>
2023-10-03 17:13:51 +05:30

189 lines
4.3 KiB
JavaScript

export function get_workflow_elements(workflow, workflow_data) {
let elements = [];
let states = {};
let actions = {};
let transitions = {};
let x = 150;
let y = 100;
workflow_data.forEach((node) => {
if (node.type == "state") {
states[node.id] = node;
} else if (node.type == "action") {
actions[node.id] = node;
} else if (node.type == "transition") {
transitions[`edge-${node.source}-${node.target}`] = node;
if (node.source.startsWith("action-")) {
const action = actions[node.source];
if (!action.data.to_id) {
action.data.to_id = node.target;
}
node.sourceNode = action;
node.targetNode = states[node.target];
} else {
const action = actions[node.target];
if (!action.data.from_id) {
action.data.from_id = node.source;
}
node.targetNode = action;
node.sourceNode = states[node.source];
}
}
});
function state_obj(id, data) {
let state = states[id];
if (state) {
state.data = data;
} else {
state = {
id: id.toString(),
type: "state",
position: { x, y },
data,
};
}
Object.assign(state, {
initialized: true,
selected: false,
dragging: false,
resizing: false,
});
return (states[id] = state);
}
function action_obj(id, data, position) {
let action = actions[id];
if (action) {
data.from_id = action.data.from_id;
(data.to_id = action.data.to_id), (action.data = data);
} else {
action = {
id,
type: "action",
position,
data,
};
}
Object.assign(action, {
initialized: true,
selected: false,
dragging: false,
resizing: false,
});
return (actions[id] = action);
}
function transition_obj(id, source, target) {
let transition = transitions[id];
if (!transition) {
transition = {
id,
type: "transition",
source: source.toString(),
target: target.toString(),
sourceHandle: "right",
targetHandle: "left",
updatable: true,
animated: true,
};
}
Object.assign(transition, {
initialized: true,
selected: false,
dragging: false,
resizing: false,
});
return (transitions[id] = transition);
}
let state_id = Math.max(...workflow.states.map((state) => state.workflow_builder_id || 0));
workflow.states.forEach((state, i) => {
x += 400;
let doc_status_map = {
0: "Draft",
1: "Submitted",
2: "Cancelled",
};
const id = state.workflow_builder_id || ++state_id;
elements.push(
state_obj(id, {
...state,
doc_status: doc_status_map[state.doc_status],
})
);
});
let action_id = Math.max(
...workflow.transitions.map(
(transition) => transition.workflow_builder_id?.replace("action-", "") || 0
)
);
workflow.transitions.forEach((transition, i) => {
const id = transition.workflow_builder_id || "action-" + ++action_id;
let action = actions[id];
let source, target;
if (action && action.data.from_id && action.data.to_id) {
source = states[action.data.from_id];
target = states[action.data.to_id];
} else {
source = Object.values(states).filter(
(state) => state.data?.state == transition.state
)[0];
target = Object.values(states).filter(
(state) => state.data?.state == transition.next_state
)[0];
}
let position = { x: source.position.x + 250, y: y + 20 };
let data = {
...transition,
from_id: source.id,
to_id: target.id,
from: transition.state,
to: transition.next_state,
};
elements.push(action_obj(id, data, position));
elements.push(transition_obj("edge-" + source.id + "-" + id, source.id, id));
elements.push(transition_obj("edge-" + id + "-" + target.id, id, target.id));
});
return elements;
}
export function validate_transitions(state, next_state) {
let message;
if (state.doc_status == "Cancelled") {
message = __("Cannot change state of Cancelled Document <b>({0} State)</b>", [
state.state,
]);
}
if (state.doc_status == "Submitted" && next_state.doc_status == "Draft") {
message = __(
"Submitted document cannot be converted back to draft while transitioning from <b>{0} State</b> to <b>{1} State</b>",
[state.state, next_state.state]
);
}
if (state.doc_status == "Draft" && next_state.doc_status == "Cancelled") {
message = __(
"Cannot cancel before submitting while transitioning from <b>{0} State</b> to <b>{1} State</b>",
[state.state, next_state.state]
);
}
return message;
}