nocode-js/sequential-workflow-designer

Nested If block restriction

Closed this issue · 20 comments

Is there a way to restrict nested if blocks in the designer in angular?

Or atleast any way to know which step is being currently dropped? So i can undo that step if it is a nested if?

b4rtaz commented

Hi @raBot19! Check this article: https://nocode-js.com/docs/sequential-workflow-designer/features/editing-restrictions

To use this feature with Angular you need to create a property in your component:

public readonly stepsConfiguration: StepsConfiguration = {
   canInsertStep: (step, targetSequence, targetIndex) => { /* ... */ },
   canMoveStep: (sourceSequence, step, targetSequence, targetIndex) => { /* ... */ },
   // ...
}

And pass it to the sqd-designer:

<sqd-designer
  ...
  [stepsConfiguration]="stepsConfiguration"></sqd-designer>

That's neat ! Thank you, will check this out.

Is there any release restriction to this feature?

b4rtaz commented

Is there any release restriction to this feature?

What you mean?

What version of the designer should I be on for this to work ?

b4rtaz commented

I don't remember exactly which versions introduced this, but I recommend to use the latest one.

Is there also a way for me to get the parent step of a dropped step?
this.designer.getStepParents(step) returns an error :(

Nevermind, worked it out with the targetIndex :)

@b4rtaz saw this. I think what's happening here is I'm trying to call this on dragging the step ( canInsertStep method), since the designer change hasn't already happened, getting the parent by the dragged step is returning an error. ( I'm guessing because that step doesn't exist in the definition yet).

My motive here is to stop the user from dropping a step if it's in a nested conditional block.

I tried the getStepParents method by passing the targetSequence of the canInsertStep method. I'm then checking if the dragged step is of type if. And also checking the returned parent for branches. (Length>=2)

I would prevent dropping the step if these two conditions satisfy.

Is there a better way i can do this or something I'm missing here?

b4rtaz commented

I'm guessing because that step doesn't exist in the definition yet

That's correct. The dragging step doesn't have parents. In case with the canInsertStep method: the getStepParents method searches the current definition and the dragging step is not added to it yet.

I'm then checking if the dragged step is of type if. And also checking the returned parent for branches. (Length>=2)

You should check only parents of the targetSequence. If parents contain any specific step type, then you have the answer.

canInsertStep: (step, targetSequence, targetIndex) => {
  const parents = designer.getStepParents(targetSequence);
  const isInLoop = parents.some(s => typeof s === 'object' && s.type === 'loop');
  // ...

Got it.
This really helps. Will try to put this in and get back if I face any hurdles.

image

this.designer.getStepParents(editor.step) for RunAnyPostgresQuery

doesnt give me the task above the if condition :(

b4rtaz commented

Yes, this is correct behavior. Because the "Check_Connectivity_of_Server" step is not a parent of the "RunAnyPostgresQuery" step.

Is there a method to get the sequence trail for the RunAnyPostgresQuery step?

As in the steps :
SecurityRemedyTask
Check_Connectivity_of_Server

b4rtaz commented
const step = /* ... * /;
const parents = designer.getStepParents(step);
const definition = designer.getDefinition();
let predecessors = [];
let parentSequence = definition.sequence;
for (let i = 0; ; i++) {
   const parent = parents[i];
   const offset = parentSequence.indexOf(parent);
   if (offset < 0) {
      throw new Error('Parent not found');
   }
   predecessors = [
      ...predecessors,
      ...parentSequence.slice(0, offset + 1)
   ];
   if (i === parents.length - 1) {
      break;
   }
   if (parent.branches) {
      const branchName = parents[i + 1];
      predecessors.push(branchName);
      parentSequence = parent.branches[branchName];
      i++;
      continue;
   }
   if (parent.sequence) {
      parentSequence = parent.sequence;
      continue;
   }
   throw new Error('Unexpected parent type');
}

console.log(predecessors.map((stepOrName) => typeof stepOrName === 'string' ? stepOrName : stepOrName.name));

BTW: please don't change the topic of the issue. If you want to ask another question, please open another issue.

Thanks a ton @b4rtaz !! This serves the purpose. Thanks again :)

Sorry about the diversion. Will follow through next time.

Also wanted to say great work on the designer! We're looking to automate a few processes with it as a front end and it works great :)

b4rtaz commented

Thanks!

Is this issue solved?

Yes the snippet you provided serves the purpose but I have to write some more customisations to it to cater to how we are using the designer. I'm guessing it should work through :)

Will close the issue and raise another one if there is an issue with traversal! Thanks :)