RED-2519
This commit is contained in:
parent
be9988ca11
commit
c71a3e65b6
@ -76,7 +76,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell user-column">
|
<div class="cell user-column">
|
||||||
<redaction-initials-avatar [user]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar>
|
<redaction-initials-avatar
|
||||||
|
[defaultValue]="'unknown' | translate"
|
||||||
|
[user]="dossierTemplate.createdBy"
|
||||||
|
[withName]="true"
|
||||||
|
></redaction-initials-avatar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell small-label">
|
<div class="cell small-label">
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<button [class.overlay]="showDot" mat-button>
|
<button [class.overlay]="showDot" mat-button>
|
||||||
<redaction-initials-avatar [user]="userId" [withName]="true" size="small"></redaction-initials-avatar>
|
<redaction-initials-avatar [user]="userService.currentUser$ | async" [withName]="true" size="small"></redaction-initials-avatar>
|
||||||
<mat-icon svgIcon="iqser:arrow-down"></mat-icon>
|
<mat-icon svgIcon="iqser:arrow-down"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div *ngIf="showDot" class="dot"></div>
|
<div *ngIf="showDot" class="dot"></div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||||
|
import { UserService } from '@services/user.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-user-button',
|
selector: 'redaction-user-button',
|
||||||
@ -9,4 +10,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
|||||||
export class UserButtonComponent {
|
export class UserButtonComponent {
|
||||||
@Input() userId: string;
|
@Input() userId: string;
|
||||||
@Input() showDot = false;
|
@Input() showDot = false;
|
||||||
|
|
||||||
|
constructor(readonly userService: UserService) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
[matTooltipPosition]="tooltipPosition"
|
[matTooltipPosition]="tooltipPosition"
|
||||||
[matTooltip]="userName"
|
[matTooltip]="userName"
|
||||||
>
|
>
|
||||||
{{ _user | name: { showInitials: true, defaultValue: ('initials-avatar.unassigned' | translate) } }}
|
{{ _user | name: { showInitials: true } }}
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username">
|
<div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username">
|
||||||
{{ userName }}
|
{{ userName }}
|
||||||
|
|||||||
@ -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 { UserService } from '@services/user.service';
|
||||||
import { AutoUnsubscribe } from '@iqser/common-ui';
|
import { AutoUnsubscribe } from '@iqser/common-ui';
|
||||||
import { User } from '@models/user';
|
import { User } from '@models/user';
|
||||||
@ -11,18 +11,16 @@ import { NamePipeOptions } from '@shared/pipes/name.pipe';
|
|||||||
styleUrls: ['./initials-avatar.component.scss'],
|
styleUrls: ['./initials-avatar.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy {
|
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnInit, OnChanges, OnDestroy {
|
||||||
@Input() color = 'lightgray';
|
@Input() color = 'lightgray';
|
||||||
@Input() size: 'small' | 'large' = 'small';
|
@Input() size: 'small' | 'large' = 'small';
|
||||||
@Input() withName = false;
|
@Input() withName = false;
|
||||||
@Input() showYou = false;
|
@Input() showYou = false;
|
||||||
@Input() tooltipPosition: 'below' | 'above' = 'above';
|
@Input() tooltipPosition: 'below' | 'above' = 'above';
|
||||||
|
@Input() defaultValue = this._translateService.instant('initials-avatar.unassigned');
|
||||||
colorClass: string;
|
colorClass: string;
|
||||||
|
|
||||||
readonly namePipeOptions: NamePipeOptions = {
|
namePipeOptions: NamePipeOptions;
|
||||||
showYou: this.showYou,
|
|
||||||
defaultValue: this._translateService.instant('initials-avatar.unassigned'),
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {
|
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {
|
||||||
super();
|
super();
|
||||||
@ -44,7 +42,7 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
get disabled(): boolean {
|
get disabled(): boolean {
|
||||||
return this._user && !this._user.isActive;
|
return this._user && !this._isSystemUser && !this._user.isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isCurrentUser(): boolean {
|
get isCurrentUser(): boolean {
|
||||||
@ -65,13 +63,23 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange
|
|||||||
return `${this.color}-dark`;
|
return `${this.color}-dark`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get _isSystemUser() {
|
||||||
|
return this._user?.id?.toLowerCase() === 'system';
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
const isSystemUser = this._user?.id?.toLowerCase() === 'system';
|
if (this._isSystemUser) {
|
||||||
if (isSystemUser) {
|
|
||||||
this.colorClass = 'primary-white primary';
|
this.colorClass = 'primary-white primary';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.colorClass = this._colorClass;
|
this.colorClass = this._colorClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.namePipeOptions = {
|
||||||
|
showYou: this.showYou,
|
||||||
|
defaultValue: this.defaultValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,12 +36,13 @@ export class NamePipe implements PipeTransform {
|
|||||||
|
|
||||||
transform(value?: User | string, options = this._defaultOptions): string {
|
transform(value?: User | string, options = this._defaultOptions): string {
|
||||||
let name;
|
let name;
|
||||||
if (!value || !isSystemUser(value)) {
|
|
||||||
name = this._getName(value) || options?.defaultValue;
|
if (!value && options?.showInitials) {
|
||||||
} else {
|
return '?';
|
||||||
name = 'System';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = this._getName(value) || options?.defaultValue;
|
||||||
|
|
||||||
if (options?.showYou && this._isCurrentUser(value)) {
|
if (options?.showYou && this._isCurrentUser(value)) {
|
||||||
name = `${name} (${this._translateService.instant('initials-avatar.you')})`;
|
name = `${name} (${this._translateService.instant('initials-avatar.you')})`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import jwt_decode from 'jwt-decode';
|
|||||||
import { CreateUserRequest, IUser, ResetPasswordRequest, UpdateMyProfileRequest, UpdateProfileRequest } from '@redaction/red-ui-http';
|
import { CreateUserRequest, IUser, ResetPasswordRequest, UpdateMyProfileRequest, UpdateProfileRequest } from '@redaction/red-ui-http';
|
||||||
import { wipeCaches } from '@redaction/red-cache';
|
import { wipeCaches } from '@redaction/red-cache';
|
||||||
import { BASE_HREF } from '../tokens';
|
import { BASE_HREF } from '../tokens';
|
||||||
import { Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
import { User } from '@models/user';
|
import { User } from '@models/user';
|
||||||
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||||
import { tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
@ -21,18 +21,20 @@ export interface ProfileModel {
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class UserService extends EntitiesService<User, IUser> {
|
export class UserService extends EntitiesService<User, IUser> {
|
||||||
|
readonly currentUser$: Observable<User>;
|
||||||
|
private readonly _currentUser$ = new BehaviorSubject<User>(null);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly _injector: Injector,
|
protected readonly _injector: Injector,
|
||||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||||
private readonly _keycloakService: KeycloakService,
|
private readonly _keycloakService: KeycloakService,
|
||||||
) {
|
) {
|
||||||
super(_injector, User, 'user');
|
super(_injector, User, 'user');
|
||||||
|
this.currentUser$ = this._currentUser$.asObservable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _currentUser: User;
|
|
||||||
|
|
||||||
get currentUser(): User {
|
get currentUser(): User {
|
||||||
return this._currentUser;
|
return this._currentUser$.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get managerUsers(): User[] {
|
get managerUsers(): User[] {
|
||||||
@ -49,7 +51,7 @@ export class UserService extends EntitiesService<User, IUser> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadAll() {
|
loadAll() {
|
||||||
const all$ = this._currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true);
|
const all$ = this.currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true);
|
||||||
|
|
||||||
return all$.pipe(
|
return all$.pipe(
|
||||||
mapEach(user => new User(user, user.roles, user.userId)),
|
mapEach(user => new User(user, user.roles, user.userId)),
|
||||||
@ -59,16 +61,20 @@ export class UserService extends EntitiesService<User, IUser> {
|
|||||||
|
|
||||||
async loadCurrentUser() {
|
async loadCurrentUser() {
|
||||||
const token = await this._keycloakService.getToken();
|
const token = await this._keycloakService.getToken();
|
||||||
const decoded: { sub: string } = jwt_decode(token);
|
const decoded = jwt_decode(token);
|
||||||
const userId = decoded.sub;
|
const userId = (<{ sub: string }>decoded).sub;
|
||||||
this._currentUser = new User(await this._keycloakService.loadUserProfile(true), this._keycloakService.getUserRoles(true), userId);
|
|
||||||
|
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 {
|
getNameForId(userId: string): string | undefined {
|
||||||
return this.find(userId)?.name;
|
return this.find(userId)?.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean {
|
hasAnyRole(requiredRoles: string[], user = this.currentUser): boolean {
|
||||||
if (requiredRoles?.length > 0) {
|
if (requiredRoles?.length > 0) {
|
||||||
for (const role of requiredRoles) {
|
for (const role of requiredRoles) {
|
||||||
if (user.roles.indexOf(role) >= 0) {
|
if (user.roles.indexOf(role) >= 0) {
|
||||||
@ -111,4 +117,11 @@ export class UserService extends EntitiesService<User, IUser> {
|
|||||||
const queryParams = userIds.map<QueryParam>(userId => ({ key: 'userId', value: userId }));
|
const queryParams = userIds.map<QueryParam>(userId => ({ key: 'userId', value: userId }));
|
||||||
return super.delete(userIds, this._defaultModelPath, queryParams);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,11 +19,11 @@ export class AppStateGuard implements CanActivate {
|
|||||||
|
|
||||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||||
if (this._userService.currentUser.isUserAdmin) {
|
if (this._userService.currentUser.isUserAdmin) {
|
||||||
await this._userService.loadAllIfEmpty();
|
await this._userService.loadAll().toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
|
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
|
||||||
await this._userService.loadAllIfEmpty();
|
await this._userService.loadAll().toPromise();
|
||||||
await this._dossierTemplatesService.loadAllIfEmpty();
|
await this._dossierTemplatesService.loadAllIfEmpty();
|
||||||
await this._appStateService.loadDictionaryDataIfNecessary();
|
await this._appStateService.loadDictionaryDataIfNecessary();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user