From 274fa67a531009398c68a4789515381d048d3937 Mon Sep 17 00:00:00 2001 From: Martin Rojas Miguel Angel Date: Tue, 20 Feb 2018 12:45:36 +0100 Subject: [PATCH] TSK-179 Create filtering component and apply filtering on workbasket list. --- admin/package.json | 2 +- admin/src/app/app.module.ts | 7 +- .../app/services/workbasketservice.service.ts | 55 ++++--- .../app/shared/filter/filter.component.html | 51 ++++++ .../app/shared/filter/filter.component.scss | 7 + .../shared/filter/filter.component.spec.ts | 73 +++++++++ .../src/app/shared/filter/filter.component.ts | 45 ++++++ .../details/workbasket-details.component.html | 2 +- .../details/workbasket-details.component.ts | 8 +- .../list/workbasket-list.component.html | 98 +++++------ .../list/workbasket-list.component.scss | 4 - .../list/workbasket-list.component.spec.ts | 49 +++--- .../list/workbasket-list.component.ts | 152 ++++++++++-------- admin/src/assets/_site.scss | 9 +- 14 files changed, 366 insertions(+), 196 deletions(-) create mode 100644 admin/src/app/shared/filter/filter.component.html create mode 100644 admin/src/app/shared/filter/filter.component.scss create mode 100644 admin/src/app/shared/filter/filter.component.spec.ts create mode 100644 admin/src/app/shared/filter/filter.component.ts diff --git a/admin/package.json b/admin/package.json index 1bf294fe7..6c826507f 100755 --- a/admin/package.json +++ b/admin/package.json @@ -9,7 +9,7 @@ "build:prod": "ng build --environment=prod --no-progress", "test": "./node_modules/.bin/karma start --single-run --browsers Firefox", "test-phantom": "./node_modules/.bin/karma start --single-run --browsers PhantomJS", - "test:watch": "./node_modules/.bin/karma start --browsers Firefox", + "test:watch": "./node_modules/.bin/karma start --browsers Chrome", "lint": "ng lint", "e2e": "ng e2e" }, diff --git a/admin/src/app/app.module.ts b/admin/src/app/app.module.ts index 51be2d8dc..82f9ce105 100644 --- a/admin/src/app/app.module.ts +++ b/admin/src/app/app.module.ts @@ -26,6 +26,7 @@ import { WorkbasketDetailsComponent } from './workbasket/details/workbasket-deta import { WorkbasketInformationComponent } from './workbasket/details/information/workbasket-information.component'; import { NoAccessComponent } from './workbasket/noAccess/no-access.component'; import { SpinnerComponent } from './shared/spinner/spinner.component'; +import { FilterComponent } from './shared/filter/filter.component'; //Shared import { MasterAndDetailComponent} from './shared/masterAndDetail/master-and-detail.component'; @@ -56,7 +57,7 @@ const MODULES = [ HttpClientModule ]; -const COMPONENTS = [ +const DECLARATIONS = [ AppComponent, WorkbasketListComponent, CategorieslistComponent, @@ -70,10 +71,12 @@ const COMPONENTS = [ WorkbasketInformationComponent, NoAccessComponent, SpinnerComponent, + FilterComponent, MapValuesPipe ]; + @NgModule({ - declarations: COMPONENTS, + declarations: DECLARATIONS, imports: MODULES, providers: [ WorkbasketService, diff --git a/admin/src/app/services/workbasketservice.service.ts b/admin/src/app/services/workbasketservice.service.ts index bfdd639b8..8dbaada61 100644 --- a/admin/src/app/services/workbasketservice.service.ts +++ b/admin/src/app/services/workbasketservice.service.ts @@ -10,8 +10,8 @@ import { Subject } from 'rxjs/Subject'; //sort direction export enum Direction{ - ASC = "asc", - DESC = "desc" + ASC = 'asc', + DESC = 'desc' }; @Injectable() @@ -22,20 +22,21 @@ export class WorkbasketService { constructor(private httpClient: HttpClient) { } //Sorting - readonly SORTBY="sortBy"; - readonly ORDER="order"; + readonly SORTBY='sortBy'; + readonly ORDER='order'; //Filtering - readonly NAME="name"; - readonly NAMELIKE="nameLike"; - readonly DESCLIKE="descLike"; - readonly OWNER="owner"; - readonly OWNERLIKE="ownerLike"; - readonly TYPE="type"; - readonly KEY="key"; + readonly NAME='name'; + readonly NAMELIKE='nameLike'; + readonly DESCLIKE='descLike'; + readonly OWNER='owner'; + readonly OWNERLIKE='ownerLike'; + readonly TYPE='type'; + readonly KEY='key'; + readonly KEYLIKE='keyLike'; //Access - readonly REQUIREDPERMISSION="requiredPermission"; + readonly REQUIREDPERMISSION='requiredPermission'; httpOptions = { headers: new HttpHeaders({ @@ -53,10 +54,12 @@ export class WorkbasketService { owner:string = undefined, ownerLike:string = undefined, type:string = undefined, + key:string = undefined, + keyLike:string = undefined, requiredPermission: string = undefined): Observable { return this.httpClient.get(`${environment.taskanaRestUrl}/v1/workbaskets/${this.getWorkbasketSummaryQueryParameters(sortBy, order, name, - nameLike, descLike, owner, ownerLike, type, requiredPermission)}`,this.httpOptions) + nameLike, descLike, owner, ownerLike, type, key, keyLike, requiredPermission)}`,this.httpOptions) } @@ -65,31 +68,31 @@ export class WorkbasketService { } createWorkbasket(workbasket: WorkbasketSummary): Observable { - return this.httpClient.post(environment.taskanaRestUrl + "/v1/workbaskets", workbasket, this.httpOptions); + return this.httpClient.post(environment.taskanaRestUrl + '/v1/workbaskets', workbasket, this.httpOptions); } deleteWorkbasket(id: string) { - return this.httpClient.delete(environment.taskanaRestUrl + "/v1/workbaskets/" + id, this.httpOptions); + return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/' + id, this.httpOptions); } updateWorkbasket(workbasket: WorkbasketSummary): Observable { - return this.httpClient.put(environment.taskanaRestUrl + "/v1/workbaskets/" + workbasket.workbasketId, workbasket, this.httpOptions); + return this.httpClient.put(environment.taskanaRestUrl + '/v1/workbaskets/' + workbasket.workbasketId, workbasket, this.httpOptions); } getAllWorkBasketAuthorizations(id: String): Observable { - return this.httpClient.get(environment.taskanaRestUrl + "/v1/workbaskets/" + id + "/authorizations", this.httpOptions); + return this.httpClient.get(environment.taskanaRestUrl + '/v1/workbaskets/' + id + '/authorizations', this.httpOptions); } createWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable { - return this.httpClient.post(environment.taskanaRestUrl + "/v1/workbaskets/authorizations", workbasketAuthorization, this.httpOptions); + return this.httpClient.post(environment.taskanaRestUrl + '/v1/workbaskets/authorizations', workbasketAuthorization, this.httpOptions); } updateWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization): Observable { - return this.httpClient.put(environment.taskanaRestUrl + "/v1/workbaskets/authorizations/" + workbasketAuthorization.id, workbasketAuthorization, this.httpOptions) + return this.httpClient.put(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.id, workbasketAuthorization, this.httpOptions) } deleteWorkBasketAuthorization(workbasketAuthorization: WorkbasketAuthorization) { - return this.httpClient.delete(environment.taskanaRestUrl + "/v1/workbaskets/authorizations/" + workbasketAuthorization.id, this.httpOptions); + return this.httpClient.delete(environment.taskanaRestUrl + '/v1/workbaskets/authorizations/' + workbasketAuthorization.id, this.httpOptions); } //Service extras @@ -106,11 +109,13 @@ export class WorkbasketService { name: string, nameLike: string, descLike: string, - owner:string, - ownerLike:string, - type:string, + owner: string, + ownerLike: string, + type: string, + key: string, + keyLike: string, requiredPermission: string): string{ - let query: string = "?"; + let query: string = '?'; query += sortBy? `${this.SORTBY}=${sortBy}&`:''; query += order? `${this.ORDER}=${order}&`:''; query += name? `${this.NAME}=${name}&`:''; @@ -119,6 +124,8 @@ export class WorkbasketService { query += owner? `${this.OWNER}=${owner}&`:''; query += ownerLike? `${this.OWNERLIKE}=${ownerLike}&`:''; query += type? `${this.TYPE}=${type}&`:''; + query += key? `${this.KEY}=${key}&`:''; + query += keyLike? `${this.KEYLIKE}=${keyLike}&`:''; query += requiredPermission? `${this.REQUIREDPERMISSION}=${requiredPermission}&`:''; if(query.lastIndexOf('&') === query.length-1){ diff --git a/admin/src/app/shared/filter/filter.component.html b/admin/src/app/shared/filter/filter.component.html new file mode 100644 index 000000000..903e912c3 --- /dev/null +++ b/admin/src/app/shared/filter/filter.component.html @@ -0,0 +1,51 @@ +
+
+ +
+ +
+
+ +
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/admin/src/app/shared/filter/filter.component.scss b/admin/src/app/shared/filter/filter.component.scss new file mode 100644 index 000000000..dd7fb54bc --- /dev/null +++ b/admin/src/app/shared/filter/filter.component.scss @@ -0,0 +1,7 @@ + +.dropdown-menu-users { + &>li{ + margin-bottom: 5px; + } + margin-left: 15px; +} diff --git a/admin/src/app/shared/filter/filter.component.spec.ts b/admin/src/app/shared/filter/filter.component.spec.ts new file mode 100644 index 000000000..f6e7178d7 --- /dev/null +++ b/admin/src/app/shared/filter/filter.component.spec.ts @@ -0,0 +1,73 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; +import { AngularSvgIconModule } from 'angular-svg-icon'; +import { HttpClientModule } from '@angular/common/http'; +import { HttpModule } from '@angular/http'; + +import { FilterComponent, FilterModel } from './filter.component'; + +describe('FilterComponent', () => { + let component: FilterComponent, + fixture: ComponentFixture, + debugElement: any; + + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FilterComponent ], + imports: [AngularSvgIconModule, FormsModule, HttpClientModule, HttpModule ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FilterComponent); + component = fixture.componentInstance; + debugElement = fixture.debugElement.nativeElement; + fixture.detectChanges(); + })); + + afterEach(() => { + document.body.removeChild(debugElement); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create a component with id target', () => { + expect(debugElement.querySelector('#some-id')).toBeNull(); + component.target = 'some-id' + fixture.detectChanges(); + expect(debugElement.querySelector('#some-id')).toBeDefined(); + }); + + it('should have filter by: name, description, key, owner and type defined', () => { + expect(debugElement.querySelector('#wb-display-name-filter')).toBeDefined(); + expect(debugElement.querySelector('#wb-display-description-filter')).toBeDefined(); + expect(debugElement.querySelector('#wb-display-key-filter')).toBeDefined(); + expect(debugElement.querySelector('#wb-display-owner-filter')).toBeDefined(); + expect(debugElement.querySelector('#wb-display-type-filter')).toBeDefined(); + }); + + it('should be able to clear all fields after pressing clear button', () => { + component.filter = new FilterModel('a','a','a','a'); + debugElement.querySelector('[title="Clear"]').click(); + expect(component.filter.name).toBe(''); + expect(component.filter.description).toBe(''); + expect(component.filter.owner).toBe(''); + expect(component.filter.type).toBe(''); + }); + + it('should be able to select a type and return it based on a number', () => { + expect(component).toBeTruthy(); + }); + + it('should be able to emit a filter after clicking on search button', (done) => { + component.filter = new FilterModel('a', 'name1', 'a', 'a'); + component.performFilter.subscribe(filter => { + expect(filter.name).toBe('name1'); + done(); + }) + debugElement.querySelector('[title="Search"]').click(); + }); + +}); diff --git a/admin/src/app/shared/filter/filter.component.ts b/admin/src/app/shared/filter/filter.component.ts new file mode 100644 index 000000000..292b68772 --- /dev/null +++ b/admin/src/app/shared/filter/filter.component.ts @@ -0,0 +1,45 @@ +import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'; + +export class FilterModel { + type:string; + name:string; + description:string; + owner:string; + constructor(type:string = '', name:string = '', description:string = '', owner:string = ''){ + this.type = type; + this.name = name; + this.description= description; + this.owner = owner; + } +} + +@Component({ + selector: 'taskana-filter', + templateUrl: './filter.component.html', + styleUrls: ['./filter.component.scss'] +}) +export class FilterComponent{ + + constructor() { } + + filter: FilterModel = new FilterModel(); + + @Input() + target:string; + + @Output() + performFilter = new EventEmitter(); + + selectType(type: number){ + this.filter.type = type === 0 ? 'PERSONAL': type === 1? 'GROUP': ''; + } + + clear(){ + this.filter = new FilterModel(); + } + + search(){ + this.performFilter.emit(this.filter); + } + +} diff --git a/admin/src/app/workbasket/details/workbasket-details.component.html b/admin/src/app/workbasket/details/workbasket-details.component.html index 572670f81..502a2c074 100644 --- a/admin/src/app/workbasket/details/workbasket-details.component.html +++ b/admin/src/app/workbasket/details/workbasket-details.component.html @@ -1,6 +1,6 @@
- +