Merge branch 'RED-10183' into 'master'
RED-10183: use the user preferred language + component refactoring. See merge request redactmanager/red-ui!610
This commit is contained in:
commit
9836c2aab5
@ -20,6 +20,7 @@
|
||||
<label [translate]="'top-bar.navigation-items.my-account.children.language.label'"></label>
|
||||
<mat-form-field>
|
||||
<mat-select formControlName="language">
|
||||
<mat-select-trigger>{{ languageSelectLabel() | translate }}</mat-select-trigger>
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{ translations[language] | translate }}
|
||||
</mat-option>
|
||||
@ -41,7 +42,7 @@
|
||||
|
||||
<div class="dialog-actions">
|
||||
<iqser-icon-button
|
||||
[disabled]="form.invalid || !(profileChanged || languageChanged || themeChanged)"
|
||||
[disabled]="disabled"
|
||||
[label]="'user-profile-screen.actions.save' | translate"
|
||||
[submit]="true"
|
||||
[type]="iconButtonTypes.primary"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed } from '@angular/core';
|
||||
import { FormGroup, ReactiveFormsModule, UntypedFormBuilder, Validators } from '@angular/forms';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import {
|
||||
BaseFormComponent,
|
||||
@ -19,22 +19,49 @@ import { firstValueFrom } from 'rxjs';
|
||||
import { UserProfileDialogService } from '../services/user-profile-dialog.service';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { MatFormField } from '@angular/material/form-field';
|
||||
import { MatOption, MatSelect } from '@angular/material/select';
|
||||
import { MatOption, MatSelect, MatSelectTrigger } from '@angular/material/select';
|
||||
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
||||
import { PdfViewer } from '../../../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { formControlToSignal } from '@utils/functions';
|
||||
import { AsControl } from '@common-ui/utils';
|
||||
|
||||
interface UserProfileForm {
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
language: string;
|
||||
darkTheme: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './user-profile-screen.component.html',
|
||||
styleUrls: ['./user-profile-screen.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [ReactiveFormsModule, NgIf, MatFormField, MatSelect, MatOption, NgForOf, TranslateModule, MatSlideToggle, IconButtonComponent],
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
NgIf,
|
||||
MatFormField,
|
||||
MatSelect,
|
||||
MatOption,
|
||||
NgForOf,
|
||||
TranslateModule,
|
||||
MatSlideToggle,
|
||||
IconButtonComponent,
|
||||
MatSelectTrigger,
|
||||
],
|
||||
})
|
||||
export class UserProfileScreenComponent extends BaseFormComponent implements OnInit {
|
||||
#profileModel: IProfile;
|
||||
export class UserProfileScreenComponent extends BaseFormComponent {
|
||||
readonly form: FormGroup<AsControl<UserProfileForm>> = this.#getForm();
|
||||
initialFormValue = this.form.getRawValue();
|
||||
readonly translations = languagesTranslations;
|
||||
readonly devMode = this._userPreferenceService.isIqserDevMode;
|
||||
|
||||
readonly profileKeys = ['email', 'firstName', 'lastName'];
|
||||
readonly languages = this._translateService.langs;
|
||||
readonly language = formControlToSignal<UserProfileForm['language']>(this.form.controls.language);
|
||||
readonly languageSelectLabel = computed(() => this.translations[this.language()]);
|
||||
|
||||
constructor(
|
||||
private readonly _userService: UserService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
@ -49,41 +76,26 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
private readonly _pdfViewer: PdfViewer,
|
||||
) {
|
||||
super();
|
||||
this._loadingService.start();
|
||||
if (!this._permissionsService.has(Roles.updateMyProfile)) {
|
||||
this.form.disable();
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
get languageChanged(): boolean {
|
||||
return this.#profileModel['language'] !== this.form.get('language').value;
|
||||
return this.initialFormValue['language'] !== this.form.controls.language.value;
|
||||
}
|
||||
|
||||
get themeChanged(): boolean {
|
||||
return this.#profileModel['darkTheme'] !== this.form.get('darkTheme').value;
|
||||
return this.initialFormValue['darkTheme'] !== this.form.controls.darkTheme.value;
|
||||
}
|
||||
|
||||
get emailChanged(): boolean {
|
||||
return this.#profileModel['email'] !== this.form.get('email').value;
|
||||
return this.initialFormValue['email'] !== this.form.controls.email.value;
|
||||
}
|
||||
|
||||
get profileChanged(): boolean {
|
||||
const keys = Object.keys(this.form.getRawValue());
|
||||
keys.splice(keys.indexOf('language'), 1);
|
||||
keys.splice(keys.indexOf('darkTheme'), 1);
|
||||
|
||||
for (const key of keys) {
|
||||
if (this.#profileModel[key] !== this.form.get(key).value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
get languages(): string[] {
|
||||
return this._translateService.langs;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._initializeForm();
|
||||
return this.profileKeys.some(key => this.initialFormValue[key] !== this.form.get(key).value);
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
@ -108,16 +120,17 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
}
|
||||
|
||||
if (this.languageChanged) {
|
||||
await this._languageService.change(this.form.get('language').value);
|
||||
await this._languageService.change(this.form.controls.language.value);
|
||||
await this._pdfViewer.instance?.UI.setLanguage(this._languageService.currentLanguage);
|
||||
}
|
||||
|
||||
if (this.themeChanged) {
|
||||
await this._userPreferenceService.saveTheme(this.form.get('darkTheme').value ? 'dark' : 'light');
|
||||
await this._userPreferenceService.saveTheme(this.form.controls.darkTheme.value ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
this._initializeForm();
|
||||
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
this._changeRef.markForCheck();
|
||||
this._loadingService.stop();
|
||||
this._toaster.success(_('user-profile-screen.update.success'));
|
||||
} catch (e) {
|
||||
this._loadingService.stop();
|
||||
@ -128,35 +141,13 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
await this._userService.createResetPasswordAction();
|
||||
}
|
||||
|
||||
private _getForm(): UntypedFormGroup {
|
||||
#getForm() {
|
||||
return this._formBuilder.group({
|
||||
email: ['', [Validators.required, Validators.email]],
|
||||
firstName: [''],
|
||||
lastName: [''],
|
||||
language: [''],
|
||||
darkTheme: [false],
|
||||
email: [this._userService.currentUser.email ?? '', [Validators.required, Validators.email]],
|
||||
firstName: [this._userService.currentUser.firstName ?? ''],
|
||||
lastName: [this._userService.currentUser.lastName ?? ''],
|
||||
language: [this._userPreferenceService.getLanguage()],
|
||||
darkTheme: [this._userPreferenceService.getTheme() === 'dark'],
|
||||
});
|
||||
}
|
||||
|
||||
private _initializeForm(): void {
|
||||
try {
|
||||
this.form = this._getForm();
|
||||
if (!this._permissionsService.has(Roles.updateMyProfile)) {
|
||||
this.form.disable();
|
||||
}
|
||||
this.#profileModel = {
|
||||
email: this._userService.currentUser.email ?? '',
|
||||
firstName: this._userService.currentUser.firstName ?? '',
|
||||
lastName: this._userService.currentUser.lastName ?? '',
|
||||
language: this._languageService.currentLanguage ?? '',
|
||||
darkTheme: this._userPreferenceService.getTheme() === 'dark',
|
||||
};
|
||||
this.form.patchValue(this.#profileModel, { emitEvent: false });
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
this._loadingService.stop();
|
||||
this._changeRef.markForCheck();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@ import { ITrackable } from '@iqser/common-ui';
|
||||
import type { List } from '@iqser/common-ui/lib/utils';
|
||||
import type { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
export function hexToRgb(hex: string) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
@ -143,3 +145,7 @@ export function urlFileId() {
|
||||
const fileId = splitUrl[splitUrl.length - 1];
|
||||
return fileId.split('?')[0];
|
||||
}
|
||||
|
||||
export function formControlToSignal<T>(control: FormControl<T>) {
|
||||
return toSignal(control.valueChanges, { initialValue: control.value });
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { AsyncGuard, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
|
||||
import { AsyncGuard, IqserPermissionsService, LanguageService, LoadingService } from '@iqser/common-ui';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { DossiersChangesService } from '@services/dossiers/dossier-changes.service';
|
||||
@ -38,6 +38,7 @@ export function mainGuard(): AsyncGuard {
|
||||
const tenantsService = inject(TenantsService);
|
||||
const loadingService = inject(LoadingService);
|
||||
const configService = inject(ConfigService);
|
||||
const languageService = inject(LanguageService);
|
||||
const baseHref = inject(APP_BASE_HREF);
|
||||
|
||||
const generalConfig$ = inject(GeneralSettingsService).getGeneralConfigurations();
|
||||
@ -51,6 +52,7 @@ export function mainGuard(): AsyncGuard {
|
||||
firstValueFrom(updatedDisplayName$),
|
||||
]);
|
||||
|
||||
await languageService.setInitialLanguage();
|
||||
const lastDossierTemplate = userPreferenceService.getLastDossierTemplate();
|
||||
|
||||
if (lastDossierTemplate && !isUsersAdminOnly) {
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 3c89b8f7e71eb9253aa40f40c1598eac2c400c71
|
||||
Subproject commit 32de7758599d887c4b574d70a11b4e0382f30f0c
|
||||
Loading…
x
Reference in New Issue
Block a user