From 242884db2007593af16000955bf555c253cde493 Mon Sep 17 00:00:00 2001 From: siva kumar Date: Tue, 11 Dec 2018 20:31:12 +0530 Subject: [PATCH] [ADF-3799] Process Filter definition in a component APS2 (#4048) * * Generated EditProcessFilterComponent by cli * Added MatExpansionModule * * Added translation keys related to the editProcessFilterComponent * Updated editProcessFilterComponent * * Refactored EditProcessFilter component * Created delete , save and saveAs filter methods in the service * Generated ProcessDialog component * Exported process-cloud * Added Unit tests to the EditProcessFilter * * Added unit tests to the processFIlterDialog component* Refactored process-list-cloud-demo component * * Added editProcessFilter documentaion. * * Unified process filter cloud models * * Used new process-filter-cloud model * * Updated documentation * * Updated demo component * * Updated editProcessFilter unit tests * * After rebase* Fixed missing documentation * * Fixed conflicts * Rebased with dev branch * Fix import --- .../cloud/cloud-layout.component.ts | 9 +- .../cloud/processes-cloud-demo.component.html | 60 +--- .../cloud/processes-cloud-demo.component.ts | 99 +++--- .../edit-process-filter-cloud.component.png | Bin 0 -> 10722 bytes .../edit-process-filter-cloud.component.md | 50 +++ .../process-filters-cloud.component.md | 27 +- .../src/lib/i18n/en.json | 23 ++ .../models/process-filter-cloud.model.ts | 56 +--- .../lib/process-cloud/process-cloud.module.ts | 13 +- .../edit-process-filter-cloud.component.html | 60 ++++ .../edit-process-filter-cloud.component.scss | 0 ...dit-process-filter-cloud.component.spec.ts | 317 ++++++++++++++++++ .../edit-process-filter-cloud.component.ts | 189 +++++++++++ ...process-filter-dialog-cloud.component.html | 22 ++ ...process-filter-dialog-cloud.component.scss | 9 + ...cess-filter-dialog-cloud.component.spec.ts | 136 ++++++++ .../process-filter-dialog-cloud.component.ts | 66 ++++ .../process-filters-cloud.component.spec.ts | 28 +- .../process-filters-cloud.component.ts | 24 +- .../src/lib/process-cloud/public-api.ts | 2 + .../services/process-filter-cloud.service.ts | 97 ++++-- lib/process-services-cloud/src/public-api.ts | 1 + 22 files changed, 1071 insertions(+), 217 deletions(-) create mode 100644 docs/docassets/images/edit-process-filter-cloud.component.png create mode 100644 docs/process-services-cloud/edit-process-filter-cloud.component.md create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.html create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.scss create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.spec.ts create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.ts create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.html create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.scss create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.spec.ts create mode 100644 lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.ts diff --git a/demo-shell/src/app/components/app-layout/cloud/cloud-layout.component.ts b/demo-shell/src/app/components/app-layout/cloud/cloud-layout.component.ts index 6ecdbd403c..59f0b1bc02 100644 --- a/demo-shell/src/app/components/app-layout/cloud/cloud-layout.component.ts +++ b/demo-shell/src/app/components/app-layout/cloud/cloud-layout.component.ts @@ -46,12 +46,7 @@ export class CloudLayoutComponent implements OnInit { } onProcessFilterSelected(filter) { - const queryParams = { - status: filter.query.state, - filterName: filter.name, - sort: filter.query.sort, - order: filter.query.order - }; - this.router.navigate([`/cloud/${this.applicationName}/processes/`], { queryParams: queryParams }); + const currentFilter = Object.assign({}, filter); + this.router.navigate([`/cloud/${this.applicationName}/processes/`], { queryParams: currentFilter }); } } 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 e4dd1a318e..4fa568e229 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 @@ -1,57 +1,15 @@
- - - - - {{filterName | translate}} - - - {{ 'PROCESS_LIST_CLOUD_DEMO.CUSTOMIZE_FILTERS' | translate}} - - -
- - - - ALL - - - RUNNING - - - COMPLETED - - - - - - Select a column - - {{column.label}} - - - - - - Select a direction - - ASC - - - DESC - - - -
- -
-
-
+ + +
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 7169781d8f..2e3f074fb9 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 @@ -16,9 +16,15 @@ */ import { Component, ViewChild, OnInit } from '@angular/core'; -import { ProcessListCloudComponent } from '@alfresco/adf-process-services-cloud'; +import { + ProcessListCloudComponent, + ProcessFilterCloudModel, + EditProcessFilterCloudComponent, + ProcessListCloudSortingModel, + ProcessFiltersCloudComponent +} from '@alfresco/adf-process-services-cloud'; + import { ActivatedRoute } from '@angular/router'; -import { FormControl } from '@angular/forms'; import { UserPreferencesService } from '@alfresco/adf-core'; @Component({ @@ -30,27 +36,17 @@ export class ProcessesCloudDemoComponent implements OnInit { @ViewChild('processCloud') processCloud: ProcessListCloudComponent; - sortFormControl: FormControl; - sortDirectionFormControl: FormControl; + @ViewChild('processFiltersCloud') + processFiltersCloud: ProcessFiltersCloudComponent; applicationName: string = ''; - isFilterLoaded: boolean; + isFilterLoaded: boolean; - status: string = ''; - filterName: string; filterId: string = ''; - sort: string = ''; sortArray: any = []; - sortField: string; - sortDirection: string; selectedRow: any; - columns = [ - {key: 'id', label: 'ID'}, - {key: 'name', label: 'NAME'}, - {key: 'status', label: 'STATUS'}, - {key: 'startDate', label: 'START DATE'} - ]; + editedFilter: ProcessFilterCloudModel; constructor(private route: ActivatedRoute, private userPreference: UserPreferencesService) { @@ -62,43 +58,11 @@ export class ProcessesCloudDemoComponent implements OnInit { this.applicationName = params.applicationName; }); - this.sortFormControl = new FormControl(''); - - this.sortFormControl.valueChanges.subscribe( - (sortValue) => { - this.sort = sortValue; - - this.sortArray = [{ - orderBy: this.sort, - direction: this.sortDirection - }]; - } - ); - this.sortDirectionFormControl = new FormControl(''); - - this.sortDirectionFormControl.valueChanges.subscribe( - (sortDirectionValue) => { - this.sortDirection = sortDirectionValue; - - this.sortArray = [{ - orderBy: this.sort, - direction: this.sortDirection - }]; - } - ); - - this.route.queryParams - .subscribe((params) => { - if (params.filterName) { - this.status = params.status ? params.status : ''; - this.sort = params.sort; - this.sortDirection = params.order; - this.filterName = params.filterName; - this.isFilterLoaded = true; - this.sortDirectionFormControl.setValue(this.sortDirection); - this.sortFormControl.setValue(this.sort); - } - }); + this.route.queryParams.subscribe((params) => { + this.isFilterLoaded = true; + this.onFilterChange(params); + this.filterId = params.id; + }); } onChangePageSize(event) { @@ -108,4 +72,33 @@ export class ProcessesCloudDemoComponent implements OnInit { onRowClick($event) { this.selectedRow = $event; } + + onFilterChange(query: any) { + this.editedFilter = Object.assign({}, query); + this.sortArray = [new ProcessListCloudSortingModel({ orderBy: this.editedFilter.sort, direction: this.editedFilter.order })]; + } + + onEditActions(event: any) { + if (event.actionType === EditProcessFilterCloudComponent.ACTION_SAVE) { + this.save(event.id); + } else if (event.actionType === EditProcessFilterCloudComponent.ACTION_SAVE_AS) { + this.saveAs(event.id); + } else if (event.actionType === EditProcessFilterCloudComponent.ACTION_DELETE) { + this.deleteFilter(); + } + } + + saveAs(filterId) { + this.processFiltersCloud.filterParam = {id : filterId}; + this.processFiltersCloud.getFilters(this.applicationName); + } + + save(filterId) { + this.processFiltersCloud.filterParam = {id : filterId}; + this.processFiltersCloud.getFilters(this.applicationName); + } + + deleteFilter() { + this.processFiltersCloud.getFilters(this.applicationName); + } } diff --git a/docs/docassets/images/edit-process-filter-cloud.component.png b/docs/docassets/images/edit-process-filter-cloud.component.png new file mode 100644 index 0000000000000000000000000000000000000000..969570e8c6ed95b20c8249f0c32d080a73919a33 GIT binary patch literal 10722 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 + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| ---- | ---- | ------------- | ----------- | +| appName | `string` | | The name of the application. | +| id | `string` | | Id of the process filter. | + +### Events + +| Name | Type | Description | +| ---- | ---- | ----------- | +| action | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterActionType`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts)`>` | Emitted when an filter action occurs i.e Save, SaveAs, Delete. | +| filterChange | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterCloudModel`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts)`>` | Emitted when an process instance filter property changes. | + +## Details + +### Editing APS2 process filter + +Use the process filter id property to edit process filter properties: + +```html + + +``` + +![edit-process-filter-cloud](../docassets/images/edit-process-filter-cloud.component.png) diff --git a/docs/process-services-cloud/process-filters-cloud.component.md b/docs/process-services-cloud/process-filters-cloud.component.md index 9d8d05ca18..eee06978ab 100644 --- a/docs/process-services-cloud/process-filters-cloud.component.md +++ b/docs/process-services-cloud/process-filters-cloud.component.md @@ -24,13 +24,32 @@ Lists all available process filters and allows to select a filter. | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | | appName | `string` | | (required) The application name | -| filterParam | [`ProcessFilterParamModel`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts) | | (optional) The filter to be selected by default | +| filterParam | `ProcessFilterCloudModel` | | (optional) The filter to be selected by default | | showIcons | `boolean` | false | (optional) The flag hides/shows icon against each filter | ### Events | Name | Type | Description | | ---- | ---- | ----------- | -| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when any error occurs while loading the filters | -| filterClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterRepresentationModel`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts)`>` | Emitted when a filter is selected/clicked | -| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when filters are loaded successfully | +| filterClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessFilterCloudModel`](../../lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts)`>` | Emitted when a filter is selected/clicked. | +| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when filters are loaded successfully. | +| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when any error occurs while loading the filters. | + +### Details + +The `filterParam` input can be used to select a filter as mentioned below. + +```html + + +``` + +A filter can be selected by using any of the `ProcessFilterCloudModel` property. + +| Name | Type | Description | +| ---- | ---- | ----------- | +| id | string | The id of the filter | +| name | string | The name of the filter | +| key | string | The key of the filter | +| index | string | The zero-based position of the filter in the array | diff --git a/lib/process-services-cloud/src/lib/i18n/en.json b/lib/process-services-cloud/src/lib/i18n/en.json index f999d220c9..249e9bfc32 100644 --- a/lib/process-services-cloud/src/lib/i18n/en.json +++ b/lib/process-services-cloud/src/lib/i18n/en.json @@ -80,5 +80,28 @@ "SAVE": "SAVE", "CANCEL": "CANCEL" } + }, + "ADF_CLOUD_EDIT_PROCESS_FILTER": { + "TITLE": "Customize your filter", + "STATUS": "Select a status", + "ASSIGNMENT": "ASSIGNMENT", + "COLUMN": "Select a column", + "DIRECTION": "Select a direction", + "TOOL_TIP": { + "SAVE": "Save filter", + "SAVE_AS": "Save filter as", + "DELETE": "Delete filter" + }, + "LABEL": { + "STATUS": "Status", + "ASSIGNMENT": "Assignment", + "COLUMN": "Column", + "DIRECTION": "Direction" + }, + "DIALOG": { + "TITLE": "Save filter as", + "SAVE": "SAVE", + "CANCEL": "CANCEL" + } } } diff --git a/lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts b/lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts index ebc37e1b73..2e77410b4e 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/models/process-filter-cloud.model.ts @@ -14,31 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export class ProcessQueryModel { - processDefinitionId: string; - appName: string; - state: string; - sort: string; - assignment: string; - order: string; - constructor(obj?: any) { - if (obj) { - this.appName = obj.appName || null; - this.processDefinitionId = obj.processDefinitionId || null; - this.state = obj.state || null; - this.sort = obj.sort || null; - this.assignment = obj.assignment || null; - this.order = obj.order || null; - } - } -} -export class ProcessFilterRepresentationModel { +export class ProcessFilterCloudModel { id: string; name: string; key: string; icon: string; - query: ProcessQueryModel; + index: number; + processDefinitionId: string; + appName: string; + state: string; + sort: string; + order: string; constructor(obj?: any) { if (obj) { @@ -46,26 +33,17 @@ export class ProcessFilterRepresentationModel { this.name = obj.name || null; this.key = obj.key || null; this.icon = obj.icon || null; - this.query = new ProcessQueryModel(obj.query); - } - } - - hasFilter() { - return !!this.query; - } -} - -export class ProcessFilterParamModel { - id: string; - name: string; - key: string; - index: number; - constructor(obj?: any) { - if (obj) { - this.id = obj.id || null; - this.name = obj.name || null; - this.key = obj.key || null; this.index = obj.index || null; + this.appName = obj.appName || null; + this.processDefinitionId = obj.processDefinitionId || null; + this.state = obj.state || null; + this.sort = obj.sort || null; + this.order = obj.order || null; } } } + +export interface ProcessFilterActionType { + actionType: string; + id: string; +} diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-cloud.module.ts b/lib/process-services-cloud/src/lib/process-cloud/process-cloud.module.ts index f5290f353f..529809b395 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/process-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/process-cloud.module.ts @@ -17,14 +17,20 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FlexLayoutModule } from '@angular/flex-layout'; import { ProcessFiltersCloudComponent } from './process-filters-cloud/process-filters-cloud.component'; import { MaterialModule } from '../material.module'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateLoaderService, LogService, StorageService } from '@alfresco/adf-core'; import { ProcessFilterCloudService } from './services/process-filter-cloud.service'; import { HttpClientModule } from '@angular/common/http'; +import { EditProcessFilterCloudComponent } from './process-filters-cloud/edit-process-filter-cloud.component'; +import { ProcessFilterDialogCloudComponent } from './process-filters-cloud/process-filter-dialog-cloud.component'; @NgModule({ imports: [ + FormsModule, + ReactiveFormsModule, HttpClientModule, CommonModule, TranslateModule.forRoot({ @@ -33,11 +39,12 @@ import { HttpClientModule } from '@angular/common/http'; useClass: TranslateLoaderService } }), + FlexLayoutModule, MaterialModule ], - declarations: [ProcessFiltersCloudComponent], - - exports: [ProcessFiltersCloudComponent], + declarations: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent], + exports: [ProcessFiltersCloudComponent, EditProcessFilterCloudComponent, ProcessFilterDialogCloudComponent], + entryComponents: [ProcessFilterDialogCloudComponent], providers: [ProcessFilterCloudService, LogService, StorageService] }) export class ProcessCloudModule { } diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.html b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.html new file mode 100644 index 0000000000..c4e428795e --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.html @@ -0,0 +1,60 @@ + + + + {{processFilter.name | translate}} + + {{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.TITLE' | translate}} + + +
+
+ + + + {{ state.label }} + + + + + + + + + + + + + {{ column.label }} + + + + + + + {{ direction }} + + + +
+ + + +
+
+
+
+
diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.scss b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.spec.ts new file mode 100644 index 0000000000..bb580f45c4 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.spec.ts @@ -0,0 +1,317 @@ +/*! + * @license + * Copyright 2016 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 { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { SimpleChange } from '@angular/core'; +import { By } from '@angular/platform-browser'; + +import { setupTestBed } from '@alfresco/adf-core'; +import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; +import { MatDialog } from '@angular/material'; +import { of } from 'rxjs'; +import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component'; +import { EditProcessFilterCloudComponent } from './edit-process-filter-cloud.component'; +import { ProcessCloudModule } from '../process-cloud.module'; +import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model'; +import { ProcessFilterCloudService } from '../services/process-filter-cloud.service'; + +describe('EditProcessFilterCloudComponent', () => { + let component: EditProcessFilterCloudComponent; + let service: ProcessFilterCloudService; + let fixture: ComponentFixture; + let dialog: MatDialog; + + let fakeFilter = new ProcessFilterCloudModel({ + name: 'FakeRunningProcess', + icon: 'adjust', + id: 10, + state: 'RUNNING', + appName: 'app-name', + processDefinitionId: 'process-def-id', + assignment: 'fake-involved', + order: 'ASC', + sort: 'id' + }); + + setupTestBed({ + imports: [ProcessServiceCloudTestingModule, ProcessCloudModule], + providers: [MatDialog] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditProcessFilterCloudComponent); + component = fixture.componentInstance; + service = TestBed.get(ProcessFilterCloudService); + dialog = TestBed.get(MatDialog); + spyOn(dialog, 'open').and.returnValue({ afterClosed() { return of({ + action: ProcessFilterDialogCloudComponent.ACTION_SAVE, + icon: 'icon', + name: 'fake-name' + }); }}); + spyOn(service, 'getProcessFilterById').and.returnValue(fakeFilter); + }); + + it('should create EditProcessFilterCloudComponent', () => { + expect(component instanceof EditProcessFilterCloudComponent).toBeTruthy(); + }); + + it('should fetch process instance filter by id', async(() => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(component.processFilter.name).toEqual('FakeRunningProcess'); + expect(component.processFilter.icon).toEqual('adjust'); + expect(component.processFilter.state).toEqual('RUNNING'); + expect(component.processFilter.order).toEqual('ASC'); + expect(component.processFilter.sort).toEqual('id'); + }); + })); + + it('should display filter name as title', () => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + fixture.detectChanges(); + const title = fixture.debugElement.nativeElement.querySelector('#adf-edit-process-filter-title-id'); + const subTitle = fixture.debugElement.nativeElement.querySelector('#adf-edit-process-filter-sub-title-id'); + expect(title).toBeDefined(); + expect(subTitle).toBeDefined(); + expect(title.innerText).toEqual('FakeRunningProcess'); + expect(subTitle.innerText).toEqual('ADF_CLOUD_EDIT_PROCESS_FILTER.TITLE'); + }); + + describe('EditProcessFilter form', () => { + + beforeEach(() => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + }); + + it('should define editProcessFilter form', () => { + expect(component.editProcessFilterForm).toBeDefined(); + }); + + it('should create editProcessFilter form', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + const stateController = component.editProcessFilterForm.get('state'); + const sortController = component.editProcessFilterForm.get('sort'); + const orderController = component.editProcessFilterForm.get('order'); + expect(component.editProcessFilterForm).toBeDefined(); + expect(stateController).toBeDefined(); + expect(sortController).toBeDefined(); + expect(orderController).toBeDefined(); + + expect(stateController.value).toBe('RUNNING'); + expect(sortController.value).toBe('id'); + expect(orderController.value).toBe('ASC'); + }); + })); + + it('should disable save button if the process filter is not changed', async(() => { + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + expect(saveButton.disabled).toBe(true); + }); + })); + + it('should disable saveAs button if the process filter is not changed', async(() => { + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + expect(saveButton.disabled).toBe(true); + }); + })); + + it('should enable delete button by default', async(() => { + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + expect(deleteButton.disabled).toBe(false); + }); + })); + + it('should display current process filter details', async(() => { + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let stateElement = fixture.debugElement.nativeElement.querySelector('#adf-process-filter-state-id'); + let sortElement = fixture.debugElement.nativeElement.querySelector('#adf-process-filter-sort-id'); + let orderElement = fixture.debugElement.nativeElement.querySelector('#adf-process-filter-order-id'); + expect(stateElement).toBeDefined(); + expect(sortElement).toBeDefined(); + expect(orderElement).toBeDefined(); + expect(stateElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.STATUS'); + expect(sortElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.COLUMN'); + expect(orderElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DIRECTION'); + }); + })); + + it('should enable save button if the process filter is changed', async(() => { + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + const options = fixture.debugElement.queryAll(By.css('.mat-option-text')); + options[2].nativeElement.click(); + fixture.detectChanges(); + expect(saveButton.disabled).toBe(false); + }); + })); + + it('should display state drop down', async(() => { + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const statusOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + expect(statusOptions.length).toEqual(3); + }); + })); + + it('should display sort drop down', async(() => { + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const sortElement = fixture.debugElement.query(By.css('#adf-process-filter-sort-id .mat-select-trigger')).nativeElement; + sortElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const sortOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + expect(sortOptions.length).toEqual(4); + }); + })); + + it('should display order drop down', async(() => { + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const orderElement = fixture.debugElement.query(By.css('#adf-process-filter-order-id .mat-select-trigger')).nativeElement; + orderElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const orderOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + expect(orderOptions.length).toEqual(2); + }); + })); + }); + + describe('edit filter actions', () => { + + beforeEach(() => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + }); + + it('should emit save event and save the filter on click save button', async(() => { + const saveFilterSpy = spyOn(service, 'updateFilter').and.returnValue(fakeFilter); + let saveSpy: jasmine.Spy = spyOn(component.action, 'emit'); + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + stateOptions[2].nativeElement.click(); + fixture.detectChanges(); + saveButton.click(); + fixture.detectChanges(); + expect(saveFilterSpy).toHaveBeenCalled(); + expect(saveSpy).toHaveBeenCalled(); + }); + })); + + it('should emit delete event and delete the filter on click of delete button', async(() => { + const deleteFilterSpy = spyOn(service, 'deleteFilter').and.callThrough(); + let deleteSpy: jasmine.Spy = spyOn(component.action, 'emit'); + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + let deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + deleteButton.click(); + fixture.detectChanges(); + expect(deleteFilterSpy).toHaveBeenCalled(); + expect(deleteSpy).toHaveBeenCalled(); + }); + })); + + it('should emit saveAs event and add filter on click of saveAs button', async(() => { + const saveAsFilterSpy = spyOn(service, 'addFilter').and.callThrough(); + let saveAsSpy: jasmine.Spy = spyOn(component.action, 'emit'); + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + stateOptions[2].nativeElement.click(); + fixture.detectChanges(); + saveButton.click(); + fixture.detectChanges(); + expect(saveAsFilterSpy).toHaveBeenCalled(); + expect(saveAsSpy).toHaveBeenCalled(); + expect(dialog.open).toHaveBeenCalled(); + }); + })); + + it('should able to open save dialog on click of saveAs button', async(() => { + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + const stateElement = fixture.debugElement.query(By.css('#adf-process-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + stateOptions[2].nativeElement.click(); + fixture.detectChanges(); + saveButton.click(); + fixture.detectChanges(); + expect(dialog.open).toHaveBeenCalled(); + }); + })); + }); +}); diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.ts new file mode 100644 index 0000000000..e5c1156d3b --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/edit-process-filter-cloud.component.ts @@ -0,0 +1,189 @@ +/*! + * @license + * Copyright 2016 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 { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { ProcessFilterCloudModel, ProcessFilterActionType } 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'; +import { MatDialog } from '@angular/material'; + +@Component({ + selector: 'adf-cloud-edit-process-filter', + templateUrl: './edit-process-filter-cloud.component.html', + styleUrls: ['./edit-process-filter-cloud.component.scss'] +}) +export class EditProcessFilterCloudComponent implements OnChanges { + + public static ACTION_SAVE = 'SAVE'; + public static ACTION_SAVE_AS = 'SAVE_AS'; + public static ACTION_DELETE = 'DELETE'; + + /** The name of the application. */ + @Input() + appName: string; + + /** Id of the process instance filter. */ + @Input() + id: string; + + /** Emitted when an process instance filter property changes. */ + @Output() + filterChange: EventEmitter = new EventEmitter(); + + /** Emitted when an filter action occurs i.e Save, SaveAs, Delete. */ + @Output() + action: EventEmitter = new EventEmitter(); + + processFilter: ProcessFilterCloudModel; + changedProcessFilter: ProcessFilterCloudModel; + + columns = [ + {key: 'id', label: 'ID'}, + {key: 'name', label: 'NAME'}, + {key: 'status', label: 'STATUS'}, + {key: 'startDate', label: 'START DATE'} + ]; + + status = [ + {label: 'ALL', value: ''}, + {label: 'RUNNING', value: 'RUNNING'}, + {label: 'COMPLETED', value: 'COMPLETED'} + ]; + + directions = ['ASC', 'DESC']; + formHasBeenChanged = false; + editProcessFilterForm: FormGroup; + + constructor( + private formBuilder: FormBuilder, + public dialog: MatDialog, + private translateService: TranslationService, + private processFilterCloudService: ProcessFilterCloudService) {} + + ngOnChanges(changes: SimpleChanges) { + const id = changes['id']; + if (id && id.currentValue !== id.previousValue) { + this.retrieveProcessFilter(); + this.buildForm(); + } + } + + /** + * Build process filter edit form + */ + buildForm() { + this.formHasBeenChanged = false; + this.editProcessFilterForm = this.formBuilder.group({ + state: this.processFilter.state ? this.processFilter.state : '', + sort: this.processFilter.sort, + order: this.processFilter.order, + processDefinitionId: this.processFilter.processDefinitionId, + appName: this.processFilter.appName + }); + this.onFilterChange(); + } + + /** + * Return process instance filter by application name and filter id + */ + retrieveProcessFilter() { + this.processFilter = this.processFilterCloudService.getProcessFilterById(this.appName, this.id); + } + + /** + * Check process instance filter changes + */ + onFilterChange() { + this.editProcessFilterForm.valueChanges.subscribe((formValues: ProcessFilterCloudModel) => { + this.changedProcessFilter = new ProcessFilterCloudModel(Object.assign({}, this.processFilter, formValues)); + this.formHasBeenChanged = !this.compareFilters(this.changedProcessFilter, this.processFilter); + this.filterChange.emit(this.changedProcessFilter); + }); + } + + /** + * Return true if both filters are same + * @param editedQuery, @param currentQuery + */ + compareFilters(editedQuery: ProcessFilterCloudModel, currentQuery: ProcessFilterCloudModel): boolean { + return JSON.stringify(editedQuery).toLowerCase() === JSON.stringify(currentQuery).toLowerCase(); + } + + /** + * Save a process instance filter + */ + onSave() { + this.processFilterCloudService.updateFilter(this.changedProcessFilter); + this.action.emit({actionType: EditProcessFilterCloudComponent.ACTION_SAVE, id: this.changedProcessFilter.id}); + } + + /** + * Delete a process instance filter + */ + onDelete() { + this.processFilterCloudService.deleteFilter(this.processFilter); + this.action.emit({actionType: EditProcessFilterCloudComponent.ACTION_DELETE, id: this.processFilter.id}); + } + + /** + * Save As a process instance filter + */ + onSaveAs() { + const dialogRef = this.dialog.open(ProcessFilterDialogCloudComponent, { + data: { + name: this.translateService.instant(this.processFilter.name) + }, + height: 'auto', + minWidth: '30%' + }); + dialogRef.afterClosed().subscribe( (result) => { + if (result && result.action === ProcessFilterDialogCloudComponent.ACTION_SAVE) { + const filterId = Math.random().toString(36).substr(2, 9); + const filterKey = this.getSanitizeFilterName(result.name); + const newFilter = { + name: result.name, + icon: result.icon, + id: filterId, + key: 'custom-' + filterKey + }; + const filter = Object.assign({}, this.changedProcessFilter, newFilter); + this.processFilterCloudService.addFilter(filter); + this.action.emit({actionType: EditProcessFilterCloudComponent.ACTION_SAVE_AS, id: filter.id}); + } + }); + } + + /** + * Return filter name + * @param filterName + */ + getSanitizeFilterName(filterName: string): string { + const nameWithHyphen = this.replaceSpaceWithHyphen(filterName.trim()); + return nameWithHyphen.toLowerCase(); + } + + /** + * Return name with hyphen + * @param name + */ + replaceSpaceWithHyphen(name: string): string { + const regExt = new RegExp(' ', 'g'); + return name.replace(regExt, '-'); + } +} diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.html b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.html new file mode 100644 index 0000000000..f47f9688bc --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.html @@ -0,0 +1,22 @@ +
+ + {{ 'ADF_CLOUD_EDIT_PROCESS_FILTER.DIALOG.TITLE' | translate}} + + + +
+ + + +
+
+ + + + +
+
diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.scss b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.scss new file mode 100644 index 0000000000..48e59d0a11 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.scss @@ -0,0 +1,9 @@ +.adf-process-filter-dialog .mat-card { + padding: 0; + box-shadow: none; +} + +.adf-process-filter-dialog .mat-card-content { + padding: 0; + box-shadow: none; +} diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.spec.ts new file mode 100644 index 0000000000..3f7d3a49a4 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.spec.ts @@ -0,0 +1,136 @@ +/*! + * @license + * Copyright 2016 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 { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { ProcessFilterDialogCloudComponent } from './process-filter-dialog-cloud.component'; +import { setupTestBed } from '@alfresco/adf-core'; +import { ProcessServiceCloudTestingModule } from './../../testing/process-service-cloud.testing.module'; +import { ProcessCloudModule } from '../process-cloud.module'; + +describe('ProcessFilterDialogCloudComponent', () => { + let component: ProcessFilterDialogCloudComponent; + let fixture: ComponentFixture; + + const mockDialogRef = { + close: jasmine.createSpy('close'), + open: jasmine.createSpy('open') + }; + + const mockDialogData = { + data: {name: 'Mock-Title'} + }; + + setupTestBed({ + imports: [ProcessServiceCloudTestingModule, ProcessCloudModule], + providers: [ + { provide: MatDialogRef, useValue: mockDialogRef }, + { provide: MAT_DIALOG_DATA, useValue: mockDialogData } + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProcessFilterDialogCloudComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create ProcessFilterDialogCloudComponent', () => { + expect(component instanceof ProcessFilterDialogCloudComponent).toBeTruthy(); + }); + + it('should get data from MAT_DIALOG_DATA as an input to the dialog', () => { + fixture.detectChanges(); + const mockData = component.data; + fixture.detectChanges(); + expect(mockData).toEqual(mockDialogData); + expect(mockData.data.name).toEqual('Mock-Title'); + }); + + it('should display title', () => { + fixture.detectChanges(); + let titleElement = fixture.debugElement.nativeElement.querySelector( + '#adf-process-filter-dialog-title' + ); + expect(titleElement.textContent).toEqual(' ADF_CLOUD_EDIT_PROCESS_FILTER.DIALOG.TITLE '); + }); + + it('should enable save button if form is valid', async(() => { + fixture.detectChanges(); + let saveButton = fixture.debugElement.nativeElement.querySelector( + '#adf-save-button-id' + ); + const inputElement = fixture.debugElement.nativeElement.querySelector( + '#adf-filter-name-id' + ); + inputElement.value = 'My custom Name'; + inputElement.dispatchEvent(new Event('input')); + fixture.whenStable().then(() => { + fixture.detectChanges(); + expect(saveButton).toBeDefined(); + expect(saveButton.disabled).toBeFalsy(); + }); + })); + + it('should disable save button if form is not valid', async(() => { + fixture.detectChanges(); + const inputElement = fixture.debugElement.nativeElement.querySelector( + '#adf-filter-name-id' + ); + inputElement.value = ''; + inputElement.dispatchEvent(new Event('input')); + fixture.whenStable().then(() => { + let saveButton = fixture.debugElement.nativeElement.querySelector( + '#adf-save-button-id' + ); + fixture.detectChanges(); + expect(saveButton).toBeDefined(); + expect(saveButton.disabled).toBe(true); + }); + })); + + it('should able to close dialog on click of save button if form is valid', async(() => { + fixture.detectChanges(); + const inputElement = fixture.debugElement.nativeElement.querySelector( + '#adf-filter-name-id' + ); + inputElement.value = 'My custom Name'; + inputElement.dispatchEvent(new Event('input')); + fixture.whenStable().then(() => { + let saveButton = fixture.debugElement.nativeElement.querySelector( + '#adf-save-button-id' + ); + fixture.detectChanges(); + saveButton.click(); + expect(saveButton).toBeDefined(); + expect(saveButton.disabled).toBeFalsy(); + expect(component.dialogRef.close).toHaveBeenCalled(); + }); + })); + + it('should able close dialog on click of cancel button', () => { + component.data = { data: { name: '' } }; + let cancelButton = fixture.debugElement.nativeElement.querySelector( + '#adf-cancel-button-id' + ); + fixture.detectChanges(); + cancelButton.click(); + expect(cancelButton).toBeDefined(); + expect(cancelButton.disabled).toBeFalsy(); + expect(component.dialogRef.close).toHaveBeenCalled(); + }); +}); diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.ts new file mode 100644 index 0000000000..7e341222a4 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filter-dialog-cloud.component.ts @@ -0,0 +1,66 @@ +/*! + * @license + * Copyright 2016 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 { Component, Inject } from '@angular/core'; +import { OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FormBuilder, FormGroup, AbstractControl, Validators } from '@angular/forms'; + +@Component({ + selector: 'adf-cloud-process-filter-dialog-cloud', + templateUrl: './process-filter-dialog-cloud.component.html', + styleUrls: ['./process-filter-dialog-cloud.component.scss'] +}) +export class ProcessFilterDialogCloudComponent implements OnInit { + + public static ACTION_SAVE = 'SAVE'; + defaultIcon = 'inbox'; + + filterForm: FormGroup; + + constructor( + private fb: FormBuilder, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data) { + } + + ngOnInit() { + this.filterForm = this.fb.group({ + name: [this.data.name, Validators.required] + }); + } + + onSaveClick() { + this.dialogRef.close({ + action: ProcessFilterDialogCloudComponent.ACTION_SAVE, + icon: this.defaultIcon, + name: this.nameController.value + }); + } + + onCancelClick() { + this.dialogRef.close(); + } + + get nameController(): AbstractControl { + return this.filterForm.get('name'); + } + + isValid(): boolean { + return this.filterForm.valid; + } +} diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.spec.ts index 8b554c86f3..806886f7d9 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.spec.ts @@ -19,7 +19,7 @@ import { SimpleChange } from '@angular/core'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; import { setupTestBed } from '@alfresco/adf-core'; import { from, Observable } from 'rxjs'; -import { ProcessFilterRepresentationModel, ProcessFilterParamModel } from '../models/process-filter-cloud.model'; +import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model'; import { ProcessFilterCloudService } from '../services/process-filter-cloud.service'; import { ProcessFiltersCloudComponent } from './process-filters-cloud.component'; import { By } from '@angular/platform-browser'; @@ -31,24 +31,24 @@ describe('ProcessFiltersCloudComponent', () => { let processFilterService: ProcessFilterCloudService; let fakeGlobalFilter = [ - new ProcessFilterRepresentationModel({ + new ProcessFilterCloudModel({ name: 'FakeAllProcesses', icon: 'adjust', id: '10', - query: {state: ''} + state: '' }), - new ProcessFilterRepresentationModel({ + new ProcessFilterCloudModel({ name: 'FakeRunningProcesses', icon: 'inbox', id: '11', - query: {state: 'RUNNING'} + state: 'RUNNING' }), - new ProcessFilterRepresentationModel({ + new ProcessFilterCloudModel({ name: 'FakeCompletedProcesses', key: 'completed-processes', icon: 'done', id: '12', - query: {state: 'COMPLETED'} + state: 'COMPLETED' }) ]; @@ -205,7 +205,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should select the filter based on the input by name param', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ name: 'FakeRunningProcesses' }); + component.filterParam = new ProcessFilterCloudModel({ name: 'FakeRunningProcesses' }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -224,7 +224,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should select the filter based on the input by key param', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ key: 'completed-processes' }); + component.filterParam = new ProcessFilterCloudModel({ key: 'completed-processes' }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -244,7 +244,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should select the default filter if filter input does not exist', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ name: 'UnexistableFilter' }); + component.filterParam = new ProcessFilterCloudModel({ name: 'UnexistableFilter' }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -265,7 +265,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should select the filter based on the input by index param', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ index: 2 }); + component.filterParam = new ProcessFilterCloudModel({ index: 2 }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -285,7 +285,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should select the filter based on the input by id param', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ id: '12' }); + component.filterParam = new ProcessFilterCloudModel({ id: '12' }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -304,7 +304,7 @@ describe('ProcessFiltersCloudComponent', () => { it('should emit an event when a filter is selected', (done) => { spyOn(processFilterService, 'getProcessFilters').and.returnValue(fakeGlobalFilterObservable); - component.filterParam = new ProcessFilterParamModel({ id: '10' }); + component.filterParam = new ProcessFilterCloudModel({ id: '10' }); const appName = 'my-app-1'; let change = new SimpleChange(null, appName, true); @@ -369,7 +369,7 @@ describe('ProcessFiltersCloudComponent', () => { component.filters = fakeGlobalFilter; expect(component.currentFilter).toBeUndefined(); - component.selectFilter( {id: filter.id}); + component.selectFilter( {id: filter.id}); expect(component.getCurrentFilter()).toBe(filter); }); }); diff --git a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.ts b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.ts index 79ce89fbd1..db12faa723 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/process-filters-cloud/process-filters-cloud.component.ts @@ -18,7 +18,7 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; import { Observable } from 'rxjs'; import { ProcessFilterCloudService } from '../services/process-filter-cloud.service'; -import { ProcessFilterRepresentationModel, ProcessFilterParamModel } from '../models/process-filter-cloud.model'; +import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model'; import { TranslationService } from '@alfresco/adf-core'; @Component({ selector: 'adf-cloud-process-filters', @@ -33,7 +33,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { /** (optional) The filter to be selected by default */ @Input() - filterParam: ProcessFilterParamModel; + filterParam: ProcessFilterCloudModel; /** (optional) The flag hides/shows icon against each filter */ @Input() @@ -41,7 +41,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { /** Emitted when a filter is selected/clicked */ @Output() - filterClick: EventEmitter = new EventEmitter(); + filterClick: EventEmitter = new EventEmitter(); /** Emitted when filters are loaded successfully */ @Output() @@ -51,11 +51,11 @@ export class ProcessFiltersCloudComponent implements OnChanges { @Output() error: EventEmitter = new EventEmitter(); - filters$: Observable; + filters$: Observable; - currentFilter: ProcessFilterRepresentationModel; + currentFilter: ProcessFilterCloudModel; - filters: ProcessFilterRepresentationModel [] = []; + filters: ProcessFilterCloudModel [] = []; constructor( private processFilterCloudService: ProcessFilterCloudService, @@ -78,7 +78,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { this.filters$ = this.processFilterCloudService.getProcessFilters(appName); this.filters$.subscribe( - (res: ProcessFilterRepresentationModel[]) => { + (res: ProcessFilterCloudModel[]) => { if (res.length === 0) { this.createFilters(appName); } else { @@ -101,7 +101,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { this.filters$ = this.processFilterCloudService.createDefaultFilters(appName); this.filters$.subscribe( - (resDefault: ProcessFilterRepresentationModel[]) => { + (resDefault: ProcessFilterCloudModel[]) => { this.resetFilter(); this.filters = resDefault; }, @@ -114,7 +114,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { /** * Pass the selected filter as next */ - public selectFilter(filterParam: ProcessFilterParamModel) { + public selectFilter(filterParam: ProcessFilterCloudModel) { if (filterParam) { this.currentFilter = this.filters.find((filter, index) => { return filterParam.id === filter.id || @@ -141,7 +141,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { /** * Select and emit the given filter */ - public selectFilterAndEmit(newFilter: ProcessFilterParamModel) { + public selectFilterAndEmit(newFilter: ProcessFilterCloudModel) { this.selectFilter(newFilter); this.filterClick.emit(this.currentFilter); } @@ -150,7 +150,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { * Select filter with the id */ public selectFilterById(id: string) { - this.selectFilterAndEmit( {id: id}); + this.selectFilterAndEmit( {id: id}); } /** @@ -165,7 +165,7 @@ export class ProcessFiltersCloudComponent implements OnChanges { /** * Return the current process */ - getCurrentFilter(): ProcessFilterRepresentationModel { + getCurrentFilter(): ProcessFilterCloudModel { return this.currentFilter; } diff --git a/lib/process-services-cloud/src/lib/process-cloud/public-api.ts b/lib/process-services-cloud/src/lib/process-cloud/public-api.ts index 2438eb04b6..8b9d0f3b25 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/public-api.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/public-api.ts @@ -16,5 +16,7 @@ */ export * from './process-filters-cloud/process-filters-cloud.component'; +export * from './process-filters-cloud/edit-process-filter-cloud.component'; export * from './models/process-filter-cloud.model'; +export * from './services/process-filter-cloud.service'; export * from './process-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/process-cloud/services/process-filter-cloud.service.ts b/lib/process-services-cloud/src/lib/process-cloud/services/process-filter-cloud.service.ts index d56f916ea2..d6d4ad5738 100644 --- a/lib/process-services-cloud/src/lib/process-cloud/services/process-filter-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/process-cloud/services/process-filter-cloud.service.ts @@ -18,7 +18,7 @@ import { StorageService } from '@alfresco/adf-core'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { ProcessFilterRepresentationModel, ProcessQueryModel } from '../models/process-filter-cloud.model'; +import { ProcessFilterCloudModel } from '../models/process-filter-cloud.model'; @Injectable() export class ProcessFilterCloudService { @@ -31,7 +31,7 @@ export class ProcessFilterCloudService { * @param appName Name of the target app * @returns Observable of default filters just created */ - public createDefaultFilters(appName: string): Observable { + public createDefaultFilters(appName: string): Observable { const allProcessesFilter = this.getAllProcessesFilter(appName); this.addFilter(allProcessesFilter); const runningProcessesFilter = this.getRunningProcessesFilter(appName); @@ -47,7 +47,7 @@ export class ProcessFilterCloudService { * @param appName Name of the target app * @returns Observable of process filter details */ - getProcessFilters(appName: string): Observable { + getProcessFilters(appName: string): Observable { let key = 'process-filters-' + appName; const filters = JSON.parse(this.storage.getItem(key) || '[]'); return new Observable(function(observer) { @@ -56,36 +56,73 @@ export class ProcessFilterCloudService { }); } + /** + * Get process instance filter for given filter id + * @param appName Name of the target app + * @param id Id of the target process instance filter + * @returns Details of process filter + */ + getProcessFilterById(appName: string, id: string): ProcessFilterCloudModel { + const key = 'process-filters-' + appName; + let filters = []; + filters = JSON.parse(this.storage.getItem(key)) || []; + return filters.filter((filterTmp: ProcessFilterCloudModel) => id === filterTmp.id)[0]; + } + /** * Adds a new process instance filter * @param filter The new filter to add * @returns Details of process filter just added */ - addFilter(filter: ProcessFilterRepresentationModel) { - const key = 'process-filters-' + filter.query.appName; + addFilter(filter: ProcessFilterCloudModel) { + const key = 'process-filters-' + filter.appName; const storedFilters = JSON.parse(this.storage.getItem(key) || '[]'); storedFilters.push(filter); this.storage.setItem(key, JSON.stringify(storedFilters)); } + /** + * Update process instance filter + * @param filter The new filter to update + */ + updateFilter(filter: ProcessFilterCloudModel) { + const key = 'process-filters-' + filter.appName; + if (key) { + let filters = JSON.parse(this.storage.getItem(key) || '[]'); + let itemIndex = filters.findIndex((flt: ProcessFilterCloudModel) => flt.id === filter.id); + filters[itemIndex] = filter; + this.storage.setItem(key, JSON.stringify(filters)); + } + } + + /** + * Delete process instance filter + * @param filter The new filter to delete + */ + deleteFilter(filter: ProcessFilterCloudModel) { + const key = 'process-filters-' + filter.appName; + if (key) { + let filters = JSON.parse(this.storage.getItem(key) || '[]'); + filters = filters.filter((item) => item.id !== filter.id); + this.storage.setItem(key, JSON.stringify(filters)); + } + } + /** * Creates and returns a filter for "All" Process instances. * @param appName Name of the target app * @returns The newly created filter */ - getAllProcessesFilter(appName: string): ProcessFilterRepresentationModel { - return new ProcessFilterRepresentationModel({ + getAllProcessesFilter(appName: string): ProcessFilterCloudModel { + return new ProcessFilterCloudModel({ name: 'ADF_CLOUD_PROCESS_FILTERS.ALL_PROCESSES', key: 'all-processes', icon: 'adjust', - query: new ProcessQueryModel( - { - appName: appName, - sort: 'startDate', - order: 'DESC' - } - ) + appName: appName, + sort: 'startDate', + state: '', + order: 'DESC' }); } @@ -94,19 +131,15 @@ export class ProcessFilterCloudService { * @param appName Name of the target app * @returns The newly created filter */ - getRunningProcessesFilter(appName: string): ProcessFilterRepresentationModel { - return new ProcessFilterRepresentationModel({ + getRunningProcessesFilter(appName: string): ProcessFilterCloudModel { + return new ProcessFilterCloudModel({ name: 'ADF_CLOUD_PROCESS_FILTERS.RUNNING_PROCESSES', icon: 'inbox', key: 'running-processes', - query: new ProcessQueryModel( - { - appName: appName, - sort: 'startDate', - state: 'RUNNING', - order: 'DESC' - } - ) + appName: appName, + sort: 'startDate', + state: 'RUNNING', + order: 'DESC' }); } @@ -115,19 +148,15 @@ export class ProcessFilterCloudService { * @param appName Name of the target app * @returns The newly created filter */ - getCompletedProcessesFilter(appName: string): ProcessFilterRepresentationModel { - return new ProcessFilterRepresentationModel({ + getCompletedProcessesFilter(appName: string): ProcessFilterCloudModel { + return new ProcessFilterCloudModel({ name: 'ADF_CLOUD_PROCESS_FILTERS.COMPLETED_PROCESSES', icon: 'done', key: 'completed-processes', - query: new ProcessQueryModel( - { - appName: appName, - sort: 'startDate', - state: 'COMPLETED', - order: 'DESC' - } - ) + appName: appName, + sort: 'startDate', + state: 'COMPLETED', + order: 'DESC' }); } } diff --git a/lib/process-services-cloud/src/public-api.ts b/lib/process-services-cloud/src/public-api.ts index f263daaedc..31c7381a59 100644 --- a/lib/process-services-cloud/src/public-api.ts +++ b/lib/process-services-cloud/src/public-api.ts @@ -19,5 +19,6 @@ export * from './lib/process-services-cloud.module'; export * from './lib/app-list-cloud/public-api'; export * from './lib/task-list-cloud/public-api'; export * from './lib/task-cloud/public-api'; +export * from './lib/process-cloud/public-api'; export * from './lib/process-list-cloud/public_api'; export * from './lib/start-task-cloud/public-api';