From cb20dd1ccb7ed9499d0ff13df5cb119c049ff88f Mon Sep 17 00:00:00 2001 From: Martin Rojas Miguel Angel Date: Thu, 19 Apr 2018 15:19:39 +0200 Subject: [PATCH] TSK-454 Domain switching bug --- .../classification-details.component.html | 6 ++--- .../classification-details.component.ts | 24 +++++++++++++++---- .../list/classification-list.component.ts | 3 --- .../distribution-targets.component.html | 2 -- .../distribution-targets.component.ts | 6 ++--- .../details/workbasket-details.component.ts | 15 +++++++++++- .../list/workbasket-list.component.html | 10 ++++---- web/src/app/app-routing.module.ts | 5 ++-- web/src/app/app.module.ts | 4 +++- web/src/app/guards/domain-guard.ts | 22 +++++++++++++++++ .../classification-categories.service.ts | 17 ++++++++++--- .../classification-types.service.ts | 17 +++++++++++-- .../classifications.service.ts | 10 ++------ .../services/domain/domain.service.mock.ts | 10 +++++++- web/src/app/services/domain/domain.service.ts | 21 +++++++++++++++- .../errorModal/error-modal.service.ts | 2 +- .../app/shared/nav-bar/nav-bar.component.html | 2 +- .../app/shared/nav-bar/nav-bar.component.ts | 4 ++-- 18 files changed, 136 insertions(+), 44 deletions(-) create mode 100644 web/src/app/guards/domain-guard.ts diff --git a/web/src/app/administration/classification/details/classification-details.component.html b/web/src/app/administration/classification/details/classification-details.component.html index 2d735b9b0..1bd29c2af 100644 --- a/web/src/app/administration/classification/details/classification-details.component.html +++ b/web/src/app/administration/classification/details/classification-details.component.html @@ -26,9 +26,9 @@
- -
+ +
* Key is required
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 094b33da4..2908d01ba 100644 --- a/web/src/app/administration/classification/details/classification-details.component.ts +++ b/web/src/app/administration/classification/details/classification-details.component.ts @@ -45,6 +45,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { private classificationRemoveSubscription: Subscription; private selectedClassificationSubscription: Subscription; private categoriesSubscription: Subscription; + private domainSubscription: Subscription; constructor(private classificationsService: ClassificationsService, private route: ActivatedRoute, @@ -66,7 +67,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { .subscribe(classificationIdSelected => { this.classification = undefined; if (classificationIdSelected) { - this.getClassificationInformation(classificationIdSelected); + this.fillClassificationInformation(classificationIdSelected); } }); @@ -80,7 +81,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { if (id === 'undefined') { id = undefined; } - this.getClassificationInformation(id); + this.fillClassificationInformation(id); } if (id && id !== '') { @@ -111,6 +112,11 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { } removeClassification() { + if (!this.classification || !this.classification.classificationId) { + this.errorModalService.triggerError( + new ErrorModel('There is no classification selected', 'Please check if you are creating a classification')); + return false; + } this.requestInProgressService.setRequestInProgress(true); this.treeService.setRemovedNodeId(this.classification.classificationId); @@ -147,6 +153,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { .putClassification(this.classification._links.self.href, this.classification) .subscribe((classification: ClassificationDefinition) => { this.classification = classification; + this.classificationsService.selectClassification(classification.classificationId); this.afterRequest(); this.alertService.triggerAlert(new AlertModel(AlertType.SUCCESS, `Classification ${classification.key} was saved successfully`)); }, error => { @@ -176,7 +183,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { this.classificationsService.selectClassification(id); } - private getClassificationInformation(classificationIdSelected: string) { + private fillClassificationInformation(classificationIdSelected: string) { if (this.action === ACTION.CREATE) { // CREATE this.initClassificationCreation(classificationIdSelected); } else { @@ -186,6 +193,7 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { this.classification = classification; this.classificationClone = { ...this.classification }; this.requestInProgress = false; + this.checkDomainAndRedirect(); }); } } @@ -208,6 +216,14 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { this.classificationClone = { ...this.classification }; } + private checkDomainAndRedirect() { + this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => { + if (this.classification && this.classification.domain !== domain) { + this.backClicked(); + } + }); + } + ngOnDestroy(): void { if (this.masterAndDetailSubscription) { this.masterAndDetailSubscription.unsubscribe(); } @@ -218,6 +234,6 @@ export class ClassificationDetailsComponent implements OnInit, OnDestroy { if (this.classificationRemoveSubscription) { this.classificationRemoveSubscription.unsubscribe(); } if (this.selectedClassificationSubscription) { this.selectedClassificationSubscription.unsubscribe(); } if (this.categoriesSubscription) { this.categoriesSubscription.unsubscribe(); } - + if (this.domainSubscription) { this.domainSubscription.unsubscribe(); } } } 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 646594db5..a705a9e87 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 @@ -84,9 +84,6 @@ export class ClassificationListComponent implements OnInit, OnDestroy { this.classificationServiceSubscription = this.classificationService.getClassifications(true) .subscribe((classifications: Array) => { this.requestInProgress = false; - if (!classifications.length) { - return null; - } this.classifications = classifications; this.classificationTypeServiceSubscription = this.classificationTypeService.getClassificationTypes() .subscribe((classificationsTypes: Array) => { diff --git a/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.html b/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.html index ab007d181..a65acdf71 100644 --- a/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.html +++ b/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.html @@ -1,5 +1,3 @@ -
diff --git a/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.ts b/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.ts index ef61049c4..9e7e94972 100644 --- a/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.ts +++ b/web/src/app/administration/workbasket/details/distribution-targets/distribution-targets.component.ts @@ -47,7 +47,6 @@ export class DistributionTargetsComponent implements OnChanges, OnDestroy { distributionTargetsClone: Array; distributionTargetsSelectedClone: Array; - requestInProgress = false; requestInProgressLeft = false; requestInProgressRight = false; modalErrorMessage: string; @@ -119,10 +118,9 @@ export class DistributionTargetsComponent implements OnChanges, OnDestroy { onSave() { this.requestInProgressService.setRequestInProgress(true); - this.requestInProgress = true; this.workbasketService.updateWorkBasketsDistributionTargets( this.distributionTargetsSelectedResource._links.self.href, this.getSeletedIds()).subscribe(response => { - this.requestInProgress = false; + this.requestInProgressService.setRequestInProgress(false); this.distributionTargetsSelected = response._embedded ? response._embedded.distributionTargets : []; this.distributionTargetsSelectedClone = Object.assign([], this.distributionTargetsSelected); this.distributionTargetsClone = Object.assign([], this.distributionTargetsLeft); @@ -132,7 +130,7 @@ export class DistributionTargetsComponent implements OnChanges, OnDestroy { }, error => { this.errorModalService.triggerError(new ErrorModel(`There was error while saving your workbasket's distribution targets`, error)) - this.requestInProgress = false; + this.requestInProgressService.setRequestInProgress(false); return false; } ) diff --git a/web/src/app/administration/workbasket/details/workbasket-details.component.ts b/web/src/app/administration/workbasket/details/workbasket-details.component.ts index 933ca4a04..fa3d9c3ce 100644 --- a/web/src/app/administration/workbasket/details/workbasket-details.component.ts +++ b/web/src/app/administration/workbasket/details/workbasket-details.component.ts @@ -37,6 +37,7 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy { private routeSubscription: Subscription; private masterAndDetailSubscription: Subscription; private permissionSubscription: Subscription; + private domainSubscription: Subscription; constructor(private service: WorkbasketService, private route: ActivatedRoute, @@ -104,7 +105,9 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy { if (!workbasketIdSelected && this.action === ACTION.CREATE) { // CREATE this.workbasket = new Workbasket(undefined); - this.workbasket.domain = this.domainService.getSelectedDomainValue(); + this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => { + this.workbasket.domain = domain; + }); this.requestInProgress = false; } else if (!workbasketIdSelected && this.action === ACTION.COPY) { // COPY this.workbasket = { ...this.workbasketCopy }; @@ -115,15 +118,25 @@ export class WorkbasketDetailsComponent implements OnInit, OnDestroy { this.workbasketSubscription = this.service.getWorkBasket(workbasketIdSelected).subscribe(workbasket => { this.workbasket = workbasket; this.requestInProgress = false; + this.checkDomainAndRedirect(); }); } } + private checkDomainAndRedirect() { + this.domainSubscription = this.domainService.getSelectedDomain().subscribe(domain => { + if (this.workbasket && this.workbasket.domain !== domain) { + this.backClicked(); + } + }); + } + ngOnDestroy(): void { if (this.workbasketSelectedSubscription) { this.workbasketSelectedSubscription.unsubscribe(); } if (this.workbasketSubscription) { this.workbasketSubscription.unsubscribe(); } if (this.routeSubscription) { this.routeSubscription.unsubscribe(); } if (this.masterAndDetailSubscription) { this.masterAndDetailSubscription.unsubscribe(); } if (this.permissionSubscription) { this.permissionSubscription.unsubscribe(); } + if (this.domainSubscription) { this.domainSubscription.unsubscribe(); } } } diff --git a/web/src/app/administration/workbasket/master/list/workbasket-list.component.html b/web/src/app/administration/workbasket/master/list/workbasket-list.component.html index 244daf855..e1ffc4eea 100644 --- a/web/src/app/administration/workbasket/master/list/workbasket-list.component.html +++ b/web/src/app/administration/workbasket/master/list/workbasket-list.component.html @@ -15,18 +15,18 @@
-
{{workbasket.name}}, - {{workbasket.key}} +
{{workbasket.name}}, + {{workbasket.key}}
-
{{workbasket.description}}  
-
{{workbasket.owner}}  
+
{{workbasket.description}}  
+
{{workbasket.owner}}  
- +
\ No newline at end of file diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index 39683b68c..3ca49d81c 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -9,12 +9,13 @@ import { NoAccessComponent } from './administration/workbasket/details/noAccess/ import { ClassificationListComponent } from './administration/classification/master/list/classification-list.component'; import { ClassificationDetailsComponent } from 'app/administration/classification/details/classification-details.component'; import { EnvironmentUrlGuard } from 'app/guards/environment-url-guard'; +import { DomainGuard } from 'app/guards/domain-guard'; const appRoutes: Routes = [ { path: 'administration/workbaskets', component: MasterAndDetailComponent, - canActivate: [EnvironmentUrlGuard], + canActivate: [EnvironmentUrlGuard, DomainGuard], children: [ { path: '', @@ -41,7 +42,7 @@ const appRoutes: Routes = [ { path: 'administration/classifications', component: MasterAndDetailComponent, - canActivate: [EnvironmentUrlGuard], + canActivate: [EnvironmentUrlGuard, DomainGuard], children: [ { path: '', diff --git a/web/src/app/app.module.ts b/web/src/app/app.module.ts index e913c5b9b..4fd2d8a3f 100644 --- a/web/src/app/app.module.ts +++ b/web/src/app/app.module.ts @@ -73,6 +73,7 @@ import { DomainService } from './services/domain/domain.service'; * Guards */ import { EnvironmentUrlGuard } from './guards/environment-url-guard'; +import { DomainGuard } from './guards/domain-guard'; const MODULES = [ BrowserModule, @@ -142,7 +143,8 @@ const DECLARATIONS = [ TreeService, ClassificationTypesService, ClassificationCategoriesService, - EnvironmentUrlGuard + EnvironmentUrlGuard, + DomainGuard ], bootstrap: [AppComponent] }) diff --git a/web/src/app/guards/domain-guard.ts b/web/src/app/guards/domain-guard.ts new file mode 100644 index 000000000..5ddf40c11 --- /dev/null +++ b/web/src/app/guards/domain-guard.ts @@ -0,0 +1,22 @@ +import { Observable } from 'rxjs/Observable'; +import { HttpClient } from '@angular/common/http'; +import { CanActivate } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { DomainService } from 'app/services/domain/domain.service'; +import { ErrorModalService } from 'app/services/errorModal/error-modal.service'; +import { ErrorModel } from 'app/models/modal-error'; + +@Injectable() +export class DomainGuard implements CanActivate { + constructor(private domainService: DomainService, private errorModalService: ErrorModalService) { } + + canActivate() { + return this.domainService.getDomains().map(domain => { + return true; + }).catch(() => { + this.errorModalService.triggerError(new ErrorModel( + 'There was an error, please contact with your administrator', 'There was an error getting Domains')) + return Observable.of(false) + }); + } +} diff --git a/web/src/app/services/classification-categories-service/classification-categories.service.ts b/web/src/app/services/classification-categories-service/classification-categories.service.ts index 47e7d79f0..ce3e40c6e 100644 --- a/web/src/app/services/classification-categories-service/classification-categories.service.ts +++ b/web/src/app/services/classification-categories-service/classification-categories.service.ts @@ -3,7 +3,7 @@ import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { environment } from 'environments/environment'; import { Observable } from 'rxjs/Observable'; - +import { ReplaySubject } from 'rxjs/ReplaySubject'; @Injectable() export class ClassificationCategoriesService { @@ -14,10 +14,21 @@ export class ClassificationCategoriesService { 'Authorization': 'Basic VEVBTUxFQURfMTpURUFNTEVBRF8x' }) }; + private dataObs$ = new ReplaySubject>(1); constructor(private httpClient: HttpClient) { } - getCategories(): Observable> { - return this.httpClient.get>(this.url, this.httpOptions); + getCategories(forceRefresh = false): Observable> { + if (!this.dataObs$.observers.length || forceRefresh) { + this.httpClient.get>(this.url, this.httpOptions).subscribe( + data => this.dataObs$.next(data), + error => { + this.dataObs$.error(error); + this.dataObs$ = new ReplaySubject(1); + } + ); + } + + return this.dataObs$; }; } diff --git a/web/src/app/services/classification-types/classification-types.service.ts b/web/src/app/services/classification-types/classification-types.service.ts index 2e67197eb..8b4b8beb7 100644 --- a/web/src/app/services/classification-types/classification-types.service.ts +++ b/web/src/app/services/classification-types/classification-types.service.ts @@ -4,6 +4,7 @@ import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { environment } from 'environments/environment'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { ReplaySubject } from 'rxjs/ReplaySubject'; @Injectable() export class ClassificationTypesService { @@ -16,11 +17,23 @@ export class ClassificationTypesService { }; private classificationTypeSelectedValue = 'TASK'; private classificationTypeSelected = new BehaviorSubject(this.classificationTypeSelectedValue); + private dataObs$ = new ReplaySubject>(1); constructor(private httpClient: HttpClient) { } - getClassificationTypes(): Observable> { - return this.httpClient.get>(this.url, this.httpOptions); + getClassificationTypes(forceRefresh = false): Observable> { + + if (!this.dataObs$.observers.length || forceRefresh) { + this.httpClient.get>(this.url, this.httpOptions).subscribe( + data => this.dataObs$.next(data), + error => { + this.dataObs$.error(error); + this.dataObs$ = new ReplaySubject(1); + } + ); + } + + return this.dataObs$; }; selectClassificationType(id: string) { diff --git a/web/src/app/services/classifications/classifications.service.ts b/web/src/app/services/classifications/classifications.service.ts index 876ba33b2..051db18e7 100644 --- a/web/src/app/services/classifications/classifications.service.ts +++ b/web/src/app/services/classifications/classifications.service.ts @@ -29,7 +29,6 @@ export class ClassificationsService { }) }; - private classificationRef: Observable; private classificationTypes: Array; constructor( @@ -42,14 +41,9 @@ export class ClassificationsService { getClassifications(forceRequest = false): Observable { return this.domainService.getSelectedDomain().mergeMap(domain => { const classificationTypes = this.classificationTypeService.getSelectedClassificationType(); - if (!forceRequest && this.classificationRef) { - return this.getClassificationObservable(this.classificationRef) - } - this.classificationRef = this.httpClient.get( + return this.getClassificationObservable(this.httpClient.get( `${environment.taskanaRestUrl}/v1/classifications/?domain=${domain}`, - this.httpOptions) - - return this.getClassificationObservable(this.classificationRef); + this.httpOptions)); }).do(() => { this.domainService.domainChangedComplete(); diff --git a/web/src/app/services/domain/domain.service.mock.ts b/web/src/app/services/domain/domain.service.mock.ts index c8fdb899d..d0752bc57 100644 --- a/web/src/app/services/domain/domain.service.mock.ts +++ b/web/src/app/services/domain/domain.service.mock.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; +import { Subject } from 'rxjs/Subject'; @Injectable() export class DomainServiceMock { @@ -8,6 +9,7 @@ export class DomainServiceMock { private domainSelectedValue; private domainSelected = new BehaviorSubject('DOMAIN_A'); + private domainSwitched = new Subject(); constructor() { } @@ -32,6 +34,12 @@ export class DomainServiceMock { getSelectedDomainValue() { } + getSwitchedDomain(): Observable { + return this.domainSwitched.asObservable(); + } - + switchDomain(value: string) { + this.selectDomain(value) + this.domainSwitched.next(value) + } } diff --git a/web/src/app/services/domain/domain.service.ts b/web/src/app/services/domain/domain.service.ts index 497d28fdc..01c8b90a6 100644 --- a/web/src/app/services/domain/domain.service.ts +++ b/web/src/app/services/domain/domain.service.ts @@ -5,6 +5,7 @@ import { environment } from '../../../environments/environment'; import { Router } from '@angular/router'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { RequestInProgressService } from '../requestInProgress/request-in-progress.service'; +import { Subject } from 'rxjs/Subject'; @Injectable() export class DomainService { @@ -19,6 +20,7 @@ export class DomainService { }; private domainSelectedValue; private domainSelected = new BehaviorSubject(''); + private domainSwitched = new Subject(); constructor( private httpClient: HttpClient, @@ -40,13 +42,22 @@ export class DomainService { return this.domainSelected.asObservable(); } + getSwitchedDomain(): Observable { + return this.domainSwitched.asObservable(); + } + selectDomain(value: string) { this.requestInProgressService.setRequestInProgress(true); - // this.router.navigate(['']); this.domainSelectedValue = value; this.domainSelected.next(value); } + switchDomain(value: string) { + this.selectDomain(value); + this.domainSwitched.next(value); + this.router.navigate([this.getNavigationUrl()]); + } + domainChangedComplete() { this.requestInProgressService.setRequestInProgress(false); } @@ -54,4 +65,12 @@ export class DomainService { getSelectedDomainValue() { return this.domainSelectedValue; } + + private getNavigationUrl(): string { + if (this.router.url.indexOf('workbaskets') !== -1) { + return 'administration/workbaskets'; + } else if (this.router.url.indexOf('classifications') !== -1) { + return 'administration/classifications'; + } + } } diff --git a/web/src/app/services/errorModal/error-modal.service.ts b/web/src/app/services/errorModal/error-modal.service.ts index c6987d316..3e6ca001d 100644 --- a/web/src/app/services/errorModal/error-modal.service.ts +++ b/web/src/app/services/errorModal/error-modal.service.ts @@ -6,7 +6,7 @@ import { ErrorModel } from 'app/models/modal-error'; @Injectable() export class ErrorModalService { - public errorTriggered = new Subject(); + private errorTriggered = new Subject(); constructor() { } diff --git a/web/src/app/shared/nav-bar/nav-bar.component.html b/web/src/app/shared/nav-bar/nav-bar.component.html index 2416152e7..21a545804 100644 --- a/web/src/app/shared/nav-bar/nav-bar.component.html +++ b/web/src/app/shared/nav-bar/nav-bar.component.html @@ -24,7 +24,7 @@