From d619db18ab004e0d10eddcd807c986a68c23edd7 Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Mon, 5 Oct 2026 13:26:23 +0800 Subject: [PATCH] Activity flow: tolerate cyclic flows; Lifecycle tab: inline save button A configured lifecycle can loop back (active -> extended -> active) and an activity can have several parents. addChildActivities walked the flow as a tree and recursed forever on a cycle until JointJS overflowed the stack when opening the Activity Flow tab. An activity already on the graph now only gets a link from the additional parent. The Lifecycle tab's save button sits under the form instead of in a separate collapsible Controls panel. --- .../order-config-manager/activity-flow.js | 9 ++++++ .../order-config-manager/lifecycle.hbs | 29 +++++++++---------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/addon/components/order-config-manager/activity-flow.js b/addon/components/order-config-manager/activity-flow.js index 814a0fb79..3ed847ca8 100644 --- a/addon/components/order-config-manager/activity-flow.js +++ b/addon/components/order-config-manager/activity-flow.js @@ -455,6 +455,10 @@ export default class OrderConfigManagerActivityFlowComponent extends Component { * and creates links from the parent to each child. It then calls itself to add any children of the current child activities. * Finally, it repositions all child activities to maintain visual consistency. * + * A flow is a graph, not a tree: an activity may be reachable from several parents, and a + * configured lifecycle can loop back (e.g. active -> extended -> active). An activity that is + * already on the graph only gets a link from this parent; it is never placed or walked twice. + * * @param {Object} parentActivity - The parent activity to which child activities will be added. * @param {Array} [childActivities=[]] - An array of child activity objects to be added. Defaults to an empty array. */ @@ -463,6 +467,11 @@ export default class OrderConfigManagerActivityFlowComponent extends Component { return; } childActivities.forEach((childActivityObject) => { + if (childActivityObject.get('node')) { + this.addLinkToGraph(parentActivity, childActivityObject); + return; + } + const childPositionals = this.getActivityPositioning(childActivityObject, parentActivity); const childActivity = this.createActivityNode(childActivityObject, childPositionals); childActivity.set('parentId', parentActivity.get('id')); diff --git a/addon/components/order-config-manager/lifecycle.hbs b/addon/components/order-config-manager/lifecycle.hbs index 13ecd9175..c5998f089 100644 --- a/addon/components/order-config-manager/lifecycle.hbs +++ b/addon/components/order-config-manager/lifecycle.hbs @@ -122,6 +122,20 @@ {{else}}

{{t "order-config-manager.lifecycle.default-lifecycle"}}

{{/if}} + + {{#if this.canEdit}} +
+
+ {{/if}} {{#if this.saved}} @@ -157,19 +171,4 @@ {{/if}} - {{#if this.canEdit}} - -
-
-
- {{/if}} \ No newline at end of file