diff --git a/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.html b/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.html index 3c04a3ff..53da5174 100644 --- a/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.html +++ b/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.html @@ -15,7 +15,8 @@
+ [(ngModel)]="editHost.hostApiKey" + [placeholder]="hasApiKey ? '(key configured - enter a new key here to change it)' : '(e.g. 123ThisIsMyKey!)'">
diff --git a/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.ts b/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.ts index 93db6eda..116daa93 100644 --- a/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.ts +++ b/projects/gameboard-ui/src/app/admin/components/external-host-editor/external-host-editor.component.ts @@ -15,15 +15,14 @@ export class ExternalHostEditorComponent implements OnInit { startupEndpoint: "" }; protected errors: any[] = []; + protected hasApiKey = false; public hostId?: string; public onSave?: (host: UpsertExternalGameHost) => void | Promise; protected subtitle?: string; protected title = "New External Game Host"; protected tryPingResult?: { success: boolean; response?: string }; - constructor( - private externalGameService: ExternalGameService, - ) { } + constructor(private externalGameService: ExternalGameService) { } async ngOnInit() { if (this.hostId) { @@ -34,6 +33,7 @@ export class ExternalHostEditorComponent implements OnInit { throw new Error(`Couldn't resolve host ${this.hostId}.`); this.editHost = host; + this.hasApiKey = host.hasApiKey; this.subtitle = "Edit External Game Host"; this.title = host.name; } diff --git a/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.html b/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.html index a9cc5ec3..b072ac36 100644 --- a/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.html +++ b/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.html @@ -297,12 +297,17 @@

Execution

- + yyyy-mm-ddT00:00:00+00:00
+
+ The game's open date must be less than its close date. +
+
Registration yyyy-mm-ddT00:00:00+00:00 +
@@ -425,10 +431,20 @@

Registration

[(ngModel)]="game.registrationClose"> yyyy-mm-ddT00:00:00+00:00
+ + +
+
+ + The registration period's open date must be prior to its close date. + +
+
+
-
@@ -436,12 +452,26 @@

Registration

+ [min]="game.minTeamSize" [(ngModel)]="game.maxTeamSize">
+
+
+ + The minimum team size must be less than (or equal to) the maximum team size. + +
+ +
+ + The minimum team size must be a positive integer. + +
+
+
diff --git a/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.ts b/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.ts index 3d0140ec..824adf6f 100644 --- a/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.ts +++ b/projects/gameboard-ui/src/app/admin/game-editor/game-editor.component.ts @@ -6,12 +6,11 @@ import { FormGroup, NgForm } from '@angular/forms'; import { ActivatedRoute } from '@angular/router'; import { Observable, firstValueFrom } from 'rxjs'; import { debounceTime, filter, map, switchMap, tap } from 'rxjs/operators'; -import { ExternalGameHost, Game, GameEngineMode } from '../../api/game-models'; +import { ExternalGameHost, Game, GameEngineMode, GameRegistrationType } from '../../api/game-models'; import { GameService } from '../../api/game.service'; import { KeyValue } from '@angular/common'; import { AppTitleService } from '@/services/app-title.service'; import { fa } from '@/services/font-awesome.service'; -import { PlayerMode } from '@/api/player-models'; import { ToastService } from '@/utility/services/toast.service'; import { PracticeService } from '@/services/practice.service'; import { FeedbackTemplate } from '@/api/feedback-models'; @@ -81,7 +80,7 @@ export class GameEditorComponent implements AfterViewInit { ngAfterViewInit(): void { this.updated$ = this.form.valueChanges.pipe( - filter(f => !this.form.pristine && (this.form.valid || false)), + filter(f => !this.form.pristine && (this.form.valid || false) && this.doAdditionalValidation(f)), tap(values => { this.dirty = true; this.needsPracticeModeEnabledRefresh = values.playerMode !== this.game.playerMode; @@ -181,4 +180,17 @@ export class GameEditorComponent implements AfterViewInit { if (a.key > b.key) return 1; return 0; } + + private doAdditionalValidation(game: Game) { + if (game.minTeamSize > game.maxTeamSize) + return false; + + if (game.gameStart > game.gameEnd) + return false; + + if (game.registrationType == GameRegistrationType.open && game.registrationOpen > game.registrationClose) + return false; + + return true; + } } diff --git a/projects/gameboard-ui/src/app/api/game-models.ts b/projects/gameboard-ui/src/app/api/game-models.ts index 8594e58b..925dcc09 100644 --- a/projects/gameboard-ui/src/app/api/game-models.ts +++ b/projects/gameboard-ui/src/app/api/game-models.ts @@ -146,7 +146,7 @@ export interface ExternalGameHost { clientUrl: string; destroyResourcesOnDeployFailure?: boolean; gamespaceDeployBatchSize?: number; - hostApiKey?: string; + hasApiKey: boolean; hostUrl: string; pingEndpoint?: string; startupEndpoint: string;