RED-4718: move user preference service to common-ui

This commit is contained in:
Dan Percic 2022-07-25 17:51:02 +03:00
parent 68b8480875
commit 8166ff6933
16 changed files with 37 additions and 120 deletions

View File

@ -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,

View File

@ -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';

View File

@ -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);
}

View File

@ -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) {

View File

@ -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';

View File

@ -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';

View File

@ -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());

View File

@ -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';

View File

@ -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';

View File

@ -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,
{

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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({

View File

@ -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');

View File

@ -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