diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index e60f99572b..947925b086 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -69,7 +69,6 @@ import { TaskListCloudDemoComponent } from './components/task-list-cloud-demo/ta import { ProcessListCloudExampleComponent } from './components/cloud/process-list-cloud-example.component'; import { TreeViewSampleComponent } from './components/tree-view/tree-view-sample.component'; import { AppExtensionsModule } from './extensions/extensions.module'; - @NgModule({ imports: [ BrowserModule, diff --git a/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.html b/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.html index 9122f3ae35..363f6169a6 100644 --- a/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.html +++ b/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.html @@ -18,71 +18,27 @@
- + - - - - - {{filterName | translate}} - - - Customise your filter - - -
- - - - ALL - - - CREATED - - - CANCELLED - - - ASSIGNED - - - SUSPENDED - - - COMPLETED - - - DELETED - - - - - - Select a column - - {{column.label}} - - - - - - Select a direction - - ASC - - - DESC - - - -
+ + -
-
-
- +
+ diff --git a/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.ts b/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.ts index d990d2d531..67ab7963f1 100644 --- a/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.ts +++ b/demo-shell/src/app/components/task-list-cloud-demo/task-list-cloud-demo.component.ts @@ -16,12 +16,16 @@ */ import { Component, ViewChild, OnInit } from '@angular/core'; -import { TaskListCloudComponent, TaskListCloudSortingModel } from '@alfresco/adf-process-services-cloud'; +import { + TaskListCloudComponent, + TaskFiltersCloudComponent, + TaskListCloudSortingModel, + TaskFilterCloudModel, + EditTaskFilterCloudComponent +} from '@alfresco/adf-process-services-cloud'; import { UserPreferencesService } from '@alfresco/adf-core'; import { Observable } from 'rxjs'; import { ActivatedRoute, Router } from '@angular/router'; -import { FormControl } from '@angular/forms'; -import { MatDialog } from '@angular/material'; @Component({ selector: 'app-task-list-cloud-demo', @@ -33,91 +37,48 @@ export class TaskListCloudDemoComponent implements OnInit { @ViewChild('taskCloud') taskCloud: TaskListCloudComponent; - sortFormControl: FormControl; - sortDirectionFormControl: FormControl; + @ViewChild('taskFiltersCloud') + taskFiltersCloud: TaskFiltersCloudComponent; appDefinitionList: Observable; applicationName; status: string = ''; - sort: string = ''; - isFilterLoaded = false; showStartTask = false; - sortDirection: string = 'ASC'; - filterName: string; clickedRow: string = ''; - selectTask: string = ''; filterTaskParam; - sortArray: TaskListCloudSortingModel []; + sortArray: TaskListCloudSortingModel[]; + editedFilter: TaskFilterCloudModel; - columns = [ - {key: 'id', label: 'ID'}, - {key: 'name', label: 'NAME'}, - {key: 'createdDate', label: 'Created Date'}, - {key: 'priority', label: 'PRIORITY'}, - {key: 'processDefinitionId', label: 'PROCESS DEFINITION ID'} - ]; + currentFilter: TaskFilterCloudModel; constructor( - public dialog: MatDialog, private route: ActivatedRoute, private router: Router, - private userPreference: UserPreferencesService) { - } + private userPreference: UserPreferencesService + ) {} ngOnInit() { this.route.params.subscribe((params) => { 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.status) { - this.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.onFilterChange(params); + }); } - onFilterSelected(filter) { - const queryParams = { - id: filter.id, - filterName: filter.name, - status: filter.query.state, - assignee: filter.query.assignment, - sort: filter.query.sort, - order: filter.query.order - }; - this.router.navigate([`/cloud/${this.applicationName}/tasks/`], {queryParams: queryParams}); + onFilterSelected(filter: TaskFilterCloudModel) { + this.currentFilter = Object.assign({}, filter); + this.sortArray = [new TaskListCloudSortingModel({ orderBy: this.currentFilter.sort, direction: this.currentFilter.order})]; + + this.router.navigate([`/cloud/${this.applicationName}/tasks/`], { + queryParams: this.currentFilter + }); + } + + onFilterChange(filter: any) { + this.editedFilter = Object.assign({}, this.currentFilter, filter); + this.sortArray = [new TaskListCloudSortingModel({ orderBy: this.editedFilter.sort, direction: this.editedFilter.order})]; } onStartTask() { @@ -140,4 +101,28 @@ export class TaskListCloudDemoComponent implements OnInit { onRowClick($event) { this.clickedRow = $event; } + + onEditActions(event: any) { + if (event.actionType === EditTaskFilterCloudComponent.ACTION_SAVE) { + this.save(event.id); + } else if (event.actionType === EditTaskFilterCloudComponent.ACTION_SAVE_AS) { + this.saveAs(event.id); + } else if (event.actionType === EditTaskFilterCloudComponent.ACTION_DELETE) { + this.deleteFilter(); + } + } + + saveAs(filterId) { + this.taskFiltersCloud.filterParam = {id : filterId}; + this.taskFiltersCloud.getFilters(this.applicationName); + } + + save(filterId) { + this.taskFiltersCloud.filterParam = {id : filterId}; + this.taskFiltersCloud.getFilters(this.applicationName); + } + + deleteFilter() { + this.taskFiltersCloud.getFilters(this.applicationName); + } } diff --git a/docs/docassets/images/edit-task-filter-cloud.component.png b/docs/docassets/images/edit-task-filter-cloud.component.png new file mode 100644 index 0000000000..7752514f9f Binary files /dev/null and b/docs/docassets/images/edit-task-filter-cloud.component.png differ diff --git a/docs/process-services-cloud/edit-task-filter-cloud.component.md b/docs/process-services-cloud/edit-task-filter-cloud.component.md new file mode 100644 index 0000000000..20e353f6a5 --- /dev/null +++ b/docs/process-services-cloud/edit-task-filter-cloud.component.md @@ -0,0 +1,50 @@ +--- +Title: Edit Task Filter Cloud component +Added: v3.0.0 +Status: Active +Last reviewed: 2018-20-11 +--- + +# Edit Task Filter Cloud component + +Shows Task Filter Details. + +## Basic Usage + +```html + + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| ---- | ---- | ------------- | ----------- | +| id | `string` | "" | The id of the Task filter. | +| appName | `string` | "" | The name of the application. | + +### Events + +| Name | Type | Description | +| ---- | ---- | ----------- | +| filterChange | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterCloudModel`](../../lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts)`>` | Emitted when a filter properties changed. | +| action | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FilterActionType`](../../lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts)`>` | Emitted when the task filter action clicked (i.e, save, saveAs, Delete). | + +## Details + +### Editing APS2 task filter + +Use the application name and task filter id property to edit task filter properties: + +```html + + +``` + +![edit-task-filter-cloud](../docassets/images/edit-task-filter-cloud.component.png) diff --git a/docs/process-services-cloud/task-filters-cloud.component.md b/docs/process-services-cloud/task-filters-cloud.component.md index b47c00d157..25da1f2c10 100644 --- a/docs/process-services-cloud/task-filters-cloud.component.md +++ b/docs/process-services-cloud/task-filters-cloud.component.md @@ -22,7 +22,7 @@ Shows all available filters. | Name | Type | Default value | Description | | ---- | ---- | ------------- | ----------- | | appName | `string` | | Display filters available to the current user for the application with the specified name. | -| filterParam | [`FilterParamsModel`](../../lib/process-services/task-list/models/filter.model.ts) | | Parameters to use for the task filter cloud. If there is no match then the default filter (the first one in the list) is selected. | +| filterParam | [`TaskFilterCloudModel`](../../lib/process-services/task-list/models/filter.model.ts) | | Parameters to use for the task filter cloud. If there is no match then the default filter (the first one in the list) is selected. | | showIcons | `boolean` | false | Toggles display of the filter's icons. | ### Events @@ -30,7 +30,7 @@ Shows all available filters. | Name | Type | Description | | ---- | ---- | ----------- | | error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when an error occurs during loading. | -| filterClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterCloudRepresentationModel`](../../lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts)`>` | Emitted when a filter in the list is clicked. | +| filterClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterCloudModel`](../../lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts)`>` | Emitted when a filter in the list is clicked. | | success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`` | Emitted when the list is loaded. | ## Details @@ -45,7 +45,7 @@ Use the `filterParam` property to restrict the range of filters that are shown: ``` -You can use properties from [`FilterParamsModel`](../../lib/process-services/task-list/models/filter.model.ts) +You can use properties from [`TaskFilterCloudModel`](../../lib/process-services/task-list/models/filter.model.ts) as the value of `filterParam` as shown in the table below: | Name | Type | Description | diff --git a/lib/process-services-cloud/src/lib/i18n/en.json b/lib/process-services-cloud/src/lib/i18n/en.json index 5084bd8288..0d2f63f336 100644 --- a/lib/process-services-cloud/src/lib/i18n/en.json +++ b/lib/process-services-cloud/src/lib/i18n/en.json @@ -22,5 +22,24 @@ "DATE": "Date format DD/MM/YYYY", "MAXIMUM_LENGTH": "Length exceeded, {{characters}} characters max." } + }, + "ADF_CLOUD_EDIT_TASK_FILTER": { + "TITLE": "Customize your filter", + "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/material.module.ts b/lib/process-services-cloud/src/lib/material.module.ts index 76c04b2672..b98cf61b82 100644 --- a/lib/process-services-cloud/src/lib/material.module.ts +++ b/lib/process-services-cloud/src/lib/material.module.ts @@ -21,7 +21,7 @@ import { MatChipsModule, MatDatepickerModule, MatDialogModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatNativeDateModule, MatOptionModule, MatProgressSpinnerModule, MatRadioModule, MatRippleModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule, - MatTooltipModule, MatMenuModule + MatTooltipModule, MatMenuModule, MatExpansionModule } from '@angular/material'; export function modules() { @@ -30,7 +30,7 @@ export function modules() { MatCheckboxModule, MatDatepickerModule, MatGridListModule, MatIconModule, MatInputModule, MatListModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule, MatProgressSpinnerModule, MatNativeDateModule, MatRippleModule, MatTooltipModule, - MatChipsModule, MatMenuModule + MatChipsModule, MatMenuModule, MatExpansionModule ]; } diff --git a/lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts b/lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts index f4123dfcc3..2bd903baf5 100644 --- a/lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts +++ b/lib/process-services-cloud/src/lib/task-cloud/models/filter-cloud.model.ts @@ -14,9 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export class QueryModel { - processDefinitionId: string; + +export class TaskFilterCloudModel { + id: string; + name: string; + key: string; + icon: string; + index: number; appName: string; + processDefinitionId: string; state: string; sort: string; assignment: string; @@ -24,6 +30,11 @@ export class QueryModel { constructor(obj?: any) { if (obj) { + this.id = obj.id || Math.random().toString(36).substr(2, 9); + this.name = obj.name || null; + this.key = obj.key || null; + this.icon = obj.icon || null; + this.index = obj.index || null; this.appName = obj.appName || null; this.processDefinitionId = obj.processDefinitionId || null; this.state = obj.state || null; @@ -33,39 +44,8 @@ export class QueryModel { } } } -export class TaskFilterCloudRepresentationModel { + +export interface FilterActionType { + actionType: string; id: string; - name: string; - key: string; - icon: string; - query: QueryModel; - - constructor(obj?: any) { - if (obj) { - this.id = obj.id; - this.name = obj.name; - this.key = obj.key; - this.icon = obj.icon; - this.query = new QueryModel(obj.query); - } - } - - hasFilter() { - return !!this.query; - } -} -export class FilterParamsModel { - 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; - } - } } diff --git a/lib/process-services-cloud/src/lib/task-cloud/public-api.ts b/lib/process-services-cloud/src/lib/task-cloud/public-api.ts index 31364da8b6..2f78e32fc6 100644 --- a/lib/process-services-cloud/src/lib/task-cloud/public-api.ts +++ b/lib/process-services-cloud/src/lib/task-cloud/public-api.ts @@ -16,5 +16,7 @@ */ export * from './task-filters-cloud/task-filters-cloud.component'; +export * from './task-filters-cloud/edit-task-filter-cloud.component'; export * from './models/filter-cloud.model'; +export * from './services/task-filter-cloud.service'; export * from './task-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/task-cloud/services/task-filter-cloud.service.ts b/lib/process-services-cloud/src/lib/task-cloud/services/task-filter-cloud.service.ts index cbab590374..ff3403fcdb 100644 --- a/lib/process-services-cloud/src/lib/task-cloud/services/task-filter-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task-cloud/services/task-filter-cloud.service.ts @@ -18,7 +18,7 @@ import { StorageService, JwtHelperService } from '@alfresco/adf-core'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { TaskFilterCloudRepresentationModel, QueryModel } from '../models/filter-cloud.model'; +import { TaskFilterCloudModel } from '../models/filter-cloud.model'; @Injectable() export class TaskFilterCloudService { @@ -31,7 +31,7 @@ export class TaskFilterCloudService { * @param appName Name of the target app * @returns Observable of default filters just created */ - public createDefaultFilters(appName: string): Observable { + public createDefaultFilters(appName: string): Observable { let myTasksFilter = this.getMyTasksFilterInstance(appName); this.addFilter(myTasksFilter); @@ -46,7 +46,7 @@ export class TaskFilterCloudService { * @param appName Name of the target app * @returns Observable of task filter details */ - getTaskListFilters(appName?: string): Observable { + getTaskListFilters(appName?: string): Observable { const username = this.getUsername(); let key = `task-filters-${appName}-${username}`; const filters = JSON.parse(this.storage.getItem(key) || '[]'); @@ -56,14 +56,22 @@ export class TaskFilterCloudService { }); } + getTaskFilterById(appName: string, id: string): TaskFilterCloudModel { + const username = this.getUsername(); + let key = `task-filters-${appName}-${username}`; + let filters = []; + filters = JSON.parse(this.storage.getItem(key)) || []; + return filters.filter((filterTmp: TaskFilterCloudModel) => id === filterTmp.id)[0]; + } + /** * Adds a new task filter * @param filter The new filter to add * @returns Details of task filter just added */ - addFilter(filter: TaskFilterCloudRepresentationModel): Observable { + addFilter(filter: TaskFilterCloudModel): Observable { const username = this.getUsername(); - const key = `task-filters-${filter.query.appName}-${username}`; + const key = `task-filters-${filter.appName}-${username}`; let filters = JSON.parse(this.storage.getItem(key) || '[]'); filters.push(filter); @@ -76,6 +84,35 @@ export class TaskFilterCloudService { }); } + /** + * Update task filter + * @param filter The new filter to update + */ + updateFilter(filter: TaskFilterCloudModel) { + const username = this.getUsername(); + const key = `task-filters-${filter.appName}-${username}`; + if (key) { + let filters = JSON.parse(this.storage.getItem(key) || '[]'); + let itemIndex = filters.findIndex((flt: TaskFilterCloudModel) => flt.id === filter.id); + filters[itemIndex] = filter; + this.storage.setItem(key, JSON.stringify(filters)); + } + } + + /** + * Delete task filter + * @param filter The new filter to delete + */ + deleteFilter(filter: TaskFilterCloudModel) { + const username = this.getUsername(); + const key = `task-filters-${filter.appName}-${username}`; + 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)); + } + } + getUsername(): string { return this.getValueFromToken('preferred_username'); } @@ -95,22 +132,17 @@ export class TaskFilterCloudService { * @param appName Name of the target app * @returns The newly created filter */ - getMyTasksFilterInstance(appName: string): TaskFilterCloudRepresentationModel { + getMyTasksFilterInstance(appName: string): TaskFilterCloudModel { const username = this.getUsername(); - return new TaskFilterCloudRepresentationModel({ - id: Math.random().toString(36).substr(2, 9), + return new TaskFilterCloudModel({ name: 'ADF_CLOUD_TASK_FILTERS.MY_TASKS', key: 'my-tasks', icon: 'inbox', - query: new QueryModel( - { - appName: appName, - state: 'ASSIGNED', - assignment: username, - sort: 'id', - order: 'ASC' - } - ) + appName: appName, + state: 'ASSIGNED', + assignment: username, + sort: 'id', + order: 'ASC' }); } @@ -119,21 +151,16 @@ export class TaskFilterCloudService { * @param appName Name of the target app * @returns The newly created filter */ - getCompletedTasksFilterInstance(appName: string): TaskFilterCloudRepresentationModel { - return new TaskFilterCloudRepresentationModel({ - id: Math.random().toString(36).substr(2, 9), + getCompletedTasksFilterInstance(appName: string): TaskFilterCloudModel { + return new TaskFilterCloudModel({ name: 'ADF_CLOUD_TASK_FILTERS.COMPLETED_TASKS', key: 'completed-tasks', icon: 'done', - query: new QueryModel( - { - appName: appName, - state: 'COMPLETED', - assignment: '', - sort: 'id', - order: 'ASC' - } - ) + appName: appName, + state: 'COMPLETED', + assignment: '', + sort: 'id', + order: 'ASC' }); } } diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-cloud.module.ts b/lib/process-services-cloud/src/lib/task-cloud/task-cloud.module.ts index ecb442f243..98335e645a 100644 --- a/lib/process-services-cloud/src/lib/task-cloud/task-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/task-cloud/task-cloud.module.ts @@ -16,17 +16,24 @@ */ import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; +import { FlexLayoutModule } from '@angular/flex-layout'; import { TaskFiltersCloudComponent } from './task-filters-cloud/task-filters-cloud.component'; import { MaterialModule } from '../material.module'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateLoaderService, LogService, StorageService } from '@alfresco/adf-core'; import { TaskFilterCloudService } from './services/task-filter-cloud.service'; import { HttpClientModule } from '@angular/common/http'; +import { EditTaskFilterCloudComponent } from './task-filters-cloud/edit-task-filter-cloud.component'; +import { TaskFilterDialogCloudComponent } from './task-filters-cloud/task-filter-dialog-cloud.component'; @NgModule({ imports: [ + FormsModule, + ReactiveFormsModule, HttpClientModule, CommonModule, + FlexLayoutModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, @@ -35,9 +42,11 @@ import { HttpClientModule } from '@angular/common/http'; }), MaterialModule ], - declarations: [TaskFiltersCloudComponent], - - exports: [TaskFiltersCloudComponent], - providers: [TaskFilterCloudService, LogService, StorageService] + declarations: [TaskFiltersCloudComponent, EditTaskFilterCloudComponent, TaskFilterDialogCloudComponent], + exports: [TaskFiltersCloudComponent, EditTaskFilterCloudComponent], + providers: [TaskFilterCloudService, LogService, StorageService], + entryComponents: [ + TaskFilterDialogCloudComponent + ] }) export class TaskCloudModule { } diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.html b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.html new file mode 100644 index 0000000000..9ef9afd3a1 --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.html @@ -0,0 +1,67 @@ + + + + {{taskFilter.name | translate}} + + {{ 'ADF_CLOUD_EDIT_TASK_FILTER.TITLE' | translate}} + + +
+
+ + + + {{ state.label }} + + + + + + + + + + + + + + + + {{ column.label }} + + + + + + + {{ direction }} + + + +
+ + + +
+
+
+
+
diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.scss b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.spec.ts new file mode 100644 index 0000000000..0b866dd476 --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.spec.ts @@ -0,0 +1,286 @@ +/*! + * @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 { TaskFilterCloudModel } from '../models/filter-cloud.model'; +import { TaskCloudModule } from './../task-cloud.module'; +import { EditTaskFilterCloudComponent } from './edit-task-filter-cloud.component'; +import { TaskFilterCloudService } from '../services/task-filter-cloud.service'; +import { MatDialog } from '@angular/material'; +import { of } from 'rxjs'; +import { TaskFilterDialogCloudComponent } from './task-filter-dialog-cloud.component'; + +describe('EditTaskFilterCloudComponent', () => { + let component: EditTaskFilterCloudComponent; + let service: TaskFilterCloudService; + let fixture: ComponentFixture; + let dialog: MatDialog; + + let fakeFilter = new TaskFilterCloudModel({ + name: 'FakeInvolvedTasks', + icon: 'adjust', + id: 10, + state: 'CREATED', + appName: 'app-name', + processDefinitionId: 'process-def-id', + assignment: 'fake-involved', + order: 'ASC', + sort: 'id' + }); + + setupTestBed({ + imports: [ProcessServiceCloudTestingModule, TaskCloudModule], + providers: [MatDialog] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditTaskFilterCloudComponent); + component = fixture.componentInstance; + service = TestBed.get(TaskFilterCloudService); + dialog = TestBed.get(MatDialog); + spyOn(dialog, 'open').and.returnValue({ afterClosed() { return of({ + action: TaskFilterDialogCloudComponent.ACTION_SAVE, + icon: 'icon', + name: 'fake-name' + }); }}); + spyOn(service, 'getTaskFilterById').and.returnValue(fakeFilter); + }); + + it('should create EditTaskFilterCloudComponent', () => { + expect(component instanceof EditTaskFilterCloudComponent).toBeTruthy(); + }); + + it('should fetch task filter by taskId', async(() => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(component.taskFilter.name).toEqual('FakeInvolvedTasks'); + expect(component.taskFilter.icon).toEqual('adjust'); + expect(component.taskFilter.state).toEqual('CREATED'); + expect(component.taskFilter.order).toEqual('ASC'); + expect(component.taskFilter.sort).toEqual('id'); + }); + })); + + it('should display filter name as title', () => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + const title = fixture.debugElement.nativeElement.querySelector('#adf-edit-task-filter-title-id'); + const subTitle = fixture.debugElement.nativeElement.querySelector('#adf-edit-task-filter-sub-title-id'); + expect(title).toBeDefined(); + expect(subTitle).toBeDefined(); + expect(title.innerText).toEqual('FakeInvolvedTasks'); + expect(subTitle.innerText).toEqual('ADF_CLOUD_EDIT_TASK_FILTER.TITLE'); + }); + + describe('EditTaskFilter form', () => { + + beforeEach(() => { + let change = new SimpleChange(undefined, '10', true); + component.ngOnChanges({ 'id': change }); + fixture.detectChanges(); + }); + + it('should define editTaskFilter form ', () => { + expect(component.editTaskFilterForm).toBeDefined(); + }); + + it('should create editTaskFilter form with given input ', async(() => { + fixture.detectChanges(); + fixture.whenStable().then(() => { + const stateController = component.editTaskFilterForm.get('state'); + const sortController = component.editTaskFilterForm.get('sort'); + const orderController = component.editTaskFilterForm.get('order'); + const assignmentController = component.editTaskFilterForm.get('assignment'); + expect(component.editTaskFilterForm).toBeDefined(); + expect(stateController).toBeDefined(); + expect(sortController).toBeDefined(); + expect(orderController).toBeDefined(); + expect(assignmentController).toBeDefined(); + + expect(stateController.value).toBe('CREATED'); + expect(sortController.value).toBe('id'); + expect(orderController.value).toBe('ASC'); + expect(assignmentController.value).toBe('fake-involved'); + }); + })); + + it('should disable save button if the task 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 task 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(() => { + fixture.detectChanges(); + let expansionPanel = fixture.debugElement.nativeElement.querySelector('mat-expansion-panel-header'); + expansionPanel.click(); + fixture.whenStable().then(() => { + let deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + expect(deleteButton.disabled).toBe(false); + }); + })); + + it('should display current task 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-task-filter-state-id'); + let assignmentElement = fixture.debugElement.nativeElement.querySelector('#adf-task-filter-assignment-id'); + let sortElement = fixture.debugElement.nativeElement.querySelector('#adf-task-filter-sort-id'); + let orderElement = fixture.debugElement.nativeElement.querySelector('#adf-task-filter-order-id'); + expect(stateElement).toBeDefined(); + expect(assignmentElement).toBeDefined(); + expect(sortElement).toBeDefined(); + expect(orderElement).toBeDefined(); + expect(stateElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_TASK_FILTER.LABEL.STATUS'); + expect(sortElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_TASK_FILTER.LABEL.COLUMN'); + expect(orderElement.innerText.trim()).toBe('ADF_CLOUD_EDIT_TASK_FILTER.LABEL.DIRECTION'); + }); + })); + + 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-task-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(7); + }); + })); + + 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-task-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(5); + }); + })); + + 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-task-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-task-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + stateOptions[3].nativeElement.click(); + fixture.detectChanges(); + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-id'); + saveButton.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + 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-task-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + let deleteButton = fixture.debugElement.nativeElement.querySelector('#adf-delete-id'); + deleteButton.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(deleteFilterSpy).toHaveBeenCalled(); + expect(deleteSpy).toHaveBeenCalled(); + }); + })); + + it('should emit saveAs event and add filter on click 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-task-filter-state-id .mat-select-trigger')).nativeElement; + stateElement.click(); + fixture.detectChanges(); + const saveButton = fixture.debugElement.nativeElement.querySelector('#adf-save-as-id'); + const stateOptions = fixture.debugElement.queryAll(By.css('.mat-option-text')); + stateOptions[3].nativeElement.click(); + fixture.detectChanges(); + saveButton.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(saveAsFilterSpy).toHaveBeenCalled(); + expect(saveAsSpy).toHaveBeenCalled(); + expect(dialog.open).toHaveBeenCalled(); + }); + })); + }); +}); diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.ts b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.ts new file mode 100644 index 0000000000..eda766654c --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.ts @@ -0,0 +1,172 @@ +/*! + * @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, OnChanges, Input, Output, EventEmitter, SimpleChanges } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { TaskFilterCloudModel, FilterActionType } from './../models/filter-cloud.model'; +import { TaskFilterCloudService } from '../services/task-filter-cloud.service'; +import { MatDialog } from '@angular/material'; +import { TaskFilterDialogCloudComponent } from './task-filter-dialog-cloud.component'; +import { TranslationService } from '@alfresco/adf-core'; +import { debounceTime } from 'rxjs/operators'; + +@Component({ + selector: 'adf-cloud-edit-task-filter', + templateUrl: './edit-task-filter-cloud.component.html', + styleUrls: ['./edit-task-filter-cloud.component.scss'] +}) +export class EditTaskFilterCloudComponent implements OnChanges { + + public static ACTION_SAVE = 'SAVE'; + public static ACTION_SAVE_AS = 'SAVE_AS'; + public static ACTION_DELETE = 'DELETE'; + + @Input() + appName: string; + + @Input() + id: string; + + taskFilter: TaskFilterCloudModel; + changedTaskFilter: TaskFilterCloudModel; + + /** Emitted when an task filter property changes. */ + @Output() + filterChange: EventEmitter = new EventEmitter(); + + /** Emitted when an filter action occurs i.e Save, SaveAs, Delete. */ + @Output() + action: EventEmitter = new EventEmitter(); + + columns = [ + {key: 'id', label: 'ID'}, + {key: 'name', label: 'NAME'}, + {key: 'createdDate', label: 'Created Date'}, + {key: 'priority', label: 'PRIORITY'}, + {key: 'processDefinitionId', label: 'PROCESS DEFINITION ID'} + ]; + + status = [ + {label: 'ALL', value: ''}, + {label: 'CREATED', value: 'CREATED'}, + {label: 'CANCELLED', value: 'CANCELLED'}, + {label: 'ASSIGNED', value: 'ASSIGNED'}, + {label: 'SUSPENDED', value: 'SUSPENDED'}, + {label: 'COMPLETED', value: 'COMPLETED'}, + {label: 'DELETED', value: 'DELETED'} + ]; + + directions = ['ASC', 'DESC']; + formHasBeenChanged = false; + editTaskFilterForm: FormGroup; + + constructor( + private formBuilder: FormBuilder, + public dialog: MatDialog, + private translateService: TranslationService, + private taskFilterCloudService: TaskFilterCloudService) {} + + ngOnChanges(changes: SimpleChanges) { + const id = changes['id']; + if (id && id.currentValue !== id.previousValue) { + this.retrieveTaskFilter(); + this.buildForm(); + } + } + + buildForm() { + this.formHasBeenChanged = false; + this.editTaskFilterForm = this.formBuilder.group({ + state: this.taskFilter.state, + appName: this.taskFilter.appName, + processDefinitionId: this.taskFilter.processDefinitionId, + assignment: this.taskFilter.assignment, + sort: this.taskFilter.sort, + order: this.taskFilter.order + }); + this.onFilterChange(); + } + + retrieveTaskFilter() { + this.taskFilter = this.taskFilterCloudService.getTaskFilterById(this.appName, this.id); + } + + /** + * Check for edit task filter form changes + */ + onFilterChange() { + this.editTaskFilterForm.valueChanges + .pipe(debounceTime(300)) + .subscribe((formValues: TaskFilterCloudModel) => { + this.changedTaskFilter = new TaskFilterCloudModel(Object.assign({}, this.taskFilter, formValues)); + this.formHasBeenChanged = !this.compareFilters(this.changedTaskFilter, this.taskFilter); + this.filterChange.emit(this.changedTaskFilter); + }); + } + + /** + * Check if both filters are same + */ + compareFilters(editedQuery, currentQuery): boolean { + return JSON.stringify(editedQuery).toLowerCase() === JSON.stringify(currentQuery).toLowerCase(); + } + + onSave() { + this.taskFilterCloudService.updateFilter(this.changedTaskFilter); + this.action.emit({actionType: EditTaskFilterCloudComponent.ACTION_SAVE, id: this.changedTaskFilter.id}); + } + + onDelete() { + this.taskFilterCloudService.deleteFilter(this.taskFilter); + this.action.emit({actionType: EditTaskFilterCloudComponent.ACTION_DELETE, id: this.taskFilter.id}); + } + + onSaveAs() { + const dialogRef = this.dialog.open(TaskFilterDialogCloudComponent, { + data: { + name: this.translateService.instant(this.taskFilter.name) + }, + height: 'auto', + minWidth: '30%' + }); + dialogRef.afterClosed().subscribe( (result) => { + if (result && result.action === TaskFilterDialogCloudComponent.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.changedTaskFilter, newFilter); + this.taskFilterCloudService.addFilter(filter); + this.action.emit({actionType: EditTaskFilterCloudComponent.ACTION_SAVE_AS, id: filter.id}); + } + }); + } + + getSanitizeFilterName(filterName) { + const nameWithHyphen = this.replaceSpaceWithHyphen(filterName.trim()); + return nameWithHyphen.toLowerCase(); + } + + replaceSpaceWithHyphen(name) { + const regExt = new RegExp(' ', 'g'); + return name.replace(regExt, '-'); + } +} diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.html b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.html new file mode 100644 index 0000000000..e72e0bc1bd --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.html @@ -0,0 +1,22 @@ +
+ + {{ 'ADF_CLOUD_EDIT_TASK_FILTER.DIALOG.TITLE' | translate}} + + + +
+ + + +
+
+ + + + +
+
diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.scss b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.scss new file mode 100644 index 0000000000..52de875d6e --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.scss @@ -0,0 +1,9 @@ +.adf-task-filter-dialog .mat-card { + padding: 0; + box-shadow: none; +} + +.adf-task-filter-dialog .mat-card-content { + padding: 0; + box-shadow: none; +} diff --git a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.spec.ts new file mode 100644 index 0000000000..f3418bab1e --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.spec.ts @@ -0,0 +1,119 @@ +/*! + * @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 { ComponentFixture, TestBed, async } from '@angular/core/testing'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { TaskFilterDialogCloudComponent } from './task-filter-dialog-cloud.component'; +import { TaskCloudModule } from '../task-cloud.module'; +import { setupTestBed } from '@alfresco/adf-core'; +import { ProcessServiceCloudTestingModule } from '../../testing/process-service-cloud.testing.module'; + +describe('TaskFilterDialogCloudComponent', () => { + let component: TaskFilterDialogCloudComponent; + let fixture: ComponentFixture; + + const mockDialogRef = { + close: jasmine.createSpy('close'), + open: jasmine.createSpy('open') + }; + + const mockDialogData = { + data: {name: 'Mock-Title'} + }; + + setupTestBed({ + imports: [ProcessServiceCloudTestingModule, TaskCloudModule], + providers: [ + { provide: MatDialogRef, useValue: mockDialogRef }, + { provide: MAT_DIALOG_DATA, useValue: mockDialogData } + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TaskFilterDialogCloudComponent); + component = fixture.componentInstance; + }); + + it('should create TaskFilterDialogCloudComponent', () => { + expect(component instanceof TaskFilterDialogCloudComponent).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-task-filter-dialog-title'); + expect(titleElement.textContent).toEqual(' ADF_CLOUD_EDIT_TASK_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/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.ts b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.ts new file mode 100644 index 0000000000..7a3bb67b29 --- /dev/null +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-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-task-filter-dialog', + templateUrl: './task-filter-dialog-cloud.component.html', + styleUrls: ['./task-filter-dialog-cloud.component.scss'] +}) +export class TaskFilterDialogCloudComponent 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: TaskFilterDialogCloudComponent.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/task-cloud/task-filters-cloud/task-filters-cloud.component.html b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filters-cloud.component.html index 8043e9d5d2..d1db317094 100644 --- a/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filters-cloud.component.html +++ b/lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filters-cloud.component.html @@ -1,6 +1,6 @@