From 6557bafd2ff5cfc809aa7941179fb701c53f73f2 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Sun, 19 Sep 2021 23:44:11 +0300 Subject: [PATCH] move server error interceptor, update app config service --- angular.json | 3 + apps/red-ui/src/app/app.module.ts | 10 ++- .../auth-error/auth-error.component.html | 16 ++--- .../auth-error/auth-error.component.ts | 21 ++----- .../user-profile-screen.component.ts | 4 +- .../license-information-screen.component.html | 15 +++-- .../license-information-screen.component.ts | 10 +-- .../screens/trash/trash-screen.component.ts | 4 +- .../modules/app-config/app-config.service.ts | 50 ++++++--------- .../red-ui/src/app/modules/auth/auth.guard.ts | 6 +- .../src/app/modules/auth/auth.module.ts | 62 +++++++++---------- .../page-indicator.component.ts | 6 +- .../pdf-viewer/pdf-viewer.component.ts | 4 +- ...dit-dossier-deleted-documents.component.ts | 4 +- .../dossier-overview-screen.component.ts | 6 +- .../services/file-download.service.ts | 4 +- .../services/file-upload.service.ts | 4 +- .../upload-status-overlay.component.ts | 2 +- .../src/app/utils/api-path-interceptor.ts | 6 +- .../src/app/utils/server-error-interceptor.ts | 23 ------- apps/red-ui/src/assets/config/config.json | 8 ++- apps/red-ui/src/assets/i18n/en.json | 4 +- apps/red-ui/tsconfig.app.json | 2 +- libs/common-ui | 2 +- 24 files changed, 123 insertions(+), 153 deletions(-) delete mode 100644 apps/red-ui/src/app/utils/server-error-interceptor.ts diff --git a/angular.json b/angular.json index 699301363..77f8b6ea5 100644 --- a/angular.json +++ b/angular.json @@ -110,6 +110,9 @@ "apps/red-ui/src/manifest.webmanifest" ], "styles": ["apps/red-ui/src/styles.scss", "libs/common-ui/src/assets/styles/common.scss"], + "stylePreprocessorOptions": { + "includePaths": ["./apps/red-ui/src/assets/styles"] + }, "scripts": ["node_modules/@pdftron/webviewer/webviewer.min.js"], "vendorChunk": true, "extractLicenses": false, diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index a1d9b56cd..707f389fd 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -36,10 +36,9 @@ import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight import { PruningTranslationLoader } from '@utils/pruning-translation-loader'; import { DatePipe } from '@shared/pipes/date.pipe'; import * as links from '../assets/help-mode/links.json'; -import { HELP_DOCS, IqserHelpModeModule } from '@iqser/common-ui'; -import { ServerErrorInterceptor } from '@utils/server-error-interceptor'; +import { HELP_DOCS, IqserHelpModeModule, MAX_RETRIES_ON_SERVER_ERROR, ServerErrorInterceptor } from '@iqser/common-ui'; -export function httpLoaderFactory(httpClient: HttpClient) { +export function httpLoaderFactory(httpClient: HttpClient): PruningTranslationLoader { return new PruningTranslationLoader(httpClient, '/assets/i18n/', '.json'); } @@ -145,6 +144,11 @@ const components = [ provide: HELP_DOCS, useValue: links }, + { + provide: MAX_RETRIES_ON_SERVER_ERROR, + useFactory: (appConfigService: AppConfigService) => appConfigService.config.MAX_RETRIES_ON_SERVER_ERROR, + deps: [AppConfigService] + }, DatePipe ], bootstrap: [AppComponent] diff --git a/apps/red-ui/src/app/components/auth-error/auth-error.component.html b/apps/red-ui/src/app/components/auth-error/auth-error.component.html index a2597f3bc..83eb55942 100644 --- a/apps/red-ui/src/app/components/auth-error/auth-error.component.html +++ b/apps/red-ui/src/app/components/auth-error/auth-error.component.html @@ -1,19 +1,19 @@
-

+

- +
diff --git a/apps/red-ui/src/app/components/auth-error/auth-error.component.ts b/apps/red-ui/src/app/components/auth-error/auth-error.component.ts index 351af3380..0ceee0aa9 100644 --- a/apps/red-ui/src/app/components/auth-error/auth-error.component.ts +++ b/apps/red-ui/src/app/components/auth-error/auth-error.component.ts @@ -1,24 +1,15 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; import { UserService } from '@services/user.service'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; @Component({ selector: 'redaction-auth-error', templateUrl: './auth-error.component.html', styleUrls: ['./auth-error.component.scss'] }) -export class AuthErrorComponent implements OnInit { - configuredAdminName: string; - configuredAdminUrl: string; +export class AuthErrorComponent { + adminName = this._appConfigService.config.ADMIN_CONTACT_NAME; + adminUrl = this._appConfigService.config.ADMIN_CONTACT_URL; - constructor(private readonly _userService: UserService, private readonly _appConfigService: AppConfigService) {} - - ngOnInit(): void { - this.configuredAdminName = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_NAME); - this.configuredAdminUrl = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_URL); - } - - logout() { - this._userService.logout(); - } + constructor(readonly userService: UserService, private readonly _appConfigService: AppConfigService) {} } diff --git a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts index 873a7797f..2723f55fd 100644 --- a/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts +++ b/apps/red-ui/src/app/components/user-profile/user-profile-screen.component.ts @@ -5,7 +5,7 @@ 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 { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { DomSanitizer } from '@angular/platform-browser'; import { languagesTranslations } from '../../translations/languages-translations'; import { LoadingService } from '@iqser/common-ui'; @@ -42,7 +42,7 @@ export class UserProfileScreenComponent implements OnInit { }); this.changePasswordUrl = this._domSanitizer.bypassSecurityTrustResourceUrl( - this._appConfigService.getConfig(AppConfigKey.OAUTH_URL) + '/account/password' + this._appConfigService.config.OAUTH_URL + '/account/password' ); } diff --git a/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.html index c55476fe4..0dee2b859 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.html @@ -16,17 +16,17 @@
-
{{ appConfigService.getConfig('BACKEND_APP_VERSION', '-') }}
+
{{ appConfigService.config.BACKEND_APP_VERSION || '-' }}
-
{{ appConfigService.getConfig('FRONTEND_APP_VERSION', '-') }}
+
{{ appConfigService.config.FRONTEND_APP_VERSION || '-' }}
-
{{ appConfigService.getConfig('APP_NAME', '-') }}
+
{{ appConfigService.config.APP_NAME || '-' }}
@@ -45,14 +45,14 @@
-
{{ appConfigService.getConfig('LICENSE_CUSTOMER', '-') }}
+
{{ appConfigService.config.LICENSE_CUSTOMER || '-' }}
- {{ appConfigService.getConfig('LICENSE_START', '-') }} / - {{ appConfigService.getConfig('LICENSE_END', '-') }} + {{ appConfigService.config.LICENSE_START || '-' }} / + {{ appConfigService.config.LICENSE_END || '-' }}
@@ -107,8 +107,7 @@ [yAxisLabelRight]="'license-info-screen.chart.total-pages' | translate" [yAxisLabel]="'license-info-screen.chart.pages-per-month' | translate" [yAxis]="true" - > - + >
diff --git a/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.ts index 35f22ad14..9206b4e65 100644 --- a/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/license-information/license-information-screen.component.ts @@ -60,9 +60,9 @@ export class LicenseInformationScreenComponent implements OnInit { } async ngOnInit() { - this.totalLicensedNumberOfPages = this.appConfigService.getConfig('LICENSE_PAGE_COUNT', 0); - const startDate = moment(this.appConfigService.getConfig('LICENSE_START'), 'DD-MM-YYYY'); - const endDate = moment(this.appConfigService.getConfig('LICENSE_END'), 'DD-MM-YYYY'); + this.totalLicensedNumberOfPages = this.appConfigService.config.LICENSE_PAGE_COUNT || 0; + const startDate = moment(this.appConfigService.config.LICENSE_START, 'DD-MM-YYYY'); + const endDate = moment(this.appConfigService.config.LICENSE_END, 'DD-MM-YYYY'); await this._setMonthlyStats(startDate, endDate); @@ -93,7 +93,7 @@ export class LicenseInformationScreenComponent implements OnInit { } sendMail(): void { - const licenseCustomer = this.appConfigService.getConfig('LICENSE_CUSTOMER'); + const licenseCustomer = this.appConfigService.config.LICENSE_CUSTOMER; const subject = this._translateService.instant('license-info-screen.email.title', { licenseCustomer }); @@ -106,7 +106,7 @@ export class LicenseInformationScreenComponent implements OnInit { pages: this.totalLicensedNumberOfPages }) ].join(lineBreak); - window.location.href = `mailto:${this.appConfigService.getConfig('LICENSE_EMAIL')}?subject=${subject}&body=${body}`; + window.location.href = `mailto:${this.appConfigService.config.LICENSE_EMAIL}?subject=${subject}&body=${body}`; } private async _setMonthlyStats(startDate: moment.Moment, endDate: moment.Moment) { diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts index 6dcf85ce1..55c194a6b 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.ts @@ -9,7 +9,7 @@ import { SortingOrders, TableColumnConfig } from '@iqser/common-ui'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import * as moment from 'moment'; import { DossiersService } from '../../../dossier/services/dossiers.service'; import { AdminDialogService } from '../../services/admin-dialog.service'; @@ -45,7 +45,7 @@ export class TrashScreenComponent extends ListingComponent impl @ViewChild('deletedTimeTemplate', { static: true }) deletedTimeTemplate: TemplateRef; @ViewChild('restoreDateTemplate', { static: true }) restoreDateTemplate: TemplateRef; protected readonly _primaryKey = 'dossierName'; - private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS); + private readonly _deleteRetentionHours = this._appConfigService.config.DELETE_RETENTION_HOURS; constructor( protected readonly _injector: Injector, diff --git a/apps/red-ui/src/app/modules/app-config/app-config.service.ts b/apps/red-ui/src/app/modules/app-config/app-config.service.ts index 5da8dece3..01dae46ec 100644 --- a/apps/red-ui/src/app/modules/app-config/app-config.service.ts +++ b/apps/red-ui/src/app/modules/app-config/app-config.service.ts @@ -1,14 +1,13 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { tap } from 'rxjs/operators'; -import { Observable } from 'rxjs'; import { Title } from '@angular/platform-browser'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore import packageInfo from '../../../../../../package.json'; +import config from '../../../assets/config/config.json'; import { CacheApiService, wipeCaches } from '@redaction/red-cache'; -export enum AppConfigKey { +const version = packageInfo.version; + +export const enum AppConfigKey { OAUTH_URL = 'OAUTH_URL', OAUTH_CLIENT_ID = 'OAUTH_CLIENT_ID', OAUTH_IDP_HINT = 'OAUTH_IDP_HINT', @@ -21,6 +20,7 @@ export enum AppConfigKey { RECENT_PERIOD_IN_HOURS = 'RECENT_PERIOD_IN_HOURS', DELETE_RETENTION_HOURS = 'DELETE_RETENTION_HOURS', APP_NAME = 'APP_NAME', + MAX_RETRIES_ON_SERVER_ERROR = 'MAX_RETRIES_ON_SERVER_ERROR', // TODO BACKEND_APP_VERSION = 'BACKEND_APP_VERSION', @@ -37,47 +37,37 @@ export enum AppConfigKey { providedIn: 'root' }) export class AppConfigService { - private _config: { [key in AppConfigKey]?: any } = {}; + private _config = { ...config, [AppConfigKey.FRONTEND_APP_VERSION]: version } as const; constructor( private readonly _httpClient: HttpClient, private readonly _cacheApiService: CacheApiService, private readonly _titleService: Title - ) {} - - get version(): string { - return packageInfo.version; + ) { + this._checkFrontendVersion(); } - loadAppConfig(): Observable { + private _checkFrontendVersion(): void { this._cacheApiService.getCachedValue(AppConfigKey.FRONTEND_APP_VERSION).then(async lastVersion => { - console.log('[REDACTION] Last app version: ', lastVersion, ' current version ', this.version); - if (lastVersion !== this.version) { - console.log('[REDACTION] Version-missmatch - wiping caches!'); + console.log('[REDACTION] Last app version: ', lastVersion, ' current version ', version); + if (lastVersion !== version) { + console.warn('[REDACTION] Version-mismatch - wiping caches!'); await wipeCaches(); } - await this._cacheApiService.cacheValue(AppConfigKey.FRONTEND_APP_VERSION, this.version); + await this._cacheApiService.cacheValue(AppConfigKey.FRONTEND_APP_VERSION, version); }); - - return this._httpClient.get('/assets/config/config.json').pipe( - tap(config => { - console.log('[REDACTION] Started with config: ', config); - this._config = config; - this._config[AppConfigKey.FRONTEND_APP_VERSION] = this.version; - }) - ); } - updateDisplayName(name: string) { - this.setConfig(AppConfigKey.APP_NAME, name); - this._titleService.setTitle(this.getConfig(AppConfigKey.APP_NAME, 'RedactManager')); + get config() { + return this._config; } - setConfig(key: AppConfigKey, value: any) { - this._config[key] = value; + updateDisplayName(name: string): void { + this._config = { ...this._config, [AppConfigKey.APP_NAME]: name } as const; + this._titleService.setTitle(this._config.APP_NAME || 'RedactManager'); } - getConfig(key: AppConfigKey | string, defaultValue?: any) { - return this._config[key] ? this._config[key] : defaultValue; + getConfig(key: AppConfigKey, defaultValue?: string): string | number { + return this._config[key] ?? defaultValue; } } 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 b073f9500..1ac4d1e83 100644 --- a/apps/red-ui/src/app/modules/auth/auth.guard.ts +++ b/apps/red-ui/src/app/modules/auth/auth.guard.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular'; import { UserService } from '@services/user.service'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { BASE_HREF } from '../../tokens'; @Injectable({ @@ -19,10 +19,10 @@ export class AuthGuard extends KeycloakAuthGuard { super(_router, _keycloak); } - async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { if (!this.authenticated) { await this._keycloak.login({ - idpHint: this._appConfigService.getConfig(AppConfigKey.OAUTH_IDP_HINT, null), + idpHint: this._appConfigService.config.OAUTH_IDP_HINT, redirectUri: window.location.origin + this._baseHref + state.url }); return false; 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 7ba78bc5d..17a3554fc 100644 --- a/apps/red-ui/src/app/modules/auth/auth.module.ts +++ b/apps/red-ui/src/app/modules/auth/auth.module.ts @@ -4,49 +4,47 @@ import { HttpClientModule } from '@angular/common/http'; import { AppConfigModule } from '@app-config/app-config.module'; import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloak-angular'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { BASE_HREF } from '../../tokens'; import { APP_BOOTSTRAPPED } from '../bootstrap/app-bootstrap'; -export function keycloakInitializer(keycloak: KeycloakService, appConfigService: AppConfigService, baseUrl) { +export function keycloakInitializer( + keycloakService: KeycloakService, + appConfigService: AppConfigService, + baseUrl: string +): () => Promise { + let url = appConfigService.config.OAUTH_URL; + url = url.replace(/\/$/, ''); // remove trailing slash + const realm = url.substring(url.lastIndexOf('/') + 1, url.length); + url = url.substr(0, url.lastIndexOf('/realms')); + const options: KeycloakOptions = { + config: { + url: url, + realm: realm, + clientId: appConfigService.config.OAUTH_CLIENT_ID + }, + initOptions: { + checkLoginIframe: false, + onLoad: 'check-sso', + silentCheckSsoRedirectUri: window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html', + flow: 'standard' + }, + enableBearerInterceptor: true + }; return () => - appConfigService - .loadAppConfig() - .toPromise() - .then(() => { - let url = appConfigService.getConfig(AppConfigKey.OAUTH_URL); - url = url.replace(/\/$/, ''); // remove trailing slash - const realm = url.substring(url.lastIndexOf('/') + 1, url.length); - url = url.substr(0, url.lastIndexOf('/realms')); - const options: KeycloakOptions = { - config: { - url: url, - realm: realm, - clientId: appConfigService.getConfig(AppConfigKey.OAUTH_CLIENT_ID) - }, - initOptions: { - checkLoginIframe: false, - onLoad: 'check-sso', - silentCheckSsoRedirectUri: window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html', - flow: 'standard' - }, - enableBearerInterceptor: true - }; - return keycloak - .init(options) - .then(() => configureAutomaticRedirectToLoginScreen(keycloak)) - .then(() => APP_BOOTSTRAPPED.next(true)); - }); + keycloakService + .init(options) + .then(() => configureAutomaticRedirectToLoginScreen(keycloakService)) + .then(() => APP_BOOTSTRAPPED.next(true)); } function configureAutomaticRedirectToLoginScreen(keyCloakService: KeycloakService) { - keyCloakService.getKeycloakInstance().onAuthRefreshError = () => { - keyCloakService.logout(); + keyCloakService.getKeycloakInstance().onAuthRefreshError = async () => { + await keyCloakService.logout(); }; } @NgModule({ - declarations: [], imports: [CommonModule, HttpClientModule, KeycloakAngularModule, AppConfigModule], providers: [ { diff --git a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts index f91cc4380..5b1097158 100644 --- a/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/page-indicator/page-indicator.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, S import { ViewedPages, ViewedPagesControllerService } from '@redaction/red-ui-http'; import { AppStateService } from '@state/app-state.service'; import { PermissionsService } from '@services/permissions.service'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { Subscription } from 'rxjs'; @Component({ @@ -67,11 +67,11 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy { clearTimeout(this.pageReadTimeout); } if (this.active && !this.read) { - this.pageReadTimeout = setTimeout(() => { + this.pageReadTimeout = window.setTimeout(() => { if (this.active && !this.read) { this._markPageRead(); } - }, this._appConfigService.getConfig(AppConfigKey.AUTO_READ_TIME, 1.5) * 1000); + }, this._appConfigService.config.AUTO_READ_TIME * 1000); } } } diff --git a/apps/red-ui/src/app/modules/dossier/components/pdf-viewer/pdf-viewer.component.ts b/apps/red-ui/src/app/modules/dossier/components/pdf-viewer/pdf-viewer.component.ts index 145e99206..10f3821c8 100644 --- a/apps/red-ui/src/app/modules/dossier/components/pdf-viewer/pdf-viewer.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/pdf-viewer/pdf-viewer.component.ts @@ -23,7 +23,7 @@ import { AnnotationDrawService } from '../../services/annotation-draw.service'; import { AnnotationActionsService } from '../../services/annotation-actions.service'; import { UserPreferenceService } from '@services/user-preference.service'; import { BASE_HREF } from '../../../../tokens'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { LoadingService } from '@iqser/common-ui'; import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component'; @@ -298,7 +298,7 @@ export class PdfViewerComponent implements OnInit, OnChanges { private _setSelectionMode(): void { const textTool = (this.instance.Core.Tools.TextTool) as TextTool; - textTool.SELECTION_MODE = this._appConfigService.getConfig(AppConfigKey.SELECTION_MODE); + textTool.SELECTION_MODE = this._appConfigService.config.SELECTION_MODE; } private _toggleRectangleAnnotationAction(readonly: boolean) { diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component.ts index cce960008..2d998029f 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component.ts @@ -13,7 +13,7 @@ import { import { FileManagementControllerService, FileStatus, StatusControllerService } from '@redaction/red-ui-http'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import * as moment from 'moment'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { getLeftDateTime } from '@utils/functions'; import { Observable } from 'rxjs'; import { distinctUntilChanged, map } from 'rxjs/operators'; @@ -44,7 +44,7 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent[]; readonly tableHeaderLabel = _('edit-dossier-dialog.deleted-documents.table-header.label'); readonly circleButtonTypes = CircleButtonTypes; - readonly deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS); + readonly deleteRetentionHours = this._appConfigService.config.DELETE_RETENTION_HOURS; @ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef; @ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef; @ViewChild('deletedDateTemplate', { static: true }) deletedDateTemplate: TemplateRef; diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts index b42a66abc..c2f670670 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts @@ -27,7 +27,7 @@ import { StatusSorter } from '@utils/sorters/status-sorter'; import { convertFiles, handleFileDrop } from '@utils/file-drop-utils'; import { DossiersDialogService } from '../../services/dossiers-dialog.service'; import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { ActionConfig } from '@shared/components/page-header/models/action-config.model'; import { CircleButtonTypes, @@ -256,7 +256,7 @@ export class DossierOverviewScreenComponent extends ListingComponent - moment(file.lastUpdated).add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours').isAfter(moment()); + moment(file.lastUpdated).add(this._appConfigService.config.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment()); private _configureTableColumns() { const dynamicColumns: TableColumnConfig[] = []; @@ -472,7 +472,7 @@ export class DossierOverviewScreenComponent extends ListingComponent 0) { - const recentPeriod = this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS); + const recentPeriod = this._appConfigService.config.RECENT_PERIOD_IN_HOURS; quickFilters = [ { key: 'recent', diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts index 421761d8e..e4c7871d6 100644 --- a/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts +++ b/apps/red-ui/src/app/modules/upload-download/services/file-download.service.ts @@ -1,7 +1,7 @@ import { ApplicationRef, Injectable } from '@angular/core'; import { DownloadControllerService, FileManagementControllerService } from '@redaction/red-ui-http'; import { interval, Observable } from 'rxjs'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { TranslateService } from '@ngx-translate/core'; import { DossierWrapper } from '@state/model/dossier.wrapper'; import { FileStatusWrapper } from '@models/file/file-status.wrapper'; @@ -56,7 +56,7 @@ export class FileDownloadService { const token = await this._keycloakService.getToken(); const anchor = document.createElement('a'); anchor.href = - this._appConfigService.getConfig(AppConfigKey.API_URL) + + this._appConfigService.config.API_URL + '/async/download?access_token=' + encodeURIComponent(token) + '&storageId=' + diff --git a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts index c4caebff1..13f80339c 100644 --- a/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts +++ b/apps/red-ui/src/app/modules/upload-download/services/file-upload.service.ts @@ -3,7 +3,7 @@ import { FileUploadModel } from '../model/file-upload.model'; import { AppStateService } from '@state/app-state.service'; import { HttpErrorResponse, HttpEventType } from '@angular/common/http'; import { interval, Subscription } from 'rxjs'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { TranslateService } from '@ngx-translate/core'; import { UploadDownloadDialogService } from './upload-download-dialog.service'; import { toNumber } from '@utils/functions'; @@ -55,7 +55,7 @@ export class FileUploadService { } async uploadFiles(files: FileUploadModel[]): Promise { - const maxSizeMB = this._appConfigService.getConfig(AppConfigKey.MAX_FILE_SIZE_MB, 100); + const maxSizeMB = this._appConfigService.config.MAX_FILE_SIZE_MB; const maxSizeBytes = toNumber(maxSizeMB) * 1024 * 1024; const dossierFiles = this._appStateService.activeDossier.files; let option: 'overwrite' | 'skip' | undefined; diff --git a/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.ts b/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.ts index 900b15930..e5c97d513 100644 --- a/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.ts +++ b/apps/red-ui/src/app/modules/upload-download/upload-status-overlay/upload-status-overlay.component.ts @@ -22,7 +22,7 @@ export class UploadStatusOverlayComponent implements OnInit { ) {} ngOnInit() { - this.uploadStatusInterval = setInterval(() => { + this.uploadStatusInterval = window.setInterval(() => { // keep only errors this.uploadService.filterFiles(); if (this.uploadService.files.length === 0) { 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 61d262e22..e7396f163 100644 --- a/apps/red-ui/src/app/utils/api-path-interceptor.ts +++ b/apps/red-ui/src/app/utils/api-path-interceptor.ts @@ -1,17 +1,17 @@ import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Inject, Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { AppConfigKey, AppConfigService } from '@app-config/app-config.service'; +import { AppConfigService } from '@app-config/app-config.service'; import { BASE_HREF } from '../tokens'; @Injectable() export class ApiPathInterceptor implements HttpInterceptor { constructor(@Inject(BASE_HREF) private readonly _baseHref: string, private readonly _appConfigService: AppConfigService) {} - intercept(req: HttpRequest, next: HttpHandler): Observable> { + intercept(req: HttpRequest, next: HttpHandler): Observable> { if (!req.url.startsWith('/assets')) { const updatedRequest = req.clone({ - url: this._appConfigService.getConfig(AppConfigKey.API_URL) + req.url + url: this._appConfigService.config.API_URL + req.url }); return next.handle(updatedRequest); } else { diff --git a/apps/red-ui/src/app/utils/server-error-interceptor.ts b/apps/red-ui/src/app/utils/server-error-interceptor.ts deleted file mode 100644 index bb8d15624..000000000 --- a/apps/red-ui/src/app/utils/server-error-interceptor.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { ErrorService } from '@iqser/common-ui'; -import { Observable, throwError } from 'rxjs'; -import { catchError, map } from 'rxjs/operators'; - -@Injectable() -export class ServerErrorInterceptor implements HttpInterceptor { - constructor(private readonly _errorService: ErrorService) {} - - intercept(req: HttpRequest, next: HttpHandler): Observable> { - return next.handle(req).pipe( - map((event: HttpEvent) => event), - catchError((error: HttpErrorResponse) => { - if (error.status >= 500) { - // || error.status === 0 - this._errorService.set(error); - } - return throwError(error); - }) - ); - } -} diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 551c74563..16a19f97a 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,4 +1,9 @@ { + "APP_NAME": "RedactManager", + "ADMIN_CONTACT_NAME": null, + "ADMIN_CONTACT_URL": null, + "AUTO_READ_TIME": 1.5, + "OAUTH_IDP_HINT": null, "OAUTH_URL": "https://demo.redactmanager.com/auth/realms/redaction", "API_URL": "https://demo.redactmanager.com/redaction-gateway-v1", "OAUTH_CLIENT_ID": "redaction", @@ -13,5 +18,6 @@ "SELECTION_MODE": "structural", "RECENT_PERIOD_IN_HOURS": 24, "MAX_FILE_SIZE_MB": 100, - "DELETE_RETENTION_HOURS": 96 + "DELETE_RETENTION_HOURS": 96, + "MAX_RETRIES_ON_SERVER_ERROR": 3 } diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index bd220b610..b9a9e5c17 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -865,7 +865,9 @@ "generic": "Action failed with code {status}" }, "reload": "Reload", - "title": "Oops! Something went wrong..." + "title": "Oops! Something went wrong...", + "offline": "You're offline", + "close": "Close" }, "exact-date": "{day} {month} {year} at {hour}:{minute}", "file": "File", diff --git a/apps/red-ui/tsconfig.app.json b/apps/red-ui/tsconfig.app.json index e9fa6dfd9..9d14205ee 100644 --- a/apps/red-ui/tsconfig.app.json +++ b/apps/red-ui/tsconfig.app.json @@ -2,7 +2,7 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "types": [] + "allowSyntheticDefaultImports": true }, "files": ["src/main.ts", "src/polyfills.ts"] } diff --git a/libs/common-ui b/libs/common-ui index c7546078e..90287baf6 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit c7546078ec884dd9a051a965111c4093f2a2ae94 +Subproject commit 90287baf62e8a5cfbec742b6947352c56c255bdb