diff --git a/src/app/app-root/admin-starter/admin-starter.component.html b/src/app/app-root/admin-starter/admin-starter.component.html
index f7a4e9bfd9e65a6ec9075711fef205551e30926b..29cee951d5c9e7a9b901125eaaea8617e88d7322 100644
--- a/src/app/app-root/admin-starter/admin-starter.component.html
+++ b/src/app/app-root/admin-starter/admin-starter.component.html
@@ -1,6 +1,7 @@
 <div fxLayout="row wrap" fxLayoutAlign="center stretch">
   <mat-card fxFlex="0 0 400px" fxLayout="column">
-    <mat-card-title>Verwaltung: Bitte Studie wählen</mat-card-title>
+    <mat-card-title>Verwaltung</mat-card-title>
+    <mat-card-subtitle>Bitte Arbeitsbereich wählen</mat-card-subtitle>
     <mat-card-content>
       <div fxLayoutGap="10px" fxLayout="column">
         <p *ngIf="workspaces.length === 0">
@@ -19,7 +20,7 @@
   </mat-card>
 
   <mat-card fxFlex="0 0 400px" class="mat-card-gray">
-    <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }}</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
 
     <mat-card-content>
 
diff --git a/src/app/app-root/admin-starter/admin-starter.component.ts b/src/app/app-root/admin-starter/admin-starter.component.ts
index 56e9bd8dd6ba4a23155f198ca29274591b3ae46d..ce891c06c31bd76b79acf4e5d2800440d4053d43 100644
--- a/src/app/app-root/admin-starter/admin-starter.component.ts
+++ b/src/app/app-root/admin-starter/admin-starter.component.ts
@@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
 import { from, Subscription } from 'rxjs';
 import { concatMap } from 'rxjs/operators';
-import { CustomtextService } from 'iqb-components';
 import { BackendService } from '../../backend.service';
 import { AuthAccessKeyType, AuthData, WorkspaceData } from '../../app.interfaces';
 import { MainDataService } from '../../maindata.service';
@@ -23,11 +22,12 @@ export class AdminStarterComponent implements OnInit, OnDestroy {
   constructor(
     private router: Router,
     private bs: BackendService,
-    private mds: MainDataService
+    public mds: MainDataService
   ) { }
 
   ngOnInit(): void {
     setTimeout(() => {
+      this.mds.appSubTitle$.next('Verwaltung: Bitte Arbeitsbereich wählen');
       this.mds.setSpinnerOn();
       this.bs.getSessionData().subscribe(authDataUntyped => {
         if (this.getWorkspaceDataSubscription !== null) {
diff --git a/src/app/app-root/code-input/code-input.component.html b/src/app/app-root/code-input/code-input.component.html
index d1f68c750a321c8b64a9b357ff2b4a8f3d6bb152..78f511012fef4b725cba2188d3dbd3ddff1767c1 100644
--- a/src/app/app-root/code-input/code-input.component.html
+++ b/src/app/app-root/code-input/code-input.component.html
@@ -17,7 +17,7 @@
   </mat-card>
 
   <mat-card fxFlex="0 0 400px" class="mat-card-gray">
-    <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }}</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
 
     <mat-card-content>
 
diff --git a/src/app/app-root/code-input/code-input.component.ts b/src/app/app-root/code-input/code-input.component.ts
index 9e7a606affb04a32f564a7169d07f40669a46f9a..60b37bf747200695c36508ceb25cae5a0cd6be1c 100644
--- a/src/app/app-root/code-input/code-input.component.ts
+++ b/src/app/app-root/code-input/code-input.component.ts
@@ -35,6 +35,7 @@ export class CodeInputComponent implements OnInit {
   // eslint-disable-next-line class-methods-use-this
   ngOnInit(): void {
     setTimeout(() => {
+      this.mds.appSubTitle$.next('Bitte Code eingeben');
       const element = <HTMLElement>document.querySelector('.mat-input-element[formControlName="code"]');
       if (element) {
         element.focus();
diff --git a/src/app/app-root/login/login.component.html b/src/app/app-root/login/login.component.html
index 86a68e274e00c7dbd7be7d68175651cc44c77fb6..803f31d85d5ea78b89897010d3f03de89a76dabc 100644
--- a/src/app/app-root/login/login.component.html
+++ b/src/app/app-root/login/login.component.html
@@ -27,7 +27,7 @@
   </mat-card>
 
   <mat-card fxFlex="0 0 400px" class="mat-card-gray">
-    <mat-card-title>{{ 'IQB-Testcenter' | customtext:'app_title' | async }}</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
 
     <mat-card-content>
       <div [innerHTML]="mds.appConfig?.trusted_intro_html"></div>
diff --git a/src/app/app-root/login/login.component.ts b/src/app/app-root/login/login.component.ts
index 568e7886a3b97a12764592430769e466339c9236..6c47e4cbe3eb539d4f8563a9725fc4ef31bfedcb 100644
--- a/src/app/app-root/login/login.component.ts
+++ b/src/app/app-root/login/login.component.ts
@@ -41,6 +41,7 @@ export class LoginComponent implements OnInit, OnDestroy {
 
   ngOnInit(): void {
     this.mds.setSpinnerOff();
+    this.mds.appSubTitle$.next('Bitte Anmelden');
     this.routingSubscription = this.route.params
       .subscribe(params => { this.returnTo = params.returnTo; });
     this.systemAnnouncementSubscription = <Subscription> this.cts.getCustomText$('system_announcement')
diff --git a/src/app/app-root/monitor-starter/monitor-starter.component.html b/src/app/app-root/monitor-starter/monitor-starter.component.html
index fd26c5d1a39c0c6784345fa3c3e13402af691722..44c714647659ba6bac8380c2ae946f88373a9903 100644
--- a/src/app/app-root/monitor-starter/monitor-starter.component.html
+++ b/src/app/app-root/monitor-starter/monitor-starter.component.html
@@ -31,7 +31,7 @@
   </mat-card>
 
   <mat-card fxFlex="0 0 400px" class="mat-card-gray">
-    <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }}</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
 
     <mat-card-content>
 
diff --git a/src/app/app-root/monitor-starter/monitor-starter.component.ts b/src/app/app-root/monitor-starter/monitor-starter.component.ts
index fc91475b685b3418cdb2c31c9b81b68de1903f78..82623d6f123254aa82e8b8ac163243370d796a31 100644
--- a/src/app/app-root/monitor-starter/monitor-starter.component.ts
+++ b/src/app/app-root/monitor-starter/monitor-starter.component.ts
@@ -16,18 +16,19 @@ import {
 export class MonitorStarterComponent implements OnInit, OnDestroy {
   accessObjects: { [accessType: string]: (AccessObject|BookletData)[] } = {};
   private getMonitorDataSubscription: Subscription = null;
-  public AuthAccessKeyType = AuthAccessKeyType;
-  public problemText: string;
+  AuthAccessKeyType = AuthAccessKeyType;
+  problemText: string;
 
   constructor(
     private router: Router,
     private bs: BackendService,
     public cts: CustomtextService,
-    private mds: MainDataService
+    public mds: MainDataService
   ) { }
 
   ngOnInit(): void {
     setTimeout(() => {
+      this.mds.appSubTitle$.next(this.cts.getCustomText('gm_headline'));
       this.mds.setSpinnerOn();
       this.bs.getSessionData().subscribe(authDataUntyped => {
         if (typeof authDataUntyped === 'number') {
diff --git a/src/app/app-root/privacy/privacy.component.html b/src/app/app-root/privacy/privacy.component.html
index 622dcce13a5b90ad36e3d9ea9732fb3f8f0ca2fe..c6c61cbb4bb6b7367ed5573c4acab8709bd27d7f 100644
--- a/src/app/app-root/privacy/privacy.component.html
+++ b/src/app/app-root/privacy/privacy.component.html
@@ -1,7 +1,7 @@
 <div class="root-body">
   <div fxLayout="row" fxLayoutAlign="center start">
     <mat-card fxFlex="0 0 500px">
-      <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }} - Impressum/Datenschutz</mat-card-title>
+      <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
 
       <!-- - - - - - - - - - - - - - - - - -->
       <mat-card-content>
diff --git a/src/app/app-root/privacy/privacy.component.ts b/src/app/app-root/privacy/privacy.component.ts
index a974ca1e658f02c9424f1825c74a8a3db4ccb53e..42352e90e430d7ad5d6de03be7a391d6f1f72b54 100644
--- a/src/app/app-root/privacy/privacy.component.ts
+++ b/src/app/app-root/privacy/privacy.component.ts
@@ -1,4 +1,4 @@
-import { Component, Inject } from '@angular/core';
+import { Component, Inject, OnInit } from '@angular/core';
 import { MainDataService } from '../../maindata.service';
 
 @Component({
@@ -7,7 +7,7 @@ import { MainDataService } from '../../maindata.service';
     'mat-card {margin: 10px}'
   ]
 })
-export class PrivacyComponent {
+export class PrivacyComponent implements OnInit {
   constructor(
     @Inject('APP_NAME') public appName: string,
     @Inject('APP_PUBLISHER') public appPublisher: string,
@@ -16,4 +16,8 @@ export class PrivacyComponent {
     @Inject('IS_PRODUCTION_MODE') public isProductionMode: boolean,
     public mds: MainDataService
   ) { }
+
+  ngOnInit(): void {
+    setTimeout(() => this.mds.appSubTitle$.next('Impressum/Datenschutz'));
+  }
 }
diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.html b/src/app/app-root/sys-check-starter/sys-check-starter.component.html
index 5c3adfa30c05a1367b56923858c9762d673a3cc5..cd0d1110e19c6cb8e2a6c3bf6b55903bb75f07a1 100644
--- a/src/app/app-root/sys-check-starter/sys-check-starter.component.html
+++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.html
@@ -1,6 +1,6 @@
 <div fxLayout="row wrap" fxLayoutAlign="center stretch">
   <mat-card fxFlex="0 2 500px">
-    <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }}: System-Check</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</mat-card-title>
     <mat-card-content>
       <p>Hier können Sie ermitteln, ob das Computersystem, das Sie gerade benutzen, für
         die hier vorgesehenen Testungen geeignet ist.</p>
diff --git a/src/app/app-root/sys-check-starter/sys-check-starter.component.ts b/src/app/app-root/sys-check-starter/sys-check-starter.component.ts
index 627724c8927db8d05bf492cfd15447225cb13028..2cd1896c283886c17f66c9db0a496913d261563e 100644
--- a/src/app/app-root/sys-check-starter/sys-check-starter.component.ts
+++ b/src/app/app-root/sys-check-starter/sys-check-starter.component.ts
@@ -20,6 +20,7 @@ export class SysCheckStarterComponent implements OnInit {
 
   ngOnInit(): void {
     setTimeout(() => {
+      this.mds.appSubTitle$.next('System-Check Auswahl');
       this.loading = true;
       this.mds.setSpinnerOn();
       this.bs.getSysCheckInfo().subscribe(myConfigs => {
diff --git a/src/app/app-root/test-starter/test-starter.component.html b/src/app/app-root/test-starter/test-starter.component.html
index 6409ec52d08eef83cac3c8294e9c8ca584476329..7ac76759176b2b6727af5278331e3f958eb647f5 100644
--- a/src/app/app-root/test-starter/test-starter.component.html
+++ b/src/app/app-root/test-starter/test-starter.component.html
@@ -17,7 +17,7 @@
   </mat-card>
 
   <mat-card fxFlex="0 0 400px" class="mat-card-gray">
-    <mat-card-title>{{ 'app_title' | customtext:'app_title' | async }}</mat-card-title>
+    <mat-card-title>{{mds.appTitle$ | async}}</mat-card-title>
 
     <mat-card-content>
       <p *ngIf="openTestletsCount === 0">{{ 'login_bookletSelectPromptNull' | customtext: 'login_bookletSelectPromptNull' | async}}</p>
diff --git a/src/app/app-root/test-starter/test-starter.component.ts b/src/app/app-root/test-starter/test-starter.component.ts
index 19d16889f34fbb79c9d758833e9ce384831c5306..8caa9ef238b560cd5134cfe5966c9de819325330 100644
--- a/src/app/app-root/test-starter/test-starter.component.ts
+++ b/src/app/app-root/test-starter/test-starter.component.ts
@@ -15,17 +15,19 @@ export class TestStarterComponent implements OnInit, OnDestroy {
   booklets: BookletData[] = [];
   openTestletsCount = 0;
   private getBookletDataSubscription: Subscription = null;
-  public bookletSelectTitle = 'Bitte wählen';
+  bookletSelectTitle = 'Bitte wählen';
   problemText = '';
 
   constructor(
     private router: Router,
     private bs: BackendService,
-    private mds: MainDataService
+    private cts:CustomtextService,
+    public mds: MainDataService
   ) { }
 
   ngOnInit(): void {
     setTimeout(() => {
+      this.mds.appSubTitle$.next('');
       this.mds.setSpinnerOn();
       this.bs.getSessionData().subscribe(authDataUntyped => {
         if (typeof authDataUntyped !== 'number') {
@@ -53,6 +55,13 @@ export class TestStarterComponent implements OnInit, OnDestroy {
                     },
                     () => {
                       this.problemText = this.booklets.length ? '' : 'Für diese Anmeldung wurde kein Test gefunden.';
+                      if (this.openTestletsCount <= 0) {
+                        this.mds.appSubTitle$.next(this.cts.getCustomText('login_bookletSelectPromptNull'));
+                      } else if (this.openTestletsCount === 1) {
+                        this.mds.appSubTitle$.next(this.cts.getCustomText('login_bookletSelectPromptOne'));
+                      } else {
+                        this.mds.appSubTitle$.next(this.cts.getCustomText('login_bookletSelectPromptMany'));
+                      }
                       this.mds.setSpinnerOff();
                     }
                   );
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 79bfba9a09cff3c42fb54b7be7229e26ebe951a8..9f195da13493ced0b8a037f3a6e7edba809ccad7 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,9 +1,9 @@
 import {
   Component, OnDestroy, OnInit
 } from '@angular/core';
-import { Subscription } from 'rxjs';
+import { Subscription, combineLatest } from 'rxjs';
 import { CustomtextService } from 'iqb-components';
-import { DomSanitizer } from '@angular/platform-browser';
+import { DomSanitizer, Title } from '@angular/platform-browser';
 import { MainDataService } from './maindata.service';
 import { BackendService } from './backend.service';
 import { AppError } from './app.interfaces';
@@ -16,6 +16,7 @@ import { AppConfig } from './config/app.config';
 
 export class AppComponent implements OnInit, OnDestroy {
   private appErrorSubscription: Subscription = null;
+  private appTitleSubscription: Subscription = null;
   showError = false;
 
   errorData: AppError;
@@ -24,6 +25,7 @@ export class AppComponent implements OnInit, OnDestroy {
     public mds: MainDataService,
     private bs: BackendService,
     private cts: CustomtextService,
+    private titleService: Title,
     private sanitizer: DomSanitizer
   ) { }
 
@@ -39,6 +41,16 @@ export class AppComponent implements OnInit, OnDestroy {
           this.showError = true;
         }
       });
+      this.appTitleSubscription = combineLatest([this.mds.appTitle$, this.mds.appSubTitle$, this.mds.isSpinnerOn$])
+        .subscribe(titles => {
+          if (titles[2]) {
+            this.titleService.setTitle(`${titles[0]} | Bitte warten}`);
+          } else if (titles[1]) {
+            this.titleService.setTitle(`${titles[0]} | ${titles[1]}`);
+          } else {
+            this.titleService.setTitle(titles[0]);
+          }
+        });
 
       window.addEventListener('message', (event: MessageEvent) => {
         const msgData = event.data;
@@ -54,6 +66,7 @@ export class AppComponent implements OnInit, OnDestroy {
 
       this.bs.getSysConfig().subscribe(sysConfig => {
         this.mds.appConfig = new AppConfig(sysConfig, this.cts, this.mds.expectedApiVersion, this.sanitizer);
+        this.mds.appTitle$.next(this.mds.appConfig.app_title);
         if (!sysConfig) {
           this.mds.appError$.next({
             label: 'Server-Problem: Konnte Konfiguration nicht laden',
@@ -122,5 +135,8 @@ export class AppComponent implements OnInit, OnDestroy {
     if (this.appErrorSubscription !== null) {
       this.appErrorSubscription.unsubscribe();
     }
+    if (this.appTitleSubscription !== null) {
+      this.appTitleSubscription.unsubscribe();
+    }
   }
 }
diff --git a/src/app/config/custom-texts.json b/src/app/config/custom-texts.json
index 402445d94afae200f366a06a7dc2e00964d26cd4..9f108446e21527fd4572fa84b259e31230aa175e 100644
--- a/src/app/config/custom-texts.json
+++ b/src/app/config/custom-texts.json
@@ -118,7 +118,7 @@
 
   "gm_headline": {
     "label": "Ãœberschrift: Gruppenmonitor",
-    "defaultvalue": "IQB-Testcenter Gruppenüberwachung"
+    "defaultvalue": "Gruppenüberwachung"
   },
   "gm_menu_filter": {
     "label": "Meinueintrag: Sitzungen ausblenden",
diff --git a/src/app/group-monitor/group-monitor.component.html b/src/app/group-monitor/group-monitor.component.html
index 24772dbe5640fdb3144ffabb0711a982466f95b1..b66d586333abb60139efc0868dde9ee61a270621 100644
--- a/src/app/group-monitor/group-monitor.component.html
+++ b/src/app/group-monitor/group-monitor.component.html
@@ -1,6 +1,6 @@
 <div class="page-header">
   <p>
-    {{'IQB-Testcenter Gruppenüberwachung' | customtext:'gm_headline' | async}} -
+    {{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}} -
     <span *ngIf="ownGroup$ | async as ownGroup">{{ownGroup.label}}</span>
   </p>
   <span class="fill-remaining-space"></span>
diff --git a/src/app/group-monitor/group-monitor.component.ts b/src/app/group-monitor/group-monitor.component.ts
index 588814aced396de30791c54ca5320b30aefd17d2..a21da6d7d4b8eea4e37a5a6e74fe871fe1e9757b 100644
--- a/src/app/group-monitor/group-monitor.component.ts
+++ b/src/app/group-monitor/group-monitor.component.ts
@@ -19,6 +19,7 @@ import {
 import { TestSessionManager } from './test-session-manager/test-session-manager.service';
 import { ConnectionStatus } from '../shared/websocket-backend.service';
 import { BookletUtil } from './booklet/booklet.util';
+import { MainDataService } from '../maindata.service';
 
 @Component({
   selector: 'app-group-monitor',
@@ -60,7 +61,8 @@ export class GroupMonitorComponent implements OnInit, OnDestroy {
     private bs: BackendService,
     public tsm: TestSessionManager,
     private router: Router,
-    private cts: CustomtextService
+    private cts: CustomtextService,
+    public mds: MainDataService
   ) {}
 
   ngOnInit(): void {
@@ -85,6 +87,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy {
     ];
 
     this.connectionStatus$ = this.bs.connectionStatus$;
+    this.mds.appSubTitle$.next(this.cts.getCustomText('gm_headline'));
   }
 
   private commandResponseToMessage(commandResponse: CommandResponse): UIMessage {
diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts
index 86199785880fd1c5c6d003e4c020d5b387125ddb..39dc280e9108a5c2ca8316e482eaf5e43b219d7d 100644
--- a/src/app/maindata.service.ts
+++ b/src/app/maindata.service.ts
@@ -20,6 +20,8 @@ export class MainDataService {
   progressVisualEnabled = true;
   appConfig: AppConfig = null;
   sysCheckAvailable = false;
+  appTitle$ = new BehaviorSubject<string>('IQB-Testcenter');
+  appSubTitle$ = new BehaviorSubject<string>('');
 
   defaultTcHeaderHeight = document.documentElement.style.getPropertyValue('--tc-header-height');
   defaultTcUnitTitleHeight = document.documentElement.style.getPropertyValue('--tc-unit-title-height');
diff --git a/src/app/superadmin/superadmin.component.html b/src/app/superadmin/superadmin.component.html
index 81c55274caa62899ba46b52a2d321ef6eb894223..6ac1b29ec291a0142564421811e16b3948c207fc 100644
--- a/src/app/superadmin/superadmin.component.html
+++ b/src/app/superadmin/superadmin.component.html
@@ -1,5 +1,5 @@
 <div class="page-header">
-  <p>IQB-Testcenter Systemverwaltung</p>
+  <p>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</p>
 </div>
 
 <div class="page-body">
diff --git a/src/app/superadmin/superadmin.component.ts b/src/app/superadmin/superadmin.component.ts
index 79b415bf91610b4f4abbb37bc6188f4859b46879..c802b3675313c91c77f288d25ad9c1c8137152a0 100644
--- a/src/app/superadmin/superadmin.component.ts
+++ b/src/app/superadmin/superadmin.component.ts
@@ -1,17 +1,21 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 import { MainDataService } from '../maindata.service';
 
 @Component({
   templateUrl: './superadmin.component.html',
   styleUrls: ['./superadmin.component.css']
 })
-export class SuperadminComponent {
+export class SuperadminComponent implements OnInit {
   constructor(
     public mds: MainDataService
   ) { }
 
-  public navLinks = [
+  navLinks = [
     { path: 'users', label: 'Users' },
     { path: 'workspaces', label: 'Arbeitsbereiche' }
   ];
+
+  ngOnInit():void {
+    setTimeout(() => this.mds.appSubTitle$.next('Systemverwaltung'));
+  }
 }
diff --git a/src/app/sys-check/sys-check.component.ts b/src/app/sys-check/sys-check.component.ts
index a81c5c47c476f5ccd68212e6085d78f2eaab045a..2d083fc7b6659d95c57fcfc7e791c2a098b07128 100644
--- a/src/app/sys-check/sys-check.component.ts
+++ b/src/app/sys-check/sys-check.component.ts
@@ -23,6 +23,7 @@ export class SysCheckComponent implements OnInit {
   }
 
   ngOnInit(): void {
+    setTimeout(() => this.mds.appSubTitle$.next('System-Check'));
     this.route.paramMap.subscribe((params: ParamMap) => {
       const sysCheckId = params.get('sys-check-name');
       const workspaceId = parseInt(params.get('workspace-id'), 10);
@@ -32,6 +33,7 @@ export class SysCheckComponent implements OnInit {
           this.ds.checkConfig = checkConfig;
           if (checkConfig) {
             this.checkLabel = checkConfig.label;
+            this.mds.appSubTitle$.next(`System-Check ${this.checkLabel}`);
             if (checkConfig.customTexts.length > 0) {
               const myCustomTexts: { [key: string]: string } = {};
               checkConfig.customTexts.forEach(ct => {
diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts
index 6d1f3668647d4bade0bfe38df84a1b32d99506f2..7756408206a5d79f714a25778fc5fe782409469f 100644
--- a/src/app/test-controller/unithost/unithost.component.ts
+++ b/src/app/test-controller/unithost/unithost.component.ts
@@ -4,7 +4,6 @@ import {
 } from '@angular/core';
 import { ActivatedRoute } from '@angular/router';
 
-import { CustomtextService } from 'iqb-components';
 import {
   PageData,
   TestStateKey,
@@ -26,10 +25,10 @@ export class UnithostComponent implements OnInit, OnDestroy {
   private iFrameHostElement: HTMLElement;
   private iFrameItemplayer: HTMLIFrameElement;
   private routingSubscription: Subscription = null;
-  public leaveWarning = false;
+  leaveWarning = false;
 
-  public unitTitle = '';
-  public showPageNav = false;
+  unitTitle = '';
+  showPageNav = false;
 
   private myUnitSequenceId = -1;
   private myUnitDbKey = '';
@@ -39,7 +38,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
   private postMessageTarget: Window = null;
   private pendingUnitData: PendingUnitData = null;
 
-  public pageList: PageData[] = [];
+  pageList: PageData[] = [];
   private knownPages: string[];
 
   constructor(
@@ -49,7 +48,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
     private route: ActivatedRoute
   ) { }
 
-  ngOnInit() {
+  ngOnInit(): void {
     setTimeout(() => {
       this.postMessageSubscription = this.mds.postMessage$.subscribe((m: MessageEvent) => {
         const msgData = m.data;
@@ -118,7 +117,8 @@ export class UnithostComponent implements OnInit, OnDestroy {
                   const { unitState } = msgData;
                   const { presentationProgress } = unitState;
                   if (presentationProgress) {
-                    this.tcs.updateUnitStatePresentationProgress(this.myUnitDbKey, this.myUnitSequenceId, presentationProgress);
+                    this.tcs.updateUnitStatePresentationProgress(this.myUnitDbKey,
+                      this.myUnitSequenceId, presentationProgress);
                   }
                   const { responseProgress } = unitState;
                   if (responseProgress) {
@@ -170,7 +170,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
       this.routingSubscription = this.route.params.subscribe(params => {
         this.myUnitSequenceId = Number(params.u);
         this.tcs.currentUnitSequenceId = this.myUnitSequenceId;
-
+        this.mds.appSubTitle$.next(`Seite ${this.myUnitSequenceId}`);
         while (this.iFrameHostElement.hasChildNodes()) {
           this.iFrameHostElement.removeChild(this.iFrameHostElement.lastChild);
         }
@@ -201,8 +201,10 @@ export class UnithostComponent implements OnInit, OnDestroy {
 
           this.pendingUnitData = {
             playerId: this.itemplayerSessionId,
-            unitDefinition: this.tcs.hasUnitDefinition(this.myUnitSequenceId) ? this.tcs.getUnitDefinition(this.myUnitSequenceId) : null,
-            unitState: this.tcs.hasUnitStateData(this.myUnitSequenceId) ? this.tcs.getUnitStateData(this.myUnitSequenceId) : null
+            unitDefinition: this.tcs.hasUnitDefinition(this.myUnitSequenceId) ?
+              this.tcs.getUnitDefinition(this.myUnitSequenceId) : null,
+            unitState: this.tcs.hasUnitStateData(this.myUnitSequenceId) ?
+              this.tcs.getUnitStateData(this.myUnitSequenceId) : null
           };
           this.leaveWarning = false;
           this.iFrameHostElement.appendChild(this.iFrameItemplayer);
@@ -213,7 +215,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
   }
 
   @HostListener('window:resize')
-  public onResize(): any {
+  onResize(): any {
     if (this.iFrameItemplayer && this.iFrameHostElement) {
       const divHeight = this.iFrameHostElement.clientHeight;
       this.iFrameItemplayer.setAttribute('height', String(divHeight - 5));
@@ -221,7 +223,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
     }
   }
 
-  setPageList(validPages: string[], currentPage: string) {
+  setPageList(validPages: string[], currentPage: string): void {
     if ((validPages instanceof Array)) {
       this.knownPages = validPages.length ? validPages : [];
       const newPageList: PageData[] = [];
@@ -277,7 +279,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
     this.showPageNav = this.pageList.length > 0;
   }
 
-  gotoPage(action: string, index = 0) {
+  gotoPage(action: string, index = 0): void {
     let nextPageId = '';
     // currentpage is detected by disabled-attribute of page
     if (action === '#next') {
@@ -320,7 +322,7 @@ export class UnithostComponent implements OnInit, OnDestroy {
     }
   }
 
-  ngOnDestroy() {
+  ngOnDestroy(): void {
     if (this.routingSubscription !== null) {
       this.routingSubscription.unsubscribe();
     }
diff --git a/src/app/workspace-admin/workspace.component.html b/src/app/workspace-admin/workspace.component.html
index 8bd3f2db9d742240fff08a0fa71e2812b3b20ffe..cd0da9fcc3f3d1cb9993ea4bf11412fa8a9453b2 100644
--- a/src/app/workspace-admin/workspace.component.html
+++ b/src/app/workspace-admin/workspace.component.html
@@ -1,5 +1,5 @@
 <div class="page-header">
-  <p>IQB-Testcenter Verwaltung: {{wds.wsName}} ({{ wds.wsRole }})</p>
+  <p>{{mds.appTitle$ | async}} {{mds.appSubTitle$ | async}}</p>
 </div>
 
 <div class="page-body">
diff --git a/src/app/workspace-admin/workspace.component.ts b/src/app/workspace-admin/workspace.component.ts
index 8350007ece833e15a26d7704b565a960a31cd5eb..3f176136203e00cb03e016aa396528068815951a 100644
--- a/src/app/workspace-admin/workspace.component.ts
+++ b/src/app/workspace-admin/workspace.component.ts
@@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router';
 import { Subscription } from 'rxjs';
 import { WorkspaceDataService } from './workspacedata.service';
 import { BackendService } from './backend.service';
+import { MainDataService } from '../maindata.service';
 
 @Component({
   templateUrl: './workspace.component.html',
@@ -14,17 +15,22 @@ export class WorkspaceComponent implements OnInit, OnDestroy {
   constructor(
     private route: ActivatedRoute,
     private bs: BackendService,
+    public mds: MainDataService,
     public wds: WorkspaceDataService
   ) { }
 
   ngOnInit(): void {
-    this.routingSubscription = this.route.params.subscribe(params => {
-      this.wds.wsId = params.ws;
-      this.bs.getWorkspaceData(this.wds.wsId).subscribe(wsData => {
-        if (typeof wsData !== 'number') {
-          this.wds.wsName = wsData.name;
-          this.wds.wsRole = wsData.role;
-        }
+    setTimeout(() => {
+      this.mds.appSubTitle$.next('');
+      this.routingSubscription = this.route.params.subscribe(params => {
+        this.wds.wsId = params.ws;
+        this.bs.getWorkspaceData(this.wds.wsId).subscribe(wsData => {
+          if (typeof wsData !== 'number') {
+            this.wds.wsName = wsData.name;
+            this.wds.wsRole = wsData.role;
+            this.mds.appSubTitle$.next(`Verwaltung "${this.wds.wsName}" (${this.wds.wsRole})`);
+          }
+        });
       });
     });
   }