update user service, name pipe, initials avatars

This commit is contained in:
Dan Percic 2021-10-06 14:19:10 +03:00
parent 3c286f5f67
commit 4357c7fc59
26 changed files with 179 additions and 148 deletions

View File

@ -4,7 +4,6 @@ import { ProfileModel, UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service';
import { LanguageService } from '@i18n/language.service';
import { TranslateService } from '@ngx-translate/core';
import { UserControllerService } from '@redaction/red-ui-http';
import { ConfigService } from '@services/config.service';
import { DomSanitizer } from '@angular/platform-browser';
import { languagesTranslations } from '../../translations/languages-translations';
@ -27,7 +26,6 @@ export class UserProfileScreenComponent implements OnInit {
private readonly _formBuilder: FormBuilder,
private readonly _userService: UserService,
private readonly _configService: ConfigService,
private readonly _userControllerService: UserControllerService,
private readonly _languageService: LanguageService,
private readonly _domSanitizer: DomSanitizer,
private readonly _translateService: TranslateService,
@ -82,14 +80,14 @@ export class UserProfileScreenComponent implements OnInit {
const value = this.formGroup.value as ProfileModel;
delete value.language;
await this._userControllerService
await this._userService
.updateMyProfile({
...value,
})
.toPromise();
await this._userService.loadCurrentUser();
await this._userService.loadAllUsers();
await this._userService.loadAll().toPromise();
}
this._initializeForm();

View File

@ -1,6 +1,5 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { UserControllerService } from '@redaction/red-ui-http';
import { UserService } from '@services/user.service';
import { LoadingService } from '@iqser/common-ui';
import { User } from '@models/user';
@ -19,14 +18,13 @@ export class ResetPasswordComponent {
constructor(
private readonly _formBuilder: FormBuilder,
private readonly _userControllerService: UserControllerService,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
) {}
async save() {
this._loadingService.start();
await this._userControllerService
await this._userService
.resetPassword(
{
password: this.passwordForm.get('temporaryPassword').value,

View File

@ -1,11 +1,11 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../../services/admin-dialog.service';
import { IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { rolesTranslations } from '../../../../../translations/roles-translations';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@models/user';
import { UserService } from '@services/user.service';
@Component({
selector: 'redaction-user-details',
@ -29,7 +29,7 @@ export class UserDetailsComponent implements OnInit {
private readonly _toaster: Toaster,
private readonly _dialogService: AdminDialogService,
private readonly _loadingService: LoadingService,
private readonly _userControllerService: UserControllerService,
private readonly _userService: UserService,
) {}
get changed(): boolean {
@ -102,8 +102,8 @@ export class UserDetailsComponent implements OnInit {
const userData = { ...this.userForm.getRawValue(), roles: this.activeRoles };
if (!this.user) {
await this._userControllerService
.createUser(userData)
await this._userService
.create(userData)
.toPromise()
.then(() => {
this.closeDialog.emit(true);
@ -117,7 +117,7 @@ export class UserDetailsComponent implements OnInit {
this._loadingService.stop();
});
} else {
await this._userControllerService.updateProfile(userData, this.user.id).toPromise();
await this._userService.updateProfile(userData, this.user.id).toPromise();
this.closeDialog.emit(true);
}
}

View File

@ -1,10 +1,10 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { UserControllerService } from '@redaction/red-ui-http';
import { LoadingService } from '@iqser/common-ui';
import { List, LoadingService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { User } from '@models/user';
import { DossiersService } from '../../../dossier/services/dossiers.service';
import { UserService } from '@services/user.service';
@Component({
selector: 'redaction-confirm-delete-users-dialog',
@ -20,11 +20,11 @@ export class ConfirmDeleteUsersDialogComponent {
dossiersCount: number;
constructor(
private readonly _dossiersService: DossiersService,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _userControllerService: UserControllerService,
private readonly _dossiersService: DossiersService,
@Inject(MAT_DIALOG_DATA) readonly users: List<User>,
readonly dialogRef: MatDialogRef<ConfirmDeleteUsersDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly users: User[],
) {
this.dossiersCount = this._dossiersService.all.filter(dw => {
for (const user of this.users) {
@ -43,7 +43,7 @@ export class ConfirmDeleteUsersDialogComponent {
async deleteUser() {
if (this.valid) {
this._loadingService.start();
await this._userControllerService.deleteUsers(this.users.map(u => u.id)).toPromise();
await this._userService.delete(this.users.map(u => u.id)).toPromise();
this.dialogRef.close(true);
} else {
this.showToast = true;

View File

@ -57,7 +57,7 @@
<mat-select-trigger>
<redaction-initials-avatar
*ngIf="filterForm.get('userId').value !== ALL_USERS"
[userId]="filterForm.get('userId').value"
[user]="filterForm.get('userId').value"
[withName]="true"
size="small"
></redaction-initials-avatar>
@ -66,7 +66,7 @@
<mat-option *ngFor="let userId of userIds" [value]="userId">
<redaction-initials-avatar
*ngIf="userId !== ALL_USERS"
[userId]="userId"
[user]="userId"
[withName]="true"
size="small"
></redaction-initials-avatar>
@ -108,7 +108,7 @@
</div>
<div class="user-column cell">
<redaction-initials-avatar [userId]="log.userId" [withName]="true" size="small"></redaction-initials-avatar>
<redaction-initials-avatar [user]="log.userId" [withName]="true" size="small"></redaction-initials-avatar>
</div>
<div [translate]="translations[log.category]" class="cell"></div>

View File

@ -76,7 +76,7 @@
</div>
<div class="cell user-column">
<redaction-initials-avatar [userId]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [user]="dossierTemplate.createdBy" [withName]="true"></redaction-initials-avatar>
</div>
<div class="cell small-label">

View File

@ -63,7 +63,7 @@
</div>
<div class="cell user-column">
<redaction-initials-avatar [userId]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [user]="entity.ownerId" [withName]="true"></redaction-initials-avatar>
</div>
<div class="cell">

View File

@ -68,7 +68,7 @@
<ng-template #tableItemTemplate let-user="entity">
<div>
<div class="cell">
<redaction-initials-avatar [showYou]="true" [userId]="user.id" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [showYou]="true" [user]="user" [withName]="true"></redaction-initials-avatar>
</div>
<div class="small-label cell">{{ user.email || '-' }}</div>

View File

@ -1,19 +1,18 @@
import { Component, forwardRef, Injector, OnInit, QueryList, ViewChildren } from '@angular/core';
import { Component, forwardRef, Injector, OnInit } from '@angular/core';
import { UserService } from '@services/user.service';
import { UserControllerService } from '@redaction/red-ui-http';
import { AdminDialogService } from '../../services/admin-dialog.service';
import { TranslateService } from '@ngx-translate/core';
import { DoughnutChartConfig } from '@shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
import { TranslateChartService } from '@services/translate-chart.service';
import {
CircleButtonTypes,
DefaultListingServices,
DefaultListingServicesTmp,
EntitiesService,
IconButtonTypes,
ListingComponent,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
import { InitialsAvatarComponent } from '@shared/components/initials-avatar/initials-avatar.component';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { rolesTranslations } from '../../../../translations/roles-translations';
@ -23,7 +22,14 @@ import { User } from '@models/user';
@Component({
templateUrl: './user-listing-screen.component.html',
styleUrls: ['./user-listing-screen.component.scss'],
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => UserListingScreenComponent) }],
providers: [
...DefaultListingServicesTmp,
{ provide: EntitiesService, useExisting: UserService },
{
provide: ListingComponent,
useExisting: forwardRef(() => UserListingScreenComponent),
},
],
})
export class UserListingScreenComponent extends ListingComponent<User> implements OnInit {
readonly translations = rolesTranslations;
@ -40,8 +46,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
];
collapsedDetails = false;
chartData: DoughnutChartConfig[] = [];
@ViewChildren(InitialsAvatarComponent)
private readonly _avatars: QueryList<InitialsAvatarComponent>;
constructor(
readonly userService: UserService,
@ -49,7 +53,6 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
private readonly _loadingService: LoadingService,
private readonly _dialogService: AdminDialogService,
private readonly _translateService: TranslateService,
private readonly _userControllerService: UserControllerService,
private readonly _translateChartService: TranslateChartService,
) {
super(_injector);
@ -87,9 +90,8 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
async toggleActive(user: User) {
this._loadingService.start();
const requestBody = { ...user, roles: user.isActive ? [] : ['RED_USER'] };
await this._userControllerService.updateProfile(requestBody, user.id).toPromise();
await this.userService.updateProfile(requestBody, user.id).toPromise();
await this._loadData();
this._avatars.find(item => item.userId === user.id).detectChanges();
}
bulkDelete() {
@ -97,7 +99,7 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
}
private async _loadData() {
this.entitiesService.setEntities(await this.userService.loadAllUsers());
await this.userService.loadAll().toPromise();
this._computeStats();
this._loadingService.stop();
}

View File

@ -36,8 +36,8 @@
<pre *ngIf="selectedReviewersList.length === 0" [innerHTML]="'assign-dossier-owner.dialog.no-reviewers' | translate" class="info"></pre>
<iqser-input-with-action
[(value)]="searchQuery"
(valueChange)="setMembersSelectOptions()"
[(value)]="searchQuery"
[placeholder]="'assign-dossier-owner.dialog.search' | translate"
[width]="560"
class="search-container"
@ -49,7 +49,7 @@
*ngFor="let userId of membersSelectOptions"
[class.selected]="isMemberSelected(userId)"
>
<redaction-initials-avatar [userId]="userId" [withName]="true" size="large"></redaction-initials-avatar>
<redaction-initials-avatar [user]="userId" [withName]="true" size="large"></redaction-initials-avatar>
<div class="actions">
<div (click)="toggleApprover(userId, $event)" *ngIf="!isOwner(userId)" class="make-approver">
<iqser-round-checkbox [active]="isApprover(userId)" class="mr-8"></iqser-round-checkbox>

View File

@ -15,7 +15,7 @@
<div class="all-caps-label" translate="dossier-details.owner"></div>
<div class="mt-12 d-flex">
<ng-container *ngIf="!editingOwner; else editOwner">
<redaction-initials-avatar [userId]="owner?.id" [withName]="true" color="gray" size="large"></redaction-initials-avatar>
<redaction-initials-avatar [user]="owner" [withName]="true" color="gray" size="large"></redaction-initials-avatar>
<iqser-circle-button
(action)="editingOwner = true"

View File

@ -46,7 +46,7 @@ export class DossierDetailsComponent implements OnInit {
}
ngOnInit(): void {
this.owner = this._userService.getRedUserById(this.dossiersService.activeDossier.ownerId);
this.owner = this._userService.find(this.dossiersService.activeDossier.ownerId);
this.calculateChartConfig();
this.appStateService.fileChanged$.subscribe(() => {
this.calculateChartConfig();
@ -75,7 +75,7 @@ export class DossierDetailsComponent implements OnInit {
}
async assignOwner(user: User | string) {
this.owner = typeof user === 'string' ? this._userService.getRedUserById(user) : user;
this.owner = typeof user === 'string' ? this._userService.find(user) : user;
const activeDossier = this.dossiersService.activeDossier;
const dossierRequest: DossierRequest = { ...activeDossier, dossierId: activeDossier.dossierId, ownerId: this.owner.id };
await this.dossiersService.createOrUpdate(dossierRequest).toPromise();

View File

@ -34,7 +34,7 @@
</div>
<div *ngIf="!file.isError" class="user-column cell">
<redaction-initials-avatar [userId]="file.currentReviewer" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [user]="file.currentReviewer" [withName]="true"></redaction-initials-avatar>
</div>
<div *ngIf="!file.isError" class="cell">

View File

@ -131,7 +131,7 @@
<ng-container *ngTemplateOutlet="statsTemplate; context: { entity: file }"></ng-container>
</div>
<div class="user">
<redaction-initials-avatar [userId]="file.currentReviewer"></redaction-initials-avatar>
<redaction-initials-avatar [user]="file.currentReviewer"></redaction-initials-avatar>
</div>
</div>
<redaction-file-actions

View File

@ -5,7 +5,7 @@
<redaction-needs-work-badge [needsWorkInput]="dossier"></redaction-needs-work-badge>
</div>
<div class="cell user-column">
<redaction-initials-avatar [userId]="dossier.ownerId" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [user]="dossier.ownerId" [withName]="true"></redaction-initials-avatar>
</div>
<div class="cell status-container">
<redaction-dossiers-listing-actions (actionPerformed)="calculateData.emit()" [dossier]="dossier"></redaction-dossiers-listing-actions>

View File

@ -42,7 +42,7 @@
<redaction-initials-avatar
*ngIf="!editingReviewer"
[userId]="currentReviewer"
[user]="currentReviewer"
[withName]="!!currentReviewer"
tooltipPosition="below"
></redaction-initials-avatar>
@ -83,7 +83,7 @@
<ng-container *ngIf="permissionsService.isApprover() && !!lastReviewer">
<div class="vertical-line"></div>
<div class="all-caps-label mr-16 ml-8" translate="file-preview.last-reviewer"></div>
<redaction-initials-avatar [userId]="lastReviewer" [withName]="true"></redaction-initials-avatar>
<redaction-initials-avatar [user]="lastReviewer" [withName]="true"></redaction-initials-avatar>
</ng-container>
<div class="vertical-line"></div>

View File

@ -27,5 +27,5 @@
</div>
<ng-template #avatar let-userId="userId">
<redaction-initials-avatar [userId]="userId" [withName]="true" color="gray" size="small"></redaction-initials-avatar>
<redaction-initials-avatar [user]="userId" [withName]="true" color="gray" size="small"></redaction-initials-avatar>
</ng-template>

View File

@ -1,5 +1,5 @@
<button [class.overlay]="showDot" mat-button>
<redaction-initials-avatar [userId]="userId" [withName]="true" size="small"></redaction-initials-avatar>
<redaction-initials-avatar [user]="userId" [withName]="true" size="small"></redaction-initials-avatar>
<mat-icon svgIcon="iqser:arrow-down"></mat-icon>
</button>
<div *ngIf="showDot" class="dot"></div>

View File

@ -1,12 +1,12 @@
<div class="wrapper">
<div *ngIf="_user && _user | name: namePipeOptions as userName" class="wrapper">
<div
[className]="colorClass + ' oval ' + size + (hasBorder ? ' border' : '')"
[matTooltipPosition]="tooltipPosition"
[matTooltip]="displayName || ('initials-avatar.unassigned' | translate)"
[matTooltip]="userName"
>
{{ initials }}
{{ _user | name: { showInitials: true, defaultValue: ('initials-avatar.unassigned' | translate) } }}
</div>
<div *ngIf="withName" [class.disabled]="disabled" class="clamp-2 username">
{{ displayName || ('initials-avatar.unassigned' | translate) }}
{{ userName }}
</div>
</div>

View File

@ -1,8 +1,9 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnChanges, OnDestroy } from '@angular/core';
import { UserService } from '@services/user.service';
import { TranslateService } from '@ngx-translate/core';
import { AutoUnsubscribe } from '@iqser/common-ui';
import { User } from '@models/user';
import { TranslateService } from '@ngx-translate/core';
import { NamePipeOptions } from '@shared/pipes/name.pipe';
@Component({
selector: 'redaction-initials-avatar',
@ -11,39 +12,47 @@ import { User } from '@models/user';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChanges, OnDestroy {
@Input() userId: string;
@Input() color = 'lightgray';
@Input() size: 'small' | 'large' = 'small';
@Input() withName = false;
@Input() showYou = false;
@Input() tooltipPosition: 'below' | 'above' = 'above';
displayName: string;
initials: string;
colorClass: string;
user: User;
constructor(
private readonly _userService: UserService,
private readonly _translateService: TranslateService,
private readonly _changeDetectorRef: ChangeDetectorRef,
) {
readonly namePipeOptions: NamePipeOptions = {
showYou: this.showYou,
defaultValue: this._translateService.instant('initials-avatar.unassigned'),
};
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {
super();
this.addSubscription = _userService.usersReloaded$.subscribe(() => {
this.detectChanges();
});
}
_user: User;
@Input()
set user(user: User | string) {
if (typeof user === 'string') {
this._user = this._userService.find(user);
} else {
this._user = user;
}
}
get hasBorder(): boolean {
return !!this.user && !this._isCurrentUser && this.user.isManager;
return !!this._user && !this.isCurrentUser && this._user.isManager;
}
get disabled(): boolean {
return this.user && !this.user.isActive;
return this._user && !this._user.isActive;
}
get isCurrentUser(): boolean {
return this._userService.currentUser.id === this._user?.id;
}
private get _colorClass() {
if (this._isCurrentUser) {
if (this.isCurrentUser) {
return 'primary-white';
}
if (this.disabled) {
@ -56,44 +65,13 @@ export class InitialsAvatarComponent extends AutoUnsubscribe implements OnChange
return `${this.color}-dark`;
}
private get _isCurrentUser(): boolean {
return this._userService.currentUser.id === this.user?.id;
}
ngOnChanges(): void {
const isSystemUser = this.userId?.toLowerCase() === 'system';
const isSystemUser = this._user?.id?.toLowerCase() === 'system';
if (isSystemUser) {
this.displayName = 'System';
this.initials = 'SY';
this.colorClass = 'primary-white primary';
return;
}
this.user = this._userService.getUserById(this.userId);
this.displayName = this._userService.getNameForId(this.userId);
this.initials = this._getInitials();
this.colorClass = this._colorClass;
if (this.showYou && this._isCurrentUser) {
this.displayName += ` (${this._translateService.instant('initials-avatar.you')})`;
}
}
detectChanges(): void {
this.ngOnChanges();
this._changeDetectorRef.detectChanges();
}
private _getInitials(): string {
if (!this.displayName) {
return '?';
}
return this.displayName
.split(' ')
.filter((value, idx) => idx < 2 && value !== ' ')
.map(str => str[0])
.join('');
}
}

View File

@ -6,7 +6,7 @@
[class.large-spacing]="largeSpacing"
class="member"
>
<redaction-initials-avatar [userId]="userId" color="gray" size="large"></redaction-initials-avatar>
<redaction-initials-avatar [user]="userId" color="gray" size="large"></redaction-initials-avatar>
<div *ngIf="canRemoveMember(userId)" class="remove">
<mat-icon svgIcon="iqser:close"></mat-icon>
</div>

View File

@ -3,16 +3,61 @@ import { UserService } from '@services/user.service';
import { TranslateService } from '@ngx-translate/core';
import { User } from '@models/user';
function getInitials(name: string) {
if (name.toLowerCase() === 'system') {
return 'SY';
}
const splittedName = name.split(' ').filter(value => value !== ' ' && value !== '');
return splittedName
.filter((value, index) => index < 2)
.map(str => str[0])
.join('');
}
function isSystemUser(user: User | string) {
const userId = typeof user === 'string' ? user : user.id;
return userId.toLowerCase() === 'system';
}
export interface NamePipeOptions {
showYou?: boolean;
showInitials?: boolean;
defaultValue?: string;
}
@Pipe({
name: 'name',
})
export class NamePipe implements PipeTransform {
private readonly _defaultOptions: NamePipeOptions = { defaultValue: this._translateService.instant('unknown') };
constructor(private readonly _userService: UserService, private readonly _translateService: TranslateService) {}
transform(value: User | string): string {
if (typeof value === 'string') {
return this._userService.getNameForId(value) || this._translateService.instant('unknown');
transform(value?: User | string, options = this._defaultOptions): string {
let name;
if (!value || !isSystemUser(value)) {
name = this._getName(value) || options?.defaultValue;
} else {
name = 'System';
}
return value.name;
if (options?.showYou && this._isCurrentUser(value)) {
name = `${name} (${this._translateService.instant('initials-avatar.you')})`;
}
return options?.showInitials ? getInitials(name) : name;
}
private _isCurrentUser(user: User | string): boolean {
const userId = typeof user === 'string' ? user : user.id;
return this._userService.currentUser.id === userId;
}
private _getName(user: User | string): string | undefined {
if (!user) {
return undefined;
}
return typeof user === 'string' ? this._userService.getNameForId(user) : user.name;
}
}

View File

@ -1,11 +1,13 @@
import { Inject, Injectable } from '@angular/core';
import { Inject, Injectable, Injector } from '@angular/core';
import { KeycloakService } from 'keycloak-angular';
import jwt_decode from 'jwt-decode';
import { IUser, UserControllerService } from '@redaction/red-ui-http';
import { CreateUserRequest, IUser, ResetPasswordRequest, UpdateMyProfileRequest, UpdateProfileRequest } from '@redaction/red-ui-http';
import { wipeCaches } from '@redaction/red-cache';
import { BASE_HREF } from '../tokens';
import { Subject } from 'rxjs';
import { Observable } from 'rxjs';
import { User } from '@models/user';
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
import { tap } from 'rxjs/operators';
export interface ProfileModel {
username?: string;
@ -18,16 +20,14 @@ export interface ProfileModel {
@Injectable({
providedIn: 'root',
})
export class UserService {
usersReloaded$ = new Subject();
private _allUsers: User[];
private _allRedUsers: User[];
export class UserService extends EntitiesService<User, IUser> {
constructor(
protected readonly _injector: Injector,
@Inject(BASE_HREF) private readonly _baseHref: string,
private readonly _keycloakService: KeycloakService,
private readonly _userControllerService: UserControllerService,
) {}
) {
super(_injector, User, 'user');
}
private _currentUser: User;
@ -36,11 +36,11 @@ export class UserService {
}
get managerUsers(): User[] {
return this._allRedUsers.filter(user => user.isManager);
return this.all.filter(user => user.isManager);
}
get eligibleUsers(): User[] {
return this._allRedUsers.filter(user => user.isUser || user.isManager);
return this.all.filter(user => user.isUser || user.isManager);
}
logout() {
@ -48,23 +48,13 @@ export class UserService {
this._keycloakService.logout(window.location.origin + this._baseHref).then();
}
async loadUsersIfNecessary() {
if (!this._allRedUsers) {
await this.loadAllUsers();
}
}
loadAll() {
const all$ = this._currentUser.isUserAdmin ? this.getUsers() : this.getUsers(true);
async loadAllUsers() {
let allUsers: IUser[];
if (this._currentUser.isUserAdmin) {
allUsers = await this._userControllerService.getAllUsers().toPromise();
} else {
allUsers = await this._userControllerService.getUsers().toPromise();
}
this._allUsers = allUsers.map(user => new User(user, user.roles, user.userId));
this._allRedUsers = this._allUsers.filter(user => user.hasAnyREDRoles);
this.usersReloaded$.next();
return this._allUsers;
return all$.pipe(
mapEach(user => new User(user, user.roles, user.userId)),
tap(users => this.setEntities(users)),
);
}
async loadCurrentUser() {
@ -74,16 +64,8 @@ export class UserService {
this._currentUser = new User(await this._keycloakService.loadUserProfile(true), this._keycloakService.getUserRoles(true), userId);
}
getRedUserById(id: string) {
return this._allRedUsers.find(u => u.id === id);
}
getUserById(id: string) {
return this._allUsers ? this._allUsers.find(u => u.id === id) : this.getRedUserById(id);
}
getNameForId(userId: string): string | undefined {
return this.getUserById(userId)?.name;
return this.find(userId)?.name;
}
hasAnyRole(requiredRoles: string[], user = this._currentUser): boolean {
@ -99,4 +81,34 @@ export class UserService {
return true;
}
getUsers(onlyRed = false, refreshCache = false): Observable<IUser[]> {
const url = onlyRed ? `${this._defaultModelPath}/red` : this._defaultModelPath;
return super.getAll(url, [{ key: 'refreshCache', value: refreshCache }]);
}
@Validate()
updateProfile(@RequiredParam() body: UpdateProfileRequest, @RequiredParam() userId: string) {
return this._post<unknown>(body, `${this._defaultModelPath}/profile/${userId}`);
}
@Validate()
updateMyProfile(@RequiredParam() body: UpdateMyProfileRequest) {
return this._post<unknown>(body, `${this._defaultModelPath}/my-profile`);
}
@Validate()
resetPassword(@RequiredParam() body: ResetPasswordRequest, @RequiredParam() userId: string) {
return this._post<unknown>(body, `${this._defaultModelPath}/${userId}/reset-password`);
}
@Validate()
create(@RequiredParam() body: CreateUserRequest) {
return this._post(body);
}
delete(userIds: List) {
const queryParams = userIds.map<QueryParam>(userId => ({ key: 'userId', value: userId }));
return super.delete(userIds, this._defaultModelPath, queryParams);
}
}

View File

@ -19,11 +19,11 @@ export class AppStateGuard implements CanActivate {
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
if (this._userService.currentUser.isUserAdmin) {
await this._userService.loadUsersIfNecessary();
await this._userService.loadAllIfEmpty();
}
if (this._userService.currentUser.isUser || this._userService.currentUser.isAdmin) {
await this._userService.loadUsersIfNecessary();
await this._userService.loadAllIfEmpty();
await this._dossierTemplatesService.loadAllIfEmpty();
await this._appStateService.loadDictionaryDataIfNecessary();
}

@ -1 +1 @@
Subproject commit 56ef15eecb738262b6bae51c15e0f4726d8af7e4
Subproject commit eca1fd1b9cf14febef7583e69501b4ab85342dba

View File

@ -19,7 +19,6 @@ import { ReportTemplateControllerService } from './api/reportTemplateController.
import { RulesControllerService } from './api/rulesController.service';
import { SmtpConfigurationControllerService } from './api/smtpConfigurationController.service';
import { UploadControllerService } from './api/uploadController.service';
import { UserControllerService } from './api/userController.service';
import { VersionsControllerService } from './api/versionsController.service';
import { ViewedPagesControllerService } from './api/viewedPagesController.service';
import { WatermarkControllerService } from './api/watermarkController.service';
@ -49,7 +48,6 @@ import { StatusReportControllerService } from './api/statusReportController.serv
RulesControllerService,
SmtpConfigurationControllerService,
UploadControllerService,
UserControllerService,
VersionsControllerService,
ViewedPagesControllerService,
WatermarkControllerService,