Skip to content

Commit adcf318

Browse files
Akanksha	 SinghAkanksha	 Singh
authored andcommitted
feat(core): filter action based on selected event
1 parent 8020519 commit adcf318

5 files changed

Lines changed: 133 additions & 20 deletions

File tree

projects/workflows-creator/src/lib/builder/builder.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
[isLast]="true"
2626
[isFirst]="true"
2727
[nodeType]="types.GROUP"
28+
[eventGroups]="eventGroups"
2829
[popupTemplate]="nodePopup"
2930
[templateMap]="templateMap"
3031
[allColumns]="allColumns"

projects/workflows-creator/src/lib/builder/builder.component.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ export class BuilderComponent<E> implements OnInit, OnChanges {
113113

114114
nodeList: AbstractBaseGroup<E>[] = [];
115115
processId: string;
116+
117+
// Current selected event identifier for action filtering
118+
get currentSelectedEvent(): string | undefined {
119+
// Look through event groups to find the first selected event
120+
for (const eventGroup of this.eventGroups) {
121+
if (eventGroup.children && eventGroup.children.length > 0) {
122+
const firstChild = eventGroup.children[0];
123+
if (
124+
firstChild &&
125+
firstChild.node &&
126+
firstChild.node.type === NodeTypes.EVENT
127+
) {
128+
return firstChild.node.getIdentifier();
129+
}
130+
}
131+
}
132+
return undefined;
133+
}
116134
// sonarignore:start
117135
// TODO: Refactor this code to be more flexible
118136
// sonarignore:start
@@ -225,6 +243,9 @@ export class BuilderComponent<E> implements OnInit, OnChanges {
225243
* @param event - ElementsWithInput<E>
226244
*/
227245
onEventAdded(event: ElementsWithInput<E>) {
246+
// Check if we need to clear existing actions when event changes
247+
this.clearIncompatibleActions(event.node.getIdentifier());
248+
228249
this.eventAdded.emit({
229250
name: event.node.getIdentifier(),
230251
event: event.newNode.node as WorkflowEvent<E>,
@@ -237,6 +258,44 @@ export class BuilderComponent<E> implements OnInit, OnChanges {
237258
event.node.getIdentifier() === EventTypes.OnAddItemEvent);
238259
}
239260

261+
/**
262+
* Clears actions that are not compatible with the selected event
263+
* @param selectedEvent - The identifier of the selected event
264+
*/
265+
private clearIncompatibleActions(selectedEvent: string) {
266+
if (this.actionGroups[0]?.children?.length > 0) {
267+
// Get list of actions that should remain (compatible with new event)
268+
const compatibleActions = this.nodes.getActions(selectedEvent);
269+
const compatibleActionIds = new Set(
270+
compatibleActions.map(action => action.getIdentifier()),
271+
);
272+
273+
// Filter out incompatible actions
274+
const currentActions = [...this.actionGroups[0].children];
275+
const actionsToRemove: number[] = [];
276+
277+
currentActions.forEach((action, index) => {
278+
const actionId = action.node.getIdentifier();
279+
if (!compatibleActionIds.has(actionId)) {
280+
actionsToRemove.push(index);
281+
}
282+
});
283+
284+
// Remove incompatible actions (reverse order to maintain indexes)
285+
actionsToRemove.reverse().forEach(index => {
286+
this.actionGroups[0].children.splice(index, 1);
287+
});
288+
289+
// Clear state for removed actions
290+
actionsToRemove.forEach(index => {
291+
const removedAction = currentActions[index];
292+
if (removedAction) {
293+
this.updateState(removedAction.node, removedAction.inputs, true);
294+
}
295+
});
296+
}
297+
}
298+
240299
/**
241300
* The function is called when an event is removed from the workflow.
242301
* Hides the else block when it is not needed.

projects/workflows-creator/src/lib/builder/group/group.component.ts

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,7 @@ export class GroupComponent<E> implements OnInit, AfterViewInit {
176176
ngOnInit(): void {
177177
this.events = this.nodes.getEvents();
178178
this.triggerEvents = this.nodes.getEvents(true);
179-
this.actions = this.nodes
180-
.getActions()
181-
.sort((a, b) =>
182-
a.name
183-
.toString()
184-
.localeCompare(b.name.toString(), undefined, {sensitivity: 'base'}),
185-
);
179+
this.actions = [];
186180

187181
this.typeSubjectPlaceholder = this.localizationSvc.getLocalizedString(
188182
LocalizedStringKeys.TypeSubject,
@@ -323,10 +317,50 @@ export class GroupComponent<E> implements OnInit, AfterViewInit {
323317
*/
324318
openPopup(type: NodeTypes) {
325319
if (type === NodeTypes.ACTION) {
326-
this.nodeList = this.actions;
320+
// Get the selected event identifier
321+
let selectedEvent: string | undefined;
322+
323+
// Method 1: Check eventGroups (passed from parent)
324+
if (this.eventGroups && this.eventGroups.length > 0) {
325+
for (const eventGroup of this.eventGroups) {
326+
if (eventGroup.children && eventGroup.children.length > 0) {
327+
// Find the first event node in the group
328+
const firstChild = eventGroup.children[0];
329+
330+
if (
331+
firstChild &&
332+
firstChild.node &&
333+
firstChild.node.type === NodeTypes.EVENT
334+
) {
335+
selectedEvent = firstChild.node.getIdentifier();
336+
337+
break;
338+
}
339+
}
340+
}
341+
}
342+
343+
// Method 2: Fallback - check current group's children for events
344+
if (
345+
!selectedEvent &&
346+
this.group.children &&
347+
this.group.children.length > 0
348+
) {
349+
for (const child of this.group.children) {
350+
if (child.node && child.node.type === NodeTypes.EVENT) {
351+
selectedEvent = child.node.getIdentifier();
352+
353+
break;
354+
}
355+
}
356+
}
357+
// Get filtered actions based on selected event
358+
this.nodeList = this.nodes.getActions(selectedEvent);
327359
} else if (type === NodeTypes.EVENT) {
328360
this.nodeList =
329-
this.eventGroups.length === 1 && !this.group.children.length
361+
this.eventGroups &&
362+
this.eventGroups.length === 1 &&
363+
!this.group.children.length
330364
? this.triggerEvents
331365
: this.events;
332366
} else {
@@ -362,6 +396,7 @@ export class GroupComponent<E> implements OnInit, AfterViewInit {
362396
if (newNode.node.getIdentifier() === 'OnIntervalEvent') {
363397
newNode.node.state.change('valueInputType', 'number');
364398
}
399+
this.actions = this.nodes.getActions(); // Get all actions initially
365400
this.group.children.push(newNode as EventWithInput<E>);
366401
this.eventAdded.emit({
367402
node: node,

projects/workflows-creator/src/lib/classes/services/abstract-node-service.class.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {WorkflowNode} from '../../types/base.types';
44
import {AbstractBaseGroup} from '../nodes';
55

66
export abstract class NodeService<E> {
7-
abstract getActions(): WorkflowNode<E>[];
7+
abstract getActions(selectedEvent?: string): WorkflowNode<E>[];
88
abstract getEvents(trigger?: boolean): WorkflowNode<E>[];
99
abstract getGroups(
1010
trigger?: boolean,

projects/workflows-creator/src/lib/services/bpmn/node.service.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,36 @@ export class BpmnNodesService<E> extends NodeService<E> {
3434
* > Get all the nodes that are of type `ACTION`
3535
*
3636
* The function is a bit more complicated than that, but that's the gist of it
37+
* @param selectedEvent - Optional event identifier to filter actions by eventBinded property
3738
* @returns An array of action nodes.
3839
*/
39-
getActions() {
40-
return this.nodes
41-
.map(
42-
Node =>
43-
new Node(
44-
this.localizationSvc.getLocalizedStringMap(),
45-
this.utils.uuid(),
46-
),
47-
)
48-
.filter(n => n.type === NodeTypes.ACTION);
40+
getActions(selectedEvent?: string) {
41+
const localizedStrings = this.localizationSvc.getLocalizedStringMap();
42+
43+
const actions = this.nodes
44+
.map(Node => new Node(localizedStrings, this.utils.uuid()))
45+
.filter(n => n.type === NodeTypes.ACTION)
46+
.sort((a, b) =>
47+
a.name.toString().localeCompare(b.name.toString(), undefined, {
48+
sensitivity: 'base',
49+
}),
50+
);
51+
52+
return actions.filter(action => {
53+
const a = action as WorkflowAction<E> & {eventBinded?: string[]};
54+
const events = a.eventBinded;
55+
56+
if (!Array.isArray(events)) {
57+
// unbound actions always allowed
58+
return true;
59+
}
60+
61+
if (!selectedEvent) {
62+
// no selectedEvent → return only unbound actions
63+
return false;
64+
}
65+
return events.includes(selectedEvent);
66+
});
4967
}
5068

5169
/**

0 commit comments

Comments
 (0)