From c71a3e65b626ed13ebfa5d959bf888ce92c555a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 20 Oct 2021 02:25:54 +0300 Subject: [PATCH] RED-2519 --- ...er-templates-listing-screen.component.html | 6 +++- .../user-button/user-button.component.html | 2 +- .../user-button/user-button.component.ts | 3 ++ .../initials-avatar.component.html | 2 +- .../initials-avatar.component.ts | 26 ++++++++++------ .../src/app/modules/shared/pipes/name.pipe.ts | 9 +++--- apps/red-ui/src/app/services/user.service.ts | 31 +++++++++++++------ apps/red-ui/src/app/state/app-state.guard.ts | 4 +-- 8 files changed, 56 insertions(+), 27 deletions(-) diff --git a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html index c16e1da3f..9d80847a3 100644 --- a/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/dossier-template-listing/dossier-templates-listing-screen.component.html @@ -76,7 +76,11 @@
- +
diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.html b/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.html index 82028be44..d336757c6 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.html +++ b/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.html @@ -1,5 +1,5 @@
diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.ts index 7d38097fa..f0d95622c 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/buttons/user-button/user-button.component.ts @@ -1,4 +1,5 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { UserService } from '@services/user.service'; @Component({ selector: 'redaction-user-button', @@ -9,4 +10,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; export class UserButtonComponent { @Input() userId: string; @Input() showDot = false; + + constructor(readonly userService: UserService) {} } diff --git a/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.html b/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.html index b2f2ed660..538181b7c 100644 --- a/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.html +++ b/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.html @@ -4,7 +4,7 @@ [matTooltipPosition]="tooltipPosition" [matTooltip]="userName" > - {{ _user | name: { showInitials: true, defaultValue: ('initials-avatar.unassigned' | translate) } }} + {{ _user | name: { showInitials: true } }}
{{ userName }} diff --git a/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.ts b/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.ts index efe4e086b..ac759b710 100644 --- a/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/initials-avatar/initials-avatar.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core'; import { UserService } from '@services/user.service'; import { AutoUnsubscribe } from '@iqser/common-ui'; import { User } from '@models/user'; @@ -11,18 +11,16 @@ import { NamePipeOptions } from '@shared/pipes/name.pipe'; styleUrls: ['./initials-avatar.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy { +export class InitialsAvatarComponent extends AutoUnsubscribe implements OnInit, OnChanges, OnDestroy { @Input() color = 'lightgray'; @Input() size: 'small' | 'large' = 'small'; @Input() withName = false; @Input() showYou = false; @Input() tooltipPosition: 'below' | 'above' = 'above'; + @Input() defaultValue = this._translateService.instant('initials-avatar.unassigned'); colorClass: string; - readonly namePipeOptions: NamePipeOptions = { - showYou: this.showYou, - defaultValue: this._translateService.instant('initials-avatar.unassigned'), - }; + namePipeOptions: NamePipeOptions; constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) { super(); @@ -44,7 +42,7 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange } get disabled(): boolean { - return this._user && !this._user.isActive; + return this._user && !this._isSystemUser && !this._user.isActive; } get isCurrentUser(): boolean { @@ -65,13 +63,23 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange return `${this.color}-dark`; } + private get _isSystemUser() { + return this._user?.id?.toLowerCase() === 'system'; + } + ngOnChanges(): void { - const isSystemUser = this._user?.id?.toLowerCase() === 'system'; - if (isSystemUser) { + if (this._isSystemUser) { this.colorClass = 'primary-white primary'; return; } this.colorClass = this._colorClass; } + + ngOnInit(): void { + this.namePipeOptions = { + showYou: this.showYou, + defaultValue: this.defaultValue, + }; + } } diff --git a/apps/red-ui/src/app/modules/shared/pipes/name.pipe.ts b/apps/red-ui/src/app/modules/shared/pipes/name.pipe.ts index 13da6ecb4..90a54fe78 100644 --- a/apps/red-ui/src/app/modules/shared/pipes/name.pipe.ts +++ b/apps/red-ui/src/app/modules/shared/pipes/name.pipe.ts @@ -36,12 +36,13 @@ export class NamePipe implements PipeTransform { transform(value?: User | string, options = this._defaultOptions): string { let name; - if (!value || !isSystemUser(value)) { - name = this._getName(value) || options?.defaultValue; - } else { - name = 'System'; + + if (!value && options?.showInitials) { + return '?'; } + name = this._getName(value) || options?.defaultValue; + if (options?.showYou && this._isCurrentUser(value)) { name = `${name} (${this._translateService.instant('initials-avatar.you')})`; } diff --git a/apps/red-ui/src/app/services/user.service.ts b/apps/red-ui/src/app/services/user.service.ts index fa84aec68..39e815871 100644 --- a/apps/red-ui/src/app/services/user.service.ts +++ b/apps/red-ui/src/app/services/user.service.ts @@ -4,7 +4,7 @@ import jwt_decode from 'jwt-decode'; import { CreateUserRequest, IUser, ResetPasswordRequest, UpdateMyProfileRequest, UpdateProfileRequest } from '@redaction/red-ui-http'; import { wipeCaches } from '@redaction/red-cache'; import { BASE_HREF } from '../tokens'; -import { Observable } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { User } from '@models/user'; import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui'; import { tap } from 'rxjs/operators'; @@ -21,18 +21,20 @@ export interface ProfileModel { providedIn: 'root', }) export class UserService extends EntitiesService { + readonly currentUser$: Observable; + private readonly _currentUser$ = new BehaviorSubject(null); + constructor( protected readonly _injector: Injector, @Inject(BASE_HREF) private readonly _baseHref: string, private readonly _keycloakService: KeycloakService, ) { super(_injector, User, 'user'); + this.currentUser$ = this._currentUser$.asObservable(); } - private _currentUser: User; - get currentUser(): User { - return this._currentUser; + return this._currentUser$.value; } get managerUsers(): User[] { @@ -49,7 +51,7 @@ export class UserService extends EntitiesService { } loadAll() { - const all$ = this._currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true); + const all$ = this.currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true); return all$.pipe( mapEach(user => new User(user, user.roles, user.userId)), @@ -59,16 +61,20 @@ export class UserService extends EntitiesService { async loadCurrentUser() { const token = await this._keycloakService.getToken(); - const decoded: { sub: string } = jwt_decode(token); - const userId = decoded.sub; - this._currentUser = new User(await this._keycloakService.loadUserProfile(true), this._keycloakService.getUserRoles(true), userId); + const decoded = jwt_decode(token); + const userId = (<{ sub: string }>decoded).sub; + + const roles = this._keycloakService.getUserRoles(true).filter(role => role.startsWith('RED_')); + this.replace(new User(await this._keycloakService.loadUserProfile(true), roles, userId)); + + this._currentUser$.next(this.find(userId)); } getNameForId(userId: string): string | undefined { return this.find(userId)?.name; } - hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean { + hasAnyRole(requiredRoles: string[], user = this.currentUser): boolean { if (requiredRoles?.length > 0) { for (const role of requiredRoles) { if (user.roles.indexOf(role) >= 0) { @@ -111,4 +117,11 @@ export class UserService extends EntitiesService { const queryParams = userIds.map(userId => ({ key: 'userId', value: userId })); return super.delete(userIds, this._defaultModelPath, queryParams); } + + find(id: string): User | undefined { + if (id?.toLowerCase() === 'system') { + return new User({ email: 'System' }, [], 'system'); + } + return super.find(id); + } } diff --git a/apps/red-ui/src/app/state/app-state.guard.ts b/apps/red-ui/src/app/state/app-state.guard.ts index e52638e04..437bb8cb4 100644 --- a/apps/red-ui/src/app/state/app-state.guard.ts +++ b/apps/red-ui/src/app/state/app-state.guard.ts @@ -19,11 +19,11 @@ export class AppStateGuard implements CanActivate { async canActivate(route: ActivatedRouteSnapshot): Promise { if (this._userService.currentUser.isUserAdmin) { - await this._userService.loadAllIfEmpty(); + await this._userService.loadAll().toPromise(); } if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) { - await this._userService.loadAllIfEmpty(); + await this._userService.loadAll().toPromise(); await this._dossierTemplatesService.loadAllIfEmpty(); await this._appStateService.loadDictionaryDataIfNecessary(); }