From 6f526c38623c0b33e00c518a2ee0959ae422e980 Mon Sep 17 00:00:00 2001 From: siva kumar Date: Wed, 5 Dec 2018 20:57:21 +0530 Subject: [PATCH] [ADF-3773] Filter definition in a component APS2 (#4016) * * Genearated EditTaskFilterCloudComponent * * Added unit tests to the editTaskFiltercomponent * Added unit tests to the taskFilterDialog * Added id selector * * Added translation keys to the editTaskFilter component* Added translation keys related to the editTask in the en.json file* Changed FilterRepresentationModel to TaskFilterCloudRepresentationModel* Refactored editTaskFilterComponent* Created a deleteFilter method in the taskService * * Refactored editTaskFilterComponent * * used new editTaskFilterCloud component in the demo shell * * Refactored editTaskFilter component* Updated unit tests * Refresh the filters after the action Reset the values after the EditComponentChanges Improve the code * * Added translate keys in demo shell for edittaskDialog component * Modified translate keys for editTaskFilterCLoud component * * Added documentation to the editTaskFilter component.* Fixed a typo.* Fixed Failing Test cases. * Added a EditTaskFilterCloud png * rebase to dev fix bugs and improve integration * * Fixed tsLint css error * * Fixed tslint css error * Fixed one unit test * Move the concern of save delete saveAs into the component fix integration with Demo shell fix bugs * * Updated unit test to the recent changes * * Updated editTaskFIlter doc * Added unit tests to the taskFIlterDialog component * * Updated editTaskFIlter doc* Added unit tests to the taskFIlterDialog component * * Merged task filter models to a single model * * Updated tests with new taskfilter model * * Updated documentation for new taskfilter model * * Used new taskfilter model in the demo * * Improved filter selection method * * Removed unnecessory tanslate keys from demo shell * Modified filterCloudModel * fixed unit tests to the recent changes * * Improved change handling for filter properties * * Improved unit tests --- demo-shell/src/app/app.module.ts | 1 - .../task-list-cloud-demo.component.html | 80 ++--- .../task-list-cloud-demo.component.ts | 121 ++++---- .../edit-task-filter-cloud.component.png | Bin 0 -> 12605 bytes .../edit-task-filter-cloud.component.md | 50 +++ .../task-filters-cloud.component.md | 6 +- .../src/lib/i18n/en.json | 19 ++ .../src/lib/material.module.ts | 4 +- .../task-cloud/models/filter-cloud.model.ts | 52 +--- .../src/lib/task-cloud/public-api.ts | 2 + .../services/task-filter-cloud.service.ts | 85 ++++-- .../src/lib/task-cloud/task-cloud.module.ts | 17 +- .../edit-task-filter-cloud.component.html | 67 ++++ .../edit-task-filter-cloud.component.scss | 0 .../edit-task-filter-cloud.component.spec.ts | 286 ++++++++++++++++++ .../edit-task-filter-cloud.component.ts | 172 +++++++++++ .../task-filter-dialog-cloud.component.html | 22 ++ .../task-filter-dialog-cloud.component.scss | 9 + ...task-filter-dialog-cloud.component.spec.ts | 119 ++++++++ .../task-filter-dialog-cloud.component.ts | 66 ++++ .../task-filters-cloud.component.html | 2 +- .../task-filters-cloud.component.spec.ts | 39 +-- .../task-filters-cloud.component.ts | 24 +- 23 files changed, 1007 insertions(+), 236 deletions(-) create mode 100644 docs/docassets/images/edit-task-filter-cloud.component.png create mode 100644 docs/process-services-cloud/edit-task-filter-cloud.component.md create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.html create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.scss create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.spec.ts create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/edit-task-filter-cloud.component.ts create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.html create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.scss create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.spec.ts create mode 100644 lib/process-services-cloud/src/lib/task-cloud/task-filters-cloud/task-filter-dialog-cloud.component.ts 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 0000000000000000000000000000000000000000..7752514f9f814e28f9bde5fcb78a1dea34841a7d GIT binary patch literal 12605 zcmdsecR1E<7`7HI$w(PdvS;=l=@Frjz01lLl1;rOD@l@&k?bu}BpOs!l9@fSvt^I( z^uFI8-*J53pWh$f@%@gY-lvD>_uRkxzOM5+&-1$8VD-z2qz7pa5)l!RUQ{AnAtKsq zkJr)rcjNEIAcIf%&mLF#i(32l@9!E=>&HK7ZYt>A)O51C>3+?{lIXgllY=FXtGSD% zrK790)6JPZl`=#`r-&{R&S`l(pXzZp(p=t>opqNd=HgcPr6Nb)|4D~ji)!C%t?om* zC#@$-+Po%nbtcF1wL`QgvM8%|X=_bn92VUj5~5D7wb#Pwld}B$`jAgt+@X*vI=QLI z)wkhaFMVHq-ndGC@asbD^?Om#(d~uiiaYBiBD!sL^^Mz}e_s;yvhCOS@0GG#(0@Nx z-z`t|?_0Mijwb*2vnRKY?)&#u(%yUQ|GmX>im>b7SM0k^?`#Yak=%j*7jGq_D*o@q zng8@<=fuXwMtws=d!BKZNBg&kGi+)JQs!SCi0Zhk&JXW9L|yLEzBJY4>*Mpp_Az$s z&#xl3OR*^}8bm*AEd+i|b-fuH8aj07&@cOv!b0atzfG^d6Mt`MOZ%?1baonCx^#)f zLDFOPskY9gYf>fztN@x_5bSgWe4s+L|+$ayOAfcy9J^a|xQH8q{hjf}d7 zzJ|x?fA0Tymy&|wS-WA0eP&)>?_1|H3p$2|h5?uM-4Z zUL0=@JQL<~+FVK(cP{<1o0%0AGUT3K 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 F{11T6^V9$U literal 0 HcmV?d00001 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 @@