From e79829c5165cb10a0ddcf3346c5c1b6a3cdc87fb Mon Sep 17 00:00:00 2001 From: Martin Rojas Miguel Angel Date: Mon, 16 Apr 2018 12:13:07 +0200 Subject: [PATCH] TSK-440 Fix loading... text when remove the last children of a node --- .../classification-details.component.spec.ts | 25 +++++++++++++++---- .../classification-details.component.ts | 6 ++++- .../classification-list.component.spec.ts | 7 +++--- .../list/classification-list.component.ts | 2 +- web/src/app/app.module.ts | 4 ++- web/src/app/services/tree/tree.service.ts | 20 +++++++++++++++ .../app/shared/tree/tree.component.spec.ts | 10 +++++--- web/src/app/shared/tree/tree.component.ts | 16 +++++++++--- 8 files changed, 71 insertions(+), 19 deletions(-) create mode 100644 web/src/app/services/tree/tree.service.ts 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 e21d0e634..07bec618f 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 @@ -8,14 +8,16 @@ import { Observable } from 'rxjs/Observable'; import { ClassificationDetailsComponent } from './classification-details.component'; import { SpinnerComponent } from 'app/shared/spinner/spinner.component'; +import { ClassificationDefinition } from 'app/models/classification-definition'; +import { LinksClassification } from 'app/models/links-classfication'; import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and-detail.service'; import { RequestInProgressService } from 'app/services/requestInProgress/request-in-progress.service'; import { ClassificationsService } from 'app/services/classifications/classifications.service'; import { TreeNodeModel } from 'app/models/tree-node'; import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; -import { AlertService } from '../../../services/alert/alert.service'; - +import { AlertService } from 'app/services/alert/alert.service'; +import { TreeService } from 'app/services/tree/tree.service'; @Component({ selector: 'taskana-dummy-detail', @@ -25,8 +27,7 @@ class DummyDetailComponent { } const routes: Routes = [ - { path: ':id', component: DummyDetailComponent, outlet: 'detail' }, - { path: 'classifications', component: DummyDetailComponent } + { path: 'administration/classifications', component: DummyDetailComponent } ]; describe('ClassificationDetailsComponent', () => { @@ -36,12 +37,14 @@ describe('ClassificationDetailsComponent', () => { const classificationTypes: Array = new Array('type1', 'type2'); let classificationsSpy, classificationsTypesSpy; let classificationsService; + let treeService; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [FormsModule, HttpClientModule, RouterTestingModule.withRoutes(routes)], declarations: [ClassificationDetailsComponent, SpinnerComponent, DummyDetailComponent], - providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService] + providers: [MasterAndDetailService, RequestInProgressService, ClassificationsService, HttpClient, ErrorModalService, AlertService, + TreeService] }) .compileComponents(); })); @@ -52,10 +55,22 @@ describe('ClassificationDetailsComponent', () => { classificationsService = TestBed.get(ClassificationsService); classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes)); classificationsTypesSpy = spyOn(classificationsService, 'getClassificationTypes').and.returnValue(Observable.of(classificationTypes)); + spyOn(classificationsService, 'deleteClassification').and.returnValue(Observable.of(true)); + + treeService = TestBed.get(TreeService); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should trigger treeService remove node id after removing a node', () => { + const treeServiceSpy = spyOn(treeService, 'setRemovedNodeId'); + component.classification = new ClassificationDefinition('id1', undefined, undefined, undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, + undefined, undefined, undefined, new LinksClassification({ 'self': '' })); + component.removeClassification(); + expect(treeServiceSpy).toHaveBeenCalledWith('id1'); + }); }); 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 038284479..4c09820f1 100644 --- a/web/src/app/administration/classification/details/classification-details.component.ts +++ b/web/src/app/administration/classification/details/classification-details.component.ts @@ -15,6 +15,7 @@ import { MasterAndDetailService } from 'app/services/masterAndDetail/master-and- 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'; @Component({ selector: 'taskana-classification-details', @@ -46,7 +47,8 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private masterAndDetailService: MasterAndDetailService, private errorModalService: ErrorModalService, private requestInProgressService: RequestInProgressService, - private alertService: AlertService) { } + private alertService: AlertService, + private treeService: TreeService) { } ngOnInit() { @@ -97,6 +99,8 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { removeClassification() { this.requestInProgressService.setRequestInProgress(true); + this.treeService.setRemovedNodeId(this.classification.classificationId); + this.classificationRemoveSubscription = this.classificationsService .deleteClassification(this.classification._links.self.href) .subscribe(() => { 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 bb5fa4e7f..097947edf 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 @@ -18,7 +18,7 @@ import { AlertService } from 'app/services/alert/alert.service'; import { ClassificationsService } from 'app/services/classifications/classifications.service'; 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 { ErrorModalService } from 'app/services/errorModal/error-modal.service'; @Component({ selector: 'taskana-tree', @@ -37,8 +37,8 @@ class DummyDetailComponent { } const routes: Routes = [ - { path: ':id', component: DummyDetailComponent, outlet: 'detail' }, - { path: 'classifications', component: DummyDetailComponent } + + { path: ':id', component: DummyDetailComponent } ]; @@ -66,6 +66,7 @@ describe('ClassificationListComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ClassificationListComponent); component = fixture.componentInstance; + classificationsService = TestBed.get(ClassificationsService); classificationsSpy = spyOn(classificationsService, 'getClassifications').and.returnValue(Observable.of(treeNodes)); classificationsTypesSpy = spyOn(classificationsService, 'getClassificationTypes').and.returnValue(Observable.of(classificationTypes)); 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 8805b2f48..36ebe01e3 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 @@ -33,7 +33,7 @@ export class ClassificationListComponent implements OnInit, OnDestroy { constructor( private classificationService: ClassificationsService, private router: Router, - private route: ActivatedRoute, ) { + private route: ActivatedRoute) { } ngOnInit() { diff --git a/web/src/app/app.module.ts b/web/src/app/app.module.ts index 492890c0b..6adcc4745 100644 --- a/web/src/app/app.module.ts +++ b/web/src/app/app.module.ts @@ -55,6 +55,7 @@ import { ClassificationDefinitionService } from './services/classification-defin import { WorkbasketDefinitionService } from './services/workbasket-definition/workbasket-definition.service'; import { SelectedRouteService } from './services/selected-route/selected-route'; import { ClassificationsService } from './services/classifications/classifications.service'; +import { TreeService } from './services/tree/tree.service'; /** * Pipes @@ -129,7 +130,8 @@ const DECLARATIONS = [ SavingWorkbasketService, OrientationService, SelectedRouteService, - ClassificationsService + ClassificationsService, + TreeService ], bootstrap: [AppComponent] }) diff --git a/web/src/app/services/tree/tree.service.ts b/web/src/app/services/tree/tree.service.ts new file mode 100644 index 000000000..9d9c24c44 --- /dev/null +++ b/web/src/app/services/tree/tree.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; + +@Injectable() +export class TreeService { + + public removedNodeId = new Subject(); + + constructor() { } + + setRemovedNodeId(value: string) { + this.removedNodeId.next(value); + } + + getRemovedNodeId() { + return this.removedNodeId.asObservable(); + } + +} diff --git a/web/src/app/shared/tree/tree.component.spec.ts b/web/src/app/shared/tree/tree.component.spec.ts index 610beb8a0..93dbd46d1 100644 --- a/web/src/app/shared/tree/tree.component.spec.ts +++ b/web/src/app/shared/tree/tree.component.spec.ts @@ -1,12 +1,13 @@ import { Input, Component } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TaskanaTreeComponent } from './tree.component'; - import { AngularSvgIconModule } from 'angular-svg-icon'; import { HttpClientModule } from '@angular/common/http'; import { HttpModule } from '@angular/http'; +import { TaskanaTreeComponent } from './tree.component'; + +import { TreeService } from 'app/services/tree/tree.service'; + // tslint:disable:component-selector @Component({ selector: 'tree-root', @@ -29,7 +30,8 @@ describe('TaskanaTreeComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ imports: [AngularSvgIconModule, HttpClientModule, HttpModule], - declarations: [TaskanaTreeComponent, TreeVendorComponent] + declarations: [TaskanaTreeComponent, TreeVendorComponent], + providers: [TreeService] }) .compileComponents(); })); diff --git a/web/src/app/shared/tree/tree.component.ts b/web/src/app/shared/tree/tree.component.ts index d32e05b64..698f2e952 100644 --- a/web/src/app/shared/tree/tree.component.ts +++ b/web/src/app/shared/tree/tree.component.ts @@ -1,7 +1,8 @@ -import { Component, OnInit, Input, Output, EventEmitter, ViewChild, AfterViewChecked } from '@angular/core'; +import { Component, OnInit, Input, Output, EventEmitter, ViewChild, AfterViewChecked, OnChanges, SimpleChanges } from '@angular/core'; import { TreeNodeModel } from 'app/models/tree-node'; import { TREE_ACTIONS, KEYS, IActionMapping, ITreeOptions, ITreeState, TreeComponent, TreeNode } from 'angular-tree-component'; +import { TreeService } from '../../services/tree/tree.service'; @Component({ selector: 'taskana-tree', @@ -34,12 +35,19 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked { levelPadding: 20 } - constructor() { } + constructor(private treeService: TreeService) { } ngOnInit() { this.selectNode(this.selectNodeId); + this.treeService.getRemovedNodeId().subscribe(value => { + const removedNode = this.getNode(value); + if (removedNode.parent) { + removedNode.parent.collapse(); + } + }); } + ngAfterViewChecked(): void { if (this.selectNodeId && !this.tree.treeModel.getActiveNode()) { this.selectNode(this.selectNodeId); @@ -58,7 +66,7 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked { private selectNode(nodeId: string) { if (nodeId) { - const selectedNode = this.getSelectedNode(nodeId) + const selectedNode = this.getNode(nodeId) if (selectedNode) { selectedNode.setIsActive(true) this.expandParent(selectedNode); @@ -72,7 +80,7 @@ export class TaskanaTreeComponent implements OnInit, AfterViewChecked { activeNode.blur(); } - private getSelectedNode(nodeId: string) { + private getNode(nodeId: string) { return this.tree.treeModel.getNodeById(nodeId); }