mirror of
https://codeberg.org/beerbrawl/beerbrawl.git
synced 2024-09-23 05:40:51 +02:00
feat(#85): add checkin functionality on score table
This commit is contained in:
parent
363ff338e1
commit
b33199e991
6
frontend/package-lock.json
generated
6
frontend/package-lock.json
generated
|
@ -20,6 +20,7 @@
|
|||
"@angular/platform-browser-dynamic": "17.3.4",
|
||||
"@angular/router": "17.3.4",
|
||||
"@fontsource/material-icons": "^5.0.18",
|
||||
"@fontsource/material-icons-outlined": "^5.0.12",
|
||||
"@fontsource/roboto": "^5.0.13",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"core-js": "3.36.1",
|
||||
|
@ -3082,6 +3083,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@fontsource/material-icons/-/material-icons-5.0.18.tgz",
|
||||
"integrity": "sha512-2DL5z2yKWE+kXQrBiUTwIOMQjhs6t+EoPql8Ai4N6t2mjUhBdi2RChW44V3z1WgwupoqILXrAa4/id4/AuruMQ=="
|
||||
},
|
||||
"node_modules/@fontsource/material-icons-outlined": {
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/material-icons-outlined/-/material-icons-outlined-5.0.12.tgz",
|
||||
"integrity": "sha512-Zi8qYVOCtSS6CFGZzjUY+ENYmVtSgH1GDQBeGllwXJ2Ny/TmCTsO+tjHpr74nV4u63JSAAl72QnX0eOhOcldJw=="
|
||||
},
|
||||
"node_modules/@fontsource/roboto": {
|
||||
"version": "5.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.13.tgz",
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"@angular/platform-browser-dynamic": "17.3.4",
|
||||
"@angular/router": "17.3.4",
|
||||
"@fontsource/material-icons": "^5.0.18",
|
||||
"@fontsource/material-icons-outlined": "^5.0.12",
|
||||
"@fontsource/roboto": "^5.0.13",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"core-js": "3.36.1",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
.header-card {
|
||||
//background-color: red;
|
||||
height: 10vh;
|
||||
box-shadow: 0 0 5px 0 rgba(50, 50, 50, 0.75);
|
||||
display: flex;
|
||||
|
|
|
@ -7,7 +7,22 @@
|
|||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span [ngClass]="{ 'grey-text': asScoreDto(element) }">{{ element.name }}</span>
|
||||
<div class="name-container">
|
||||
<span class="name-text" [ngClass]="{ 'grey-text': !asScoreDto(element).ready }">
|
||||
{{ asScoreDto(element).name }}
|
||||
@if (!asScoreDto(element).ready) {
|
||||
<button
|
||||
class="check-in-button"
|
||||
mat-icon-button
|
||||
aria-label="mark team as ready"
|
||||
(click)="checkInTeam.emit(element)"
|
||||
[matTooltip]="'Mark team as ready'"
|
||||
>
|
||||
<mat-icon class="material-icons-outlined">waving_hand</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.grey-text {
|
||||
color: grey;
|
||||
color: darkgrey;
|
||||
}
|
||||
|
||||
.mat-mdc-header-cell,
|
||||
|
@ -7,3 +7,15 @@
|
|||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.check-in-button {
|
||||
position: absolute;
|
||||
top: -1.5rem;
|
||||
right: -2.2rem;
|
||||
scale: 0.8;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.name-text {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, input } from '@angular/core';
|
||||
import { Component, inject, input, output } from '@angular/core';
|
||||
import {
|
||||
MatCell,
|
||||
MatCellDef,
|
||||
|
@ -12,7 +12,13 @@ import {
|
|||
MatTable,
|
||||
} from '@angular/material/table';
|
||||
import { NgClass, NgStyle } from '@angular/common';
|
||||
import { QualificationTeamScoreDto } from '@api';
|
||||
import { QualificationTeamScoreDto, TeamDto, TournamentEndpointService } from '@api';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { catchError, of } from 'rxjs';
|
||||
import { ConfirmationService } from '../../services/confirmation.service';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tournament-score-table',
|
||||
|
@ -30,12 +36,17 @@ import { QualificationTeamScoreDto } from '@api';
|
|||
MatHeaderRowDef,
|
||||
NgStyle,
|
||||
NgClass,
|
||||
MatIconButton,
|
||||
MatIcon,
|
||||
MatTooltip,
|
||||
],
|
||||
templateUrl: './tournament-score-table.component.html',
|
||||
styleUrl: './tournament-score-table.component.scss',
|
||||
})
|
||||
export class TournamentScoreTableComponent {
|
||||
scoreDtos = input<QualificationTeamScoreDto[]>();
|
||||
tournamentId = input<number>();
|
||||
checkInTeam = output<QualificationTeamScoreDto>();
|
||||
displayedColumns = ['position', 'name', 'gamesPlayed', 'wins', 'losses', 'points'];
|
||||
|
||||
asScoreDto(element: QualificationTeamScoreDto): QualificationTeamScoreDto {
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
}
|
||||
</div>
|
||||
<div class="score-table mat-elevation-z8">
|
||||
<app-tournament-score-table [scoreDtos]="scoreDtos()"></app-tournament-score-table>
|
||||
<app-tournament-score-table
|
||||
(checkInTeam)="checkInTeam($event)"
|
||||
[scoreDtos]="scoreDtos()"
|
||||
></app-tournament-score-table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,14 +5,16 @@ import { MatCard } from '@angular/material/card';
|
|||
import { TournamentTeamsComponent } from '../../tournament-teams/tournament-teams.component';
|
||||
import {
|
||||
QualificationTeamScoreDto,
|
||||
TeamDto,
|
||||
TournamentEndpointService,
|
||||
TournamentQualificationMatchDto,
|
||||
} from '@api';
|
||||
import { catchError, of } from 'rxjs';
|
||||
import { catchError, firstValueFrom, of } from 'rxjs';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { TournamentScoreTableComponent } from '../../tournament-score-table/tournament-score-table.component';
|
||||
import { QualificationMatchLineComponent } from '../../qualification-match-line/qualification-match-line.component';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { ConfirmationService } from '../../../services/confirmation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tournament-qualification-phase',
|
||||
|
@ -32,12 +34,13 @@ import { DatePipe } from '@angular/common';
|
|||
export class TournamentQualificationPhaseComponent implements OnInit, OnDestroy {
|
||||
tournamentService = inject(TournamentEndpointService);
|
||||
snackBar = inject(MatSnackBar);
|
||||
deleteConfirmationService = inject(ConfirmationService);
|
||||
|
||||
tournamentId = input<number>();
|
||||
scoreDtos = signal<QualificationTeamScoreDto[]>([]);
|
||||
qualificationMatches = signal<TournamentQualificationMatchDto[]>([]);
|
||||
|
||||
// @ts-ignore
|
||||
// @ts-ignore - ts does not 'know' NodeJS types for some reason
|
||||
refreshInterval: NodeJS.Timeout | undefined;
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -89,4 +92,28 @@ export class TournamentQualificationPhaseComponent implements OnInit, OnDestroy
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
async checkInTeam(team: QualificationTeamScoreDto): Promise<void> {
|
||||
if (this.tournamentId() !== undefined && team.id !== undefined) {
|
||||
const answer = await this.deleteConfirmationService.openConfirmationDialog(
|
||||
`check in team ${team.name}?`,
|
||||
'This action cannot be undone.',
|
||||
);
|
||||
|
||||
if (answer) {
|
||||
firstValueFrom(
|
||||
this.tournamentService.markTeamAsReady(this.tournamentId()!, team.id).pipe(
|
||||
catchError(error => {
|
||||
console.error(error);
|
||||
this.snackBar.open('Failed to check in team: ' + error.message, 'Close');
|
||||
return of([]);
|
||||
}),
|
||||
),
|
||||
).then(() => {
|
||||
this.loadScores();
|
||||
this.loadQualificationMatches();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
@import '@fontsource/roboto';
|
||||
@import '@fontsource/material-icons';
|
||||
@import '@fontsource/material-icons-outlined';
|
||||
|
||||
html,
|
||||
body {
|
||||
|
@ -45,3 +46,29 @@ a.no-decoration {
|
|||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
||||
// for using material outlined icons with fontsource
|
||||
.material-icons-outlined {
|
||||
font-family: 'Material Icons Outlined', serif;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px; /* Preferred icon size */
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* Support for Safari and Chrome. */
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
/* Support for Firefox. */
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"experimentalDecorators": true,
|
||||
"target": "es2022",
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"lib": ["es2018", "dom", "ES2020.Intl"],
|
||||
"lib": ["es2018", "dom"],
|
||||
"useDefineForClassFields": false,
|
||||
"strict": true,
|
||||
"paths": { "@api": ["./openapi-generated"] }
|
||||
|
|
Loading…
Reference in a new issue