Restrict Edit Delete actions only to admins and curators

This commit is contained in:
Konstantinos Triantafyllou 2022-06-06 17:17:26 +03:00
parent bd63de452b
commit 0ec44320c5
5 changed files with 73 additions and 78 deletions

@ -1 +1 @@
Subproject commit eac367a8727e6abfc9107cba3fc4837e02d10e36 Subproject commit f3af762dab9b3d489dd4f78c46f3537aff840efd

View File

@ -44,10 +44,10 @@
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false"> <div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li> <ng-container *ngIf="isCurator">
<a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a> <li><a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a></li>
</li> <li class="uk-nav-divider"></li>
<li class="uk-nav-divider"></li> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li> <li>
<a (click)="changeIndicatorStatus(number._id, indicator, v.value);"> <a (click)="changeIndicatorStatus(number._id, indicator, v.value);">
@ -59,10 +59,10 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<hr *ngIf="!indicator.defaultId" class="uk-nav-divider"> <ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li *ngIf="!indicator.defaultId && !editing"><a <li class="uk-nav-divider">
(click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a> <li><a (click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a></li>
</li> </ng-container>
</ul> </ul>
</div> </div>
</div> </div>
@ -79,7 +79,7 @@
</div> </div>
</ng-template> </ng-template>
</div> </div>
<div class="uk-margin-medium-top"> <div *ngIf="isCurator" class="uk-margin-medium-top">
<div class="uk-grid" uk-grid> <div class="uk-grid" uk-grid>
<div [ngClass]="getNumberClassBySize('small')"> <div [ngClass]="getNumberClassBySize('small')">
<a class="uk-card uk-card-default uk-card-body uk-link-reset" (click)="editNumberIndicatorOpen(number)"> <a class="uk-card uk-card-default uk-card-body uk-link-reset" (click)="editNumberIndicatorOpen(number)">
@ -145,10 +145,10 @@
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false"> <div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li> <ng-container *ngIf="isCurator">
<a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a> <li><a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a></li>
</li> <li class="uk-nav-divider"></li>
<li class="uk-nav-divider"></li> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li> <li>
<a (click)="changeIndicatorStatus(chart._id, indicator, v.value);"> <a (click)="changeIndicatorStatus(chart._id, indicator, v.value);">
@ -160,10 +160,10 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<hr *ngIf="!indicator.defaultId" class="uk-nav-divider"> <ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li *ngIf="!indicator.defaultId && !editing"><a <li class="uk-nav-divider">
(click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a> <li><a (click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a></li>
</li> </ng-container>
</ul> </ul>
</div> </div>
</div> </div>
@ -190,7 +190,7 @@
</div> </div>
</ng-template> </ng-template>
</div> </div>
<div class="uk-margin-medium-top"> <div *ngIf="isCurator" class="uk-margin-medium-top">
<div class="uk-grid uk-grid-column-medium" uk-grid> <div class="uk-grid uk-grid-column-medium" uk-grid>
<div [ngClass]="getChartClassBySize('small')"> <div [ngClass]="getChartClassBySize('small')">
<div class=" uk-card uk-card-default uk-card-body clickable" (click)="editChartIndicatorOpen(chart)"> <div class=" uk-card uk-card-default uk-card-body clickable" (click)="editChartIndicatorOpen(chart)">
@ -416,7 +416,7 @@
<div #editChartNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div> <div #editChartNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
</div> </div>
</modal-alert> </modal-alert>
<modal-alert #deleteModal (alertOutput)="deleteIndicator()"> <modal-alert #deleteModal (alertOutput)="deleteIndicator()" [overflowBody]="false">
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1"> You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
"{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently. "{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently.
<div *ngIf="indicatorChildrenActionOnDelete == 'delete'" class="uk-text-bold"> <div *ngIf="indicatorChildrenActionOnDelete == 'delete'" class="uk-text-bold">
@ -440,7 +440,7 @@
<span class="uk-text-bold">Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.</span> <span class="uk-text-bold">Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.</span>
Are you sure you want to proceed? Are you sure you want to proceed?
</modal-alert>--> </modal-alert>-->
<modal-alert #deleteSectionModal (alertOutput)="deleteSection()"> <modal-alert #deleteSectionModal (alertOutput)="deleteSection()" [overflowBody]="false">
You are about to delete this section and its indicators permanently. You are about to delete this section and its indicators permanently.
<div *ngIf="sectionChildrenActionOnDelete == 'delete' && !stakeholder.defaultId" class="uk-text-bold"> <div *ngIf="sectionChildrenActionOnDelete == 'delete' && !stakeholder.defaultId" class="uk-text-bold">
Sections of all profiles based on this default section and their contents, will be deleted as well. Sections of all profiles based on this default section and their contents, will be deleted as well.
@ -468,14 +468,3 @@
</div> </div>
</div> </div>
</ng-template> </ng-template>
<ng-template #description let-indicator="indicator">
<span class="descriptionIcon"
*ngIf="(indicator.description && indicator.description.length > 0)
|| (indicator.additionalDescription && indicator.additionalDescription.length > 0)"
uk-icon="info"
[attr.uk-tooltip]="'title:<div class=\'uk-padding-small\'>'+
(indicator.description&& indicator.description.length > 0?indicator.description:'') +'<br>'+
(indicator.additionalDescription && indicator.additionalDescription.length?indicator.additionalDescription:'')
+'</div>'">
</span>
</ng-template>

View File

@ -60,6 +60,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
public stakeholder: Stakeholder = null; public stakeholder: Stakeholder = null;
@Input() @Input()
public changed: Observable<void>; public changed: Observable<void>;
@Input()
public user: User = null; public user: User = null;
public preview: string; public preview: string;
public indicatorUtils: IndicatorUtils = new IndicatorUtils(); public indicatorUtils: IndicatorUtils = new IndicatorUtils();
@ -105,7 +106,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
constructor(private layoutService: LayoutService, constructor(private layoutService: LayoutService,
private stakeholderService: StakeholderService, private stakeholderService: StakeholderService,
private statisticsService: StatisticsService, private statisticsService: StatisticsService,
private userManagementService: UserManagementService,
private notificationService: NotificationService, private notificationService: NotificationService,
private fb: FormBuilder, private fb: FormBuilder,
private router: Router, private router: Router,
@ -115,9 +115,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} }
ngOnInit(): void { ngOnInit(): void {
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}));
if (this.stakeholder) { if (this.stakeholder) {
this.setCharts(); this.setCharts();
this.setNumbers(); this.setNumbers();
@ -924,7 +921,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} }
public get isCurator(): boolean { public get isCurator(): boolean {
return this.isAdministrator || Session.isMonitorCurator(this.user); return this.isAdministrator || Session.isCurator(this.stakeholder.type, this.user);
} }
refreshIndicator() { refreshIndicator() {

View File

@ -1,4 +1,4 @@
<aside id="sidebar_main"> <aside *ngIf="stakeholder" id="sidebar_main">
<div id="sidebar_content"> <div id="sidebar_content">
<div class="menu_section uk-margin-top"> <div class="menu_section uk-margin-top">
<ul class="uk-list uk-nav-parent-icon uk-nav" uk-nav> <ul class="uk-list uk-nav-parent-icon uk-nav" uk-nav>
@ -37,10 +37,12 @@
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false"> <div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li> <ng-container *ngIf="isCurator">
<a (click)="editTopicOpen(i); hide(element)">Edit</a> <li>
</li> <a (click)="editTopicOpen(i); hide(element)">Edit</a>
<li class="uk-nav-divider"></li> </li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="topic.visibility === v.value"> <li [class.uk-active]="topic.visibility === v.value">
<a (click)="changeTopicStatus(i, v.value);"> <a (click)="changeTopicStatus(i, v.value);">
@ -52,14 +54,16 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<hr *ngIf="!topic.defaultId" class="uk-nav-divider"> <ng-container *ngIf="!topic.defaultId && isCurator">
<li *ngIf="!topic.defaultId"> <li class="uk-nav-divider">
<li>
<a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete</a> <a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete</a>
<!--<ng-container *ngIf="!stakeholder.defaultId"> <!--<ng-container *ngIf="!stakeholder.defaultId">
<a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete from all profiles</a> <a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete from all profiles</a>
<a (click)="deleteTopicOpen(i, 'disconnect'); hide(element)">Delete and disconnect from all profiles</a> <a (click)="deleteTopicOpen(i, 'disconnect'); hide(element)">Delete and disconnect from all profiles</a>
</ng-container>--> </ng-container>-->
</li> </li>
</ng-container>
</ul> </ul>
</div> </div>
</span> </span>
@ -67,7 +71,7 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<li> <li *ngIf="isCurator">
<a (click)="editTopicOpen(-1); $event.preventDefault()"> <a (click)="editTopicOpen(-1); $event.preventDefault()">
<div class="uk-flex uk-flex-middle uk-flex-center"> <div class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto"> <div class="uk-width-auto">
@ -79,7 +83,7 @@
</li> </li>
</ul> </ul>
</div> </div>
<div *ngIf="stakeholder && stakeholder.topics.length > 0" class="uk-position-bottom uk-margin-bottom"> <div *ngIf="stakeholder.topics.length > 0" class="uk-position-bottom uk-margin-bottom">
<div class="uk-flex uk-flex-center"> <div class="uk-flex uk-flex-center">
<button class="uk-icon-button uk-button-primary" uk-tooltip="Preview"> <button class="uk-icon-button uk-button-primary" uk-tooltip="Preview">
<icon name="visibility" [flex]="true"></icon> <icon name="visibility" [flex]="true"></icon>
@ -131,10 +135,12 @@
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false"> <div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li> <ng-container *ngIf="isCurator">
<a (click)="editCategoryOpen(i); hide(element)">Edit</a> <li>
</li> <a (click)="editCategoryOpen(i); hide(element)">Edit</a>
<li class="uk-nav-divider"></li> </li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="category.visibility === v.value"> <li [class.uk-active]="category.visibility === v.value">
<a (click)="changeCategoryStatus(i, v.value);"> <a (click)="changeCategoryStatus(i, v.value);">
@ -146,16 +152,16 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<hr *ngIf="!category.defaultId" class="uk-nav-divider"> <ng-container *ngIf="!category.defaultId && isCurator">
<li *ngIf="!category.defaultId"> <li class="uk-nav-divider">
<a (click)="deleteCategoryOpen(i, 'delete'); hide(element)">Delete</a> <li><a (click)="deleteCategoryOpen(i, 'delete'); hide(element)">Delete</a></li>
</li> </ng-container>
</ul> </ul>
</div> </div>
</span> </span>
</li> </li>
</ng-template> </ng-template>
<li> <li *ngIf="isCurator">
<a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle"> <a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon> <icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Create new category</span> <span class="uk-margin-small-left">Create new category</span>
@ -181,12 +187,14 @@
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false"> <div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li> <ng-container *ngIf="isCurator">
<a (click)="editSubCategoryOpen(i); hide(element)">Edit</a> <li>
</li> <a (click)="editSubCategoryOpen(i); hide(element)">Edit</a>
<li *ngIf="indicators && indicators.isCurator"><a (click)=" indicators.exportIndicators();hide(element)">Export indicators</a></li> </li>
<li *ngIf="indicators && indicators.isCurator"><a (click)="file.value = ''; this.index=i; file.click(); hide(element)">Import indicators</a></li> <li *ngIf="indicators"><a (click)=" indicators.exportIndicators();hide(element)">Export indicators</a></li>
<li class="uk-nav-divider"></li> <li *ngIf="indicators"><a (click)="file.value = ''; this.index=i; file.click(); hide(element)">Import indicators</a></li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="subCategory.visibility === v.value"> <li [class.uk-active]="subCategory.visibility === v.value">
<a (click)="changeSubcategoryStatus(i, v.value)"> <a (click)="changeSubcategoryStatus(i, v.value)">
@ -198,16 +206,16 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
<hr *ngIf="!subCategory.defaultId" class="uk-nav-divider"> <ng-container *ngIf="!subCategory.defaultId && isCurator">
<li *ngIf="!subCategory.defaultId"> <li class="uk-nav-divider">
<a (click)="deleteSubcategoryOpen(i, 'delete'); hide(element)">Delete</a> <li><a (click)="deleteSubcategoryOpen(i, 'delete'); hide(element)">Delete</a></li>
</li> </ng-container>
</ul> </ul>
</div> </div>
</span> </span>
</li> </li>
</ng-template> </ng-template>
<li> <li *ngIf="isCurator">
<a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle"> <a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon> <icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Create new subcategory</span> <span class="uk-margin-small-left">Create new subcategory</span>
@ -216,11 +224,11 @@
</ul> </ul>
<input #file id="import-file" type="file" class="uk-hidden" (change)="indicators.fileChangeEvent($event, this.index)"/> <input #file id="import-file" type="file" class="uk-hidden" (change)="indicators.fileChangeEvent($event, this.index)"/>
<indicators #indicators [topicIndex]="topicIndex" [categoryIndex]="categoryIndex" <indicators #indicators [topicIndex]="topicIndex" [categoryIndex]="categoryIndex"
[subcategoryIndex]="subCategoryIndex" [subcategoryIndex]="subCategoryIndex" [user]="user"
[stakeholder]="stakeholder" [changed]="change.asObservable()"></indicators> [stakeholder]="stakeholder" [changed]="change.asObservable()"></indicators>
</div> </div>
</div> </div>
<modal-alert #deleteModal (alertOutput)="deleteElement()"> <modal-alert #deleteModal (alertOutput)="deleteElement()" [overflowBody]="false">
You are about to delete <span class="uk-text-bold" *ngIf="element">"{{element.name}}"</span> {{type}} permanently. You are about to delete <span class="uk-text-bold" *ngIf="element">"{{element.name}}"</span> {{type}} permanently.
<div *ngIf="elementChildrenActionOnDelete == 'delete'" class="uk-text-bold"> <div *ngIf="elementChildrenActionOnDelete == 'delete'" class="uk-text-bold">
{{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well. {{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well.

View File

@ -14,6 +14,8 @@ import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard";
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {Option} from "../openaireLibrary/sharedComponents/input/input.component"; import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
import {properties} from "../../environments/environment"; import {properties} from "../../environments/environment";
import {Session, User} from "../openaireLibrary/login/utils/helper.class";
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
declare var UIkit; declare var UIkit;
@ -29,6 +31,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
public loading: boolean = true; public loading: boolean = true;
public stickyPageHeader: boolean = false; public stickyPageHeader: boolean = false;
public stakeholder: Stakeholder; public stakeholder: Stakeholder;
public user: User;
/** /**
* Stakeholder change event * Stakeholder change event
* */ * */
@ -69,6 +72,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
private title: Title, private title: Title,
private fb: FormBuilder, private fb: FormBuilder,
private stakeholderService: StakeholderService, private stakeholderService: StakeholderService,
private userManagementService: UserManagementService,
private layoutService: LayoutService) { private layoutService: LayoutService) {
} }
@ -102,6 +106,9 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
}); });
this.subscriptions.push(subscription); this.subscriptions.push(subscription);
}); });
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}))
} }
public ngOnDestroy() { public ngOnDestroy() {
@ -435,6 +442,10 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}}); this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}});
} }
get isCurator(): boolean {
return Session.isPortalAdministrator(this.user) || Session.isCurator(this.stakeholder.type, this.user);
}
private editOpen() { private editOpen() {
this.editModal.cancelButtonText = 'Cancel'; this.editModal.cancelButtonText = 'Cancel';
this.editModal.okButtonLeft = false; this.editModal.okButtonLeft = false;
@ -509,16 +520,6 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
})); }));
} }
public toggleStatusByIndex(index: number, visibility: Visibility, type) {
if (type == "sub") {
this.changeSubcategoryStatus(index, visibility);
} else if (type == "cat") {
this.changeCategoryStatus(index, visibility);
} else if (type == "topic") {
this.changeTopicStatus(index, visibility);
}
}
private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility) { private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility) {
this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => { this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => {
element.visibility = visibility; element.visibility = visibility;