1. Add cache in get managers and members methods. 2. Add delete Authorization level with values curator and manager in role users for managers. Authorization level for mebers are always manager. 3. Clear cache when managers and members list has been updated.

This commit is contained in:
Konstantinos Triantafyllou 2023-02-09 16:30:24 +02:00
parent a4dbbffe20
commit 1e35eb5d6f
4 changed files with 43 additions and 16 deletions

View File

@ -67,9 +67,11 @@
<div class="uk-card-body"> <div class="uk-card-body">
<span class="uk-text-bold uk-text-large">{{(showCurrent) ? item.email : item}}</span> <span class="uk-text-bold uk-text-large">{{(showCurrent) ? item.email : item}}</span>
</div> </div>
<div *ngIf="isCurator || !showCurrent" class="uk-card-footer uk-flex uk-flex-right"> <div *ngIf="!showCurrent || role === 'member' || canDelete" class="uk-card-footer uk-flex uk-flex-right">
<button (click)="openDeleteModal(item)" class="uk-button uk-button-link uk-flex uk-flex-middle" [disabled]="role === 'member' && item.isManager" <button (click)="openDeleteModal(item)" class="uk-button uk-button-link uk-flex uk-flex-middle"
[attr.uk-tooltip]="(role === 'member' && item.isManager)?'This user is a manager and cannot be removed.':null"> [disabled]="(role === 'member' && item.isManager) || isMe(item.id)"
[attr.uk-tooltip]="(role === 'member' && item.isManager)?'This user is a manager and cannot be removed.':
(isMe(item.id)?'You cannot remove yourself':null)">
<icon name="delete" [flex]="true" type="filled"></icon> <icon name="delete" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">{{showCurrent ? 'Delete' : 'Cancel invitation'}}</span> <span class="uk-margin-small-left uk-text-bold uk-text-uppercase">{{showCurrent ? 'Delete' : 'Cancel invitation'}}</span>
</button> </button>

View File

@ -11,6 +11,7 @@ import {StringUtils} from "../../../utils/string-utils.class";
import {NotificationService} from "../../../notifications/notification.service"; import {NotificationService} from "../../../notifications/notification.service";
import {Subscription} from "rxjs"; import {Subscription} from "rxjs";
import {NotificationHandler} from "../../../utils/notification-handler"; import {NotificationHandler} from "../../../utils/notification-handler";
import {ClearCacheService} from "../../../services/clear-cache.service";
@Component({ @Component({
selector: 'role-users', selector: 'role-users',
@ -29,6 +30,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@Input() @Input()
public role: "member" | "manager" = "manager"; public role: "member" | "manager" = "manager";
@Input() @Input()
public deleteAuthorizationLevel: 'curator' | 'manager' = 'curator';
@Input()
public message: string = null; public message: string = null;
@Input() @Input()
public emailComposer: Function; public emailComposer: Function;
@ -63,6 +66,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
constructor(private userRegistryService: UserRegistryService, constructor(private userRegistryService: UserRegistryService,
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private clearCacheService: ClearCacheService,
private notificationService: NotificationService, private notificationService: NotificationService,
private router: Router, private router: Router,
private fb: UntypedFormBuilder) { private fb: UntypedFormBuilder) {
@ -73,6 +77,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
this.updateLists(); this.updateLists();
this.userManagementService.getUserInfo().subscribe(user => { this.userManagementService.getUserInfo().subscribe(user => {
this.user = user; this.user = user;
console.log(this.canDelete)
}); });
} }
@ -196,6 +201,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
} }
this.filterActiveBySearch(this.filterForm.value.active); this.filterActiveBySearch(this.filterForm.value.active);
this.userManagementService.updateUserInfo(); this.userManagementService.updateUserInfo();
this.clearCacheService.clearCache(this.role + 's of ' + this.id + ' have been updated');
NotificationHandler.rise(this.selectedUser + ' <b>is no longer</b> ' + this.role + ' of ' + this.name + ' Dashboard'); NotificationHandler.rise(this.selectedUser + ' <b>is no longer</b> ' + this.role + ' of ' + this.name + ' Dashboard');
this.loadActive = false; this.loadActive = false;
}, error => { }, error => {
@ -267,6 +273,18 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
}); });
} }
public get canDelete() {
return (this.deleteAuthorizationLevel === 'curator'?this.isCurator:this.isManager);
}
public isMe(userId: string) {
return userId.includes(this.user.id) && !this.isCurator;
}
public get isManager(): boolean {
return this.isCurator || !!Session.isManager(this.type, this.id, this.user);
}
public get isCurator(): boolean { public get isCurator(): boolean {
return this.isPortalAdmin || !!Session.isCurator(this.type, this.user); return this.isPortalAdmin || !!Session.isCurator(this.type, this.user);
} }

View File

@ -10,6 +10,7 @@ import {AlertModal} from "../utils/modal/alert";
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
import {EmailService} from "../utils/email/email.service"; import {EmailService} from "../utils/email/email.service";
import {Composer} from "../utils/email/composer"; import {Composer} from "../utils/email/composer";
import {ClearCacheService} from "../services/clear-cache.service";
@Component({ @Component({
selector: 'role-verification', selector: 'role-verification',
@ -106,7 +107,8 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
private emailService: EmailService, private emailService: EmailService,
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private userRegistryService: UserRegistryService) { private userRegistryService: UserRegistryService,
private clearCacheService: ClearCacheService) {
} }
ngOnInit() { ngOnInit() {
@ -195,6 +197,7 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn
public verifyManager() { public verifyManager() {
this.loading = true; this.loading = true;
this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value).subscribe(() => { this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value).subscribe(() => {
this.clearCacheService.clearCache('Managers updated');
this.managerModal.cancel(); this.managerModal.cancel();
this.error = null; this.error = null;
this.userManagementService.updateUserInfo(() => { this.userManagementService.updateUserInfo(() => {
@ -232,6 +235,7 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn
this.loading = true; this.loading = true;
if (!this.isMember) { if (!this.isMember) {
this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value, "member").subscribe(() => { this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value, "member").subscribe(() => {
this.clearCacheService.clearCache('Members updated');
this.loading = false; this.loading = false;
this.error = null; this.error = null;
this.userManagementService.updateUserInfo(() => { this.userManagementService.updateUserInfo(() => {

View File

@ -14,50 +14,52 @@ export class UserRegistryService {
} }
public createRole(type: string, id: string): Observable<any[]> { public createRole(type: string, id: string): Observable<any[]> {
return this.http.post<any>(properties.registryUrl + 'create/' + encodeURIComponent(type) + '/' + encodeURIComponent(id), null, return this.http.post<any>(properties.registryUrl + 'create/' + type + '/' + id, null,
CustomOptions.registryOptions()).pipe(map((response: any) => response.response)); CustomOptions.registryOptions()).pipe(map((response: any) => response.response));
} }
public getMembersCount(type: string, id: string): Observable<any> { public getMembersCount(type: string, id: string): Observable<any> {
return this.http.get(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/members/count'); let url = properties.registryUrl + type + '/' + id + '/members/count';
return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url);
} }
public subscribeTo(type: string, id: string): Observable<any> { public subscribeTo(type: string, id: string): Observable<any> {
return this.http.post(properties.registryUrl + 'subscribe/' + encodeURIComponent(type) + '/' + encodeURIComponent(id), return this.http.post(properties.registryUrl + 'subscribe/' + type + '/' + id,
null, CustomOptions.registryOptions()); null, CustomOptions.registryOptions());
} }
public unsubscribeFrom(type: string, id: string): Observable<any> { public unsubscribeFrom(type: string, id: string): Observable<any> {
return this.http.post(properties.registryUrl + 'unsubscribe/' + encodeURIComponent(type) + '/' + encodeURIComponent(id), return this.http.post(properties.registryUrl + 'unsubscribe/' + type + '/' + id,
null, CustomOptions.registryOptions()); null, CustomOptions.registryOptions());
} }
public remove(type: string, id: string, email: string, role: "member" | "manager" = "manager"): Observable<any> { public remove(type: string, id: string, email: string, role: "member" | "manager" = "manager"): Observable<any> {
return this.http.delete<any>(properties.registryUrl + return this.http.delete<any>(properties.registryUrl +
encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/' + role + '/' + encodeURIComponent(email), CustomOptions.registryOptions()); type + '/' + id + '/' + role + '/' + encodeURIComponent(email), CustomOptions.registryOptions());
} }
public invite(type: string, id: string, details: any, role: "member" | "manager" = "manager"): Observable<any[]> { public invite(type: string, id: string, details: any, role: "member" | "manager" = "manager"): Observable<any[]> {
return this.http.post<any>(properties.registryUrl + 'invite/' + return this.http.post<any>(properties.registryUrl + 'invite/' +
encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/' + role, details, type + '/' + id + '/' + role, details,
CustomOptions.registryOptions()).pipe(map((response: any) => response.response)); CustomOptions.registryOptions()).pipe(map((response: any) => response.response));
} }
public verify(id: string, code: string, role: "member" | "manager" = "manager"): Observable<any> { public verify(id: string, code: string, role: "member" | "manager" = "manager"): Observable<any> {
return this.http.post<any>(properties.registryUrl + 'verification/' + role + '/' + encodeURIComponent(id), code, CustomOptions.registryOptions()); return this.http.post<any>(properties.registryUrl + 'verification/' + role + '/' + id, code, CustomOptions.registryOptions());
} }
public getInvitation(id: string): Observable<any> { public getInvitation(id: string): Observable<any> {
return this.http.get<any>(properties.registryUrl + 'verification/' + encodeURIComponent(id), CustomOptions.registryOptions()) return this.http.get<any>(properties.registryUrl + 'verification/' + id, CustomOptions.registryOptions())
.pipe(map((response: any) => response.response)); .pipe(map((response: any) => response.response));
} }
public deleteVerification(id: string): Observable<any> { public deleteVerification(id: string): Observable<any> {
return this.http.delete<any>(properties.registryUrl + 'verification/' + encodeURIComponent(id), CustomOptions.registryOptions()); return this.http.delete<any>(properties.registryUrl + 'verification/' + id, CustomOptions.registryOptions());
} }
public getActive(type: string, id: string, role: "member" | "manager" = "manager"): Observable<any[]> { public getActive(type: string, id: string, role: "member" | "manager" = "manager"): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + encodeURIComponent(type) + '/' + encodeURIComponent(id) + "/" + role + 's', let url = properties.registryUrl + type + '/' + id + "/" + role + 's';
return this.http.get<any>((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url,
CustomOptions.registryOptions()).pipe(map((response:any) => response.response), map(users => { CustomOptions.registryOptions()).pipe(map((response:any) => response.response), map(users => {
if(users.length > 0 && !users[0].email) { if(users.length > 0 && !users[0].email) {
return []; return [];
@ -68,13 +70,14 @@ export class UserRegistryService {
} }
public getPending(type: string, id: string, role: "member" | "manager" = "manager"): Observable<any[]> { public getPending(type: string, id: string, role: "member" | "manager" = "manager"): Observable<any[]> {
return this.http.get<any>(properties.registryUrl + 'invite/' + encodeURIComponent(type) + '/' + encodeURIComponent(id) + "/" + role + 's/', let url = properties.registryUrl + 'invite/' +type + '/' +id + "/" + role + 's/';
return this.http.get<any>((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url,
CustomOptions.registryOptions()).pipe(map((response: any) => response.response)); CustomOptions.registryOptions()).pipe(map((response: any) => response.response));
} }
public cancelInvitation(type: string, id: string, email: string, role: "member" | "manager" = "manager"): Observable<any> { public cancelInvitation(type: string, id: string, email: string, role: "member" | "manager" = "manager"): Observable<any> {
return this.http.delete<any>(properties.registryUrl + 'invite/' + return this.http.delete<any>(properties.registryUrl + 'invite/' +
encodeURIComponent(type) + '/' + encodeURIComponent(id) + '/' + role + '/' + encodeURIComponent(email), type + '/' + id + '/' + role + '/' + encodeURIComponent(email),
CustomOptions.registryOptions()); CustomOptions.registryOptions());
} }
} }