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 13641cb97ce2a0b1472599382237096238585eb8..08a0bc546d81aeceac3036b24e0ac096b6bd4078 100644 --- a/src/app/app-root/monitor-starter/monitor-starter.component.html +++ b/src/app/app-root/monitor-starter/monitor-starter.component.html @@ -4,7 +4,7 @@ <mat-card-content> <div fxLayoutGap="10px" fxLayout="column"> <p *ngIf="accessObjects.length === 0"> - Sie sind angemeldet. Aktuell sind keine Bereiche zur Überwachung für Sie freigegeben. + Sie sind angemeldet. Aktuell sind keine Testgruppen zur Überwachung für Sie freigegeben. </p> <button mat-raised-button color="primary" (click)="buttonGotoMonitor(accessObject)" *ngFor="let accessObject of accessObjects"> 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 8c5fb5b660a3356582bb1aca546e4953fa854d26..3a9fbc9f9f22e0ed40c0012ff72082b7842ec093 100644 --- a/src/app/app-root/monitor-starter/monitor-starter.component.ts +++ b/src/app/app-root/monitor-starter/monitor-starter.component.ts @@ -1,11 +1,13 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; -import {AccessObject, AuthAccessKeyType, AuthData, WorkspaceData} from '../../app.interfaces'; -import {from, Subscription} from 'rxjs'; -import {Router} from '@angular/router'; -import {BackendService} from '../../backend.service'; -import {MainDataService} from '../../maindata.service'; -import {concatMap} from 'rxjs/operators'; -import {CustomtextService} from 'iqb-components'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { from, Subscription } from 'rxjs'; +import { Router } from '@angular/router'; +import { concatMap } from 'rxjs/operators'; +import { CustomtextService } from 'iqb-components'; +import { BackendService } from '../../backend.service'; +import { MainDataService } from '../../maindata.service'; +import { + AccessObject, AuthAccessKeyType, AuthData, WorkspaceData +} from '../../app.interfaces'; @Component({ templateUrl: './monitor-starter.component.html', @@ -16,7 +18,7 @@ import {CustomtextService} from 'iqb-components'; }) export class MonitorStarterComponent implements OnInit, OnDestroy { accessObjects: (WorkspaceData|AccessObject)[] = []; - isWorkspaceMonitor = false; + private getWorkspaceDataSubscription: Subscription = null; constructor( @@ -26,10 +28,10 @@ export class MonitorStarterComponent implements OnInit, OnDestroy { private mds: MainDataService ) { } - ngOnInit() { + ngOnInit(): void { setTimeout(() => { this.mds.setSpinnerOn(); - this.bs.getSessionData().subscribe(authDataUntyped => { + this.bs.getSessionData().subscribe((authDataUntyped) => { if (typeof authDataUntyped !== 'number') { const authData = authDataUntyped as AuthData; if (authData) { @@ -38,23 +40,24 @@ export class MonitorStarterComponent implements OnInit, OnDestroy { let scopeIdList = []; if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { scopeIdList = authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]; - this.isWorkspaceMonitor = false; - } else if (authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { - scopeIdList = authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]; - this.isWorkspaceMonitor = true; } if (this.getWorkspaceDataSubscription !== null) { this.getWorkspaceDataSubscription.unsubscribe(); } this.getWorkspaceDataSubscription = from(scopeIdList).pipe( - concatMap(monitorScopeId => { + concatMap((monitorScopeId) => { + let functionReturn = null; if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { - return this.bs.getGroupData(monitorScopeId); - } else if (authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { - return this.bs.getWorkspaceData(monitorScopeId); + functionReturn = this.bs.getGroupData(monitorScopeId); + } + return functionReturn; + }) + ).subscribe( + (wsData: AccessObject) => { + if (wsData) { + this.accessObjects.push(wsData); } - })).subscribe( - wsData => this.accessObjects.push(wsData), + }, () => this.mds.setSpinnerOff(), () => this.mds.setSpinnerOff() ); @@ -74,21 +77,16 @@ export class MonitorStarterComponent implements OnInit, OnDestroy { }); } - buttonGotoMonitor(accessObject: AccessObject) { - - if (this.isWorkspaceMonitor) { - this.router.navigateByUrl('/wm/' + accessObject.id.toString()); - } else { - this.router.navigateByUrl('/gm/' + accessObject.id.toString()); - } + buttonGotoMonitor(accessObject: AccessObject): void { + this.router.navigateByUrl(`/gm/${accessObject.id.toString()}`); } - resetLogin() { + resetLogin(): void { this.mds.setAuthData(); this.router.navigate(['/']); } - ngOnDestroy() { + ngOnDestroy(): void { if (this.getWorkspaceDataSubscription !== null) { this.getWorkspaceDataSubscription.unsubscribe(); } diff --git a/src/app/app-route-guards.ts b/src/app/app-route-guards.ts index d7424117d846fdf181169be68783ab84d6691b5e..043f06c20c1d41f4ea6cda1f0b30c112807bf553 100644 --- a/src/app/app-route-guards.ts +++ b/src/app/app-route-guards.ts @@ -1,7 +1,11 @@ +// eslint-disable-next-line max-classes-per-file import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; -import { MainDataService } from './maindata.service'; +import { + ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot +} from '@angular/router'; import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { MainDataService } from './maindata.service'; import { AuthAccessKeyType, AuthData, AuthFlagType } from './app.interfaces'; import { BackendService } from './backend.service'; @@ -12,20 +16,18 @@ export class RouteDispatcherActivateGuard implements CanActivate { ) { } - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { - + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.token) { - if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN] || authData.access[AuthAccessKeyType.SUPER_ADMIN]) { + if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN] + || authData.access[AuthAccessKeyType.SUPER_ADMIN]) { this.router.navigate(['/r/admin-starter']); } else if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) { 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] || authData.access[AuthAccessKeyType.WORKSPACE_MONITOR]) { + } else if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { this.router.navigate(['/r/monitor-starter']); } else { this.router.navigate(['/r/login', '']); @@ -52,27 +54,25 @@ export class DirectLoginActivateGuard implements CanActivate { canActivate( next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { - + state: RouterStateSnapshot + ): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (!authData) { const directLoginName = state.url.substr(1); if (directLoginName.length > 0 && directLoginName.indexOf('/') < 0) { - this.bs.nameOnlyLogin(directLoginName).subscribe((authDataResponse: AuthData|number) => { - if (typeof authDataResponse !== 'number') { - this.mds.setAuthData(authDataResponse as AuthData); - this.router.navigate(['/r']); - return false; - } else { + return this.bs.nameOnlyLogin(directLoginName).pipe( + map((authDataResponse: AuthData|number) => { + if (typeof authDataResponse !== 'number') { + this.mds.setAuthData(authDataResponse as AuthData); + this.router.navigate(['/r']); + return false; + } return true; - } - }); - } else { - return true; + }) + ); } - } else { - return true; } + return true; } } @@ -80,29 +80,23 @@ export class DirectLoginActivateGuard implements CanActivate { providedIn: 'root' }) export class CodeInputComponentActivateGuard implements CanActivate { - constructor( private router: Router ) { } - - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + constructor(private router: Router) { } + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.flags) { if (authData.flags.indexOf(AuthFlagType.CODE_REQUIRED) >= 0) { return true; - } else { - this.router.navigate(['/r']); - return false; } - } else { this.router.navigate(['/r']); return false; } - } else { this.router.navigate(['/r']); return false; } + this.router.navigate(['/r']); + return false; } } @@ -110,29 +104,23 @@ export class CodeInputComponentActivateGuard implements CanActivate { providedIn: 'root' }) export class AdminComponentActivateGuard implements CanActivate { - constructor( private router: Router ) { } - - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + constructor(private router: Router) { } + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.access) { if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN]) { return true; - } else { - this.router.navigate(['/r']); - return false; } - } else { this.router.navigate(['/r']); return false; } - } else { this.router.navigate(['/r']); return false; } + this.router.navigate(['/r']); + return false; } } @@ -140,29 +128,24 @@ export class AdminComponentActivateGuard implements CanActivate { providedIn: 'root' }) export class AdminOrSuperAdminComponentActivateGuard implements CanActivate { - constructor( private router: Router ) { } - - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + constructor(private router: Router) { } + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.access) { - if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN] || authData.access[AuthAccessKeyType.SUPER_ADMIN]) { + if (authData.access[AuthAccessKeyType.WORKSPACE_ADMIN] + || authData.access[AuthAccessKeyType.SUPER_ADMIN]) { return true; - } else { - this.router.navigate(['/r']); - return false; } - } else { this.router.navigate(['/r']); return false; } - } else { this.router.navigate(['/r']); return false; } + this.router.navigate(['/r']); + return false; } } @@ -170,29 +153,23 @@ export class AdminOrSuperAdminComponentActivateGuard implements CanActivate { providedIn: 'root' }) export class SuperAdminComponentActivateGuard implements CanActivate { - constructor( private router: Router ) { } - - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + constructor(private router: Router) { } + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.access) { if (authData.access[AuthAccessKeyType.SUPER_ADMIN]) { return true; - } else { - this.router.navigate(['/r']); - return false; } - } else { this.router.navigate(['/r']); return false; } - } else { this.router.navigate(['/r']); return false; } + this.router.navigate(['/r']); + return false; } } @@ -200,60 +177,45 @@ export class SuperAdminComponentActivateGuard implements CanActivate { providedIn: 'root' }) export class TestComponentActivateGuard implements CanActivate { - constructor( private router: Router ) { } - - canActivate( - next: ActivatedRouteSnapshot, - state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { + constructor(private router: Router) { } + canActivate(): Observable<boolean> | Promise<boolean> | boolean { const authData = MainDataService.getAuthData(); if (authData) { if (authData.access) { if (authData.access[AuthAccessKeyType.TEST]) { return true; - } else { - this.router.navigate(['/r']); - return false; } - } else { this.router.navigate(['/r']); return false; } - } else { this.router.navigate(['/r']); return false; } + this.router.navigate(['/r']); + return false; } } - @Injectable({ providedIn: 'root' }) export class GroupMonitorActivateGuard implements CanActivate { - constructor( - private router: Router + private router: Router ) {} - canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { - const authData = MainDataService.getAuthData(); + canActivate(): boolean { + const authData = MainDataService.getAuthData(); - if (authData) { - if (authData.access) { - if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { - return true; - } else { - this.router.navigate(['/r']); - return ; - } - } else { - this.router.navigate(['/r']); - return false; - } - } else { - this.router.navigate(['/r']); - return false; + if (authData) { + if (authData.access) { + if (authData.access[AuthAccessKeyType.TEST_GROUP_MONITOR]) { + return true; } + } + } + this.router.navigate(['/r']); + return false; } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 21c53f0e91889d844612529825c231fa698c41af..84aeeb726d13722c13982909d7ae7df2b1d14ded 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -67,7 +67,7 @@ const routes: Routes = [ { path: 'monitor-starter', component: MonitorStarterComponent, - canActivate: [GroupMonitorActivateGuard] // TODO, also: workspaceMonitor + canActivate: [GroupMonitorActivateGuard] } ] }, @@ -89,10 +89,6 @@ const routes: Routes = [ loadChildren: () => import('./superadmin/superadmin.module').then((m) => m.SuperadminModule), canActivate: [SuperAdminComponentActivateGuard] }, - { - path: 'wm', - loadChildren: () => import('./workspace-monitor/workspace-monitor.module').then((m) => m.WorkspaceMonitorModule) - }, { path: 'gm', loadChildren: () => import('./group-monitor/group-monitor.module').then((m) => m.GroupMonitorModule) diff --git a/src/app/workspace-monitor/backend.service.spec.ts b/src/app/workspace-monitor/backend.service.spec.ts deleted file mode 100644 index e4f50fbf746555c900e07a497bb9b6c1425a6437..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/backend.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { HttpClientModule } from '@angular/common/http'; - -import { BackendService } from './backend.service'; - -describe('HttpClient testing', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [HttpClientModule], - providers: [BackendService] - }); - }); - it('should be created', inject([BackendService], (service: BackendService) => { - expect(service).toBeTruthy(); - })); -}); diff --git a/src/app/workspace-monitor/backend.service.ts b/src/app/workspace-monitor/backend.service.ts deleted file mode 100644 index faedd52f99592ad09aef42cf643e7a79dbe76e81..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/backend.service.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Injectable, Inject } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { catchError } from 'rxjs/operators'; - -import { ErrorHandler, ServerError } from 'iqb-components'; -import { BookletsStarted, MonitorData } from './workspace-monitor.interfaces'; - -@Injectable({ - providedIn: 'root' -}) - -export class BackendService { - private serverUrlSlim = ''; - private serverUrlSysCheck = ''; - - constructor( - @Inject('SERVER_URL') private readonly serverUrl: string, - private http: HttpClient) { - this.serverUrlSlim = this.serverUrl + 'php/ws.php/'; - this.serverUrlSysCheck = this.serverUrl + 'php_admin/'; - this.serverUrl = this.serverUrl + 'php/'; - } - - getBookletsStarted(workspaceId: number, groups: string[]) - : Observable<BookletsStarted[] | ServerError> { - return this.http - .get<BookletsStarted[]>(this.serverUrl + `workspace/${workspaceId}/booklets/started`, {params: {groups: groups.join(',')}}) - .pipe(catchError(ErrorHandler.handle)); - } - - lockBooklets(workspaceId: number, groups: string[]): Observable<boolean | ServerError> { - return this.http - .patch<boolean>(this.serverUrl + `workspace/${workspaceId}/tests/lock`, {groups: groups}) - .pipe(catchError(ErrorHandler.handle)); - } - - unlockBooklets(workspaceId: number, groups: string[]): Observable<boolean | ServerError> { - return this.http - .patch<boolean>(this.serverUrl + `workspace/${workspaceId}/tests/unlock`, {groups: groups}) - .pipe(catchError(ErrorHandler.handle)); - } - - - getMonitorData(workspaceId: number): Observable<MonitorData[] | ServerError> { - return this.http - .get<MonitorData[]>(this.serverUrl + `workspace/${workspaceId}/status`, {}) - .pipe(catchError(ErrorHandler.handle)); - } -} diff --git a/src/app/workspace-monitor/workspace-monitor-routing.module.ts b/src/app/workspace-monitor/workspace-monitor-routing.module.ts deleted file mode 100644 index 0ec6b9f9b1017b6144418a3dd58e03f74ef43c62..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor-routing.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { WorkspaceMonitorComponent } from './workspace-monitor.component'; - -const routes: Routes = [{ - path: '', - component: WorkspaceMonitorComponent -}]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class WorkspaceMonitorRoutingModule { } diff --git a/src/app/workspace-monitor/workspace-monitor.component.css b/src/app/workspace-monitor/workspace-monitor.component.css deleted file mode 100644 index efc397ba31fa8530440f8960e54c125d125954dd..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.component.css +++ /dev/null @@ -1,26 +0,0 @@ -.adminbackground { - flex: 10 0 900px; - box-shadow: 5px 10px 20px black; - background-color: white; - min-height: 85%; - margin: 15px; - padding: 25px; -} - -.columnhost { - width: 100%; - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: flex-start; - justify-content: left; -} - -.cellstyle1 { - padding: 5px; -} - -.mat-raised-button { - margin: 5px; - min-width: 100px; -} diff --git a/src/app/workspace-monitor/workspace-monitor.component.html b/src/app/workspace-monitor/workspace-monitor.component.html deleted file mode 100644 index 920f5a8a60107b5bc311b3afc93d48d87b6460a5..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.component.html +++ /dev/null @@ -1,89 +0,0 @@ -<div id="buttonsContainer" fxLayout="row" fxLayoutAlign="start center"> - <a [routerLink]="['/']"> - <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/> - </a> - <div fxLayout="row wrap" fxLayoutAlign="space-between center" fxFlex> - <div>IQB-Testcenter Monitor</div> - <div>{{ workspaceName }}</div> - </div> -</div> -<div class="page-body"> - <div class="adminbackground"> - - <div class="columnhost" fxLayout="column"> - <div class="spinner" *ngIf="dataLoading"> - <mat-spinner></mat-spinner> - </div> - <div fxLayout="row"> - <button mat-raised-button (click)="downloadCSV()" [disabled]="!tableselectionCheckbox.hasValue()" - matTooltip="Download markierte Gruppen als CSV für Excel" matTooltipPosition="above"> - <mat-icon>cloud_download</mat-icon> - </button> - <button mat-raised-button (click)="lock()" [disabled]="!tableselectionCheckbox.hasValue()" - matTooltip="Sperre gestartete Testhefte für markierte Gruppen" matTooltipPosition="above"> - <mat-icon>lock</mat-icon> - </button> - - <button mat-raised-button (click)="unlock()" [disabled]="!tableselectionCheckbox.hasValue()" - matTooltip="Gesperrte Testhefte für markierte Gruppen freigeben" matTooltipPosition="above"> - <mat-icon>lock_open</mat-icon> - </button> - </div> - - <mat-table [dataSource]="monitorDataSource" matSort> - <ng-container matColumnDef="selectCheckbox"> - <mat-header-cell *matHeaderCellDef fxFlex="70px"> - <mat-checkbox (change)="$event ? masterToggle() : null" - [checked]="tableselectionCheckbox.hasValue() && isAllSelected()" - [indeterminate]="tableselectionCheckbox.hasValue() && !isAllSelected()"> - </mat-checkbox> - </mat-header-cell> - <mat-cell *matCellDef="let row" fxFlex="70px"> - <mat-checkbox (click)="$event.stopPropagation()" - (change)="$event ? tableselectionCheckbox.toggle(row) : null" - [checked]="tableselectionCheckbox.isSelected(row)"> - </mat-checkbox> - </mat-cell> - </ng-container> - - <ng-container matColumnDef="groupname"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxFlex="300px">Login-Gruppe</mat-header-cell> - <mat-cell *matCellDef="let element" fxFlex="300px">{{element.groupname}}</mat-cell> - </ng-container> - - <ng-container matColumnDef="loginsPrepared"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">Logins</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center">{{element.loginsPrepared}} </mat-cell> - </ng-container> - - <ng-container matColumnDef="personsPrepared"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">Personen</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center"> {{element.personsPrepared}} </mat-cell> - </ng-container> - - <ng-container matColumnDef="bookletsPrepared"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">Testhefte insges.</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center"> {{element.bookletsPrepared}} </mat-cell> - </ng-container> - - <ng-container matColumnDef="bookletsStarted"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">Testhefte gestartet</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center"> {{element.bookletsStarted}} </mat-cell> - </ng-container> - - <ng-container matColumnDef="bookletsLocked"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">gesperrte Testhefte</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center"> {{ element.bookletsLocked }} </mat-cell> - </ng-container> - - <ng-container matColumnDef="laststart"> - <mat-header-cell *matHeaderCellDef mat-sort-header fxLayoutAlign="center center">Letzter Start</mat-header-cell> - <mat-cell *matCellDef="let element" fxLayoutAlign="center center"> {{ element.laststartStr }} </mat-cell> - </ng-container> - - <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> - </mat-table> - </div> - </div> -</div> diff --git a/src/app/workspace-monitor/workspace-monitor.component.ts b/src/app/workspace-monitor/workspace-monitor.component.ts deleted file mode 100644 index 8a43a5f3481cfe047a386952c547b57065d25344..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.component.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { - Component, OnDestroy, OnInit, ViewChild -} from '@angular/core'; -import { MatTableDataSource } from '@angular/material/table'; -import { SelectionModel } from '@angular/cdk/collections'; -import { ActivatedRoute } from '@angular/router'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { MatSort } from '@angular/material/sort'; -import { Subscription } from 'rxjs'; - -import { ServerError } from 'iqb-components'; -import { BookletsStarted, MonitorData } from './workspace-monitor.interfaces'; -import { BackendService } from './backend.service'; -import { MainDataService } from '../maindata.service'; - -@Component({ - selector: 'app-workspace-monitor', - templateUrl: './workspace-monitor.component.html', - styleUrls: ['./workspace-monitor.component.css'] -}) -export class WorkspaceMonitorComponent implements OnInit, OnDestroy { - private routingSubscription: Subscription = null; - workspaceId = 0; - workspaceName = ''; - - displayedColumns: string[] = ['selectCheckbox', 'groupname', 'loginsPrepared', - 'personsPrepared', 'bookletsPrepared', 'bookletsStarted', 'bookletsLocked', 'laststart']; - public monitorDataSource = new MatTableDataSource<MonitorData>([]); - public tableselectionCheckbox = new SelectionModel<MonitorData>(true, []); - public dataLoading = false; - @ViewChild(MatSort, { static: true }) sort: MatSort; - - constructor( - private route: ActivatedRoute, - private bs: BackendService, - public mds: MainDataService, - public snackBar: MatSnackBar - ) { } - - ngOnInit(): void { - this.routingSubscription = this.route.params.subscribe((params) => { - this.workspaceId = Number(params['ws']); - this.workspaceName = 'xx'; // TODO where to get the workspace name from? - this.updateTable(); - }); - } - - updateTable(): void { - this.dataLoading = true; - this.tableselectionCheckbox.clear(); - this.bs.getMonitorData(this.workspaceId).subscribe( - (monitorData: MonitorData[]) => { - this.dataLoading = false; - this.monitorDataSource = new MatTableDataSource<MonitorData>(monitorData); - this.monitorDataSource.sort = this.sort; - } - ); - } - - isAllSelected(): boolean { - const numSelected = this.tableselectionCheckbox.selected.length; - const numRows = this.monitorDataSource.data.length; - return numSelected === numRows; - } - - masterToggle(): void { - this.isAllSelected() ? - this.tableselectionCheckbox.clear() : - this.monitorDataSource.data.forEach(row => this.tableselectionCheckbox.select(row)); - } - - downloadCSV() { - if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; - const selectedGroups: string[] = []; - this.tableselectionCheckbox.selected.forEach(element => { - selectedGroups.push(element.groupname); - }); - this.bs.getBookletsStarted(this.workspaceId, selectedGroups).subscribe((bData) => { - const bookletList = bData as BookletsStarted[]; - if (bookletList.length > 0) { - const columnDelimiter = ';'; - const lineDelimiter = '\n'; - - let myCsvData = 'groupname' + columnDelimiter + 'loginname' + columnDelimiter + 'code' + columnDelimiter + - 'bookletname' + columnDelimiter + 'locked' + columnDelimiter + 'laststart' + lineDelimiter; - bookletList.forEach((b: BookletsStarted) => { - myCsvData += '"' - + b.groupname + '"' + columnDelimiter + '"' - + b.loginname + '"' + columnDelimiter + '"' - + b.code + '"' + columnDelimiter + '"' - + b.bookletname + '"' + columnDelimiter - + '"' + (b.locked ? 'X' : '-') + '"' + columnDelimiter + '"' - + b.laststart + '"' + lineDelimiter; - }); - const blob = new Blob([myCsvData], { type: 'text/csv;charset=utf-8' }); - saveAs(blob, 'iqb-testcenter-bookletsStarted.csv'); - } else { - this.snackBar.open('Keine Daten verfügbar.', 'Fehler', { duration: 3000 }); - } - - this.tableselectionCheckbox.clear(); - this.dataLoading = false; - }); - } - } - - lock(): void { - if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; - const selectedGroups: string[] = []; - this.tableselectionCheckbox.selected.forEach((element) => { - selectedGroups.push(element.groupname); - }); - this.bs.lockBooklets(this.workspaceId, selectedGroups).subscribe((success) => { - if (success instanceof ServerError) { - this.snackBar.open('Testhefte konnten nicht gesperrt werden.', 'Systemfehler', { duration: 3000 }); - } else { - const ok = success as boolean; - if (ok) { - this.snackBar.open('Testhefte wurden gesperrt.', 'Sperrung', { duration: 1000 }); - } else { - this.snackBar.open('Testhefte konnten nicht gesperrt werden.', 'Fehler', { duration: 3000 }); - } - } - this.dataLoading = false; - this.updateTable(); - }); - } - } - - unlock(): void { - if (this.tableselectionCheckbox.selected.length > 0) { - this.dataLoading = true; - const selectedGroups: string[] = []; - this.tableselectionCheckbox.selected.forEach((element) => { - selectedGroups.push(element.groupname); - }); - this.bs.unlockBooklets(this.workspaceId, selectedGroups).subscribe((success) => { - if (success instanceof ServerError) { - this.snackBar.open('Testhefte konnten nicht freigegeben werden.', 'Systemfehler', { duration: 3000 }); - } else { - const ok = success as boolean; - if (ok) { - this.snackBar.open('Testhefte wurden freigegeben.', 'Sperrung', { duration: 1000 }); - } else { - this.snackBar.open('Testhefte konnten nicht freigegeben werden.', 'Fehler', { duration: 3000 }); - } - } - this.dataLoading = false; - this.updateTable(); - }); - } - } - - ngOnDestroy(): void { - if (this.routingSubscription !== null) { - this.routingSubscription.unsubscribe(); - } - } -} diff --git a/src/app/workspace-monitor/workspace-monitor.interfaces.ts b/src/app/workspace-monitor/workspace-monitor.interfaces.ts deleted file mode 100644 index 8cd7ae1fac3fb4f6c576af52562645a496edb17a..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.interfaces.ts +++ /dev/null @@ -1,19 +0,0 @@ -export interface MonitorData { - groupname: string; - loginsPrepared: number; - personsPrepared: number; - bookletsPrepared: number; - bookletsStarted: number; - bookletsLocked: number; - laststart: Date; - laststartStr: string; -} - -export interface BookletsStarted { - groupname: string; - loginname: string; - code: string; - bookletname: string; - locked: boolean; - laststart: Date; -} diff --git a/src/app/workspace-monitor/workspace-monitor.module.spec.ts b/src/app/workspace-monitor/workspace-monitor.module.spec.ts deleted file mode 100644 index 4118ff7f16464bd2c9159f4c46df78c9bf3ca964..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.module.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { WorkspaceMonitorModule } from './workspace-monitor.module'; - -describe('WorkspaceMonitorModule', () => { - let workspaceMonitorModule: WorkspaceMonitorModule; - - beforeEach(() => { - workspaceMonitorModule = new WorkspaceMonitorModule(); - }); - - it('should create an instance', () => { - expect(workspaceMonitorModule).toBeTruthy(); - }); -}); diff --git a/src/app/workspace-monitor/workspace-monitor.module.ts b/src/app/workspace-monitor/workspace-monitor.module.ts deleted file mode 100644 index 0fc765bdd8a24410d7e0e7cb23c8dc7e47959f41..0000000000000000000000000000000000000000 --- a/src/app/workspace-monitor/workspace-monitor.module.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { MatTableModule } from '@angular/material/table'; -import { MatSortModule } from '@angular/material/sort'; -import { MatSnackBarModule } from '@angular/material/snack-bar'; -import { FlexLayoutModule } from '@angular/flex-layout'; -import { MatIconModule } from '@angular/material/icon'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; - -import { IqbComponentsModule } from 'iqb-components'; -import { BackendService } from './backend.service'; -import { WorkspaceMonitorRoutingModule } from './workspace-monitor-routing.module'; -import { WorkspaceMonitorComponent } from './workspace-monitor.component'; - -@NgModule({ - declarations: [WorkspaceMonitorComponent], - imports: [ - CommonModule, - MatTableModule, - MatSortModule, - MatSnackBarModule, - IqbComponentsModule, - WorkspaceMonitorRoutingModule, - FlexLayoutModule, - MatIconModule, - MatProgressSpinnerModule, - ReactiveFormsModule, - MatTooltipModule, - MatCheckboxModule, - MatButtonModule - ], - providers: [ - BackendService - ] -}) -export class WorkspaceMonitorModule { }