RED-4718: move user preference service to common-ui
This commit is contained in:
parent
68b8480875
commit
8166ff6933
@ -18,8 +18,8 @@ import { DownloadsListScreenComponent } from '@components/downloads-list-screen/
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { FileUploadDownloadModule } from '@upload-download/file-upload-download.module';
|
||||
import { DatePipe as BaseDatePipe, PlatformLocation } from '@angular/common';
|
||||
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE, BASE_HREF, BASE_HREF_FN } from './tokens';
|
||||
import { DatePipe as BaseDatePipe } from '@angular/common';
|
||||
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens';
|
||||
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
|
||||
import { GlobalErrorHandler } from '@utils/global-error-handler.service';
|
||||
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
|
||||
@ -31,6 +31,7 @@ import { PruningTranslationLoader } from '@utils/pruning-translation-loader';
|
||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||
import * as links from '../assets/help-mode/links.json';
|
||||
import {
|
||||
BASE_HREF,
|
||||
CachingModule,
|
||||
HELP_DOCS,
|
||||
IqserHelpModeModule,
|
||||
@ -62,15 +63,6 @@ export function httpLoaderFactory(httpClient: HttpClient, configService: ConfigS
|
||||
return new PruningTranslationLoader(httpClient, '/assets/i18n/', `.json?version=${configService.values.FRONTEND_APP_VERSION}`);
|
||||
}
|
||||
|
||||
function cleanupBaseUrl(baseUrl: string) {
|
||||
if (!baseUrl) {
|
||||
return '';
|
||||
} else if (baseUrl[baseUrl.length - 1] === '/') {
|
||||
return baseUrl.substring(0, baseUrl.length - 1);
|
||||
}
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
const screens = [BaseScreenComponent, DownloadsListScreenComponent];
|
||||
|
||||
const components = [AppComponent, AuthErrorComponent, NotificationsComponent, SpotlightSearchComponent, BreadcrumbsComponent, ...screens];
|
||||
@ -156,16 +148,6 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp
|
||||
provide: ErrorHandler,
|
||||
useClass: GlobalErrorHandler,
|
||||
},
|
||||
{
|
||||
provide: BASE_HREF,
|
||||
useFactory: (s: PlatformLocation) => cleanupBaseUrl(s.getBaseHrefFromDOM()),
|
||||
deps: [PlatformLocation],
|
||||
},
|
||||
{
|
||||
provide: BASE_HREF_FN,
|
||||
useFactory: (baseHref: string) => (path: string) => baseHref + path,
|
||||
deps: [BASE_HREF],
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
multi: true,
|
||||
|
||||
@ -3,9 +3,8 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { DOSSIER_TEMPLATE_ID, IWatermark, Watermark, WATERMARK_ID, WatermarkOrientation, WatermarkOrientations } from '@red/domain';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../../../tokens';
|
||||
import { BASE_HREF_FN, BaseHrefFn, Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { DOSSIER_TEMPLATE_ID, IWatermark, WATERMARK_ID, WatermarkOrientation, WatermarkOrientations } from '@red/domain';
|
||||
import { stampPDFPage } from '@utils/page-stamper';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Router } from '@angular/router';
|
||||
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { BASE_HREF } from '../../tokens';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -14,7 +13,6 @@ export class AuthGuard extends KeycloakAuthGuard {
|
||||
private readonly _userService: UserService,
|
||||
protected readonly _keycloak: KeycloakService,
|
||||
private readonly _configService: ConfigService,
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
) {
|
||||
super(_router, _keycloak);
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { HttpClientModule } from '@angular/common/http';
|
||||
|
||||
import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloak-angular';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { BASE_HREF } from '../../tokens';
|
||||
import { BASE_HREF } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
function getKeycloakOptions(configService: ConfigService, baseUrl: string) {
|
||||
|
||||
@ -5,7 +5,7 @@ import { PermissionsService } from '../../../services/permissions.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import { BASE_HREF_FN } from '../../../tokens';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { IHeaderElement } from '@red/domain';
|
||||
|
||||
|
||||
@ -9,8 +9,7 @@ import {
|
||||
} from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
|
||||
import { shareDistinctLast } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN, BaseHrefFn, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { toPosition } from '../utils/pdf-calculation.utils';
|
||||
import { MultiSelectService } from './multi-select.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { Inject, Injectable, Injector } from '@angular/core';
|
||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
|
||||
import { BASE_HREF_FN, BaseHrefFn, ErrorService, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { File, IHeaderElement } from '@red/domain';
|
||||
import { ErrorService, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { BehaviorSubject, combineLatest, fromEvent, Observable, switchMap } from 'rxjs';
|
||||
@ -169,11 +168,11 @@ export class PdfViewer {
|
||||
this.#compareMode$.next(false);
|
||||
}
|
||||
|
||||
async loadDocument(blob: Blob, file: File, actionOnError: () => void = () => {}) {
|
||||
async loadDocument(blob: Blob, file: File, actionOnError?: () => void) {
|
||||
const onError = () => {
|
||||
this._injector.get(ErrorService).set(DOCUMENT_LOADING_ERROR);
|
||||
this._logger.error('[PDF] Error while loading document');
|
||||
actionOnError();
|
||||
actionOnError?.();
|
||||
};
|
||||
|
||||
const document = await this.PDFNet.PDFDoc.createFromBuffer(await blob.arrayBuffer());
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { UserPreferenceService } from '../../../services/user-preference.service';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { HeaderElements } from '../../file-preview/utils/constants';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '@iqser/common-ui';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { REDDocumentViewer } from './document-viewer.service';
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { Inject, Injectable, Injector } from '@angular/core';
|
||||
import { IHeaderElement, RotationTypes } from '@red/domain';
|
||||
import { HeaderElements, HeaderElementType } from '../../file-preview/utils/constants';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../tokens';
|
||||
import { BASE_HREF_FN, BaseHrefFn } from '@iqser/common-ui';
|
||||
import { TooltipsService } from './tooltips.service';
|
||||
import { PageRotationService } from './page-rotation.service';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
|
||||
@ -37,6 +37,7 @@ import { SharedDialogService } from './services/dialog.service';
|
||||
import { AddEditEntityComponent } from './components/add-edit-entity/add-edit-entity.component';
|
||||
import { ColorPickerModule } from 'ngx-color-picker';
|
||||
import { WatermarkSelectorComponent } from './components/dossier-watermark-selector/watermark-selector.component';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
|
||||
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
||||
|
||||
@ -68,12 +69,19 @@ const utils = [DatePipe, NamePipe, NavigateLastDossiersScreenDirective, LongPres
|
||||
|
||||
const services = [SharedDialogService];
|
||||
|
||||
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule, ColorPickerModule];
|
||||
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, ColorPickerModule];
|
||||
|
||||
@NgModule({
|
||||
declarations: [...components, ...utils, EditorComponent],
|
||||
imports: [CommonModule, ...modules, MonacoEditorModule, TranslateModule, RouterModule],
|
||||
exports: [...modules, ...components, ...utils],
|
||||
imports: [
|
||||
CommonModule,
|
||||
CommonUiModule.forRoot({ existingUserPreferenceService: UserPreferenceService }),
|
||||
...modules,
|
||||
MonacoEditorModule,
|
||||
TranslateModule,
|
||||
RouterModule,
|
||||
],
|
||||
exports: [...modules, CommonUiModule, ...components, ...utils],
|
||||
providers: [
|
||||
...services,
|
||||
{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { BASE_HREF, EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { EMPTY, iif, Observable, of, timer } from 'rxjs';
|
||||
import { Dossier, INotification, Notification, NotificationTypes } from '@red/domain';
|
||||
@ -9,7 +9,6 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from './user.service';
|
||||
import dayjs from 'dayjs';
|
||||
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { DossiersCacheService } from './dossiers/dossiers-cache.service';
|
||||
|
||||
const INCLUDE_SEEN = false;
|
||||
|
||||
@ -1,32 +1,18 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { GenericService, List, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
|
||||
type UserAttributes = Record<string, List>;
|
||||
import { BaseUserPreferenceService } from '@iqser/common-ui';
|
||||
|
||||
const KEYS = {
|
||||
language: 'Language',
|
||||
dossierRecent: 'Dossier-Recent',
|
||||
filePreviewTooltips: 'File-Preview-Tooltips',
|
||||
lastDossierTemplate: 'Last-Dossier-Template',
|
||||
theme: 'Theme',
|
||||
} as const;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class UserPreferenceService extends GenericService<UserAttributes> {
|
||||
export class UserPreferenceService extends BaseUserPreferenceService {
|
||||
protected readonly _defaultModelPath = 'attributes';
|
||||
#userAttributes: UserAttributes = {};
|
||||
|
||||
get userAttributes(): UserAttributes {
|
||||
return this.#userAttributes;
|
||||
}
|
||||
|
||||
get areDevFeaturesEnabled(): boolean {
|
||||
const value = sessionStorage.getItem('redaction.enable-dev-features');
|
||||
return value ? value === 'true' : false;
|
||||
}
|
||||
protected readonly _devFeaturesEnabledKey = 'redaction.enable-dev-features';
|
||||
|
||||
getLastOpenedFileForDossier(dossierId: string): string {
|
||||
return this._getAttribute(`${KEYS.dossierRecent}-${dossierId}`);
|
||||
@ -44,23 +30,6 @@ export class UserPreferenceService extends GenericService<UserAttributes> {
|
||||
await this._save(KEYS.lastDossierTemplate, dossierTemplateId);
|
||||
}
|
||||
|
||||
getTheme(): string {
|
||||
return this._getAttribute(KEYS.theme, 'light');
|
||||
}
|
||||
|
||||
async saveTheme(theme: 'light' | 'dark'): Promise<void> {
|
||||
await this._save(KEYS.theme, theme);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
getLanguage(): string {
|
||||
return this._getAttribute(KEYS.language);
|
||||
}
|
||||
|
||||
async saveLanguage(language: string): Promise<void> {
|
||||
await this._save(KEYS.language, language);
|
||||
}
|
||||
|
||||
getFilePreviewTooltipsPreference(): boolean {
|
||||
return this._getAttribute(KEYS.filePreviewTooltips, 'false') === 'true';
|
||||
}
|
||||
@ -69,31 +38,4 @@ export class UserPreferenceService extends GenericService<UserAttributes> {
|
||||
const nextValue = (!this.getFilePreviewTooltipsPreference()).toString();
|
||||
await this._save(KEYS.filePreviewTooltips, nextValue);
|
||||
}
|
||||
|
||||
toggleDevFeatures(): void {
|
||||
sessionStorage.setItem('redaction.enable-dev-features', String(!this.areDevFeaturesEnabled));
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
async reload(): Promise<void> {
|
||||
const attributes = await firstValueFrom(this.getAll<UserAttributes>());
|
||||
this.#userAttributes = attributes ?? {};
|
||||
}
|
||||
|
||||
@Validate()
|
||||
savePreferences(@RequiredParam() body: List, @RequiredParam() key: string) {
|
||||
return this._put(body, `${this._defaultModelPath}/${key}`);
|
||||
}
|
||||
|
||||
private async _save(key: string, value: string): Promise<void> {
|
||||
this.userAttributes[key] = [value];
|
||||
await firstValueFrom(this.savePreferences([value], key));
|
||||
}
|
||||
|
||||
private _getAttribute(key: string, defaultValue = ''): string {
|
||||
if (this.userAttributes[key]?.length > 0) {
|
||||
return this.userAttributes[key][0];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,8 @@ import { inject, Inject, Injectable } from '@angular/core';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import jwt_decode from 'jwt-decode';
|
||||
import { ICreateUserRequest, IMyProfileUpdateRequest, IProfileUpdateRequest, IResetPasswordRequest, IUser, User } from '@red/domain';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { BASE_HREF, CacheApiService, EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs';
|
||||
import { CacheApiService, EntitiesService, List, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
export const BASE_HREF = new InjectionToken<string>('BASE_HREF');
|
||||
export type BaseHrefFn = (path: string) => string;
|
||||
export const BASE_HREF_FN = new InjectionToken<BaseHrefFn>('Convert path function');
|
||||
export const DOSSIER_ID = new InjectionToken<string>('DOSSIER_ID');
|
||||
|
||||
export const ACTIVE_DOSSIERS_SERVICE = new InjectionToken<string>('Active dossiers service');
|
||||
|
||||
@ -2,7 +2,7 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/c
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { BASE_HREF } from '../tokens';
|
||||
import { BASE_HREF } from '@iqser/common-ui';
|
||||
|
||||
@Injectable()
|
||||
export class ApiPathInterceptor implements HttpInterceptor {
|
||||
@ -10,15 +10,10 @@ export class ApiPathInterceptor implements HttpInterceptor {
|
||||
|
||||
intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||
if (!req.url.startsWith('/assets')) {
|
||||
const updatedRequest = req.clone({
|
||||
url: `${this._configService.values.API_URL}${req.url}`,
|
||||
});
|
||||
return next.handle(updatedRequest);
|
||||
} else {
|
||||
const updatedRequest = req.clone({
|
||||
url: this._baseHref + req.url,
|
||||
});
|
||||
return next.handle(updatedRequest);
|
||||
const apiUrl = `${this._configService.values.API_URL}${req.url}`;
|
||||
return next.handle(req.clone({ url: apiUrl }));
|
||||
}
|
||||
const url = this._baseHref + req.url;
|
||||
return next.handle(req.clone({ url }));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 2bc66542a6032b7b54cc3a3acec9737af6618031
|
||||
Subproject commit 884df60cb8df2af2b70e8dfc6dc8435b7cb5d260
|
||||
Loading…
x
Reference in New Issue
Block a user