diff --git a/src/app/group-monitor/booklet.service.spec.ts b/src/app/group-monitor/booklet/booklet.service.spec.ts similarity index 75% rename from src/app/group-monitor/booklet.service.spec.ts rename to src/app/group-monitor/booklet/booklet.service.spec.ts index d6dacc9e7aa26d5282e6fd5358f8acc89fe04507..bea117e3e128797b0af33b22d89b566bfc98861a 100644 --- a/src/app/group-monitor/booklet.service.spec.ts +++ b/src/app/group-monitor/booklet/booklet.service.spec.ts @@ -3,8 +3,7 @@ import { MatIconModule } from '@angular/material/icon'; import { TestBed } from '@angular/core/testing'; import { Observable, of } from 'rxjs'; import { BookletService } from './booklet.service'; -import { BackendService } from './backend.service'; -import { unitTestExampleBooklets } from './test-data.spec'; +import { BackendService } from '../backend.service'; class MockBackendService { // eslint-disable-next-line class-methods-use-this,@typescript-eslint/no-unused-vars @@ -34,24 +33,6 @@ describe('BookletService', () => { expect(service).toBeTruthy(); }); - it('getFirstUnit() should get first unit if a testlet, regardless of nested sub-testlets', () => { - expect(BookletService.getFirstUnit(unitTestExampleBooklets.example_booklet_1.units).id).toEqual('unit-1'); - expect(BookletService.getFirstUnit(unitTestExampleBooklets.example_booklet_2.units).id).toEqual('unit-1'); - expect(BookletService.getFirstUnit(unitTestExampleBooklets.example_booklet_2.units.children[2])).toBeNull(); - }); - - describe('getBlockById()', () => { - it('should return the block by id', () => { - const result = BookletService.getBlockById('block-2', unitTestExampleBooklets.example_booklet_1); - expect(result.id).toEqual('alf'); - }); - - it('should return null when blockId is not found in booklet', () => { - const result = BookletService.getBlockById('not-existing', unitTestExampleBooklets.example_booklet_1); - expect(result).toBeNull(); - }); - }); - xit('parseBookletXml() should parse a Booklet-Xml to a Booklet-Object', () => { // TODO implement unit.test }); diff --git a/src/app/group-monitor/booklet.service.ts b/src/app/group-monitor/booklet/booklet.service.ts similarity index 83% rename from src/app/group-monitor/booklet.service.ts rename to src/app/group-monitor/booklet/booklet.service.ts index 7b192bf6b09f9c592c0edfcd15885cb3d79954e1..7f7d468f8e3b46f5caffa275660d7afb8c8df5a0 100644 --- a/src/app/group-monitor/booklet.service.ts +++ b/src/app/group-monitor/booklet/booklet.service.ts @@ -3,13 +3,13 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; -import { MainDataService } from '../maindata.service'; -import { BackendService } from './backend.service'; +import { MainDataService } from '../../maindata.service'; +import { BackendService } from '../backend.service'; import { Booklet, BookletError, BookletMetadata, isUnit, Restrictions, Testlet, Unit -} from './group-monitor.interfaces'; +} from '../group-monitor.interfaces'; // eslint-disable-next-line import/extensions -import { BookletConfig } from '../config/booklet-config'; +import { BookletConfig } from '../../config/booklet-config'; @Injectable() export class BookletService { @@ -19,49 +19,6 @@ export class BookletService { private bs: BackendService ) { } - static getFirstUnit(testletOrUnit: Testlet|Unit): Unit|null { - while (!isUnit(testletOrUnit)) { - if (!testletOrUnit.children.length) { - return null; - } - // eslint-disable-next-line no-param-reassign,prefer-destructuring - testletOrUnit = testletOrUnit.children[0]; - } - return testletOrUnit; - } - - static getFirstUnitOfBlock(blockId: string, booklet: Booklet): Unit|null { - for (let i = 0; i < booklet.units.children.length; i++) { - const child = booklet.units.children[i]; - if (!isUnit(child) && (child.blockId === blockId)) { - return BookletService.getFirstUnit(child); - } - } - return null; - } - - static getBlockById(blockId: string, booklet: Booklet): Testlet { - return <Testlet>booklet.units.children - .filter(testletOrUnit => !isUnit(testletOrUnit)) - .reduce((found: Testlet, block: Testlet) => ((block.blockId === blockId) ? block : found), null); - } - - static addBookletStructureInformation(booklet: Booklet): void { - booklet.species = BookletService.getBookletSpecies(booklet); - booklet.units.children - .filter(testletOrUnit => !isUnit(testletOrUnit)) - .forEach((block: Testlet, index, blocks) => { - block.blockId = `block ${index + 1}`; - if (index < blocks.length - 1) { - block.nextBlockId = `block ${index + 2}`; - } - }); - } - - static getBookletSpecies(booklet: Booklet): string { - return `species: ${booklet.units.children.filter(testletOrUnit => !isUnit(testletOrUnit)).length}`; - } - getBooklet(bookletName = ''): Observable<Booklet|BookletError> { if (typeof this.booklets[bookletName] !== 'undefined') { return this.booklets[bookletName]; @@ -103,6 +60,22 @@ export class BookletService { } } + private static addBookletStructureInformation(booklet: Booklet): void { + booklet.species = BookletService.getBookletSpecies(booklet); + booklet.units.children + .filter(testletOrUnit => !isUnit(testletOrUnit)) + .forEach((block: Testlet, index, blocks) => { + block.blockId = `block ${index + 1}`; + if (index < blocks.length - 1) { + block.nextBlockId = `block ${index + 2}`; + } + }); + } + + private static getBookletSpecies(booklet: Booklet): string { + return `species: ${booklet.units.children.filter(testletOrUnit => !isUnit(testletOrUnit)).length}`; + } + private static parseBookletConfig(bookletElement: Element): BookletConfig { const bookletConfigElements = BookletService.xmlGetChildIfExists(bookletElement, 'BookletConfig', true); const bookletConfig = new BookletConfig(); diff --git a/src/app/group-monitor/booklet/booklet.util.spec.ts b/src/app/group-monitor/booklet/booklet.util.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..649668bd43c28b429331d52b690a53428d5d5030 --- /dev/null +++ b/src/app/group-monitor/booklet/booklet.util.spec.ts @@ -0,0 +1,22 @@ +import { unitTestExampleBooklets } from '../unit-test-example-data.spec'; +import { BookletUtil } from './booklet.util'; + +describe('BookletUtil', () => { + it('getFirstUnit() should get first unit if a testlet, regardless of nested sub-testlets', () => { + expect(BookletUtil.getFirstUnit(unitTestExampleBooklets.example_booklet_1.units).id).toEqual('unit-1'); + expect(BookletUtil.getFirstUnit(unitTestExampleBooklets.example_booklet_2.units).id).toEqual('unit-1'); + expect(BookletUtil.getFirstUnit(unitTestExampleBooklets.example_booklet_2.units.children[2])).toBeNull(); + }); + + describe('getBlockById()', () => { + it('should return the block by id', () => { + const result = BookletUtil.getBlockById('block-2', unitTestExampleBooklets.example_booklet_1); + expect(result.id).toEqual('alf'); + }); + + it('should return null when blockId is not found in booklet', () => { + const result = BookletUtil.getBlockById('not-existing', unitTestExampleBooklets.example_booklet_1); + expect(result).toBeNull(); + }); + }); +}); diff --git a/src/app/group-monitor/booklet/booklet.util.ts b/src/app/group-monitor/booklet/booklet.util.ts new file mode 100644 index 0000000000000000000000000000000000000000..decadb25200cee31461ced4bee2b06e07bce93c4 --- /dev/null +++ b/src/app/group-monitor/booklet/booklet.util.ts @@ -0,0 +1,32 @@ +import { + Booklet, isUnit, Testlet, Unit +} from '../group-monitor.interfaces'; + +export class BookletUtil { + static getFirstUnit(testletOrUnit: Testlet|Unit): Unit|null { + while (!isUnit(testletOrUnit)) { + if (!testletOrUnit.children.length) { + return null; + } + // eslint-disable-next-line no-param-reassign,prefer-destructuring + testletOrUnit = testletOrUnit.children[0]; + } + return testletOrUnit; + } + + static getFirstUnitOfBlock(blockId: string, booklet: Booklet): Unit|null { + for (let i = 0; i < booklet.units.children.length; i++) { + const child = booklet.units.children[i]; + if (!isUnit(child) && (child.blockId === blockId)) { + return BookletUtil.getFirstUnit(child); + } + } + return null; + } + + static getBlockById(blockId: string, booklet: Booklet): Testlet { + return <Testlet>booklet.units.children + .filter(testletOrUnit => !isUnit(testletOrUnit)) + .reduce((found: Testlet, block: Testlet) => ((block.blockId === blockId) ? block : found), null); + } +} diff --git a/src/app/group-monitor/group-monitor.component.css b/src/app/group-monitor/group-monitor.component.css index 0c6eff40c6f590a74946bab15358d639703abb80..59fd008c65be41b33156e57b2dba5cd5a7cb20ee 100644 --- a/src/app/group-monitor/group-monitor.component.css +++ b/src/app/group-monitor/group-monitor.component.css @@ -2,25 +2,25 @@ overflow-x: hidden; } -.test-view-table { +.test-session-table { border-collapse: collapse; display: table; width: 100%; } -.test-view-table thead tr td { +.test-session-table thead tr td { position: sticky; top: 0; z-index: 2; background: rgba(255, 255, 255, 0.8); } -.test-view-table td { +.test-session-table td { padding-top: 15px; margin-right: 1em; } -.test-view-table td[mat-sort-header="_checked"] { +.test-session-table td[mat-sort-header="_checked"] { padding-left: 5px; } diff --git a/src/app/group-monitor/group-monitor.component.html b/src/app/group-monitor/group-monitor.component.html index 4071b48b0dc9e2fb95576c54c7023eafbfbb19fc..37111736f0f64fe1bf2b5816eee577ff443f6570 100644 --- a/src/app/group-monitor/group-monitor.component.html +++ b/src/app/group-monitor/group-monitor.component.html @@ -5,7 +5,7 @@ </p> <span class="fill-remaining-space"></span> <p> - <mat-chip-list *ngIf="gms.connectionStatus$ | async as connectionStatus"> + <mat-chip-list *ngIf="connectionStatus$ | async as connectionStatus"> <mat-chip [class]="connectionStatus + ' connection-status'"> <mat-icon> @@ -38,7 +38,7 @@ </mat-menu> <mat-menu #filters="matMenu"> - <button mat-menu-item *ngFor="let filterOption of gms.filterOptions; let i = index" (click)="gms.switchFilter(i)"> + <button mat-menu-item *ngFor="let filterOption of tsm.filterOptions; let i = index" (click)="tsm.switchFilter(i)"> <mat-icon *ngIf="filterOption.selected">check</mat-icon> <span>{{filterOption.label | customtext:filterOption.label | async}}</span> </button> @@ -85,12 +85,12 @@ <h2>{{'Test-Steuerung' | customtext:'gm_controls' | async}}</h2> - <div class="toolbar-section" *ngIf="gms.sessionsStats$ | async as sessionsStats"> + <div class="toolbar-section" *ngIf="tsm.sessionsStats$ | async as sessionsStats"> <mat-slide-toggle color="accent" (change)="toggleAlwaysCheckAll($event)" - [disabled]="!gms.checkingOptions.enableAutoCheckAll" - [checked]="gms.checkingOptions.autoCheckAll" + [disabled]="!tsm.checkingOptions.enableAutoCheckAll" + [checked]="tsm.checkingOptions.autoCheckAll" [matTooltip]="(sessionsStats.differentBookletSpecies > 1) ? ( 'Die verwendeten Booklets sind zu unterschiedlich, um gemeinsam gesteuert zu werden.' | customtext:'gm_multiple_booklet_species_warning' @@ -103,7 +103,7 @@ <div class="toolbar-section min-height-section"> <ng-container *ngIf="displayOptions.manualChecking"> - <ng-container *ngIf="gms.checkedStats$ | async as checkedStats"> + <ng-container *ngIf="tsm.checkedStats$ | async as checkedStats"> <alert *ngIf="checkedStats.number; else noCheckedSession" level="info" @@ -125,12 +125,12 @@ </div> <div class="toolbar-section"> - <button mat-raised-button class="control" color="primary" (click)="gms.testCommandResume()"> + <button mat-raised-button class="control" color="primary" (click)="tsm.testCommandResume()"> <mat-icon>play_arrow</mat-icon> {{'weiter' | customtext:'gm_control_resume' | async}} </button> - <button mat-raised-button class="control" color="primary" (click)="gms.testCommandPause()"> + <button mat-raised-button class="control" color="primary" (click)="tsm.testCommandPause()"> <mat-icon>pause</mat-icon> {{'pause' | customtext:'gm_control_pause' | async}} </button> @@ -208,13 +208,13 @@ </button> </div> - <div class="test-view-table-wrapper"> - <table class="test-view-table" matSort (matSortChange)="setTableSorting($event)"> + <div class="test-session-table-wrapper"> + <table class="test-session-table" matSort (matSortChange)="setTableSorting($event)"> <thead> <tr class="mat-sort-container"> <td mat-sort-header="_checked" *ngIf="displayOptions.manualChecking"> <mat-checkbox - *ngIf="gms.checkedStats$ | async as checkedStats" + *ngIf="tsm.checkedStats$ | async as checkedStats" (click)="$event.stopPropagation()" (change)="toggleCheckAll($event)" [checked]="checkedStats.all" @@ -245,19 +245,19 @@ </tr> </thead> - <ng-container *ngFor="let session of gms.sessions$ | async; trackBy: trackSession"> - <tc-test-view + <ng-container *ngFor="let session of tsm.sessions$ | async; trackBy: trackSession"> + <tc-test-session [testSession]="session" [displayOptions]="displayOptions" [marked]="markedElement" (markedElement$)="markElement($event)" [selected]="selectedElement" (selectedElement$)="selectElement($event)" - [checked]="gms.isChecked(session)" + [checked]="tsm.isChecked(session)" (checked$)="toggleChecked($event, session)" [ngStyle]="{background: getSessionColor(session)}" > - </tc-test-view> + </tc-test-session> </ng-container> </table> </div> diff --git a/src/app/group-monitor/group-monitor.component.spec.ts b/src/app/group-monitor/group-monitor.component.spec.ts index d336edf2e43958994a8b7691cdb7d2bd07fa756e..24fe392dfcd25a39d0113daa9b8ef3840669a0ac 100644 --- a/src/app/group-monitor/group-monitor.component.spec.ts +++ b/src/app/group-monitor/group-monitor.component.spec.ts @@ -22,14 +22,14 @@ import { TestSessionData, TestSessionSetStats } from './group-monitor.interfaces'; import { BackendService } from './backend.service'; -import { TestViewComponent } from './test-view/test-view.component'; -import { GroupMonitorService } from './group-monitor.service'; +import { TestSessionComponent } from './test-session/test-session.component'; +import { TestSessionManager } from './test-session-manager/test-session-manager.service'; import { unitTestSessionsStats, unitTestCheckedStats, unitTestExampleSessions, unitTestCommandResponse -} from './test-data.spec'; +} from './unit-test-example-data.spec'; import { AlertModule } from '../shared/alert/alert.module'; class MockMatDialog { @@ -55,7 +55,7 @@ class MockBackendService { cutConnection(): void {} } -class MockGroupMonitorService { +class MockTestSessionManagerService { checkingOptions: CheckingOptions = { enableAutoCheckAll: false, autoCheckAll: true @@ -89,7 +89,7 @@ describe('GroupMonitorComponent', () => { TestBed.configureTestingModule({ declarations: [ GroupMonitorComponent, - TestViewComponent, + TestSessionComponent, CustomtextPipe ], imports: [ @@ -107,7 +107,7 @@ describe('GroupMonitorComponent', () => { AlertModule ], providers: [ - { provide: GroupMonitorService, useValue: new MockGroupMonitorService() }, + { provide: TestSessionManager, useValue: new MockTestSessionManagerService() }, { provide: MatDialog, useValue: new MockMatDialog() }, { provide: BackendService, useValue: new MockBackendService() } ] diff --git a/src/app/group-monitor/group-monitor.component.ts b/src/app/group-monitor/group-monitor.component.ts index 1c1016220485ffc543313b24984441ea7f23ed69..4d7e1b5d17734f72f975b688abf16cca7ae84de6 100644 --- a/src/app/group-monitor/group-monitor.component.ts +++ b/src/app/group-monitor/group-monitor.component.ts @@ -16,8 +16,9 @@ import { TestViewDisplayOptions, TestViewDisplayOptionKey, Selected, TestSession, TestSessionSetStats, CommandResponse, UIMessage, isBooklet } from './group-monitor.interfaces'; -import { GroupMonitorService } from './group-monitor.service'; -import { BookletService } from './booklet.service'; +import { TestSessionManager } from './test-session-manager/test-session-manager.service'; +import { ConnectionStatus } from '../shared/websocket-backend.service'; +import { BookletUtil } from './booklet/booklet.util'; @Component({ selector: 'app-group-monitor', @@ -28,12 +29,14 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { constructor( public dialog: MatDialog, private route: ActivatedRoute, - private bs: BackendService, // TODO move completely to service - public gms: GroupMonitorService, + private bs: BackendService, + public tsm: TestSessionManager, private router: Router, private cts: CustomtextService ) {} + connectionStatus$: Observable<ConnectionStatus>; + ownGroup$: Observable<GroupData>; private ownGroupName = ''; @@ -65,21 +68,23 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { this.route.params.subscribe(params => { this.ownGroup$ = this.bs.getGroupData(params['group-name']); this.ownGroupName = params['group-name']; - this.gms.connect(params['group-name']); + this.tsm.connect(params['group-name']); }), - this.gms.sessionsStats$.subscribe(stats => { + this.tsm.sessionsStats$.subscribe(stats => { this.onSessionsUpdate(stats); }), - this.gms.checkedStats$.subscribe(stats => { + this.tsm.checkedStats$.subscribe(stats => { this.onCheckedChange(stats); }), - this.gms.commandResponses$.subscribe(commandResponse => { + this.tsm.commandResponses$.subscribe(commandResponse => { this.messages.push(this.commandResponseToMessage(commandResponse)); }), - this.gms.commandResponses$ + this.tsm.commandResponses$ .pipe(switchMap(() => interval(7000))) .subscribe(() => this.messages.shift()) ]; + + this.connectionStatus$ = this.bs.connectionStatus$; } private commandResponseToMessage(commandResponse: CommandResponse): UIMessage { @@ -102,7 +107,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { } ngOnDestroy(): void { - this.gms.disconnect(); + this.tsm.disconnect(); this.subscriptions.forEach(subscription => subscription.unsubscribe()); } @@ -113,7 +118,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { private onSessionsUpdate(stats: TestSessionSetStats): void { this.displayOptions.highlightSpecies = (stats.differentBookletSpecies > 1); - if (!this.gms.checkingOptions.enableAutoCheckAll) { + if (!this.tsm.checkingOptions.enableAutoCheckAll) { this.displayOptions.manualChecking = true; } } @@ -130,7 +135,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { if (!sort.active || sort.direction === '') { return; } - this.gms.sortBy$.next(sort); + this.tsm.sortBy$.next(sort); } setDisplayOption(option: string, value: TestViewDisplayOptions[TestViewDisplayOptionKey]): void { @@ -180,7 +185,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { } selectElement(selected: Selected): void { - this.gms.checkSessionsBySelection(selected); + this.tsm.checkSessionsBySelection(selected); this.selectedElement = selected; } @@ -198,7 +203,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { dialogRef.afterClosed().subscribe((confirmed: boolean) => { if (confirmed) { this.isClosing = true; - this.gms.commandFinishEverything() + this.tsm.commandFinishEverything() .subscribe(() => { setTimeout(() => { this.router.navigateByUrl('/r/login'); }, 5000); // go away }); @@ -214,7 +219,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { text: 'Kein Zielblock ausgewählt' }); } else { - this.gms.testCommandGoto(this.selectedElement) + this.tsm.testCommandGoto(this.selectedElement) .subscribe(() => this.selectNextBlock()); } } @@ -225,7 +230,7 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { } this.selectedElement = { element: this.selectedElement.element.nextBlockId ? - BookletService.getBlockById( + BookletUtil.getBlockById( this.selectedElement.element.nextBlockId, this.selectedElement.originSession.booklet ) : null, @@ -236,40 +241,40 @@ export class GroupMonitorComponent implements OnInit, OnDestroy { } unlockCommand(): void { - this.gms.testCommandUnlock(); + this.tsm.testCommandUnlock(); } toggleChecked(checked: boolean, session: TestSession): void { - if (!this.gms.isChecked(session)) { - this.gms.checkSession(session); + if (!this.tsm.isChecked(session)) { + this.tsm.checkSession(session); } else { - this.gms.uncheckSession(session); + this.tsm.uncheckSession(session); } } invertChecked(event: Event): boolean { event.preventDefault(); - this.gms.invertChecked(); + this.tsm.invertChecked(); return false; } toggleAlwaysCheckAll(event: MatSlideToggleChange): void { - if (this.gms.checkingOptions.enableAutoCheckAll && event.checked) { - this.gms.checkAll(); + if (this.tsm.checkingOptions.enableAutoCheckAll && event.checked) { + this.tsm.checkAll(); this.displayOptions.manualChecking = false; - this.gms.checkingOptions.autoCheckAll = true; + this.tsm.checkingOptions.autoCheckAll = true; } else { - this.gms.checkNone(); + this.tsm.checkNone(); this.displayOptions.manualChecking = true; - this.gms.checkingOptions.autoCheckAll = false; + this.tsm.checkingOptions.autoCheckAll = false; } } toggleCheckAll(event: MatCheckboxChange): void { if (event.checked) { - this.gms.checkAll(); + this.tsm.checkAll(); } else { - this.gms.checkNone(); + this.tsm.checkNone(); } } } diff --git a/src/app/group-monitor/group-monitor.module.ts b/src/app/group-monitor/group-monitor.module.ts index 00625b1fd19740a5f662387a029a2a6bc5e13e79..08c5bf51de3628f5a235b84756fcc858e3d25a25 100644 --- a/src/app/group-monitor/group-monitor.module.ts +++ b/src/app/group-monitor/group-monitor.module.ts @@ -20,16 +20,15 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { GroupMonitorRoutingModule } from './group-monitor-routing.module'; import { GroupMonitorComponent } from './group-monitor.component'; import { BackendService } from './backend.service'; -import { BookletService } from './booklet.service'; -import { TestViewComponent } from './test-view/test-view.component'; -import { TestSessionService } from './test-session.service'; -import { GroupMonitorService } from './group-monitor.service'; +import { BookletService } from './booklet/booklet.service'; +import { TestSessionComponent } from './test-session/test-session.component'; +import { TestSessionManager } from './test-session-manager/test-session-manager.service'; import { AlertModule } from '../shared/alert/alert.module'; @NgModule({ declarations: [ GroupMonitorComponent, - TestViewComponent + TestSessionComponent ], imports: [ CommonModule, @@ -55,8 +54,7 @@ import { AlertModule } from '../shared/alert/alert.module'; providers: [ BackendService, BookletService, - TestSessionService, - GroupMonitorService + TestSessionManager ] }) export class GroupMonitorModule { diff --git a/src/app/group-monitor/group-monitor.service.spec.ts b/src/app/group-monitor/test-session-manager/test-session-manager.service.spec.ts similarity index 94% rename from src/app/group-monitor/group-monitor.service.spec.ts rename to src/app/group-monitor/test-session-manager/test-session-manager.service.spec.ts index 610d30a7170468d056883d6084621f433c74cbb4..1e03671db776dc1375b6bfe628e196ab67f1d534 100644 --- a/src/app/group-monitor/group-monitor.service.spec.ts +++ b/src/app/group-monitor/test-session-manager/test-session-manager.service.spec.ts @@ -8,11 +8,13 @@ import { BookletError, CommandResponse, GroupData, Selected, Testlet, TestSessionData, TestSessionFilter, TestSessionSetStats -} from './group-monitor.interfaces'; -import { BookletService } from './booklet.service'; -import { BackendService } from './backend.service'; -import { GroupMonitorService } from './group-monitor.service'; -import { unitTestExampleSessions, unitTestExampleBooklets, additionalUnitTestExampleSessions } from './test-data.spec'; +} from '../group-monitor.interfaces'; +import { BookletService } from '../booklet/booklet.service'; +import { BackendService } from '../backend.service'; +import { TestSessionManager } from './test-session-manager.service'; +import { + unitTestExampleSessions, unitTestExampleBooklets, additionalUnitTestExampleSessions +} from '../unit-test-example-data.spec'; class MockBookletService { booklets: Observable<Booklet>[] = [of(unitTestExampleBooklets.example_booklet_1)]; @@ -58,21 +60,21 @@ class MockCustomtextPipe { } } -describe('GroupMonitorService', () => { - let service: GroupMonitorService; +describe('TestSessionManager', () => { + let service: TestSessionManager; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [], imports: [], providers: [ - GroupMonitorService, + TestSessionManager, { provide: BookletService, useValue: new MockBookletService() }, { provide: BackendService, useValue: new MockBackendService() } ] }) .compileComponents(); - service = TestBed.inject(GroupMonitorService); + service = TestBed.inject(TestSessionManager); service.connect('unit-test-group-name'); })); @@ -161,7 +163,7 @@ describe('GroupMonitorService', () => { describe('getSessionSetStats', () => { it('should fetch correct stats from sessions', () => { // eslint-disable-next-line @typescript-eslint/dot-notation - const result = GroupMonitorService['getSessionSetStats'](unitTestExampleSessions, 2); + const result = TestSessionManager['getSessionSetStats'](unitTestExampleSessions, 2); const expectation: TestSessionSetStats = { number: 3, differentBooklets: 3, @@ -176,7 +178,7 @@ describe('GroupMonitorService', () => { describe('filterSessions', () => { // eslint-disable-next-line @typescript-eslint/dot-notation - const filterSessions = GroupMonitorService['filterSessions']; + const filterSessions = TestSessionManager['filterSessions']; it('should filter the sessions array by various filters', () => { const sessionsSet = [...unitTestExampleSessions]; @@ -245,7 +247,7 @@ describe('GroupMonitorService', () => { }; const sessions = [...unitTestExampleSessions, ...additionalUnitTestExampleSessions]; // eslint-disable-next-line @typescript-eslint/dot-notation - const result = GroupMonitorService['groupForGoto'](sessions, selection); + const result = TestSessionManager['groupForGoto'](sessions, selection); expect(result).toEqual({ example_booklet_1: { testIds: [1, 33], firstUnitId: 'unit-3' }, example_booklet_3: { testIds: [34], firstUnitId: 'unit-1' } diff --git a/src/app/group-monitor/group-monitor.service.ts b/src/app/group-monitor/test-session-manager/test-session-manager.service.ts similarity index 87% rename from src/app/group-monitor/group-monitor.service.ts rename to src/app/group-monitor/test-session-manager/test-session-manager.service.ts index e67cb87663cf0b37406f1314d7d1293a0c1e2515..6ef84b7ec3181bd182ff853ba17dfd8523c68dd0 100644 --- a/src/app/group-monitor/group-monitor.service.ts +++ b/src/app/group-monitor/test-session-manager/test-session-manager.service.ts @@ -6,26 +6,24 @@ import { Sort } from '@angular/material/sort'; import { delay, flatMap, map, switchMap, tap } from 'rxjs/operators'; -import { BackendService } from './backend.service'; -import { BookletService } from './booklet.service'; -import { TestSessionService } from './test-session.service'; +import { BackendService } from '../backend.service'; +import { BookletService } from '../booklet/booklet.service'; +import { TestSessionUtil } from '../test-session/test-session.util'; import { isBooklet, Selected, CheckingOptions, TestSession, TestSessionFilter, TestSessionSetStats, TestSessionsSuperStates, CommandResponse, GotoCommandData -} from './group-monitor.interfaces'; -import { ConnectionStatus } from '../shared/websocket-backend.service'; +} from '../group-monitor.interfaces'; +import { BookletUtil } from '../booklet/booklet.util'; @Injectable() -export class GroupMonitorService { +export class TestSessionManager { sortBy$: Subject<Sort>; filters$: Subject<TestSessionFilter[]>; checkingOptions: CheckingOptions; - connectionStatus$: Observable<ConnectionStatus>; - private groupName: string; get sessions$(): Observable<TestSession[]> { @@ -96,8 +94,8 @@ export class GroupMonitorService { autoCheckAll: true }; - this._checkedStats$ = new BehaviorSubject<TestSessionSetStats>(GroupMonitorService.getEmptyStats()); - this._sessionsStats$ = new BehaviorSubject<TestSessionSetStats>(GroupMonitorService.getEmptyStats()); + this._checkedStats$ = new BehaviorSubject<TestSessionSetStats>(TestSessionManager.getEmptyStats()); + this._sessionsStats$ = new BehaviorSubject<TestSessionSetStats>(TestSessionManager.getEmptyStats()); this._commandResponses$ = new Subject<CommandResponse>(); this.monitor$ = this.bs.observeSessionsMonitor() @@ -105,7 +103,7 @@ export class GroupMonitorService { switchMap(sessions => zip(...sessions .map(session => this.bookletService.getBooklet(session.bookletName) .pipe( - map(booklet => TestSessionService.analyzeTestSession(session, booklet)) + map(booklet => TestSessionUtil.analyzeTestSession(session, booklet)) )))) ); @@ -113,12 +111,10 @@ export class GroupMonitorService { combineLatest<[Sort, TestSessionFilter[], TestSession[]]>([this.sortBy$, this.filters$, this.monitor$]) .pipe( // eslint-disable-next-line max-len - map(([sortBy, filters, sessions]) => this.sortSessions(sortBy, GroupMonitorService.filterSessions(sessions, filters))), + map(([sortBy, filters, sessions]) => this.sortSessions(sortBy, TestSessionManager.filterSessions(sessions, filters))), tap(sessions => this.synchronizeChecked(sessions)) ) .subscribe(this._sessions$); - - this.connectionStatus$ = this.bs.connectionStatus$; } disconnect(): void { @@ -139,7 +135,7 @@ export class GroupMonitorService { private static filterSessions(sessions: TestSession[], filters: TestSessionFilter[]): TestSession[] { return sessions .filter(session => session.data.testId && session.data.testId > -1) // testsession without testId is deprecated - .filter(session => GroupMonitorService.applyFilters(session, filters)); + .filter(session => TestSessionManager.applyFilters(session, filters)); } private static applyFilters(session: TestSession, filters: TestSessionFilter[]): boolean { @@ -187,7 +183,7 @@ export class GroupMonitorService { } private synchronizeChecked(sessions: TestSession[]): void { - const sessionsStats = GroupMonitorService.getSessionSetStats(sessions); + const sessionsStats = TestSessionManager.getSessionSetStats(sessions); this.checkingOptions.enableAutoCheckAll = (sessionsStats.differentBookletSpecies < 2); @@ -204,7 +200,7 @@ export class GroupMonitorService { }); this._checked = newCheckedSessions; - this._checkedStats$.next(GroupMonitorService.getSessionSetStats(Object.values(this._checked), sessions.length)); + this._checkedStats$.next(TestSessionManager.getSessionSetStats(Object.values(this._checked), sessions.length)); this._sessionsStats$.next(sessionsStats); } @@ -248,7 +244,7 @@ export class GroupMonitorService { testCommandPause(): void { const testIds = this.checked - .filter(session => !TestSessionService.isPaused(session)) + .filter(session => !TestSessionUtil.isPaused(session)) .map(session => session.data.testId); if (!testIds.length) { this._commandResponses$.next({ commandType: 'pause', testIds }); @@ -272,7 +268,7 @@ export class GroupMonitorService { } testCommandGoto(selection: Selected): Observable<true> { - const gfd = GroupMonitorService.groupForGoto(this.checked, selection); + const gfd = TestSessionManager.groupForGoto(this.checked, selection); const allTestIds = this.checked.map(s => s.data.testId); return zip( ...Object.keys(gfd).map(key => this.bs.command('goto', ['id', gfd[key].firstUnitId], gfd[key].testIds)) @@ -291,7 +287,7 @@ export class GroupMonitorService { const groupedByBooklet: GotoCommandData = {}; sessionsSet.forEach(session => { if (!groupedByBooklet[session.data.bookletName] && isBooklet(session.booklet)) { - const firstUnit = BookletService.getFirstUnitOfBlock(selection.element.blockId, session.booklet); + const firstUnit = BookletUtil.getFirstUnitOfBlock(selection.element.blockId, session.booklet); if (firstUnit) { groupedByBooklet[session.data.bookletName] = { testIds: [], @@ -308,7 +304,7 @@ export class GroupMonitorService { testCommandUnlock(): void { const testIds = this.checked - .filter(TestSessionService.isLocked) + .filter(TestSessionUtil.isLocked) .map(session => session.data.testId); if (!testIds.length) { this._commandResponses$.next({ commandType: 'unlock', testIds }); @@ -322,14 +318,14 @@ export class GroupMonitorService { // todo unit test commandFinishEverything(): Observable<CommandResponse> { const getUnlockedConnectedTestIds = () => Object.values(this._sessions$.getValue()) - .filter(session => !TestSessionService.hasState(session.data.testState, 'status', 'locked') && - !TestSessionService.hasState(session.data.testState, 'CONTROLLER', 'TERMINATED') && - (TestSessionService.hasState(session.data.testState, 'CONNECTION', 'POLLING') || - TestSessionService.hasState(session.data.testState, 'CONNECTION', 'WEBSOCKET'))) + .filter(session => !TestSessionUtil.hasState(session.data.testState, 'status', 'locked') && + !TestSessionUtil.hasState(session.data.testState, 'CONTROLLER', 'TERMINATED') && + (TestSessionUtil.hasState(session.data.testState, 'CONNECTION', 'POLLING') || + TestSessionUtil.hasState(session.data.testState, 'CONNECTION', 'WEBSOCKET'))) .map(session => session.data.testId); const getUnlockedTestIds = () => Object.values(this._sessions$.getValue()) .filter(session => session.data.testId > 0) - .filter(session => !TestSessionService.hasState(session.data.testState, 'status', 'locked')) + .filter(session => !TestSessionUtil.hasState(session.data.testState, 'status', 'locked')) .map(session => session.data.testId); this.filters$.next([]); @@ -414,7 +410,7 @@ export class GroupMonitorService { } private onCheckedChanged(): void { - this._checkedStats$.next(GroupMonitorService.getSessionSetStats(this.checked, this.sessions.length)); + this._checkedStats$.next(TestSessionManager.getSessionSetStats(this.checked, this.sessions.length)); } private static getSessionSetStats(sessionSet: TestSession[], all: number = sessionSet.length): TestSessionSetStats { @@ -427,8 +423,8 @@ export class GroupMonitorService { .forEach(session => { booklets.add(session.data.bookletName); bookletSpecies.add(session.booklet.species); - if (TestSessionService.isPaused(session)) paused += 1; - if (TestSessionService.isLocked(session)) locked += 1; + if (TestSessionUtil.isPaused(session)) paused += 1; + if (TestSessionUtil.isLocked(session)) locked += 1; }); return { diff --git a/src/app/group-monitor/test-view/super-states.js b/src/app/group-monitor/test-session/super-states.js similarity index 100% rename from src/app/group-monitor/test-view/super-states.js rename to src/app/group-monitor/test-session/super-states.js diff --git a/src/app/group-monitor/test-view/test-view.component.css b/src/app/group-monitor/test-session/test-session.component.css similarity index 84% rename from src/app/group-monitor/test-view/test-view.component.css rename to src/app/group-monitor/test-session/test-session.component.css index c5ae762d7925132e2d62a91f1e547a477d74c2bd..9db1aecb229c78da2afd7c440c4042b07c500aee 100644 --- a/src/app/group-monitor/test-view/test-view.component.css +++ b/src/app/group-monitor/test-session/test-session.component.css @@ -1,3 +1,38 @@ +:host(tc-test-session) { + display: table-row; + vertical-align: middle; +} + +td { + padding-bottom: 0.2em; + padding-top: 0.2em; + border-bottom: 1px solid silver; + padding-right: 2em; +} + +:host(tc-test-session):last-of-type td { + border-bottom: none; +} + +td.super-state, +td.selected, +td:last-child { + padding-right: 0; +} + +td.selected { + padding-left: 5px; +} + +td:last-child { + min-width: 100%; +} + +:host(test-session:last-child) td { + border-bottom: none; + +} + h1, h2 { font-size: 100%; diff --git a/src/app/group-monitor/test-view/test-view.component.html b/src/app/group-monitor/test-session/test-session.component.html similarity index 100% rename from src/app/group-monitor/test-view/test-view.component.html rename to src/app/group-monitor/test-session/test-session.component.html diff --git a/src/app/group-monitor/test-view/test-view.component.spec.ts b/src/app/group-monitor/test-session/test-session.component.spec.ts similarity index 74% rename from src/app/group-monitor/test-view/test-view.component.spec.ts rename to src/app/group-monitor/test-session/test-session.component.spec.ts index f0f4890107cc1c54e980992690afe49f2b987ae2..a142205a19a84d32fd4581e6b446b1016c95118f 100644 --- a/src/app/group-monitor/test-view/test-view.component.spec.ts +++ b/src/app/group-monitor/test-session/test-session.component.spec.ts @@ -2,24 +2,24 @@ import { MatIconModule } from '@angular/material/icon'; import { MatTooltipModule } from '@angular/material/tooltip'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { MatCheckboxModule } from '@angular/material/checkbox'; -import { TestViewComponent } from './test-view.component'; +import { TestSessionComponent } from './test-session.component'; import { TestViewDisplayOptions } from '../group-monitor.interfaces'; -import { unitTestExampleSessions } from '../test-data.spec'; +import { unitTestExampleSessions } from '../unit-test-example-data.spec'; describe('TestViewComponent', () => { - let component: TestViewComponent; - let fixture: ComponentFixture<TestViewComponent>; + let component: TestSessionComponent; + let fixture: ComponentFixture<TestSessionComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [TestViewComponent], + declarations: [TestSessionComponent], imports: [MatIconModule, MatTooltipModule, MatCheckboxModule] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(TestViewComponent); + fixture = TestBed.createComponent(TestSessionComponent); component = fixture.componentInstance; component.testSession = unitTestExampleSessions[0]; component.displayOptions = <TestViewDisplayOptions>{ diff --git a/src/app/group-monitor/test-view/test-view.component.ts b/src/app/group-monitor/test-session/test-session.component.ts similarity index 90% rename from src/app/group-monitor/test-view/test-view.component.ts rename to src/app/group-monitor/test-session/test-session.component.ts index ac9abc69ceb21ac87227297131c3a0731388b696..27fb7a797dd100a76336ef951a1f912c47549a53 100644 --- a/src/app/group-monitor/test-view/test-view.component.ts +++ b/src/app/group-monitor/test-session/test-session.component.ts @@ -6,7 +6,7 @@ import { Testlet, Unit, TestViewDisplayOptions, isUnit, Selected, TestSession, TestSessionSuperState } from '../group-monitor.interfaces'; -import { TestSessionService } from '../test-session.service'; +import { TestSessionUtil } from './test-session.util'; import { superStates } from './super-states'; interface IconData { @@ -17,11 +17,11 @@ interface IconData { } @Component({ - selector: 'tc-test-view', - templateUrl: './test-view.component.html', - styleUrls: ['./test-view.component.css', './test-view-table.css'] + selector: 'tc-test-session', + templateUrl: './test-session.component.html', + styleUrls: ['./test-session.component.css'] }) -export class TestViewComponent { +export class TestSessionComponent { @Input() testSession: TestSession; @Input() displayOptions: TestViewDisplayOptions; @Input() marked: Selected; @@ -34,9 +34,9 @@ export class TestViewComponent { superStateIcons: { [key in TestSessionSuperState]: IconData } = superStates; - stateString = TestSessionService.stateString; + stateString = TestSessionUtil.stateString; - hasState = TestSessionService.hasState; + hasState = TestSessionUtil.hasState; getTestletType = (testletOrUnit: Unit|Testlet): 'testlet'|'unit' => (isUnit(testletOrUnit) ? 'unit' : 'testlet'); diff --git a/src/app/group-monitor/test-session.service.spec.ts b/src/app/group-monitor/test-session/test-session.util.spec.ts similarity index 72% rename from src/app/group-monitor/test-session.service.spec.ts rename to src/app/group-monitor/test-session/test-session.util.spec.ts index f2f428c50e6de4883d310d3278044aff02da6bce..e06707dc9fa5535b5281695c723b706e7074035f 100644 --- a/src/app/group-monitor/test-session.service.spec.ts +++ b/src/app/group-monitor/test-session/test-session.util.spec.ts @@ -1,26 +1,9 @@ /* eslint-disable object-curly-newline */ -import { TestBed } from '@angular/core/testing'; -import { TestSessionService } from './test-session.service'; -import { unitTestExampleBooklets } from './test-data.spec'; -import { Testlet, UnitContext } from './group-monitor.interfaces'; - -describe('TestSessionService', () => { - let service: TestSessionService; - - beforeEach(() => { - TestBed.configureTestingModule({ - providers: [ - TestSessionService - ] - }); - service = TestBed.inject(TestSessionService); - }); - - it('should be created', () => { - expect(service) - .toBeTruthy(); - }); +import { TestSessionUtil } from './test-session.util'; +import { unitTestExampleBooklets } from '../unit-test-example-data.spec'; +import { Testlet, UnitContext } from '../group-monitor.interfaces'; +describe('TestSessionUtil', () => { describe('getCurrent()', () => { it('should find correct indices for unit, parent and ancestor ( = top-level-testlet or root)', () => { const fakeTestlet = (id: string): Testlet => ({ @@ -104,7 +87,7 @@ describe('TestSessionService', () => { for (let i = 1; i < 11; i++) { // eslint-disable-next-line @typescript-eslint/dot-notation - const result = TestSessionService['getCurrent'](unitTestExampleBooklets.example_booklet_1.units, `unit-${i}`); + const result = TestSessionUtil['getCurrent'](unitTestExampleBooklets.example_booklet_1.units, `unit-${i}`); const expectation = expectations[`unit-${i}`]; expect(result.indexGlobal) .withContext(`global index of unit-${i}`) @@ -129,7 +112,7 @@ describe('TestSessionService', () => { it('should find return a unitContext without unit for not existing id', () => { // eslint-disable-next-line @typescript-eslint/dot-notation - const result = TestSessionService['getCurrent'](unitTestExampleBooklets.example_booklet_1.units, 'not-existing'); + const result = TestSessionUtil['getCurrent'](unitTestExampleBooklets.example_booklet_1.units, 'not-existing'); expect(result.unit).toBeNull(); }); }); @@ -141,15 +124,15 @@ describe('TestSessionService', () => { second_key: 'second_value' }; - let result = TestSessionService.stateString(stateObject, ['first_key'], '|'); + let result = TestSessionUtil.stateString(stateObject, ['first_key'], '|'); let expectation = 'first_value'; expect(result).withContext('one existing value').toEqual(expectation); - result = TestSessionService.stateString(stateObject, ['first_key', 'second_key'], '|'); + result = TestSessionUtil.stateString(stateObject, ['first_key', 'second_key'], '|'); expectation = 'first_value|second_value'; expect(result).withContext('two existing values').toEqual(expectation); - result = TestSessionService.stateString(stateObject, ['first_key', 'second_key', 'not_existing'], '|'); + result = TestSessionUtil.stateString(stateObject, ['first_key', 'second_key', 'not_existing'], '|'); expectation = 'first_value|second_value'; expect(result).withContext('two existing values and one not existing').toEqual(expectation); }); @@ -162,29 +145,17 @@ describe('TestSessionService', () => { second_key: null }; - let result = TestSessionService.hasState(stateObject, 'first_key', 'first_value'); + let result = TestSessionUtil.hasState(stateObject, 'first_key', 'first_value'); expect(result).withContext('key exists and has value').toBeTrue(); - result = TestSessionService.hasState(stateObject, 'first_key', 'something_else'); + result = TestSessionUtil.hasState(stateObject, 'first_key', 'something_else'); expect(result).withContext('key exists and not has value').toBeFalse(); - result = TestSessionService.hasState(stateObject, 'first_key'); + result = TestSessionUtil.hasState(stateObject, 'first_key'); expect(result).withContext('key exists').toBeTrue(); - result = TestSessionService.hasState(stateObject, 'non_existing_key'); + result = TestSessionUtil.hasState(stateObject, 'non_existing_key'); expect(result).withContext('key exists not').toBeFalse(); }); }); - - describe('parseJsonState()', () => { - xit('should parse an string containing a state-object', () => { - // TOOD implement unit-test - }); - }); - - describe('getMode()', () => { - xit('should transform mode-string into label', () => { - // TOOD implement unit-test - }); - }); }); diff --git a/src/app/group-monitor/test-session.service.ts b/src/app/group-monitor/test-session/test-session.util.ts similarity index 80% rename from src/app/group-monitor/test-session.service.ts rename to src/app/group-monitor/test-session/test-session.util.ts index 9ca3c31a723264cc703155c0cfbf4e61411c769d..369e440dbbb814fba885b04d5e1a02aecdbfaa87 100644 --- a/src/app/group-monitor/test-session.service.ts +++ b/src/app/group-monitor/test-session/test-session.util.ts @@ -1,4 +1,3 @@ -import { Injectable } from '@angular/core'; import { Booklet, BookletError, isBooklet, @@ -8,37 +7,36 @@ import { TestSessionData, TestSessionSuperState, UnitContext -} from './group-monitor.interfaces'; +} from '../group-monitor.interfaces'; -@Injectable() -export class TestSessionService { +export class TestSessionUtil { static hasState(state: Record<string, unknown>, key: string, value = null): boolean { return ((typeof state[key] !== 'undefined') && ((value !== null) ? (state[key] === value) : true)); } static isPaused(session: TestSession): boolean { - return TestSessionService.hasState(session.data.testState, 'CONTROLLER', 'PAUSED'); + return TestSessionUtil.hasState(session.data.testState, 'CONTROLLER', 'PAUSED'); } static isLocked(session: TestSession): boolean { - return TestSessionService.hasState(session.data.testState, 'status', 'locked'); + return TestSessionUtil.hasState(session.data.testState, 'status', 'locked'); } static analyzeTestSession(session: TestSessionData, booklet: Booklet | BookletError): TestSession { - const current = isBooklet(booklet) ? TestSessionService.getCurrent(booklet.units, session.unitName) : null; + const current = isBooklet(booklet) ? TestSessionUtil.getCurrent(booklet.units, session.unitName) : null; return { data: session, - state: TestSessionService.getSuperState(session), + state: TestSessionUtil.getSuperState(session), current: current && current.unit ? current : null, booklet, - timeLeft: TestSessionService.parseJsonState(session.testState, 'TESTLETS_TIMELEFT'), - clearedCodes: TestSessionService.parseJsonState(session.testState, 'TESTLETS_CLEARED_CODE') + timeLeft: TestSessionUtil.parseJsonState(session.testState, 'TESTLETS_TIMELEFT'), + clearedCodes: TestSessionUtil.parseJsonState(session.testState, 'TESTLETS_CLEARED_CODE') }; } static stateString(state: Record<string, string>, keys: string[], glue = ''): string { return keys - .map((key: string) => (TestSessionService.hasState(state, key) ? state[key] : null)) + .map((key: string) => (TestSessionUtil.hasState(state, key) ? state[key] : null)) .filter((value: string) => value !== null) .join(glue); } @@ -67,7 +65,7 @@ export class TestSessionService { if (this.hasState(state, 'FOCUS', 'HAS_NOT')) { return 'focus_lost'; } - if (TestSessionService.idleSinceMinutes(session) > 5) { + if (TestSessionUtil.idleSinceMinutes(session) > 5) { return 'idle'; } if (this.hasState(state, 'CONNECTION', 'WEBSOCKET')) { @@ -121,7 +119,7 @@ export class TestSessionService { return result; } } else { - const subResult = TestSessionService.getCurrent(child, searchUnitId, level + 1, { + const subResult = TestSessionUtil.getCurrent(child, searchUnitId, level + 1, { unit: null, parent: child, ancestor: level < 1 ? child : result.ancestor, diff --git a/src/app/group-monitor/test-view/test-view-table.css b/src/app/group-monitor/test-view/test-view-table.css deleted file mode 100644 index af59988162ad3f4fc67be4d78d4b3c174d17c6a5..0000000000000000000000000000000000000000 --- a/src/app/group-monitor/test-view/test-view-table.css +++ /dev/null @@ -1,34 +0,0 @@ -:host(tc-test-view) { - display: table-row; - vertical-align: middle; -} - -td { - padding-bottom: 0.2em; - padding-top: 0.2em; - border-bottom: 1px solid silver; - padding-right: 2em; -} - -:host(tc-test-view):last-of-type td { - border-bottom: none; -} - -td.super-state, -td.selected, -td:last-child { - padding-right: 0; -} - -td.selected { - padding-left: 5px; -} - -td:last-child { - min-width: 100%; -} - -:host(test-view:last-child) td { - border-bottom: none; - -} diff --git a/src/app/group-monitor/test-data.spec.ts b/src/app/group-monitor/unit-test-example-data.spec.ts similarity index 97% rename from src/app/group-monitor/test-data.spec.ts rename to src/app/group-monitor/unit-test-example-data.spec.ts index 0da3e961d8e13a7e86e2e6596f8d0e876136855e..1f770d296a16286aa29327b8549b6c1ee68ff2a7 100644 --- a/src/app/group-monitor/test-data.spec.ts +++ b/src/app/group-monitor/unit-test-example-data.spec.ts @@ -1,7 +1,7 @@ import { Booklet, CommandResponse, TestSession, TestSessionData, TestSessionSetStats } from './group-monitor.interfaces'; -import { TestSessionService } from './test-session.service'; +import { TestSessionUtil } from './test-session/test-session.util'; // labels are: {global index}-{ancestor index}-{local index} export const unitTestExampleBooklets: { [name: string]: Booklet } = { @@ -211,7 +211,7 @@ export const unitTestExampleSessions: TestSession[] = [ timestamp: 10000000 } ] - .map(session => TestSessionService.analyzeTestSession( + .map(session => TestSessionUtil.analyzeTestSession( session, unitTestExampleBooklets[session.bookletName] || { error: 'missing-file', species: null } )); @@ -249,7 +249,7 @@ export const additionalUnitTestExampleSessions: TestSession[] = [ timestamp: 10000340 } ] - .map(session => TestSessionService.analyzeTestSession( + .map(session => TestSessionUtil.analyzeTestSession( session, unitTestExampleBooklets[session.bookletName] || { error: 'missing-file', species: null } )); diff --git a/src/scripts/generateDocs-testSuperState.js b/src/scripts/generateDocs-testSuperState.js index db0be97163aeb3443f342fdb0463d5cd06d0aae0..8ac37b05ad8a99287c780f38a7e7ce039ff779cb 100644 --- a/src/scripts/generateDocs-testSuperState.js +++ b/src/scripts/generateDocs-testSuperState.js @@ -1,6 +1,6 @@ /* eslint-disable no-console,@typescript-eslint/no-var-requires */ const fs = require('fs'); -const { superStates } = require('../app/group-monitor/test-view/super-states'); +const { superStates } = require('../app/group-monitor/test-session/super-states'); const mdTargetFilename = '../../docs/super-states.html';