Skip to content
Snippets Groups Projects
Commit 2b7ebe60 authored by paf's avatar paf
Browse files

make all tests from group available for group-monitor as demo

parent 0cfa260d
No related branches found
No related tags found
No related merge requests found
...@@ -14,17 +14,18 @@ then switch on some restrictions and store responses, and finally evaluate the ...@@ -14,17 +14,18 @@ then switch on some restrictions and store responses, and finally evaluate the
test like a testtaker. test like a testtaker.
* `DEMO` (default): Nur Ansicht (Demo) * `DEMO` (default): Nur Ansicht (Demo)
* `MONITOR-GROUP`: Testgruppen-Monitor (Demo)
* `HOT`: Durchführung Test/Befragung * `HOT`: Durchführung Test/Befragung
* `REVIEW`: Prüfdurchgang ohne Speichern * `REVIEW`: Prüfdurchgang ohne Speichern
* `TRIAL`: Prüfdurchgang mit Speichern * `TRIAL`: Prüfdurchgang mit Speichern
| | `DEMO` | `HOT` | `REVIEW` | `TRIAL` | | | `DEMO` | `MONITOR-GROUP` | `HOT` | `REVIEW` | `TRIAL` |
| :------------- | :-------------: | :-------------: | :-------------: | :-------------: | | :------------- | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: |
|Es können Reviews abgegeben werden (Kommentare/Einschätzungen zur Unit bzw. zum Test)| | |X | | |Es können Reviews abgegeben werden (Kommentare/Einschätzungen zur Unit bzw. zum Test)| | | |X | |
|Es werden Antworten und Logs gespeichert.| |X | |X | |Es werden Antworten und Logs gespeichert.| | |X | |X |
|Alle Zeitbeschränkungen für Testabschnitte werden angewendet.| |X | |X | |Alle Zeitbeschränkungen für Testabschnitte werden angewendet.| | |X | |X |
|Alle Navigationsbeschränkungen des Booklets werden angewendet (z. B. erst weiter, wenn vollständig angezeigt).| |X | |X | |Alle Navigationsbeschränkungen des Booklets werden angewendet (z. B. erst weiter, wenn vollständig angezeigt).| | |X | |X |
|Sollte ein Testabschnitt mit einem Freigabewort geschützt sein, wird dieses bei der Eingabebox schon eingetragen.|X | |X |X | |Sollte ein Testabschnitt mit einem Freigabewort geschützt sein, wird dieses bei der Eingabebox schon eingetragen.|X |X | |X |X |
|Sollte eine Maximalzeit für einen Testabschnitt festgelegt sein, wird die verbleibende Zeit angezeigt, auch wenn die Booklet-Konfiguration dies unterbindet.|X | |X | | |Sollte eine Maximalzeit für einen Testabschnitt festgelegt sein, wird die verbleibende Zeit angezeigt, auch wenn die Booklet-Konfiguration dies unterbindet.|X |X | |X | |
|Die Seite mit der Aufgaben-Übersicht wird erlaubt, auch wenn das Booklet dies unterbindet.| | |X | | |Die Seite mit der Aufgaben-Übersicht wird erlaubt, auch wenn das Booklet dies unterbindet.| | | |X | |
mat-card {
margin: 10px;
}
.mat-card-gray {
background-color: lightgray
}
.booklet_title {
display: block;
font-size: 16pt;
margin-top: 4px;
margin-bottom: 0;
white-space: pre-wrap;
word-break: break-word;
line-height: 130%;
}
.booklet_status {
display: block;
font-size: 8pt;
margin-top: 0;
color: mediumturquoise;
height: 24px;
margin-bottom: 18px;
}
...@@ -6,9 +6,18 @@ ...@@ -6,9 +6,18 @@
<p *ngIf="accessObjects.length === 0"> <p *ngIf="accessObjects.length === 0">
Sie sind angemeldet. Aktuell sind keine Testgruppen zur Überwachung für Sie freigegeben. Sie sind angemeldet. Aktuell sind keine Testgruppen zur Überwachung für Sie freigegeben.
</p> </p>
<p style="color: chocolate"><b>{{ problemText }}</b></p>
<button mat-raised-button color="primary" (click)="buttonGotoMonitor(accessObject)" <button mat-raised-button color="primary" (click)="buttonGotoMonitor(accessObject)"
*ngFor="let accessObject of accessObjects"> *ngFor="let accessObject of accessObjects[AuthAccessKeyType.TEST_GROUP_MONITOR]">
{{accessObject.name}} <span class="booklet_title">{{accessObject.name}}</span>
<span class="booklet_status">Überwachung starten</span>
</button>
<br>
<h4>Folgende Testhefte stehen für Sie zur Ansicht bereit:</h4>
<button mat-raised-button color="primary" (click)="startTest(b)" [disabled]="b.locked"
*ngFor="let b of accessObjects[AuthAccessKeyType.TEST]">
<span class="booklet_title">{{b.label}}</span>
<span class="booklet_status">{{b.locked ? 'gesperrt' : (b.running ? 'Fortsetzen' : 'Ansehen')}}</span>
</button> </button>
</div> </div>
</mat-card-content> </mat-card-content>
......
import { Component, OnDestroy, OnInit } from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import { from, Subscription } from 'rxjs'; import {from, Subscription} from 'rxjs';
import { Router } from '@angular/router'; import {Router} from '@angular/router';
import { concatMap } from 'rxjs/operators'; import {concatMap, map} from 'rxjs/operators';
import { CustomtextService } from 'iqb-components'; import {CustomtextService} from 'iqb-components';
import { BackendService } from '../../backend.service'; import {BackendService} from '../../backend.service';
import { MainDataService } from '../../maindata.service'; import {MainDataService} from '../../maindata.service';
import { import {AccessObject, AuthAccessKeyType, AuthData, BookletData} from '../../app.interfaces';
AccessObject, AuthAccessKeyType, AuthData, WorkspaceData
} from '../../app.interfaces';
@Component({ @Component({
templateUrl: './monitor-starter.component.html', templateUrl: './monitor-starter.component.html',
styles: [ styleUrls: ['./monitor-starter.component.css']
'mat-card {margin: 10px;}',
'.mat-card-gray {background-color: lightgray}'
]
}) })
export class MonitorStarterComponent implements OnInit, OnDestroy { export class MonitorStarterComponent implements OnInit, OnDestroy {
accessObjects: (WorkspaceData|AccessObject)[] = []; accessObjects: {[accessType: string]: (AccessObject|BookletData)[]} = {};
private getMonitorDataSubscription: Subscription = null;
private getWorkspaceDataSubscription: Subscription = null; public AuthAccessKeyType = AuthAccessKeyType;
public problemText: string;
constructor( constructor(
private router: Router, private router: Router,
...@@ -32,51 +28,74 @@ export class MonitorStarterComponent implements OnInit, OnDestroy { ...@@ -32,51 +28,74 @@ export class MonitorStarterComponent implements OnInit, OnDestroy {
setTimeout(() => { setTimeout(() => {
this.mds.setSpinnerOn(); this.mds.setSpinnerOn();
this.bs.getSessionData().subscribe((authDataUntyped) => { this.bs.getSessionData().subscribe((authDataUntyped) => {
if (typeof authDataUntyped !== 'number') { if (typeof authDataUntyped === 'number') {
const authData = authDataUntyped as AuthData;
if (authData) {
if (authData.token) {
this.accessObjects = [];
let scopeIdList = [];
if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) {
scopeIdList = authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR];
}
if (this.getWorkspaceDataSubscription !== null) {
this.getWorkspaceDataSubscription.unsubscribe();
}
this.getWorkspaceDataSubscription = from(scopeIdList).pipe(
concatMap((monitorScopeId) => {
let functionReturn = null;
if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) {
functionReturn = this.bs.getGroupData(monitorScopeId);
}
return functionReturn;
})
).subscribe(
(wsData: AccessObject) => {
if (wsData) {
this.accessObjects.push(wsData);
}
},
() => this.mds.setSpinnerOff(),
() => this.mds.setSpinnerOff()
);
this.mds.setAuthData(authData);
} else {
this.mds.setAuthData();
this.mds.setSpinnerOff();
}
} else {
this.mds.setAuthData();
this.mds.setSpinnerOff();
}
} else {
this.mds.setSpinnerOff(); this.mds.setSpinnerOff();
return;
}
const authData = authDataUntyped as AuthData;
if (!authData || !authData.token) {
this.mds.setAuthData();
this.mds.setSpinnerOff();
return;
}
this.accessObjects = {};
let scopeIdList: {[id: string]: {id: string, type: AuthAccessKeyType}} = {};
[AuthAccessKeyType.TEST_GROUP_MONITOR, AuthAccessKeyType.TEST]
.forEach(accessType => {
this.accessObjects[accessType] = [];
(authData.access[accessType] || [])
.forEach(accessObjectId => {
scopeIdList[accessObjectId] = {id: accessObjectId, type: accessType};
});
});
if (this.getMonitorDataSubscription !== null) {
this.getMonitorDataSubscription.unsubscribe();
} }
this.getMonitorDataSubscription =
from(Object.keys(scopeIdList))
.pipe(
map((accessType: AuthAccessKeyType) => scopeIdList[accessType]),
concatMap((accessIdAndType) => {
if (accessIdAndType.type === AuthAccessKeyType.TEST_GROUP_MONITOR) {
return this.bs.getGroupData(accessIdAndType.id);
} else if (authData.access[AuthAccessKeyType.TEST]) {
return this.bs.getBookletData(accessIdAndType.id);
}
})
)
.subscribe(
(wsData: AccessObject) => {
if (wsData) {
this.accessObjects[scopeIdList[wsData.id].type].push(wsData);
}
},
() => this.mds.setSpinnerOff(),
() => this.mds.setSpinnerOff()
);
this.mds.setAuthData(authData);
}); });
}); });
} }
startTest(b: BookletData) {
this.bs.startTest(b.id).subscribe(testId => {
if (typeof testId === 'number') {
const errCode = testId as number;
if (errCode === 423) {
this.problemText = 'Dieser Test ist gesperrt';
} else {
this.problemText = `Problem beim Start (${errCode})`;
}
} else {
this.router.navigate(['/t', testId]);
}
});
}
buttonGotoMonitor(accessObject: AccessObject): void { buttonGotoMonitor(accessObject: AccessObject): void {
this.router.navigateByUrl(`/gm/${accessObject.id.toString()}`); this.router.navigateByUrl(`/gm/${accessObject.id.toString()}`);
} }
...@@ -87,8 +106,8 @@ export class MonitorStarterComponent implements OnInit, OnDestroy { ...@@ -87,8 +106,8 @@ export class MonitorStarterComponent implements OnInit, OnDestroy {
} }
ngOnDestroy(): void { ngOnDestroy(): void {
if (this.getWorkspaceDataSubscription !== null) { if (this.getMonitorDataSubscription !== null) {
this.getWorkspaceDataSubscription.unsubscribe(); this.getMonitorDataSubscription.unsubscribe();
} }
} }
} }
...@@ -25,10 +25,10 @@ export class RouteDispatcherActivateGuard implements CanActivate { ...@@ -25,10 +25,10 @@ export class RouteDispatcherActivateGuard implements CanActivate {
this.router.navigate(['/r/admin-starter']); this.router.navigate(['/r/admin-starter']);
} else if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) { } else if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) {
this.router.navigate(['/r/code-input']); this.router.navigate(['/r/code-input']);
} else if (authData.access[AuthAccessKeyType.TEST]) {
this.router.navigate(['/r/test-starter']);
} else if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { } else if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) {
this.router.navigate(['/r/monitor-starter']); this.router.navigate(['/r/monitor-starter']);
} else if (authData.access[AuthAccessKeyType.TEST]) {
this.router.navigate(['/r/test-starter']);
} else { } else {
this.router.navigate(['/r/login', '']); this.router.navigate(['/r/login', '']);
} }
......
...@@ -17,7 +17,7 @@ export class TestMode { ...@@ -17,7 +17,7 @@ export class TestMode {
public constructor (loginMode: string = 'DEMO') { public constructor (loginMode: string = 'DEMO') {
if (loginMode) { if (loginMode) {
const regExPattern = /(DEMO|HOT|REVIEW|TRIAL)/; const regExPattern = /(DEMO|MONITOR-GROUP|HOT|REVIEW|TRIAL)/;
if (regExPattern.test(loginMode.toUpperCase())) { if (regExPattern.test(loginMode.toUpperCase())) {
const mode = loginMode.toUpperCase().match(regExPattern)[0]; const mode = loginMode.toUpperCase().match(regExPattern)[0];
const modeConfig = testModes[mode]; const modeConfig = testModes[mode];
......
...@@ -11,6 +11,18 @@ ...@@ -11,6 +11,18 @@
"showUnitMenu": false "showUnitMenu": false
} }
}, },
"MONITOR-GROUP": {
"label": "Testgruppen-Monitor (Demo)",
"config": {
"canReview": false,
"saveResponses": false,
"forceTimeRestrictions": false,
"forceNaviRestrictions": false,
"presetCode": true,
"showTimeLeft": true,
"showUnitMenu": false
}
},
"HOT": { "HOT": {
"label": "Durchführung Test/Befragung", "label": "Durchführung Test/Befragung",
"config": { "config": {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment