diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 84c8c197e0f61f6155948588d1a3d37d36e93eaa..7a9e938bd4d28fa1d2ec23f756cb82a53b57ab6b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,5 +1,7 @@ import { MainDataService } from './maindata.service'; import { Component, OnInit } from '@angular/core'; +import { BackendService, ServerError } from './backend.service'; +import { LoginData } from './app.interfaces'; @Component({ selector: 'tc-root', @@ -11,7 +13,8 @@ import { Component, OnInit } from '@angular/core'; export class AppComponent implements OnInit { constructor ( - private mds: MainDataService + private mds: MainDataService, + private bs: BackendService ) { } ngOnInit() { @@ -25,6 +28,48 @@ export class AppComponent implements OnInit { } } }); - this.mds.loadLoginStatus(); + + // restore login status if stored in localStorage + const loginToken = localStorage.getItem('lt'); + if (loginToken !== null) { + if (loginToken.length > 0) { + let personToken = localStorage.getItem('pt'); + let bookletDbId = 0; + if (personToken !== null) { + if (personToken.length > 0) { + const bookletDbIdStr = localStorage.getItem('bi'); + if (bookletDbIdStr !== null) { + bookletDbId = Number(bookletDbIdStr); + } + } + } else { + personToken = ''; + } + let code = localStorage.getItem('c'); + if (code === null) { + code = ''; + } + + // bookletDbId is not yet checked by getLoginData, only passed-through + this.bs.getLoginData(loginToken, personToken, bookletDbId).subscribe(ld => { + if (ld instanceof ServerError) { + this.mds.setNewLoginData(); + } else { + const loginData = ld as LoginData; + loginData.logintoken = loginToken; + loginData.persontoken = personToken; + if (personToken.length === 0) { + loginData.code = code; + loginData.booklet = 0; + } + this.mds.setNewLoginData(loginData); + } + }); + } else { + this.mds.setNewLoginData(); + } + } else { + this.mds.setNewLoginData(); + } } } diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts index 25bde7247cb48c64f71e094b3aad7d1190d08179..8816aa35558ad77f1e1b5baf1144bf05b2240cc1 100644 --- a/src/app/backend.service.ts +++ b/src/app/backend.service.ts @@ -59,9 +59,9 @@ export class BackendService { } // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB - getLoginData(loginToken: string, personToken: string): Observable<LoginData | ServerError> { + getLoginData(loginToken: string, personToken: string, bookletDbId: number): Observable<LoginData | ServerError> { return this.http - .post<LoginData>(this.serverSlimUrl + 'login', {lt: loginToken, pt: personToken}) + .post<LoginData>(this.serverSlimUrl + 'login', {lt: loginToken, pt: personToken, b: bookletDbId}) .pipe( catchError(ErrorHandler.handle) ); diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts index c3467376c38bc4dc6562ec91475707069b5de59f..6e74d967cde10aacc4d6005d133e3a323adaafef 100644 --- a/src/app/maindata.service.ts +++ b/src/app/maindata.service.ts @@ -1,7 +1,7 @@ -import { BackendService, ServerError } from './backend.service'; +import { ServerError } from './backend.service'; import { BehaviorSubject, Subject, merge } from 'rxjs'; import { Injectable } from '@angular/core'; -import { LoginData, BookletStatus, BookletData, BookletDataListByCode } from './app.interfaces'; +import { LoginData } from './app.interfaces'; @Injectable({ providedIn: 'root' @@ -27,54 +27,6 @@ export class MainDataService { public postMessage$ = new Subject<MessageEvent>(); - constructor( private bs: BackendService ) { } - - - // call only from app.component.ts to restore data after reload - loadLoginStatus() { - const loginToken = localStorage.getItem('lt'); - if (loginToken !== null) { - if (loginToken.length > 0) { - let personToken = localStorage.getItem('pt'); - let bookletDbId = 0; - if (personToken !== null) { - if (personToken.length > 0) { - const bookletDbIdStr = localStorage.getItem('bi'); - if (bookletDbIdStr !== null) { - bookletDbId = Number(bookletDbId); - } - } - } else { - personToken = ''; - } - let code = localStorage.getItem('c'); - if (code === null) { - code = ''; - } - - this.bs.getLoginData(loginToken, personToken).subscribe(ld => { - if (ld instanceof ServerError) { - this.setNewLoginData(); - } else { - const loginData = ld as LoginData; - // dirty: one should check whether the localStored booklet is valid - loginData.logintoken = loginToken; - loginData.persontoken = personToken; - if (personToken.length === 0) { - loginData.code = code; - } - loginData.booklet = bookletDbId; - this.setNewLoginData(loginData); - } - }); - } else { - this.setNewLoginData(); - } - } else { - this.setNewLoginData(); - } - } - // ensures consistency setNewLoginData(logindata?: LoginData) { const myLoginData: LoginData = { diff --git a/src/app/test-controller/index.ts b/src/app/test-controller/index.ts index 02065aa3d34bb8992b17da116e7b73e68e7a004f..b7937b817ec3fa28ed38b7178878cc6f717fc457 100644 --- a/src/app/test-controller/index.ts +++ b/src/app/test-controller/index.ts @@ -1,5 +1,3 @@ export { TestControllerService } from './test-controller.service'; -export { TcMenuButtonsComponent } from './tc-menu-buttons/tc-menu-buttons.component'; export { TestControllerComponent } from './test-controller.component'; export { TestControllerModule } from './test-controller.module'; -export { TcNaviButtonsComponent } from './tc-navi-buttons/tc-navi-buttons.component'; diff --git a/src/app/test-controller/tc-menu-buttons/review-dialog.component.html b/src/app/test-controller/review-dialog/review-dialog.component.html similarity index 82% rename from src/app/test-controller/tc-menu-buttons/review-dialog.component.html rename to src/app/test-controller/review-dialog/review-dialog.component.html index a30d2f17446438fabf3ab198bea51dbdce45fb59..ade8aec365bc57e6f1d42815b0da806fd778d3af 100644 --- a/src/app/test-controller/tc-menu-buttons/review-dialog.component.html +++ b/src/app/test-controller/review-dialog/review-dialog.component.html @@ -1,12 +1,12 @@ <form [formGroup]="reviewform"> - <h1 mat-dialog-title>Kommentar geben</h1> + <h1 mat-dialog-title>Kommentar geben ({{ data.loginname }})</h1> <mat-dialog-content fxLayout="column"> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> <p>Kommentar für:</p> - <mat-radio-group formControlName="target" fxLayout="row" fxLayoutGap="10px"> - <mat-radio-button value="b" [matTooltip]="data.bookletname">aktuelles Testheft</mat-radio-button> - <mat-radio-button value="u" [disabled]="data.unitname.length === 0" [matTooltip]="data.unitname">aktuelle Aufgabe</mat-radio-button> + <mat-radio-group formControlName="target" fxLayout="column" fxLayoutGap="4px"> + <mat-radio-button value="b" [matTooltip]="data.bookletname">aktuelles Testheft "{{ data.bookletname }}"</mat-radio-button> + <mat-radio-button value="u" [disabled]="data.unitname.length === 0" [matTooltip]="data.unitname">aktuelle Aufgabe "{{ data.unitname }}"</mat-radio-button> </mat-radio-group> </div> <div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px"> diff --git a/src/app/test-controller/tc-menu-buttons/review-dialog.component.spec.ts b/src/app/test-controller/review-dialog/review-dialog.component.spec.ts similarity index 100% rename from src/app/test-controller/tc-menu-buttons/review-dialog.component.spec.ts rename to src/app/test-controller/review-dialog/review-dialog.component.spec.ts diff --git a/src/app/test-controller/tc-menu-buttons/review-dialog.component.ts b/src/app/test-controller/review-dialog/review-dialog.component.ts similarity index 92% rename from src/app/test-controller/tc-menu-buttons/review-dialog.component.ts rename to src/app/test-controller/review-dialog/review-dialog.component.ts index 6e60b5528d9038e0545ee452ba812e8103001bcd..5729f5528f18d0d4538fae3d25ab6fe13b38a913 100644 --- a/src/app/test-controller/tc-menu-buttons/review-dialog.component.ts +++ b/src/app/test-controller/review-dialog/review-dialog.component.ts @@ -3,8 +3,7 @@ import { MAT_DIALOG_DATA } from '@angular/material'; import { Component, OnInit, Inject } from '@angular/core'; @Component({ - templateUrl: './review-dialog.component.html', - styleUrls: ['./review-dialog.component.css'] + templateUrl: './review-dialog.component.html' }) export class ReviewDialogComponent implements OnInit { reviewform: FormGroup; diff --git a/src/app/test-controller/tc-menu-buttons/review-dialog.component.css b/src/app/test-controller/tc-menu-buttons/review-dialog.component.css deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.css b/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.css deleted file mode 100644 index 2a4be11556c3c326e612d072ce1d92710eb3816b..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.css +++ /dev/null @@ -1,14 +0,0 @@ -/* button.mat-menu-item { - margin: 0px; -} - -button { - margin: 5px; -} */ - -.material-icons { - font-size: 2.0rem; -} -.mat-button { - text-align: right; -} diff --git a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.html b/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.html deleted file mode 100644 index 4ea5c5238ed4c699ac160a75885bbfb21bc1eb03..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.html +++ /dev/null @@ -1,3 +0,0 @@ -<button mat-button *ngIf="showReviewMenuEntry" (click)="showReviewDialog()"> - <mat-icon>rate_review</mat-icon> -</button> diff --git a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.spec.ts b/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.spec.ts deleted file mode 100644 index 5b082405ada6902994a5e552107c55230a72b159..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TcMenuButtonsComponent } from './tc-menu-buttons.component'; - -describe('TcMenuButtonsComponent', () => { - let component: TcMenuButtonsComponent; - let fixture: ComponentFixture<TcMenuButtonsComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ TcMenuButtonsComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TcMenuButtonsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.ts b/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.ts deleted file mode 100644 index fd36f38b548f5320bc44e27ef9d5a52d17d40589..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-menu-buttons/tc-menu-buttons.component.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { merge } from 'rxjs'; -import { FormGroup } from '@angular/forms'; -import { BackendService } from './../backend.service'; -import { ServerError } from '../../backend.service'; -import { MatDialog, MatSnackBar } from '@angular/material'; -import { Component, OnInit } from '@angular/core'; -import { TestControllerService } from '../test-controller.service'; -import { ReviewDialogComponent } from './review-dialog.component'; - -@Component({ - selector: 'tc-menu-buttons', - templateUrl: './tc-menu-buttons.component.html', - styleUrls: ['./tc-menu-buttons.component.css'] -}) -export class TcMenuButtonsComponent implements OnInit { - private showReviewMenuEntry = false; - - constructor( - private tcs: TestControllerService, - private reviewDialog: MatDialog, - private bs: BackendService, - // private lds: LogindataService, - private snackBar: MatSnackBar - ) { - - } - - ngOnInit() { - // merge( - // this.lds.loginMode$, - // this.lds.bookletDbId$, - // this.tcs.currentUnitPos$ - // ).subscribe(k => { - // const mode = this.lds.loginMode$.getValue(); - // if ((mode === 'trial') || (mode === 'review')) { - // this.showReviewMenuEntry = this.lds.bookletDbId$.getValue() > 0; - // } else { - // this.showReviewMenuEntry = false; - // } - // }); - } - - showReviewDialog() { - // const currentUnitPos = this.tcs.currentUnitPos$.getValue(); - // let currentUnitId = ''; - // const currentBookletId = this.lds.bookletDbId$.getValue(); - // let currentUnitLabel = ''; - // if (currentUnitPos >= 0) { - // const booklet = this.tcs.booklet$.getValue(); - // if (booklet !== null) { - // const currentUnit = booklet.getUnitAt(currentUnitPos); - // currentUnitLabel = currentUnit.label; - // currentUnitId = currentUnit.id; - // } - // } - // const dialogRef = this.reviewDialog.open(ReviewDialogComponent, { - // width: '700px', - // data: { - // loginname: this.lds.loginName$.getValue(), - // bookletname: this.lds.bookletLabel$.getValue(), - // unitname: currentUnitLabel - // } - // }); - - // dialogRef.afterClosed().subscribe(result => { - // if (typeof result !== 'undefined') { - // if (result !== false) { - // const targetSelection = (<FormGroup>result).get('target').value; - // if (targetSelection === 'u') { - // this.bs.saveUnitReview( - // this.lds.personToken$.getValue(), - // this.lds.bookletDbId$.getValue(), - // currentUnitId, - // (<FormGroup>result).get('priority').value, - // dialogRef.componentInstance.getCategories(), - // (<FormGroup>result).get('entry').value - // ).subscribe(myData => { - // if (myData instanceof ServerError) { - // const e = myData as ServerError; - // this.snackBar.open( -// 'Konnte Kommentar nicht speichern (' + e.code.toString() + ': ' + e.labelNice, '', {duration: 3000}); - // } else { - // const ok = myData as boolean; - // if (ok) { - // this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); - // } else { - // this.snackBar.open('Konnte Kommentar nicht speichern.', '', {duration: 3000}); - // } - // } - // }); - // } else { - // this.bs.saveBookletReview( - // this.lds.personToken$.getValue(), - // this.lds.bookletDbId$.getValue(), - // (<FormGroup>result).get('priority').value, - // dialogRef.componentInstance.getCategories(), - // (<FormGroup>result).get('entry').value - // ).subscribe(myData => { - // if (myData instanceof ServerError) { - // const e = myData as ServerError; - // this.snackBar.open('Konnte Kommentar nicht speichern (' + e.code.toString() + ': ' + e.labelNice, '', {duration: 3000}); - // } else { - // const ok = myData as boolean; - // if (ok) { - // this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); - // } else { - // this.snackBar.open('Konnte Kommentar nicht speichern.', '', {duration: 3000}); - // } - // } - // }); - // } - // } - // } - // }); - } -} diff --git a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.css b/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.css deleted file mode 100644 index 8caa25de760d990088532dd03ce1ad7489b08a60..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.css +++ /dev/null @@ -1,21 +0,0 @@ -.navPageButtonsContainer { - margin-top: 40px; - margin-left: -30px; - margin-right: -30px; - z-index: 200; -} - -.navButtonsContainer { - position: fixed; - z-index: 100; - top: 8px; - right: 70px; -} - -.mat-fab { - margin-right: 4px -} - -.mat-fab[disabled], .mat-mini-fab[disabled] { - background-color: grey; -} diff --git a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.html b/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.html deleted file mode 100644 index 842f827a1cc06b58de947076e37da111084c1ad4..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.html +++ /dev/null @@ -1,16 +0,0 @@ -<div class="navButtonsContainer" *ngIf="showNaviButtons" fxLayout="row"> - <button mat-fab [disabled]="!unitPrevEnabled" color="accent" (click)="prevUnitNaviButtonClick()"> - <i class="material-icons">chevron_left</i> - </button> - <div class="navPageButtonsContainer" *ngIf="showPageNaviButtons"> - <button mat-mini-fab [disabled]="!pagePrevEnabled" color="foreground" (click)="prevPageNaviButtonClick()"> - <i class="material-icons">chevron_left</i> - </button> - <button mat-mini-fab [disabled]="!pageNextEnabled" color="foreground" (click)="nextPageNaviButtonClick()"> - <i class="material-icons">chevron_right</i> - </button> - </div> - <button mat-fab [disabled]="!unitNextEnabled" color="accent" (click)="nextUnitNaviButtonClick()"> - <i class="material-icons">chevron_right</i> - </button> -</div> diff --git a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.spec.ts b/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.spec.ts deleted file mode 100644 index 28cb3a9fb15d5f43ffea1c780f730df1bd72adaa..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TcNaviButtonsComponent } from './tc-navi-buttons.component'; - -describe('TcNaviButtonsComponent', () => { - let component: TcNaviButtonsComponent; - let fixture: ComponentFixture<TcNaviButtonsComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ TcNaviButtonsComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TcNaviButtonsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.ts b/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.ts deleted file mode 100644 index e35fc366c5048f0eb82a8c9ce932115659608355..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-navi-buttons/tc-navi-buttons.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { TestControllerService } from './../test-controller.service'; -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'tc-navi-buttons', - templateUrl: './tc-navi-buttons.component.html', - styleUrls: ['./tc-navi-buttons.component.css'] -}) -export class TcNaviButtonsComponent { - private showNaviButtons = false; - private showPageNaviButtons = false; - private pagePrevEnabled = false; - private pageNextEnabled = false; - private unitPrevEnabled = false; - private unitNextEnabled = false; - - constructor( private tcs: TestControllerService) { - this.tcs.showNaviButtons$.subscribe(show => this.showNaviButtons = show); - this.tcs.itemplayerValidPages$.subscribe((pages: string[]) => this.showPageNaviButtons = pages.length > 1); - this.tcs.itemplayerCurrentPage$.subscribe((p: string) => { - const validPages = this.tcs.itemplayerValidPages$.getValue(); - const pagePos = validPages.indexOf(p); - - this.pageNextEnabled = (pagePos >= 0) && (pagePos < validPages.length - 1); - this.pagePrevEnabled = (pagePos > 0) && (validPages.length > 1); - }); - this.tcs.nextUnit$.subscribe(u => { - this.unitNextEnabled = u >= 0; - }); - this.tcs.prevUnit$.subscribe(u => this.unitPrevEnabled = u >= 0); - } - - // ******************************************************************************************************* - prevPageNaviButtonClick() { - const validPages = this.tcs.itemplayerValidPages$.getValue(); - const p = this.tcs.itemplayerCurrentPage$.getValue(); - const pagePos = validPages.indexOf(p); - // if (pagePos > 0) { - // this.tcs.itemplayerPageRequest$.next(validPages[pagePos - 1]); - // } - } - nextPageNaviButtonClick() { - const validPages = this.tcs.itemplayerValidPages$.getValue(); - const p = this.tcs.itemplayerCurrentPage$.getValue(); - const pagePos = validPages.indexOf(p); - // if ((pagePos >= 0) && (pagePos < validPages.length - 1)) { - // this.tcs.itemplayerPageRequest$.next(validPages[pagePos + 1]); - // } - } - nextUnitNaviButtonClick() { - this.tcs.unitRequest$.next(this.tcs.nextUnit$.getValue()); - } - prevUnitNaviButtonClick() { - this.tcs.unitRequest$.next(this.tcs.prevUnit$.getValue()); - } -} diff --git a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.css b/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.css deleted file mode 100644 index d6d4d8e819b1bb8168c0d15a38b9aa92819184a4..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.css +++ /dev/null @@ -1,18 +0,0 @@ -button { - margin: 0px 10px 0px 10px; -} - -div.active-bar, div.not-active-bar { - position: relative; - top: 24px; - width: 100%; - height: 10px; -} - -div.active-bar { - background-color: yellow; -} - -div.not-active-bar { - background-color: transparent; -} diff --git a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.html b/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.html deleted file mode 100644 index 5f6e8e5c58b253dada8c69404a1eedf4773a81bc..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.html +++ /dev/null @@ -1,8 +0,0 @@ -<div> - <div class="active-bar" *ngIf="isActive"></div> - <div class="not-active-bar" *ngIf="!isActive"></div> - <button mat-raised-button (click)="sideNaviButtonClick()" - [disabled]="unitData.locked" > - {{ unitData.sequenceId + 1 }} - </button> -</div> diff --git a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.spec.ts b/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.spec.ts deleted file mode 100644 index 49cf33c12f117c0e2a3b288997a3ef061145c1d6..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TcSidenaviButtonComponent } from './tc-sidenavi-button.component'; - -describe('TcSidenaviButtonComponent', () => { - let component: TcSidenaviButtonComponent; - let fixture: ComponentFixture<TcSidenaviButtonComponent>; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ TcSidenaviButtonComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(TcSidenaviButtonComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.ts b/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.ts deleted file mode 100644 index a0db4e5a08584c0d15a5fedabeacb2f78a655d87..0000000000000000000000000000000000000000 --- a/src/app/test-controller/tc-sidenavi-button/tc-sidenavi-button.component.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { TestControllerService } from '../test-controller.service'; -import { Component, OnInit, Input } from '@angular/core'; -import { UnitDef } from '../test-controller.classes'; - -@Component({ - selector: 'tc-sidenavi-button', - templateUrl: './tc-sidenavi-button.component.html', - styleUrls: ['./tc-sidenavi-button.component.css'] -}) -export class TcSidenaviButtonComponent implements OnInit { - @Input() unitData: UnitDef = null; - isActive = false; - constructor( - private tcs: TestControllerService - ) { - this.tcs.currentUnitPos$.subscribe(up => { - if (this.unitData !== null) { - this.isActive = up === this.unitData.sequenceId; - } - }); - } - - ngOnInit() { - if (this.unitData !== null) { - this.isActive = this.tcs.currentUnitPos$.getValue() === this.unitData.sequenceId; - } - } - - sideNaviButtonClick() { - if (this.unitData !== null) { - // this.tcs.goToUnitByPosition(this.unitData.sequenceId); - } - } -} diff --git a/src/app/test-controller/test-controller.classes.ts b/src/app/test-controller/test-controller.classes.ts index 81c307c8a5f585109734e7959ab081451762a181..c8087f7d497b8a313fe2c27cc073b019bdf99cd6 100644 --- a/src/app/test-controller/test-controller.classes.ts +++ b/src/app/test-controller/test-controller.classes.ts @@ -97,8 +97,8 @@ export class TestletContentElement { export class UnitDef extends TestletContentElement { readonly alias: string; readonly naviButtonLabel: string; - readonly playerId: string; readonly reportStatus: boolean; + playerId: string; statusResponses: 'no' | 'some' | 'all'; statusPresentation: 'no' | 'partly' | 'full'; diff --git a/src/app/test-controller/test-controller.component.css b/src/app/test-controller/test-controller.component.css index 6ca5d21bb7a7bd72b576bb5470c6d08f4d6916f6..8b85c0589973f16b517509c154c138f6cceab625 100644 --- a/src/app/test-controller/test-controller.component.css +++ b/src/app/test-controller/test-controller.component.css @@ -25,3 +25,16 @@ top: 65px; bottom: 0; } + +#reviewbutton .material-icons { + font-size: 2.0rem; +} +#reviewbutton .mat-button { + text-align: right; +} +#reviewbutton { + position: absolute; + right: 5px; + top: 5px; + color: white; +} diff --git a/src/app/test-controller/test-controller.component.html b/src/app/test-controller/test-controller.component.html index 831568c414a8cceabc2af817ec45b0bd9cff5d4b..1761fce41615009a74bee4a8370fb5360af38d1e 100644 --- a/src/app/test-controller/test-controller.component.html +++ b/src/app/test-controller/test-controller.component.html @@ -3,6 +3,9 @@ <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> </a> </div> +<button id="reviewbutton" mat-button *ngIf="tcs.mode === 'review'" (click)="showReviewDialog()"> + <mat-icon>rate_review</mat-icon> +</button> <div class="spinner-container" *ngIf="dataLoading"> <mat-spinner></mat-spinner> </div> diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts index c25efe7bc99623f72e3be7e58c4fbee2d4d3b263..759e6552e7b248bb1d7419ee85e3ad374aa07c75 100644 --- a/src/app/test-controller/test-controller.component.ts +++ b/src/app/test-controller/test-controller.component.ts @@ -1,10 +1,14 @@ +import { ReviewDialogComponent } from './review-dialog/review-dialog.component'; +import { MatDialog, MatSnackBar } from '@angular/material'; +import { FormGroup } from '@angular/forms'; +import { Router } from '@angular/router'; import { MainDataService } from './../maindata.service'; import { ServerError } from '../backend.service'; import { BackendService } from './backend.service'; import { TestControllerService } from './test-controller.service'; import { Component, OnInit, OnDestroy } from '@angular/core'; -import { UnitDef, Testlet } from './test-controller.classes'; +import { UnitDef, Testlet, UnitControllerData } from './test-controller.classes'; import { BookletData, UnitData } from './test-controller.interfaces'; import { Subscription, Observable, of, forkJoin } from 'rxjs'; import { switchMap } from 'rxjs/operators'; @@ -26,8 +30,11 @@ export class TestControllerComponent implements OnInit, OnDestroy { constructor ( private tcs: TestControllerService, + private reviewDialog: MatDialog, private bs: BackendService, - private mds: MainDataService + private mds: MainDataService, + private snackBar: MatSnackBar, + private router: Router ) { // this.unitPosSubsription = this.tcs.currentUnitPos$.subscribe(u => this.updateStatus()); } @@ -215,6 +222,7 @@ export class TestControllerComponent implements OnInit, OnDestroy { } if (playerId.length > 0) { + myUnit.playerId = playerId; return this.loadPlayerOk(playerId).pipe( switchMap(ok => { @@ -249,22 +257,27 @@ export class TestControllerComponent implements OnInit, OnDestroy { // ========================================================== // ========================================================== ngOnInit() { + this.router.navigateByUrl('/t'); + this.loginDataSubscription = this.mds.loginData$.subscribe(loginData => { this.tcs.resetDataStore(); if ((loginData.persontoken.length > 0) && (loginData.booklet > 0)) { this.tcs.mode = loginData.mode; + this.tcs.loginname = loginData.loginname; this.dataLoading = true; this.bs.getBookletData().subscribe(myData => { if (myData instanceof ServerError) { const e = myData as ServerError; this.mds.globalErrorMsg$.next(e); + this.dataLoading = false; } else { const bookletData = myData as BookletData; this.tcs.rootTestlet = this.getBookletFromXml(bookletData.xml); if (this.tcs.rootTestlet === null) { this.mds.globalErrorMsg$.next(new ServerError(0, 'Error Parsing Booklet Xml', '')); + this.dataLoading = false; } else { this.mds.globalErrorMsg$.next(null); this.tcs.numberOfUnits = this.lastUnitSequenceId - 1; @@ -272,14 +285,30 @@ export class TestControllerComponent implements OnInit, OnDestroy { const myUnitLoadings = []; for (let i = 1; i < this.tcs.numberOfUnits + 1; i++) { const ud = this.tcs.rootTestlet.getUnitAt(i); - if (ud === null) { - console.log('# yo hm: ' + i.toString()); - } else { - myUnitLoadings.push(this.loadUnitOk(ud.unitDef, i)); - } + myUnitLoadings.push(this.loadUnitOk(ud.unitDef, i)); } forkJoin(myUnitLoadings).subscribe(allOk => { - console.log(allOk); + this.dataLoading = false; + + let loadingOk = true; + for (const ok of allOk) { + if (!ok) { + loadingOk = false; + break; + } + } + + if (loadingOk) { + // ================================================= + + this.goToUnitBySequenceId(1); + + // ================================================= + } else { + console.log('loading failed'); + this.mds.globalErrorMsg$.next(new ServerError(0, 'Inhalte des Testheftes konnten nicht alle geladen werden.', '')); + this.tcs.resetDataStore(); + } }); } } @@ -288,6 +317,84 @@ export class TestControllerComponent implements OnInit, OnDestroy { }); } + + + // ========================================================== + goToUnitBySequenceId(sequenceId: number) { + if (this.tcs.rootTestlet !== null) { + this.router.navigateByUrl('/t/u/' + sequenceId.toString()); + } + } + + + + // ========================================================== + showReviewDialog() { + if (this.tcs.rootTestlet === null) { + this.snackBar.open('Kein Testheft verfügbar.', '', {duration: 3000}); + } else { + const dialogRef = this.reviewDialog.open(ReviewDialogComponent, { + width: '700px', + data: { + loginname: this.tcs.loginname, + bookletname: this.tcs.rootTestlet.title, + unitname: this.tcs.currentUnitTitle + } + }); + + dialogRef.afterClosed().subscribe(result => { + if (typeof result !== 'undefined') { + if (result !== false) { + const targetSelection = (<FormGroup>result).get('target').value; + if (targetSelection === 'u') { + // this.bs.saveUnitReview( + // this.lds.personToken$.getValue(), + // this.lds.bookletDbId$.getValue(), + // currentUnitId, + // (<FormGroup>result).get('priority').value, + // dialogRef.componentInstance.getCategories(), + // (<FormGroup>result).get('entry').value + // ).subscribe(myData => { + // if (myData instanceof ServerError) { + // const e = myData as ServerError; + // this.snackBar.open( + // 'Konnte Kommentar nicht speichern (' + e.code.toString() + ': ' + e.labelNice, '', {duration: 3000}); + // } else { + // const ok = myData as boolean; + // if (ok) { + // this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); + // } else { + // this.snackBar.open('Konnte Kommentar nicht speichern.', '', {duration: 3000}); + // } + // } + // }); + } else { + // this.bs.saveBookletReview( + // this.lds.personToken$.getValue(), + // this.lds.bookletDbId$.getValue(), + // (<FormGroup>result).get('priority').value, + // dialogRef.componentInstance.getCategories(), + // (<FormGroup>result).get('entry').value + // ).subscribe(myData => { + // if (myData instanceof ServerError) { + // const e = myData as ServerError; + // this.snackBar.open('Konnte Kommentar nicht speichern (' + e.code.toString() + ': ' + e.labelNice, '', {duration: 3000}); + // } else { + // const ok = myData as boolean; + // if (ok) { + // this.snackBar.open('Kommentar gespeichert', '', {duration: 1000}); + // } else { + // this.snackBar.open('Konnte Kommentar nicht speichern.', '', {duration: 3000}); + // } + // } + // }); + } + } + } + }); + } + } + // private updateStatus() { // const cu = this.tcs.currentUnitPos$.getValue(); // if (cu >= 0) { @@ -321,15 +428,6 @@ export class TestControllerComponent implements OnInit, OnDestroy { - // goToUnitByPosition(pos: number) { - // const myBooklet = this.booklet$.getValue(); - // if (myBooklet !== null) { - // const unitCount = myBooklet.units.length; - // if ((pos >= 0 ) && (pos < unitCount)) { - // this.router.navigateByUrl('/t/u/' + pos.toString()); - // } - // } - // } // setCurrentUnit(targetUnitSequenceId: number) { // const currentBooklet = this.booklet$.getValue(); diff --git a/src/app/test-controller/test-controller.module.ts b/src/app/test-controller/test-controller.module.ts index 5d47bfeb086867762dad2097fc788a22015ff8ec..6d2e1daf4b376996190d67efebe49df7454281cc 100644 --- a/src/app/test-controller/test-controller.module.ts +++ b/src/app/test-controller/test-controller.module.ts @@ -9,12 +9,9 @@ import { MatProgressSpinnerModule, MatIconModule, MatMenuModule, MatTooltipModul import { TestControllerComponent } from './test-controller.component'; import { ResizeIFrameChildDirective } from './resize-IFrameChild/resize-IFrameChild.directive'; import { unitRoutingGuards } from './unithost/unit-routing-guards'; -import { TcMenuButtonsComponent } from './tc-menu-buttons/tc-menu-buttons.component'; -// import { TcNaviButtonsComponent } from './tc-navi-buttons/tc-navi-buttons.component'; import { FlexLayoutModule } from '@angular/flex-layout'; -import { ReviewDialogComponent } from './tc-menu-buttons/review-dialog.component'; +import { ReviewDialogComponent } from './review-dialog/review-dialog.component'; import { ReactiveFormsModule } from '../../../node_modules/@angular/forms'; -// import { TcSidenaviButtonComponent } from './tc-sidenavi-button/tc-sidenavi-button.component'; import { StartLockInputComponent } from './start-lock-input/start-lock-input.component'; @@ -40,10 +37,7 @@ import { StartLockInputComponent } from './start-lock-input/start-lock-input.com UnithostComponent, TestControllerComponent, ResizeIFrameChildDirective, - TcMenuButtonsComponent, - // TcNaviButtonsComponent, ReviewDialogComponent, - // TcSidenaviButtonComponent, StartLockInputComponent ], entryComponents: [ @@ -54,9 +48,7 @@ import { StartLockInputComponent } from './start-lock-input/start-lock-input.com unitRoutingGuards ], exports: [ - TestControllerComponent, - // TcNaviButtonsComponent, - TcMenuButtonsComponent + TestControllerComponent ] }) export class TestControllerModule { } diff --git a/src/app/test-controller/test-controller.service.ts b/src/app/test-controller/test-controller.service.ts index 7f46d21a06206feb9b0b7721b99973ab3b5aa78b..36e68eb80a24cce266b42d94bcf0ec55ce2126ae 100644 --- a/src/app/test-controller/test-controller.service.ts +++ b/src/app/test-controller/test-controller.service.ts @@ -1,10 +1,6 @@ -import { Router } from '@angular/router'; import { BehaviorSubject, of, Observable } from 'rxjs'; import { Injectable } from '@angular/core'; -import { switchMap } from 'rxjs/operators'; -import { BackendService } from './backend.service'; -import { ServerError} from '../backend.service'; -import { UnitDef, Testlet, BookletConfig } from './test-controller.classes'; +import { Testlet, BookletConfig } from './test-controller.classes'; @Injectable({ providedIn: 'root' @@ -16,11 +12,14 @@ export class TestControllerService { public bookletConfig$ = new BehaviorSubject<BookletConfig>(this.standardBookletConfig); public rootTestlet: Testlet = null; public numberOfUnits = 0; + public loginname = ''; public mode = ''; + public currentUnitSequenceId = -1; + public currentUnitId = ''; + public currentUnitTitle = ''; // public booklet$ = new BehaviorSubject<BookletDef>(null); - public currentUnitPos$ = new BehaviorSubject<number>(-1); // for Navi-Buttons: public showNaviButtons$ = new BehaviorSubject<boolean>(false); @@ -45,6 +44,10 @@ export class TestControllerService { this.rootTestlet = null; this.numberOfUnits = 0; this.mode = ''; + this.loginname = ''; + this.currentUnitSequenceId = 0; + this.currentUnitId = ''; + this.currentUnitTitle = ''; } diff --git a/src/app/test-controller/unithost/unithost.component.ts b/src/app/test-controller/unithost/unithost.component.ts index d67f0d8d61e74b2b4a34228ae01556388d10f45b..063bed1f29e3be8c081919c482c5ea6b17bcbd16 100644 --- a/src/app/test-controller/unithost/unithost.component.ts +++ b/src/app/test-controller/unithost/unithost.component.ts @@ -235,6 +235,7 @@ export class UnithostComponent implements OnInit, OnDestroy { this.routingSubscription = this.route.params.subscribe(params => { this.myUnitNumber = Number(params['u']); + this.tcs.currentUnitSequenceId = this.myUnitNumber; this.loadItemplayer(this.myUnitNumber); }); @@ -259,6 +260,8 @@ export class UnithostComponent implements OnInit, OnDestroy { const currentUnit = this.tcs.rootTestlet.getUnitAt(unitSequenceId); this.unitTitle = currentUnit.unitDef.title; // (currentUnitId + 1).toString() + '. ' this.myUnitName = currentUnit.unitDef.id; + this.tcs.currentUnitId = this.myUnitName; + this.tcs.currentUnitTitle = this.unitTitle; this.iFrameItemplayer = <HTMLIFrameElement>document.createElement('iframe'); this.iFrameItemplayer.setAttribute('srcdoc', this.tcs.getPlayer(currentUnit.unitDef.playerId));