From 4ece9a5b60aec38a98bee3a436afff6daaa9a1c1 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Thu, 14 Jul 2022 17:44:53 +0300 Subject: [PATCH] Fix a bug with guard losing redirection. Add reorder in topics, categories, subcategories for Curators --- src/app/monitor/monitor.component.html | 30 ++-- src/app/openaireLibrary | 2 +- src/app/topic/topic.component.html | 201 ++++++++++++++++++------- src/app/topic/topic.component.ts | 143 ++++++++++++++---- src/app/utils/adminDashboard.guard.ts | 13 +- src/assets/dashboard-theme | 2 +- 6 files changed, 279 insertions(+), 112 deletions(-) diff --git a/src/app/monitor/monitor.component.html b/src/app/monitor/monitor.component.html index dca3f67..deedc5b 100644 --- a/src/app/monitor/monitor.component.html +++ b/src/app/monitor/monitor.component.html @@ -39,7 +39,7 @@ -
+
@@ -48,23 +48,17 @@

{{stakeholder.name}}

-
-
-
-
- -
-
+
diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index 013ce7d..e3f082b 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit 013ce7d5f45dd64e28e82585451b2741c41f9d2e +Subproject commit e3f082b8026053bc6095d29f4e2ac2d6922ef775 diff --git a/src/app/topic/topic.component.html b/src/app/topic/topic.component.html index 7af8f36..3a03900 100644 --- a/src/app/topic/topic.component.html +++ b/src/app/topic/topic.component.html @@ -8,7 +8,8 @@
- Indicators + Indicators
@@ -31,7 +32,8 @@ - +
@@ -45,7 +47,7 @@
-
  • +
  • -
  • +
  • @@ -136,34 +139,61 @@
  • -
    +
    - +
    +
    +
    - + You are about to delete "{{element.name}}" {{type}} permanently.
    {{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well.
    Are you sure you want to proceed?
    - +
    -
    +
    diff --git a/src/app/topic/topic.component.ts b/src/app/topic/topic.component.ts index c484b5d..e320318 100644 --- a/src/app/topic/topic.component.ts +++ b/src/app/topic/topic.component.ts @@ -1,4 +1,4 @@ -import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; +import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {Title} from '@angular/platform-browser'; import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties'; @@ -6,7 +6,7 @@ import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../openaire import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; import {AlertModal} from "../openaireLibrary/utils/modal/alert"; -import {Subject, Subscriber, Subscription} from "rxjs"; +import {BehaviorSubject, Subject, Subscriber, Subscription} from "rxjs"; import {FormBuilder, FormGroup, Validators} from "@angular/forms"; import {StakeholderUtils} from "../utils/indicator-utils"; import {StringUtils} from "../openaireLibrary/utils/string-utils.class"; @@ -27,12 +27,11 @@ declare var UIkit; templateUrl: './topic.component.html', }) export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { + private topicSubscriptions: any[] = []; private subscriptions: any[] = []; - private paramsSub: any; public properties: EnvProperties = properties; public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); public loading: boolean = true; - public stickyPageHeader: boolean = false; public stakeholder: Stakeholder; public user: User; /** @@ -42,14 +41,17 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { /** * Current topic **/ + public topicIndexSubject: BehaviorSubject = new BehaviorSubject(0); public topicIndex: number = 0; /** * Current category */ + public categoryIndexSubject: BehaviorSubject = new BehaviorSubject(0); public categoryIndex: number = 0; /** * Current Subcategory */ + public subCategoryIndexSubject: BehaviorSubject = new BehaviorSubject(0); public subCategoryIndex: number = 0; /** * Current element and index of topic, category or subcategory to be deleted. @@ -63,6 +65,8 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { @ViewChild('editModal', {static: true}) editModal: AlertModal; @ViewChild("topics") topics: TransitionGroupComponent; + @ViewChild("categories") categories: TransitionGroupComponent; + @ViewChild("subCategories") subCategories: TransitionGroupComponent; public elementChildrenActionOnDelete: string; public filters: FormGroup; @@ -78,12 +82,45 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { private fb: FormBuilder, private stakeholderService: StakeholderService, private userManagementService: UserManagementService, - private layoutService: LayoutService) { + private layoutService: LayoutService, + private cdr: ChangeDetectorRef) { } - public ngOnInit() { let subscription: Subscription; - this.paramsSub = this.route.params.subscribe(params => { + this.subscriptions.push(this.topicIndexSubject.asObservable().subscribe(index => { + if(this.categories) { + this.categories.disable(); + if(this.subCategories) { + this.subCategories.disable(); + } + } + this.topicIndex = index; + this.cdr.detectChanges(); + if(this.categories) { + this.categories.init(); + this.categories.enable(); + if(this.subCategories) { + this.subCategories.init(); + this.subCategories.enable(); + } + } + })); + this.subscriptions.push(this.categoryIndexSubject.asObservable().subscribe(index => { + if(this.subCategories) { + this.subCategories.disable(); + } + this.categoryIndex = index; + this.cdr.detectChanges(); + if(this.subCategories) { + this.subCategories.init(); + this.subCategories.enable(); + } + })); + this.subscriptions.push(this.subCategoryIndexSubject.asObservable().subscribe(index => { + this.subCategoryIndex = index; + this.cdr.detectChanges(); + })); + this.subscriptions.push(this.route.params.subscribe(params => { if (subscription) { subscription.unsubscribe(); } @@ -91,12 +128,11 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { if (stakeholder) { this.stakeholder = stakeholder; if (params['topic']) { - this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']); + this.chooseTopic(this.stakeholder.topics.findIndex(topic => topic.alias === params['topic'])); } else { - this.topicIndex = 0; + this.chooseTopic(0); } - this.categoryIndex = 0; - this.subCategoryIndex = 0; + this.chooseCategory(0); this.filters = this.fb.group({ chartType: this.fb.control('all'), status: this.fb.control('all'), @@ -109,26 +145,28 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } } }); - this.subscriptions.push(subscription); - }); - this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { + this.topicSubscriptions.push(subscription); + })); + this.topicSubscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.user = user; })) } public ngOnDestroy() { + this.topicSubscriptions.forEach(value => { + if (value instanceof Subscriber) { + value.unsubscribe(); + } + }); this.subscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } }); - if (this.paramsSub instanceof Subscriber) { - this.paramsSub.unsubscribe(); - } } canExit(): boolean { - this.subscriptions.forEach(value => { + this.topicSubscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } @@ -169,6 +207,10 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } } + public chooseTopic(topicIndex: number) { + this.topicIndexSubject.next(topicIndex); + } + private buildTopic(topic: Topic) { let topics = this.stakeholder.topics.filter(element => element._id !== topic._id); this.form = this.fb.group({ @@ -186,7 +228,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { categories: this.fb.control(topic.categories), icon: this.fb.control(topic.icon) }); - this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { + this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { let i = 1; value = this.stakeholderUtils.generateAlias(value); this.form.controls['alias'].setValue(value); @@ -249,7 +291,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { this.stakeholder.topics[this.index]._id ]; let callback = (): void => { - this.topicIndex = Math.max(0, this.index - 1); + this.chooseTopic(Math.max(0, this.index - 1)); this.stakeholder.topics.splice(this.index, 1); this.topics.init(); }; @@ -264,7 +306,9 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { HelperFunctions.swap(this.stakeholder.topics, index, newIndex); if(this.topicIndex === index) { - this.topicIndex = newIndex; + this.chooseTopic(newIndex); + } else if(this.topicIndex === newIndex) { + this.chooseTopic(index); } }, error => { NotificationHandler.rise(error.error.message) @@ -272,8 +316,8 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } public chooseCategory(index: number) { - this.categoryIndex = index; - this.subCategoryIndex = 0; + this.categoryIndexSubject.next(index); + this.chooseSubcategory(0); } private buildCategory(category: Category) { @@ -292,7 +336,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { defaultId: this.fb.control(category.defaultId), subCategories: this.fb.control(category.subCategories) }); - this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { + this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { let i = 1; value = this.stakeholderUtils.generateAlias(value); this.form.controls['alias'].setValue(value); @@ -320,6 +364,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { let callback = (category: Category): void => { if (this.index === -1) { this.stakeholder.topics[this.topicIndex].categories.push(category); + this.categories.init(); } else { this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category); } @@ -343,7 +388,6 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.index], path, visibility); } - public deleteCategoryOpen(index: number, childrenAction: string = null) { this.type = 'category'; this.index = index; @@ -358,12 +402,30 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { this.stakeholder.topics[this.topicIndex].categories[this.index]._id ]; let callback = (): void => { - this.categoryIndex = Math.max(0, this.index - 1); + this.chooseCategory(Math.max(0, this.index - 1)); this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1); + this.categories.init(); }; this.delete('Category has been successfully be deleted', path, callback); } + public moveCategory(index: number, newIndex: number = index - 1) { + this.categories.init(); + let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id]; + let ids = this.stakeholder.topics[this.topicIndex].categories.map(category => category._id); + HelperFunctions.swap(ids, index, newIndex); + this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { + HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories, index, newIndex); + if(this.categoryIndex === index) { + this.chooseCategory(newIndex); + } else if(this.categoryIndex === newIndex) { + this.chooseCategory(index); + } + }, error => { + NotificationHandler.rise(error.error.message) + }); + } + private buildSubcategory(subCategory: SubCategory) { let subCategories = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.filter(element => element._id !== subCategory._id); this.form = this.fb.group({ @@ -381,7 +443,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { charts: this.fb.control(subCategory.charts), numbers: this.fb.control(subCategory.numbers) }); - this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { + this.topicSubscriptions.push(this.form.get('name').valueChanges.subscribe(value => { let i = 1; value = this.stakeholderUtils.generateAlias(value); this.form.controls['alias'].setValue(value); @@ -453,12 +515,29 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id ]; let callback = (): void => { - this.subCategoryIndex = Math.max(0, this.index - 1); + this.chooseSubcategory(Math.max(0, this.index - 1)); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1); }; this.delete('Subcategory has been successfully be deleted', path, callback); } + public moveSubCategory(index: number, newIndex: number = index - 1) { + this.subCategories.init(); + let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id]; + let ids = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.map(subCategory => subCategory._id); + HelperFunctions.swap(ids, index, newIndex); + this.stakeholderService.reorderElements(properties.monitorServiceAPIURL, path, ids).subscribe(() => { + HelperFunctions.swap(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories, index, newIndex); + if(this.subCategoryIndex === index) { + this.chooseSubcategory(newIndex); + } else if(this.subCategoryIndex === newIndex) { + this.chooseSubcategory(index); + } + }, error => { + NotificationHandler.rise(error.error.message) + }); + } + private navigateToError() { this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}}); } @@ -498,7 +577,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } private save(message: string, path: string[], saveElement: any, callback: Function, redirect = false) { - this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => { + this.topicSubscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => { callback(saveElement); this.stakeholderChanged(); NotificationHandler.rise(message); @@ -513,7 +592,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } private delete(message: string, path: string[], callback: Function, redirect = false) { - this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => { + this.topicSubscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => { callback(); this.stakeholderChanged(); NotificationHandler.rise(message); @@ -526,7 +605,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility) { - this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => { + this.topicSubscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => { element.visibility = visibility; NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been successfully changed to ' + element.visibility.toLowerCase()); }, error => { @@ -541,7 +620,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent { } chooseSubcategory(subcategoryIndex: number) { - this.subCategoryIndex = subcategoryIndex; + this.subCategoryIndexSubject.next(subcategoryIndex); } public getPluralTypeName(): string { diff --git a/src/app/utils/adminDashboard.guard.ts b/src/app/utils/adminDashboard.guard.ts index 11e97f5..f9322d0 100644 --- a/src/app/utils/adminDashboard.guard.ts +++ b/src/app/utils/adminDashboard.guard.ts @@ -13,6 +13,7 @@ import {LoginErrorCodes} from "../openaireLibrary/login/utils/guardHelper.class" import {Session} from "../openaireLibrary/login/utils/helper.class"; import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; import {Observable, zip} from "rxjs"; +import {error} from "protractor"; @Injectable() @@ -24,15 +25,19 @@ export class AdminDashboardGuard implements CanActivate, CanActivateChild { } check(path: string, alias: string): Observable | boolean { + let errorCode = LoginErrorCodes.NOT_LOGIN; return zip( this.userManagementService.getUserInfo(false) ,this.stakeholderService.getStakeholder(alias) - ).pipe(take(1),map(res => - res[0] && res[1] && (Session.isPortalAdministrator(res[0]) || + ).pipe(take(1),map(res => { + if(res[0]) { + errorCode = LoginErrorCodes.NOT_ADMIN; + } + return res[0] && res[1] && (Session.isPortalAdministrator(res[0]) || Session.isCurator(res[1].type, res[0]) || Session.isManager(res[1].type, res[1].alias, res[0])) - ),tap(authorized => { + }),tap(authorized => { if(!authorized){ - this.router.navigate(['/user-info'], {queryParams: {'errorCode': LoginErrorCodes.NOT_ADMIN, 'redirectUrl':path}}); + this.router.navigate(['/user-info'], {queryParams: {'errorCode': errorCode, 'redirectUrl':path}}); } })); } diff --git a/src/assets/dashboard-theme b/src/assets/dashboard-theme index 00fc1f9..6a92074 160000 --- a/src/assets/dashboard-theme +++ b/src/assets/dashboard-theme @@ -1 +1 @@ -Subproject commit 00fc1f9e2b9158a6be224061d742cf80a043fab8 +Subproject commit 6a92074076f71ee522120e9941e22a9caf16e6dc