From 43bfeb4e1ebb3a0950a0bfb7cdf9d9dccfd78960 Mon Sep 17 00:00:00 2001 From: Nicoleta Panaghiu Date: Tue, 30 Jul 2024 11:12:16 +0300 Subject: [PATCH] RED-9571: fixed initials-avatar not updating in some cases. --- .../initials-avatar.component.html | 14 +-- .../initials-avatar.component.ts | 110 ++++++------------ src/lib/users/services/iqser-user.service.ts | 12 +- 3 files changed, 55 insertions(+), 81 deletions(-) diff --git a/src/lib/users/components/initials-avatar/initials-avatar.component.html b/src/lib/users/components/initials-avatar/initials-avatar.component.html index 46eadd3..aee6b34 100644 --- a/src/lib/users/components/initials-avatar/initials-avatar.component.html +++ b/src/lib/users/components/initials-avatar/initials-avatar.component.html @@ -1,14 +1,14 @@ -@if (_user && _user | name: namePipeOptions; as userName) { +@if (_user() && _user() | name: namePipeOptions(); as userName) {
- {{ _user | name: { showInitials: true } }} + {{ _user() | name: { showInitials: true } }}
- @if (withName) { -
+ @if (withName()) { +
{{ userName }}
} diff --git a/src/lib/users/components/initials-avatar/initials-avatar.component.ts b/src/lib/users/components/initials-avatar/initials-avatar.component.ts index 01300b5..c7e6d67 100644 --- a/src/lib/users/components/initials-avatar/initials-avatar.component.ts +++ b/src/lib/users/components/initials-avatar/initials-avatar.component.ts @@ -1,4 +1,4 @@ -import { ChangeDetectionStrategy, Component, inject, Input, OnChanges, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { IqserUser } from '../../iqser-user.model'; import { IqserUserService } from '../../services/iqser-user.service'; @@ -7,6 +7,7 @@ import { IIqserUser } from '../../types/user.response'; import { NgIf } from '@angular/common'; import { NamePipe } from '../../name.pipe'; import { MatTooltip } from '@angular/material/tooltip'; +import { toSignal } from '@angular/core/rxjs-interop'; @Component({ selector: 'iqser-initials-avatar', @@ -16,80 +17,45 @@ import { MatTooltip } from '@angular/material/tooltip'; standalone: true, imports: [NgIf, NamePipe, MatTooltip], }) -export class InitialsAvatarComponent - implements OnInit, OnChanges -{ +export class InitialsAvatarComponent< + Interface extends IIqserUser = IIqserUser, + Class extends IqserUser & Interface = IqserUser & Interface, +> { + readonly #userService = inject>(IqserUserService); readonly #translateService = inject(TranslateService); - @Input() color = 'lightgray'; - @Input() size: 'small' | 'large' = 'small'; - @Input() withName = false; - @Input() showYou = false; - @Input() tooltipPosition: 'below' | 'above' = 'above'; - @Input() defaultValue: string = this.#translateService.instant('initials-avatar.unassigned'); - @Input() showTooltip = true; - colorClass?: string; - namePipeOptions?: NamePipeOptions; + readonly #isSystemUser = computed(() => this._user()?.id?.toLowerCase() === 'system'); + readonly #users = toSignal(this.#userService.all$); - constructor(private readonly _userService: IqserUserService) {} + readonly color = input('lightgray'); + readonly size = input<'small' | 'large'>('small'); + readonly withName = input(false); + readonly showYou = input(false); + readonly tooltipPosition = input<'below' | 'above'>('above'); + readonly defaultValue = input(this.#translateService.instant('initials-avatar.unassigned')); + readonly showTooltip = input(true); + readonly user = input.required(); + readonly showBorderCondition = input<(user: T) => boolean>(user => user.isSpecial); - _user?: Class; - - @Input() - set user(user: Class | string) { + readonly _user = computed(() => { + const user = this.user(); if (typeof user === 'string') { - this._user = this._userService.find(user); - } else { - this._user = user; + if (user?.toLowerCase() === 'system') return this.#userService.newSystemUser(); + if (!user) return undefined; + return this.#users()?.find(u => u.id === user) ?? this.#userService.newDeletedUser(); } - } - - get hasBorder(): boolean { - return !!this._user && !this.isCurrentUser && this.showBorderCondition(this._user); - } - - get disabled(): boolean { - return !!this._user && !this.#isSystemUser && !this._user.hasAnyRole; - } - - get isCurrentUser(): boolean { - return this._userService.currentUser?.id === this._user?.id; - } - - get #colorClass() { - if (this.isCurrentUser) { - return 'primary-white'; - } - - if (this.disabled) { - return 'inactive'; - } - - if (this.color.includes('-')) { - return this.color; - } - - return `${this.color}-dark`; - } - - get #isSystemUser() { - return this._user?.id?.toLowerCase() === 'system'; - } - - @Input() showBorderCondition: (user: T) => boolean = user => user.isSpecial; - - ngOnChanges(): void { - if (this.#isSystemUser) { - this.colorClass = 'primary-white primary'; - return; - } - - this.colorClass = this.#colorClass; - } - - ngOnInit(): void { - this.namePipeOptions = { - showYou: this.showYou, - defaultValue: this.defaultValue, - }; - } + return user; + }); + readonly isCurrentUser = computed(() => this.#userService.currentUser?.id === this._user()?.id); + readonly hasBorder = computed(() => !!this._user() && !this.isCurrentUser() && this.showBorderCondition()(this._user()!)); + readonly disabled = computed(() => !!this._user() && !this.#isSystemUser() && !this._user()?.hasAnyRole); + readonly colorClass = computed(() => { + if (this.isCurrentUser()) return 'primary-white'; + if (this.disabled()) return 'inactive'; + if (this.color().includes('-')) return this.color(); + if (this.#isSystemUser()) return 'primary-white primary'; + return `${this.color()}-dark`; + }); + readonly namePipeOptions = computed( + () => ({ showYou: this.showYou(), defaultValue: this.defaultValue() }) as NamePipeOptions, + ); } diff --git a/src/lib/users/services/iqser-user.service.ts b/src/lib/users/services/iqser-user.service.ts index f8a0d8f..254ab98 100644 --- a/src/lib/users/services/iqser-user.service.ts +++ b/src/lib/users/services/iqser-user.service.ts @@ -164,14 +164,22 @@ export abstract class IqserUserService< find(id: string): Class | undefined { if (id?.toLowerCase() === 'system') { - return new this._entityClass({ username: 'System' }, [], 'system'); + return this.newSystemUser(); } if (!id) { return undefined; } - return super.find(id) ?? new this._entityClass({ username: 'Deleted User' }, [], 'deleted'); + return super.find(id) ?? this.newDeletedUser(); + } + + newSystemUser() { + return new this._entityClass({ username: 'System' }, [], 'system'); + } + + newDeletedUser() { + return new this._entityClass({ username: 'Deleted User' }, [], 'deleted'); } }