From bc5208b767bceb3d8ab9a8778030e4f996f1bc1b Mon Sep 17 00:00:00 2001 From: siva kumar Date: Wed, 13 Mar 2019 22:40:19 +0530 Subject: [PATCH] [ADF-3977] EditProcessComponent - Be able to change the sort and actions (#4250) * [ADF-3883] Improve edit-process-filter-cloud by adding inputs to control filters, sort and actions * Provided an input to pass sort properties * Provided an input to pass filter actions * Provided a way to configure sort properties and actions * * Updated unit tests to the recent changes * Fixed order should be visible if sort as been added to the config * Fixed if lastModified if defined the component should show the range lastModifiedTo lastModifiedFrom * Updated doc * * Removed ProcessFilterActionType* Renamed state to status* Refactored edit-process-filter * Updated doc * * After rebase * * Fixed editProcessFilter e2e tests. * * Removed unwanted comment * * After rebase * * After rebase * * After rebase --- demo-shell/src/app.config.json | 6 + .../cloud/processes-cloud-demo.component.html | 4 +- .../cloud/processes-cloud-demo.component.ts | 6 +- .../edit-process-filter-cloud.component.md | 101 ++++++++- .../editProcessFilterCloudComponent.ts | 12 +- .../process-custom-filters.e2e.ts | 4 +- .../edit-process-filter-cloud.component.html | 26 +-- ...dit-process-filter-cloud.component.spec.ts | 167 +++++++++++---- .../edit-process-filter-cloud.component.ts | 198 ++++++++++++++---- .../process-filters-cloud.component.spec.ts | 6 +- .../models/process-filter-cloud.model.ts | 17 +- .../services/process-filter-cloud.service.ts | 6 +- 12 files changed, 425 insertions(+), 128 deletions(-) diff --git a/demo-shell/src/app.config.json b/demo-shell/src/app.config.json index e983422944..0143585c40 100644 --- a/demo-shell/src/app.config.json +++ b/demo-shell/src/app.config.json @@ -575,6 +575,12 @@ "state", "assignment", "sort", "order" ] }, + "adf-edit-process-filter": { + "filterProperties": [ "status", "sort", "order", "processName" ], + "sortProperties": [ "id", "name", "status", "startDate" ], + "actions": ["save", "saveAs", "delete"] + + }, "content-metadata": { "presets": { "default": { diff --git a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.html b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.html index a9e7b786e1..c81c7c78d2 100644 --- a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.html +++ b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.html @@ -2,7 +2,9 @@ diff --git a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts index 9ff71c4c4c..99ec46a3c6 100644 --- a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts +++ b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts @@ -33,8 +33,8 @@ import { CloudLayoutService } from './services/cloud-layout.service'; }) export class ProcessesCloudDemoComponent implements OnInit { - public static ACTION_SAVE_AS = 'SAVE_AS'; - static PROCESS_FILTER_PROPERTY_KEYS = 'adf-edit-process-filter.properties'; + public static ACTION_SAVE_AS = 'saveAs'; + static PROCESS_FILTER_PROPERTY_KEYS = 'adf-edit-process-filter'; @ViewChild('processCloud') processCloud: ProcessListCloudComponent; @@ -52,7 +52,7 @@ export class ProcessesCloudDemoComponent implements OnInit { selectionMode: string; selectedRows: string[] = []; testingMode: boolean; - processFilterProperties: any[] = []; + processFilterProperties: any = { filterProperties: [], sortProperties: [], actions: [] }; editedFilter: ProcessFilterCloudModel; diff --git a/docs/process-services-cloud/edit-process-filter-cloud.component.md b/docs/process-services-cloud/edit-process-filter-cloud.component.md index b584f6c63f..4a3d8e1ab5 100644 --- a/docs/process-services-cloud/edit-process-filter-cloud.component.md +++ b/docs/process-services-cloud/edit-process-filter-cloud.component.md @@ -20,6 +20,8 @@ Shows Process Filter Details. - [Details](#details) - [Editing APS2 process filters](#editing-aps2-process-filters) - [Filter properties](#filter-properties) + - [Sort properties](#sort-properties) + - [Action properties](#action-properties) - [See also](#see-also) ## Basic Usage @@ -40,17 +42,19 @@ Shows Process Filter Details. | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | +| actions | `string[]` | | List of sort actions. | | appName | `string` | | The name of the application. | | filterProperties | `string[]` | | List of process filter properties to display | | id | `string` | | Id of the process instance filter. | | showFilterActions | `boolean` | true | Toggles editing of process filter actions. | | showTitle | `boolean` | true | Toggles editing of the process filter title. | +| sortProperties | `string[]` | | List of sort properties to display. | ### Events | Name | Type | Description | | ---- | ---- | ----------- | -| action | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterActionType`](../../lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts)`>` | Emitted when a filter action occurs i.e Save, SaveAs, Delete. | +| action | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterAction`](../../lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts)`>` | Emitted when a filter action occurs i.e Save, SaveAs, Delete. | | filterChange | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterCloudModel`](../../lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts)`>` | Emitted when a process instance filter property changes. | ## Details @@ -78,23 +82,21 @@ given below: | **_processInstanceId_** | Process instance ID | | **_processName_** | Process name. | | **_initiator_** | ID of the user who initiated the process | -| **_state_** | Execution state of the process. | +| **_status_** | Execution status of the process. | | **_processDefinitionId_** | Process definition ID | | **_processDefinitionKey_** | Process definition key | -| **_lastModifiedFrom_** | Finds processes modified _after_ this date | -| **_lastModifiedTo_** | Finds processes modified _before_ this date | +| **_lastModified_** | Date the process was last modified. If lastModified defined the component will show the range **_lastModifiedTo_**, **_lastModifiedFrom_**| +| **_startDate_** | Date the process was started | | **_sort_** | Field on which the filter results will be sorted (doesn't participate in the filtering itself). Can be "id", "name", "status" or "startDate". | | **_order_** | Sort ordering of the filter results (this doesn't participate in the filtering itself) | -By default, the **_state_**, **_sort_** and **_order_** properties are +By default, the **_status_**, **_sort_** and **_order_** properties are displayed in the editor. However, you can also choose which properties to show using the `filterProperties` array. For example, the code below initializes the editor with the **_appName_**, **_processInstanceId_**, **_startDate_** and **_lastModified_** properties: ```ts -import { UserProcessModel } from '@alfresco/adf-core'; - export class SomeComponent implements OnInit { filterProperties: string[] = [ @@ -107,15 +109,94 @@ export class SomeComponent implements OnInit { console.log('On filter change: ', filter); } - onAction($event: ProcessFilterActionType) { + onAction($event: ProcessFilterAction) { console.log('Clicked action: ', $event); } ``` +```html + + +``` + With this configuration, only the four listed properties will be shown. -**Note:** Currently, the `sort` property has a limited set of properties -to choose from: **_id_**, **_name_**, **_status_** and **_startDate_**. +### Sort properties + +You can supply various _sort properties_ to sort the processes. + +By default, the **_id_**, **_name_**, **_status_** and **_startDate_** properties are +displayed in the editor. However, you can also choose which sort properties +to show using the `sortProperties` array. +For example, the code below initializes the editor with the **_startDate_** and **_lastModified_** properties: + +```ts +export class SomeComponent implements OnInit { + + sortProperties: string[] = [ + "startDate", + "lastModified"]; + + onFilterChange(filter: ProcessFilterCloudModel) { + console.log('On filter change: ', filter); + } + + onAction($event: ProcessFilterAction) { + console.log('Clicked action: ', $event); + } +``` + +```html + + +``` + +With this configuration, only the two listed sort properties will be shown. + +### Action properties + +You can supply various _actions_ to apply on process filter. + +| Name | Description | +| ---- | ----------- | +| **_save_** | Save process filter. | +| **_saveAs_** | Creates a new process filter. | +| **_delete_** | Delete process filter. | + +By default, the **_save_**, **_saveAs_** and **_delete_** actions are +displayed in the editor. However, you can also choose which actions to +show using the `actions` array. +For example, the code below initializes the editor with the **_save_** and **_delete_** actions: + +```ts +export class SomeComponent implements OnInit { + + actions: string[] = ['save', 'delete']; + + onFilterChange(filter: ProcessFilterCloudModel) { + console.log('On filter change: ', filter); + } + + onAction($event: ProcessFilterAction) { + console.log('Clicked action: ', $event); + } +``` + +```html + + +``` + +With this configuration, only the two actions will be shown. ## See also diff --git a/e2e/pages/adf/process-cloud/editProcessFilterCloudComponent.ts b/e2e/pages/adf/process-cloud/editProcessFilterCloudComponent.ts index 029e36b27b..e924e81516 100644 --- a/e2e/pages/adf/process-cloud/editProcessFilterCloudComponent.ts +++ b/e2e/pages/adf/process-cloud/editProcessFilterCloudComponent.ts @@ -46,13 +46,13 @@ export class EditProcessFilterCloudComponent { return this; } - setStateFilterDropDown(option) { - this.clickOnDropDownArrow('state'); + setStatusFilterDropDown(option) { + this.clickOnDropDownArrow('status'); - let stateElement = element.all(by.cssContainingText('mat-option span', option)).first(); - Util.waitUntilElementIsClickable(stateElement); - Util.waitUntilElementIsVisible(stateElement); - stateElement.click(); + let statusElement = element.all(by.cssContainingText('mat-option span', option)).first(); + Util.waitUntilElementIsClickable(statusElement); + Util.waitUntilElementIsVisible(statusElement); + statusElement.click(); return this; } diff --git a/e2e/process-services-cloud/process-custom-filters.e2e.ts b/e2e/process-services-cloud/process-custom-filters.e2e.ts index 7330c6688d..c90ba4c908 100644 --- a/e2e/process-services-cloud/process-custom-filters.e2e.ts +++ b/e2e/process-services-cloud/process-custom-filters.e2e.ts @@ -94,7 +94,7 @@ describe('Process list cloud', () => { }); it('[C290069] Should display processes ordered by name when Name is selected from sort dropdown', async() => { - processCloudDemoPage.editProcessFilterCloudComponent().clickCustomiseFilterHeader().setStateFilterDropDown('RUNNING') + processCloudDemoPage.editProcessFilterCloudComponent().clickCustomiseFilterHeader().setStatusFilterDropDown('RUNNING') .setSortFilterDropDown('NAME').setOrderFilterDropDown('ASC'); processCloudDemoPage.processListCloudComponent().getAllRowsNameColumn().then(function (list) { let initialList = list.slice(0); @@ -112,7 +112,7 @@ describe('Process list cloud', () => { }); it('[C291783] Should display processes ordered by id when Id is selected from sort dropdown', async() => { - processCloudDemoPage.editProcessFilterCloudComponent().clickCustomiseFilterHeader().setStateFilterDropDown('RUNNING') + processCloudDemoPage.editProcessFilterCloudComponent().clickCustomiseFilterHeader().setStatusFilterDropDown('RUNNING') .setSortFilterDropDown('ID').setOrderFilterDropDown('ASC'); processCloudDemoPage.processListCloudComponent().getDataTable().checkSpinnerIsDisplayed().checkSpinnerIsNotDisplayed(); processCloudDemoPage.getAllRowsByIdColumn().then(function (list) { diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.html b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.html index e242cc3f68..9b97456690 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.html +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.html @@ -6,14 +6,8 @@ {{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.TITLE' | translate}}
- - -
@@ -27,7 +21,7 @@ placeholder="{{processFilterProperty.label | translate}}" [formControlName]="processFilterProperty.key" [attr.data-automation-id]="'adf-cloud-edit-process-property-' + processFilterProperty.key"> - + {{ propertyOption.label }} @@ -49,14 +43,14 @@ placeholder="{{processFilterProperty.label | translate}}" [formControlName]="processFilterProperty.key" [attr.data-automation-id]="'adf-cloud-edit-process-property-' + processFilterProperty.key"> - - -
-
-
{{'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.DATE' | translate}}
- warning -
+ + +
+
+
{{'ADF_CLOUD_EDIT_PROCESS_FILTER.ERROR.DATE' | translate}}
+ warning
+
diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts index 7a780c196a..6892e7fbd3 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.spec.ts @@ -44,10 +44,9 @@ describe('EditProcessFilterCloudComponent', () => { name: 'FakeRunningProcess', icon: 'adjust', id: 'mock-process-filter-id', - state: 'RUNNING', + status: 'RUNNING', appName: 'mock-app-name', processDefinitionId: 'process-def-id', - assignment: 'fake-involved', order: 'ASC', sort: 'id' }); @@ -85,7 +84,7 @@ describe('EditProcessFilterCloudComponent', () => { expect(getProcessFilterByIdSpy).toHaveBeenCalled(); expect(component.processFilter.name).toEqual('FakeRunningProcess'); expect(component.processFilter.icon).toEqual('adjust'); - expect(component.processFilter.state).toEqual('RUNNING'); + expect(component.processFilter.status).toEqual('RUNNING'); expect(component.processFilter.order).toEqual('ASC'); expect(component.processFilter.sort).toEqual('id'); }); @@ -118,7 +117,7 @@ describe('EditProcessFilterCloudComponent', () => { it('should create editProcessFilter form', async(() => { fixture.detectChanges(); fixture.whenStable().then(() => { - const stateController = component.editProcessFilterForm.get('state'); + const stateController = component.editProcessFilterForm.get('status'); const sortController = component.editProcessFilterForm.get('sort'); const orderController = component.editProcessFilterForm.get('order'); expect(component.editProcessFilterForm).toBeDefined(); @@ -138,7 +137,7 @@ describe('EditProcessFilterCloudComponent', () => { expansionPanel.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - let saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + let saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]'); expect(saveButton.disabled).toBe(true); }); })); @@ -149,7 +148,7 @@ describe('EditProcessFilterCloudComponent', () => { expansionPanel.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - let saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + let saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]'); expect(saveButton.disabled).toBe(true); }); })); @@ -160,7 +159,7 @@ describe('EditProcessFilterCloudComponent', () => { expansionPanel.click(); fixture.detectChanges(); fixture.whenStable().then(() => { - let deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + let deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]'); expect(deleteButton.disabled).toBe(false); }); })); @@ -171,14 +170,14 @@ describe('EditProcessFilterCloudComponent', () => { let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); fixture.detectChanges(); - let stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"]'); + let stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"]'); let sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-sort"]'); let orderElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-order"]'); expect(stateElement).toBeDefined(); expect(sortElement).toBeDefined(); expect(orderElement).toBeDefined(); expect(stateElement.innerText.trim()).toBe('RUNNING'); - expect(sortElement.innerText.trim()).toBe('ID'); + expect(sortElement.innerText.trim()).toBe('Id'); expect(orderElement.innerText.trim()).toBe('ASC'); }); })); @@ -187,10 +186,10 @@ describe('EditProcessFilterCloudComponent', () => { fixture.detectChanges(); let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); - let stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"] .mat-select-trigger'); + let stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger'); stateElement.click(); fixture.detectChanges(); - const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]'); const options = fixture.debugElement.queryAll(By.css('.mat-option-text')); options[2].nativeElement.click(); fixture.detectChanges(); @@ -203,7 +202,7 @@ describe('EditProcessFilterCloudComponent', () => { fixture.detectChanges(); let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); - const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"] .mat-select-trigger'); + const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger'); stateElement.click(); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -237,6 +236,9 @@ describe('EditProcessFilterCloudComponent', () => { expect(orderOptions.length).toEqual(2); }); })); + }); + + describe('Process filterProperties', () => { it('should able to build a editProcessFilter form with default properties if input is empty', async(() => { let processFilterIDchange = new SimpleChange(undefined, 'mock-process-filter-id', true); @@ -244,12 +246,12 @@ describe('EditProcessFilterCloudComponent', () => { component.filterProperties = []; fixture.detectChanges(); fixture.whenStable().then(() => { - const stateController = component.editProcessFilterForm.get('state'); + const stateController = component.editProcessFilterForm.get('status'); const sortController = component.editProcessFilterForm.get('sort'); const orderController = component.editProcessFilterForm.get('order'); fixture.detectChanges(); expect(component.processFilterProperties).toBeDefined(); - expect(component.processFilterProperties.length).toBe(3); + expect(component.processFilterProperties.length).toBe(4); expect(component.editProcessFilterForm).toBeDefined(); expect(stateController).toBeDefined(); expect(sortController).toBeDefined(); @@ -259,18 +261,13 @@ describe('EditProcessFilterCloudComponent', () => { expect(orderController.value).toBe('ASC'); }); })); - }); - - describe('Process filterProperties', () => { - - beforeEach(() => { - component.filterProperties = ['appName', 'processInstanceId', 'processName']; - }); it('should able to fetch running applications when appName property defined in the input', async(() => { fixture.detectChanges(); let processFilterIDchange = new SimpleChange(undefined, 'mock-process-filter-id', true); component.ngOnChanges({'id': processFilterIDchange}); + fixture.detectChanges(); + component.filterProperties = ['appName', 'processName']; const appController = component.editProcessFilterForm.get('appName'); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -280,26 +277,54 @@ describe('EditProcessFilterCloudComponent', () => { }); })); - it('should able to build a editProcessFilter form with given input properties', async(() => { - fixture.detectChanges(); - getProcessFilterByIdSpy.and.returnValue({ appName: 'mock-app-name', processInstanceId: 'process-instance-id', processName: 'mock-process-name' }); + it('should able to filter filterProperties when input is defined', async(() => { + component.id = 'mock-process-filter-id'; let processFilterIDchange = new SimpleChange(undefined, 'mock-process-filter-id', true); component.ngOnChanges({'id': processFilterIDchange}); - fixture.detectChanges(); - const appController = component.editProcessFilterForm.get('appName'); - const processNameController = component.editProcessFilterForm.get('processName'); - const processInsIdController = component.editProcessFilterForm.get('processInstanceId'); + component.filterProperties = ['appName', 'processName']; fixture.detectChanges(); fixture.whenStable().then(() => { fixture.detectChanges(); - expect(getRunningApplicationsSpy).toHaveBeenCalled(); - expect(component.processFilterProperties).toBeDefined(); - expect(component.editProcessFilterForm).toBeDefined(); - expect(component.processFilterProperties.length).toBe(3); - expect(appController).toBeDefined(); - expect(processNameController).toBeDefined(); - expect(processInsIdController).toBeDefined(); - expect(appController.value).toBe('mock-app-name'); + expect(component.processFilterProperties.length).toBe(2); + }); + })); + }); + + describe('sort properties', () => { + + it('should display default sort properties', async(() => { + fixture.detectChanges(); + let processFilterIdchange = new SimpleChange(undefined, 'mock-process-filter-id', true); + component.ngOnChanges({ 'id': processFilterIdchange}); + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + let sortElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-sort"]'); + sortElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const sortController = component.editProcessFilterForm.get('sort'); + const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + expect(sortController).toBeDefined(); + expect(sortController.value).toBe('id'); + expect(sortOptions.length).toEqual(4); + }); + })); + + it('should display sort properties when sort properties are specified', async(() => { + component.sortProperties = ['id', 'processName', 'processDefinitionId']; + fixture.detectChanges(); + let processFilterIdchange = new SimpleChange(undefined, 'mock-process-filter-id', true); + component.ngOnChanges({ 'id': processFilterIdchange}); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const sortController = component.editProcessFilterForm.get('sort'); + const sortProperties = component.processFilterProperties[1].options; + fixture.detectChanges(); + expect(sortController).toBeDefined(); + expect(sortProperties.length).toBe(3); }); })); }); @@ -321,10 +346,10 @@ describe('EditProcessFilterCloudComponent', () => { const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); fixture.detectChanges(); - const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"] .mat-select-trigger'); + const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger'); stateElement.click(); fixture.detectChanges(); - const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]'); const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); stateOptions[2].nativeElement.click(); saveButton.click(); @@ -344,10 +369,10 @@ describe('EditProcessFilterCloudComponent', () => { const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); fixture.detectChanges(); - const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"] .mat-select-trigger'); + const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger'); stateElement.click(); fixture.detectChanges(); - const deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]'); deleteButton.click(); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -365,10 +390,10 @@ describe('EditProcessFilterCloudComponent', () => { const expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); expansionPanel.click(); fixture.detectChanges(); - const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-state"] .mat-select-trigger'); + const stateElement = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-cloud-edit-process-property-status"] .mat-select-trigger'); stateElement.click(); fixture.detectChanges(); - const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]'); const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); stateOptions[2].nativeElement.click(); fixture.detectChanges(); @@ -380,5 +405,63 @@ describe('EditProcessFilterCloudComponent', () => { expect(dialog.open).toHaveBeenCalled(); }); })); + + it('should display default filter actions', async(() => { + fixture.detectChanges(); + component.toggleFilterActions = true; + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + const saveAsButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]'); + const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]'); + const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]'); + expect(component.processFilterActions).toBeDefined(); + expect(component.processFilterActions.length).toBe(3); + expect(saveButton).toBeDefined(); + expect(saveAsButton).toBeDefined(); + expect(deleteButton).toBeDefined(); + expect(saveButton.disabled).toBeTruthy(); + expect(saveAsButton.disabled).toBeTruthy(false); + expect(deleteButton.disabled).toBe(false); + }); + })); + + it('should filter actions when input actions are specified', async(() => { + component.actions = ['save']; + fixture.detectChanges(); + let processFilterIDchange = new SimpleChange(undefined, 'mock-process-filter-id', true); + component.ngOnChanges({'id': processFilterIDchange}); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(component.processFilterActions).toBeDefined(); + expect(component.actions.length).toBe(1); + expect(component.processFilterActions.length).toBe(1); + }); + })); + + it('should display default filter actions when input is empty', async(() => { + fixture.detectChanges(); + component.actions = []; + component.toggleFilterActions = true; + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const saveAsButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-saveAs"]'); + const saveButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-save"]'); + const deleteButton = fixture.debugElement.nativeElement.querySelector('[data-automation-id="adf-filter-action-delete"]'); + expect(component.processFilterActions).toBeDefined(); + expect(component.processFilterActions.length).toBe(3); + expect(saveButton).toBeDefined(); + expect(saveAsButton).toBeDefined(); + expect(deleteButton).toBeDefined(); + expect(saveButton.disabled).toBeTruthy(); + expect(saveAsButton.disabled).toBeTruthy(false); + expect(deleteButton.disabled).toBe(false); + }); + })); }); }); diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts index 6039372a58..96e985fc32 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts @@ -23,7 +23,7 @@ import moment from 'moment-es6'; import { ApplicationInstanceModel } from '../../../app/models/application-instance.model'; import { AppsProcessCloudService } from '../../../app/services/apps-process-cloud.service'; -import { ProcessFilterCloudModel, ProcessFilterActionType, ProcessFilterProperties } from '../models/process-filter-cloud.model'; +import { ProcessFilterCloudModel, ProcessFilterProperties, ProcessFilterAction, ProcessFilterOptions } from '../models/process-filter-cloud.model'; import { TranslationService } from '@alfresco/adf-core'; import { ProcessFilterCloudService } from '../services/process-filter-cloud.service'; import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component'; @@ -35,12 +35,17 @@ import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud }) export class EditProcessFilterCloudComponent implements OnChanges { - public static ACTION_SAVE = 'SAVE'; - public static ACTION_SAVE_AS = 'SAVE_AS'; - public static ACTION_DELETE = 'DELETE'; + public static ACTION_SAVE = 'save'; + public static ACTION_SAVE_AS = 'saveAs'; + public static ACTION_DELETE = 'delete'; public static APPLICATION_NAME: string = 'appName'; public static APP_RUNNING_STATUS: string = 'Running'; - public static DEFAULT_PROCESS_FILTER_PROPERTIES = ['state', 'sort', 'order']; + public static LAST_MODIFIED: string = 'lastModified'; + public static SORT: string = 'sort'; + public static ORDER: string = 'order'; + public static DEFAULT_PROCESS_FILTER_PROPERTIES = ['status', 'sort', 'order']; + public static DEFAULT_SORT_PROPERTIES = ['id', 'name', 'status', 'startDate']; + public static DEFAULT_ACTIONS = ['save', 'saveAs', 'delete']; public FORMAT_DATE: string = 'DD/MM/YYYY'; /** The name of the application. */ @@ -53,7 +58,15 @@ export class EditProcessFilterCloudComponent implements OnChanges { /** List of process filter properties to display */ @Input() - filterProperties: string[] = EditProcessFilterCloudComponent.DEFAULT_PROCESS_FILTER_PROPERTIES; // default ['state', 'sort', 'order'] + filterProperties: string[] = EditProcessFilterCloudComponent.DEFAULT_PROCESS_FILTER_PROPERTIES; + + /** List of sort properties to display. */ + @Input() + sortProperties: string[] = EditProcessFilterCloudComponent.DEFAULT_SORT_PROPERTIES; + + /** List of sort actions. */ + @Input() + actions: string[] = EditProcessFilterCloudComponent.DEFAULT_ACTIONS; /** Toggles editing of process filter actions. */ @Input() @@ -69,18 +82,11 @@ export class EditProcessFilterCloudComponent implements OnChanges { /** Emitted when a filter action occurs i.e Save, SaveAs, Delete. */ @Output() - action: EventEmitter = new EventEmitter(); + action: EventEmitter = new EventEmitter(); processFilter: ProcessFilterCloudModel; changedProcessFilter: ProcessFilterCloudModel; - columns = [ - { value: 'id', label: 'ID' }, - { value: 'name', label: 'NAME' }, - { value: 'status', label: 'STATUS' }, - { value: 'startDate', label: 'START DATE' } - ]; - status = [ { label: 'ALL', value: '' }, { label: 'RUNNING', value: 'RUNNING' }, @@ -91,7 +97,8 @@ export class EditProcessFilterCloudComponent implements OnChanges { applicationNames: any[] = []; formHasBeenChanged = false; editProcessFilterForm: FormGroup; - processFilterProperties: any[] = []; + processFilterProperties: ProcessFilterProperties[] = []; + processFilterActions: ProcessFilterAction[] = []; toggleFilterActions: boolean = false; constructor( @@ -105,6 +112,7 @@ export class EditProcessFilterCloudComponent implements OnChanges { const id = changes['id']; if (id && id.currentValue !== id.previousValue) { this.processFilterProperties = this.createAndFilterProperties(); + this.processFilterActions = this.createAndFilterActions(); this.buildForm(this.processFilterProperties); } } @@ -145,7 +153,7 @@ export class EditProcessFilterCloudComponent implements OnChanges { }); } - createAndFilterProperties() { + createAndFilterProperties(): ProcessFilterProperties[] { this.checkMandatoryFilterProperties(); if (this.checkForApplicationNameProperty()) { this.applicationNames = []; @@ -153,7 +161,15 @@ export class EditProcessFilterCloudComponent implements OnChanges { } this.processFilter = this.retrieveProcessFilter(); const defaultProperties = this.createProcessFilterProperties(this.processFilter); - return defaultProperties.filter((filterProperty: ProcessFilterProperties) => this.isValidProperty(this.filterProperties, filterProperty)); + let filteredProperties = defaultProperties.filter((filterProperty: ProcessFilterProperties) => this.isValidProperty(this.filterProperties, filterProperty)); + if (!this.hasSortProperty()) { + filteredProperties = this.removeOrderProperty(filteredProperties); + } + if (this.hasLastModifiedProperty()) { + filteredProperties = [...filteredProperties, ...this.createLastModifiedProperty()]; + } + + return filteredProperties; } checkMandatoryFilterProperties() { @@ -170,6 +186,54 @@ export class EditProcessFilterCloudComponent implements OnChanges { return filterProperties ? filterProperties.indexOf(filterProperty.key) >= 0 : true; } + hasSortProperty(): boolean { + return this.filterProperties.indexOf(EditProcessFilterCloudComponent.SORT) >= 0; + } + + hasLastModifiedProperty(): boolean { + return this.filterProperties.indexOf(EditProcessFilterCloudComponent.LAST_MODIFIED) >= 0; + } + + removeOrderProperty(filteredProperties: ProcessFilterProperties[]) { + if (filteredProperties && filteredProperties.length > 0) { + const propertiesWithOutOrderProperty = filteredProperties.filter( + (property: ProcessFilterProperties) => { + return property.key !== EditProcessFilterCloudComponent.ORDER; + }); + return propertiesWithOutOrderProperty; + } + } + + createSortProperties(): any { + this.checkMandatorySortProperties(); + const sortProperties = this.sortProperties.map((property: string) => { + return { label: property.charAt(0).toUpperCase() + property.slice(1), value: property }; + }); + return sortProperties; + } + + checkMandatorySortProperties() { + if (this.sortProperties === undefined || this.sortProperties.length === 0) { + this.sortProperties = EditProcessFilterCloudComponent.DEFAULT_SORT_PROPERTIES; + } + } + + createAndFilterActions() { + this.checkMandatoryActions(); + const actions = this.createFilterActions(); + return actions.filter((action: ProcessFilterAction) => this.isValidAction(this.actions, action)); + } + + checkMandatoryActions() { + if (this.actions === undefined || this.actions.length === 0) { + this.actions = EditProcessFilterCloudComponent.DEFAULT_ACTIONS; + } + } + + private isValidAction(actions: string[], action: any): boolean { + return actions ? actions.indexOf(action.actionType) >= 0 : true; + } + isFormValid(): boolean { return this.editProcessFilterForm.valid; } @@ -220,27 +284,39 @@ export class EditProcessFilterCloudComponent implements OnChanges { }); } + executeFilterActions(action: ProcessFilterAction): void { + if (action.actionType === EditProcessFilterCloudComponent.ACTION_SAVE) { + this.save(action); + } else if (action.actionType === EditProcessFilterCloudComponent.ACTION_SAVE_AS) { + this.saveAs(action); + } else if (action.actionType === EditProcessFilterCloudComponent.ACTION_DELETE) { + this.delete(action); + } + } + /** * Save a process instance filter */ - onSave() { + save(saveAction: ProcessFilterAction) { this.processFilterCloudService.updateFilter(this.changedProcessFilter); - this.action.emit({ actionType: EditProcessFilterCloudComponent.ACTION_SAVE, filter: this.changedProcessFilter }); + saveAction.filter = this.changedProcessFilter; + this.action.emit(saveAction); this.formHasBeenChanged = this.compareFilters(this.changedProcessFilter, this.processFilter); } /** * Delete a process instance filter */ - onDelete() { + delete(deleteAction: ProcessFilterAction) { this.processFilterCloudService.deleteFilter(this.processFilter); - this.action.emit({ actionType: EditProcessFilterCloudComponent.ACTION_DELETE, filter: this.processFilter }); + deleteAction.filter = this.processFilter; + this.action.emit(deleteAction); } /** * Save As a process instance filter */ - onSaveAs() { + saveAs(saveAsAction: ProcessFilterAction) { const dialogRef = this.dialog.open(ProcessFilterDialogCloudComponent, { data: { name: this.translateService.instant(this.processFilter.name) @@ -260,7 +336,8 @@ export class EditProcessFilterCloudComponent implements OnChanges { }; const resultFilter: ProcessFilterCloudModel = Object.assign({}, this.changedProcessFilter, newFilter); this.processFilterCloudService.addFilter(resultFilter); - this.action.emit({ actionType: EditProcessFilterCloudComponent.ACTION_SAVE_AS, filter: resultFilter }); + saveAsAction.filter = resultFilter; + this.action.emit(saveAsAction); } }); } @@ -307,6 +384,55 @@ export class EditProcessFilterCloudComponent implements OnChanges { return property.type === 'text'; } + hasFormChanged(action: any): boolean { + if (action.actionType === EditProcessFilterCloudComponent.ACTION_SAVE) { + return !this.formHasBeenChanged; + } + if (action.actionType === EditProcessFilterCloudComponent.ACTION_SAVE_AS) { + return !this.formHasBeenChanged; + } + if (action.actionType === EditProcessFilterCloudComponent.ACTION_DELETE) { + return false; + } + } + + createFilterActions(): ProcessFilterAction[] { + return [ + new ProcessFilterAction({ + actionType: EditProcessFilterCloudComponent.ACTION_SAVE, + icon: 'save', + tooltip: 'ADF_CLOUD_EDIT_PROCESS_FILTER.TOOL_TIP.SAVE' + }), + new ProcessFilterAction({ + actionType: EditProcessFilterCloudComponent.ACTION_SAVE_AS, + icon: 'unarchive', + tooltip: 'ADF_CLOUD_EDIT_PROCESS_FILTER.TOOL_TIP.SAVE_AS' + }), + new ProcessFilterAction({ + actionType: EditProcessFilterCloudComponent.ACTION_DELETE, + icon: 'delete', + tooltip: 'ADF_CLOUD_EDIT_PROCESS_FILTER.TOOL_TIP.DELETE' + }) + ]; + } + + createLastModifiedProperty(): ProcessFilterProperties[] { + return [ + new ProcessFilterProperties({ + label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.LAST_MODIFIED_DATE_FORM', + type: 'date', + key: 'lastModifiedFrom', + value: '' + }), + new ProcessFilterProperties({ + label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.LAST_MODIFIED_TO', + type: 'date', + key: 'lastModifiedTo', + value: '' + }) + ]; + } + createProcessFilterProperties(currentProcessFilter: ProcessFilterCloudModel): ProcessFilterProperties[] { return [ new ProcessFilterProperties({ @@ -337,8 +463,8 @@ export class EditProcessFilterCloudComponent implements OnChanges { new ProcessFilterProperties({ label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.STATUS', type: 'select', - key: 'state', - value: currentProcessFilter.state || this.status[0].value, + key: 'status', + value: currentProcessFilter.status || this.status[0].value, options: this.status }), new ProcessFilterProperties({ @@ -353,24 +479,12 @@ export class EditProcessFilterCloudComponent implements OnChanges { key: 'processDefinitionKey', value: currentProcessFilter.processDefinitionKey || '' }), - new ProcessFilterProperties({ - label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.LAST_MODIFIED_DATE_FORM', - type: 'date', - key: 'lastModifiedFrom', - value: '' - }), - new ProcessFilterProperties({ - label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.LAST_MODIFIED_TO', - type: 'date', - key: 'lastModifiedTo', - value: '' - }), new ProcessFilterProperties({ label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.SORT', type: 'select', key: 'sort', - value: currentProcessFilter.sort || this.columns[0].value, - options: this.columns + value: currentProcessFilter.sort || this.createSortProperties[0].value, + options: this.createSortProperties() }), new ProcessFilterProperties({ label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DIRECTION', @@ -378,6 +492,12 @@ export class EditProcessFilterCloudComponent implements OnChanges { key: 'order', value: currentProcessFilter.order || this.directions[0].value, options: this.directions + }), + new ProcessFilterProperties({ + label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.START_DATE', + type: 'date', + key: 'startDate', + value: '' }) ]; } diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters-cloud.component.spec.ts index 115cbdafac..596be8c1a9 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/process-filters-cloud.component.spec.ts @@ -36,21 +36,21 @@ describe('ProcessFiltersCloudComponent', () => { name: 'FakeAllProcesses', icon: 'adjust', id: '10', - state: '' + status: '' }), new ProcessFilterCloudModel({ name: 'FakeRunningProcesses', key: 'FakeRunningProcesses', icon: 'inbox', id: '11', - state: 'RUNNING' + status: 'RUNNING' }), new ProcessFilterCloudModel({ name: 'FakeCompletedProcesses', key: 'completed-processes', icon: 'done', id: '12', - state: 'COMPLETED' + status: 'COMPLETED' }) ]; diff --git a/lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts b/lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts index 91ba964c0b..b0c120aec8 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/models/process-filter-cloud.model.ts @@ -24,7 +24,7 @@ export class ProcessFilterCloudModel { appName: string; processName: string; initiator: string; - state: string; + status: string; sort: string; order: string; processDefinitionId: string; @@ -45,7 +45,7 @@ export class ProcessFilterCloudModel { this.appName = obj.appName || null; this.processName = obj.processName || null; this.initiator = obj.initiator || null; - this.state = obj.state || null; + this.status = obj.status || null; this.sort = obj.sort || null; this.order = obj.order || null; this.processDefinitionId = obj.processDefinitionId || null; @@ -59,9 +59,20 @@ export class ProcessFilterCloudModel { } } -export interface ProcessFilterActionType { +export class ProcessFilterAction { actionType: string; + icon: string; + tooltip: string; filter: ProcessFilterCloudModel; + + constructor(obj?: any) { + if (obj) { + this.actionType = obj.actionType || null; + this.icon = obj.icon || null; + this.tooltip = obj.tooltip || null; + this.filter = obj.filter || null; + } + } } export interface ProcessFilterOptions { diff --git a/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.ts b/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.ts index afec6f1f1d..6d4894fa1e 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.ts @@ -142,7 +142,7 @@ export class ProcessFilterCloudService { icon: 'adjust', appName: appName, sort: 'startDate', - state: '', + status: '', order: 'DESC' }); } @@ -159,7 +159,7 @@ export class ProcessFilterCloudService { key: 'running-processes', appName: appName, sort: 'startDate', - state: 'RUNNING', + status: 'RUNNING', order: 'DESC' }); } @@ -176,7 +176,7 @@ export class ProcessFilterCloudService { key: 'completed-processes', appName: appName, sort: 'startDate', - state: 'COMPLETED', + status: 'COMPLETED', order: 'DESC' }); }