How to config only one flow between two elements?

Hi everyone,

I want to config only one flow between two elements. I was tried setup Rule provider with below code, it worked, but when I reconnect connection it has no effect.
Hope anyone help, thank you so much!

   (this as RuleProvider).addRule('connection.create', 2500, function (context: BPMNContext) {
        const { source, target } = context;
        const outgoing = source.outgoing ?? [];
        if (outgoing.some((c) => c.target === target)) {
            return false;
        }
    });

image

1 Like

I just tried your code and it seems to work as expected. When I add the second connection, it’s being reversed. Third connection is not allowed.

image

when I reconnect connection it has no effect

What do you mean by that?

1 Like

When i reconnect from another, it still allows(image bellow), I just want to disable it.

Here is my code sanbox https://codesandbox.io/p/devbox/nervous-wilson-fp9svr

Thanks for your quick reply!
image

What exactly is the behavior you want? Only one connection between two elements? Or only one incoming and one outgoing connection for each element?

I just want maximum 1 connections between 2 elements(same direction). My code worked when I create new connection, but when I change target from another element it does not work.
image

For reconnecting existing connections there is a different rule: bpmn-js/lib/features/rules/BpmnRules.js at develop · bpmn-io/bpmn-js · GitHub You’ll have to override this rule as well.

I tried override ‘connection.reconnect’ rule, but it failed with bpmn:EndEvent element. Could you view my code in sandbox, please. https://codesandbox.io/p/devbox/nervous-wilson-fp9svr
image

The reason your reconnection logic doesn’t work is that you condition is true when the reconnection is initiated, not giving it a chance to change targets.

You should not run your check when the “new” target is the current target of the connection.

this.addRule("connection.reconnect", 2500, function (context) {
  const { source, target, connection } = context;

  if (connection.target.id === target.id) {
    return;
  }

  if (source.outgoing.some((c) => c.target === target)) {
    return false;
  }
});
1 Like

Please explain again in clear terms what exactly you want to allow and what not.

1 Like

So sorry with my explain, that is not clear.
Whatever, your solution save my week.
Thank you so much @jarekdanielak!

Yes, this is my mistake about images description. Sorry team!

Excuse me sir, could you help me one more question?
When I drag source of connection, i meet a problem, I describe it in image bellow.
Thanks sir!
image

Please describe what is what you are doing step by step, what is happening and what you want to happen.

Do not use screenshots as the only description for your problem or to share code. Share a snippet or CodeSandbox link instead.

When I tried the code you provided, it worked when I moved the arrowhead of the connection. However, when I moved the source of the connection, it did not satisfy the condition connection.target.id === target.id, so I was still able to connect(which is incorrect).

Here is my CodeSandbox: https://codesandbox.io/p/devbox/nervous-wilson-fp9svr

Thank you so much! You are very helpful.

Are you sure about that? Your comment in the CodeSandbox says otherwise (which is correct):

if (connection?.target?.id === target.id) {
  // Drag source of connection allways match condition
  // So, I can't prevent dropping
  return;
}

How would you change this condition to only be satisfied when both the connection target and source hasn’t changed?

Sorry about my English,
I just mean the code worked when I moved the arrowhead of the connection. However, when I moved the source of the connection, it did not.
https://codesandbox.io/p/devbox/nervous-wilson-fp9svr

  this.addRule("connection.reconnect", 2500, function (context) {
    const { source, target, connection } = context;

    if (connection?.target?.id === target.id) {
      return;
    }

    if (source.outgoing.some((c) => c.target === target)) {
      return false;
    }
  });

I’d suggest you come back to my last reply and try to adjust the conditional statement to also check the connection target. I’m sure you can figure this out and learn something in the process. :slight_smile:

1 Like

Finally, I found the solution, I need to check one more condition. I send my code here to help someone facing same issue. Thanks support team so much!


  this.addRule("connection.reconnect", 2500, function (context) {
    const { source, target, connection } = context;

    if (
      connection?.target?.id === target.id &&
      connection?.source?.id === source.id
    ) {
      return;
    }

    if (source.outgoing.some((c) => c.target === target)) {
      return false;
    }
  });

https://codesandbox.io/p/devbox/nervous-wilson-fp9svr

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.