diff --git a/client/src/app/app.config.ts b/client/src/app/app.config.ts index d830c8d5ef5dc3fd64fafa718662bdd7beab9e8c..cd7098b47b17956a255b4be21506e2397688d918 100644 --- a/client/src/app/app.config.ts +++ b/client/src/app/app.config.ts @@ -3,10 +3,11 @@ import { importProvidersFrom } from '@angular/core'; import { MatDialogModule } from '@angular/material/dialog'; import { MatSnackBarModule } from '@angular/material/snack-bar'; import { provideAnimations } from '@angular/platform-browser/animations'; -import { PreloadAllModules, provideRouter, withHashLocation, withPreloading } from '@angular/router'; +import { PreloadAllModules, TitleStrategy, provideRouter, withHashLocation, withPreloading } from '@angular/router'; import { routes } from '@app/app.routes'; import { provideToastr } from 'ngx-toastr'; import { authInterceptor } from './interceptors/auth/auth.interceptor'; +import { PageTitleStrategy } from './strategies/page-title/page-title.strategy'; export const config = { providers: [ @@ -16,5 +17,6 @@ export const config = { provideToastr(), importProvidersFrom(MatDialogModule), importProvidersFrom(MatSnackBarModule), + { provide: TitleStrategy, useClass: PageTitleStrategy }, ], }; diff --git a/client/src/app/app.routes.ts b/client/src/app/app.routes.ts index 9fd4091a90822443fa17b2ad20338b365c907eef..4c5acd8082810e70d7bc9c01b292adce15aefadd 100644 --- a/client/src/app/app.routes.ts +++ b/client/src/app/app.routes.ts @@ -5,7 +5,7 @@ import { gameRoutes } from './pages/game/game.routes'; export const routes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, - { path: 'home', component: MainPageComponent }, + { path: 'home', title: 'Accueil', component: MainPageComponent }, { path: 'game', children: gameRoutes, diff --git a/client/src/app/pages/admin/admin.routes.ts b/client/src/app/pages/admin/admin.routes.ts index c37e75b4c1264064c0208f11314d6bf54091a90a..cfd3d0e99b89d1908e659c499c22829e0a22b916 100644 --- a/client/src/app/pages/admin/admin.routes.ts +++ b/client/src/app/pages/admin/admin.routes.ts @@ -4,7 +4,11 @@ import { logoutGuard } from '@app/guards/logout/logout.guard'; import { AppWithTopbarComponent } from '@app/pages/app-with-topbar/app-with-topbar.component'; export const adminRoutes: Route[] = [ - { path: 'login', loadComponent: async () => (await import('@app/pages/admin/login-page/login-page.component')).LoginPageComponent }, + { + path: 'login', + title: 'Connexion', + loadComponent: async () => (await import('@app/pages/admin/login-page/login-page.component')).LoginPageComponent, + }, { path: '', canActivate: [authGuard({ redirectTo: '/admin/login' })], @@ -13,20 +17,24 @@ export const adminRoutes: Route[] = [ children: [ { path: '', + title: 'Administration', loadComponent: async () => (await import('@app/pages/admin/admin-page/admin-page.component')).AdminPageComponent, }, { path: 'create-quiz', + title: 'Créer un jeu', loadComponent: async () => (await import('@app/pages/admin/creating-quiz-page/creating-quiz-page.component')).CreatingQuizPageComponent, }, { path: 'create-quiz/:id', + title: 'Modifier un jeu', loadComponent: async () => (await import('@app/pages/admin/creating-quiz-page/creating-quiz-page.component')).CreatingQuizPageComponent, }, { path: 'question-bank', + title: 'Banque de questions', loadComponent: async () => (await import('@app/pages/admin/question-bank-page/question-bank-page.component')).QuestionBankPageComponent, }, diff --git a/client/src/app/pages/game/game.routes.ts b/client/src/app/pages/game/game.routes.ts index 804b80d26076db345d94f246a9c8c4b7e1fcac05..ab0a99041ac3d06cdfdcf8aeb286893c2e04b851 100644 --- a/client/src/app/pages/game/game.routes.ts +++ b/client/src/app/pages/game/game.routes.ts @@ -6,6 +6,7 @@ import { AppWithTopbarComponent } from '@app/pages/app-with-topbar/app-with-topb export const gameRoutes: Route[] = [ { path: 'join', + title: 'Rejoindre une partie', children: [ { path: '', @@ -28,6 +29,7 @@ export const gameRoutes: Route[] = [ }, { path: 'create', + title: 'Créer une partie', loadComponent: async () => (await import('./create-game-page/create-game.component')).CreateGamePageComponent, }, { @@ -37,18 +39,22 @@ export const gameRoutes: Route[] = [ children: [ { path: 'lobby', + title: "Salle d'attente", loadComponent: async () => (await import('./lobby-page/lobby-page.component')).LobbyPageComponent, }, { path: 'play', + title: 'Jeu', loadComponent: async () => (await import('./game-page/game-page.component')).GamePageComponent, }, { path: 'play/host', + title: 'Jeu', loadComponent: async () => (await import('./organiser-game-page/organiser-game-page.component')).OrganiserGamePageComponent, }, { path: 'results', + title: 'Résultats', loadComponent: async () => (await import('./results-page/results-page.component')).ResultsPageComponent, }, ], diff --git a/client/src/app/strategies/page-title/page-title.strategy.constants.ts b/client/src/app/strategies/page-title/page-title.strategy.constants.ts new file mode 100644 index 0000000000000000000000000000000000000000..fdff595148bdf0225486437017dbdb6f7808046f --- /dev/null +++ b/client/src/app/strategies/page-title/page-title.strategy.constants.ts @@ -0,0 +1 @@ +export const APP_TITLE = 'Oracles'; diff --git a/client/src/app/strategies/page-title/page-title.strategy.spec.ts b/client/src/app/strategies/page-title/page-title.strategy.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..61e04e0827a37bc138408b494fc1caf340b3ffd4 --- /dev/null +++ b/client/src/app/strategies/page-title/page-title.strategy.spec.ts @@ -0,0 +1,71 @@ +import { DOCUMENT } from '@angular/common'; +import { provideLocationMocks } from '@angular/common/testing'; +import { Component } from '@angular/core'; +import { fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { provideRouter, Router, TitleStrategy } from '@angular/router'; +import { PageTitleStrategy } from './page-title.strategy'; + +@Component({ template: '' }) +export class TestComponent {} + +describe('PageTitleStrategyService', () => { + let router: Router; + let document: Document; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + provideRouter([]), + provideLocationMocks(), + { + provide: TitleStrategy, + useClass: PageTitleStrategy, + }, + ], + }); + + router = TestBed.inject(Router); + document = TestBed.inject(DOCUMENT); + }); + + it('should format title corerctly if it is missing', fakeAsync(() => { + router.resetConfig([ + { + path: 'foo', + component: TestComponent, + }, + ]); + + router.navigateByUrl('/foo'); + tick(); + expect(document.title).toBe('Oracles'); + })); + + it('should format title corerctly if it is empty', fakeAsync(() => { + router.resetConfig([ + { + path: 'foo', + title: '', + component: TestComponent, + }, + ]); + + router.navigateByUrl('/foo'); + tick(); + expect(document.title).toBe('Oracles'); + })); + + it('should format title corerctly if it is provided', fakeAsync(() => { + router.resetConfig([ + { + path: 'foo', + title: 'Foo', + component: TestComponent, + }, + ]); + + router.navigateByUrl('/foo'); + tick(); + expect(document.title).toBe('Foo | Oracles'); + })); +}); diff --git a/client/src/app/strategies/page-title/page-title.strategy.ts b/client/src/app/strategies/page-title/page-title.strategy.ts new file mode 100644 index 0000000000000000000000000000000000000000..5bfd6d9ebcd3f4cd05f4937d929a31c73c6738fd --- /dev/null +++ b/client/src/app/strategies/page-title/page-title.strategy.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { Title } from '@angular/platform-browser'; +import { RouterStateSnapshot, TitleStrategy } from '@angular/router'; +import { APP_TITLE } from './page-title.strategy.constants'; + +@Injectable({ providedIn: 'root' }) +export class PageTitleStrategy extends TitleStrategy { + constructor(private readonly title: Title) { + super(); + } + + override updateTitle(routerState: RouterStateSnapshot) { + const title = this.buildTitle(routerState); + this.title.setTitle(title ? `${title} | ${APP_TITLE}` : APP_TITLE); + } +} diff --git a/client/src/index.html b/client/src/index.html index f63f7c66a1da6c1c0a9e92e5aa8a3d2dfd52fdba..9c0496e4db9ca5b7a3575c003442f83c513ef94b 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta charset="utf-8" /> - <title>Client</title> + <title>Oracles</title> <base href="/" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" type="image/x-icon" href="favicon.ico" />