Added match counter
All checks were successful
Gitea/swiss-client/pipeline/head This commit looks good
All checks were successful
Gitea/swiss-client/pipeline/head This commit looks good
This commit is contained in:
@@ -4,9 +4,6 @@ import {PlayerEditComponent} from "./components/player-edit/player-edit.componen
|
|||||||
import {TournamentListComponent} from "./components/tournament-list/tournament-list.component";
|
import {TournamentListComponent} from "./components/tournament-list/tournament-list.component";
|
||||||
import {TournamentEditComponent} from "./components/tournament-edit/tournament-edit.component";
|
import {TournamentEditComponent} from "./components/tournament-edit/tournament-edit.component";
|
||||||
import {PlayerRegistrationsComponent} from "./components/player-registrations/player-registrations.component";
|
import {PlayerRegistrationsComponent} from "./components/player-registrations/player-registrations.component";
|
||||||
import {TournamentRegistrationsComponent} from "./components/tournament-registrations/tournament-registrations.component";
|
|
||||||
import {TournamentValidateComponent} from "./components/tournament-validate/tournament-validate.component";
|
|
||||||
import {TournamentDivideComponent} from "./components/tournament-divide/tournament-divide.component";
|
|
||||||
import {TournamentDrawComponent} from "./components/tournament-draw/tournament-draw.component";
|
import {TournamentDrawComponent} from "./components/tournament-draw/tournament-draw.component";
|
||||||
import {TournamentManageComponent} from "./components/tournament-manage/tournament-manage.component";
|
import {TournamentManageComponent} from "./components/tournament-manage/tournament-manage.component";
|
||||||
import {MatchSheetsComponent} from "./components/match-sheets/match-sheets.component";
|
import {MatchSheetsComponent} from "./components/match-sheets/match-sheets.component";
|
||||||
@@ -21,14 +18,12 @@ export const routes: Routes = [
|
|||||||
{ path: 'tournaments/add', component: TournamentEditComponent, canActivate: [AuthGuard], data: { header: 'Nieuw Toernooi' }},
|
{ path: 'tournaments/add', component: TournamentEditComponent, canActivate: [AuthGuard], data: { header: 'Nieuw Toernooi' }},
|
||||||
{ path: 'tournaments/:id/edit', component: TournamentEditComponent, canActivate: [AuthGuard], data: { header: 'Bewerk Toernooi' }},
|
{ path: 'tournaments/:id/edit', component: TournamentEditComponent, canActivate: [AuthGuard], data: { header: 'Bewerk Toernooi' }},
|
||||||
{ path: 'tournaments/:id/registrations', component: TournamentPlayersComponent, canActivate: [AuthGuard], data: { header: 'Inschrijvingen' }},
|
{ path: 'tournaments/:id/registrations', component: TournamentPlayersComponent, canActivate: [AuthGuard], data: { header: 'Inschrijvingen' }},
|
||||||
{ path: 'tournaments/:id/validate', component: TournamentValidateComponent, canActivate: [AuthGuard], data: { header: 'Toernooi' }},
|
|
||||||
{ path: 'tournaments/:id/divide', component: TournamentDivideComponent, canActivate: [AuthGuard], data: { header: 'Toernooi valideren' }},
|
|
||||||
{ path: 'tournaments/:id/draw', component: TournamentDrawComponent, canActivate: [AuthGuard], data: { header: 'Toernooi loten' }},
|
{ path: 'tournaments/:id/draw', component: TournamentDrawComponent, canActivate: [AuthGuard], data: { header: 'Toernooi loten' }},
|
||||||
{ path: 'tournaments/:id/manage', component: TournamentManageComponent, canActivate: [AuthGuard]},
|
{ path: 'tournaments/:id/manage', component: TournamentManageComponent, canActivate: [AuthGuard]},
|
||||||
{ path: 'tournaments/:id/manage/:tab', component: TournamentManageComponent, canActivate: [AuthGuard], data: { header: 'Toernooien' }},
|
{ path: 'tournaments/:id/manage/:tab', component: TournamentManageComponent, canActivate: [AuthGuard], data: { header: 'Toernooien' }},
|
||||||
{ path: 'players', component: PlayerListComponent, canActivate: [AuthGuard], data: { header: 'Spelers' }},
|
{ path: 'players', component: PlayerListComponent, canActivate: [AuthGuard], data: { header: 'Spelers' }},
|
||||||
{ path: 'players/add', component: PlayerEditComponent, canActivate: [AuthGuard], data: { header: 'Nieuwe Speler' }},
|
{ path: 'players/add', component: PlayerEditComponent, canActivate: [AuthGuard], data: { header: 'Nieuwe Speler' }},
|
||||||
{ path: 'players/edit/:id', component: PlayerEditComponent, canActivate: [AuthGuard], data: { header: 'Bewerk Speler' }},
|
{ path: 'players/:id/edit', component: PlayerEditComponent, canActivate: [AuthGuard], data: { header: 'Bewerk Speler' }},
|
||||||
{ path: 'players/:id/registrations', component: PlayerRegistrationsComponent, canActivate: [AuthGuard]},
|
{ path: 'players/:id/registrations', component: PlayerRegistrationsComponent, canActivate: [AuthGuard]},
|
||||||
{ path: 'tournaments/:id/rounds/:roundId/matchsheets', component: MatchSheetsComponent, canActivate: [AuthGuard]},
|
{ path: 'tournaments/:id/rounds/:roundId/matchsheets', component: MatchSheetsComponent, canActivate: [AuthGuard]},
|
||||||
{ path: 'tournaments/:id/rounds/:roundId/overview', component: RoundOverviewComponent, canActivate: [AuthGuard], data: { header: 'Rondeoverzicht' }},
|
{ path: 'tournaments/:id/rounds/:roundId/overview', component: RoundOverviewComponent, canActivate: [AuthGuard], data: { header: 'Rondeoverzicht' }},
|
||||||
|
|||||||
@@ -1,13 +1,32 @@
|
|||||||
<h2 mat-dialog-title>Kies een baan:</h2>
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
@for (item of [].constructor(data.totalCourts); track item) {
|
<h3>Kies een baan:</h3>
|
||||||
<button type="button" class="btn {{ data.availableCourts.indexOf($index + 1) < 0 ? 'btn-secondary' : 'btn-primary' }} btn-lg m-3"
|
@for (item of [].constructor(data.totalCourts); track $index) {
|
||||||
[disabled]="data.availableCourts.indexOf($index + 1) < 0" [mat-dialog-close]="$index + 1">
|
<button type="button"
|
||||||
|
class="btn {{ this.court == ($index + 1) ? 'btn-primary' : (data.availableCourts.indexOf($index + 1) < 0 ? 'btn-outline-secondary' : 'btn-outline-primary') }} btn-lg m-3"
|
||||||
|
[disabled]="data.availableCourts.indexOf($index + 1) < 0"
|
||||||
|
(click)="selectCourt($index + 1)">
|
||||||
{{ $index + 1 }}
|
{{ $index + 1 }}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
<br>
|
<br>
|
||||||
|
<h3>Kies een teller:</h3>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Teller</mat-label>
|
||||||
|
<mat-select [(ngModel)]="counter">
|
||||||
|
<mat-option>Geen</mat-option>
|
||||||
|
@for (player of data.availableCounters; track player.playerId) {
|
||||||
|
<mat-option [value]="player">
|
||||||
|
{{ player.name }}
|
||||||
|
</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
<mat-dialog-actions>
|
<mat-dialog-actions>
|
||||||
|
@if (court && counter) {
|
||||||
|
<button mat-button [mat-dialog-close]="{court: court, counter: counter}">Wedstrijd starten</button>
|
||||||
|
}
|
||||||
<button mat-button (click)="onAnnulerenClick()">Annuleren</button>
|
<button mat-button (click)="onAnnulerenClick()">Annuleren</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
button:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: all !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,20 +3,29 @@ import {
|
|||||||
MAT_DIALOG_DATA,
|
MAT_DIALOG_DATA,
|
||||||
MatDialogActions,
|
MatDialogActions,
|
||||||
MatDialogClose,
|
MatDialogClose,
|
||||||
MatDialogContent, MatDialogRef,
|
MatDialogContent,
|
||||||
MatDialogTitle
|
MatDialogRef
|
||||||
} from "@angular/material/dialog";
|
} from "@angular/material/dialog";
|
||||||
import {Match} from "../../model/match";
|
import {Match} from "../../model/match";
|
||||||
import {MatButton} from "@angular/material/button";
|
import {MatButton} from "@angular/material/button";
|
||||||
|
import {TournamentPlayer} from "../../model/tournamentPlayer";
|
||||||
|
import {MatFormField, MatLabel} from "@angular/material/form-field";
|
||||||
|
import {MatOption, MatSelect} from "@angular/material/select";
|
||||||
|
import {FormsModule} from "@angular/forms";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-court-selection',
|
selector: 'app-court-selection',
|
||||||
imports: [
|
imports: [
|
||||||
MatDialogTitle,
|
|
||||||
MatDialogContent,
|
MatDialogContent,
|
||||||
MatButton,
|
MatButton,
|
||||||
MatDialogClose,
|
MatDialogClose,
|
||||||
MatDialogActions
|
MatDialogActions,
|
||||||
|
MatFormField,
|
||||||
|
MatLabel,
|
||||||
|
MatOption,
|
||||||
|
MatSelect,
|
||||||
|
FormsModule,
|
||||||
|
|
||||||
],
|
],
|
||||||
templateUrl: './court-selection.component.html',
|
templateUrl: './court-selection.component.html',
|
||||||
styleUrl: './court-selection.component.scss'
|
styleUrl: './court-selection.component.scss'
|
||||||
@@ -24,16 +33,22 @@ import {MatButton} from "@angular/material/button";
|
|||||||
export class CourtSelectionComponent {
|
export class CourtSelectionComponent {
|
||||||
|
|
||||||
court: number;
|
court: number;
|
||||||
|
counter: TournamentPlayer;
|
||||||
|
|
||||||
readonly dialogRef = inject(MatDialogRef<CourtSelectionComponent>);
|
readonly dialogRef = inject(MatDialogRef<CourtSelectionComponent>);
|
||||||
|
|
||||||
constructor(@Inject(MAT_DIALOG_DATA) public data: {
|
constructor(@Inject(MAT_DIALOG_DATA) public data: {
|
||||||
match: Match,
|
match: Match,
|
||||||
availableCourts: number[],
|
availableCourts: number[],
|
||||||
totalCourts: number
|
totalCourts: number,
|
||||||
|
availableCounters: TournamentPlayer[]
|
||||||
}) {}
|
}) {}
|
||||||
|
|
||||||
onAnnulerenClick() {
|
onAnnulerenClick() {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectCourt(selectedCourt: number) {
|
||||||
|
this.court = selectedCourt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<ng-container matColumnDef="action">
|
<ng-container matColumnDef="action">
|
||||||
<th mat-header-cell *matHeaderCellDef></th>
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
<td mat-cell *matCellDef="let player">
|
<td mat-cell *matCellDef="let player">
|
||||||
<a mat-button [routerLink]="['/players/edit', player.id]">
|
<a mat-button [routerLink]="['/players', player.id, 'edit']">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
Bewerk
|
Bewerk
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
@if (eventRegistration.doublesEvent) {
|
@if (eventRegistration.doublesEvent) {
|
||||||
<ng-container>
|
|
||||||
<mat-form-field appearance="fill">
|
<mat-form-field appearance="fill">
|
||||||
<mat-label>Partner</mat-label>
|
<mat-label>Partner</mat-label>
|
||||||
<mat-select [value]="eventRegistration.partner" [disabled]="!tournamentRegistration.editable || !eventRegistration.registered" [(ngModel)]="eventRegistration.partner">
|
<mat-select [value]="eventRegistration.partner" [disabled]="!tournamentRegistration.editable || !eventRegistration.registered" [(ngModel)]="eventRegistration.partner">
|
||||||
@@ -28,7 +27,6 @@
|
|||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</ng-container>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6"></div>
|
<div class="col-6"></div>
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
@if (tournament) {
|
|
||||||
<mat-card appearance="outlined">
|
|
||||||
<mat-card-header>
|
|
||||||
<h5>Indeling voor {{ tournament.name }}</h5>
|
|
||||||
</mat-card-header>
|
|
||||||
<mat-card-content>
|
|
||||||
@for (event of tournament.events; track event.id) {
|
|
||||||
<mat-card appearance="outlined" class="m-3">
|
|
||||||
<mat-card-header>
|
|
||||||
<h6>Indeling {{ TournamentEvent.getType(event.type) }}</h6>
|
|
||||||
</mat-card-header>
|
|
||||||
<mat-card-content>
|
|
||||||
<mat-accordion multi="true">
|
|
||||||
@for (group of event.groups; track group.id) {
|
|
||||||
<mat-expansion-panel>
|
|
||||||
<mat-expansion-panel-header>
|
|
||||||
<mat-panel-title>
|
|
||||||
{{ group.name }} <span class="badge text-bg-success">{{ group.teams.length }}</span>
|
|
||||||
</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
<table class="table {{ event.doublesEvent ? 'w-100' : 'w-50' }}">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<tr>
|
|
||||||
<th scope="col" class="w-20">Naam</th>
|
|
||||||
<th scope="col" class="w-20">Club</th>
|
|
||||||
<th scope="col" class="w-10">Speelsterkte</th>
|
|
||||||
@if (event.doublesEvent) {
|
|
||||||
<th scope="col" class="w-20">Partner</th>
|
|
||||||
<th scope="col" class="w-20">Club</th>
|
|
||||||
<th scope="col" class="w-10">Speelsterkte</th>
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@for (team of group.teams; track team.id) {
|
|
||||||
<tr>
|
|
||||||
<td class="align-middle">{{ team.player1 | fullName }}</td>
|
|
||||||
<td class="align-middle">{{ team.player1.club }}</td>
|
|
||||||
<td class="align-middle">{{ getStrength(team.player1.strength.valueOf()) }}</td>
|
|
||||||
@if (event.doublesEvent) {
|
|
||||||
<td class="align-middle">{{ team.player2 | fullName }}</td>
|
|
||||||
<td class="align-middle">{{ team.player2?.club }}</td>
|
|
||||||
<td class="align-middle">{{ team.player2 ? getStrength(team.player2!.strength.valueOf()) : '' }}</td>
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
}
|
|
||||||
</mat-accordion>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
}
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
td, th {
|
|
||||||
background-color: transparent !important;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
|
||||||
import {Tournament} from "../../model/tournament";
|
|
||||||
import {TournamentService} from "../../service/tournament.service";
|
|
||||||
import {ActivatedRoute, Router} from "@angular/router";
|
|
||||||
import {MatCard, MatCardContent, MatCardHeader} from "@angular/material/card";
|
|
||||||
import {
|
|
||||||
MatAccordion,
|
|
||||||
MatExpansionPanel,
|
|
||||||
MatExpansionPanelHeader,
|
|
||||||
MatExpansionPanelTitle
|
|
||||||
} from "@angular/material/expansion";
|
|
||||||
import {Event} from "../../model/event";
|
|
||||||
import {Strength} from "../../model/player";
|
|
||||||
import {FullNamePipe} from "../../pipes/fullname-pipe";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-tournament-divide',
|
|
||||||
imports: [
|
|
||||||
MatCard,
|
|
||||||
MatCardHeader,
|
|
||||||
MatCardContent,
|
|
||||||
MatExpansionPanel,
|
|
||||||
MatExpansionPanelTitle,
|
|
||||||
MatExpansionPanelHeader,
|
|
||||||
FullNamePipe,
|
|
||||||
MatAccordion
|
|
||||||
],
|
|
||||||
templateUrl: './tournament-divide.component.html',
|
|
||||||
styleUrl: './tournament-divide.component.scss'
|
|
||||||
})
|
|
||||||
export class TournamentDivideComponent implements OnInit {
|
|
||||||
tournament?: Tournament;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private tournamentService: TournamentService,
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
const id = this.route.snapshot.paramMap.get('id');
|
|
||||||
this.tournamentService.getById(Number(id)).subscribe(data => {
|
|
||||||
this.tournament = data;
|
|
||||||
});
|
|
||||||
// this.tournamentService.getDivision(Number(id)).subscribe(data => {
|
|
||||||
// this.tournamentDivision = data;
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
protected readonly TournamentEvent = Event;
|
|
||||||
|
|
||||||
getStrength(strength: string) {
|
|
||||||
for (let [key, value] of Object.entries(Strength)) {
|
|
||||||
if (key == strength) return value;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,5 @@
|
|||||||
@if (tournament) {
|
@if (tournament) {
|
||||||
<mat-card appearance="outlined">
|
<mat-card appearance="outlined">
|
||||||
<!--
|
|
||||||
<mat-card-header>
|
|
||||||
<h5>{{ tournament.name }}</h5>
|
|
||||||
</mat-card-header>
|
|
||||||
-->
|
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<mat-tab-group animationDuration="0ms" disableRipple="true">
|
<mat-tab-group animationDuration="0ms" disableRipple="true">
|
||||||
|
|
||||||
@@ -108,56 +103,43 @@
|
|||||||
<mat-tab>
|
<mat-tab>
|
||||||
<ng-template mat-tab-label>
|
<ng-template mat-tab-label>
|
||||||
<mat-icon>play_arrow</mat-icon>
|
<mat-icon>play_arrow</mat-icon>
|
||||||
Actieve wedstrijden
|
Actieve wedstrijden
|
||||||
|
|
||||||
@if (this.activeMatches().length > 0) {
|
@if (this.activeMatches().length > 0) {
|
||||||
<span class="badge text-bg-success">{{ this.activeMatches().length }}</span>
|
<span class="badge text-bg-success">{{ this.activeMatches().length }}</span>
|
||||||
}
|
}
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
@if (this.activeMatches().length > 0) {
|
@if (this.activeMatches().length > 0) {
|
||||||
<table class="table table-hover w-100 m-4">
|
<h6 class="mt-3">Actieve wedstrijden</h6>
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th colspan="3">Wedstrijd</th>
|
|
||||||
<th>Onderdeel/Ronde</th>
|
|
||||||
<th>Start</th>
|
|
||||||
<th>Baan</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@for (activeMatch of this.activeMatches(); track activeMatch.match.id) {
|
@for (activeMatch of this.activeMatches(); track activeMatch.match.id) {
|
||||||
<tr>
|
<mat-expansion-panel>
|
||||||
<td class="align-middle">{{ activeMatch.match.team1 | teamText }}</td>
|
<mat-expansion-panel-header>
|
||||||
<td class="align-middle">-</td>
|
<div class="col-md-2">Baan {{ activeMatch.match.court }}</div>
|
||||||
<td class="align-middle">{{ activeMatch.match.team2 | teamText }}</td>
|
<div class="col-md-3">{{ activeMatch.match.team1 | teamText }}</div>
|
||||||
<td class="align-middle">{{ activeMatch.group.name }} {{ activeMatch.round.name }}</td>
|
<div class="col-md-1">-</div>
|
||||||
<td class="align-middle">{{ activeMatch.match.startTime | date: 'HH:mm' }}</td>
|
<div class="col-md-3">{{ activeMatch.match.team2 | teamText }}</div>
|
||||||
<td class="align-middle">{{ activeMatch.match.court }}</td>
|
<div class="col-md-3">{{ activeMatch.group.name }} {{ activeMatch.round.name }}</div>
|
||||||
<td nowrap class="align-middle">
|
</mat-expansion-panel-header>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">Teller: {{ activeMatch.match.counter | fullName }}</div>
|
||||||
|
<div class="col-md-5"></div>
|
||||||
|
<div class="col-md-2">Starttijd: {{ activeMatch.match.startTime | date: 'HH:mm' }}</div>
|
||||||
|
<div class="col-md-2">Duur: {{ getDuration(activeMatch.match.startTime) | date: 'mm:ss' }}</div>
|
||||||
|
</div>
|
||||||
|
<mat-action-row>
|
||||||
<button class="align-baseline" mat-button (click)="editResult(activeMatch.match, activeMatch.group, activeMatch.round)">
|
<button class="align-baseline" mat-button (click)="editResult(activeMatch.match, activeMatch.group, activeMatch.round)">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
Uitslag invoeren
|
Uitslag invoeren
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button [matMenuTriggerFor]="activeMatchMenu" [matMenuTriggerData]="{ match: activeMatch.match }" class="menu-button">
|
<button mat-button (click)="stopMatch(activeMatch.match)">
|
||||||
<mat-icon>more_vert</mat-icon>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<mat-menu #activeMatchMenu="matMenu">
|
|
||||||
<ng-template matMenuContent let-match="match">
|
|
||||||
<button mat-button (click)="stopMatch(match)">
|
|
||||||
<mat-icon>stop</mat-icon>
|
<mat-icon>stop</mat-icon>
|
||||||
Wedstrijd stoppen
|
Wedstrijd stoppen
|
||||||
</button>
|
</button>
|
||||||
</ng-template>
|
</mat-action-row>
|
||||||
</mat-menu>
|
</mat-expansion-panel>
|
||||||
|
<br>
|
||||||
|
}
|
||||||
} @else {
|
} @else {
|
||||||
<h6 class="mt-3">Geen actieve wedstrijden</h6>
|
<h6 class="mt-3">Geen actieve wedstrijden</h6>
|
||||||
}
|
}
|
||||||
@@ -223,11 +205,11 @@
|
|||||||
<mat-icon>play_arrow</mat-icon>
|
<mat-icon>play_arrow</mat-icon>
|
||||||
Ronde starten
|
Ronde starten
|
||||||
</button>
|
</button>
|
||||||
|
}
|
||||||
<button mat-menu-item (click)="printMatchSheets(round)">
|
<button mat-menu-item (click)="printMatchSheets(round)">
|
||||||
<mat-icon>print</mat-icon>
|
<mat-icon>print</mat-icon>
|
||||||
Wedstrijdbriefjes printen
|
Wedstrijdbriefjes printen
|
||||||
</button>
|
</button>
|
||||||
}
|
|
||||||
<button mat-menu-item (click)="printRoundOverview(round)">
|
<button mat-menu-item (click)="printRoundOverview(round)">
|
||||||
<mat-icon>print</mat-icon>
|
<mat-icon>print</mat-icon>
|
||||||
Rondeoverzicht printen
|
Rondeoverzicht printen
|
||||||
@@ -402,8 +384,7 @@
|
|||||||
}
|
}
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
}
|
|
||||||
@if (tournament.status == 'ONGOING' || tournament.status == 'DRAWN') {
|
|
||||||
<mat-tab>
|
<mat-tab>
|
||||||
<ng-template mat-tab-label>
|
<ng-template mat-tab-label>
|
||||||
<mat-icon>settings</mat-icon>
|
<mat-icon>settings</mat-icon>
|
||||||
|
|||||||
@@ -24,3 +24,11 @@ td.w-sep {
|
|||||||
td.w-fill {
|
td.w-fill {
|
||||||
width: 35%;
|
width: 35%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-90 {
|
||||||
|
width: 90% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-tooltip {
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {Component, inject, Input, OnDestroy, OnInit} from '@angular/core';
|
import {Component, inject, Input, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {
|
import {
|
||||||
MatAccordion,
|
MatAccordion,
|
||||||
MatExpansionPanel,
|
MatExpansionPanel, MatExpansionPanelActionRow,
|
||||||
MatExpansionPanelHeader,
|
MatExpansionPanelHeader,
|
||||||
MatExpansionPanelTitle
|
MatExpansionPanelTitle
|
||||||
} from "@angular/material/expansion";
|
} from "@angular/material/expansion";
|
||||||
@@ -25,13 +25,15 @@ import {MatDialog} from "@angular/material/dialog";
|
|||||||
import {MatchResultPipe} from "../../pipes/match-result-pipe";
|
import {MatchResultPipe} from "../../pipes/match-result-pipe";
|
||||||
import {Event} from "../../model/event";
|
import {Event} from "../../model/event";
|
||||||
import {TournamentValidateComponent} from "../tournament-validate/tournament-validate.component";
|
import {TournamentValidateComponent} from "../tournament-validate/tournament-validate.component";
|
||||||
import {Strength} from "../../model/player";
|
import {Player, Strength} from "../../model/player";
|
||||||
import {MatSlideToggleChange} from "@angular/material/slide-toggle";
|
import {MatSlideToggleChange} from "@angular/material/slide-toggle";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {CourtSelectionComponent} from "../court-selection/court-selection.component";
|
import {CourtSelectionComponent} from "../court-selection/court-selection.component";
|
||||||
import {Standings} from "../../model/standings";
|
import {Standings} from "../../model/standings";
|
||||||
import {HeaderService} from "../../service/header.service";
|
import {HeaderService} from "../../service/header.service";
|
||||||
import {TournamentPlayersComponent} from "../tournament-players/tournament-players.component";
|
import {TournamentPlayersComponent} from "../tournament-players/tournament-players.component";
|
||||||
|
import {TournamentPlayer} from "../../model/tournamentPlayer";
|
||||||
|
import {MatTooltip} from "@angular/material/tooltip";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-tournament-manage',
|
selector: 'app-tournament-manage',
|
||||||
@@ -60,7 +62,8 @@ import {TournamentPlayersComponent} from "../tournament-players/tournament-playe
|
|||||||
DecimalPipe,
|
DecimalPipe,
|
||||||
TournamentValidateComponent,
|
TournamentValidateComponent,
|
||||||
MatMenuContent,
|
MatMenuContent,
|
||||||
TournamentPlayersComponent
|
TournamentPlayersComponent,
|
||||||
|
MatExpansionPanelActionRow,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
FullNamePipe,
|
FullNamePipe,
|
||||||
@@ -102,6 +105,16 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
this.headerService.clearTitle();
|
this.headerService.clearTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDuration(startTime: string | Date): Date {
|
||||||
|
const start = new Date(startTime);
|
||||||
|
const now = new Date();
|
||||||
|
const diffInMs = now.getTime() - start.getTime();
|
||||||
|
|
||||||
|
// Convert milliseconds to a Date object starting from epoch
|
||||||
|
// This allows the date pipe to format it as mm:ss
|
||||||
|
return new Date(diffInMs);
|
||||||
|
}
|
||||||
|
|
||||||
onRoundTabChange(event: MatTabChangeEvent) {
|
onRoundTabChange(event: MatTabChangeEvent) {
|
||||||
const index = event.index;
|
const index = event.index;
|
||||||
this.router.navigate(
|
this.router.navigate(
|
||||||
@@ -152,6 +165,7 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
this.tournament = data;
|
this.tournament = data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reopenGroup(group: Group) {
|
reopenGroup(group: Group) {
|
||||||
this.tournamentService.reopenGroup(this.tournament.id, group.id).subscribe(data => {
|
this.tournamentService.reopenGroup(this.tournament.id, group.id).subscribe(data => {
|
||||||
this.tournament = data;
|
this.tournament = data;
|
||||||
@@ -183,20 +197,24 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
alert('Geen banen beschikbaar!');
|
alert('Geen banen beschikbaar!');
|
||||||
} else if (this.matchContainsPlayersThatArePlaying(match)) {
|
} else if (this.matchContainsPlayersThatArePlaying(match)) {
|
||||||
alert('Deze wedstrijd bevat spelers die al aan het spelen zijn!');
|
alert('Deze wedstrijd bevat spelers die al aan het spelen zijn!');
|
||||||
|
} else if (this.matchContainsPlayersThatAreCounting(match)) {
|
||||||
|
alert('Deze wedstrijd bevat spelers die aan het tellen zijn!');
|
||||||
} else {
|
} else {
|
||||||
this.courtSelectionDialog.open(CourtSelectionComponent, {
|
this.courtSelectionDialog.open(CourtSelectionComponent, {
|
||||||
data: {
|
data: {
|
||||||
match: match,
|
match: match,
|
||||||
availableCourts: this.getAvailableCourts(),
|
availableCourts: this.getAvailableCourts(),
|
||||||
totalCourts: this.tournament.courts
|
totalCourts: this.tournament.courts,
|
||||||
|
availableCounters: this.getAvailableCounters()
|
||||||
},
|
},
|
||||||
minWidth: '800px',
|
minWidth: '800px',
|
||||||
minHeight: '250px'
|
minHeight: '250px'
|
||||||
}).afterClosed().subscribe(result => {
|
}).afterClosed().subscribe(result => {
|
||||||
if (result != undefined) {
|
if (result != undefined) {
|
||||||
this.tournamentService.startMatch(this.tournament.id, match.id, result).subscribe(data => {
|
console.log('Start match on court ' + result.court + ' with counter ' + result.counter.name);
|
||||||
|
this.tournamentService.startMatch(this.tournament.id, match.id, result.court, result.counter.playerId).subscribe(data => {
|
||||||
this.tournament = data;
|
this.tournament = data;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -219,6 +237,22 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
return playersThatArePlaying.length > 0;
|
return playersThatArePlaying.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matchContainsPlayersThatAreCounting(match: Match): boolean {
|
||||||
|
let currentCounters: number[] = [];
|
||||||
|
for (let activeMatch of this.activeMatches()) {
|
||||||
|
currentCounters.push(activeMatch.match.counter.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let matchPlayers: number[] = [];
|
||||||
|
matchPlayers.push(match.team1.player1.id);
|
||||||
|
if (match.team1.player2) matchPlayers.push(match.team1.player2.id);
|
||||||
|
matchPlayers.push(match.team2.player1.id);
|
||||||
|
if (match.team2.player2) matchPlayers.push(match.team2.player2.id);
|
||||||
|
|
||||||
|
let playersThatAreCounting = currentCounters.filter(Set.prototype.has, new Set(matchPlayers));
|
||||||
|
return playersThatAreCounting.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
getAvailableCourts(): number[] {
|
getAvailableCourts(): number[] {
|
||||||
const maxCourts = this.tournament.courts;
|
const maxCourts = this.tournament.courts;
|
||||||
const activeCourts = this.activeMatches().map(activeMatch => activeMatch.match.court);
|
const activeCourts = this.activeMatches().map(activeMatch => activeMatch.match.court);
|
||||||
@@ -229,6 +263,21 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
return courts.filter(court => activeCourts.indexOf(court) < 0);
|
return courts.filter(court => activeCourts.indexOf(court) < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAvailableCounters(): TournamentPlayer[] {
|
||||||
|
const activePlayerIds = new Set(
|
||||||
|
this.activeMatches().flatMap(activeMatch => [
|
||||||
|
activeMatch.match.team1.player1.id,
|
||||||
|
activeMatch.match.team1.player2?.id,
|
||||||
|
activeMatch.match.team2.player1.id,
|
||||||
|
activeMatch.match.team2.player2?.id
|
||||||
|
].filter(id => id !== undefined))
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.tournament.tournamentPlayers.filter(
|
||||||
|
player => !player.counting && !activePlayerIds.has(player.playerId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
stopMatch(match: Match) {
|
stopMatch(match: Match) {
|
||||||
this.tournamentService.stopMatch(this.tournament.id, match.id).subscribe(data => {
|
this.tournamentService.stopMatch(this.tournament.id, match.id).subscribe(data => {
|
||||||
this.tournament = data;
|
this.tournament = data;
|
||||||
@@ -241,18 +290,6 @@ export class TournamentManageComponent implements OnInit, OnDestroy {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
playerPaid($event: MatSlideToggleChange, playerId: number) {
|
|
||||||
this.tournamentService.playerPaid(this.tournament.id, playerId, $event.checked).subscribe(() => {
|
|
||||||
this._snackBar.open('Opgeslagen.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
playerPresent($event: MatSlideToggleChange, playerId: number) {
|
|
||||||
this.tournamentService.playerPresent(this.tournament.id, playerId, $event.checked).subscribe(() => {
|
|
||||||
this._snackBar.open('Opgeslagen.');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getStrength(strength: string | undefined) {
|
getStrength(strength: string | undefined) {
|
||||||
if (strength == undefined) return "";
|
if (strength == undefined) return "";
|
||||||
for (let [key, value] of Object.entries(Strength)) {
|
for (let [key, value] of Object.entries(Strength)) {
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
@if (tournament) {
|
@if (tournament) {
|
||||||
<!-- <mat-card appearance="outlined" class="m-3">-->
|
|
||||||
<!-- <mat-card-header>-->
|
|
||||||
<!-- <h6>Toernooi</h6>-->
|
|
||||||
<!-- </mat-card-header>-->
|
|
||||||
<!-- <mat-card-content>-->
|
|
||||||
<table class="table table-hover w-75 m-4">
|
<table class="table table-hover w-75 m-4">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -48,7 +43,4 @@
|
|||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- </mat-card-content>-->
|
|
||||||
<!-- </mat-card>-->
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
td, th {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {MatCard, MatCardContent, MatCardHeader} from "@angular/material/card";
|
|
||||||
import {CurrencyPipe} from "@angular/common";
|
import {CurrencyPipe} from "@angular/common";
|
||||||
import {MatSlideToggle, MatSlideToggleChange} from "@angular/material/slide-toggle";
|
import {MatSlideToggle, MatSlideToggleChange} from "@angular/material/slide-toggle";
|
||||||
import {TournamentService} from "../../service/tournament.service";
|
import {TournamentService} from "../../service/tournament.service";
|
||||||
@@ -11,10 +10,6 @@ import {MatSnackBar} from "@angular/material/snack-bar";
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-tournament-players',
|
selector: 'app-tournament-players',
|
||||||
imports: [
|
imports: [
|
||||||
MatCard,
|
|
||||||
MatCardContent,
|
|
||||||
MatCardHeader,
|
|
||||||
// MatIcon,
|
|
||||||
CurrencyPipe,
|
CurrencyPipe,
|
||||||
MatSlideToggle,
|
MatSlideToggle,
|
||||||
FormsModule
|
FormsModule
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@if (tournamentValidation && tournament) {
|
@if (tournamentValidation && tournament) {
|
||||||
<mat-card appearance="outlined" class="m-3">
|
<mat-card appearance="outlined" class="m-3">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<h6>Toernooi</h6>
|
<h6>Toernooi ({{ getTournamentMatchCount(tournament)}} wedstrijden)</h6>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<mat-expansion-panel [disabled]="tournamentValidation.validations.length == 0">
|
<mat-expansion-panel [disabled]="tournamentValidation.validations.length == 0">
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
@for (event of tournament.events; track event.id) {
|
@for (event of tournament.events; track event.id) {
|
||||||
<mat-card appearance="outlined" class="m-3">
|
<mat-card appearance="outlined" class="m-3">
|
||||||
<mat-card-header>
|
<mat-card-header>
|
||||||
<h6>{{ TournamentEvent.getType(event.type) }}</h6>
|
<h6>{{ TournamentEvent.getType(event.type) }} ({{ getEventMatchCount(event)}} wedstrijden)</h6>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<mat-accordion multi="true">
|
<mat-accordion multi="true">
|
||||||
|
|||||||
@@ -98,4 +98,24 @@ export class TournamentValidateComponent implements OnInit {
|
|||||||
return hasErrors;
|
return hasErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEventMatchCount(event: Event) {
|
||||||
|
let numTeams = 0;
|
||||||
|
if (event.doublesEvent) {
|
||||||
|
numTeams = event.registrations.length / 2;
|
||||||
|
} else {
|
||||||
|
numTeams = event.registrations.length;
|
||||||
|
}
|
||||||
|
let rounds = numTeams <= 4 ? 3 : 4;
|
||||||
|
let matchesPerRound = Math.trunc(numTeams / 2);
|
||||||
|
|
||||||
|
return rounds * matchesPerRound;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTournamentMatchCount(tournament: Tournament) {
|
||||||
|
let count = 0;
|
||||||
|
for (let event of tournament.events) {
|
||||||
|
count += this.getEventMatchCount(event);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Team } from "./team";
|
import { Team } from "./team";
|
||||||
import {Game} from "./game";
|
import {Game} from "./game";
|
||||||
|
import {Player} from "./player";
|
||||||
|
|
||||||
export class Match {
|
export class Match {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -11,4 +12,5 @@ export class Match {
|
|||||||
endTime: Date;
|
endTime: Date;
|
||||||
games: Game[];
|
games: Game[];
|
||||||
court: number;
|
court: number;
|
||||||
|
counter: Player;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,6 @@ export class TournamentPlayer {
|
|||||||
events: string[];
|
events: string[];
|
||||||
paid: boolean;
|
paid: boolean;
|
||||||
present: boolean;
|
present: boolean;
|
||||||
|
counting: boolean;
|
||||||
|
counts: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,8 @@ export class TeamPipe implements PipeTransform {
|
|||||||
|
|
||||||
transform(team: any, args?: any): any {
|
transform(team: any, args?: any): any {
|
||||||
if (team.player2 != null) {
|
if (team.player2 != null) {
|
||||||
// return this.player1.getFullName() + " / " + this.player2.getFullName();
|
|
||||||
return this.fullNamePipe.transform(team.player1) + " / " + this.fullNamePipe.transform(team.player2);
|
return this.fullNamePipe.transform(team.player1) + " / " + this.fullNamePipe.transform(team.player2);
|
||||||
}
|
}
|
||||||
// return this.player1.getFullName();
|
|
||||||
return this.fullNamePipe.transform(team.player1);
|
return this.fullNamePipe.transform(team.player1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ export class TournamentService {
|
|||||||
return this.http.post<Tournament>(`${this.tournamentsUrl}/${tournamentId}/groups/${groupId}/new`, null);
|
return this.http.post<Tournament>(`${this.tournamentsUrl}/${tournamentId}/groups/${groupId}/new`, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public startMatch(tournamentId: number, matchId: number, court: number): Observable<Tournament> {
|
public startMatch(tournamentId: number, matchId: number, court: number, counter: number): Observable<Tournament> {
|
||||||
return this.http.post<Tournament>(`${this.tournamentsUrl}/${tournamentId}/matches/${matchId}/start/${court}`, null);
|
return this.http.post<Tournament>(`${this.tournamentsUrl}/${tournamentId}/matches/${matchId}/start?court=${court}&counter=${counter}`, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopMatch(tournamentId: number, matchId: number): Observable<Tournament> {
|
public stopMatch(tournamentId: number, matchId: number): Observable<Tournament> {
|
||||||
|
|||||||
Reference in New Issue
Block a user