mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-7856] Show variables in table
This commit is contained in:
@@ -21,6 +21,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
|
|||||||
- [Column Template](#column-template)
|
- [Column Template](#column-template)
|
||||||
- [Styling Techniques](#styling-techniques)
|
- [Styling Techniques](#styling-techniques)
|
||||||
- [Using the copyContent option](#using-the-copycontent-option)
|
- [Using the copyContent option](#using-the-copycontent-option)
|
||||||
|
- [Exapmple of column customData](#example-of-column-customData)
|
||||||
- [See also](#see-also)
|
- [See also](#see-also)
|
||||||
|
|
||||||
## Basic Usage
|
## Basic Usage
|
||||||
@@ -52,6 +53,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
|
|||||||
| formatTooltip | `Function` | | Custom tooltip formatter function. |
|
| formatTooltip | `Function` | | Custom tooltip formatter function. |
|
||||||
| key | `string` | | Data source key. Can be either a column/property key like `title` or a property path like `createdBy.name`. |
|
| key | `string` | | Data source key. Can be either a column/property key like `title` or a property path like `createdBy.name`. |
|
||||||
| sortable | `boolean` | true | Toggles ability to sort by this column, for example by clicking the column header. |
|
| sortable | `boolean` | true | Toggles ability to sort by this column, for example by clicking the column header. |
|
||||||
|
| customData | `Generic` | any | Any feature specific data |
|
||||||
| draggable | `boolean` | false | Toggles drag and drop for header column. |
|
| draggable | `boolean` | false | Toggles drag and drop for header column. |
|
||||||
| isHidden | `boolean` | false | Hides columns |
|
| isHidden | `boolean` | false | Hides columns |
|
||||||
| sortingKey | `string` | | When using server side sorting the column used by the api call where the sorting will be performed |
|
| sortingKey | `string` | | When using server side sorting the column used by the api call where the sorting will be performed |
|
||||||
@@ -351,6 +353,35 @@ HTML `<data-column>` element example:
|
|||||||
</adf-tasklist>
|
</adf-tasklist>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Example of column customData
|
||||||
|
|
||||||
|
If you would like to pass any custom data related to your specific feature, you can use customData
|
||||||
|
|
||||||
|
HTML `<data-column>` element example:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<data-column [customData]="MyCustomData" key="id" title="Id"></data-column>
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use generic type for `DataColumn` in order to get intellisense working e.g.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const dataColumn: DataColumn<{ shouldPerformActionIfDisplayed: boolean }> = {
|
||||||
|
...
|
||||||
|
customData: { shouldPerformActionIfDisplayed: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should get proper types
|
||||||
|
consol.log(dataColumn.customData.shouldPerformActionIfDisplayed);
|
||||||
|
|
||||||
|
// Now we can use this data in our feature e.g.
|
||||||
|
const shouldPerformAction = this.columns
|
||||||
|
.filter(column => column.isHidden)
|
||||||
|
.some(column => column.customData?.shouldPerformActionIfDisplayed === true);
|
||||||
|
|
||||||
|
if (shouldPerformAction) { /* action */}
|
||||||
|
```
|
||||||
|
|
||||||
## See also
|
## See also
|
||||||
|
|
||||||
- [Document list component](../../content-services/components/document-list.component.md)
|
- [Document list component](../../content-services/components/document-list.component.md)
|
||||||
|
@@ -70,6 +70,10 @@ export class ShareDataTableAdapter implements DataTableAdapter {
|
|||||||
this.allowDropFiles = allowDropFiles;
|
this.allowDropFiles = allowDropFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getColumnType(_row: DataRow, col: DataColumn): string {
|
||||||
|
return col.type;
|
||||||
|
}
|
||||||
|
|
||||||
getRows(): Array<DataRow> {
|
getRows(): Array<DataRow> {
|
||||||
return this.rows;
|
return this.rows;
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,10 @@ export class DataColumnComponent implements OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
key: string;
|
key: string;
|
||||||
|
|
||||||
|
/** You can specify any custom data which can be used by any specific feature */
|
||||||
|
@Input()
|
||||||
|
customData: any;
|
||||||
|
|
||||||
/** Value type for the column. Possible settings are 'text', 'image',
|
/** Value type for the column. Possible settings are 'text', 'image',
|
||||||
* 'date', 'fileSize', 'location', and 'json'.
|
* 'date', 'fileSize', 'location', and 'json'.
|
||||||
*/
|
*/
|
||||||
@@ -52,6 +56,10 @@ export class DataColumnComponent implements OnInit {
|
|||||||
@Input()
|
@Input()
|
||||||
draggable: boolean = false;
|
draggable: boolean = false;
|
||||||
|
|
||||||
|
/* Hide column */
|
||||||
|
@Input()
|
||||||
|
isHidden: boolean = false;
|
||||||
|
|
||||||
/** Display title of the column, typically used for column headers. You can use the
|
/** Display title of the column, typically used for column headers. You can use the
|
||||||
* i18n resource key to get it translated automatically.
|
* i18n resource key to get it translated automatically.
|
||||||
*/
|
*/
|
||||||
|
@@ -24,10 +24,11 @@
|
|||||||
[placeholder]='"ADF-DATATABLE.COLUMNS_SELECTOR.SEARCH" | translate'>
|
[placeholder]='"ADF-DATATABLE.COLUMNS_SELECTOR.SEARCH" | translate'>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="adf-columns-selector-list-container">
|
||||||
<ng-container *ngFor="let column of columnItems">
|
<ng-container *ngFor="let column of columnItems">
|
||||||
<div
|
<div
|
||||||
*ngIf="(column.title | translate | filterString:searchQuery) as translatedTitle"
|
*ngIf="(column.title | translate | filterString:searchQuery) as translatedTitle"
|
||||||
class="adf-columns-selector-list-item-container">
|
class="adf-columns-selector-list-item">
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
color="primary"
|
color="primary"
|
||||||
class="adf-columns-selector-column-checkbox"
|
class="adf-columns-selector-column-checkbox"
|
||||||
@@ -38,6 +39,7 @@
|
|||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-divider class="adf-columns-selector-divider"></mat-divider>
|
<mat-divider class="adf-columns-selector-divider"></mat-divider>
|
||||||
|
|
||||||
|
@@ -25,7 +25,13 @@ $adf-columns-selector-space: 12px;
|
|||||||
font-size: var(--theme-body-1-font-size);
|
font-size: var(--theme-body-1-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-list-item-container {
|
&-list-container {
|
||||||
|
max-height: 350px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-list-item {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@@ -194,7 +194,7 @@
|
|||||||
[adf-context-menu-enabled]="contextMenu"
|
[adf-context-menu-enabled]="contextMenu"
|
||||||
adf-drop-zone dropTarget="cell" [dropColumn]="col" [dropRow]="row">
|
adf-drop-zone dropTarget="cell" [dropColumn]="col" [dropRow]="row">
|
||||||
<div *ngIf="!col.template" class="adf-datatable-cell-container">
|
<div *ngIf="!col.template" class="adf-datatable-cell-container">
|
||||||
<ng-container [ngSwitch]="col.type">
|
<ng-container [ngSwitch]="data.getColumnType(row, col)">
|
||||||
<div *ngSwitchCase="'image'" class="adf-cell-value">
|
<div *ngSwitchCase="'image'" class="adf-cell-value">
|
||||||
<mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}
|
<mat-icon *ngIf="isIconValue(row, col); else no_iconvalue">{{ asIconValue(row, col) }}
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
@@ -204,12 +204,12 @@
|
|||||||
</mat-icon>
|
</mat-icon>
|
||||||
<ng-template #no_selected_row>
|
<ng-template #no_selected_row>
|
||||||
<img class="adf-datatable-center-img-ie"
|
<img class="adf-datatable-center-img-ie"
|
||||||
[attr.aria-label]=" (data.getValue(row, col) | fileType) === 'disable' ?
|
[attr.aria-label]="(data.getValue(row, col) | fileType) === 'disable' ?
|
||||||
('ADF-DATATABLE.ACCESSIBILITY.ICON_DISABLED' | translate) :
|
('ADF-DATATABLE.ACCESSIBILITY.ICON_DISABLED' | translate) :
|
||||||
'ADF-DATATABLE.ACCESSIBILITY.ICON_TEXT' | translate:{
|
'ADF-DATATABLE.ACCESSIBILITY.ICON_TEXT' | translate:{
|
||||||
type: 'ADF-DATATABLE.FILE_TYPE.' + (data.getValue(row, col) | fileType | uppercase) | translate
|
type: 'ADF-DATATABLE.FILE_TYPE.' + (data.getValue(row, col) | fileType | uppercase) | translate
|
||||||
}"
|
}"
|
||||||
[attr.alt]=" (data.getValue(row, col) | fileType) === 'disable' ?
|
[attr.alt]="(data.getValue(row, col) | fileType) === 'disable' ?
|
||||||
('ADF-DATATABLE.ACCESSIBILITY.ICON_DISABLED' | translate) :
|
('ADF-DATATABLE.ACCESSIBILITY.ICON_DISABLED' | translate) :
|
||||||
'ADF-DATATABLE.ACCESSIBILITY.ICON_TEXT' | translate:{
|
'ADF-DATATABLE.ACCESSIBILITY.ICON_TEXT' | translate:{
|
||||||
type: 'ADF-DATATABLE.FILE_TYPE.' + (data.getValue(row, col) | fileType | uppercase) | translate
|
type: 'ADF-DATATABLE.FILE_TYPE.' + (data.getValue(row, col) | fileType | uppercase) | translate
|
||||||
|
@@ -29,7 +29,7 @@ export interface DataColumnTypes {
|
|||||||
|
|
||||||
export type DataColumnType = keyof DataColumnTypes;
|
export type DataColumnType = keyof DataColumnTypes;
|
||||||
|
|
||||||
export interface DataColumn {
|
export interface DataColumn<T = unknown> {
|
||||||
id?: string;
|
id?: string;
|
||||||
key: string;
|
key: string;
|
||||||
type: DataColumnType;
|
type: DataColumnType;
|
||||||
@@ -47,4 +47,5 @@ export interface DataColumn {
|
|||||||
header?: TemplateRef<any>;
|
header?: TemplateRef<any>;
|
||||||
draggable?: boolean;
|
draggable?: boolean;
|
||||||
isHidden?: boolean;
|
isHidden?: boolean;
|
||||||
|
customData?: T;
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ import { ObjectDataColumn } from './object-datacolumn.model';
|
|||||||
|
|
||||||
@Directive()
|
@Directive()
|
||||||
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
||||||
export abstract class DataTableSchema {
|
export abstract class DataTableSchema<T = unknown> {
|
||||||
|
|
||||||
@ContentChild(DataColumnListComponent)
|
@ContentChild(DataColumnListComponent)
|
||||||
columnList: DataColumnListComponent;
|
columnList: DataColumnListComponent;
|
||||||
@@ -33,7 +33,7 @@ export abstract class DataTableSchema {
|
|||||||
@Input()
|
@Input()
|
||||||
presetColumn: string;
|
presetColumn: string;
|
||||||
|
|
||||||
columns: any;
|
columns: DataColumn<T>[];
|
||||||
|
|
||||||
protected columnsOrder: string[] | undefined;
|
protected columnsOrder: string[] | undefined;
|
||||||
protected columnsOrderedByKey: string = 'id';
|
protected columnsOrderedByKey: string = 'id';
|
||||||
@@ -91,7 +91,7 @@ export abstract class DataTableSchema {
|
|||||||
return customSchemaColumns;
|
return customSchemaColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSchemaFromHtml(columnList: DataColumnListComponent): any {
|
public getSchemaFromHtml(columnList: DataColumnListComponent): DataColumn[] {
|
||||||
let schema = [];
|
let schema = [];
|
||||||
if (columnList && columnList.columns && columnList.columns.length > 0) {
|
if (columnList && columnList.columns && columnList.columns.length > 0) {
|
||||||
schema = columnList.columns.map((c) => c as DataColumn);
|
schema = columnList.columns.map((c) => c as DataColumn);
|
||||||
|
@@ -29,6 +29,7 @@ export interface DataTableAdapter {
|
|||||||
getColumns(): Array<DataColumn>;
|
getColumns(): Array<DataColumn>;
|
||||||
setColumns(columns: Array<DataColumn>): void;
|
setColumns(columns: Array<DataColumn>): void;
|
||||||
getValue(row: DataRow, col: DataColumn, resolverFn?: (_row: DataRow, _col: DataColumn) => any): any;
|
getValue(row: DataRow, col: DataColumn, resolverFn?: (_row: DataRow, _col: DataColumn) => any): any;
|
||||||
|
getColumnType(row: DataRow, col: DataColumn): string;
|
||||||
getSorting(): DataSorting;
|
getSorting(): DataSorting;
|
||||||
setSorting(sorting: DataSorting): void;
|
setSorting(sorting: DataSorting): void;
|
||||||
sort(key?: string, direction?: string): void;
|
sort(key?: string, direction?: string): void;
|
||||||
|
@@ -19,7 +19,7 @@ import { TemplateRef } from '@angular/core';
|
|||||||
import { DataColumn, DataColumnType } from './data-column.model';
|
import { DataColumn, DataColumnType } from './data-column.model';
|
||||||
|
|
||||||
// Simple implementation of the DataColumn interface.
|
// Simple implementation of the DataColumn interface.
|
||||||
export class ObjectDataColumn implements DataColumn {
|
export class ObjectDataColumn<T = unknown> implements DataColumn<T> {
|
||||||
id?: string;
|
id?: string;
|
||||||
key: string;
|
key: string;
|
||||||
type: DataColumnType;
|
type: DataColumnType;
|
||||||
@@ -35,6 +35,7 @@ export class ObjectDataColumn implements DataColumn {
|
|||||||
header?: TemplateRef<any>;
|
header?: TemplateRef<any>;
|
||||||
draggable: boolean;
|
draggable: boolean;
|
||||||
isHidden: boolean;
|
isHidden: boolean;
|
||||||
|
customData?: T;
|
||||||
|
|
||||||
constructor(input: any) {
|
constructor(input: any) {
|
||||||
this.id = input.id ?? '';
|
this.id = input.id ?? '';
|
||||||
@@ -52,5 +53,6 @@ export class ObjectDataColumn implements DataColumn {
|
|||||||
this.header = input.header;
|
this.header = input.header;
|
||||||
this.draggable = input.draggable ?? false;
|
this.draggable = input.draggable ?? false;
|
||||||
this.isHidden = input.isHidden ?? false;
|
this.isHidden = input.isHidden ?? false;
|
||||||
|
this.customData = input.customData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -77,6 +77,10 @@ export class ObjectDataTableAdapter implements DataTableAdapter {
|
|||||||
this.rowsChanged = new Subject<Array<DataRow>>();
|
this.rowsChanged = new Subject<Array<DataRow>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getColumnType(_row: DataRow, col: DataColumn): string {
|
||||||
|
return col.type;
|
||||||
|
}
|
||||||
|
|
||||||
getRows(): Array<DataRow> {
|
getRows(): Array<DataRow> {
|
||||||
return this._rows;
|
return this._rows;
|
||||||
}
|
}
|
||||||
|
22
lib/core/mock/data-column.mock.ts
Normal file
22
lib/core/mock/data-column.mock.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { DataColumn } from '../datatable/data/data-column.model';
|
||||||
|
|
||||||
|
export const getDataColumnMock = <T = unknown>(column: Partial<DataColumn<T>> = {}): DataColumn<T> => ({
|
||||||
|
id: 'columnId',
|
||||||
|
key: 'key',
|
||||||
|
type: 'text',
|
||||||
|
format: 'format',
|
||||||
|
sortable: false,
|
||||||
|
title: 'title',
|
||||||
|
srTitle: 'srTitle',
|
||||||
|
cssClass: 'cssClass',
|
||||||
|
template: undefined,
|
||||||
|
copyContent: false,
|
||||||
|
editable: false,
|
||||||
|
focus: false,
|
||||||
|
sortingKey: 'sortingKey',
|
||||||
|
header: undefined,
|
||||||
|
draggable: false,
|
||||||
|
isHidden: false,
|
||||||
|
customData: undefined,
|
||||||
|
...column
|
||||||
|
});
|
@@ -41,3 +41,4 @@ export * from './identity-group.mock';
|
|||||||
export * from './identity-user.mock';
|
export * from './identity-user.mock';
|
||||||
export * from './identity-group.service.mock';
|
export * from './identity-group.service.mock';
|
||||||
export * from './identity-user.service.mock';
|
export * from './identity-user.service.mock';
|
||||||
|
export * from './data-column.mock';
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
// eslint-disable-next-line no-shadow
|
||||||
|
export enum ColumnDataType {
|
||||||
|
processVariableColumn = 'process-variable-column'
|
||||||
|
}
|
@@ -15,6 +15,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ProcessVariableDefinition } from './variable-definition';
|
||||||
|
|
||||||
export class ProcessDefinitionCloud {
|
export class ProcessDefinitionCloud {
|
||||||
id: string;
|
id: string;
|
||||||
appName: string;
|
appName: string;
|
||||||
@@ -25,6 +27,7 @@ export class ProcessDefinitionCloud {
|
|||||||
name: string;
|
name: string;
|
||||||
category: string;
|
category: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
variableDefinitions?: ProcessVariableDefinition[];
|
||||||
|
|
||||||
constructor(obj?: any) {
|
constructor(obj?: any) {
|
||||||
this.id = obj && obj.id || null;
|
this.id = obj && obj.id || null;
|
||||||
@@ -36,5 +39,6 @@ export class ProcessDefinitionCloud {
|
|||||||
this.appVersion = obj && obj.appVersion || 0;
|
this.appVersion = obj && obj.appVersion || 0;
|
||||||
this.category = obj && obj?.category || '';
|
this.category = obj && obj?.category || '';
|
||||||
this.description = obj && obj?.description || '';
|
this.description = obj && obj?.description || '';
|
||||||
|
this.variableDefinitions = obj?.variableDefinitions ?? [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ProcessInstanceVariable {
|
||||||
|
id: number;
|
||||||
|
variableDefinitionId: string;
|
||||||
|
value: string;
|
||||||
|
appName: string;
|
||||||
|
createTime: string;
|
||||||
|
lastUpdatedTime: string;
|
||||||
|
markedAsDeleted: boolean;
|
||||||
|
name: string;
|
||||||
|
processInstanceId: string;
|
||||||
|
serviceFullName: string;
|
||||||
|
serviceName: string;
|
||||||
|
serviceVersion: string;
|
||||||
|
taskVariable: boolean;
|
||||||
|
type: string;
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ProcessVariableDefinition {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
required: boolean;
|
||||||
|
display: boolean;
|
||||||
|
displayName?: string;
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
<adf-datatable #dataTable
|
<adf-datatable #dataTable
|
||||||
[rows]="rows"
|
[rows]="rows"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
|
[data]="dataAdapter"
|
||||||
[stickyHeader]="stickyHeader"
|
[stickyHeader]="stickyHeader"
|
||||||
[loading]="isLoading"
|
[loading]="isLoading"
|
||||||
[sorting]="formattedSorting"
|
[sorting]="formattedSorting"
|
||||||
|
@@ -22,6 +22,7 @@ import {
|
|||||||
ColumnsSelectorComponent,
|
ColumnsSelectorComponent,
|
||||||
DataColumn,
|
DataColumn,
|
||||||
DataRowEvent,
|
DataRowEvent,
|
||||||
|
getDataColumnMock,
|
||||||
ObjectDataRow,
|
ObjectDataRow,
|
||||||
setupTestBed
|
setupTestBed
|
||||||
} from '@alfresco/adf-core';
|
} from '@alfresco/adf-core';
|
||||||
@@ -33,6 +34,10 @@ import { shareReplay, skip } from 'rxjs/operators';
|
|||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
||||||
|
import { PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
|
import { LocalPreferenceCloudService } from '../../../services/local-preference-cloud.service';
|
||||||
|
import { ProcessListCloudPreferences } from '../models/process-cloud-preferences';
|
||||||
|
import { ColumnDataType } from '../../../models/column-data-type.model';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
@@ -71,6 +76,9 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
let fixture: ComponentFixture<ProcessListCloudComponent>;
|
let fixture: ComponentFixture<ProcessListCloudComponent>;
|
||||||
let appConfig: AppConfigService;
|
let appConfig: AppConfigService;
|
||||||
let processListCloudService: ProcessListCloudService;
|
let processListCloudService: ProcessListCloudService;
|
||||||
|
let preferencesService: LocalPreferenceCloudService;
|
||||||
|
const fakeCustomSchemaName = 'fakeCustomSchema';
|
||||||
|
const schemaWithVariable = 'schemaWithVariableId';
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -82,12 +90,13 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
appConfig = TestBed.inject(AppConfigService);
|
appConfig = TestBed.inject(AppConfigService);
|
||||||
processListCloudService = TestBed.inject(ProcessListCloudService);
|
processListCloudService = TestBed.inject(ProcessListCloudService);
|
||||||
|
preferencesService = TestBed.inject<LocalPreferenceCloudService>(PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN);
|
||||||
fixture = TestBed.createComponent(ProcessListCloudComponent);
|
fixture = TestBed.createComponent(ProcessListCloudComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
appConfig.config = Object.assign(appConfig.config, {
|
appConfig.config = Object.assign(appConfig.config, {
|
||||||
'adf-cloud-process-list': {
|
'adf-cloud-process-list': {
|
||||||
presets: {
|
presets: {
|
||||||
fakeCustomSchema: [
|
[fakeCustomSchemaName]: [
|
||||||
{
|
{
|
||||||
key: 'fakeName',
|
key: 'fakeName',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
@@ -100,6 +109,16 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.TASK_FAKE',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.TASK_FAKE',
|
||||||
sortable: true
|
sortable: true
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
[schemaWithVariable]: [
|
||||||
|
getDataColumnMock(),
|
||||||
|
getDataColumnMock({
|
||||||
|
id: 'variableColumnId',
|
||||||
|
customData: {
|
||||||
|
assignedVariableDefinitionIds: ['variableDefinitionId'],
|
||||||
|
columnType: ColumnDataType.processVariableColumn
|
||||||
|
}
|
||||||
|
})
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,11 +127,12 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
component.isColumnSchemaCreated$ = of(true).pipe(shareReplay(1));
|
component.isColumnSchemaCreated$ = of(true).pipe(shareReplay(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => fixture.destroy());
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('should use the default schemaColumn', () => {
|
it('should use the default schemaColumn', () => {
|
||||||
appConfig.config = Object.assign(appConfig.config, { 'adf-cloud-process-list': processListSchemaMock });
|
appConfig.config = Object.assign(appConfig.config, { 'adf-cloud-process-list': processListSchemaMock });
|
||||||
component.ngAfterContentInit();
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(component.columns).toBeDefined();
|
expect(component.columns).toBeDefined();
|
||||||
@@ -164,6 +184,7 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
it('should the payload contain the appVersion if it is defined', () => {
|
it('should the payload contain the appVersion if it is defined', () => {
|
||||||
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
component.appVersion = 1;
|
component.appVersion = 1;
|
||||||
|
component.ngAfterContentInit();
|
||||||
component.reload();
|
component.reload();
|
||||||
|
|
||||||
expect(component.requestNode.appVersion).toEqual('1');
|
expect(component.requestNode.appVersion).toEqual('1');
|
||||||
@@ -172,6 +193,7 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
it('should the payload contain all the app versions joined by a comma separator', () => {
|
it('should the payload contain all the app versions joined by a comma separator', () => {
|
||||||
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
component.appVersion = [1, 2, 3];
|
component.appVersion = [1, 2, 3];
|
||||||
|
component.ngAfterContentInit();
|
||||||
component.reload();
|
component.reload();
|
||||||
|
|
||||||
expect(component.requestNode.appVersion).toEqual('1,2,3');
|
expect(component.requestNode.appVersion).toEqual('1,2,3');
|
||||||
@@ -180,20 +202,21 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
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.reload();
|
component.reload();
|
||||||
|
|
||||||
expect(component.requestNode.appVersion).toEqual('');
|
expect(component.requestNode.appVersion).toEqual('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use the custom schemaColumn from app.config.json', () => {
|
it('should use the custom schemaColumn from app.config.json', () => {
|
||||||
component.presetColumn = 'fakeCustomSchema';
|
component.presetColumn = fakeCustomSchemaName;
|
||||||
component.ngAfterContentInit();
|
component.ngAfterContentInit();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.columns).toEqual(fakeCustomSchema);
|
expect(component.columns).toEqual(fakeCustomSchema);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch custom schemaColumn when the input presetColumn is defined', () => {
|
it('should fetch custom schemaColumn when the input presetColumn is defined', () => {
|
||||||
component.presetColumn = 'fakeCustomSchema';
|
component.presetColumn = fakeCustomSchemaName;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.columns).toBeDefined();
|
expect(component.columns).toBeDefined();
|
||||||
expect(component.columns.length).toEqual(2);
|
expect(component.columns.length).toEqual(2);
|
||||||
@@ -223,6 +246,7 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
component.appName = appName.currentValue;
|
component.appName = appName.currentValue;
|
||||||
|
component.ngAfterContentInit();
|
||||||
component.ngOnChanges({ appName });
|
component.ngOnChanges({ appName });
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
@@ -244,6 +268,7 @@ describe('ProcessListCloudComponent', () => {
|
|||||||
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);
|
||||||
|
component.ngAfterContentInit();
|
||||||
component.ngOnChanges({ appName });
|
component.ngOnChanges({ appName });
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -285,6 +310,41 @@ 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', () => {
|
||||||
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
|
spyOn(preferencesService, 'getPreferences').and.returnValue(of({
|
||||||
|
list: {
|
||||||
|
entries: []
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
component.ngAfterContentInit();
|
||||||
|
component.reload();
|
||||||
|
|
||||||
|
expect(component.requestNode.variableDefinitions).not.toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should request process variable if column for process variable is displayed', () => {
|
||||||
|
component.presetColumn = schemaWithVariable;
|
||||||
|
|
||||||
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
|
spyOn(preferencesService, 'getPreferences').and.returnValue(of({
|
||||||
|
list: {
|
||||||
|
entries: [{
|
||||||
|
entry: {
|
||||||
|
key: ProcessListCloudPreferences.columnsVisibility,
|
||||||
|
value: '{"variableColumnId":true, "2":true}'
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
component.ngAfterContentInit();
|
||||||
|
component.reload();
|
||||||
|
|
||||||
|
expect(component.requestNode.variableDefinitions).toEqual(['variableDefinitionId']);
|
||||||
|
});
|
||||||
|
|
||||||
it('should reload tasks when reload() is called', (done) => {
|
it('should reload tasks when reload() is called', (done) => {
|
||||||
component.appName = 'fake';
|
component.appName = 'fake';
|
||||||
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
spyOn(processListCloudService, 'getProcessByRequest').and.returnValue(of(fakeProcessCloudList));
|
||||||
|
@@ -21,14 +21,17 @@ import { DataTableSchema, PaginatedComponent,
|
|||||||
UserPreferencesService, PaginationModel,
|
UserPreferencesService, PaginationModel,
|
||||||
UserPreferenceValues, DataRowEvent, CustomLoadingContentTemplateDirective, DataCellEvent, DataRowActionEvent, DataTableComponent, DataColumn } from '@alfresco/adf-core';
|
UserPreferenceValues, DataRowEvent, CustomLoadingContentTemplateDirective, DataCellEvent, DataRowActionEvent, DataTableComponent, DataColumn } from '@alfresco/adf-core';
|
||||||
import { ProcessListCloudService } from '../services/process-list-cloud.service';
|
import { ProcessListCloudService } from '../services/process-list-cloud.service';
|
||||||
import { BehaviorSubject, combineLatest } from 'rxjs';
|
import { BehaviorSubject, of } from 'rxjs';
|
||||||
import { processCloudPresetsDefaultModel } from '../models/process-cloud-preset.model';
|
import { processCloudPresetsDefaultModel } from '../models/process-cloud-preset.model';
|
||||||
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
||||||
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
import { PreferenceCloudServiceInterface } from '../../../services/preference-cloud.interface';
|
||||||
import { PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
import { PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN } from '../../../services/cloud-token.service';
|
||||||
import { ProcessListCloudPreferences } from '../models/process-cloud-preferences';
|
import { ProcessListCloudPreferences } from '../models/process-cloud-preferences';
|
||||||
|
import { ColumnDataType } from '../../../models/column-data-type.model';
|
||||||
|
import { ProcessListDatatableAdapter } from '../datatable/process-list-datatable-adapter';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
|
||||||
const PRESET_KEY = 'adf-cloud-process-list.presets';
|
const PRESET_KEY = 'adf-cloud-process-list.presets';
|
||||||
|
|
||||||
@@ -38,7 +41,7 @@ const PRESET_KEY = 'adf-cloud-process-list.presets';
|
|||||||
styleUrls: ['./process-list-cloud.component.scss'],
|
styleUrls: ['./process-list-cloud.component.scss'],
|
||||||
encapsulation: ViewEncapsulation.None
|
encapsulation: ViewEncapsulation.None
|
||||||
})
|
})
|
||||||
export class ProcessListCloudComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
export class ProcessListCloudComponent extends DataTableSchema<ProcessListDataColumnCustomData> implements OnChanges, AfterContentInit, PaginatedComponent {
|
||||||
@ViewChild(DataTableComponent)
|
@ViewChild(DataTableComponent)
|
||||||
dataTable: DataTableComponent;
|
dataTable: DataTableComponent;
|
||||||
|
|
||||||
@@ -201,6 +204,7 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
rows: any[] = [];
|
rows: any[] = [];
|
||||||
formattedSorting: any[];
|
formattedSorting: any[];
|
||||||
requestNode: ProcessQueryCloudRequestModel;
|
requestNode: ProcessQueryCloudRequestModel;
|
||||||
|
dataAdapter: ProcessListDatatableAdapter;
|
||||||
|
|
||||||
private defaultSorting = { key: 'startDate', direction: 'desc' };
|
private defaultSorting = { key: 'startDate', direction: 'desc' };
|
||||||
|
|
||||||
@@ -231,7 +235,7 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
columnsOrder: columnsOrder ? JSON.parse(columnsOrder.entry.value) : undefined,
|
columnsOrder: columnsOrder ? JSON.parse(columnsOrder.entry.value) : undefined,
|
||||||
columnsVisibility: columnsVisibility ? JSON.parse(columnsVisibility.entry.value) : undefined
|
columnsVisibility: columnsVisibility ? JSON.parse(columnsVisibility.entry.value) : this.columnsVisibility
|
||||||
};
|
};
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
@@ -262,24 +266,29 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.requestNode = this.createRequestNode();
|
if (this.appName || this.appName === '') {
|
||||||
if (this.requestNode.appName || this.requestNode.appName === '') {
|
this.load();
|
||||||
this.load(this.requestNode);
|
|
||||||
} else {
|
} else {
|
||||||
this.rows = [];
|
this.rows = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private load(requestNode: ProcessQueryCloudRequestModel) {
|
private load() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
|
||||||
combineLatest([
|
this.isColumnSchemaCreated$.pipe(
|
||||||
this.processListCloudService.getProcessByRequest(requestNode),
|
take(1),
|
||||||
this.isColumnSchemaCreated$
|
switchMap(() => of(this.createRequestNode())),
|
||||||
]).pipe(
|
tap((requestNode) => this.requestNode = requestNode),
|
||||||
take(1)
|
switchMap((requestNode) => this.processListCloudService.getProcessByRequest(requestNode))
|
||||||
).subscribe(([processes]) => {
|
).subscribe((processes) => {
|
||||||
this.rows = processes.list.entries;
|
this.rows = this.processListCloudService.createRowsViewModel(
|
||||||
|
processes.list.entries,
|
||||||
|
this.columns
|
||||||
|
);
|
||||||
|
|
||||||
|
this.dataAdapter = new ProcessListDatatableAdapter(this.rows, this.columns);
|
||||||
|
|
||||||
this.success.emit(processes);
|
this.success.emit(processes);
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.pagination.next(processes.list.pagination);
|
this.pagination.next(processes.list.pagination);
|
||||||
@@ -359,6 +368,7 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
this.createColumns();
|
this.createColumns();
|
||||||
|
this.reload();
|
||||||
|
|
||||||
if (this.appName) {
|
if (this.appName) {
|
||||||
this.cloudPreferenceService.updatePreference(
|
this.cloudPreferenceService.updatePreference(
|
||||||
@@ -427,8 +437,10 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
suspendedFrom: this.suspendedFrom,
|
suspendedFrom: this.suspendedFrom,
|
||||||
suspendedTo: this.suspendedTo,
|
suspendedTo: this.suspendedTo,
|
||||||
completedDate: this.completedDate,
|
completedDate: this.completedDate,
|
||||||
sorting: this.sorting
|
sorting: this.sorting,
|
||||||
|
variableDefinitions: this.getRequestNodeVariableIds()
|
||||||
};
|
};
|
||||||
|
|
||||||
return new ProcessQueryCloudRequestModel(requestNode);
|
return new ProcessQueryCloudRequestModel(requestNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,4 +466,16 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan
|
|||||||
isValidSorting(sorting: ProcessListCloudSortingModel[]) {
|
isValidSorting(sorting: ProcessListCloudSortingModel[]) {
|
||||||
return sorting.length && sorting[0].orderBy && sorting[0].direction;
|
return sorting.length && sorting[0].orderBy && sorting[0].direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getRequestNodeVariableIds(): string[] | undefined {
|
||||||
|
const displayedVariableColumns = this.columns
|
||||||
|
.filter(column =>
|
||||||
|
column.customData?.columnType === ColumnDataType.processVariableColumn &&
|
||||||
|
column.isHidden !== true
|
||||||
|
)
|
||||||
|
.map(column => column.customData.assignedVariableDefinitionIds)
|
||||||
|
.reduce((allIds, ids) => [...ids, ...allIds], []);
|
||||||
|
|
||||||
|
return displayedVariableColumns.length ? displayedVariableColumns : undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,53 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { DataColumn, DataRow, getDataColumnMock } from '@alfresco/adf-core';
|
||||||
|
import { ColumnDataType } from '../../../models/column-data-type.model';
|
||||||
|
import { getProcessInstanceVariableMock } from '../mock/process-instance-variable.mock';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-cloud-view.model';
|
||||||
|
import { ProcessListDatatableAdapter } from './process-list-datatable-adapter';
|
||||||
|
|
||||||
|
describe('ProcessListDatatableAdapter', () => {
|
||||||
|
it('should get proepr type for column', () => {
|
||||||
|
const viewModel: ProcessInstanceCloudListViewModel = {
|
||||||
|
id: '1',
|
||||||
|
variablesMap: {
|
||||||
|
columnDisplayName1: getProcessInstanceVariableMock({ type: 'number' })
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const row: DataRow = {
|
||||||
|
getValue: () => {},
|
||||||
|
hasValue: () => true,
|
||||||
|
isSelected: false,
|
||||||
|
obj: viewModel
|
||||||
|
};
|
||||||
|
|
||||||
|
const column: DataColumn<ProcessListDataColumnCustomData> = getDataColumnMock({
|
||||||
|
title: 'columnDisplayName1',
|
||||||
|
customData: {
|
||||||
|
assignedVariableDefinitionIds: ['1'],
|
||||||
|
columnType: ColumnDataType.processVariableColumn
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const adapter = new ProcessListDatatableAdapter([], []);
|
||||||
|
|
||||||
|
expect(adapter.getColumnType(row, column)).toBe('number');
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,23 @@
|
|||||||
|
import { DataColumn, DataRow, ObjectDataTableAdapter } from '@alfresco/adf-core';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
import { ColumnDataType } from '../../../models/column-data-type.model';
|
||||||
|
import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-cloud-view.model';
|
||||||
|
|
||||||
|
export class ProcessListDatatableAdapter extends ObjectDataTableAdapter {
|
||||||
|
constructor(
|
||||||
|
data: ProcessInstanceCloudListViewModel[],
|
||||||
|
schema: DataColumn<ProcessListDataColumnCustomData>[]
|
||||||
|
) {
|
||||||
|
super(data, schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
getColumnType(row: DataRow, col: DataColumn<ProcessListDataColumnCustomData>): string {
|
||||||
|
if (col.customData?.columnType === ColumnDataType.processVariableColumn) {
|
||||||
|
const variableDisplayName = col.title;
|
||||||
|
const columnType = row.obj.variablesMap?.[variableDisplayName]?.type;
|
||||||
|
return columnType ?? 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getColumnType(row, col);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
import { ProcessInstanceVariable } from '../../../models/process-instance-variable.model';
|
||||||
|
|
||||||
|
export const getProcessInstanceVariableMock = (variable: Partial<ProcessInstanceVariable> = {}): ProcessInstanceVariable => ({
|
||||||
|
id: 1,
|
||||||
|
variableDefinitionId: 'variableDefinitionId',
|
||||||
|
value: 'value',
|
||||||
|
appName: 'appName',
|
||||||
|
createTime: 'createTime',
|
||||||
|
lastUpdatedTime: 'lastUpdatedTime',
|
||||||
|
markedAsDeleted: false,
|
||||||
|
name: 'name',
|
||||||
|
processInstanceId: 'processInstanceId',
|
||||||
|
serviceFullName: 'serviceFullName',
|
||||||
|
serviceName: 'serviceName',
|
||||||
|
serviceVersion: 'serviceVersion',
|
||||||
|
taskVariable: false,
|
||||||
|
type: 'text',
|
||||||
|
...variable
|
||||||
|
});
|
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ObjectDataColumn } from '@alfresco/adf-core';
|
import { ObjectDataColumn } from '@alfresco/adf-core';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
|
||||||
export const fakeProcessCloudList = {
|
export const fakeProcessCloudList = {
|
||||||
list: {
|
list: {
|
||||||
@@ -34,7 +35,8 @@ export const fakeProcessCloudList = {
|
|||||||
status: 'RUNNING',
|
status: 'RUNNING',
|
||||||
lastModified: 1540381146276,
|
lastModified: 1540381146276,
|
||||||
lastModifiedTo: null,
|
lastModifiedTo: null,
|
||||||
lastModifiedFrom: null
|
lastModifiedFrom: null,
|
||||||
|
variables: [{ id: 'variableId', value: 'variableValue'}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,13 +86,13 @@ export const fakeProcessCloudList = {
|
|||||||
|
|
||||||
export const fakeCustomSchema =
|
export const fakeCustomSchema =
|
||||||
[
|
[
|
||||||
new ObjectDataColumn({
|
new ObjectDataColumn<ProcessListDataColumnCustomData>({
|
||||||
key: 'fakeName',
|
key: 'fakeName',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.FAKE',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.FAKE',
|
||||||
sortable: true
|
sortable: true
|
||||||
}),
|
}),
|
||||||
new ObjectDataColumn({
|
new ObjectDataColumn<ProcessListDataColumnCustomData>({
|
||||||
key: 'fakeTaskName',
|
key: 'fakeTaskName',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.TASK_FAKE',
|
title: 'ADF_CLOUD_TASK_LIST.PROPERTIES.TASK_FAKE',
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
export interface ProcessListDataColumnCustomData {
|
||||||
|
assignedVariableDefinitionIds: string[];
|
||||||
|
columnType: string;
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ProcessInstanceVariable } from '../../../models/process-instance-variable.model';
|
||||||
|
import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model';
|
||||||
|
|
||||||
|
export interface ProcessInstanceCloudListViewModel extends ProcessInstanceCloud {
|
||||||
|
variablesMap?: {
|
||||||
|
[variableDisplayName: string]: ProcessInstanceVariable;
|
||||||
|
};
|
||||||
|
}
|
@@ -42,6 +42,8 @@ export class ProcessQueryCloudRequestModel {
|
|||||||
maxItems: number;
|
maxItems: number;
|
||||||
skipCount: number;
|
skipCount: number;
|
||||||
sorting?: ProcessListCloudSortingModel[];
|
sorting?: ProcessListCloudSortingModel[];
|
||||||
|
variableDefinitions?: string[];
|
||||||
|
|
||||||
constructor(obj?: any) {
|
constructor(obj?: any) {
|
||||||
if (obj) {
|
if (obj) {
|
||||||
this.appName = obj.appName;
|
this.appName = obj.appName;
|
||||||
@@ -68,6 +70,7 @@ export class ProcessQueryCloudRequestModel {
|
|||||||
this.maxItems = obj.maxItems;
|
this.maxItems = obj.maxItems;
|
||||||
this.skipCount = obj.skipCount;
|
this.skipCount = obj.skipCount;
|
||||||
this.sorting = obj.sorting;
|
this.sorting = obj.sorting;
|
||||||
|
this.variableDefinitions = obj.variableDefinitions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,10 +15,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { fakeAsync, TestBed } from '@angular/core/testing';
|
||||||
import { setupTestBed, AlfrescoApiService } from '@alfresco/adf-core';
|
import { setupTestBed, AlfrescoApiService, getDataColumnMock } from '@alfresco/adf-core';
|
||||||
import { ProcessListCloudService } from './process-list-cloud.service';
|
import { ProcessListCloudService } from './process-list-cloud.service';
|
||||||
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
||||||
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
|
||||||
|
import { ProcessInstanceVariable } from '../../../models/process-instance-variable.model';
|
||||||
|
import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-cloud-view.model';
|
||||||
|
import { ProcessInstanceCloud } from '../../public-api';
|
||||||
|
import { getProcessInstanceVariableMock } from '../mock/process-instance-variable.mock';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
import { ColumnDataType } from '../../../models/column-data-type.model';
|
||||||
|
|
||||||
describe('ProcessListCloudService', () => {
|
describe('ProcessListCloudService', () => {
|
||||||
let service: ProcessListCloudService;
|
let service: ProcessListCloudService;
|
||||||
@@ -98,4 +104,35 @@ describe('ProcessListCloudService', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should map to view model', () => {
|
||||||
|
const processInstanceVariable: ProcessInstanceVariable = getProcessInstanceVariableMock({
|
||||||
|
variableDefinitionId: '5c75b259-dc59-11ec-aa89-fed162b97957'
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnTitle = 'columnTitle';
|
||||||
|
const column = getDataColumnMock<ProcessListDataColumnCustomData>({
|
||||||
|
title: columnTitle,
|
||||||
|
customData: {
|
||||||
|
assignedVariableDefinitionIds: ['5c75b259-dc59-11ec-aa89-fed162b97957'],
|
||||||
|
columnType: ColumnDataType.processVariableColumn
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const processInstance: ProcessInstanceCloud = {
|
||||||
|
id: 'id',
|
||||||
|
variables: [processInstanceVariable]
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedViewModel: ProcessInstanceCloudListViewModel = {
|
||||||
|
...processInstance,
|
||||||
|
variablesMap: {
|
||||||
|
[columnTitle]: processInstanceVariable
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const viewModel = service.createRowsViewModel([processInstance], [column]);
|
||||||
|
|
||||||
|
expect(viewModel).toEqual([expectedViewModel]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -15,12 +15,15 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf-core';
|
import { AlfrescoApiService, AppConfigService, DataColumn, DataColumnType, LogService } from '@alfresco/adf-core';
|
||||||
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Observable, throwError } from 'rxjs';
|
||||||
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model';
|
||||||
import { BaseCloudService } from '../../../services/base-cloud.service';
|
import { BaseCloudService } from '../../../services/base-cloud.service';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
|
import { ProcessInstanceCloudListViewModel } from '../models/perocess-instance-cloud-view.model';
|
||||||
|
import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model';
|
||||||
|
import { ProcessListDataColumnCustomData } from '../models/data-column-custom-data';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ProcessListCloudService extends BaseCloudService {
|
export class ProcessListCloudService extends BaseCloudService {
|
||||||
@@ -62,6 +65,51 @@ export class ProcessListCloudService extends BaseCloudService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createRowsViewModel(
|
||||||
|
processes: ProcessInstanceCloud[] = [],
|
||||||
|
columnsSchema: DataColumn<ProcessListDataColumnCustomData>[]
|
||||||
|
): ProcessInstanceCloudListViewModel[] {
|
||||||
|
const columnsByVariableId = columnsSchema
|
||||||
|
.filter(column => !!column.customData)
|
||||||
|
.reduce<{ [variableId: string]: string }>((columnsByVariable, column) => {
|
||||||
|
const columnTitle = column.title;
|
||||||
|
const variableIds = column.customData.assignedVariableDefinitionIds;
|
||||||
|
|
||||||
|
variableIds.forEach((variableId) => {
|
||||||
|
columnsByVariable[variableId] = columnTitle;
|
||||||
|
});
|
||||||
|
return columnsByVariable;
|
||||||
|
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
const rowsViewModel = processes.map((process) => {
|
||||||
|
if (!process.variables?.length) {
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
const variablesMap = (process.variables ?? []).reduce((variableAccumulator, variable) => {
|
||||||
|
const processVariableDefinitionId = variable.variableDefinitionId;
|
||||||
|
|
||||||
|
const column = columnsByVariableId[processVariableDefinitionId];
|
||||||
|
if (column) {
|
||||||
|
variableAccumulator[column] = {
|
||||||
|
...variable,
|
||||||
|
type: this.mapProcessVariableTypes(variable.type)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return variableAccumulator;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return {
|
||||||
|
...process,
|
||||||
|
variablesMap
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return rowsViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
protected isPropertyValueValid(requestNode: any, property: string): boolean {
|
protected isPropertyValueValid(requestNode: any, property: string): boolean {
|
||||||
return requestNode[property] !== '' && requestNode[property] !== null && requestNode[property] !== undefined;
|
return requestNode[property] !== '' && requestNode[property] !== null && requestNode[property] !== undefined;
|
||||||
}
|
}
|
||||||
@@ -73,7 +121,7 @@ export class ProcessListCloudService extends BaseCloudService {
|
|||||||
if (requestNode.hasOwnProperty(property) &&
|
if (requestNode.hasOwnProperty(property) &&
|
||||||
!this.isExcludedField(property) &&
|
!this.isExcludedField(property) &&
|
||||||
this.isPropertyValueValid(requestNode, property)) {
|
this.isPropertyValueValid(requestNode, property)) {
|
||||||
queryParam[property] = requestNode[property];
|
queryParam[property] = this.getQueryParamValueFromRequestNode(requestNode, property as keyof ProcessQueryCloudRequestModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +132,17 @@ export class ProcessListCloudService extends BaseCloudService {
|
|||||||
return queryParam;
|
return queryParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getQueryParamValueFromRequestNode(
|
||||||
|
requestNode: ProcessQueryCloudRequestModel,
|
||||||
|
property: keyof ProcessQueryCloudRequestModel
|
||||||
|
) {
|
||||||
|
if (property === 'variableDefinitions' && requestNode[property]?.length > 0) {
|
||||||
|
return `${requestNode[property].map(variableId => variableId).join(',')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestNode[property];
|
||||||
|
}
|
||||||
|
|
||||||
protected buildFilterForAllStatus(): string[] {
|
protected buildFilterForAllStatus(): string[] {
|
||||||
return ['RUNNING', 'SUSPENDED', 'CANCELLED', 'COMPLETED'];
|
return ['RUNNING', 'SUSPENDED', 'CANCELLED', 'COMPLETED'];
|
||||||
}
|
}
|
||||||
@@ -105,4 +164,18 @@ export class ProcessListCloudService extends BaseCloudService {
|
|||||||
}
|
}
|
||||||
return encodeURI(finalSorting);
|
return encodeURI(finalSorting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private mapProcessVariableTypes(variableType: string): DataColumnType {
|
||||||
|
switch (variableType) {
|
||||||
|
case 'boolean':
|
||||||
|
case 'integer':
|
||||||
|
case 'string':
|
||||||
|
return 'text';
|
||||||
|
case 'date':
|
||||||
|
case 'datetime':
|
||||||
|
return 'date';
|
||||||
|
default:
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ProcessInstanceVariable } from '../../../models/process-instance-variable.model';
|
||||||
export interface ProcessInstanceCloud {
|
export interface ProcessInstanceCloud {
|
||||||
appName?: string;
|
appName?: string;
|
||||||
id?: string;
|
id?: string;
|
||||||
@@ -28,4 +29,5 @@ export interface ProcessInstanceCloud {
|
|||||||
processDefinitionId?: string;
|
processDefinitionId?: string;
|
||||||
processDefinitionKey?: string;
|
processDefinitionKey?: string;
|
||||||
processDefinitionName?: string;
|
processDefinitionName?: string;
|
||||||
|
variables?: ProcessInstanceVariable[];
|
||||||
}
|
}
|
||||||
|
@@ -42,11 +42,11 @@ export class StartProcessCloudService extends BaseCloudService {
|
|||||||
* @param appName Name of the target app
|
* @param appName Name of the target app
|
||||||
* @returns Array of process definitions
|
* @returns Array of process definitions
|
||||||
*/
|
*/
|
||||||
getProcessDefinitions(appName: string): Observable<ProcessDefinitionCloud[]> {
|
getProcessDefinitions(appName: string, queryParams?: { include: 'variables' }): Observable<ProcessDefinitionCloud[]> {
|
||||||
if (appName || appName === '') {
|
if (appName || appName === '') {
|
||||||
const url = `${this.getBasePath(appName)}/rb/v1/process-definitions`;
|
const url = `${this.getBasePath(appName)}/rb/v1/process-definitions`;
|
||||||
|
|
||||||
return this.get(url).pipe(
|
return this.get(url, queryParams).pipe(
|
||||||
map((res: any) => res.list.entries.map((processDefs) => new ProcessDefinitionCloud(processDefs.entry)))
|
map((res: any) => res.list.entries.map((processDefs) => new ProcessDefinitionCloud(processDefs.entry)))
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -32,3 +32,5 @@ export * from './lib/models/application-version.model';
|
|||||||
export * from './lib/models/engine-event-cloud.model';
|
export * from './lib/models/engine-event-cloud.model';
|
||||||
export * from './lib/models/filter-cloud-model';
|
export * from './lib/models/filter-cloud-model';
|
||||||
export * from './lib/models/task-list-sorting.model';
|
export * from './lib/models/task-list-sorting.model';
|
||||||
|
export * from './lib/models/column-data-type.model';
|
||||||
|
export * from './lib/models/process-instance-variable.model';
|
||||||
|
Reference in New Issue
Block a user