From 8166ff69337e80394264f3ad93139767bcce67ce Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Mon, 25 Jul 2022 17:51:02 +0300 Subject: [PATCH] RED-4718: move user preference service to common-ui --- apps/red-ui/src/app/app.module.ts | 24 +------ .../watermark-screen.component.ts | 5 +- .../red-ui/src/app/modules/auth/auth.guard.ts | 4 +- .../src/app/modules/auth/auth.module.ts | 2 +- .../pdf-annotation-actions.service.ts | 2 +- .../services/pdf-proxy.service.ts | 3 +- .../pdf-viewer/services/pdf-viewer.service.ts | 7 +- .../pdf-viewer/services/tooltips.service.ts | 4 +- .../services/viewer-header.service.ts | 2 +- .../src/app/modules/shared/shared.module.ts | 14 +++- .../src/app/services/notifications.service.ts | 3 +- .../app/services/user-preference.service.ts | 64 +------------------ apps/red-ui/src/app/services/user.service.ts | 3 +- apps/red-ui/src/app/tokens.ts | 3 - .../src/app/utils/api-path-interceptor.ts | 15 ++--- libs/common-ui | 2 +- 16 files changed, 37 insertions(+), 120 deletions(-) diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index caeffc461..9e674fb86 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -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, diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts index 4ffd87e7b..461c9207e 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts @@ -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'; diff --git a/apps/red-ui/src/app/modules/auth/auth.guard.ts b/apps/red-ui/src/app/modules/auth/auth.guard.ts index 6701e12cc..a580ee38a 100644 --- a/apps/red-ui/src/app/modules/auth/auth.guard.ts +++ b/apps/red-ui/src/app/modules/auth/auth.guard.ts @@ -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); } diff --git a/apps/red-ui/src/app/modules/auth/auth.module.ts b/apps/red-ui/src/app/modules/auth/auth.module.ts index 579141b47..f1529e645 100644 --- a/apps/red-ui/src/app/modules/auth/auth.module.ts +++ b/apps/red-ui/src/app/modules/auth/auth.module.ts @@ -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) { diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts index 2e0c5a823..f77fae7ac 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts @@ -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'; diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts index 2077f3c8f..ed84fb29a 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-proxy.service.ts @@ -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'; diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts index 48af31a27..3402bffc5 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/pdf-viewer.service.ts @@ -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()); diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/tooltips.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/tooltips.service.ts index 0d6f77389..cc0f7552d 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/tooltips.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/tooltips.service.ts @@ -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'; diff --git a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts index 7672f211e..9e5dad968 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts +++ b/apps/red-ui/src/app/modules/pdf-viewer/services/viewer-header.service.ts @@ -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'; diff --git a/apps/red-ui/src/app/modules/shared/shared.module.ts b/apps/red-ui/src/app/modules/shared/shared.module.ts index 02f0b6fa5..b7f0cda90 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -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, { diff --git a/apps/red-ui/src/app/services/notifications.service.ts b/apps/red-ui/src/app/services/notifications.service.ts index a193257ff..bea947d0d 100644 --- a/apps/red-ui/src/app/services/notifications.service.ts +++ b/apps/red-ui/src/app/services/notifications.service.ts @@ -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; diff --git a/apps/red-ui/src/app/services/user-preference.service.ts b/apps/red-ui/src/app/services/user-preference.service.ts index a70f38e40..785062401 100644 --- a/apps/red-ui/src/app/services/user-preference.service.ts +++ b/apps/red-ui/src/app/services/user-preference.service.ts @@ -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; +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 { +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 { await this._save(KEYS.lastDossierTemplate, dossierTemplateId); } - getTheme(): string { - return this._getAttribute(KEYS.theme, 'light'); - } - - async saveTheme(theme: 'light' | 'dark'): Promise { - await this._save(KEYS.theme, theme); - window.location.reload(); - } - - getLanguage(): string { - return this._getAttribute(KEYS.language); - } - - async saveLanguage(language: string): Promise { - await this._save(KEYS.language, language); - } - getFilePreviewTooltipsPreference(): boolean { return this._getAttribute(KEYS.filePreviewTooltips, 'false') === 'true'; } @@ -69,31 +38,4 @@ export class UserPreferenceService extends GenericService { 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 { - const attributes = await firstValueFrom(this.getAll()); - 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 { - 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; - } } diff --git a/apps/red-ui/src/app/services/user.service.ts b/apps/red-ui/src/app/services/user.service.ts index 5e53e5faa..ef448ea39 100644 --- a/apps/red-ui/src/app/services/user.service.ts +++ b/apps/red-ui/src/app/services/user.service.ts @@ -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({ diff --git a/apps/red-ui/src/app/tokens.ts b/apps/red-ui/src/app/tokens.ts index d19e040af..cd5e143aa 100644 --- a/apps/red-ui/src/app/tokens.ts +++ b/apps/red-ui/src/app/tokens.ts @@ -1,8 +1,5 @@ import { InjectionToken } from '@angular/core'; -export const BASE_HREF = new InjectionToken('BASE_HREF'); -export type BaseHrefFn = (path: string) => string; -export const BASE_HREF_FN = new InjectionToken('Convert path function'); export const DOSSIER_ID = new InjectionToken('DOSSIER_ID'); export const ACTIVE_DOSSIERS_SERVICE = new InjectionToken('Active dossiers service'); diff --git a/apps/red-ui/src/app/utils/api-path-interceptor.ts b/apps/red-ui/src/app/utils/api-path-interceptor.ts index fda13e3b1..09f74d882 100644 --- a/apps/red-ui/src/app/utils/api-path-interceptor.ts +++ b/apps/red-ui/src/app/utils/api-path-interceptor.ts @@ -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, next: HttpHandler): Observable> { 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 })); } } diff --git a/libs/common-ui b/libs/common-ui index 2bc66542a..884df60cb 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 2bc66542a6032b7b54cc3a3acec9737af6618031 +Subproject commit 884df60cb8df2af2b70e8dfc6dc8435b7cb5d260