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.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 {
id: string;
name: string;
key: string;
icon: string;
index: number;
appName: string;
name: string | null;
key: string | null;
icon: string | null;
index: number | null;
appName: string | null;
appVersion?: number | number[];
parentId?: string;
processName: string;
processInstanceId: string;
initiator: string;
status: string;
sort: string;
order: string;
processDefinitionId: string;
processDefinitionName?: string;
processDefinitionKey: string;
lastModified: Date;
lastModifiedTo: Date;
lastModifiedFrom: Date;
startedDate: Date;
completedDateType: DateCloudFilterType;
startedDateType: DateCloudFilterType;
suspendedDateType: DateCloudFilterType;
completedDate: Date;
environmentId?: string;
parentId: string;
processName: string | null;
processInstanceId: string | null;
initiator: string | null;
status: string | null;
sort: string | null;
order: string | null;
processDefinitionId: string | null;
processDefinitionName: string | null;
processDefinitionKey: string | null;
lastModified: Date | null;
lastModifiedTo: Date | null;
lastModifiedFrom: Date | null;
startedDate: Date | null;
completedDateType: DateCloudFilterType | null;
startedDateType: DateCloudFilterType | null;
suspendedDateType: DateCloudFilterType | null;
completedDate: Date | null;
environmentId: string | null;
showCounter: boolean;
processDefinitionNames: string[] | null;
@@ -58,60 +58,64 @@ export class ProcessFilterCloudModel {
initiators: string[] | null;
appVersions: string[] | null;
statuses: string[] | null;
excludeByProcessCategoryName: string | null;
processVariableFilters?: ProcessVariableFilterModel[];
private dateRangeFilterService = new DateRangeFilterService();
private _completedFrom: string;
private _completedTo: string;
private _startFrom: string;
private _startTo: string;
private _suspendedFrom: string;
private _suspendedTo: string;
private _completedFrom: string | null;
private _completedTo: string | null;
private _startFrom: string | null;
private _startTo: string | null;
private _suspendedFrom: string | null;
private _suspendedTo: string | null;
constructor(obj?: any) {
if (obj) {
this.id = obj.id || Math.random().toString(36).substring(2, 9);
this.name = obj.name || null;
this.key = obj.key || null;
this.environmentId = obj.environmentId;
this.showCounter = obj.showCounter || false;
this.icon = obj.icon || null;
this.index = obj.index || null;
this.appName = obj.appName || obj.appName === '' ? obj.appName : null;
this.appVersion = obj.appVersion || null;
if (obj.appVersionMultiple && Array.isArray(obj.appVersionMultiple)) {
this.appVersion = obj.appVersionMultiple;
}
this.processInstanceId = obj.processInstanceId || null;
this.parentId = obj.parentId || '';
this.processName = obj.processName || null;
this.initiator = obj.initiator || null;
this.status = obj.status || null;
this.sort = obj.sort || null;
this.order = obj.order || null;
this.processDefinitionId = obj.processDefinitionId || null;
this.processDefinitionName = obj.processDefinitionName || null;
this.processDefinitionKey = obj.processDefinitionKey || null;
this.lastModified = obj.lastModified || null;
this.lastModifiedTo = obj.lastModifiedTo || null;
this.lastModifiedFrom = obj.lastModifiedFrom || null;
this.startedDate = obj.startedDate || null;
this.startFrom = obj._startFrom || null;
this.startTo = obj._startTo || null;
this.completedDateType = obj.completedDateType || null;
this.startedDateType = obj.startedDateType || null;
this.suspendedDateType = obj.suspendedDateType || null;
this.completedFrom = obj._completedFrom || null;
this.completedTo = obj._completedTo || null;
this.completedDate = obj.completedDate || null;
this._suspendedFrom = obj._suspendedFrom || null;
this._suspendedTo = obj._suspendedTo || null;
this.initArrayProperties(obj);
if (!obj) {
return;
}
this.id = obj.id || Math.random().toString(36).substring(2, 9);
this.name = obj.name || null;
this.key = obj.key || null;
this.environmentId = obj.environmentId || null;
this.showCounter = obj.showCounter || false;
this.icon = obj.icon || null;
this.index = obj.index || null;
this.appName = obj.appName || obj.appName === '' ? obj.appName : null;
this.appVersion = obj.appVersion || null;
if (obj.appVersionMultiple && Array.isArray(obj.appVersionMultiple)) {
this.appVersion = obj.appVersionMultiple;
}
this.processInstanceId = obj.processInstanceId || null;
this.parentId = obj.parentId || '';
this.processName = obj.processName || null;
this.initiator = obj.initiator || null;
this.status = obj.status || null;
this.sort = obj.sort || null;
this.order = obj.order || null;
this.processDefinitionId = obj.processDefinitionId || null;
this.processDefinitionName = obj.processDefinitionName || null;
this.processDefinitionKey = obj.processDefinitionKey || null;
this.lastModified = obj.lastModified || null;
this.lastModifiedTo = obj.lastModifiedTo || null;
this.lastModifiedFrom = obj.lastModifiedFrom || null;
this.startedDate = obj.startedDate || null;
this.startFrom = obj._startFrom || null;
this.startTo = obj._startTo || null;
this.completedDateType = obj.completedDateType || null;
this.startedDateType = obj.startedDateType || null;
this.suspendedDateType = obj.suspendedDateType || null;
this.completedFrom = obj._completedFrom || null;
this.completedTo = obj._completedTo || null;
this.completedDate = obj.completedDate || null;
this.excludeByProcessCategoryName = obj.excludeByProcessCategoryName || null;
this._suspendedFrom = obj._suspendedFrom || null;
this._suspendedTo = obj._suspendedTo || null;
this.initArrayProperties(obj);
}
private initArrayProperties(obj) {

View File

@@ -374,7 +374,7 @@ describe('ProcessListCloudComponent', () => {
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));
component.appVersion = undefined;
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');
});
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(preferencesService, 'getPreferences').and.returnValue(
of({
@@ -668,7 +668,7 @@ describe('ProcessListCloudComponent', () => {
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));
component.appVersion = undefined;
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');
});
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(preferencesService, 'getPreferences').and.returnValue(
of({
@@ -846,6 +846,28 @@ describe('ProcessListCloudComponent', () => {
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', () => {
const fetchProcessListSpy = spyOn(processListCloudService, 'fetchProcessList').and.returnValue(of(fakeProcessCloudList));
component.onSortingChanged(
@@ -945,7 +967,7 @@ describe('ProcessListCloudComponent', () => {
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));
const appName = new SimpleChange(null, 'FAKE-APP-NAME', true);

View File

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

View File

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

View File

@@ -115,19 +115,32 @@ describe('ProcessListCloudService', () => {
});
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 = {
appName: 'fakeName',
pagination: { skipCount: 0, maxItems: 20 }
pagination: { skipCount: 0, maxItems: 20 },
parentId: ['fakeParentId'],
excludeByProcessCategoryName: 'fakeCategory'
} as ProcessListRequestModel;
requestSpy.and.callFake(returnCallQueryParameters);
const res = await firstValueFrom(service.fetchProcessList(processRequest));
const requestQueryParams = await firstValueFrom(service.fetchProcessList(processRequest));
expect(res).toBeDefined();
expect(res).not.toBeNull();
expect(res.skipCount).toBe(0);
expect(res.maxItems).toBe(20);
expect(requestQueryParams).toEqual({ skipCount: 0, maxItems: 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 () => {
@@ -137,34 +150,31 @@ describe('ProcessListCloudService', () => {
} as ProcessListRequestModel;
requestSpy.and.callFake(returnCallUrl);
const res = await firstValueFrom(service.fetchProcessList(processRequest));
const requestUrl = await firstValueFrom(service.fetchProcessList(processRequest));
expect(res).toBeDefined();
expect(res).not.toBeNull();
expect(res).toContain('/fakeName/query/v1/process-instances/search');
expect(requestUrl).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 = {
appName: 'fakeName',
pagination: { skipCount: 0, maxItems: 20 },
sorting: { orderBy: 'NAME', direction: 'DESC', isFieldProcessVariable: false }
} 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(res).not.toBeNull();
expect(requestBodyParams).toEqual({ sort: { field: 'NAME', direction: 'desc', isProcessVariable: false } });
});
it('should return an error when app name is not specified', async () => {
const taskRequest = { appName: null } as ProcessListRequestModel;
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) {
const queryData: any = {
protected buildQueryData(requestNode: ProcessListRequestModel): { [key: string]: any } {
const queryData: { [key: string]: any } = {
name: requestNode.name,
id: requestNode.id,
parentId: requestNode.parentId,
@@ -118,7 +118,8 @@ export class ProcessListCloudService extends BaseCloudService {
suspendedFrom: requestNode.suspendedFrom,
suspendedTo: requestNode.suspendedTo,
processVariableKeys: requestNode.processVariableKeys,
processVariableFilters: requestNode.processVariableFilters
processVariableFilters: requestNode.processVariableFilters,
excludeByProcessCategoryName: requestNode.excludeByProcessCategoryName
};
if (requestNode.sorting) {