Refactored title service
All checks were successful
Gitea/swiss-client/pipeline/head This commit looks good

This commit is contained in:
2025-08-13 23:40:36 +02:00
parent f88cd94316
commit 26c0c1a2da
16 changed files with 88 additions and 94 deletions

View File

@@ -7,7 +7,7 @@
<mat-icon class="menu-button-icon" style="color: white;">menu</mat-icon>
</button>
-->
<h5 class="m-3">{{ title }}</h5>
<h5 class="m-3">{{ header }}</h5>
<span class="spacer"></span>
<a routerLink="/tournaments" mat-button>
<mat-icon>list</mat-icon>

View File

@@ -1,26 +1,24 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Router, RouterLink, RouterOutlet} from '@angular/router';
import {ActivatedRoute, NavigationEnd, Router, RouterLink, RouterOutlet} from '@angular/router';
import {CommonModule, NgOptimizedImage} from "@angular/common";
import {MatAnchor, MatButton} from "@angular/material/button";
import {MatIcon} from "@angular/material/icon";
import {MatToolbar} from "@angular/material/toolbar";
import {TitleService} from "./service/title.service";
import {Subscription} from "rxjs";
import {filter, map, Subscription} from "rxjs";
import {MatMenu, MatMenuItem, MatMenuTrigger} from "@angular/material/menu";
import {UserService} from "./authentication/user.service";
import {TournamentService} from "./service/tournament.service";
import {HeaderService} from "./service/header.service";
@Component({
selector: 'app-root',
imports: [RouterOutlet, CommonModule, RouterLink, MatAnchor, MatIcon, MatButton, MatToolbar, NgOptimizedImage, MatMenuTrigger, MatMenu, MatMenuItem],
providers: [TitleService],
imports: [RouterOutlet, CommonModule, RouterLink, MatAnchor, MatIcon, MatButton, MatToolbar, NgOptimizedImage, MatMenuTrigger, MatMenu, MatMenuItem],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent implements OnInit, OnDestroy {
export class AppComponent implements OnInit {
title: string;
titleSubscription: Subscription;
header: string;
user: string;
userSubscription: Subscription;
@@ -28,18 +26,32 @@ export class AppComponent implements OnInit, OnDestroy {
protected userService: UserService,
private router: Router,
protected activatedRoute: ActivatedRoute,
private titleService: TitleService,
private tournamentService: TournamentService
private tournamentService: TournamentService,
private headerService: HeaderService
) {
}
ngOnInit() {
this.titleSubscription = this.titleService.currentTitle.subscribe(newTitle => this.title = newTitle);
this.userSubscription = this.userService.currentUser.subscribe(newUser => this.user = newUser);
}
ngOnDestroy(): void {
this.titleSubscription.unsubscribe();
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => {
let currentRoute = this.activatedRoute;
while (currentRoute.firstChild) {
currentRoute = currentRoute.firstChild;
}
return currentRoute.snapshot.data['header'] || '';
})
).subscribe(header => {
this.header = header;
});
this.headerService.header$.subscribe(override => {
if (override) {
this.header = override;
}
});
}
logOut() {

View File

@@ -15,21 +15,21 @@ import {AuthGuard} from "./authentication/authguard";
import {LoginComponent} from "./components/login/login.component";
export const routes: Routes = [
{ path: '', component: TournamentListComponent, canActivate: [AuthGuard], title: 'Toernooien' },
{ path: 'tournaments', component: TournamentListComponent, canActivate: [AuthGuard], title: 'Toernooien' },
{ path: 'tournaments/add', component: TournamentEditComponent, canActivate: [AuthGuard], title: 'Nieuw Toernooi' },
{ path: 'tournaments/:id/edit', component: TournamentEditComponent, canActivate: [AuthGuard], title: 'Bewerk Toernooi' },
{ path: 'tournaments/:id/registrations', component: TournamentRegistrationsComponent, canActivate: [AuthGuard], title: 'Inschrijvingen' },
{ path: 'tournaments/:id/validate', component: TournamentValidateComponent, canActivate: [AuthGuard], title: 'Toernooi' },
{ path: 'tournaments/:id/divide', component: TournamentDivideComponent, canActivate: [AuthGuard], title: 'Toernooi valideren' },
{ path: 'tournaments/:id/draw', component: TournamentDrawComponent, canActivate: [AuthGuard], title: 'Toernooi loten' },
{ path: 'tournaments/:id/manage', component: TournamentManageComponent, canActivate: [AuthGuard] },
{ path: 'tournaments/:id/manage/:tab', component: TournamentManageComponent, canActivate: [AuthGuard], title: 'Toernooien' },
{ path: 'players', component: PlayerListComponent, canActivate: [AuthGuard], title: 'Spelers' },
{ path: 'players/add', component: PlayerEditComponent, canActivate: [AuthGuard], title: 'Nieuwe Speler' },
{ path: 'players/edit/:id', component: PlayerEditComponent, canActivate: [AuthGuard], title: 'Bewerk Speler' },
{ path: 'players/:id/registrations', component: PlayerRegistrationsComponent, canActivate: [AuthGuard], title: 'Inschrijvingen' },
{ path: 'tournaments/:id/rounds/:roundId/matchsheets', component: MatchSheetsComponent, canActivate: [AuthGuard], title: 'Wedstrijdbriefjes' },
{ path: 'tournaments/:id/rounds/:roundId/overview', component: RoundOverviewComponent, canActivate: [AuthGuard], title: 'Rondeoverzicht' },
{ path: 'auth/login', component: LoginComponent }
{ path: '', component: TournamentListComponent, canActivate: [AuthGuard], data: { header: 'Toernooien' }},
{ path: 'tournaments', component: TournamentListComponent, canActivate: [AuthGuard], data: { header: 'Toernooien' }},
{ 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/registrations', component: TournamentRegistrationsComponent, 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/manage', component: TournamentManageComponent, canActivate: [AuthGuard]},
{ path: 'tournaments/:id/manage/:tab', component: TournamentManageComponent, canActivate: [AuthGuard], data: { header: 'Toernooien' }},
{ path: 'players', component: PlayerListComponent, canActivate: [AuthGuard], data: { header: 'Spelers' }},
{ 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/registrations', component: PlayerRegistrationsComponent, 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: 'auth/login', component: LoginComponent, data: { header: 'Inloggen'}}
];

View File

@@ -10,7 +10,6 @@ import {AuthenticationService} from "../../authentication/authentication.service
import {UserService} from "../../authentication/user.service";
import {LoginCredentials} from "../../authentication/loginCredentials";
import {User} from "../../authentication/user";
import {TitleService} from "../../service/title.service";
@Component({
@@ -38,7 +37,6 @@ export class LoginComponent implements OnInit {
private authenticationService: AuthenticationService,
private router: Router,
private userPersistenceService: UserService,
private titleService: TitleService,
) {
this.initializeForm();
}
@@ -52,7 +50,6 @@ export class LoginComponent implements OnInit {
ngOnInit() {
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
this.titleService.setTitle("Inloggen");
}
login() {

View File

@@ -1,4 +1,4 @@
import {Component, OnInit} from '@angular/core';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {MatCard, MatCardContent} from "@angular/material/card";
import {TournamentService} from "../../service/tournament.service";
import {ActivatedRoute, Router} from "@angular/router";
@@ -10,7 +10,7 @@ import {Group} from "../../model/group";
import {MatFormField} from "@angular/material/form-field";
import {MatInput} from "@angular/material/input";
import {ReactiveFormsModule} from "@angular/forms";
import {TitleService} from "../../service/title.service";
import {HeaderService} from "../../service/header.service";
@Component({
selector: 'app-match-sheets',
@@ -29,7 +29,7 @@ import {TitleService} from "../../service/title.service";
templateUrl: './match-sheets.component.html',
styleUrl: './match-sheets.component.scss'
})
export class MatchSheetsComponent implements OnInit {
export class MatchSheetsComponent implements OnInit, OnDestroy {
tournament: Tournament;
group: Group;
@@ -39,7 +39,7 @@ export class MatchSheetsComponent implements OnInit {
private tournamentService: TournamentService,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService
private headerService: HeaderService
) {
}
@@ -55,7 +55,7 @@ export class MatchSheetsComponent implements OnInit {
if (round.id == roundId) {
this.group = group;
this.round = round;
this.titleService.setTitle(`Wedstrijdbriefjes ${this.group.name} ${this.round.name}`);
this.headerService.setTitle(`Wedstrijdbriefjes ${this.group.name} ${this.round.name}`);
return;
}
}
@@ -64,4 +64,8 @@ export class MatchSheetsComponent implements OnInit {
});
}
ngOnDestroy() {
this.headerService.clearTitle()
}
}

View File

@@ -11,7 +11,6 @@ import {MatCard, MatCardActions, MatCardContent} from "@angular/material/card";
import {MatOption, MatSelect} from "@angular/material/select";
import {KeyValuePipe} from "@angular/common";
import {MatAnchor, MatButton} from "@angular/material/button";
import {TitleService} from "../../service/title.service";
import {MatSnackBar} from "@angular/material/snack-bar";
import {NgxMaskDirective} from "ngx-mask";
@@ -50,7 +49,6 @@ export class PlayerEditComponent implements OnInit {
private playerService: PlayerService,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService,
private _snackBar: MatSnackBar,
) {
this.player = new Player();
@@ -59,13 +57,11 @@ export class PlayerEditComponent implements OnInit {
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
if (id) {
this.titleService.setTitle("Bewerk Speler");
this.isEditMode = true;
this.playerService.getById(Number(id)).subscribe(data => {
this.player = data;
});
} else {
this.titleService.setTitle("Nieuwe Speler");
}
}

View File

@@ -1,11 +1,11 @@
import {Component, Input, OnInit} from '@angular/core';
import {MatAnchor} from "@angular/material/button";
// import {MatAnchor} from "@angular/material/button";
import {RouterLink} from "@angular/router";
@Component({
selector: 'player-link',
imports: [
MatAnchor,
// MatAnchor,
RouterLink
],
templateUrl: './player-link.component.html',

View File

@@ -6,7 +6,6 @@ import {MatAnchor} from "@angular/material/button";
import {MatIcon} from "@angular/material/icon";
import {MatCard, MatCardContent} from "@angular/material/card";
import {FullNamePipe} from "../../pipes/fullname-pipe";
import {TitleService} from "../../service/title.service";
import {
MatCell,
MatCellDef,
@@ -42,13 +41,11 @@ export class PlayerListComponent implements AfterViewInit {
@ViewChild(MatSort) sort: MatSort;
constructor(
private titleService: TitleService,
private playerService: PlayerService,
private fullNamePipe: FullNamePipe) {
}
ngAfterViewInit() {
this.titleService.setTitle("Spelers");
this.playerService.getAll().subscribe(data => {
this.players = data;
this.dataSource = new MatTableDataSource(this.players);

View File

@@ -14,7 +14,7 @@ import {MatIcon} from "@angular/material/icon";
import {MatAnchor, MatButton} from "@angular/material/button";
import {MatSnackBar} from "@angular/material/snack-bar";
import {FullNamePipe} from "../../pipes/fullname-pipe";
import {TitleService} from "../../service/title.service";
import {HeaderService} from "../../service/header.service";
@Component({
selector: 'app-player-registrations',
@@ -57,15 +57,15 @@ export class PlayerRegistrationsComponent implements OnInit {
private registrationService: RegistrationService,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService,
private fullNamePipe: FullNamePipe
private fullNamePipe: FullNamePipe,
private headerService: HeaderService,
) {}
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.playerService.getById(Number(id)).subscribe(data => {
this.player = data;
this.titleService.setTitle(`Inschrijvingen van ${this.fullNamePipe.transform(this.player)}`);
this.headerService.setTitle(`Inschrijvingen van ${this.fullNamePipe.transform(this.player)}`);
});
this.registrationService.getTournamentRegistrationsByPlayerId(Number(id)).subscribe(data => {
this.tournamentRegistrations = data;

View File

@@ -8,7 +8,6 @@ import {ActivatedRoute, Router} from "@angular/router";
import {DecimalPipe} from "@angular/common";
import {TeamPipe} from "../../pipes/team-pipe";
import {FullNamePipe} from "../../pipes/fullname-pipe";
import {TitleService} from "../../service/title.service";
@Component({
selector: 'app-round-overview',
@@ -36,12 +35,10 @@ export class RoundOverviewComponent implements OnInit {
private tournamentService: TournamentService,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService
) {
}
ngOnInit() {
this.titleService.setTitle("Rondeoverzicht");
const tournamentId = this.route.snapshot.paramMap.get('id');
let roundId = Number(this.route.snapshot.paramMap.get('roundId'));

View File

@@ -11,7 +11,6 @@ import {MatInput} from "@angular/material/input";
import {MatRadioButton, MatRadioGroup} from "@angular/material/radio";
import {CurrencyPipe, registerLocaleData} from "@angular/common";
import nl from "@angular/common/locales/nl";
import {TitleService} from "../../service/title.service";
import {NgxMaskDirective} from "ngx-mask";
import {MatSnackBar} from "@angular/material/snack-bar";
import {MatCheckbox} from "@angular/material/checkbox";
@@ -54,7 +53,6 @@ export class TournamentEditComponent implements OnInit {
private currencyPipe: CurrencyPipe,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService,
private _snackBar: MatSnackBar,
) {
this.tournament = new Tournament();
@@ -63,13 +61,11 @@ export class TournamentEditComponent implements OnInit {
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
if (id) {
this.titleService.setTitle("Bewerk Toernooi");
this.isEditMode = true;
this.tournamentService.getById(Number(id)).subscribe(data => {
this.tournament = data;
})
} else {
this.titleService.setTitle("Nieuw Toernooi");
}
}

View File

@@ -6,7 +6,7 @@ import {MatAnchor, MatButton} from "@angular/material/button";
import {MatIcon} from "@angular/material/icon";
import {MatCard, MatCardContent} from "@angular/material/card";
import {MatTableModule} from "@angular/material/table";
import {TitleService} from "../../service/title.service";
import {HeaderService} from "../../service/header.service";
@Component({
selector: 'app-tournament-list',
@@ -16,14 +16,13 @@ import {TitleService} from "../../service/title.service";
templateUrl: './tournament-list.component.html',
styleUrl: './tournament-list.component.scss'
})
export class TournamentListComponent implements OnInit, AfterContentChecked {
export class TournamentListComponent implements OnInit {
tournaments: Tournament[];
showInactive: boolean = false;
constructor(
private tournamentService: TournamentService,
private titleService: TitleService
private tournamentService: TournamentService
) {}
ngOnInit() {
@@ -32,10 +31,6 @@ export class TournamentListComponent implements OnInit, AfterContentChecked {
});
}
ngAfterContentChecked() {
this.titleService.setTitle("Toernooien");
}
protected readonly Tournament = Tournament;
clearDraw(tournament: Tournament) {

View File

@@ -1,4 +1,4 @@
import {Component, inject, Input, OnInit} from '@angular/core';
import {Component, inject, Input, OnDestroy, OnInit} from '@angular/core';
import {
MatAccordion,
MatExpansionPanel,
@@ -31,7 +31,7 @@ import {MatSnackBar} from "@angular/material/snack-bar";
import {CourtSelectionComponent} from "../court-selection/court-selection.component";
import {Standings} from "../../model/standings";
import {Title} from '@angular/platform-browser';
import {TitleService} from "../../service/title.service";
import {HeaderService} from "../../service/header.service";
@Component({
selector: 'app-tournament-manage',
@@ -71,7 +71,7 @@ import {TitleService} from "../../service/title.service";
templateUrl: './tournament-manage.component.html',
styleUrl: './tournament-manage.component.scss'
})
export class TournamentManageComponent implements OnInit {
export class TournamentManageComponent implements OnInit, OnDestroy {
@Input() tournament: Tournament;
@@ -82,8 +82,7 @@ export class TournamentManageComponent implements OnInit {
private _snackBar: MatSnackBar,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService,
private title: Title
private headerService: HeaderService,
) {
}
@@ -96,11 +95,14 @@ export class TournamentManageComponent implements OnInit {
})
this.tournamentService.getById(Number(id)).subscribe(data => {
this.tournament = data;
this.titleService.setTitle(this.tournament.name);
this.title.setTitle(this.tournament.name);
this.headerService.setTitle(this.tournament.name);
});
}
ngOnDestroy() {
this.headerService.clearTitle();
}
onRoundTabChange(event: MatTabChangeEvent) {
const index = event.index;
this.router.navigate(

View File

@@ -5,7 +5,6 @@ import {TournamentService} from "../../service/tournament.service";
import {ActivatedRoute, Router} from "@angular/router";
import {Event} from "../../model/event";
import {FullNamePipe} from "../../pipes/fullname-pipe";
import {TitleService} from "../../service/title.service";
@Component({
selector: 'app-tournament-registrations',
@@ -26,11 +25,9 @@ export class TournamentRegistrationsComponent implements OnInit {
private tournamentService: TournamentService,
private route: ActivatedRoute,
private router: Router,
private titleService: TitleService
) {}
ngOnInit() {
this.titleService.setTitle("Inschrijvingen");
const id = this.route.snapshot.paramMap.get('id');
this.tournamentService.getById(Number(id)).subscribe(data => {
this.tournament = data;

View File

@@ -0,0 +1,17 @@
// header.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class HeaderService {
private headerSource = new BehaviorSubject<string | null>(null);
header$ = this.headerSource.asObservable();
setTitle(header: string) {
this.headerSource.next(header);
}
clearTitle() {
this.headerSource.next(null);
}
}

View File

@@ -1,16 +0,0 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class TitleService {
private title = new BehaviorSubject('');
currentTitle = this.title.asObservable();
constructor() { }
setTitle(message: string) {
this.title.next(message);
}
}