2023-06-26 14:09:37 +02:00
import {
ChangeDetectorRef ,
Component ,
Input ,
OnChanges ,
OnDestroy ,
OnInit ,
SimpleChanges ,
ViewChild
} from '@angular/core' ;
2023-11-30 13:20:00 +01:00
import { UntypedFormArray , UntypedFormBuilder , UntypedFormGroup , ValidatorFn , Validators } from '@angular/forms' ;
2020-11-03 19:25:03 +01:00
import { AlertModal } from "../../../utils/modal/alert" ;
import { UserRegistryService } from "../../../services/user-registry.service" ;
import { EnvProperties } from "../../../utils/properties/env-properties" ;
import { properties } from "../../../../../environments/environment" ;
2021-02-04 14:36:29 +01:00
import { Role , Session , User } from "../../../login/utils/helper.class" ;
2020-11-12 18:49:20 +01:00
import { UserManagementService } from "../../../services/user-management.service" ;
import { Router } from "@angular/router" ;
2020-11-26 17:13:52 +01:00
import { StringUtils } from "../../../utils/string-utils.class" ;
2021-03-04 12:32:57 +01:00
import { NotificationService } from "../../../notifications/notification.service" ;
2023-06-26 14:09:37 +02:00
import { forkJoin , of , Subscription } from "rxjs" ;
2022-07-13 19:25:19 +02:00
import { NotificationHandler } from "../../../utils/notification-handler" ;
2023-02-09 15:30:24 +01:00
import { ClearCacheService } from "../../../services/clear-cache.service" ;
2023-06-26 14:09:37 +02:00
import { catchError , map , tap } from "rxjs/operators" ;
import { InputComponent } from "../../../sharedComponents/input/input.component" ;
2024-04-08 13:14:09 +02:00
import { StakeholderUtils } from "../../../monitor-admin/utils/indicator-utils" ;
2023-06-26 14:09:37 +02:00
class InvitationResponse {
email : string ;
invitation : any ;
constructor ( email , invitation ) {
this . email = email ;
this . invitation = invitation ;
}
}
2020-11-03 19:25:03 +01:00
@Component ( {
selector : 'role-users' ,
templateUrl : 'role-users.component.html'
} )
export class RoleUsersComponent implements OnInit , OnDestroy , OnChanges {
@Input ( )
public id : string ;
@Input ( )
2024-04-25 14:11:04 +02:00
set type ( type : string ) {
this . _type = Role . mapType ( type ) ;
}
2020-11-03 19:25:03 +01:00
@Input ( )
public name : string ;
@Input ( )
public link : string ;
@Input ( )
2020-11-19 18:13:27 +01:00
public role : "member" | "manager" = "manager" ;
@Input ( )
2023-02-09 15:30:24 +01:00
public deleteAuthorizationLevel : 'curator' | 'manager' = 'curator' ;
@Input ( )
2024-04-08 13:14:09 +02:00
public inviteAuthorizationLevel : 'curator' | 'manager' = 'manager' ;
@Input ( )
2021-01-15 11:19:08 +01:00
public message : string = null ;
2021-01-15 12:58:34 +01:00
@Input ( )
public emailComposer : Function ;
2021-03-01 19:19:53 +01:00
@Input ( )
public notificationFn : Function ;
2021-05-17 13:28:04 +02:00
@Input ( )
public inviteDisableMessage : string ;
2021-01-15 11:19:08 +01:00
public user : User = null ;
2021-09-17 19:13:35 +02:00
public active : any [ ] = [ ] ;
2021-03-28 13:07:48 +02:00
public showActive : any [ ] = [ ] ;
2020-11-03 19:25:03 +01:00
public pending : any [ ] ;
2021-03-28 13:07:48 +02:00
public showPending : any [ ] = [ ] ;
public showCurrent : boolean = true ;
2020-11-03 19:25:03 +01:00
public subs : any [ ] = [ ] ;
public loadActive : boolean = true ;
public loadPending : boolean = true ;
public selectedUser : string = null ;
2023-06-26 14:09:37 +02:00
public emailsForm : UntypedFormArray ;
public validators : ValidatorFn [ ] = [ Validators . email ] ;
2020-11-03 19:25:03 +01:00
public properties : EnvProperties = properties ;
public exists : boolean = true ;
2022-09-23 12:25:08 +02:00
public roleFb : UntypedFormGroup ;
2021-03-28 13:07:48 +02:00
/** Paging */
activePage : number = 1 ;
pendingPage : number = 1 ;
2022-03-22 16:47:38 +01:00
pageSize : number = 10 ;
2021-03-28 13:07:48 +02:00
/** Search */
2022-09-23 12:25:08 +02:00
filterForm : UntypedFormGroup ;
2020-11-03 19:25:03 +01:00
@ViewChild ( 'inviteModal' ) inviteModal : AlertModal ;
2023-06-26 14:09:37 +02:00
@ViewChild ( 'emailInput' ) emailInput : InputComponent ;
2020-11-03 19:25:03 +01:00
@ViewChild ( 'deleteModal' ) deleteModal : AlertModal ;
@ViewChild ( 'deletePendingModal' ) deletePendingModal : AlertModal ;
@ViewChild ( 'createRoleModal' ) createRoleModal : AlertModal ;
2024-04-08 13:14:09 +02:00
public stakeholderUtils : StakeholderUtils = new StakeholderUtils ( ) ;
2024-04-25 14:11:04 +02:00
private _type : string ;
2020-11-03 19:25:03 +01:00
constructor ( private userRegistryService : UserRegistryService ,
2020-11-12 18:49:20 +01:00
private userManagementService : UserManagementService ,
2023-02-09 15:30:24 +01:00
private clearCacheService : ClearCacheService ,
2021-03-04 12:32:57 +01:00
private notificationService : NotificationService ,
2023-06-26 14:09:37 +02:00
private cdr : ChangeDetectorRef ,
2022-09-23 12:25:08 +02:00
private fb : UntypedFormBuilder ) {
2020-11-03 19:25:03 +01:00
}
ngOnInit() {
2021-03-28 13:15:33 +02:00
this . initForm ( ) ;
this . updateLists ( ) ;
this . userManagementService . getUserInfo ( ) . subscribe ( user = > {
this . user = user ;
2021-03-28 13:07:48 +02:00
} ) ;
2020-11-03 19:25:03 +01:00
}
ngOnChanges ( changes : SimpleChanges ) {
2021-03-28 13:15:33 +02:00
if ( changes . role ) {
2021-01-27 15:15:50 +01:00
this . unsubscribe ( ) ;
2021-03-28 13:15:33 +02:00
this . initForm ( ) ;
2020-11-03 19:25:03 +01:00
this . updateLists ( ) ;
}
}
ngOnDestroy() {
2021-01-27 15:15:50 +01:00
this . unsubscribe ( ) ;
}
unsubscribe() {
2020-11-03 19:25:03 +01:00
this . subs . forEach ( sub = > {
if ( sub instanceof Subscription ) {
sub . unsubscribe ( ) ;
}
} ) ;
}
2021-03-28 13:15:33 +02:00
initForm() {
this . filterForm = this . fb . group ( {
active : this.fb.control ( '' ) ,
pending : this.fb.control ( '' )
} ) ;
this . subs . push ( this . filterForm . get ( 'active' ) . valueChanges . subscribe ( value = > {
this . filterActiveBySearch ( value ) ;
} ) ) ;
this . subs . push ( this . filterForm . get ( 'pending' ) . valueChanges . subscribe ( value = > {
this . filterPendingBySearch ( value ) ;
} ) ) ;
}
2020-11-03 19:25:03 +01:00
updateLists() {
this . loadActive = true ;
this . loadPending = true ;
2024-04-25 14:11:04 +02:00
this . subs . push ( this . userRegistryService . getActive ( this . _type , this . id , this . role , true ) . subscribe ( users = > {
2021-09-17 19:13:35 +02:00
this . active = users ;
this . filterActiveBySearch ( this . filterForm . value . active ) ;
this . loadActive = false ;
this . exists = true ;
2020-11-03 19:25:03 +01:00
} , error = > {
this . active = [ ] ;
2021-06-10 21:03:16 +02:00
this . showActive = [ ] ;
2021-03-28 13:15:33 +02:00
if ( error . status === 404 ) {
2020-11-03 19:25:03 +01:00
this . exists = false ;
}
this . loadActive = false ;
} ) ) ;
2024-04-25 14:11:04 +02:00
this . subs . push ( this . userRegistryService . getPending ( this . _type , this . id , this . role , true ) . subscribe ( users = > {
2020-11-03 19:25:03 +01:00
this . pending = users ;
2021-03-28 13:07:48 +02:00
this . filterPendingBySearch ( this . filterForm . value . pending ) ;
2020-11-03 19:25:03 +01:00
this . loadPending = false ;
} , error = > {
2021-03-11 13:55:59 +01:00
this . pending = [ ] ;
2020-11-26 17:13:52 +01:00
this . loadPending = false ;
2020-11-03 19:25:03 +01:00
} ) ) ;
}
2021-04-08 16:35:39 +02:00
get currentActivePage ( ) : any [ ] {
2021-08-03 11:54:41 +02:00
if ( this . showActive ) {
return this . showActive . slice ( ( this . activePage - 1 ) * this . pageSize , this . activePage * this . pageSize ) ;
2021-04-08 16:35:39 +02:00
} else {
return [ ] ;
}
}
get currentPendingPage ( ) : any [ ] {
2021-08-03 11:54:41 +02:00
if ( this . showPending ) {
return this . showPending . slice ( ( this . pendingPage - 1 ) * this . pageSize , this . pendingPage * this . pageSize ) ;
2021-04-08 16:35:39 +02:00
} else {
return [ ] ;
}
}
2020-11-03 19:25:03 +01:00
openDeleteModal ( item : any ) {
2021-03-28 13:07:48 +02:00
if ( this . showCurrent ) {
2020-11-03 19:25:03 +01:00
this . selectedUser = item . email ;
2024-04-08 13:14:09 +02:00
this . deleteModal . alertTitle = 'Delete ' + this . stakeholderUtils . roles [ this . role ] ;
2020-11-03 19:25:03 +01:00
this . deleteModal . open ( ) ;
} else {
this . selectedUser = item ;
this . deletePendingModal . alertTitle = 'Cancel invitation' ;
this . deletePendingModal . open ( ) ;
}
}
openInviteModal() {
2024-04-08 13:14:09 +02:00
this . inviteModal . alertTitle = 'Invite ' + this . stakeholderUtils . roles [ this . role ] ;
2020-11-03 19:25:03 +01:00
this . inviteModal . okButtonLeft = false ;
this . inviteModal . okButtonText = 'Send' ;
2023-06-26 14:09:37 +02:00
this . emailsForm = this . fb . array ( [ ] , Validators . required ) ;
this . cdr . detectChanges ( ) ;
2020-11-03 19:25:03 +01:00
this . inviteModal . open ( ) ;
}
openCreateRoleModal() {
this . createRoleModal . alertTitle = 'Create group' ;
this . createRoleModal . okButtonLeft = false ;
2021-01-27 15:06:28 +01:00
this . createRoleModal . okButtonText = 'Create' ;
2020-11-03 19:25:03 +01:00
this . roleFb = this . fb . group ( {
2024-04-25 14:11:04 +02:00
name : this.fb.control ( Role . roleName ( this . _type , this . id ) , Validators . required ) ,
description : this.fb.control ( Role . roleName ( this . _type , this . id ) , Validators . required )
2020-11-03 19:25:03 +01:00
} ) ;
setTimeout ( ( ) = > {
this . roleFb . get ( 'name' ) . disable ( ) ;
2021-09-17 19:13:35 +02:00
this . roleFb . get ( 'description' ) . disable ( ) ;
2020-11-03 19:25:03 +01:00
} , 0 ) ;
this . createRoleModal . open ( ) ;
}
deleteActive() {
this . loadActive = true ;
2024-04-25 14:11:04 +02:00
this . subs . push ( this . userRegistryService . remove ( this . _type , this . id , this . selectedUser , this . role ) . subscribe ( ( ) = > {
2020-11-03 19:25:03 +01:00
this . active = this . active . filter ( user = > user . email != this . selectedUser ) ;
2021-09-17 19:13:35 +02:00
if ( this . currentActivePage . length === 0 ) {
2021-04-08 16:35:39 +02:00
this . activePage = 1 ;
}
2021-03-28 13:07:48 +02:00
this . filterActiveBySearch ( this . filterForm . value . active ) ;
2020-11-12 18:49:20 +01:00
this . userManagementService . updateUserInfo ( ) ;
2023-02-09 15:30:24 +01:00
this . clearCacheService . clearCache ( this . role + 's of ' + this . id + ' have been updated' ) ;
2022-07-13 19:25:19 +02:00
NotificationHandler . rise ( this . selectedUser + ' <b>is no longer</b> ' + this . role + ' of ' + this . name + ' Dashboard' ) ;
2020-11-03 19:25:03 +01:00
this . loadActive = false ;
} , error = > {
2022-07-13 19:25:19 +02:00
NotificationHandler . rise ( 'An error has occurred. Please try again later' , 'danger' ) ;
2020-11-03 19:25:03 +01:00
this . loadActive = false ;
2021-03-01 19:19:53 +01:00
} ) ) ;
2020-11-03 19:25:03 +01:00
}
deletePending() {
this . loadPending = true ;
2024-04-25 14:11:04 +02:00
this . subs . push ( this . userRegistryService . cancelInvitation ( this . _type , this . id , this . selectedUser , this . role ) . subscribe ( ( ) = > {
2020-11-03 19:25:03 +01:00
this . pending = this . pending . filter ( user = > user != this . selectedUser ) ;
2021-03-28 13:07:48 +02:00
this . filterPendingBySearch ( this . filterForm . value . pending ) ;
2021-09-17 19:13:35 +02:00
if ( this . currentPendingPage . length === 0 ) {
2021-04-08 16:35:39 +02:00
this . pendingPage = 1 ;
}
2024-04-08 13:14:09 +02:00
NotificationHandler . rise ( StringUtils . capitalize ( this . stakeholderUtils . roles [ this . role ] ) + ' invitation to ' + this . selectedUser + ' has been <b>canceled</b>' ) ;
2020-11-03 19:25:03 +01:00
this . loadPending = false ;
} , error = > {
2022-07-13 19:25:19 +02:00
NotificationHandler . rise ( 'An error has occurred. Please try again later' , 'danger' ) ;
2020-11-03 19:25:03 +01:00
this . loadPending = false ;
2021-03-01 19:19:53 +01:00
} ) ) ;
2020-11-03 19:25:03 +01:00
}
2023-06-26 14:09:37 +02:00
get valid() {
return this . emailsForm && this . emailsForm . valid || ( this . emailInput && this . emailInput . searchControl . getRawValue ( ) && this . emailInput . searchControl . valid ) ;
}
2020-11-03 19:25:03 +01:00
invite() {
2023-06-26 14:09:37 +02:00
if ( this . emailInput . searchControl . getRawValue ( ) && this . emailInput . searchControl . valid ) {
this . emailInput . add ( null , true ) ;
}
2021-03-28 13:07:48 +02:00
this . showCurrent = false ;
2020-11-13 13:51:35 +01:00
this . loadPending = true ;
2023-06-26 14:09:37 +02:00
let current = null ;
let invitations = ( < Array < any > > this . emailsForm . value ) . map ( email = > {
current = email ;
2024-04-25 14:11:04 +02:00
return this . userRegistryService . invite ( this . _type , this . id , {
2023-06-26 14:09:37 +02:00
link : this.link ,
email : this.emailComposer ( this . name , email , this . role )
2024-04-08 14:17:53 +02:00
} , this . role ) . pipe ( catchError ( error = > {
return of ( null ) ;
} ) , map ( invitation = > new InvitationResponse ( email , invitation ) ) ) ;
2023-06-26 14:09:37 +02:00
} ) ;
this . subs . push ( forkJoin ( invitations ) . subscribe ( responses = > {
let notifications = responses . map ( response = > {
if ( response . invitation ) {
NotificationHandler . rise ( StringUtils . capitalize ( this . role ) + ' invitation to ' + response . email + ' has been <b>sent</b>' ) ;
if ( ! this . pending . includes ( response . email ) ) {
this . pending . push ( response . email ) ;
}
2024-01-09 09:51:03 +01:00
if ( this . notificationFn && properties . notificationsAPIURL ) {
2023-06-26 14:09:37 +02:00
return this . notificationService . sendNotification ( this . notificationFn ( this . name , response . email , this . role , response . invitation ) ) . pipe ( map ( notification = > {
return notification ;
} ) , tap ( ( ) = > {
NotificationHandler . rise ( 'A notification has been <b>sent</b> successfully to ' + response . email ) ;
} ) , catchError ( error = > {
NotificationHandler . rise ( 'An error has occurred while sending a notification to ' + response . email + '. Please try again later' , 'danger' ) ;
return of ( null ) ;
} ) ) ;
} else {
return of ( null ) ;
}
} else {
2024-04-08 14:17:53 +02:00
NotificationHandler . rise ( 'An error has occurred while sending the invitation mail to ' +
response . email + '.Check if the user is already a ' + this . stakeholderUtils . roles [ this . role ] + ' or try again later' , 'danger' ) ;
2023-06-26 14:09:37 +02:00
return of ( null ) ;
}
} ) ;
this . subs . push ( forkJoin ( notifications ) . subscribe ( ( ) = > {
2021-09-17 19:13:35 +02:00
this . pendingPage = Math . ceil ( this . pending . length / this . pageSize ) ;
2021-03-28 13:07:48 +02:00
this . filterPendingBySearch ( this . filterForm . value . pending ) ;
2023-06-26 14:09:37 +02:00
this . loadPending = false ;
} ) )
2021-03-01 19:19:53 +01:00
} ) ) ;
2020-11-03 19:25:03 +01:00
}
createGroup() {
this . loadActive = true ;
this . loadPending = true ;
2024-04-25 14:11:04 +02:00
this . userRegistryService . createRole ( this . _type , this . id ) . subscribe ( ( ) = > {
2022-07-13 19:25:19 +02:00
NotificationHandler . rise ( 'Group has been <b> successfully created</b>' ) ;
2020-11-03 19:25:03 +01:00
this . updateLists ( ) ;
} , error = > {
2022-07-29 11:15:54 +02:00
if ( error . status === 409 ) {
2024-04-08 13:14:09 +02:00
NotificationHandler . rise ( 'Group already exists. You can try to invite a ' + this . stakeholderUtils . roles [ this . role ] + ' instead.' , 'warning' ) ;
2022-07-29 11:15:54 +02:00
this . updateLists ( ) ;
} else {
NotificationHandler . rise ( 'An error has occurred. Please try again later' , 'danger' ) ;
this . loadActive = false ;
this . loadPending = false ;
}
2020-11-03 19:25:03 +01:00
} ) ;
}
2021-01-15 11:19:08 +01:00
2023-02-09 15:30:24 +01:00
public get canDelete() {
return ( this . deleteAuthorizationLevel === 'curator' ? this . isCurator :this.isManager ) ;
}
2024-04-08 13:14:09 +02:00
public get canInvite() {
return this . exists && ( this . inviteAuthorizationLevel === 'curator' ? this . isCurator :this.isManager ) ;
}
2023-02-09 15:30:24 +01:00
public isMe ( userId : string ) {
2023-03-21 13:02:59 +01:00
return userId && userId . includes ( this . user . id ) && ! this . isCurator ;
2023-02-09 15:30:24 +01:00
}
public get isManager ( ) : boolean {
2024-04-25 14:11:04 +02:00
return this . isCurator || ! ! Session . isManager ( this . _type , this . id , this . user ) ;
2023-02-09 15:30:24 +01:00
}
2021-02-17 15:37:28 +01:00
public get isCurator ( ) : boolean {
2024-04-25 14:11:04 +02:00
return this . isPortalAdmin || ! ! Session . isCurator ( this . _type , this . user ) ;
2021-02-17 15:37:28 +01:00
}
public get isPortalAdmin ( ) : boolean {
return ! ! Session . isPortalAdministrator ( this . user ) ;
2021-01-15 11:19:08 +01:00
}
2021-03-28 13:07:48 +02:00
updateActivePage ( event : any ) {
this . activePage = event . value ;
}
updatePendingPage ( event : any ) {
this . pendingPage = event . value ;
}
private filterActiveBySearch ( value : any ) {
this . showActive = this . active . filter ( active = > ! value || active . email . includes ( value ) ) ;
this . activePage = 1 ;
}
private filterPendingBySearch ( value : any ) {
this . showPending = this . pending . filter ( pending = > ! value || pending . includes ( value ) ) ;
this . pendingPage = 1 ;
}
2020-11-03 19:25:03 +01:00
}