From 164c527ce71a77109a344e528c559798c414373f Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Wed, 27 Jul 2022 11:02:40 +0300 Subject: [PATCH] RED-4718: update common-ui --- apps/red-ui/src/app/app.module.ts | 395 ++++++++---------- .../src/app/modules/shared/shared.module.ts | 10 +- apps/red-ui/src/main.ts | 25 +- libs/common-ui | 2 +- 4 files changed, 194 insertions(+), 238 deletions(-) diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index b4de072c0..ecb53a6cd 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -9,7 +9,9 @@ import { ApiPathInterceptor } from '@utils/api-path-interceptor'; import { MissingTranslationHandler, TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { BASE_HREF, + BaseConfigService, CachingModule, + CommonUiModule, HELP_DOCS, IqserHelpModeModule, LanguageService, @@ -52,7 +54,7 @@ import { FeaturesService } from '@services/features.service'; import { MAT_TOOLTIP_DEFAULT_OPTIONS } from '@angular/material/tooltip'; import { LoggerModule, NgxLoggerLevel, TOKEN_LOGGER_CONFIG, TOKEN_LOGGER_RULES_SERVICE } from 'ngx-logger'; import { LoggerRulesService } from '@services/logger-rules.service'; -import { ILoggerConfig } from '@red/domain'; +import { AppConfig, ILoggerConfig } from '@red/domain'; import { SystemPreferencesService } from '@services/system-preferences.service'; import { PdfViewerModule } from './modules/pdf-viewer/pdf-viewer.module'; import { LicenseService } from '@services/license.service'; @@ -67,230 +69,181 @@ const screens = [BaseScreenComponent, DownloadsListScreenComponent]; const components = [AppComponent, AuthErrorComponent, NotificationsComponent, SpotlightSearchComponent, BreadcrumbsComponent, ...screens]; -@NgModule({ - declarations: [...components], - imports: [ - BrowserModule, - BrowserAnimationsModule, - SharedModule, - FileUploadDownloadModule, - HttpClientModule, - AuthModule, - AppRoutingModule, - MonacoEditorModule, - IqserHelpModeModule, - CachingModule.forRoot(UI_CACHES), - PdfViewerModule, - ToastrModule.forRoot({ - closeButton: true, - enableHtml: true, - toastComponent: ToastComponent, - preventDuplicates: true, - resetTimeoutOnDuplicate: true, - }), - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useFactory: httpLoaderFactory, - deps: [HttpClient, ConfigService], +export const appModuleFactory = (config: AppConfig) => { + @NgModule({ + declarations: [...components], + imports: [ + BrowserModule, + BrowserAnimationsModule, + SharedModule, + FileUploadDownloadModule, + HttpClientModule, + AuthModule, + AppRoutingModule, + MonacoEditorModule, + IqserHelpModeModule, + CommonUiModule.forRoot({ + existingUserPreferenceService: UserPreferenceService, + configServiceFactory: () => new BaseConfigService(config), + }), + CachingModule.forRoot(UI_CACHES), + PdfViewerModule, + ToastrModule.forRoot({ + closeButton: true, + enableHtml: true, + toastComponent: ToastComponent, + preventDuplicates: true, + resetTimeoutOnDuplicate: true, + }), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: httpLoaderFactory, + deps: [HttpClient, ConfigService], + }, + compiler: { + provide: TranslateCompiler, + useClass: TranslateMessageFormatCompiler, + }, + }), + ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), + LoggerModule.forRoot(undefined, { + ruleProvider: { + provide: TOKEN_LOGGER_RULES_SERVICE, + useClass: LoggerRulesService, + }, + configProvider: { + provide: TOKEN_LOGGER_CONFIG, + useValue: { + level: environment.production ? NgxLoggerLevel.ERROR : NgxLoggerLevel.DEBUG, + enableSourceMaps: true, + timestampFormat: 'mm:ss:SSS', + disableFileDetails: true, + features: { + ANNOTATIONS: { + color: 'aqua', + enabled: true, + level: NgxLoggerLevel.DEBUG, + }, + FILTERS: { + enabled: false, + }, + PDF: { + enabled: false, + }, + FILE: { + enabled: false, + }, + CHANGES: { + enabled: false, + }, + STATS: { + enabled: false, + }, + }, + } as ILoggerConfig, + }, + }), + ], + providers: [ + { + provide: HTTP_INTERCEPTORS, + multi: true, + useClass: ServerErrorInterceptor, }, - compiler: { - provide: TranslateCompiler, - useClass: TranslateMessageFormatCompiler, + { + provide: ErrorHandler, + useClass: GlobalErrorHandler, }, - }), - ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }), - LoggerModule.forRoot(undefined, { - ruleProvider: { - provide: TOKEN_LOGGER_RULES_SERVICE, - useClass: LoggerRulesService, + { + provide: HTTP_INTERCEPTORS, + multi: true, + useClass: ApiPathInterceptor, }, - configProvider: { - provide: TOKEN_LOGGER_CONFIG, + { + provide: HTTP_INTERCEPTORS, + multi: true, + useClass: TenantIdInterceptor, + }, + { + provide: APP_INITIALIZER, + multi: true, + useFactory: configurationInitializer, + deps: [ + BASE_HREF, + KeycloakService, + Title, + ConfigService, + SystemPreferencesService, + FeaturesService, + GeneralSettingsService, + LanguageService, + UserService, + UserPreferenceService, + LicenseService, + ], + }, + { + provide: MissingTranslationHandler, + useClass: REDMissingTranslationHandler, + }, + { + provide: HELP_DOCS, + useValue: links, + }, + { + provide: MANUAL_BASE_URL, + useFactory: (configService: ConfigService) => configService.values.MANUAL_BASE_URL, + deps: [ConfigService], + }, + { + provide: MAX_RETRIES_ON_SERVER_ERROR, + useFactory: (configService: ConfigService) => configService.values.MAX_RETRIES_ON_SERVER_ERROR, + deps: [ConfigService], + }, + { + provide: SERVER_ERROR_SKIP_PATHS, + useValue: ['redaction-gateway-v1/license'], + }, + { + provide: ACTIVE_DOSSIERS_SERVICE, + useExisting: ActiveDossiersService, + }, + { + provide: ARCHIVED_DOSSIERS_SERVICE, + useExisting: ArchivedDossiersService, + }, + { + provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: { - level: environment.production ? NgxLoggerLevel.ERROR : NgxLoggerLevel.DEBUG, - enableSourceMaps: true, - timestampFormat: 'mm:ss:SSS', - disableFileDetails: true, - features: { - ANNOTATIONS: { - color: 'aqua', - enabled: true, - level: NgxLoggerLevel.DEBUG, - }, - FILTERS: { - enabled: false, - }, - PDF: { - enabled: false, - }, - FILE: { - enabled: false, - }, - CHANGES: { - enabled: false, - }, - STATS: { - enabled: false, - }, - }, - } as ILoggerConfig, + disableTooltipInteractivity: true, + }, }, - }), - ], - providers: [ - { - provide: HTTP_INTERCEPTORS, - multi: true, - useClass: ServerErrorInterceptor, - }, - { - provide: ErrorHandler, - useClass: GlobalErrorHandler, - }, - { - provide: HTTP_INTERCEPTORS, - multi: true, - useClass: ApiPathInterceptor, - }, - { - provide: HTTP_INTERCEPTORS, - multi: true, - useClass: TenantIdInterceptor, - }, - { - provide: APP_INITIALIZER, - multi: true, - useFactory: configurationInitializer, - deps: [ - BASE_HREF, - KeycloakService, - Title, - ConfigService, - SystemPreferencesService, - FeaturesService, - GeneralSettingsService, - LanguageService, - UserService, - UserPreferenceService, - LicenseService, - ], - }, - { - provide: MissingTranslationHandler, - useClass: REDMissingTranslationHandler, - }, - { - provide: HELP_DOCS, - useValue: links, - }, - { - provide: MANUAL_BASE_URL, - useFactory: (configService: ConfigService) => configService.values.MANUAL_BASE_URL, - deps: [ConfigService], - }, - { - provide: MAX_RETRIES_ON_SERVER_ERROR, - useFactory: (configService: ConfigService) => configService.values.MAX_RETRIES_ON_SERVER_ERROR, - deps: [ConfigService], - }, - { - provide: SERVER_ERROR_SKIP_PATHS, - useValue: ['redaction-gateway-v1/license'], - }, - { - provide: ACTIVE_DOSSIERS_SERVICE, - useExisting: ActiveDossiersService, - }, - { - provide: ARCHIVED_DOSSIERS_SERVICE, - useExisting: ArchivedDossiersService, - }, - { - provide: MAT_TOOLTIP_DEFAULT_OPTIONS, - useValue: { - disableTooltipInteractivity: true, - }, - }, - DatePipe, - BaseDatePipe, - ], - bootstrap: [AppComponent], -}) -export class AppModule { - constructor(private readonly _router: Router, private readonly _route: ActivatedRoute) { - this._configureKeyCloakRouteHandling(); - // this._test(); + DatePipe, + BaseDatePipe, + ], + bootstrap: [AppComponent], + }) + class AppModule { + constructor(private readonly _router: Router, private readonly _route: ActivatedRoute) { + this._configureKeyCloakRouteHandling(); + } + + private _configureKeyCloakRouteHandling() { + this._route.queryParamMap.subscribe(queryParams => { + if (queryParams.has('code') || queryParams.has('state') || queryParams.has('session_state')) { + this._router.navigate([], { + queryParams: { + state: null, + session_state: null, + code: null, + }, + queryParamsHandling: 'merge', + }); + } + }); + } } - private _configureKeyCloakRouteHandling() { - this._route.queryParamMap.subscribe(queryParams => { - if (queryParams.has('code') || queryParams.has('state') || queryParams.has('session_state')) { - this._router.navigate([], { - queryParams: { - state: null, - session_state: null, - code: null, - }, - queryParamsHandling: 'merge', - }); - } - }); - } - - // private _test(){ - // - // const flatGerman = flatten(german); - // - // - // const flatEnglish = flatten(english); - // - // const tmfc = new TranslateMessageFormatCompiler(); - // - // - // - // for (const key of Object.keys(flatGerman)) { - // try { - // const result = tmfc.compile(flatGerman[key], 'de'); - // //console.log(result); - // } catch (e) { - // console.error('ERROR AT: ', flatGerman[key]); - // } - // } - // - // for (const key of Object.keys(flatEnglish)) { - // try { - // const result = tmfc.compile(flatEnglish[key], 'de'); - // //console.log(result); - // } catch (e) { - // console.error('ERROR AT: ', flatEnglish[key]); - // } - // } - // console.log('done'); - // } -} - -// -// function flatten(data: any) { -// const result: any = {}; -// -// function recurse(cur: any, prop: any) { -// if (Object(cur) !== cur) { -// result[prop] = cur; -// } else if (Array.isArray(cur)) { -// let l = 0; -// for (let i = 0, l = cur.length; i < l; i++) recurse(cur[i], prop + '[' + i + ']'); -// if (l === 0) result[prop] = []; -// } else { -// let isEmpty = true; -// for (const p in cur) { -// isEmpty = false; -// recurse(cur[p], prop ? prop + '.' + p : p); -// } -// if (isEmpty && prop) result[prop] = {}; -// } -// } -// -// recurse(data, ''); -// return result; -// } + return AppModule; +}; 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 b7f0cda90..7c7a348f3 100644 --- a/apps/red-ui/src/app/modules/shared/shared.module.ts +++ b/apps/red-ui/src/app/modules/shared/shared.module.ts @@ -37,7 +37,6 @@ 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]; @@ -73,14 +72,7 @@ const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, Rea @NgModule({ declarations: [...components, ...utils, EditorComponent], - imports: [ - CommonModule, - CommonUiModule.forRoot({ existingUserPreferenceService: UserPreferenceService }), - ...modules, - MonacoEditorModule, - TranslateModule, - RouterModule, - ], + imports: [CommonModule, CommonUiModule, ...modules, MonacoEditorModule, TranslateModule, RouterModule], exports: [...modules, CommonUiModule, ...components, ...utils], providers: [ ...services, diff --git a/apps/red-ui/src/main.ts b/apps/red-ui/src/main.ts index 31e466364..410139323 100644 --- a/apps/red-ui/src/main.ts +++ b/apps/red-ui/src/main.ts @@ -1,22 +1,33 @@ import { ApplicationRef, enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; - -import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { enableDebugTools } from '@angular/platform-browser'; +import { appModuleFactory } from './app/app.module'; +import { AppConfig } from '@red/domain'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic() - .bootstrapModule(AppModule, { ngZoneEventCoalescing: true }) - .then(moduleRef => { +// https://github.com/angular/angular/issues/11195#issuecomment-248020928 +async function bootstrap(appConfig: AppConfig) { + const packageJson = await import('package.json'); + const config = { ...appConfig, FRONTEND_APP_VERSION: packageJson.version }; + + console.log('Started with local config: ', config); + const appModule = appModuleFactory(config); + + const ngModuleRef = platformBrowserDynamic().bootstrapModule(appModule, { ngZoneEventCoalescing: true }); + return ngModuleRef.then(moduleRef => { if (!environment.production) { const applicationRef = moduleRef.injector.get(ApplicationRef); const componentRef = applicationRef.components[0]; // allows to run `ng.profiler.timeChangeDetection();` enableDebugTools(componentRef); } - }) - .catch(err => window['console'].error(err)); + }); +} + +const configPromise = fetch('/ui/assets/config/config.json').then(resp => resp.json()); + +configPromise.then(bootstrap).catch(console.error); diff --git a/libs/common-ui b/libs/common-ui index bc799eae4..34b7ebcef 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit bc799eae4d71d25ab72f6b1d429c40bc7a9bdcd6 +Subproject commit 34b7ebcef7aeb4d5dd4f475d1cc4ff19a78d729c