mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
AAE-25145 Sort process and task lists by process variables (#10412)
This commit is contained in:
parent
356260b5d1
commit
fc9c82733c
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Pagination } from '@alfresco/js-api';
|
||||
import { TaskListCloudSortingModel } from './task-list-sorting.model';
|
||||
import { TaskListCloudSortingModel, TaskListRequestSortingModel } from './task-list-sorting.model';
|
||||
import { TaskFilterCloudModel } from '../task/task-filters/models/filter-cloud.model';
|
||||
|
||||
export class TaskQueryCloudRequestModel {
|
||||
@ -103,7 +103,7 @@ export interface TaskListRequestTaskVariableFilter {
|
||||
export class TaskListRequestModel {
|
||||
appName: string;
|
||||
pagination?: Pagination;
|
||||
sorting?: TaskListCloudSortingModel[];
|
||||
sorting?: TaskListRequestSortingModel;
|
||||
|
||||
onlyStandalone?: boolean;
|
||||
onlyRoot?: boolean;
|
||||
@ -172,7 +172,11 @@ export class TaskFilterCloudAdapter extends TaskListRequestModel {
|
||||
super({
|
||||
appName: filter.appName,
|
||||
pagination: { maxItems: 25, skipCount: 0 },
|
||||
sorting: [{ orderBy: filter.sort, direction: filter.order }],
|
||||
sorting: new TaskListRequestSortingModel({
|
||||
orderBy: filter.sort,
|
||||
direction: filter.order,
|
||||
isFieldProcessVariable: false
|
||||
}),
|
||||
|
||||
onlyStandalone: filter.standalone,
|
||||
name: filter.taskNames,
|
||||
|
@ -26,3 +26,29 @@ export class TaskListCloudSortingModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class TaskListRequestSortingModel extends TaskListCloudSortingModel {
|
||||
orderBy: string;
|
||||
direction: string;
|
||||
|
||||
isFieldProcessVariable: boolean;
|
||||
processVariableData?: {
|
||||
processDefinitionKeys: string[];
|
||||
type: string;
|
||||
}
|
||||
|
||||
constructor(obj: TaskListRequestSortingModel) {
|
||||
super(obj);
|
||||
if (obj.isFieldProcessVariable) {
|
||||
this.isFieldProcessVariable = true;
|
||||
this.processVariableData = obj.processVariableData;
|
||||
if (!this.processVariableData.processDefinitionKeys?.length ||
|
||||
!this.processVariableData.type
|
||||
) {
|
||||
throw new Error('missing required property when sorting by process variable');
|
||||
}
|
||||
} else {
|
||||
this.isFieldProcessVariable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ import { ProcessListCloudService } from '../services/process-list-cloud.service'
|
||||
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
|
||||
import { processCloudPresetsDefaultModel } from '../models/process-cloud-preset.model';
|
||||
import { ProcessListRequestModel, ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
||||
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
||||
import { ProcessListCloudSortingModel, ProcessListRequestSortingModel } from '../models/process-list-sorting.model';
|
||||
import { filter, map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
||||
import {
|
||||
@ -328,6 +328,7 @@ export class ProcessListCloudComponent
|
||||
this.pagination.next(processes.list.pagination);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.error.emit(error);
|
||||
this.isLoading = false;
|
||||
}
|
||||
@ -526,7 +527,7 @@ export class ProcessListCloudComponent
|
||||
maxItems: this.size,
|
||||
skipCount: this.skipCount
|
||||
},
|
||||
sorting: this.sorting,
|
||||
sorting: this.getProcessListRequestSorting(),
|
||||
name: this.names,
|
||||
initiator: this.initiators,
|
||||
appVersion: this.appVersions,
|
||||
@ -545,6 +546,39 @@ export class ProcessListCloudComponent
|
||||
return new ProcessListRequestModel(requestNode);
|
||||
}
|
||||
|
||||
private getProcessListRequestSorting(): ProcessListRequestSortingModel {
|
||||
if (!this.sorting?.length) {
|
||||
return new ProcessListRequestSortingModel({
|
||||
orderBy: this.defaultSorting.key,
|
||||
direction: this.defaultSorting.direction,
|
||||
isFieldProcessVariable: false
|
||||
});
|
||||
}
|
||||
|
||||
const orderBy = this.sorting[0]?.orderBy;
|
||||
const direction = this.sorting[0]?.direction;
|
||||
const orderByColumn = this.columnList?.columns.find((column) => column.key === orderBy);
|
||||
const isFieldProcessVariable = orderByColumn?.customData?.columnType === 'process-variable-column';
|
||||
|
||||
if (isFieldProcessVariable) {
|
||||
const processDefinitionKeys = orderByColumn.customData.variableDefinitionsPayload.map(
|
||||
(variableDefinition) => variableDefinition.split('/')[0]
|
||||
);
|
||||
const variableName = orderByColumn.customData.variableDefinitionsPayload[0].split('/')[1];
|
||||
return new ProcessListRequestSortingModel({
|
||||
orderBy: variableName,
|
||||
direction,
|
||||
isFieldProcessVariable: true,
|
||||
processVariableData: {
|
||||
processDefinitionKeys,
|
||||
type: orderByColumn.customData.variableType
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new ProcessListRequestSortingModel({orderBy, direction, isFieldProcessVariable: false});
|
||||
}
|
||||
}
|
||||
|
||||
private createRequestNode(): ProcessQueryCloudRequestModel {
|
||||
const requestNode = {
|
||||
appName: this.appName,
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Pagination } from '@alfresco/js-api';
|
||||
import { ProcessListCloudSortingModel } from './process-list-sorting.model';
|
||||
import { ProcessListCloudSortingModel, ProcessListRequestSortingModel } from './process-list-sorting.model';
|
||||
import { ProcessFilterCloudModel } from '../../process-filters/models/process-filter-cloud.model';
|
||||
|
||||
export class ProcessQueryCloudRequestModel {
|
||||
@ -90,7 +90,7 @@ export interface ProcessListRequestProcessVariableFilter {
|
||||
export class ProcessListRequestModel {
|
||||
appName: string;
|
||||
pagination?: Pagination;
|
||||
sorting?: ProcessListCloudSortingModel[];
|
||||
sorting?: ProcessListRequestSortingModel;
|
||||
|
||||
name?: string[];
|
||||
initiator?: string[];
|
||||
@ -138,7 +138,11 @@ export class ProcessFilterCloudAdapter extends ProcessListRequestModel {
|
||||
super({
|
||||
appName: filter.appName,
|
||||
pagination: { maxItems: 25, skipCount: 0 },
|
||||
sorting: [{ orderBy: filter.sort, direction: filter.order }],
|
||||
sorting: new ProcessListRequestSortingModel({
|
||||
orderBy: filter.sort,
|
||||
direction: filter.order,
|
||||
isFieldProcessVariable: false
|
||||
}),
|
||||
|
||||
name: filter.processDefinitionNames,
|
||||
initiator: filter.initiators,
|
||||
|
@ -25,3 +25,28 @@ export class ProcessListCloudSortingModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
export class ProcessListRequestSortingModel extends ProcessListCloudSortingModel {
|
||||
orderBy: string;
|
||||
direction: string;
|
||||
|
||||
isFieldProcessVariable: boolean;
|
||||
processVariableData?: {
|
||||
processDefinitionKeys: string[];
|
||||
type: string;
|
||||
}
|
||||
|
||||
constructor(obj: ProcessListRequestSortingModel) {
|
||||
super(obj);
|
||||
if (obj.isFieldProcessVariable) {
|
||||
this.isFieldProcessVariable = true;
|
||||
this.processVariableData = obj.processVariableData;
|
||||
if (!this.processVariableData.processDefinitionKeys?.length ||
|
||||
!this.processVariableData.type
|
||||
) {
|
||||
throw new Error('missing required property when sorting by process variable');
|
||||
}
|
||||
} else {
|
||||
this.isFieldProcessVariable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,10 +148,7 @@ describe('ProcessListCloudService', () => {
|
||||
const processRequest = {
|
||||
appName: 'fakeName',
|
||||
pagination: { skipCount: 0, maxItems: 20 },
|
||||
sorting: [
|
||||
{ orderBy: 'NAME', direction: 'DESC' },
|
||||
{ orderBy: 'TITLE', direction: 'ASC' }
|
||||
]
|
||||
sorting: { orderBy: 'NAME', direction: 'DESC', isFieldProcessVariable: false }
|
||||
} as ProcessListRequestModel;
|
||||
requestSpy.and.callFake(returnCallQueryParameters);
|
||||
|
||||
@ -159,7 +156,6 @@ describe('ProcessListCloudService', () => {
|
||||
|
||||
expect(res).toBeDefined();
|
||||
expect(res).not.toBeNull();
|
||||
expect(res.sort).toBe('NAME,DESC&TITLE,ASC');
|
||||
});
|
||||
|
||||
it('should return an error when app name is not specified', async () => {
|
||||
|
@ -85,8 +85,7 @@ export class ProcessListCloudService extends BaseCloudService {
|
||||
|
||||
const queryParams = {
|
||||
maxItems: requestNode.pagination?.maxItems || 25,
|
||||
skipCount: requestNode.pagination?.skipCount || 0,
|
||||
sort: this.buildSortingParam(requestNode.sorting || [])
|
||||
skipCount: requestNode.pagination?.skipCount || 0
|
||||
};
|
||||
|
||||
const queryData = this.buildQueryData(requestNode);
|
||||
@ -118,6 +117,18 @@ export class ProcessListCloudService extends BaseCloudService {
|
||||
processVariableKeys: requestNode.processVariableKeys
|
||||
};
|
||||
|
||||
if (requestNode.sorting) {
|
||||
queryData['sort'] = {
|
||||
field: requestNode.sorting.orderBy,
|
||||
direction: requestNode.sorting.direction.toLowerCase(),
|
||||
isProcessVariable: requestNode.sorting.isFieldProcessVariable
|
||||
};
|
||||
if (queryData['sort'].isProcessVariable) {
|
||||
queryData['sort'].processDefinitionKeys = requestNode.sorting.processVariableData?.processDefinitionKeys;
|
||||
queryData['sort'].type = requestNode.sorting.processVariableData?.type;
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(queryData).forEach((key) => {
|
||||
const value = queryData[key];
|
||||
const isValueEmpty = !value;
|
||||
|
@ -59,7 +59,7 @@ export abstract class BaseTaskListCloudComponent<T = unknown>
|
||||
extends DataTableSchema<T>
|
||||
// eslint-disable-next-line @typescript-eslint/brace-style
|
||||
implements OnChanges, AfterContentInit, PaginatedComponent, OnInit {
|
||||
|
||||
|
||||
@ContentChild(CustomEmptyContentTemplateDirective)
|
||||
emptyCustomContent: CustomEmptyContentTemplateDirective;
|
||||
|
||||
@ -148,7 +148,7 @@ export abstract class BaseTaskListCloudComponent<T = unknown>
|
||||
formattedSorting: any[];
|
||||
dataAdapter: ObjectDataTableAdapter | undefined;
|
||||
|
||||
private defaultSorting = { key: 'startDate', direction: 'desc' };
|
||||
protected defaultSorting = { key: 'startDate', direction: 'desc' };
|
||||
boundReplacePriorityValues: (row: DataRow, col: DataColumn) => any;
|
||||
|
||||
protected abstract isLoading$: Observable<boolean>;
|
||||
|
@ -24,7 +24,7 @@ import { TASK_LIST_CLOUD_TOKEN, TASK_LIST_PREFERENCES_SERVICE_TOKEN, TASK_SEARCH
|
||||
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
||||
import { TaskListCloudServiceInterface } from '../../../services/task-list-cloud.service.interface';
|
||||
import { BehaviorSubject, combineLatest, Subject } from 'rxjs';
|
||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||
import { filter, map, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { VariableMapperService } from '../../../services/variable-mapper.sevice';
|
||||
import { ProcessListDataColumnCustomData } from '../../../models/data-column-custom-data';
|
||||
import { TaskCloudModel } from '../../../models/task-cloud.model';
|
||||
@ -32,6 +32,7 @@ import { PaginatedEntries } from '@alfresco/js-api';
|
||||
import { TaskInstanceCloudListViewModel } from '../models/task-cloud-view.model';
|
||||
import { TasksListDatatableAdapter } from '../datatable/task-list-datatable-adapter';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { TaskListRequestSortingModel } from '../../../models/task-list-sorting.model';
|
||||
|
||||
const PRESET_KEY = 'adf-cloud-task-list.presets';
|
||||
|
||||
@ -211,6 +212,7 @@ export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessLi
|
||||
|
||||
combineLatest([this.isColumnSchemaCreated$, this.fetchProcessesTrigger$])
|
||||
.pipe(
|
||||
tap(() => this.isReloadingSubject$.next(true)),
|
||||
filter((isColumnSchemaCreated) => !!isColumnSchemaCreated),
|
||||
switchMap(() => {
|
||||
if (this.searchMethod === 'POST') {
|
||||
@ -240,6 +242,7 @@ export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessLi
|
||||
this.pagination.next(tasks.list.pagination);
|
||||
},
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.error.emit(error);
|
||||
this.isReloadingSubject$.next(false);
|
||||
}
|
||||
@ -258,7 +261,7 @@ export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessLi
|
||||
maxItems: this.size,
|
||||
skipCount: this.skipCount
|
||||
},
|
||||
sorting: this.sorting,
|
||||
sorting: this.getTaskListRequestSorting(),
|
||||
onlyStandalone: this.standalone,
|
||||
name: this.names,
|
||||
processDefinitionName: this.processDefinitionNames,
|
||||
@ -329,4 +332,37 @@ export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessLi
|
||||
|
||||
return displayedVariableColumns.length ? displayedVariableColumns : undefined;
|
||||
}
|
||||
|
||||
private getTaskListRequestSorting(): TaskListRequestSortingModel {
|
||||
if (!this.sorting?.length) {
|
||||
return new TaskListRequestSortingModel({
|
||||
orderBy: this.defaultSorting.key,
|
||||
direction: this.defaultSorting.direction,
|
||||
isFieldProcessVariable: false
|
||||
});
|
||||
}
|
||||
|
||||
const orderBy = this.sorting[0]?.orderBy;
|
||||
const direction = this.sorting[0]?.direction;
|
||||
const orderByColumn = this.columnList?.columns.find((column) => column.key === orderBy);
|
||||
const isFieldProcessVariable = orderByColumn?.customData?.columnType === 'process-variable-column';
|
||||
|
||||
if (isFieldProcessVariable) {
|
||||
const processDefinitionKeys = orderByColumn.customData.variableDefinitionsPayload.map(
|
||||
(variableDefinition) => variableDefinition.split('/')[0]
|
||||
);
|
||||
const variableName = orderByColumn.customData.variableDefinitionsPayload[0].split('/')[1];
|
||||
return new TaskListRequestSortingModel({
|
||||
orderBy: variableName,
|
||||
direction,
|
||||
isFieldProcessVariable: true,
|
||||
processVariableData: {
|
||||
processDefinitionKeys,
|
||||
type: orderByColumn.customData.variableType
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new TaskListRequestSortingModel({orderBy, direction, isFieldProcessVariable: false});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,10 +139,7 @@ describe('TaskListCloudService', () => {
|
||||
const taskRequest = {
|
||||
appName: 'fakeName',
|
||||
pagination: { skipCount: 0, maxItems: 20 },
|
||||
sorting: [
|
||||
{ orderBy: 'NAME', direction: 'DESC' },
|
||||
{ orderBy: 'TITLE', direction: 'ASC' }
|
||||
]
|
||||
sorting: { orderBy: 'NAME', direction: 'DESC', isFieldProcessVariable: false }
|
||||
} as TaskListRequestModel;
|
||||
requestSpy.and.callFake(returnCallQueryParameters);
|
||||
|
||||
@ -150,7 +147,6 @@ describe('TaskListCloudService', () => {
|
||||
|
||||
expect(res).toBeDefined();
|
||||
expect(res).not.toBeNull();
|
||||
expect(res.sort).toBe('NAME,DESC&TITLE,ASC');
|
||||
});
|
||||
|
||||
it('should return an error when app name is not specified', async () => {
|
||||
|
@ -74,8 +74,7 @@ export class TaskListCloudService extends BaseCloudService implements TaskListCl
|
||||
|
||||
const queryParams = {
|
||||
maxItems: requestNode.pagination?.maxItems || 25,
|
||||
skipCount: requestNode.pagination?.skipCount || 0,
|
||||
sort: this.buildSortingParam(requestNode.sorting || [])
|
||||
skipCount: requestNode.pagination?.skipCount || 0
|
||||
};
|
||||
|
||||
const queryData = this.buildQueryData(requestNode);
|
||||
@ -115,6 +114,18 @@ export class TaskListCloudService extends BaseCloudService implements TaskListCl
|
||||
processVariableKeys: requestNode.processVariableKeys
|
||||
};
|
||||
|
||||
if (requestNode.sorting) {
|
||||
queryData['sort'] = {
|
||||
field: requestNode.sorting.orderBy,
|
||||
direction: requestNode.sorting.direction.toLowerCase(),
|
||||
isProcessVariable: requestNode.sorting.isFieldProcessVariable
|
||||
};
|
||||
if (queryData['sort'].isProcessVariable) {
|
||||
queryData['sort'].processDefinitionKeys = requestNode.sorting.processVariableData?.processDefinitionKeys;
|
||||
queryData['sort'].type = requestNode.sorting.processVariableData?.type;
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(queryData).forEach((key) => {
|
||||
const value = queryData[key];
|
||||
const isValueEmpty = !value;
|
||||
|
Loading…
x
Reference in New Issue
Block a user