diff --git a/web/src/app/administration/classification/details/classification-details.component.spec.ts b/web/src/app/administration/classification/details/classification-details.component.spec.ts index 07bec618f..01d06569e 100644 --- a/web/src/app/administration/classification/details/classification-details.component.spec.ts +++ b/web/src/app/administration/classification/details/classification-details.component.spec.ts @@ -18,6 +18,8 @@ import { TreeNodeModel } from 'app/models/tree-node'; import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { AlertService } from 'app/services/alert/alert.service'; import { TreeService } from 'app/services/tree/tree.service'; +import { ClassificationTypesService } from 'app/services/classification-types/classification-types.service'; + @Component({ selector: 'taskana-dummy-detail', @@ -36,7 +38,7 @@ describe('ClassificationDetailsComponent', () => { const treeNodes: Array = new Array(new TreeNodeModel()); const classificationTypes: Array = new Array('type1', 'type2'); let classificationsSpy, classificationsTypesSpy; - let classificationsService; + let classificationsService, classificationTypesService; let treeService; beforeEach(async(() => { @@ -44,7 +46,7 @@ describe('ClassificationDetailsComponent', () => { imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes)], declarations: [ClassificationDetailsComponent, SpinnerComponent, DummyDetailComponent], providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService, - TreeService] + TreeService, ClassificationTypesService] }) .compileComponents(); })); @@ -53,8 +55,10 @@ describe('ClassificationDetailsComponent', () => { fixture = TestBed.createComponent(ClassificationDetailsComponent); component = fixture.componentInstance; classificationsService = TestBed.get(ClassificationsService); + classificationTypesService = TestBed.get(ClassificationTypesService); classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes)); - classificationsTypesSpy = spyOn(classificationsService, 'getClassificationTypes').and.returnValue(Observable.of(classificationTypes)); + classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes') + .and.returnValue(Observable.of(classificationTypes)); spyOn(classificationsService, 'deleteClassification').and.returnValue(Observable.of(true)); treeService = TestBed.get(TreeService); diff --git a/web/src/app/administration/classification/details/classification-details.component.ts b/web/src/app/administration/classification/details/classification-details.component.ts index 4c09820f1..b39db51c5 100644 --- a/web/src/app/administration/classification/details/classification-details.component.ts +++ b/web/src/app/administration/classification/details/classification-details.component.ts @@ -16,6 +16,7 @@ import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { AlertService } from 'app/services/alert/alert.service'; import { TreeService } from 'app/services/tree/tree.service'; +import { ClassificationTypesService } from 'app/services/classification-types/classification-types.service'; @Component({ selector: 'taskana-classification-details', @@ -48,12 +49,13 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private errorModalService: ErrorModalService, private requestInProgressService: RequestInProgressService, private alertService: AlertService, - private treeService: TreeService) { } + private treeService: TreeService, + private classificationTypeService: ClassificationTypesService) { } ngOnInit() { - this.classificationsService.getClassificationTypes().subscribe((classificationTypes: Array) => { + this.classificationTypeService.getClassificationTypes().subscribe((classificationTypes: Array) => { this.classificationTypes = classificationTypes; }) this.classificationSelectedSubscription = this.classificationsService.getSelectedClassification() @@ -161,7 +163,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private getClassificationInformation(classificationIdSelected: string) { if (this.action === ACTION.CREATE) { // CREATE this.classification = new ClassificationDefinition(); - this.selectedClassificationSubscription = this.classificationsService.getSelectedClassificationType().subscribe(value => { + this.selectedClassificationSubscription = this.classificationTypeService.getSelectedClassificationType().subscribe(value => { if (this.classification) { this.classification.type = value; } }); this.addDateToClassification(); diff --git a/web/src/app/administration/classification/master/list/classification-list.component.spec.ts b/web/src/app/administration/classification/master/list/classification-list.component.spec.ts index 097947edf..2fbbaae0f 100644 --- a/web/src/app/administration/classification/master/list/classification-list.component.spec.ts +++ b/web/src/app/administration/classification/master/list/classification-list.component.spec.ts @@ -19,6 +19,7 @@ import { ClassificationsService } from 'app/services/classifications/classificat import { ClassificationDefinitionService } from 'app/services/classification-definition/classification-definition.service'; import { DomainService } from 'app/services/domains/domain.service'; import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; +import { ClassificationTypesService } from 'app/services/classification-types/classification-types.service'; @Component({ selector: 'taskana-tree', @@ -48,7 +49,7 @@ describe('ClassificationListComponent', () => { const treeNodes: Array = new Array(new TreeNodeModel()); const classificationTypes: Array = new Array('type1', 'type2'); let classificationsSpy, classificationsTypesSpy; - let classificationsService; + let classificationsService, classificationTypesService; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -57,7 +58,7 @@ describe('ClassificationListComponent', () => { imports: [HttpClientModule, RouterTestingModule.withRoutes(routes)], providers: [ HttpClient, WorkbasketDefinitionService, AlertService, ClassificationsService, DomainService, ClassificationDefinitionService, - ErrorModalService + ErrorModalService, ClassificationTypesService ] }) .compileComponents(); @@ -68,8 +69,10 @@ describe('ClassificationListComponent', () => { component = fixture.componentInstance; classificationsService = TestBed.get(ClassificationsService); + classificationTypesService = TestBed.get(ClassificationTypesService); classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes)); - classificationsTypesSpy = spyOn(classificationsService, 'getClassificationTypes').and.returnValue(Observable.of(classificationTypes)); + classificationsTypesSpy = spyOn(classificationTypesService, 'getClassificationTypes') + .and.returnValue(Observable.of(classificationTypes)); fixture.detectChanges(); }); diff --git a/web/src/app/administration/classification/master/list/classification-list.component.ts b/web/src/app/administration/classification/master/list/classification-list.component.ts index 36ebe01e3..0b503d134 100644 --- a/web/src/app/administration/classification/master/list/classification-list.component.ts +++ b/web/src/app/administration/classification/master/list/classification-list.component.ts @@ -7,6 +7,7 @@ import { Classification } from 'app/models/classification'; import { TreeNodeModel } from 'app/models/tree-node'; import { ClassificationsService } from 'app/services/classifications/classifications.service'; +import { ClassificationTypesService } from 'app/services/classification-types/classification-types.service'; @Component({ selector: 'taskana-classification-list', @@ -33,7 +34,8 @@ export class ClassificationListComponent implements OnInit, OnDestroy { constructor( private classificationService: ClassificationsService, private router: Router, - private route: ActivatedRoute) { + private route: ActivatedRoute, + private classificationTypeService: ClassificationTypesService) { } ngOnInit() { @@ -42,7 +44,7 @@ export class ClassificationListComponent implements OnInit, OnDestroy { .subscribe(value => { this.performRequest(true); }) - this.selectedClassificationSubscription = this.classificationService.getSelectedClassificationType().subscribe(value => { + this.selectedClassificationSubscription = this.classificationTypeService.getSelectedClassificationType().subscribe(value => { this.classificationTypeSelected = value; this.performRequest(); }) @@ -51,7 +53,7 @@ export class ClassificationListComponent implements OnInit, OnDestroy { selectClassificationType(classificationTypeSelected: string) { this.classifications = []; this.requestInProgress = true; - this.classificationService.selectClassificationType(classificationTypeSelected); + this.classificationTypeService.selectClassificationType(classificationTypeSelected); this.classificationService.getClassifications(true, classificationTypeSelected) .subscribe((classifications: Array) => { this.classifications = classifications; @@ -86,7 +88,7 @@ export class ClassificationListComponent implements OnInit, OnDestroy { return null; } this.classifications = classifications; - this.classificationTypeServiceSubscription = this.classificationService.getClassificationTypes() + this.classificationTypeServiceSubscription = this.classificationTypeService.getClassificationTypes() .subscribe((classificationsTypes: Array) => { this.classificationsTypes = classificationsTypes; }); diff --git a/web/src/app/app.module.ts b/web/src/app/app.module.ts index 6adcc4745..026e6c6f1 100644 --- a/web/src/app/app.module.ts +++ b/web/src/app/app.module.ts @@ -56,6 +56,7 @@ import { WorkbasketDefinitionService } from './services/workbasket-definition/wo import { SelectedRouteService } from './services/selected-route/selected-route'; import { ClassificationsService } from './services/classifications/classifications.service'; import { TreeService } from './services/tree/tree.service'; +import { ClassificationTypesService } from './services/classification-types/classification-types.service'; /** * Pipes @@ -131,7 +132,8 @@ const DECLARATIONS = [ OrientationService, SelectedRouteService, ClassificationsService, - TreeService + TreeService, + ClassificationTypesService ], bootstrap: [AppComponent] }) diff --git a/web/src/app/services/classification-types/classification-types.service.spec.ts b/web/src/app/services/classification-types/classification-types.service.spec.ts new file mode 100644 index 000000000..6f0655c5a --- /dev/null +++ b/web/src/app/services/classification-types/classification-types.service.spec.ts @@ -0,0 +1,18 @@ +import { TestBed, inject } from '@angular/core/testing'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; +import { Observable } from 'rxjs/Observable'; + +import { ClassificationTypesService } from './classification-types.service'; + +describe('ClassificationTypesService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientModule], + providers: [HttpClient, ClassificationTypesService] + }); + }); + + it('should be created', inject([ClassificationTypesService], (service: ClassificationTypesService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/web/src/app/services/classification-types/classification-types.service.ts b/web/src/app/services/classification-types/classification-types.service.ts new file mode 100644 index 000000000..2e67197eb --- /dev/null +++ b/web/src/app/services/classification-types/classification-types.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; +import { environment } from 'environments/environment'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +@Injectable() +export class ClassificationTypesService { + private url = environment.taskanaRestUrl + '/v1/classification-types'; + httpOptions = { + headers: new HttpHeaders({ + 'Content-Type': 'application/json', + 'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x' + }) + }; + private classificationTypeSelectedValue = 'TASK'; + private classificationTypeSelected = new BehaviorSubject(this.classificationTypeSelectedValue); + + constructor(private httpClient: HttpClient) { } + + getClassificationTypes(): Observable> { + return this.httpClient.get>(this.url, this.httpOptions); + }; + + selectClassificationType(id: string) { + this.classificationTypeSelectedValue = id; + this.classificationTypeSelected.next(id); + } + + getSelectedClassificationType(): Observable { + return this.classificationTypeSelected.asObservable(); + } + +} diff --git a/web/src/app/services/classifications/classifications.service.ts b/web/src/app/services/classifications/classifications.service.ts index e6ca05b13..e5392395d 100644 --- a/web/src/app/services/classifications/classifications.service.ts +++ b/web/src/app/services/classifications/classifications.service.ts @@ -1,15 +1,18 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { environment } from '../../../environments/environment'; +import { environment } from 'environments/environment'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; +import 'rxjs/add/observable/forkJoin'; +import 'rxjs/add/observable/combineLatest'; import { Classification } from 'app/models/classification'; import { TreeNodeModel } from 'app/models/tree-node'; import { ClassificationDefinition } from 'app/models/classification-definition'; import { ClassificationResource } from '../../models/classification-resource'; +import { ClassificationTypesService } from '../classification-types/classification-types.service'; @Injectable() export class ClassificationsService { @@ -17,8 +20,6 @@ export class ClassificationsService { private url = environment.taskanaRestUrl + '/v1/classifications'; private classificationSelected = new Subject(); private classificationSaved = new Subject(); - private classificationTypeSelectedValue = 'TASK'; - private classificationTypeSelected = new BehaviorSubject(this.classificationTypeSelectedValue); httpOptions = { headers: new HttpHeaders({ @@ -30,29 +31,20 @@ export class ClassificationsService { private classificationRef: Observable; private classificationTypes: Array; - constructor(private httpClient: HttpClient) { + constructor(private httpClient: HttpClient, private classificationTypeService: ClassificationTypesService) { } // GET - getClassifications(forceRequest = false, domain = ''): Observable> { + getClassifications(forceRequest = false, domain = ''): Observable { + const classificationTypes = this.classificationTypeService.getSelectedClassificationType(); if (!forceRequest && this.classificationRef) { - return this.classificationRef.map((response: ClassificationResource) => { - if (!response._embedded) { - return []; - } - return this.buildHierarchy(response._embedded.classificationSummaryResourceList, this.classificationTypeSelectedValue, domain); - }); + return this.getClassificationObservable(domain, this.classificationRef) } this.classificationRef = this.httpClient.get(`${environment.taskanaRestUrl}/v1/classifications`, this.httpOptions); + return this.getClassificationObservable(domain, this.classificationRef) - return this.classificationRef.map((response: ClassificationResource) => { - if (!response._embedded) { - return []; - } - return this.buildHierarchy(response._embedded.classificationSummaryResourceList, this.classificationTypeSelectedValue, domain); - }); } // GET @@ -60,26 +52,11 @@ export class ClassificationsService { return this.httpClient.get(`${environment.taskanaRestUrl}/v1/classifications/${id}`, this.httpOptions) .do((classification: ClassificationDefinition) => { if (classification) { - this.selectClassificationType(classification.type); + this.classificationTypeService.selectClassificationType(classification.type); } }); } - getClassificationTypes(): Observable> { - const typesSubject = new Subject>(); - this.classificationRef.subscribe((classifications: ClassificationResource) => { - if (!classifications._embedded) { - return typesSubject; - } - const types = new Map(); - classifications._embedded.classificationSummaryResourceList.forEach(element => { - types.set(element.type, element.type); - }); - - typesSubject.next(this.map2Array(types)); - }); - return typesSubject.asObservable(); - } // POST postClassification(classification: Classification): Observable { @@ -114,17 +91,23 @@ export class ClassificationsService { return this.classificationSaved.asObservable(); } - selectClassificationType(id: string) { - this.classificationTypeSelectedValue = id; - this.classificationTypeSelected.next(id); - } - - getSelectedClassificationType(): Observable { - return this.classificationTypeSelected.asObservable(); - } - // #endregion + private getClassificationObservable(domain: string, clasisficationRef: Observable): Observable { + const classificationTypes = this.classificationTypeService.getSelectedClassificationType(); + return Observable.combineLatest( + clasisficationRef, + classificationTypes + + ).map((data: any[]) => { + if (!data[0]._embedded) { + return []; + } + return this.buildHierarchy(data[0]._embedded.classificationSummaryResourceList, data[1], domain); + }) + + } + private buildHierarchy(classifications: Array, type: string, domain: string) { const roots = [] const children = new Array();