Skip to content

Commit

Permalink
v3.24.0 (#203)
Browse files Browse the repository at this point in the history
* Fix tracking of active prac challenge

* Minor cleanup and improved console logging

* Bug fixes and challenge report tags filter.

* Fix event horizon, game center teams, enrollment report stat summary, progress widget

* Fix issue with past games not showing ongoing ones

* WIP question sets

* More question set stuff

* Improvements to OIDC experience and support for auto log in/out.

* merge from next

* Add favicon defaults. Update theme

* Fix settings link bug, more thing

* Theme stuff

* Add settings link to user menu

* Theme stuff

* Revert "Theme stuff"

This reverts commit a26c715.

* Revert "Add settings link to user menu"

This reverts commit d640ee8.

* Revert "Theme stuff"

This reverts commit c3e3b69.

* Revert "Fix settings link bug, more thing"

This reverts commit f96dc59.

* Revert "Add favicon defaults. Update theme"

This reverts commit 1b2e5a7.

* Rollback and reimplement oauth changes

* Update oidc settings to match topo

* Cleanup

* Update dev env settings

* Improvements to OIDC experience and support for auto log in/out.

* Restore ux improvements

* More retheme

* Retheming and initial work on name improvements.

* Update gh action versions

* Retheming and name mgmt

* Styling stuff

* Styling stuff

* Move challenge markdown

* Un 'fix' start practice button

* minor name fixes

* Name cleanup

* Finish merge from main

* More theming and fix to GBAPI#502

* More theming and markdown fix

* More style fixes

* Partially address GBAPI#254

* Return question example answers

* Auto-select first available uncompleted tab

* Standard challenge panel sticky enhancements

* Styling

* Roll back login experience changes

* Settings bug fix and hide rename cert

* Minor theme stuff

* Theming

* Add additional sticky panel toggle button
  • Loading branch information
sei-bstein authored Nov 8, 2024
1 parent 3054a32 commit bd3321c
Show file tree
Hide file tree
Showing 27 changed files with 166 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ <h4>Challenges</h4>
<input type="search" [(ngModel)]="search.term" placeholder="term" class="form-control"
(input)="refresh$.next(true)">
</div>
<div *ngIf="challenges$ | async as list">
<div *ngIf="challenges$ | async as list" class="mt-4">
<div class="mt-2 border-bottom">
<span>Current</span>
</div>
Expand Down Expand Up @@ -56,7 +56,8 @@ <h4>Challenges</h4>
<app-error-div [errors]="errors"></app-error-div>

<div class="text-right">
<button class="btn btn-success" (click)="regrade(selected)">
<button class="btn btn-success" (click)="regrade(selected)"
tooltip="Asks the game engine to regrade all submissions for this challenge." placement="left">
<fa-icon [icon]="faSync"></fa-icon>
<span>Regrade</span>
</button>
Expand Down Expand Up @@ -92,8 +93,9 @@ <h4 class="mt-4">Challenge</h4>
</ng-template>

<ng-template #gameEngineAuditNotLoaded>
<div *ngIf="selected && !selected.archived && !isLoadingAuditFromGameEngine"
class="btn btn-link text-success cursor-pointer py-0 px-0" (click)="auditFromGameEngine(selected.id)">
<div *ngIf="selected && !selected.archived && !isLoadingAuditFromGameEngine" class="btn btn-link py-0 px-0"
(click)="auditFromGameEngine(selected.id)"
tooltip="Displays a complete list of all submissions received by the game engine for this challenge.">
Audit from game engine?
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,18 @@ <h5 class="overflow-ellipsis">
<fa-icon [icon]="fa.barsStaggered" size="lg"></fa-icon>
</a>

<a [href]="'admin/registrar/' + spec.game.id + '?term=' + challenge.team.id | relativeToAbsoluteHref"
target="_blank" class="btn btn-success mr-2"
<a [routerLink]="['admin', 'game', spec.game.id, 'teams']"
[queryParams]="{ search: challenge.team.id }" target="_blank"
class="btn btn-success mr-2"
[tooltip]="'View this ' + (spec.game.isTeamGame ? 'team' : 'player') + '\'s session'"
placement="bottom">
<fa-icon [icon]="spec.game.isTeamGame ? fa.peopleGroup : fa.person"
size="lg"></fa-icon>
</a>

<a [href]="'admin/observer/challenges/' + spec.game.id + '?search=' + challenge.id | relativeToAbsoluteHref"
target="_blank" class="btn btn-success mr-2" tooltip="Observe this challenge"
placement="bottom">
<a [routerLink]="['admin', 'game', spec.game.id, 'observe']"
[queryParams]=" { challengeId: challenge.id }" target="_blank"
class="btn btn-success mr-2" tooltip="Observe this challenge" placement="bottom">
<fa-icon [icon]="fa.eye" size="lg"></fa-icon>
</a>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
</div>
</div>
<div contextMenu>
<button type="button" class="btn btn-info" (click)="handleUserDetailClick(user)">More</button>
<button type="button" class="btn btn-success"
(click)="handleUserDetailClick(user)">More</button>
</div>
</app-team-list-card>
</li>
Expand All @@ -51,6 +52,7 @@
</ng-template>

<ng-template #noUsers>
<div class="text-center mt-4 text-muted">No one has attempted challenges from this game in the Practice Area yet.
<div class="text-center mt-4 text-muted">
No one has attempted challenges from this game in the Practice Area yet.
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<alert type="warning" *ngIf="game && (results?.namesPendingApproval || 0) > 0">
There are {{results?.namesPendingApproval}} {{ "player" | pluralizer:results?.namesPendingApproval}} in this game
who have pending name change requests. Click <span class="btn-link"
(click)="handlePendingNamesClick(game.id)">here</span>
who have pending name change requests. Click
<span class="btn-link" (click)="handlePendingNamesClick(game.id)">here</span>
to review them.
</alert>

Expand Down Expand Up @@ -114,7 +114,7 @@
<div secondaryDetail>
<ng-container *ngIf="team.session.start && team.session.end | epochMsToDateTime | datetimeIsFuture">
<div>Playing now</div>
<strong class="text-info d-block"
<strong class="text-success d-block"
[tooltip]="'Ends ' + (team.session.end | epochMsToDateTime | friendlyDateAndTime) || ''">{{
team.session.end | epochMsToDateTime | datetimeToDate | dateToCountdown | async
}}</strong>
Expand All @@ -125,7 +125,7 @@
<div class="text-muted">Not playing yet</div>

<span *ngIf="!team.session.start">
(Registered <strong class="text-success"
(Registered <strong class="text-info"
[tooltip]="(team.registeredOn | epochMsToDateTime | friendlyDateAndTime) || ''">{{
team.registeredOn | epochMsToDateTime |
shortdate }}</strong>)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
import { debounceTime, firstValueFrom, map, Subject, tap } from 'rxjs';
import { ActivatedRoute } from '@angular/router';
import { debounceTime, firstValueFrom, map, Subject } from 'rxjs';
import { AdminService } from '@/api/admin.service';
import { fa } from '@/services/font-awesome.service';
import { Game } from '@/api/game-models';
Expand All @@ -19,7 +20,6 @@ import { LocalStorageService, StorageKey } from '@/services/local-storage.servic
import { NowService } from '@/services/now.service';
import { GameCenterTeamDetailComponent } from '../game-center-team-detail/game-center-team-detail.component';
import { TeamService } from '@/api/team.service';
import { ActivatedRoute } from '@angular/router';

interface GameCenterTeamsFilterSettings {
advancement?: GameCenterTeamsAdvancementFilter;
Expand Down Expand Up @@ -61,9 +61,13 @@ export class GameCenterTeamsComponent implements OnInit {

this.unsub.add(
this.route.data.subscribe(async d => await this.load(d.gameId)),
this.searchInput$.pipe(
debounceTime(300)
).subscribe(async event => {
this.route.queryParams.subscribe(async qp => {
if (qp.search) {
this.filterSettings.searchTerm = qp.search.toString().trim();
await this.load(this.game?.id);
}
}),
this.searchInput$.pipe(debounceTime(300)).subscribe(async event => {
this.filterSettings.searchTerm = (event.target as HTMLInputElement).value;
await this.load(this.game?.id);
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ActivatedRoute } from '@angular/router';
import { AdminService } from '@/api/admin.service';
import { Game } from '@/api/game-models';
import { GameService } from '@/api/game.service';
Expand Down Expand Up @@ -29,8 +29,7 @@ export class GameCenterComponent {
private adminService: AdminService,
private appTitle: AppTitleService,
private gameService: GameService,
private localUserService: UserService,
private router: Router) {
private localUserService: UserService) {

unsub.add(this.activatedRoute.paramMap.subscribe(async paramMap => {
const gameId = paramMap.get("gameId") || this.gameCenterCtx?.id;
Expand Down
3 changes: 1 addition & 2 deletions projects/gameboard-ui/src/app/core/pipes/pluralizer.pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'pluralizer' })
export class PluralizerPipe implements PipeTransform {

transform(label: string, count: any = 0, addE: boolean = false): string {
transform(label: string, count: number = 0, addE: boolean = false): string {
if (!label)
return "";

Expand Down
3 changes: 2 additions & 1 deletion projects/gameboard-ui/src/app/game/game.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import { HasPendingNamePipe } from './pipes/has-pending-name.pipe';
import { ChallengeQuestionsComponent } from "../standalone/games/components/challenge-questions/challenge-questions.component";
import { SpinnerComponent } from '@/standalone/core/components/spinner/spinner.component';
import { ErrorDivComponent } from '@/standalone/core/components/error-div/error-div.component';
import { VmLinkComponent } from '@/standalone/games/components/vm-link/vm-link.component';
import { SafeUrlPipe } from '@/standalone/core/pipes/safe-url.pipe';
import { ScoreboardPageComponent } from '@/scoreboard/components/scoreboard-page/scoreboard-page.component';

const MODULE_DECLARATIONS = [
CertificateComponent,
Expand Down Expand Up @@ -75,6 +75,7 @@ const MODULE_DECLARATIONS = [
{ path: 'board/:playerId', canActivate: [AuthGuard, GameIsStarted, UserIsPlayingGuard], component: GameboardPageComponent },
{ path: 'external/:gameId/start/:playerId', canActivate: [AuthGuard, UserIsPlayingGuard], component: ExternalGameLoadingPageComponent },
{ path: 'external/:gameId/:teamId', canActivate: [AuthGuard, UserIsPlayingGuard, ExternalGameGuard], component: ExternalGamePageComponent },
{ path: ":gameId/scoreboard", component: ScoreboardPageComponent },
{ path: ':id', component: GamePageComponent, children: [] }
]),
CoreModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</span>
<div class="spacer"></div>
<div class="d-flex flex-column align-items-center">
<a [routerLink]="['../scores', ctx.game.id]" class="p-4">
<a [routerLink]="['/game', ctx.game.id, 'scoreboard']" class="p-4">
<span>
<fa-icon [icon]="fa.listOl"></fa-icon>
<span>Scoreboard</span>
Expand Down Expand Up @@ -87,7 +87,7 @@ <h2>Info</h2>
<div class="col-12 page-width scoreboard">
<h2 id="scoreboard" class="text-center my-4">
<span>Scoreboard</span>&nbsp;&nbsp;
<a [routerLink]="['../', 'scores', ctx.game.id]">
<a [routerLink]="['/game', ctx.game.id, 'scoreboard']">
<small>
<fa-icon [icon]="fa.externalLinkAlt"></fa-icon>
</small>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
[playerId]="ctx.player.id"></app-gameboard-performance-summary>

<div class="d-flex my-4 align-items-center justify-content-center">
<a type="button" class="btn btn-secondary" target="_blank" [href]="'game/scores/' + ctx.game.id">
<a type="button" class="btn btn-secondary" target="_blank" [href]="'game/' + ctx.game.id + '/scoreboard'">
View Scoreboard
<fa-icon [icon]="fa.externalLink"></fa-icon>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</tbody>
</table>

<ng-container *ngIf="!isChangingSessionEnd && activeChallenge">
<ng-container *ngIf="!isChangingSessionEnd">
<div class="text-center">
<app-confirm-button btnClass="btn btn-success btn-sm" [tooltip]="extendTooltip"
[disabled]="((activeChallenge.endsAt | epochMsToMsRemaining | async) || 0) > msPerHour"
Expand All @@ -48,6 +48,12 @@
End Session
</app-confirm-button>
</div>

<div class="text-center btn-link text-muted my-2"
(click)="handleToggleStickyPanel(!userSettings$.value.useStickyChallengePanel)">
{{ (userSettings$ | async)?.useStickyChallengePanel ? "Turn off" : "Turn on" }} the Sticky Challenge
Panel
</div>
</ng-container>
</ng-container>
</ng-template>
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
a:hover {
text-decoration: none;
text-decoration: none;
}

table,
thead {
border-top-width: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ActiveChallengesRepo } from '@/stores/active-challenges.store';
import { slug } from '@/../tools/functions';
import { TeamService } from '@/api/team.service';
import { ToastService } from '@/utility/services/toast.service';
import { UserSettingsService } from '@/services/user-settings.service';

@Component({
selector: 'app-practice-challenge-state-summary',
Expand All @@ -23,11 +24,13 @@ export class PracticeChallengeStateSummaryComponent {
protected isChangingSessionEnd = false;
protected fa = fa;
protected slug = slug;
protected userSettings$ = this.userSettings.updated$;

constructor(
activeChallengesRepo: ActiveChallengesRepo,
private teamService: TeamService,
private toastService: ToastService) {
private toastService: ToastService,
private userSettings: UserSettingsService) {
this.activeChallenge$ = activeChallengesRepo.activePracticeChallenge$;
}

Expand All @@ -48,12 +51,8 @@ export class PracticeChallengeStateSummaryComponent {
this.isChangingSessionEnd = false;
}

private getExtendTooltip(msRemaining: number) {
if (msRemaining < this.msPerHour) {
return "If you want more time to practice, you can extend your session. Sessions extend to a maximum remaining time of 60 minutes.";
}

return "You can't extend your practice session because you have more than 60 minutes remaining.";
protected handleToggleStickyPanel(enable: boolean) {
this.userSettings.updated$.next({ useStickyChallengePanel: enable });
}

private showExtensionToast(sessionEnd: DateTime, isAutomatic = false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface EnrollmentReportByGameSponsor {
id: string;
name: string;
logoFileName: string;
playerCount: string;
playerCount: number;
}

export interface EnrollmentReportStatSummary {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="container">
<ng-container *ngIf="game">
<h1 class="mt-4">Scoreboard</h1>
<h2 class="text-success fw-bold text-upper fs-12">
<a [routerLink]="['/game', game.id]">{{ game.name }}</a>
</h2>

<app-scoreboard class="d-block mt-5" [gameId]="game.id"></app-scoreboard>
</ng-container>

</div>

<ng-template #loading>
<app-spinner>Loading the score...</app-spinner>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ActivatedRoute } from '@angular/router';
import { firstValueFrom } from 'rxjs';
import { GameService } from '@/api/game.service';
import { SimpleEntity } from '@/api/models';
import { AppTitleService } from '@/services/app-title.service';
import { UnsubscriberService } from '@/services/unsubscriber.service';
import { Component } from '@angular/core';

@Component({
selector: 'app-scoreboard-page',
providers: [UnsubscriberService],
templateUrl: './scoreboard-page.component.html',
styleUrls: ['./scoreboard-page.component.scss']
})
export class ScoreboardPageComponent {
protected game?: SimpleEntity;

constructor(
private appTitle: AppTitleService,
private gameService: GameService,
private route: ActivatedRoute,
private unsub: UnsubscriberService) {
this.unsub.add(this.route.params.subscribe(async params => this.loadGame(params.gameId)));
}

private async loadGame(gameId: string) {
if (!gameId) {
this.game = undefined;
return;
}

this.game = await firstValueFrom(this.gameService.retrieve(gameId));
this.appTitle.set(`Scoreboard | ${this.game.name}`);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<ng-container *ngIf="scoreboardData; else loading">
<alert *ngIf="isLive && !suppressLiveGameBanner" type="info" class="my-2">
<alert *ngIf="isLive && !suppressLiveGameBanner" type="success" class="my-2">
This game is still being played. Check back after the round ends
({{ scoreboardData.game.isLiveUntil?.toJSDate() | friendlyDateAndTime }})
to see who came out on top and view complete score breakdowns for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ScoreboardComponent } from './components/scoreboard/scoreboard.componen
import { ScoreboardTeamDetailModalComponent } from './components/scoreboard-team-detail-modal/scoreboard-team-detail-modal.component';
import { ScoreToTooltipPipe } from './pipes/score-to-tooltip.pipe';
import { SpinnerComponent } from '@/standalone/core/components/spinner/spinner.component';
import { ScoreboardPageComponent } from './components/scoreboard-page/scoreboard-page.component';

const PUBLIC_DECLARATIONS = [
ScoreboardComponent,
Expand All @@ -17,7 +18,8 @@ const PUBLIC_DECLARATIONS = [
@NgModule({
declarations: [
...PUBLIC_DECLARATIONS,
ChallengeBonusesToTooltip
ChallengeBonusesToTooltip,
ScoreboardPageComponent
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { UserAppSettings } from "@/users/users.models";
import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Injectable({ providedIn: 'root' })
export class UserSettingsService {
public updated$ = new BehaviorSubject<UserAppSettings>({ useStickyChallengePanel: false });
}
4 changes: 3 additions & 1 deletion projects/gameboard-ui/src/app/services/window.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class WindowService implements OnDestroy {
}

scrollToBottom() {
this.document.defaultView?.scrollTo(0, this.document.body.scrollHeight);
setTimeout(() => {
this.document.defaultView?.scrollTo(0, this.document.body.scrollHeight);
}, 500);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ <h3 *ngIf="size === 'compact' && context.section.name">{{ context.section.name |
formControlName="s{{ context.index }}q{{ questionIndex }}" [readOnly]="question.isCorrect"
placeholder="Enter your answer for question {{ questionIndex + 1 }} here">
</div>
<div class="text-muted fs-08" *ngIf="question.example">e.g. {{question.example}}</div>
<div class="text-muted fs-08" *ngIf="question.example">
<strong>
Example:
</strong>
{{question.example}}
</div>
</div>
</li>
</ul>
Expand Down
Loading

0 comments on commit bd3321c

Please sign in to comment.