diff --git a/src/app/test-controller/test-config.json b/src/app/test-controller/test-config.json new file mode 100644 index 0000000000000000000000000000000000000000..8fa928c1e1c06c90744e10c5dec96ad81c8007cb --- /dev/null +++ b/src/app/test-controller/test-config.json @@ -0,0 +1,65 @@ +{ + "loading_mode": { + "label": "Ladeverhalten beim Start", + "options": { + "LAZY": "Start sobald wie möglich, Laden im Hintergrund fortsetzen", + "EAGER": "Testheft erst dann starten, wenn alle Inhalte geladen sind" + }, + "defaultvalue": "LAZY" + }, + "log_mode": { + "label": "Erfassen und Speichern von Log-Daten", + "options": { + "OFF": "Ausgeschaltet", + "LEAN": "Nur wichtige Meldungen", + "RICH": "Alles" + }, + "defaultvalue": "RICH" + }, + "page_navibuttons": { + "label": "Navigationsbuttons für die Seitennavigation (innerhalb einer Aufgabe)", + "options": { + "OFF": "Keine Seitennavigation unterstützen (übernimmt ggf. die Aufgabe selbst)", + "MERGED": "Die Seitennavigation wird durch die Aufgabennavigation mit übernommen", + "SEPARATE_TOP": "Seitennavigation über getrennte Button-Leiste - oben", + "SEPARATE_BOTTOM": "Seitennavigation über getrennte Button-Leiste - unten" + }, + "defaultvalue": "SEPARATE_BOTTOM" + }, + "unit_navibuttons": { + "label": "Navigationsbuttons für die Navigation zwischen den Aufgaben", + "options": { + "OFF": "Keine Buttons für Aufgabennavigation anzeigen (übernimmt ggf. die Aufgabe selbst)", + "ARROWS_ONLY": "Nur die Buttons für 'Weiter' und 'Zurück' anzeigen", + "FULL": "Buttons für 'Weiter' und 'Zurück' und dazwischen kleine Buttons für jede Aufgabe anzeigen" + }, + "defaultvalue": "FULL" + }, + "unit_menu": { + "label": "Extra-Seite mit großen Buttons für Aufgaben zum direkten Springen", + "options": { + "OFF": "Ausgeschaltet", + "ENABLED_ONLY": "Eingeschaltet - nur die Aufgaben anzeigen, die noch freigegeben sind", + "FULL": "Eingeschaltet - auch die Aufgaben anzeigen, die nicht mehr freigegeben sind (gegraut)" + }, + "defaultvalue": "ENABLED_ONLY" + }, + "force_presentation_complete": { + "label": "Verhalten, wenn noch nicht alle Elemente der Aufgabe angezeigt wurden", + "options": { + "OFF": "Ignorieren - Weiterblättern möglich", + "ON": "Weiterblättern verhindern, bis Anzeige vollständig" + }, + "defaultvalue": "OFF" + }, + "force_responses_complete": { + "label": "Verhalten, wenn noch nicht alle Antworten der Aufgabe vollständig gegeben wurden", + "options": { + "OFF": "Ignorieren - Weiterblättern möglich", + "SOME": "Weiterblättern erst möglich, wenn einige Antworten gegeben wurden", + "COMPLETE": "Weiterblättern erst möglich, wenn alle Antworten gegeben wurden", + "COMPLETE_AND_VALID": "Weiterblättern erst möglich, wenn alle Antworten gegeben wurden und als gültig eingeschätzt wurden" + }, + "defaultvalue": "OFF" + } +} diff --git a/src/app/test-controller/test-config.ts b/src/app/test-controller/test-config.ts new file mode 100644 index 0000000000000000000000000000000000000000..3235b527116fb3edec16586f8d60ca0126d46824 --- /dev/null +++ b/src/app/test-controller/test-config.ts @@ -0,0 +1,134 @@ +// @ts-ignore +import testConfigDefinition from './test-config.json'; +import {RunModeKey} from "./test-controller.interfaces"; + +export class TestConfig { + definition = testConfigDefinition; + loading_mode: "LAZY" | "EAGER" = testConfigDefinition.loading_mode.defaultvalue; + log_mode: "OFF" | "LEAN" | "RICH" = testConfigDefinition.log_mode.defaultvalue; + page_navibuttons: "OFF" | "MERGED" | "SEPARATE_TOP" | "SEPARATE_BOTTOM" = testConfigDefinition.page_navibuttons.defaultvalue; + unit_navibuttons: "OFF" | "ARROWS_ONLY" | "FULL" = testConfigDefinition.unit_navibuttons.defaultvalue; + unit_menu: "OFF" | "ENABLED_ONLY" | "FULL" = testConfigDefinition.unit_menu.defaultvalue; + force_presentation_complete: "ON" | "OFF" = testConfigDefinition.force_presentation_complete.defaultvalue; + force_responses_complete: "OFF" | "SOME" | "COMPLETE" | "COMPLETE_AND_VALID" = testConfigDefinition.force_responses_complete.defaultvalue; + + // default for RunModeKey.DEMO + canReview = false; + saveResponses = false; + forceTimeRestrictions = false; + forceNaviRestrictions = false; + presetCode = true; + showTimeLeft = true; + modeLabel = "Demo"; + + constructor(loginMode: RunModeKey = RunModeKey.DEMO) { + if (loginMode !== RunModeKey.DEMO) { + switch (loginMode) { + case RunModeKey.HOT_RESTART: + case RunModeKey.HOT_RETURN: + this.canReview = false; + this.saveResponses = true; + this.forceTimeRestrictions = true; + this.forceNaviRestrictions = true; + this.presetCode = false; + this.showTimeLeft = false; + this.modeLabel = "Durchführung Test/Befragung"; + break; + case RunModeKey.REVIEW: + this.canReview = true; + this.saveResponses = false; + this.forceTimeRestrictions = false; + this.forceNaviRestrictions = false; + this.presetCode = true; + this.showTimeLeft = true; + this.modeLabel = "Prüfdurchgang ohne Speichern"; + break; + case RunModeKey.TRIAL: + this.canReview = true; + this.saveResponses = true; + this.forceTimeRestrictions = true; + this.forceNaviRestrictions = true; + this.presetCode = true; + this.showTimeLeft = false; + this.modeLabel = "Prüfdurchgang mit Speichern"; + break; + default: + console.error("TestConfig: invalid test mode '" + loginMode + "'") + } + } + } + + public setFromKeyValuePairs(config) { + if (config) { + if (config['loading_mode']) { this.loading_mode = config['loading_mode']} + if (config['log_mode']) { this.log_mode = config['log_mode']} + if (config['page_navibuttons']) { this.page_navibuttons = config['page_navibuttons']} + if (config['unit_navibuttons']) { this.unit_navibuttons = config['unit_navibuttons']} + if (config['unit_menu']) { this.unit_menu = config['unit_menu']} + if (config['force_presentation_complete']) { this.force_presentation_complete = config['force_presentation_complete']} + if (config['force_responses_complete']) { this.force_responses_complete = config['force_responses_complete']} + } + } + + public setFromXml(bookletConfigElement: Element) { + if (bookletConfigElement) { + const bookletConfigs = TestConfig.getChildElements(bookletConfigElement); + for (let childIndex = 0; childIndex < bookletConfigs.length; childIndex++) { + const configParameter = bookletConfigs[childIndex].getAttribute('parameter'); + + switch (bookletConfigs[childIndex].nodeName) { + // ---------------------- + case 'NavPolicy': + if (configParameter) { + if (configParameter.toUpperCase() === 'NextOnlyIfPresentationComplete'.toUpperCase()) { + this.force_presentation_complete = "ON" + } + } + break; + case 'NavButtons': + if (configParameter) { + switch (configParameter.toUpperCase()) { + case 'ON': + this.unit_navibuttons = "FULL"; + break; + case 'OFF': + this.unit_navibuttons = "OFF"; + break; + case 'ARROWSONLY': + this.unit_navibuttons = "ARROWS_ONLY"; + break; + } + } + break; + case 'PageNavBar': + if (configParameter) { + if (configParameter.toUpperCase() === 'OFF') { + this.page_navibuttons = "OFF" + } + } + break; + case 'Logging': + if (configParameter) { + if (configParameter.toUpperCase() === 'OFF') { + this.log_mode = "OFF" + } + } + break; + case 'Loading': + if (configParameter) { + if (configParameter.toUpperCase() === 'EAGER') { + this.loading_mode = "EAGER" + } + } + break; + } + } + } + } + + private static getChildElements(element) { + return Array.prototype.slice.call(element.childNodes) + .filter(function (e) { return e.nodeType === 1; }); + } + +} diff --git a/src/app/test-controller/test-controller-route-guards.guard.spec.ts b/src/app/test-controller/test-controller-route-guards.spec.ts similarity index 94% rename from src/app/test-controller/test-controller-route-guards.guard.spec.ts rename to src/app/test-controller/test-controller-route-guards.spec.ts index e41e876d2684ca251047ed004af08413045a8331..6b271beffd05c874397793572736478f028de60f 100644 --- a/src/app/test-controller/test-controller-route-guards.guard.spec.ts +++ b/src/app/test-controller/test-controller-route-guards.spec.ts @@ -1,6 +1,6 @@ import { TestBed } from '@angular/core/testing'; -import { TestControllerDeactivateGuard } from './test-controller-route-guards.guard'; +import { TestControllerDeactivateGuard } from './test-controller-route-guards'; describe('TestControllerDeactivateGuard', () => { let guard: TestControllerDeactivateGuard; diff --git a/src/app/test-controller/test-controller-route-guards.guard.ts b/src/app/test-controller/test-controller-route-guards.ts similarity index 100% rename from src/app/test-controller/test-controller-route-guards.guard.ts rename to src/app/test-controller/test-controller-route-guards.ts diff --git a/src/app/test-controller/test-controller-routing.module.ts b/src/app/test-controller/test-controller-routing.module.ts index 7906b38acc1bc06c6ef89c066c5a0997b69c7492..25a74a43659d661756911ffb0b8df70a1b8e6059 100644 --- a/src/app/test-controller/test-controller-routing.module.ts +++ b/src/app/test-controller/test-controller-routing.module.ts @@ -4,7 +4,7 @@ import { TestControllerComponent } from './test-controller.component'; import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import {TestStatusComponent} from "./test-status/test-status.component"; -import {TestControllerDeactivateGuard} from "./test-controller-route-guards.guard"; +import {TestControllerDeactivateGuard} from "./test-controller-route-guards"; diff --git a/src/app/test-controller/test-controller.component.html b/src/app/test-controller/test-controller.component.html index c6322092570e194b7b32231d7574eedac0d94562..2abf9cc90828d516528a168e278d9d8e6984ac43 100644 --- a/src/app/test-controller/test-controller.component.html +++ b/src/app/test-controller/test-controller.component.html @@ -3,13 +3,13 @@ <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> </a> <div fxLayout="row" fxLayoutAlign="end center"> - <p class="timer" *ngIf="(tcs.mode !== runModeKey.HOT_RESTART) && (tcs.mode !== runModeKey.HOT_RETURN)">{{ timerValue?.timeLeftString }}</p> - <button mat-fab [disabled]="!(tcs.unitPrevEnabled$ | async)" *ngIf="tcs.navArrows && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" + <p class="timer" *ngIf="tcs.testConfig.showTimeLeft">{{ timerValue?.timeLeftString }}</p> + <button mat-fab [disabled]="!tcs.unitPrevEnabled" *ngIf="(tcs.testConfig.unit_navibuttons !== 'OFF') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.PREVIOUS)" matTooltip="Zurück" fxFlex="none"> <i class="material-icons">chevron_left</i> </button> - <div *ngIf="tcs.navButtons && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="0 3 100%"> - <div *ngFor="let u of (tcs.unitListForNaviButtons$ | async)"> + <div *ngIf="(tcs.testConfig.unit_navibuttons === 'FULL') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" fxLayout="row wrap" fxLayoutAlign="start center" fxFlex="0 3 100%"> + <div *ngFor="let u of tcs.unitListForNaviButtons"> <div fxLayout="column" fxLayoutAlign="start center"> <button (click)="tcs.setUnitNavigationRequest(u.sequenceId.toString())" class="unit-button" [disabled]="u.disabled">{{ u.shortLabel }}</button> <span class="current-unit-dot" *ngIf="u.isCurrent"></span> @@ -17,15 +17,15 @@ </div> </div> </div> - <button mat-fab [disabled]="!(tcs.unitNextEnabled$ | async)" *ngIf="tcs.navArrows && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" + <button mat-fab [disabled]="!tcs.unitNextEnabled" *ngIf="(tcs.testConfig.unit_navibuttons !== 'OFF') && ((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING)" color="accent" (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.NEXT)" matTooltip="Weiter" fxFlex="none"> <i class="material-icons">chevron_right</i> </button> - <button mat-button (click)="showReviewDialog()" *ngIf="tcs.mode === runModeKey.REVIEW" matTooltip="Kommentar senden" fxFlex="none"> + <button mat-button (click)="showReviewDialog()" *ngIf="tcs.testConfig.canReview" matTooltip="Kommentar senden" fxFlex="none"> <mat-icon>rate_review</mat-icon> </button> <button mat-button (click)="tcs.setUnitNavigationRequest(unitNavigationTarget.MENU)" - *ngIf="(tcs.mode !== runModeKey.HOT_RESTART) && (tcs.mode !== runModeKey.HOT_RETURN)" + *ngIf="tcs.testConfig.unit_menu !== 'OFF'" matTooltip="Zur Aufgabenliste" fxFlex="none"> <mat-icon>menu</mat-icon> </button> diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts index d8c9b96b925c5abf8e614cc4230676624708d6fb..5e8675a5abc52191172f05978eea20f738cf15ac 100644 --- a/src/app/test-controller/test-controller.component.ts +++ b/src/app/test-controller/test-controller.component.ts @@ -23,6 +23,7 @@ import {concatMap, map, switchMap} from 'rxjs/operators'; import {CustomtextService} from 'iqb-components'; import {MatDialog} from "@angular/material/dialog"; import {MatSnackBar} from '@angular/material/snack-bar'; +import {TestConfig} from "./test-config"; @Component({ @@ -153,7 +154,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { // '''''''''''''''''''''''''''''''''''''''''''''''''''' // private: reading booklet from xml // '''''''''''''''''''''''''''''''''''''''''''''''''''' - private getBookletFromXml(xmlString: string): Testlet { + private getBookletFromXml(xmlString: string, loginMode: RunModeKey): Testlet { let rootTestlet: Testlet = null; try { @@ -186,73 +187,9 @@ export class TestControllerComponent implements OnInit, OnDestroy { const bookletConfigElements = oDOM.documentElement.getElementsByTagName('BookletConfig'); + this.tcs.testConfig = new TestConfig(loginMode); // TODO: standard test config if (bookletConfigElements.length > 0) { - const bookletConfigs = TestControllerComponent.getChildElements(bookletConfigElements[0]); - for (let childIndex = 0; childIndex < bookletConfigs.length; childIndex++) { - const configParameter = bookletConfigs[childIndex].getAttribute('parameter'); - // const configValue = bookletConfigs[childIndex].textContent; - - switch (bookletConfigs[childIndex].nodeName) { - // ---------------------- - case 'NavPolicy': - if (configParameter) { - if (configParameter.toUpperCase() === 'NextOnlyIfPresentationComplete'.toUpperCase()) { - this.tcs.navPolicyNextOnlyIfPresentationComplete = true; - } - } - break; - // ---------------------- - case 'NavButtons': - if (configParameter) { - switch (configParameter.toUpperCase()) { - case 'ON': - this.tcs.navButtons = true; - this.tcs.navArrows = true; - break; - case 'OFF': - this.tcs.navButtons = false; - this.tcs.navArrows = false; - break; - case 'ARROWSONLY': // default - this.tcs.navButtons = false; - this.tcs.navArrows = true; - break; - default: - console.log('unknown booklet configParameter NavButtons "' + configParameter + '"'); - break; - } - } - break; - // ---------------------- - case 'PageNavBar': - if (configParameter) { - if (configParameter.toUpperCase() === 'OFF') { - this.tcs.pageNav = false; - } - } - break; - // ---------------------- - case 'Logging': - if (configParameter) { - if (configParameter.toUpperCase() === 'OFF') { - this.tcs.logging = false; - } - } - break; - // ---------------------- - case 'Loading': - if (configParameter) { - if (configParameter.toUpperCase() === 'EAGER') { - this.tcs.lazyloading = false; - } - } - break; - // ---------------------- - default: - console.log('unknown booklet config "' + bookletConfigs[childIndex].nodeName + '"'); - break; - } - } + this.tcs.testConfig.setFromXml(bookletConfigElements[0]); } // recursive call through all testlets @@ -383,7 +320,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { this.tcs.setBookletState(LastStateKey.MAXTIMELEFT, JSON.stringify(this.tcs.LastMaxTimerState)); this.timerRunning = false; this.timerValue = null; - if (this.tcs.mode !== 'run-review') { + if (this.tcs.testConfig.forceTimeRestrictions) { this.tcs.setUnitNavigationRequest(UnitNavigationTarget.NEXT); } } else if (maxTimerData.type === MaxTimerDataType.CANCELLED) { @@ -426,7 +363,6 @@ export class TestControllerComponent implements OnInit, OnDestroy { this.tcs.setUnitNavigationRequest(UnitNavigationTarget.ERROR); } else { const testData = testDataUntyped as TestData; - this.tcs.mode = testData.mode; let navTarget = 1; if (testData.laststate !== null) { @@ -441,7 +377,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { } } - this.tcs.rootTestlet = this.getBookletFromXml(testData.xml); + this.tcs.rootTestlet = this.getBookletFromXml(testData.xml, testData.mode as RunModeKey); if (this.tcs.rootTestlet === null) { this.mds.appError$.next({ @@ -487,7 +423,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { this.unitLoadBlobSubscription = from(this.unitLoadQueue).pipe( concatMap(queueEntry => { const unitSequ = Number(queueEntry.tag); - if (!this.tcs.lazyloading) { + if (this.tcs.testConfig.loading_mode === "EAGER") { this.incrementProgressValueBy1(); } // avoid to load unit def if not necessary @@ -524,14 +460,14 @@ export class TestControllerComponent implements OnInit, OnDestroy { this.loadProgressValue = 100; this.tcs.loadComplete = true; - if (!this.tcs.lazyloading) { + if (this.tcs.testConfig.loading_mode === "EAGER") { this.tcs.testStatus$.next(TestStatus.RUNNING); this.tcs.setUnitNavigationRequest(navTarget.toString()); } } ); - if (this.tcs.lazyloading) { + if (this.tcs.testConfig.loading_mode === "LAZY") { this.tcs.testStatus$.next(TestStatus.RUNNING); console.log(navTarget); diff --git a/src/app/test-controller/test-controller.interfaces.ts b/src/app/test-controller/test-controller.interfaces.ts index fdd0c4cf058f1fb84c7c8c3f19a08e7e8dee759d..06eb153878dd7eb507f01f4624c935d2858ff8ea 100644 --- a/src/app/test-controller/test-controller.interfaces.ts +++ b/src/app/test-controller/test-controller.interfaces.ts @@ -104,6 +104,7 @@ export enum RunModeKey { HOT_RESTART = "run-hot-restart", TRIAL = "run-trial", REVIEW = "run-review", + DEMO = "demo" } export enum MaxTimerDataType { diff --git a/src/app/test-controller/test-controller.service.ts b/src/app/test-controller/test-controller.service.ts index 5c45a09edfe0a175ab47d82c6a4f1aaf78d63248..31864284098256f160cc421e2c39592f0291a72f 100644 --- a/src/app/test-controller/test-controller.service.ts +++ b/src/app/test-controller/test-controller.service.ts @@ -1,13 +1,12 @@ import {debounceTime, map, switchMap, takeUntil} from 'rxjs/operators'; import {BehaviorSubject, interval, Subject, Subscription, timer} from 'rxjs'; import {Injectable} from '@angular/core'; -import {BookletConfig, MaxTimerData, Testlet} from './test-controller.classes'; +import {MaxTimerData, Testlet} from './test-controller.classes'; import { KeyValuePairNumber, LastStateKey, LogEntryKey, MaxTimerDataType, - RunModeKey, TestStatus, UnitNaviButtonData, UnitNavigationTarget, @@ -16,6 +15,7 @@ import { } from './test-controller.interfaces'; import {BackendService} from './backend.service'; import {Router} from "@angular/router"; +import {TestConfig} from "./test-config"; @Injectable({ providedIn: 'root' @@ -26,16 +26,10 @@ export class TestControllerService { public testStatusEnum = TestStatus; public loadComplete = false; - private standardBookletConfig: BookletConfig = { - showMainNaviButtons: true - }; - public bookletConfig$ = new BehaviorSubject<BookletConfig>(this.standardBookletConfig); + public testConfig = new TestConfig(); public rootTestlet: Testlet = null; public maxUnitSequenceId = 0; public minUnitSequenceId = 0; - public mode = ''; - public logging = true; - public lazyloading = true; public maxTimeTimer$ = new Subject<MaxTimerData>(); public currentMaxTimerTestletId = ''; @@ -44,21 +38,17 @@ export class TestControllerService { private _currentUnitSequenceId: number; public currentUnitDbKey = ''; public currentUnitTitle = ''; - public unitPrevEnabled$ = new BehaviorSubject<boolean>(false); - public unitNextEnabled$ = new BehaviorSubject<boolean>(false); - public unitListForNaviButtons$ = new BehaviorSubject<UnitNaviButtonData[]>([]); - public navPolicyNextOnlyIfPresentationComplete = false; - public navButtons = false; - public navArrows = true; - public pageNav = true; + public unitPrevEnabled = false; + public unitNextEnabled = false; + public unitListForNaviButtons: UnitNaviButtonData[] = []; public get currentUnitSequenceId(): number { return this._currentUnitSequenceId; } public set currentUnitSequenceId(v: number) { - this.unitPrevEnabled$.next(v > this.minUnitSequenceId); - this.unitNextEnabled$.next(v < this.maxUnitSequenceId); - if (this.rootTestlet && this.navButtons) { + this.unitPrevEnabled = v > this.minUnitSequenceId; + this.unitNextEnabled = v < this.maxUnitSequenceId; + if (this.rootTestlet && (this.testConfig.unit_navibuttons !== 'OFF') ) { const myUnitListForNaviButtons: UnitNaviButtonData[] = []; for (let sequ = 1; sequ <= this.rootTestlet.getMaxSequenceId(); sequ++) { const myUnitData = this.rootTestlet.getUnitAt(sequ); @@ -74,7 +64,7 @@ export class TestControllerService { }); } } - this.unitListForNaviButtons$.next(myUnitListForNaviButtons); + this.unitListForNaviButtons = myUnitListForNaviButtons; } this._currentUnitSequenceId = v; } @@ -120,31 +110,23 @@ export class TestControllerService { // 7777777777777777777777777777777777777777777777777777777777777777777777 public resetDataStore() { - this.bookletConfig$.next(this.standardBookletConfig); this.players = {}; this.unitDefinitions = {}; this.unitRestorePoints = {}; this.rootTestlet = null; this.maxUnitSequenceId = 0; - this.mode = ''; - this.logging = true; this.currentUnitSequenceId = 0; this.currentUnitDbKey = ''; this.currentUnitTitle = ''; - this.unitPrevEnabled$.next(false); - this.unitNextEnabled$.next(false); + this.unitPrevEnabled = false; + this.unitNextEnabled = false; if (this.maxTimeIntervalSubscription !== null) { this.maxTimeIntervalSubscription.unsubscribe(); this.maxTimeIntervalSubscription = null; } this.currentMaxTimerTestletId = ''; this.LastMaxTimerState = {}; - this.unitListForNaviButtons$.next([]); - this.navPolicyNextOnlyIfPresentationComplete = false; - this.navButtons = false; - this.navArrows = true; - this.pageNav = true; - this.lazyloading = true; + this.unitListForNaviButtons = []; // this.dataLoading = false; TODO set test status? // this.bookletLoadComplete = false; } @@ -211,8 +193,7 @@ export class TestControllerService { // 7777777777777777777777777777777777777777777777777777777777777777777777 public addBookletLog(logKey: LogEntryKey, entry = '') { - if ((this.mode !== 'run-review') && this.logging) { - + if (this.testConfig.saveResponses) { const entryData = entry.length > 0 ? logKey + ': ' + JSON.stringify(entry) : logKey; this.bs.addBookletLog(this.testId, Date.now(), entryData).subscribe(ok => { if (!ok) { @@ -222,7 +203,7 @@ export class TestControllerService { } } public setBookletState(stateKey: LastStateKey, state: string) { - if (this.mode !== 'run-review') { + if (this.testConfig.saveResponses) { this.bs.setBookletState(this.testId, stateKey, state).subscribe(ok => { if (!ok) { console.warn('setBookletState failed'); @@ -231,7 +212,7 @@ export class TestControllerService { } } public addUnitLog(unitDbKey: string, logKey: LogEntryKey, entry = '') { - if ((this.mode !== 'run-review') && this.logging) { + if (this.testConfig.saveResponses) { this.bs.addUnitLog(this.testId, Date.now(), unitDbKey, entry.length > 0 ? logKey + ': ' + JSON.stringify(entry) : logKey).subscribe(ok => { if (!ok) { @@ -241,7 +222,7 @@ export class TestControllerService { } } public newUnitResponse(unitDbKey: string, response: string, responseType: string) { - if (this.mode !== 'run-review') { + if (this.testConfig.saveResponses) { this.responsesToSave$.next({ unitDbKey: unitDbKey, response: response, @@ -251,7 +232,7 @@ export class TestControllerService { } public newUnitRestorePoint(unitDbKey: string, unitSequenceId: number, restorePoint: string, postToServer: boolean) { this.unitRestorePoints[unitSequenceId] = restorePoint; - if (postToServer && this.mode !== 'run-review') { + if (postToServer && this.testConfig.saveResponses) { this.restorePointsToSave$.next({ unitDbKey: unitDbKey, restorePoint: restorePoint @@ -260,7 +241,7 @@ export class TestControllerService { } public newUnitStatePresentationComplete(unitDbKey: string, unitSequenceId: number, presentationComplete: string) { this.unitPresentationCompleteStates[unitSequenceId] = presentationComplete; - if (this.mode !== 'run-review') { + if (this.testConfig.saveResponses) { this.addUnitLog(unitDbKey, LogEntryKey.PRESENTATIONCOMPLETE, presentationComplete); this.bs.setUnitState(this.testId, unitDbKey, LastStateKey.PRESENTATIONCOMPLETE, presentationComplete).subscribe(ok => { if (!ok) { @@ -270,7 +251,7 @@ export class TestControllerService { } } public newUnitStateResponsesGiven(unitDbKey: string, unitSequenceId: number, responsesGiven: string) { - if (this.mode !== 'run-review') { + if (this.testConfig.saveResponses) { this.addUnitLog(unitDbKey, LogEntryKey.RESPONSESCOMPLETE, responsesGiven); } } @@ -317,7 +298,7 @@ export class TestControllerService { } public terminateTest() { - if (this.mode && this.mode !== RunModeKey.REVIEW) { + if (this.testConfig.saveResponses) { this.bs.addBookletLog(this.testId, Date.now(), 'BOOKLETLOCKEDbyTESTEE').pipe( switchMap(() => { return this.bs.lockBooklet(this.testId) diff --git a/src/app/test-controller/test-status/test-status.component.html b/src/app/test-controller/test-status/test-status.component.html index af6b2d987a8648802cc4a0782e26ddc7419f6056..73cc1f0deb4ec3e5bdc83cbc3847a415f02b09b3 100644 --- a/src/app/test-controller/test-status/test-status.component.html +++ b/src/app/test-controller/test-status/test-status.component.html @@ -1,6 +1,6 @@ <div class="status-body"> <div fxLayout="row wrap" fxLayoutAlign="center stretch"> - <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING) && ((tcs.unitListForNaviButtons$ | async)?.length > 0)"> + <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="((tcs.testStatus$ | async) === tcs.testStatusEnum.RUNNING) && (tcs.unitListForNaviButtons.length > 0)"> <mat-card-title>{{ 'Aufgaben' | customtext:'booklet_tasklisttitle':cts.updateCount }}</mat-card-title> <mat-card-content> <div fxLayoutGap="10px" fxLayout="column" fxLayoutAlign="center stretch"> diff --git a/src/app/test-controller/test-status/test-status.component.ts b/src/app/test-controller/test-status/test-status.component.ts index 8b45fc8279aaf38c4e37c264794472496a2e1f4f..7187fee22651b25212d3b033863371692a39f15d 100644 --- a/src/app/test-controller/test-status/test-status.component.ts +++ b/src/app/test-controller/test-status/test-status.component.ts @@ -27,18 +27,16 @@ export class TestStatusComponent implements OnInit, OnDestroy { this.routingSubscription = this.route.params.subscribe(params => { this.flag = params['f']; }); - this.unitMenuButtonListSubscription = this.tcs.unitListForNaviButtons$.subscribe(unitList => { - this.unitMenuButtonList = []; - for (let unitIndex = 0; unitIndex < unitList.length; unitIndex++) { - if (!unitList[unitIndex].disabled && unitList[unitIndex].longLabel.trim()) { - this.unitMenuButtonList.push({ - sequenceId: unitList[unitIndex].sequenceId, - label: unitList[unitIndex].longLabel, - isCurrent: unitList[unitIndex].isCurrent - }) - } + this.unitMenuButtonList = []; + for (let unitIndex = 0; unitIndex < this.tcs.unitListForNaviButtons.length; unitIndex++) { + if (!this.tcs.unitListForNaviButtons[unitIndex].disabled && this.tcs.unitListForNaviButtons[unitIndex].longLabel.trim()) { + this.unitMenuButtonList.push({ + sequenceId: this.tcs.unitListForNaviButtons[unitIndex].sequenceId, + label: this.tcs.unitListForNaviButtons[unitIndex].longLabel, + isCurrent: this.tcs.unitListForNaviButtons[unitIndex].isCurrent + }) } - }) + } }) } diff --git a/src/app/test-controller/unithost/unit-route-guards.ts b/src/app/test-controller/unithost/unit-route-guards.ts index 43aee19dd83ac169c7fcd802b7a06a5f59d09513..1fe8dd5de4d7b7495ff08cd24976a9671c547077 100644 --- a/src/app/test-controller/unithost/unit-route-guards.ts +++ b/src/app/test-controller/unithost/unit-route-guards.ts @@ -10,7 +10,6 @@ import {UnitControllerData} from '../test-controller.classes'; import { CodeInputData, LogEntryKey, - RunModeKey, StartLockData } from '../test-controller.interfaces'; import {MainDataService} from 'src/app/maindata.service'; @@ -32,7 +31,7 @@ export class UnitActivateGuard implements CanActivate { checkAndSolve_PresentationCompleteCode(newUnit: UnitControllerData): Observable<Boolean> { - if (this.tcs.navPolicyNextOnlyIfPresentationComplete && this.tcs.currentUnitSequenceId > 0) { + if ((this.tcs.testConfig.force_presentation_complete === 'ON') && this.tcs.currentUnitSequenceId > 0) { if (this.tcs.currentUnitSequenceId < newUnit.unitDef.sequenceId) { // go forwards =================================== let myreturn = true; @@ -53,7 +52,7 @@ export class UnitActivateGuard implements CanActivate { if (myreturn) { return of(true); } else { - if (this.tcs.mode === RunModeKey.HOT_RESTART || this.tcs.mode === RunModeKey.HOT_RETURN) { + if (this.tcs.testConfig.forceNaviRestrictions) { const dialogCDRef = this.confirmDialog.open(ConfirmDialogComponent, { width: '500px', // height: '300px', @@ -85,7 +84,7 @@ export class UnitActivateGuard implements CanActivate { if (myreturn) { return of(true); } else { - if (this.tcs.mode === RunModeKey.HOT_RESTART || this.tcs.mode === RunModeKey.HOT_RETURN) { + if (this.tcs.testConfig.forceNaviRestrictions) { const dialogCDRef = this.confirmDialog.open(ConfirmDialogComponent, { width: '500px', // height: '300px', @@ -120,7 +119,7 @@ export class UnitActivateGuard implements CanActivate { testletId: t.id, prompt: t.codePrompt, code: t.codeToEnter.toUpperCase().trim(), - value: (this.tcs.mode === RunModeKey.HOT_RETURN || this.tcs.mode === RunModeKey.HOT_RESTART) ? '' : t.codeToEnter + value: this.tcs.testConfig.presetCode ? t.codeToEnter : '' }); }); @@ -178,17 +177,14 @@ export class UnitActivateGuard implements CanActivate { // **************************************************************************************** checkAndSolve_DefLoaded(newUnit: UnitControllerData): Observable<Boolean> { - console.log('#1'); if (this.tcs.loadComplete) { - console.log('#2'); return of(true); } else { - console.log('#3'); if (this.tcs.currentUnitSequenceId < newUnit.unitDef.sequenceId) { // 1 going forwards - if ((newUnit.maxTimerRequiringTestlet === null) || (this.tcs.mode === 'run-review')) { + if ((newUnit.maxTimerRequiringTestlet === null) || (!this.tcs.testConfig.forceNaviRestrictions)) { // 1 a) target is not in timed block or review mode --> check only target unit diff --git a/src/app/test-controller/unithost/unithost.component.html b/src/app/test-controller/unithost/unithost.component.html index b890e7636670667713215cf7141c30383c56c4b5..e54847c482e8ee3fa65d6a5291e5e087ab169099 100644 --- a/src/app/test-controller/unithost/unithost.component.html +++ b/src/app/test-controller/unithost/unithost.component.html @@ -4,7 +4,7 @@ <div id="iFrameHost" iqbResizeIFrameChild class="unit-body"> </div> -<div id="pageNav" fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px" *ngIf="tcs.pageNav"> + <div id="pageNav" fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px" *ngIf="tcs.testConfig.page_navibuttons !== 'OFF'"> <div fxLayout="row" fxLayoutAlign="space-between center" *ngIf="showPageNav"> <div id="pageNavPrompt"> diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts index 10eceed37830c9c0f189061cabaf06d0ccdda4bc..ccc62001d7100c8c09d0247ccdf1ae0ead542e48 100644 --- a/src/app/test-controller/unithost/unithost.component.ts +++ b/src/app/test-controller/unithost/unithost.component.ts @@ -200,7 +200,7 @@ export class UnithostComponent implements OnInit, OnDestroy { } this.leaveWarning = false; - if (!this.tcs.pageNav) { + if (this.tcs.testConfig.page_navibuttons === 'OFF') { this.iFrameHostElement.style.bottom = '0px'; } @@ -267,11 +267,7 @@ export class UnithostComponent implements OnInit, OnDestroy { this.pageList[this.pageList.length - 1].disabled = false; } else { this.pageList[0].disabled = false; - if (currentPageIndex === this.pageList.length - 2) { - this.pageList[this.pageList.length - 1].disabled = true; - } else { - this.pageList[this.pageList.length - 1].disabled = false; - } + this.pageList[this.pageList.length - 1].disabled = currentPageIndex === this.pageList.length - 2; } } this.showPageNav = this.pageList.length > 0;