From a9c5f1b110a0f10cfe72cbc8106efdc012927755 Mon Sep 17 00:00:00 2001 From: mechtelm <nicht@mehr.fragen> Date: Fri, 28 May 2021 14:10:25 +0200 Subject: [PATCH] Introduce new appConfig fields Logo flexible; move some main.dataservice infos into appConfig; new appConfig data: html, warning etc. --- src/app/app-root/login/login.component.html | 4 +- .../status-card/status-card.component.html | 10 +- .../status-card/status-card.component.ts | 1 - src/app/app.component.html | 2 +- src/app/app.component.ts | 64 +++---------- src/app/app.interceptor.ts | 2 +- src/app/config/app.config.ts | 96 +++++++++++++++++-- src/app/maindata.service.ts | 23 +---- 8 files changed, 115 insertions(+), 87 deletions(-) diff --git a/src/app/app-root/login/login.component.html b/src/app/app-root/login/login.component.html index 6b5c3d2f..aeddb266 100644 --- a/src/app/app-root/login/login.component.html +++ b/src/app/app-root/login/login.component.html @@ -1,7 +1,7 @@ <div fxLayout="row wrap" fxLayoutAlign="center stretch"> <mat-card fxFlex="0 0 400px"> <mat-card-title>Anmelden</mat-card-title> - <form [formGroup]="loginForm" (ngSubmit)="login()" *ngIf="mds.isApiValid"> + <form [formGroup]="loginForm" (ngSubmit)="login()" *ngIf="mds.appConfig?.isValidApiVersion"> <mat-card-content fxLayout="column"> <mat-form-field> <input matInput formControlName="name" placeholder="Anmeldename" (keyup.enter)="pw.focus()"> @@ -22,7 +22,7 @@ </mat-card-actions> </form> <p style="color: chocolate"><b>{{ problemText }}</b></p> - <p style="color: chocolate" *ngIf="!mds.isApiValid"><b>Die Verbindung mit dem Server ist nicht möglich.</b></p> + <p style="color: chocolate" *ngIf="!mds.appConfig?.isValidApiVersion"><b>Die Verbindung mit dem Server ist nicht möglich.</b></p> <alert *ngIf="systemAnnouncement !== '-'" level="warning" [text]="systemAnnouncement"></alert> </mat-card> diff --git a/src/app/app-root/status-card/status-card.component.html b/src/app/app-root/status-card/status-card.component.html index 14dd57b6..f638168c 100644 --- a/src/app/app-root/status-card/status-card.component.html +++ b/src/app/app-root/status-card/status-card.component.html @@ -14,11 +14,11 @@ <ul style="margin: 0;"> <li *ngIf="!isProductionMode">Build-Modus: Dev</li> <li>Version {{appVersion}}</li> - <li>API: Version {{mds.apiVersion}}, {{apiVersionExpected}} erforderlich</li> - <li>Broadcasting-Service: {{mds.broadcastingServiceInfo.status}} - <span *ngIf="mds.broadcastingServiceInfo.version"> - - Version {{mds.broadcastingServiceInfo.version}}, - {{mds.broadcastingServiceInfo.versionExpected}} erforderlich + <li>API: Version {{mds.appConfig?.detectedApiVersion}}, {{mds.expectedApiVersion}} erforderlich</li> + <li>Broadcasting-Service: {{mds.appConfig?.broadcastingService.status}} + <span *ngIf="mds.appConfig?.broadcastingService.version"> + - Version {{mds.appConfig?.broadcastingService.version}}, + {{mds.appConfig?.broadcastingService.versionExpected}} erforderlich </span> </li> <li>Verona Player Interface: Version {{veronaApiVersionSupported}}</li> diff --git a/src/app/app-root/status-card/status-card.component.ts b/src/app/app-root/status-card/status-card.component.ts index 81d56d6a..8f1a459c 100644 --- a/src/app/app-root/status-card/status-card.component.ts +++ b/src/app/app-root/status-card/status-card.component.ts @@ -14,7 +14,6 @@ export class StatusCardComponent implements OnInit { @Inject('APP_NAME') public appName: string, @Inject('APP_PUBLISHER') public appPublisher: string, @Inject('APP_VERSION') public appVersion: string, - @Inject('API_VERSION_EXPECTED') public apiVersionExpected: string, @Inject('VERONA_API_VERSION_SUPPORTED') public veronaApiVersionSupported: string, @Inject('IS_PRODUCTION_MODE') public isProductionMode: boolean, public mds: MainDataService diff --git a/src/app/app.component.html b/src/app/app.component.html index bbcf9e37..e3190250 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,6 +1,6 @@ <div class="logo"> <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Zur Startseite" alt="IQB-logo"/> + <img [src]="mds.appConfig?.mainLogo" matTooltip="Zur Startseite" alt="IQB-logo"/> </a> </div> diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9d87de3a..79bfba9a 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,11 +1,13 @@ import { - Component, Inject, OnDestroy, OnInit + Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { CustomtextService } from 'iqb-components'; +import { DomSanitizer } from '@angular/platform-browser'; import { MainDataService } from './maindata.service'; import { BackendService } from './backend.service'; import { AppError } from './app.interfaces'; +import { AppConfig } from './config/app.config'; @Component({ selector: 'tc-root', @@ -14,7 +16,6 @@ import { AppError } from './app.interfaces'; export class AppComponent implements OnInit, OnDestroy { private appErrorSubscription: Subscription = null; - showError = false; errorData: AppError; @@ -23,49 +24,15 @@ export class AppComponent implements OnInit, OnDestroy { public mds: MainDataService, private bs: BackendService, private cts: CustomtextService, - @Inject('API_VERSION_EXPECTED') private readonly expectedApiVersion: string + private sanitizer: DomSanitizer ) { } - private static isValidVersion(expectedVersion: string, reportedVersion: string): boolean { - if (expectedVersion) { - const searchPattern = /\d+/g; - const expectedVersionNumbers = expectedVersion.match(searchPattern); - if (expectedVersionNumbers) { - if (reportedVersion) { - const reportedVersionNumbers = reportedVersion.match(searchPattern); - if (reportedVersionNumbers) { - if (reportedVersionNumbers[0] !== expectedVersionNumbers[0]) { - return false; - } - if (expectedVersionNumbers.length > 1) { - if ((reportedVersionNumbers.length < 2) || +reportedVersionNumbers[1] < +expectedVersionNumbers[1]) { - return false; - } - if ((expectedVersionNumbers.length > 2) && reportedVersionNumbers[1] === expectedVersionNumbers[1]) { - if ((reportedVersionNumbers.length < 3) || +reportedVersionNumbers[2] < +expectedVersionNumbers[2]) { - return false; - } - } - } - } else { - return false; - } - } else { - return false; - } - } - } - return true; - } - closeErrorBox(): void { this.showError = false; } ngOnInit(): void { setTimeout(() => { - this.mds.appConfig.setDefaultCustomTexts(); - this.appErrorSubscription = this.mds.appError$.subscribe(err => { if (err && !this.mds.errorReportingSilent) { this.errorData = err; @@ -86,33 +53,28 @@ export class AppComponent implements OnInit, OnDestroy { this.setupFocusListeners(); this.bs.getSysConfig().subscribe(sysConfig => { + this.mds.appConfig = new AppConfig(sysConfig, this.cts, this.mds.expectedApiVersion, this.sanitizer); if (!sysConfig) { - this.mds.isApiValid = false; // push on this.mds.appError$ ? + this.mds.appError$.next({ + label: 'Server-Problem: Konnte Konfiguration nicht laden', + description: 'getSysConfig ist fehlgeschlagen', + category: 'FATAL' + }); return; } - this.cts.addCustomTexts(sysConfig.customTexts); const authData = MainDataService.getAuthData(); if (authData) { this.cts.addCustomTexts(authData.customTexts); } - if (sysConfig.broadcastingService && sysConfig.broadcastingService.status) { - this.mds.broadcastingServiceInfo = sysConfig.broadcastingService; - } - this.mds.isApiValid = AppComponent.isValidVersion(this.expectedApiVersion, sysConfig.version); - this.mds.apiVersion = sysConfig.version; - - if (!this.mds.isApiValid) { + if (!this.mds.appConfig.isValidApiVersion) { this.mds.appError$.next({ label: 'Server-Problem: API-Version ungültig', - description: `erwartet: ${this.expectedApiVersion}, gefunden: ${sysConfig.version}`, + description: + `erwartet: ${this.mds.expectedApiVersion}, gefunden: ${this.mds.appConfig.detectedApiVersion}`, category: 'FATAL' }); } - - // TODO implement SysConfig.mainLogo - - this.mds.setTestConfig(sysConfig.testConfig); }); this.bs.getSysCheckInfo().subscribe(sysCheckConfigs => { diff --git a/src/app/app.interceptor.ts b/src/app/app.interceptor.ts index 74713da0..79e1e1bb 100644 --- a/src/app/app.interceptor.ts +++ b/src/app/app.interceptor.ts @@ -19,7 +19,7 @@ export class AuthInterceptor implements HttpInterceptor { // TODO separation of concerns: split into two interceptors, // one for error handling, one for auth token addition intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { - if (this.mds.isApiValid) { + if (!this.mds.appConfig || this.mds.appConfig.isValidApiVersion) { let tokenStr = ''; const authData = MainDataService.getAuthData(); if (authData) { diff --git a/src/app/config/app.config.ts b/src/app/config/app.config.ts index c33ec354..85e821de 100644 --- a/src/app/config/app.config.ts +++ b/src/app/config/app.config.ts @@ -1,4 +1,5 @@ import { CustomtextService } from 'iqb-components'; +import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import customTextsDefault from './custom-texts.json'; import { KeyValuePairs } from '../app.interfaces'; @@ -9,6 +10,13 @@ export interface SysConfig { testConfig: KeyValuePairs; serverTimestamp: number; broadcastingService: BroadCastingServiceInfo; + app_title: string; + background_color: string; + intro_html: string; + impressum_html: string; + global_warning: string; + global_warning_expired_day: Date; + global_warning_expired_hour: number; } export interface BroadCastingServiceInfo { @@ -17,17 +25,91 @@ export interface BroadCastingServiceInfo { versionExpected?: string; } +export const localStorageTestConfigKey = 'iqb-tc-c'; + export class AppConfig { + customTexts: KeyValuePairs = {}; + detectedApiVersion = ''; + mainLogo = 'assets/IQB-LogoA.png'; + testConfig: KeyValuePairs = {}; + serverTimestamp = 0; + broadcastingService: BroadCastingServiceInfo = { status: 'none' }; + app_title = 'IQB-Testcenter'; + background_color: string; + intro_html = 'Einführungstext nicht definiert'; + trusted_intro_html: SafeUrl = null; + impressum_html = 'Impressum/Datenschutz nicht definiert'; + trusted_impressum_html: SafeUrl = null; + global_warning = ''; + global_warning_expired_day: Date; + global_warning_expired_hour: number; + isValidApiVersion = false; + constructor( - private cts: CustomtextService + sysConfig: SysConfig, + cts: CustomtextService, + expectedApiVersion: string, + sanitizer: DomSanitizer ) { + const ctSettings = {}; + Object.keys(customTextsDefault).forEach(k => { + ctSettings[k] = customTextsDefault[k].defaultvalue; + if (k === 'app_title') this.app_title = customTextsDefault[k].defaultvalue; + }); + if (sysConfig) { + Object.keys(sysConfig.customTexts).forEach(k => { + ctSettings[k] = sysConfig.customTexts[k]; + if (k === 'app_title') this.app_title = sysConfig.customTexts[k]; + }); + if (sysConfig.app_title) this.app_title = sysConfig.app_title; + if (sysConfig.mainLogo) this.mainLogo = sysConfig.mainLogo; + this.background_color = sysConfig.background_color; + this.isValidApiVersion = AppConfig.checkApiVersion(sysConfig.version, expectedApiVersion); + this.detectedApiVersion = sysConfig.version; + if (sysConfig.intro_html) this.intro_html = sysConfig.intro_html; + if (sysConfig.impressum_html) this.impressum_html = sysConfig.impressum_html; + this.global_warning = sysConfig.global_warning; + this.global_warning_expired_day = sysConfig.global_warning_expired_day; + this.global_warning_expired_hour = sysConfig.global_warning_expired_hour; + this.testConfig = sysConfig.testConfig; + this.serverTimestamp = sysConfig.serverTimestamp; + if (sysConfig.broadcastingService && sysConfig.broadcastingService.status) { + this.broadcastingService = sysConfig.broadcastingService; + } + } + cts.addCustomTexts(ctSettings); + this.trusted_intro_html = sanitizer.bypassSecurityTrustHtml(this.intro_html); + this.trusted_impressum_html = sanitizer.bypassSecurityTrustHtml(this.impressum_html); + if (this.testConfig) { + localStorage.setItem(localStorageTestConfigKey, JSON.stringify(this.testConfig)); + } else { + localStorage.removeItem(localStorageTestConfigKey); + } } - setDefaultCustomTexts(): void { - const ctDefaults = {}; - Object.keys(customTextsDefault).forEach(key => { - ctDefaults[key] = customTextsDefault[key].defaultvalue; - }); - this.cts.addCustomTexts(ctDefaults); + private static checkApiVersion(versionToCheck: string, expectedVersion: string): boolean { + if (!expectedVersion || !versionToCheck) { + return false; + } + const searchPattern = /\d+/g; + const expectedVersionNumbers = expectedVersion.match(searchPattern); + const reportedVersionNumbers = versionToCheck.match(searchPattern); + if (expectedVersionNumbers && reportedVersionNumbers) { + if (reportedVersionNumbers[0] !== expectedVersionNumbers[0]) { + return false; + } + if (expectedVersionNumbers.length > 1) { + if ((reportedVersionNumbers.length < 2) || +reportedVersionNumbers[1] < +expectedVersionNumbers[1]) { + return false; + } + if ((expectedVersionNumbers.length > 2) && reportedVersionNumbers[1] === expectedVersionNumbers[1]) { + if ((reportedVersionNumbers.length < 3) || +reportedVersionNumbers[2] < +expectedVersionNumbers[2]) { + return false; + } + } + } + return true; + } + return false; } } diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts index 6d5c7f31..86199785 100644 --- a/src/app/maindata.service.ts +++ b/src/app/maindata.service.ts @@ -1,15 +1,13 @@ -import { Injectable } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { BehaviorSubject, Subject } from 'rxjs'; import { CustomtextService } from 'iqb-components'; import { AppError, AuthData, KeyValuePairs } from './app.interfaces'; -import { BackendService } from './backend.service'; -import { AppConfig, BroadCastingServiceInfo } from './config/app.config'; +import { AppConfig, localStorageTestConfigKey } from './config/app.config'; const localStorageAuthDataKey = 'iqb-tc-a'; -const localStorageTestConfigKey = 'iqb-tc-c'; @Injectable({ providedIn: 'root' @@ -20,9 +18,6 @@ export class MainDataService { errorReportingSilent = false; isSpinnerOn$ = new BehaviorSubject<boolean>(false); progressVisualEnabled = true; - isApiValid = true; - apiVersion: string; - broadcastingServiceInfo: BroadCastingServiceInfo = { status: 'none' }; appConfig: AppConfig = null; sysCheckAvailable = false; @@ -74,11 +69,9 @@ export class MainDataService { } constructor( - private bs: BackendService, + @Inject('API_VERSION_EXPECTED') readonly expectedApiVersion: string, private cts: CustomtextService - ) { - this.appConfig = new AppConfig(cts); - } + ) { } setSpinnerOn(): void { this.isSpinnerOn$.next(true); @@ -98,12 +91,4 @@ export class MainDataService { localStorage.removeItem(localStorageAuthDataKey); } } - - setTestConfig(testConfig: KeyValuePairs = null): void { - if (testConfig) { - localStorage.setItem(localStorageTestConfigKey, JSON.stringify(testConfig)); - } else { - localStorage.removeItem(localStorageTestConfigKey); - } - } } -- GitLab