AAE-35842 Admin - filter out form specific processes (in Process Instances tab) (#11131)

* AAE-35842 Update ProcessFilterCloudModel

* AAE-35842 Initial implementation
This commit is contained in:
Wiktor Danielewski
2025-09-02 09:10:08 +02:00
committed by GitHub
parent 609144551c
commit 81fed833f5
7 changed files with 150 additions and 98 deletions

View File

@@ -64,4 +64,14 @@ describe('ProcessFilterCloudModel', () => {
expect(model.startFrom).toEqual(startOfDay(date).toISOString()); expect(model.startFrom).toEqual(startOfDay(date).toISOString());
expect(model.startTo).toEqual(endOfDay(date).toISOString()); expect(model.startTo).toEqual(endOfDay(date).toISOString());
}); });
it('should assign value to the excludeByProcessCategoryName if provided', () => {
const model = new ProcessFilterCloudModel({ excludeByProcessCategoryName: 'test' });
expect(model.excludeByProcessCategoryName).toBe('test');
});
it('should assign null to the excludeByProcessCategoryName if value not provided', () => {
const model = new ProcessFilterCloudModel({});
expect(model.excludeByProcessCategoryName).toBeNull();
});
}); });

View File

@@ -24,31 +24,31 @@ import { ProcessVariableFilterModel } from '../../../models/process-variable-fil
export class ProcessFilterCloudModel { export class ProcessFilterCloudModel {
id: string; id: string;
name: string; name: string | null;
key: string; key: string | null;
icon: string; icon: string | null;
index: number; index: number | null;
appName: string; appName: string | null;
appVersion?: number | number[]; appVersion?: number | number[];
parentId?: string; parentId: string;
processName: string; processName: string | null;
processInstanceId: string; processInstanceId: string | null;
initiator: string; initiator: string | null;
status: string; status: string | null;
sort: string; sort: string | null;
order: string; order: string | null;
processDefinitionId: string; processDefinitionId: string | null;
processDefinitionName?: string; processDefinitionName: string | null;
processDefinitionKey: string; processDefinitionKey: string | null;
lastModified: Date; lastModified: Date | null;
lastModifiedTo: Date; lastModifiedTo: Date | null;
lastModifiedFrom: Date; lastModifiedFrom: Date | null;
startedDate: Date; startedDate: Date | null;
completedDateType: DateCloudFilterType; completedDateType: DateCloudFilterType | null;
startedDateType: DateCloudFilterType; startedDateType: DateCloudFilterType | null;
suspendedDateType: DateCloudFilterType; suspendedDateType: DateCloudFilterType | null;
completedDate: Date; completedDate: Date | null;
environmentId?: string; environmentId: string | null;
showCounter: boolean; showCounter: boolean;
processDefinitionNames: string[] | null; processDefinitionNames: string[] | null;
@@ -58,23 +58,27 @@ export class ProcessFilterCloudModel {
initiators: string[] | null; initiators: string[] | null;
appVersions: string[] | null; appVersions: string[] | null;
statuses: string[] | null; statuses: string[] | null;
excludeByProcessCategoryName: string | null;
processVariableFilters?: ProcessVariableFilterModel[]; processVariableFilters?: ProcessVariableFilterModel[];
private dateRangeFilterService = new DateRangeFilterService(); private dateRangeFilterService = new DateRangeFilterService();
private _completedFrom: string; private _completedFrom: string | null;
private _completedTo: string; private _completedTo: string | null;
private _startFrom: string; private _startFrom: string | null;
private _startTo: string; private _startTo: string | null;
private _suspendedFrom: string; private _suspendedFrom: string | null;
private _suspendedTo: string; private _suspendedTo: string | null;
constructor(obj?: any) { constructor(obj?: any) {
if (obj) { if (!obj) {
return;
}
this.id = obj.id || Math.random().toString(36).substring(2, 9); this.id = obj.id || Math.random().toString(36).substring(2, 9);
this.name = obj.name || null; this.name = obj.name || null;
this.key = obj.key || null; this.key = obj.key || null;
this.environmentId = obj.environmentId; this.environmentId = obj.environmentId || null;
this.showCounter = obj.showCounter || false; this.showCounter = obj.showCounter || false;
this.icon = obj.icon || null; this.icon = obj.icon || null;
this.index = obj.index || null; this.index = obj.index || null;
@@ -107,12 +111,12 @@ export class ProcessFilterCloudModel {
this.completedFrom = obj._completedFrom || null; this.completedFrom = obj._completedFrom || null;
this.completedTo = obj._completedTo || null; this.completedTo = obj._completedTo || null;
this.completedDate = obj.completedDate || null; this.completedDate = obj.completedDate || null;
this.excludeByProcessCategoryName = obj.excludeByProcessCategoryName || null;
this._suspendedFrom = obj._suspendedFrom || null; this._suspendedFrom = obj._suspendedFrom || null;
this._suspendedTo = obj._suspendedTo || null; this._suspendedTo = obj._suspendedTo || null;
this.initArrayProperties(obj); this.initArrayProperties(obj);
} }
}
private initArrayProperties(obj) { private initArrayProperties(obj) {
if (obj.processDefinitionNames) { if (obj.processDefinitionNames) {

View File

@@ -374,7 +374,7 @@ describe('ProcessListCloudComponent', () => {
expect(component.requestNode.appVersion).toEqual('1,2,3'); expect(component.requestNode.appVersion).toEqual('1,2,3');
}); });
it('should the payload NOT contain any app version when appVersion does not have a value', () => { it('should the payload NOT contain any app version when appVersion does NOT have a value', () => {
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList)); spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
component.appVersion = undefined; component.appVersion = undefined;
component.ngAfterContentInit(); component.ngAfterContentInit();
@@ -476,7 +476,7 @@ describe('ProcessListCloudComponent', () => {
expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown'); expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown');
}); });
it('should NOT request process variable if columns for process variables are not displayed', () => { it('should NOT request process variable if columns for process variables are NOT displayed', () => {
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList)); spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
spyOn(preferencesService, 'getPreferences').and.returnValue( spyOn(preferencesService, 'getPreferences').and.returnValue(
of({ of({
@@ -668,7 +668,7 @@ describe('ProcessListCloudComponent', () => {
expect(component.processListRequestNode.appVersion).toEqual(['1', '2', '3']); expect(component.processListRequestNode.appVersion).toEqual(['1', '2', '3']);
}); });
it('should the payload NOT contain any app version when appVersion does not have a value', () => { it('should the payload NOT contain any app version when appVersion does NOT have a value', () => {
spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList)); spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList));
component.appVersion = undefined; component.appVersion = undefined;
component.ngAfterContentInit(); component.ngAfterContentInit();
@@ -752,7 +752,7 @@ describe('ProcessListCloudComponent', () => {
expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown'); expect(displayedColumns.length).toBe(2, 'only column with isHidden set to false and action column should be shown');
}); });
it('should NOT request process variable if columns for process variables are not displayed', () => { it('should NOT request process variable if columns for process variables are NOT displayed', () => {
spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList)); spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList));
spyOn(preferencesService, 'getPreferences').and.returnValue( spyOn(preferencesService, 'getPreferences').and.returnValue(
of({ of({
@@ -846,6 +846,28 @@ describe('ProcessListCloudComponent', () => {
expect(fetchProcessListSpy).toHaveBeenCalled(); expect(fetchProcessListSpy).toHaveBeenCalled();
}); });
it('should reload process list when excludeByProcessCategoryName changes', () => {
const fetchProcessListSpy = spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList));
fixture.componentRef.setInput('excludeByProcessCategoryName', 'mock-category');
fixture.detectChanges();
fixture.componentRef.setInput('excludeByProcessCategoryName', 'mock-category-2');
fixture.detectChanges();
expect(fetchProcessListSpy).toHaveBeenCalledTimes(2);
expect(fetchProcessListSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
excludeByProcessCategoryName: 'mock-category'
})
);
expect(fetchProcessListSpy).toHaveBeenCalledWith(
jasmine.objectContaining({
excludeByProcessCategoryName: 'mock-category-2'
})
);
});
it('should reload process list when sorting on a column changes', () => { it('should reload process list when sorting on a column changes', () => {
const fetchProcessListSpy = spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList)); const fetchProcessListSpy = spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList));
component.onSortingChanged( component.onSortingChanged(
@@ -945,7 +967,7 @@ describe('ProcessListCloudComponent', () => {
expect(component.columns.length).toEqual(2); expect(component.columns.length).toEqual(2);
}); });
it('should not shown columns selector by default', () => { it('should NOT shown columns selector by default', () => {
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList)); spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true); const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);

View File

@@ -290,6 +290,8 @@ export class ProcessListCloudComponent
@Input() @Input()
processVariables: ProcessVariableFilterModel[]; processVariables: ProcessVariableFilterModel[];
@Input() excludeByProcessCategoryName: string = '';
/** Emitted when a row in the process list is clicked. */ /** Emitted when a row in the process list is clicked. */
@Output() @Output()
rowClick: EventEmitter<string> = new EventEmitter<string>(); rowClick: EventEmitter<string> = new EventEmitter<string>();
@@ -607,7 +609,8 @@ export class ProcessListCloudComponent
suspendedFrom: this.suspendedFrom, suspendedFrom: this.suspendedFrom,
suspendedTo: this.suspendedTo, suspendedTo: this.suspendedTo,
processVariableKeys: this.getVariableDefinitionsRequestModel(), processVariableKeys: this.getVariableDefinitionsRequestModel(),
processVariableFilters: this.processVariables processVariableFilters: this.processVariables,
excludeByProcessCategoryName: this.excludeByProcessCategoryName
}; };
return new ProcessListRequestModel(requestNode); return new ProcessListRequestModel(requestNode);

View File

@@ -102,6 +102,7 @@ export class ProcessListRequestModel {
completedTo?: string; completedTo?: string;
suspendedFrom?: string; suspendedFrom?: string;
suspendedTo?: string; suspendedTo?: string;
excludeByProcessCategoryName?: string;
processVariableFilters?: ProcessVariableFilterModel[]; processVariableFilters?: ProcessVariableFilterModel[];
processVariableKeys?: string[]; processVariableKeys?: string[];
@@ -132,6 +133,7 @@ export class ProcessListRequestModel {
this.suspendedTo = obj.suspendedTo; this.suspendedTo = obj.suspendedTo;
this.processVariableKeys = obj.processVariableKeys; this.processVariableKeys = obj.processVariableKeys;
this.processVariableFilters = obj.processVariableFilters; this.processVariableFilters = obj.processVariableFilters;
this.excludeByProcessCategoryName = obj.excludeByProcessCategoryName;
} }
} }

View File

@@ -115,19 +115,32 @@ describe('ProcessListCloudService', () => {
}); });
describe('fetchProcessList', () => { describe('fetchProcessList', () => {
it('should append to the call all the parameters', async () => { it('should append to the call all the query parameters', async () => {
const processRequest = { const processRequest = {
appName: 'fakeName', appName: 'fakeName',
pagination: { skipCount: 0, maxItems: 20 } pagination: { skipCount: 0, maxItems: 20 },
parentId: ['fakeParentId'],
excludeByProcessCategoryName: 'fakeCategory'
} as ProcessListRequestModel; } as ProcessListRequestModel;
requestSpy.and.callFake(returnCallQueryParameters); requestSpy.and.callFake(returnCallQueryParameters);
const res = await firstValueFrom(service.fetchProcessList(processRequest)); const requestQueryParams = await firstValueFrom(service.fetchProcessList(processRequest));
expect(res).toBeDefined(); expect(requestQueryParams).toEqual({ skipCount: 0, maxItems: 20 });
expect(res).not.toBeNull(); });
expect(res.skipCount).toBe(0);
expect(res.maxItems).toBe(20); it('should append to the call all the body parameters', async () => {
const processRequest = {
appName: 'fakeName',
pagination: { skipCount: 0, maxItems: 20 },
parentId: ['fakeParentId'],
excludeByProcessCategoryName: 'fakeCategory'
} as ProcessListRequestModel;
requestSpy.and.callFake(returnCallBody);
const requestBodyParams = await firstValueFrom(service.fetchProcessList(processRequest));
expect(requestBodyParams).toEqual({ excludeByProcessCategoryName: 'fakeCategory', parentId: ['fakeParentId'] });
}); });
it('should concat the app name to the request url', async () => { it('should concat the app name to the request url', async () => {
@@ -137,34 +150,31 @@ describe('ProcessListCloudService', () => {
} as ProcessListRequestModel; } as ProcessListRequestModel;
requestSpy.and.callFake(returnCallUrl); requestSpy.and.callFake(returnCallUrl);
const res = await firstValueFrom(service.fetchProcessList(processRequest)); const requestUrl = await firstValueFrom(service.fetchProcessList(processRequest));
expect(res).toBeDefined(); expect(requestUrl).toContain('/fakeName/query/v1/process-instances/search');
expect(res).not.toBeNull();
expect(res).toContain('/fakeName/query/v1/process-instances/search');
}); });
it('should concat the sorting to append as parameters', async () => { it('should concat the sorting to append as a body sort parameter', async () => {
const processRequest = { const processRequest = {
appName: 'fakeName', appName: 'fakeName',
pagination: { skipCount: 0, maxItems: 20 }, pagination: { skipCount: 0, maxItems: 20 },
sorting: { orderBy: 'NAME', direction: 'DESC', isFieldProcessVariable: false } sorting: { orderBy: 'NAME', direction: 'DESC', isFieldProcessVariable: false }
} as ProcessListRequestModel; } as ProcessListRequestModel;
requestSpy.and.callFake(returnCallQueryParameters); requestSpy.and.callFake(returnCallBody);
const res = await firstValueFrom(service.fetchProcessList(processRequest)); const requestBodyParams = await firstValueFrom(service.fetchProcessList(processRequest));
expect(res).toBeDefined(); expect(requestBodyParams).toEqual({ sort: { field: 'NAME', direction: 'desc', isProcessVariable: false } });
expect(res).not.toBeNull();
}); });
it('should return an error when app name is not specified', async () => { it('should return an error when app name is not specified', async () => {
const taskRequest = { appName: null } as ProcessListRequestModel; const taskRequest = { appName: null } as ProcessListRequestModel;
requestSpy.and.callFake(returnCallUrl); requestSpy.and.callFake(returnCallUrl);
const res = await firstValueFrom(service.fetchProcessList(taskRequest).pipe(catchError((error) => of(error.message)))); const error = await firstValueFrom(service.fetchProcessList(taskRequest).pipe(catchError((error) => of(error.message))));
expect(res).toBe('Appname not configured'); expect(error).toBe('Appname not configured');
}); });
}); });

View File

@@ -100,8 +100,8 @@ export class ProcessListCloudService extends BaseCloudService {
); );
} }
protected buildQueryData(requestNode: ProcessListRequestModel) { protected buildQueryData(requestNode: ProcessListRequestModel): { [key: string]: any } {
const queryData: any = { const queryData: { [key: string]: any } = {
name: requestNode.name, name: requestNode.name,
id: requestNode.id, id: requestNode.id,
parentId: requestNode.parentId, parentId: requestNode.parentId,
@@ -118,7 +118,8 @@ export class ProcessListCloudService extends BaseCloudService {
suspendedFrom: requestNode.suspendedFrom, suspendedFrom: requestNode.suspendedFrom,
suspendedTo: requestNode.suspendedTo, suspendedTo: requestNode.suspendedTo,
processVariableKeys: requestNode.processVariableKeys, processVariableKeys: requestNode.processVariableKeys,
processVariableFilters: requestNode.processVariableFilters processVariableFilters: requestNode.processVariableFilters,
excludeByProcessCategoryName: requestNode.excludeByProcessCategoryName
}; };
if (requestNode.sorting) { if (requestNode.sorting) {