From 0714bbab44bc481dbee3357658a4a6fc41ac5152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20PAILHAREY?= <rpailharey@grandlyon.com> Date: Thu, 30 May 2024 15:12:26 +0000 Subject: [PATCH] feat: simpler urls with permalinks --- .../deleted-structures.component.ts | 2 +- .../administred-structures.component.html | 4 +- .../admin-structures-list.component.ts | 8 +-- .../models/adminStructureList.interface.ts | 1 + .../result-list/result-list.component.ts | 7 +- src/app/app-routing.module.ts | 35 +++++----- src/app/carto/carto.component.ts | 8 ++- src/app/footer/footer.component.html | 2 +- .../form/footer-form/footer-form.component.ts | 2 +- .../form-view/form-view-routing.module.ts | 12 ++-- .../form/form-view/form-view.component.html | 8 +-- src/app/form/form-view/form-view.component.ts | 29 +++++---- src/app/form/form-view/formType.enum.ts | 9 +++ .../form-view/guards/personalOffer.guard.ts | 10 +-- .../personal-offer-form.component.ts | 2 +- .../orientation-form-view.component.ts | 2 +- src/app/guards/auth.guard.ts | 4 +- src/app/guards/resetPasswordToken.guard.ts | 2 +- src/app/guards/role.guard.ts | 8 ++- src/app/header/header.component.html | 12 ++-- src/app/header/header.component.ts | 4 +- src/app/login/login.component.ts | 8 +-- src/app/models/owner.model.ts | 1 + src/app/models/structure.model.ts | 1 + src/app/models/user.model.ts | 2 + .../newsletter-subscription.component.html | 2 +- .../post-card/post-card.component.ts | 2 +- .../post-details/post-details.component.ts | 4 +- .../post-header/post-header.component.ts | 2 +- src/app/post/models/post.model.ts | 1 + src/app/post/post-routing.module.ts | 4 +- src/app/post/services/post.service.ts | 4 +- src/app/profile/edit/edit.component.ts | 6 +- .../personal-offer-edition.component.ts | 4 +- src/app/profile/profile-routing.module.ts | 12 ++-- .../personal-offer.component.ts | 2 +- .../profile-structure.component.ts | 13 ++-- src/app/profile/profile.component.ts | 18 ++--- .../structure-edition-summary.component.ts | 4 +- .../structures-management.component.ts | 4 +- .../forgot-password.component.ts | 2 +- src/app/resolvers/structure.resolver.ts | 6 +- src/app/services/auth.service.ts | 2 +- src/app/services/structure.service.ts | 4 ++ src/app/services/user.service.ts | 5 +- .../member-card/member-card.component.ts | 2 +- .../components/card/card.component.ts | 5 +- .../structure-details.component.ts | 39 ++++++----- .../structure-list-search.component.ts | 5 +- .../structure-list/services/search.service.ts | 3 +- .../structure-list.component.ts | 19 ++---- .../structure-join.component.html | 20 +++--- .../structure-join.component.ts | 18 +++-- src/sitemap.xml | 65 +++++++++++-------- 54 files changed, 247 insertions(+), 213 deletions(-) diff --git a/src/app/admin/components/deleted-structures/deleted-structures.component.ts b/src/app/admin/components/deleted-structures/deleted-structures.component.ts index 03da0fb9d..2ef8c5594 100644 --- a/src/app/admin/components/deleted-structures/deleted-structures.component.ts +++ b/src/app/admin/components/deleted-structures/deleted-structures.component.ts @@ -65,7 +65,7 @@ export class DeletedStructuresComponent implements OnInit { } private renderLink(structure: Structure): string { - return `<a href="/acteurs?id=${structure._id}" target="_blank">${structure.structureName}</a>`; + return `<a href="/acteurs?structure=${structure.permalink}" target="_blank">${structure.structureName}</a>`; } private restoreStructure(structureId: string): void { diff --git a/src/app/admin/components/manage-users/administred-structures/administred-structures.component.html b/src/app/admin/components/manage-users/administred-structures/administred-structures.component.html index 1b32cce76..cb937d29d 100644 --- a/src/app/admin/components/manage-users/administred-structures/administred-structures.component.html +++ b/src/app/admin/components/manage-users/administred-structures/administred-structures.component.html @@ -1,5 +1,7 @@ <div *ngIf="structures.data.structures && structures.data.structures.length !== 0"> <p *ngFor="let structure of structures.data.structures"> - <a *ngIf="structure" target="_blank" href="/acteurs?id={{ structure._id }}">{{ structure.structureName }}</a> + <a *ngIf="structure" target="_blank" href="/acteurs?structure={{ structure.permalink }}">{{ + structure.structureName + }}</a> </p> </div> diff --git a/src/app/admin/components/structures-list/admin-structures-list.component.ts b/src/app/admin/components/structures-list/admin-structures-list.component.ts index dca6de719..3342277bf 100644 --- a/src/app/admin/components/structures-list/admin-structures-list.component.ts +++ b/src/app/admin/components/structures-list/admin-structures-list.component.ts @@ -1,6 +1,5 @@ import { DatePipe } from '@angular/common'; import { Component, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; import { ColDef } from 'ag-grid-community'; import { finalize } from 'rxjs/operators'; import { AdminStructure } from '../../models/adminStructureList.interface'; @@ -15,7 +14,6 @@ export class AdminStructuresListComponent implements OnInit { constructor( private adminService: AdminService, private datePipe: DatePipe, - private router: Router, ) {} public structuresClaimed: AdminStructure[]; public structuresInClaim: AdminStructure[]; @@ -28,7 +26,7 @@ export class AdminStructuresListComponent implements OnInit { public columnDefs: ColDef<AdminStructure>[] = [ { headerName: 'Structure', - cellRenderer: (params): string => this.renderLink(params.data.structureId, params.data.structureName), + cellRenderer: (params): string => this.renderLink(params.data), comparator(_, __, nodeA, nodeB): number { return nodeA.data.structureName.toLowerCase() > nodeB.data.structureName.toLocaleLowerCase() ? -1 : 1; }, @@ -59,7 +57,7 @@ export class AdminStructuresListComponent implements OnInit { }); } - private renderLink(structureId: string, structureName: string): string { - return `<a href="/acteurs?id=${structureId}" target="_blank">${structureName}</a>`; + private renderLink(structure: AdminStructure): string { + return `<a href="/acteurs?structure=${structure.permalink}" target="_blank">${structure.structureName}</a>`; } } diff --git a/src/app/admin/models/adminStructureList.interface.ts b/src/app/admin/models/adminStructureList.interface.ts index 9a751bbb6..8229ee489 100644 --- a/src/app/admin/models/adminStructureList.interface.ts +++ b/src/app/admin/models/adminStructureList.interface.ts @@ -10,4 +10,5 @@ export interface AdminStructure { structureName: string; updatedAt: Date; isOutdated: boolean; + permalink: string; } diff --git a/src/app/annuaire/result-list/result-list.component.ts b/src/app/annuaire/result-list/result-list.component.ts index 152027e06..fd7d3f431 100644 --- a/src/app/annuaire/result-list/result-list.component.ts +++ b/src/app/annuaire/result-list/result-list.component.ts @@ -53,14 +53,11 @@ export class ResultListComponent implements OnChanges, AfterViewInit { }, 0); } } - public goToUser(userId: string): void { - this.router.navigateByUrl(`/profile/${userId}`); - } public goLogin(): void { - this.router.navigate(['/login'], { queryParams: { returnUrl: '/annuaire' } }); + this.router.navigate(['/connexion'], { queryParams: { returnUrl: '/annuaire' } }); } public goRegister(): void { - this.router.navigateByUrl('/form/account'); + this.router.navigateByUrl('/formulaire/compte'); } public resetFilters(): void { this.resetEvent.emit(); diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 5e92142b2..b9bc19160 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -42,6 +42,10 @@ const routes: Routes = [ { path: 'acteurs', title: buildTitle('Cartographie'), + runGuardsAndResolvers: 'always', + resolve: { + structure: StructureResolver, + }, children: [ { path: '', @@ -51,14 +55,11 @@ const routes: Routes = [ path: '', outlet: 'left-pane', component: StructureDetailsComponent, - resolve: { - structure: StructureResolver, - }, }, ], }, { - path: 'login', + path: 'connexion', title: buildTitle('Connexion'), children: [ { @@ -78,7 +79,7 @@ const routes: Routes = [ ], }, { - path: 'legal-notice', + path: 'mentions-legales', title: buildTitle('Mentions légales'), children: [ { @@ -130,7 +131,7 @@ const routes: Routes = [ ], }, { - path: 'profile', + path: 'profil', title: buildTitle('Profil'), children: [ { @@ -142,6 +143,7 @@ const routes: Routes = [ path: '', outlet: 'left-pane', data: { fullScreen: true }, + runGuardsAndResolvers: 'always', component: StructureDetailsComponent, resolve: { structure: StructureResolver, @@ -150,7 +152,7 @@ const routes: Routes = [ ], }, { - path: 'join-request/:id', + path: 'join-request/:permalink', children: [ { path: '', @@ -176,7 +178,7 @@ const routes: Routes = [ ], }, { - path: 'reset-password', + path: 'mot-de-passe-oublie', children: [ { path: '', @@ -197,7 +199,7 @@ const routes: Routes = [ ], }, { - path: 'newsletter-unsubscribe', + path: 'desabonnement-newsletter', children: [ { path: '', @@ -218,7 +220,7 @@ const routes: Routes = [ ], }, { - path: 'news', + path: 'actualites', title: buildTitle('Actualités'), children: [ { @@ -240,13 +242,17 @@ const routes: Routes = [ ], }, { - path: 'form', + path: 'formulaire', title: buildTitle(), loadChildren: () => import('./form/form-view/form-view.module').then((m) => m.FormViewModule), }, { path: 'orientation', title: buildTitle('Orientation'), + runGuardsAndResolvers: 'always', + resolve: { + structure: StructureResolver, + }, children: [ { path: '', @@ -257,19 +263,16 @@ const routes: Routes = [ outlet: 'left-pane', data: { fullScreen: true, meeting: false }, component: StructureDetailsComponent, - resolve: { - structure: StructureResolver, - }, }, ], }, { path: 'home', - redirectTo: 'news', + redirectTo: 'actualites', }, { path: '**', - redirectTo: 'news', + redirectTo: 'actualites', }, ]; diff --git a/src/app/carto/carto.component.ts b/src/app/carto/carto.component.ts index 54c79feab..e0a9b8048 100644 --- a/src/app/carto/carto.component.ts +++ b/src/app/carto/carto.component.ts @@ -56,9 +56,11 @@ export class CartoComponent implements OnInit { } } - if (history.state.data) { - this.currentStructure = new Structure(history.state.data); - } + this.activatedRoute.data.subscribe((data) => { + if (data.structure) { + this.currentStructure = new Structure(data.structure); + } + }); this.meta.updateTag({ name: 'description', diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 358806c4b..abb538aad 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -1,6 +1,6 @@ <footer class="footer"> <div class="links"> - <a class="clickable text-align-center" routerLink="/legal-notice" i18n>Mentions légales</a> + <a class="clickable text-align-center" routerLink="/mentions-legales" i18n>Mentions légales</a> <a class="clickable text-align-center" routerLink="/newsletter" i18n>Newsletter</a> <a class="clickable text-align-center" routerLink="/contact" i18n>Contact</a> <a class="clickable text-align-center" routerLink="/page/qui-sommes-nous" i18n>Qui sommes-nous ?</a> diff --git a/src/app/form/footer-form/footer-form.component.ts b/src/app/form/footer-form/footer-form.component.ts index e9dbe8ff9..daf0dea0a 100644 --- a/src/app/form/footer-form/footer-form.component.ts +++ b/src/app/form/footer-form/footer-form.component.ts @@ -61,7 +61,7 @@ export class FooterFormComponent { } public goToProfile(): void { - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } /** diff --git a/src/app/form/form-view/form-view-routing.module.ts b/src/app/form/form-view/form-view-routing.module.ts index 73f5ba2d1..73a3a4cde 100644 --- a/src/app/form/form-view/form-view-routing.module.ts +++ b/src/app/form/form-view/form-view-routing.module.ts @@ -15,7 +15,7 @@ import { StructureFormComponent } from './structure-form/structure-form.componen const routes: Routes = [ { - path: 'structure/:id/:step', + path: 'structure/:permalink/:step', component: FormViewComponent, canActivate: [RoleGuard], data: { allowedRoles: [RouteRole.structureAdmin] }, @@ -24,7 +24,7 @@ const routes: Routes = [ }, }, { - path: 'register/:id', + path: 'inscription/:id', component: FormViewComponent, canDeactivate: [DeactivateGuard], resolve: { @@ -42,22 +42,22 @@ const routes: Routes = [ component: StructureFormComponent, }, { - path: 'profile', + path: 'profil', canActivate: [AuthGuard], component: ProfileFormComponent, }, { - path: 'personaloffer', + path: 'offre-personnelle', canActivate: [AuthGuard, PersonalOfferGuard], component: PersonalOfferFormComponent, }, { - path: 'account', + path: 'compte', component: AccountFormComponent, }, { path: '**', - redirectTo: 'account', + redirectTo: 'compte', }, ], }, diff --git a/src/app/form/form-view/form-view.component.html b/src/app/form/form-view/form-view.component.html index a4ee5a09a..052a59bcb 100644 --- a/src/app/form/form-view/form-view.component.html +++ b/src/app/form/form-view/form-view.component.html @@ -18,7 +18,7 @@ /> <div class="page"> <app-account-form - *ngIf="formType[routeParam] === formType.account || formType[this.routeParam] === formType.register" + *ngIf="routeParam === formTypeParam.account || routeParam === formTypeParam.register" [nbSteps]="nbSteps" [accountForm]="accountForm" [currentStep]="currentPage" @@ -27,7 +27,7 @@ (pageValid)="validatePage($event)" /> <app-profile-form - *ngIf="formType[routeParam] === formType.profile" + *ngIf="routeParam === formTypeParam.profile" [nbSteps]="nbSteps" [profileForm]="profileForm" [currentStep]="currentPage" @@ -35,7 +35,7 @@ (pageValid)="validatePage($event)" /> <app-structure-form - *ngIf="formType[routeParam] === formType.structure" + *ngIf="routeParam === formTypeParam.structure" [nbSteps]="nbSteps" [structure]="structure" [structureForm]="structureForm" @@ -48,7 +48,7 @@ (setEditStep)="setCurrentStep($event)" /> <app-personal-offer-form - *ngIf="formType[routeParam] === formType.personaloffer && structure" + *ngIf="routeParam === formTypeParam.personaloffer && structure" [nbSteps]="nbSteps" [personalOfferForm]="personalOfferForm" [currentStep]="currentPage" diff --git a/src/app/form/form-view/form-view.component.ts b/src/app/form/form-view/form-view.component.ts index 7cff6e41f..2db4a1406 100644 --- a/src/app/form/form-view/form-view.component.ts +++ b/src/app/form/form-view/form-view.component.ts @@ -18,7 +18,7 @@ import { FormUtils } from '../../utils/formUtils'; import { Utils } from '../../utils/utils'; import { stepType } from '../step.type'; import { accountFormStep } from './account-form/accountFormStep.enum'; -import { formType } from './formType.enum'; +import { formType, formTypeParam } from './formType.enum'; import { personalOfferFormStep } from './personal-offer-form/personalOfferFormStep.enum'; import { profileFormStep } from './profile-form/profileFormStep.enum'; import { structureFormStep } from './structure-form/structureFormStep.enum'; @@ -31,6 +31,7 @@ import { structureFormStep } from './structure-form/structureFormStep.enum'; export class FormViewComponent implements OnInit, AfterViewInit { public routeParam: string; public formType = formType; + public formTypeParam = formTypeParam; public currentPage: stepType; public currentFormType: formType; public currentForm: UntypedFormGroup; @@ -135,14 +136,14 @@ export class FormViewComponent implements OnInit, AfterViewInit { const structureFormSteps = Object.keys(structureFormStep).length / 2 - 1; const personalOfferFormSteps = Object.keys(personalOfferFormStep).length / 2 - 1; const totalFormSteps = profileFormSteps + structureFormSteps + personalOfferFormSteps; - if (formType[this.routeParam] === formType.account) { + if (this.routeParam === formTypeParam.account) { this.nbSteps = 3; this.currentPage = accountFormStep.accountInfo; this.currentFormType = formType.account; this.createAccountForm(); this.currentForm = this.accountForm; } - if (formType[this.routeParam] === formType.register) { + if (this.routeParam === formTypeParam.register) { this.nbSteps = 3; this.currentPage = accountFormStep.accountInfo; this.currentFormType = formType.account; @@ -155,14 +156,14 @@ export class FormViewComponent implements OnInit, AfterViewInit { } }); } - if (formType[this.routeParam] === formType.profile) { + if (this.routeParam === formTypeParam.profile) { this.nbSteps = totalFormSteps; this.currentPage = profileFormStep.profileBeginningInfo; this.currentFormType = formType.profile; this.createProfileForm(); this.currentForm = this.profileForm; } - if (formType[this.routeParam] === formType.structure) { + if (this.routeParam === formTypeParam.structure) { if (!this.isEditMode) { this.nbSteps = structureFormSteps; this.currentPage = structureFormStep.structureChoice; @@ -178,7 +179,7 @@ export class FormViewComponent implements OnInit, AfterViewInit { } } } - if (formType[this.routeParam] === formType.personaloffer) { + if (this.routeParam === formTypeParam.personaloffer) { this.nbSteps = personalOfferFormSteps; this.currentPage = personalOfferFormStep.personalOfferAccompaniment; this.currentFormType = formType.personaloffer; @@ -299,7 +300,7 @@ export class FormViewComponent implements OnInit, AfterViewInit { const user = await this.profileService.getProfile(); if (user.job?.hasPersonalOffer) { this.previousSteps = 0; - this.router.navigateByUrl('form/personaloffer'); + this.router.navigateByUrl('formulaire/offre-personnelle'); } else { this.router.navigateByUrl('/'); } @@ -317,7 +318,7 @@ export class FormViewComponent implements OnInit, AfterViewInit { this.saveStructureForm(); } if (type.formStep === structureFormStep.noStructure) { - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } break; case formType.personaloffer: @@ -355,13 +356,13 @@ export class FormViewComponent implements OnInit, AfterViewInit { this.structureService.getStructure(this.profile.structuresLink[0]).subscribe((structure) => { this.structure = new Structure(structure); this.previousSteps = 0; - this.router.navigateByUrl('form/personaloffer'); + this.router.navigateByUrl('formulaire/offre-personnelle'); }); } else { - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } } else { - this.router.navigateByUrl('form/structure'); + this.router.navigateByUrl('formulaire/structure'); } }); } @@ -369,7 +370,7 @@ export class FormViewComponent implements OnInit, AfterViewInit { public savePersonalOfferForm(): void { this.personalOfferService.createPersonalOffer(this.structure._id, this.personalOfferForm.value).subscribe(() => { if (this.hasOtherPersonalOffer) { - this.router.navigateByUrl('form/structure'); + this.router.navigateByUrl('formulaire/structure'); } else { this.nextPage(); } @@ -386,9 +387,9 @@ export class FormViewComponent implements OnInit, AfterViewInit { if (user.job?.hasPersonalOffer) { this.structure = struct; this.previousSteps = 0; - this.router.navigateByUrl('form/personaloffer'); + this.router.navigateByUrl('formulaire/offre-personnelle'); } else { - this.router.navigateByUrl(`acteurs?id=${struct._id}`); + this.router.navigateByUrl(`acteurs?structure=${struct.permalink}`); } }); } diff --git a/src/app/form/form-view/formType.enum.ts b/src/app/form/form-view/formType.enum.ts index 41d8aa290..01dee2beb 100644 --- a/src/app/form/form-view/formType.enum.ts +++ b/src/app/form/form-view/formType.enum.ts @@ -6,3 +6,12 @@ export enum formType { register, orientation, } + +export enum formTypeParam { + structure = 'structure', + profile = 'profil', + personaloffer = 'offre-personnelle', + account = 'compte', + register = 'inscription', + orientation = 'orientation', +} diff --git a/src/app/form/form-view/guards/personalOffer.guard.ts b/src/app/form/form-view/guards/personalOffer.guard.ts index 0652dbdcf..239a15de8 100644 --- a/src/app/form/form-view/guards/personalOffer.guard.ts +++ b/src/app/form/form-view/guards/personalOffer.guard.ts @@ -1,5 +1,5 @@ -import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; /** * Guard to assert that we are coming from the structure form. Otherwise redirect to home */ @@ -9,10 +9,10 @@ export class PersonalOfferGuard { canActivate(route: ActivatedRouteSnapshot): UrlTree | boolean { if ( - route.routeConfig.path === 'personaloffer' && - (this.router.routerState.snapshot.url === '/profile' || - this.router.routerState.snapshot.url === '/form/profile' || - this.router.routerState.snapshot.url === '/form/structure' || + route.routeConfig.path === 'offre-personnelle' && + (this.router.routerState.snapshot.url === '/profil' || + this.router.routerState.snapshot.url === '/formulaire/profil' || + this.router.routerState.snapshot.url === '/formulaire/structure' || this.router.routerState.snapshot.url.includes('/join-request/')) ) { return true; diff --git a/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts b/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts index 1db582e46..d1a829e3a 100644 --- a/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts +++ b/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts @@ -77,6 +77,6 @@ export class PersonalOfferFormComponent implements OnChanges, OnInit { } public goToProfile(): void { - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } } diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.ts b/src/app/form/orientation-form-view/orientation-form-view.component.ts index aab181800..991c0b6dc 100644 --- a/src/app/form/orientation-form-view/orientation-form-view.component.ts +++ b/src/app/form/orientation-form-view/orientation-form-view.component.ts @@ -756,6 +756,6 @@ export class OrientationFormViewComponent implements OnInit, AfterContentChecked } } public goLogin(): void { - this.router.navigate(['/login'], { queryParams: { returnUrl: '/orientation' } }); + this.router.navigate(['/connexion'], { queryParams: { returnUrl: '/orientation' } }); } } diff --git a/src/app/guards/auth.guard.ts b/src/app/guards/auth.guard.ts index 59f8b6b48..351fae1e5 100644 --- a/src/app/guards/auth.guard.ts +++ b/src/app/guards/auth.guard.ts @@ -1,5 +1,5 @@ -import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { AuthService } from '../services/auth.service'; /** * Guard to assert that we are logged in. Otherwise redirect to home @@ -15,7 +15,7 @@ export class AuthGuard { if (this.authService.isLoggedIn()) { return true; } - this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); + this.router.navigate(['/connexion'], { queryParams: { returnUrl: state.url } }); return false; } } diff --git a/src/app/guards/resetPasswordToken.guard.ts b/src/app/guards/resetPasswordToken.guard.ts index 77f212b1b..49f20272f 100644 --- a/src/app/guards/resetPasswordToken.guard.ts +++ b/src/app/guards/resetPasswordToken.guard.ts @@ -18,7 +18,7 @@ export class ResetPasswordTokenGuard { if (token) { const validToken = await firstValueFrom(this.authService.checkResetPasswordToken(token)); if (!validToken) { - this.router.navigate(['/login']); + this.router.navigate(['/connexion']); return false; } } diff --git a/src/app/guards/role.guard.ts b/src/app/guards/role.guard.ts index 216256537..36631ab12 100644 --- a/src/app/guards/role.guard.ts +++ b/src/app/guards/role.guard.ts @@ -1,7 +1,9 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router, UrlTree } from '@angular/router'; +import { lastValueFrom } from 'rxjs'; import { ProfileService } from '../profile/services/profile.service'; import { AuthService } from '../services/auth.service'; +import { StructureService } from '../services/structure.service'; import { RouteRole } from '../shared/enum/routeRole.enum'; /** * Guard to assert that a user is authorized to access route. @@ -13,6 +15,7 @@ export class RoleGuard { private router: Router, private profileService: ProfileService, private authService: AuthService, + private structureService: StructureService, ) {} async canActivate(route: ActivatedRouteSnapshot): Promise<UrlTree | boolean> { @@ -21,8 +24,9 @@ export class RoleGuard { if (this.authService.isLoggedIn()) { if (this.profileService.isAdmin()) return true; if (allowedRoles.includes(RouteRole.structureAdmin)) { - const structureId = route.params.id; - if (await this.profileService.isLinkedToStructure(structureId)) { + const structurePermalink = route.params.permalink; + const structure = await lastValueFrom(this.structureService.getStructureByPermalink(structurePermalink)); + if (await this.profileService.isLinkedToStructure(structure._id)) { return true; } } diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index 028020ab1..256280bcc 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -39,12 +39,12 @@ <div class="rightHeader"> <div class="menuItems" role="menu"> <a - routerLink="/news" + routerLink="/actualites" role="menuitem" title="Actualités" [routerLinkActive]="'active'" i18n - [attr.aria-current]="isActive('/news')" + [attr.aria-current]="isActive('/actualites')" > Actualités </a> @@ -124,10 +124,10 @@ </div> <div class="links"> <a - routerLink="/news" + routerLink="/actualites" role="menuitem" [routerLinkActive]="'active'" - [attr.aria-current]="isActive('/news')" + [attr.aria-current]="isActive('/actualites')" (click)="closeMenu()" i18n >Actualités</a @@ -178,11 +178,11 @@ >Administration</a > <a - routerLink="/legal-notice" + routerLink="/mentions-legales" role="menuitem" i18n [routerLinkActive]="'active'" - [attr.aria-current]="isActive('/legal-notice')" + [attr.aria-current]="isActive('/mentions-legales')" (click)="closeMenu()" >Mentions légales</a > diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts index 2c3ae29c3..44e3e333d 100644 --- a/src/app/header/header.component.ts +++ b/src/app/header/header.component.ts @@ -59,7 +59,7 @@ export class HeaderComponent { } public goToProfile(): void { this.showProfileMenu = false; - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } public openMenu(): void { @@ -96,7 +96,7 @@ export class HeaderComponent { return false; } public goToLoginPage(): void { - this.router.navigateByUrl('login'); + this.router.navigateByUrl('connexion'); } public get isAdmin(): boolean { return this.profileService.isAdmin(); diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index dc9450ed9..5f4844aec 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -71,7 +71,7 @@ export class LoginComponent implements OnInit { } public switchToResetPassword(): void { - this.router.navigate(['/reset-password']); + this.router.navigate(['/mot-de-passe-oublie']); } public async onSubmit(): Promise<void> { @@ -88,12 +88,12 @@ export class LoginComponent implements OnInit { await lastValueFrom(this.authService.login(this.f.email.value, this.f.password.value)); if (this.isWelcome) { - this.router.navigateByUrl('form/profile'); + this.router.navigateByUrl('formulaire/profil'); } else { if (this.returnUrl) { this.router.navigateByUrl(this.returnUrl); } else { - this.router.navigateByUrl('news'); + this.router.navigateByUrl('actualites'); } } } catch (e) { @@ -107,7 +107,7 @@ export class LoginComponent implements OnInit { } public goToAccountCreation(): void { - this.router.navigateByUrl('form/account'); + this.router.navigateByUrl('formulaire/compte'); } public getLoginStatusText(): string { diff --git a/src/app/models/owner.model.ts b/src/app/models/owner.model.ts index 89c4226c1..3152b228d 100644 --- a/src/app/models/owner.model.ts +++ b/src/app/models/owner.model.ts @@ -5,6 +5,7 @@ import { PersonalOffer } from './personalOffer.model'; export class Owner { email: string; _id: string; + permalink: string; name: string; surname: string; job?: Job; diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts index bd9df1f41..c25ad38b3 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -57,6 +57,7 @@ export class Structure { public alreadySelected? = false; public hasNoUserDN?: boolean = null; public hasUserWithAppointmentDN?: boolean = null; + public permalink = ''; constructor(obj?: any) { Object.assign(this, obj, { diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts index f8aaddc78..26577e5f6 100644 --- a/src/app/models/user.model.ts +++ b/src/app/models/user.model.ts @@ -6,6 +6,7 @@ import { PersonalOffer } from './personalOffer.model'; export class User { _id: string; id: string; + permalink: string; createdAt: Date; email: string; name: string; @@ -31,6 +32,7 @@ export class User { } export class UserAnnuary { _id: string; + permalink: string; name: string; surname: string; job: Job; diff --git a/src/app/newsletter-subscription/newsletter-subscription.component.html b/src/app/newsletter-subscription/newsletter-subscription.component.html index ca7ff6703..a61319183 100644 --- a/src/app/newsletter-subscription/newsletter-subscription.component.html +++ b/src/app/newsletter-subscription/newsletter-subscription.component.html @@ -28,7 +28,7 @@ <div class="link"> <a *ngIf="!subscriptionMod" routerLink="/newsletter">Inscription</a> - <a *ngIf="subscriptionMod" routerLink="/newsletter-unsubscribe">Désabonnement</a> + <a *ngIf="subscriptionMod" routerLink="/desabonnement-newsletter">Désabonnement</a> </div> </div> </form> diff --git a/src/app/post/components/post-card/post-card.component.ts b/src/app/post/components/post-card/post-card.component.ts index 52cf5b045..1844d30fd 100644 --- a/src/app/post/components/post-card/post-card.component.ts +++ b/src/app/post/components/post-card/post-card.component.ts @@ -15,7 +15,7 @@ export class PostCardComponent { constructor(private router: Router) {} public showDetails(post: Post): void { - this.router.navigateByUrl('news/details/' + post.id, { state: { data: post } }); + this.router.navigateByUrl('actualites/details/' + post.slug, { state: { data: post } }); } public isAppelAProjet(): boolean { diff --git a/src/app/post/components/post-details/post-details.component.ts b/src/app/post/components/post-details/post-details.component.ts index 0131c534f..f429423bc 100644 --- a/src/app/post/components/post-details/post-details.component.ts +++ b/src/app/post/components/post-details/post-details.component.ts @@ -29,8 +29,8 @@ export class PostDetailsComponent implements OnInit { this.post = new Post(history.state.data); this.post.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.post.html); } else { - const postId = this.activatedRoute.snapshot.paramMap.get('id'); - this.postService.getPost(postId).subscribe((post) => { + const postSlug = this.activatedRoute.snapshot.paramMap.get('slug'); + this.postService.getPost(postSlug).subscribe((post) => { this.post = post.posts[0]; this.post.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.post.html); }); diff --git a/src/app/post/components/post-header/post-header.component.ts b/src/app/post/components/post-header/post-header.component.ts index 953fc9aac..fd5c0a482 100644 --- a/src/app/post/components/post-header/post-header.component.ts +++ b/src/app/post/components/post-header/post-header.component.ts @@ -73,7 +73,7 @@ export class PostHeaderComponent implements OnInit { } private setQueryParam(): void { - this.router.navigate(['/news'], { + this.router.navigate(['/actualites'], { relativeTo: this.route, queryParams: { mainTag: this.getMainTag(), diff --git a/src/app/post/models/post.model.ts b/src/app/post/models/post.model.ts index 9ba0fe3e6..00ba5988e 100644 --- a/src/app/post/models/post.model.ts +++ b/src/app/post/models/post.model.ts @@ -14,6 +14,7 @@ export class Post { author: string; tags: Tag[]; safeHtml: SafeHtml; + slug: string; constructor(obj?: any) { Object.assign(this, obj); diff --git a/src/app/post/post-routing.module.ts b/src/app/post/post-routing.module.ts index c95c0ba7c..a0c999376 100644 --- a/src/app/post/post-routing.module.ts +++ b/src/app/post/post-routing.module.ts @@ -1,5 +1,5 @@ import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; import { PostDetailsComponent } from './components/post-details/post-details.component'; import { PostListComponent } from './components/post-list/post-list.component'; import { NewsComponent } from './news.component'; @@ -18,7 +18,7 @@ const routes: Routes = [ component: PostListComponent, }, { - path: 'details/:id', + path: 'details/:slug', component: PostDetailsComponent, }, ], diff --git a/src/app/post/services/post.service.ts b/src/app/post/services/post.service.ts index 3e1d886d8..d35d23885 100644 --- a/src/app/post/services/post.service.ts +++ b/src/app/post/services/post.service.ts @@ -13,8 +13,8 @@ export class PostService { private readonly baseUrl = 'api/posts'; constructor(private http: HttpClient) {} - public getPost(idPost: string): Observable<PostWithMeta> { - return this.http.get<PostWithMeta>(`${this.baseUrl}/` + idPost).pipe( + public getPost(postSlug: string): Observable<PostWithMeta> { + return this.http.get<PostWithMeta>(`${this.baseUrl}/${postSlug}`).pipe( map((item: PostWithMeta) => { item.posts.forEach((post) => this.addAuthorToPost(post)); return new PostWithMeta(item); diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index a41ff417a..0ab8834a2 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -281,7 +281,7 @@ export class EditComponent implements OnInit { localStorage.setItem('user', JSON.stringify(updatedUser)); this.authService.userSubject.next(updatedUser); this.updateInitialProfile(); - this.router.navigate(['/profile']); + this.router.navigate(['/profil']); }); } @@ -299,7 +299,7 @@ export class EditComponent implements OnInit { .updateProfile(this.selectedEmployer.name, this.selectedJob.name, this.selectedRdvChoice) .subscribe({ next: () => { - this.router.navigate(['/profile']); + this.router.navigate(['/profil']); this.notificationService.showSuccess('Vos informations ont bien été enregistrées'); }, error: () => { @@ -316,7 +316,7 @@ export class EditComponent implements OnInit { this.profileService.updateDescription(this.userProfile.description).subscribe(() => { this.notificationService.showSuccess('Vos informations ont bien été enregistrées'); this.updateInitialProfile(); - this.router.navigate(['/profile']); + this.router.navigate(['/profil']); }); } diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts index 99e37853a..28461141e 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts @@ -107,7 +107,7 @@ export class PersonalOfferEditionComponent implements OnInit { this.initialPersonalOffer = this.personalOfferForm.value; this.personalOfferForm.markAsPristine(); }); - this.router.navigateByUrl('/profile'); + this.router.navigateByUrl('/profil'); } } @@ -137,7 +137,7 @@ export class PersonalOfferEditionComponent implements OnInit { this.notificationService.showError(`${err.error.message}`, 'Une erreur est survenue'); }, ); - this.router.navigate(['/profile']); + this.router.navigate(['/profil']); } public goBack(): void { diff --git a/src/app/profile/profile-routing.module.ts b/src/app/profile/profile-routing.module.ts index ecd292897..9f3dbb5ec 100644 --- a/src/app/profile/profile-routing.module.ts +++ b/src/app/profile/profile-routing.module.ts @@ -23,13 +23,13 @@ const footerOutletRoute: Route = { const routes: Routes = [ { - path: 'edit', + path: 'edition', canActivate: [AuthGuard], canDeactivate: [DeactivateGuard], component: EditComponent, }, { - path: 'structures-management', + path: 'gestion-structures', component: StructuresManagementComponent, }, footerOutletRoute, @@ -41,13 +41,13 @@ const routes: Routes = [ component: ProfileComponent, }, { - path: ':id', + path: ':userPermalink', component: ProfileComponent, }, ], }, { - path: 'edit-structure/:id', + path: 'edition-structure/:permalink', component: StructureEditionSummaryComponent, canActivate: [RoleGuard], data: { allowedRoles: [RouteRole.structureAdmin] }, @@ -56,7 +56,7 @@ const routes: Routes = [ }, }, { - path: 'edit-personal-offer/:id', + path: 'edition-offre-personnelle/:id', component: PersonalOfferEditionComponent, canActivate: [IsPersonalOfferOwnerGuard], resolve: { @@ -64,7 +64,7 @@ const routes: Routes = [ }, }, { - path: 'structure-members-management/:id', + path: 'gestion-membres/:permalink', component: StructureMembersManagementComponent, canActivate: [RoleGuard], data: { allowedRoles: [RouteRole.structureAdmin] }, diff --git a/src/app/profile/profile-structure/personal-offer/personal-offer.component.ts b/src/app/profile/profile-structure/personal-offer/personal-offer.component.ts index 526d64fc4..1fde1ca4c 100644 --- a/src/app/profile/profile-structure/personal-offer/personal-offer.component.ts +++ b/src/app/profile/profile-structure/personal-offer/personal-offer.component.ts @@ -15,7 +15,7 @@ export class PersonalOfferComponent { constructor(private router: Router) {} public goToEditPersonalOffer(): void { - this.router.navigateByUrl(`/profile/edit-personal-offer/${this.personalOffer._id}`, { + this.router.navigateByUrl(`/profil/edition-offre-personnelle/${this.personalOffer._id}`, { state: { structureName: this.structureName }, }); } diff --git a/src/app/profile/profile-structure/profile-structure.component.ts b/src/app/profile/profile-structure/profile-structure.component.ts index cf3673974..6648500aa 100644 --- a/src/app/profile/profile-structure/profile-structure.component.ts +++ b/src/app/profile/profile-structure/profile-structure.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { DateTime } from 'luxon'; import { Structure } from '../../models/structure.model'; import { StructureWithOwners } from '../../models/structureWithOwners.model'; @@ -23,7 +23,7 @@ export class ProfileStructureComponent implements OnInit { @Input() public isPublic: boolean; @Input() public isPending = false; @Input() public joinRequestDate: string | null; - @Output() cancelJoin = new EventEmitter<any>(); + @Output() cancelJoin = new EventEmitter<string>(); public membersWithJobWithPO: User[] = []; public structureForm: FormGroup; @@ -33,7 +33,6 @@ export class ProfileStructureComponent implements OnInit { public personalOffer: PersonalOffer; constructor( - private route: ActivatedRoute, private router: Router, private userService: UserService, private searchService: SearchService, @@ -82,16 +81,16 @@ export class ProfileStructureComponent implements OnInit { this.router.navigateByUrl('/home'); } public goToDetail(): void { - this.router.navigate(['/profile'], { queryParams: { id: this.structure._id } }); + this.router.navigate([], { queryParams: { structure: this.structure.permalink } }); } public goToOffer(): void { - this.router.navigate(['/form/personaloffer'], { state: { structure: this.structure } }); + this.router.navigate(['/formulaire/offre-personnelle'], { state: { structure: this.structure } }); } public goToEditStructure(): void { - this.router.navigateByUrl(`/profile/edit-structure/${this.structure._id}`); + this.router.navigateByUrl(`/profil/edition-structure/${this.structure.permalink}`); } public goToStructureMembersManagement(): void { - this.router.navigateByUrl(`/profile/structure-members-management/${this.structure._id}`); + this.router.navigateByUrl(`/profil/gestion-membres/${this.structure.permalink}`); } public isValid(): boolean { return this.structureForm.valid; diff --git a/src/app/profile/profile.component.ts b/src/app/profile/profile.component.ts index 86f1a4969..7e899f0c5 100644 --- a/src/app/profile/profile.component.ts +++ b/src/app/profile/profile.component.ts @@ -35,11 +35,11 @@ export class ProfileComponent implements OnInit { ngOnInit(): void { this.route.params.subscribe((urlParams) => { - const userId = urlParams.id ? urlParams.id : ''; - if (userId) { + const userPermalink = urlParams.userPermalink || ''; + if (userPermalink) { this.isPublic = true; this.userService - .getUser(userId) + .getUserByPermalink(userPermalink) .pipe( map((res) => res), catchError(() => { @@ -106,20 +106,16 @@ export class ProfileComponent implements OnInit { } public goToProfileEdit(tabToSelect?: string): void { if (tabToSelect) { - this.router.navigateByUrl('/profile/edit', { state: { data: tabToSelect } }); + this.router.navigateByUrl('/profil/edition', { state: { data: tabToSelect } }); } else { - this.router.navigateByUrl('/profile/edit'); + this.router.navigateByUrl('/profil/edition'); } } public goToStructuresManagement(): void { - this.router.navigateByUrl('/profile/structures-management'); + this.router.navigateByUrl('/profil/gestion-structures'); } public goToFormStructure(): void { - this.router.navigateByUrl('/form/structure'); - } - - public addStructure(): void { - this.router.navigateByUrl('/form/structure'); + this.router.navigateByUrl('/formulaire/structure'); } public cancelJoin(idStructure: string): void { this.userService.cancelJoin(idStructure, this.userProfile._id).subscribe({ diff --git a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts index 9a9b89aaf..c775ab218 100644 --- a/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts +++ b/src/app/profile/structure-edition-summary/structure-edition-summary.component.ts @@ -94,7 +94,7 @@ export class StructureEditionSummaryComponent implements OnInit { } public goToEdit(step: structureFormStep): void { - this.router.navigate(['/form/structure', this.structure._id, structureFormStep[step]]); + this.router.navigate(['/formulaire/structure', this.structure.permalink, structureFormStep[step]]); } public isFormValid(): boolean { @@ -181,6 +181,6 @@ export class StructureEditionSummaryComponent implements OnInit { } public goToManageMembers(): void { - this.router.navigate([`/profile/structure-members-management/${this.structure._id}`]); + this.router.navigate([`/profil/gestion-membres/${this.structure.permalink}`]); } } diff --git a/src/app/profile/structures-management/structures-management.component.ts b/src/app/profile/structures-management/structures-management.component.ts index 193e936fa..7be96b72b 100644 --- a/src/app/profile/structures-management/structures-management.component.ts +++ b/src/app/profile/structures-management/structures-management.component.ts @@ -38,12 +38,12 @@ export class StructuresManagementComponent implements OnInit { history.back(); } public goToFormStructure(): void { - this.router.navigateByUrl('/form/structure'); + this.router.navigateByUrl('/formulaire/structure'); } private shouldRedirect(structures: StructureWithOwners[] | Observable<any>[]): void { if (!structures.length) { - this.router.navigate(['/profile']); + this.router.navigate(['/profil']); } } diff --git a/src/app/reset-password/forgot-password.component.ts b/src/app/reset-password/forgot-password.component.ts index 81fd6e5d9..8f3e89dc9 100644 --- a/src/app/reset-password/forgot-password.component.ts +++ b/src/app/reset-password/forgot-password.component.ts @@ -54,6 +54,6 @@ export class ForgotPasswordComponent implements OnInit { } public goLogin(): void { - this.router.navigateByUrl('/login'); + this.router.navigateByUrl('/connexion'); } } diff --git a/src/app/resolvers/structure.resolver.ts b/src/app/resolvers/structure.resolver.ts index 14fdc214f..fab997a45 100644 --- a/src/app/resolvers/structure.resolver.ts +++ b/src/app/resolvers/structure.resolver.ts @@ -20,11 +20,11 @@ export class StructureResolver { ) {} resolve(route: ActivatedRouteSnapshot): Observable<Structure> { - const structureId = route.params.id; + const structurePermalink = route.params.permalink || route.queryParams.structure; - if (structureId) { + if (structurePermalink) { forkJoin({ - structure: this.structureService.getStructure(structureId).pipe( + structure: this.structureService.getStructureByPermalink(structurePermalink).pipe( map((res) => res), catchError(() => { this.router.navigate(['/home']); diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index d303885a1..6e4382da4 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -36,7 +36,7 @@ export class AuthService { public logout(): void { localStorage.removeItem('user'); this.userSubject.next(null); - window.location.replace('/home'); + window.location.replace('/actualites'); } public isLoggedIn(): boolean { diff --git a/src/app/services/structure.service.ts b/src/app/services/structure.service.ts index 8671c4251..848b1e654 100644 --- a/src/app/services/structure.service.ts +++ b/src/app/services/structure.service.ts @@ -40,6 +40,10 @@ export class StructureService { return this.http.get<Structure>(`${this.baseUrl}/${id}`); } + public getStructureByPermalink(permalink: string): Observable<Structure> { + return this.http.get<Structure>(`${this.baseUrl}/permalink/${permalink}`); + } + public delete(id: string): Observable<Structure> { return this.http.delete<Structure>(`${this.baseUrl}/${id}`); } diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts index 1bcb892b6..795bd3d31 100644 --- a/src/app/services/user.service.ts +++ b/src/app/services/user.service.ts @@ -14,12 +14,15 @@ export class UserService { public getUser(userId: string): Observable<User> { return this.http.get<User>(`${this.baseUrl}/${userId}`); } + public getUserByPermalink(permalink: string): Observable<User> { + return this.http.get<User>(`${this.baseUrl}/permalink/${permalink}`); + } public joinStructure(id: string, email: string): Observable<Structure> { return this.http.post<any>(`${this.baseUrl}/join-request/${id}`, { email }); } public validateJoinStructure(token: string, status: string): Observable<any> { - return this.http.get<any>(`${this.baseUrl}/join-validate/${token}/${status}`); + return this.http.get<Structure>(`${this.baseUrl}/join-validate/${token}/${status}`); } public cancelJoin(idStructure: string, idUser: string): Observable<any> { return this.http.get<any>(`${this.baseUrl}/join-cancel/${idStructure}/${idUser} diff --git a/src/app/shared/components/member-card/member-card.component.ts b/src/app/shared/components/member-card/member-card.component.ts index 07a0849ab..bbc3c7c02 100644 --- a/src/app/shared/components/member-card/member-card.component.ts +++ b/src/app/shared/components/member-card/member-card.component.ts @@ -67,7 +67,7 @@ export class MemberCardComponent implements OnInit { cardClicked(): void { if (this.redirectToProfile) { this.windowScrollService.scrollYToPreserve.next(this.windowScrollService.scrollY.value); - this.router.navigateByUrl(`/profile/${this.member._id}`); + this.router.navigateByUrl(`/profil/${this.member.permalink}`); } else if (this.showRadioButton) { this.selectedCard.emit(this.member._id); } diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts index c1571a72d..22d42859b 100644 --- a/src/app/structure-list/components/card/card.component.ts +++ b/src/app/structure-list/components/card/card.component.ts @@ -65,13 +65,12 @@ export class CardComponent implements OnInit { public cardClicked(): void { if (this.redirectToStructure) { this.showDetails.emit(this.structure); - const queryString = this.route.snapshot.queryParamMap.get('search'); this.router.navigate([], { relativeTo: this.route, queryParams: { - id: this.structure._id, - ...(queryString && { search: queryString }), + structure: this.structure.permalink, }, + queryParamsHandling: 'merge', state: { isOrientation: this.isOrientation }, }); } else { diff --git a/src/app/structure-list/components/structure-details/structure-details.component.ts b/src/app/structure-list/components/structure-details/structure-details.component.ts index d28eabfb8..c42966542 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.ts +++ b/src/app/structure-list/components/structure-details/structure-details.component.ts @@ -73,23 +73,19 @@ export class StructureDetailsComponent implements OnInit { ) {} async ngOnInit(): Promise<void> { - this.route.queryParams.subscribe((queryParams) => { - if (queryParams.id) { - this.structureService.getStructure(queryParams.id).subscribe((structure) => { - this.structure = new Structure(structure); - this.profileIsLinkedToStructure(this.structure._id); - this.isLoading = true; - this.initForm(); - }); + this.route.data.subscribe((data) => { + if (data.structure) { + this.structure = new Structure(data.structure); + this.profileIsLinkedToStructure(this.structure._id); + this.isLoading = true; + this.initForm(); } else { this.structure = null; } - this.showButtons = !history.state.isOrientation; - }); - this.route.data.subscribe((data) => { if (data.fullScreen) { this.fullScreen = true; } + this.showButtons = !history.state.isOrientation; }); } @@ -138,7 +134,12 @@ export class StructureDetailsComponent implements OnInit { } public close(): void { - this.router.navigate([]); + this.router.navigate([], { + queryParams: { + structure: null, + }, + queryParamsHandling: 'merge', + }); } public print(): void { @@ -165,7 +166,9 @@ export class StructureDetailsComponent implements OnInit { public handleJoin(): void { if (!this.userIsLoggedIn()) { - this.router.navigate(['login'], { queryParams: { returnUrl: `acteurs?id=${this.structure._id}` } }); + this.router.navigate(['connexion'], { + queryParams: { returnUrl: `acteurs?structure=${this.structure.permalink}` }, + }); return; } @@ -179,7 +182,7 @@ export class StructureDetailsComponent implements OnInit { } public handleModify(): void { - this.router.navigate(['profile', 'edit-structure', this.structure._id]); + this.router.navigate(['profil', 'edition-structure', this.structure.permalink]); } public deleteStructure(shouldDelete: boolean): void { @@ -202,7 +205,9 @@ export class StructureDetailsComponent implements OnInit { this.structureService .claimStructureWithAccount(this.structure._id, this.authService.userValue.username) .subscribe(); - this.router.navigate(['join-request', this.structure._id], { state: { isClaimed: !this.structure.hasNoUserDN } }); + this.router.navigate(['join-request', this.structure.permalink], { + state: { isClaimed: !this.structure.hasNoUserDN }, + }); } } @@ -210,7 +215,9 @@ export class StructureDetailsComponent implements OnInit { this.toggleJoinModal(); if (shouldJoin) { this.usersService.joinStructure(this.structure._id, this.authService.userValue.username).subscribe(); - this.router.navigate(['join-request', this.structure._id], { state: { isClaimed: !this.structure.hasNoUserDN } }); + this.router.navigate(['join-request', this.structure.permalink], { + state: { isClaimed: !this.structure.hasNoUserDN }, + }); } } diff --git a/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts b/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts index de56f479e..0f136ba8e 100644 --- a/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts +++ b/src/app/structure-list/components/structure-list-search/structure-list-search.component.ts @@ -44,7 +44,6 @@ export class StructureListSearchComponent implements OnInit { constructor( public searchService: SearchService, private activatedRoute: ActivatedRoute, - private route: ActivatedRoute, private router: Router, private elementRef: ElementRef, ) {} @@ -98,7 +97,7 @@ export class StructureListSearchComponent implements OnInit { public updateUrlParams(filters: Filter[]): void { // No url update if the page is displaying structure details, because it must keep the url with the structure id, neither for orientation if ( - (this.activatedRoute.snapshot.queryParams.id && filters.length === 0) || + (this.activatedRoute.snapshot.queryParams.structure && filters.length === 0) || this.router.url.startsWith('/orientation') ) { return; @@ -116,7 +115,7 @@ export class StructureListSearchComponent implements OnInit { this.checkedModulesFilter = this.utils.convertFiltersToModule(filters); this.router.navigate(['./'], { - relativeTo: this.route, + relativeTo: this.activatedRoute, queryParams: queryString, }); } diff --git a/src/app/structure-list/services/search.service.ts b/src/app/structure-list/services/search.service.ts index f8e23213c..c0a3fd494 100644 --- a/src/app/structure-list/services/search.service.ts +++ b/src/app/structure-list/services/search.service.ts @@ -34,13 +34,14 @@ export class SearchService { jobsGroup?: string[], employers?: string[], ): Promise<SearchResults> { - return lastValueFrom( + const users = await lastValueFrom( this.http.post<SearchResults>(`/api/userRegistry/?search=${searchTerm}`, { jobsGroup, employer: employers, page, }), ); + return users; } public getUserRegistryCount(): Observable<number> { return this.http.get<any>(`/api/userRegistry/count`).pipe(); diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts index 50f12a4aa..19745a4f3 100644 --- a/src/app/structure-list/structure-list.component.ts +++ b/src/app/structure-list/structure-list.component.ts @@ -3,7 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { GeoJson } from '../map/models/geojson.model'; import { Structure } from '../models/structure.model'; import { AuthService } from '../services/auth.service'; -import { StructureService } from '../services/structure.service'; import { PrintService } from '../shared/service/print.service'; @Component({ @@ -30,17 +29,12 @@ export class StructureListComponent implements OnChanges, OnInit { constructor( private route: ActivatedRoute, private router: Router, - private structureService: StructureService, private authService: AuthService, private printService: PrintService, ) { - this.route.queryParams.subscribe((queryParams) => { - if (queryParams.id) { - if (!this.structure) { - this.structureService.getStructure(queryParams.id).subscribe((s) => { - this.showDetails(new Structure(s)); - }); - } + this.route.data.subscribe((data) => { + if (data.structure) { + this.showDetails(new Structure(data.structure)); } else { this.closeDetails(); } @@ -59,8 +53,9 @@ export class StructureListComponent implements OnChanges, OnInit { this.router.navigate([], { relativeTo: this.route, queryParams: { - id: this.selectedStructure._id, + structure: this.selectedStructure.permalink, }, + queryParamsHandling: 'merge', }); } if (changes.structureList) { @@ -91,9 +86,9 @@ export class StructureListComponent implements OnChanges, OnInit { public addStructure(): void { if (!this.authService.isLoggedIn()) { - this.router.navigateByUrl('/login'); + this.router.navigateByUrl('/connexion'); } else { - this.router.navigateByUrl('/form/structure'); + this.router.navigateByUrl('/formulaire/structure'); } } diff --git a/src/app/structure/structure-join/structure-join.component.html b/src/app/structure/structure-join/structure-join.component.html index 825848740..67f2d7894 100644 --- a/src/app/structure/structure-join/structure-join.component.html +++ b/src/app/structure/structure-join/structure-join.component.html @@ -20,35 +20,35 @@ <ng-container *ngIf="!structureName && !isLoading && validationToken"> <div class="container"> <div class="page"> - <img *ngIf="error" src="../../../assets/form/structureNeutral.svg" alt="join error" /> + <img *ngIf="errorStatus" src="../../../assets/form/structureNeutral.svg" alt="join error" /> <img - *ngIf="!error && isStructureJoinValidated === 'true'" + *ngIf="!errorStatus && isStructureJoinValidated === 'true'" src="../../../assets/form/structureCreated.svg" alt="join accepted" /> <img - *ngIf="!error && isStructureJoinValidated === 'false'" + *ngIf="!errorStatus && isStructureJoinValidated === 'false'" src="../../../assets/form/structureNegatif.svg" alt="join refused" /> - <h2 *ngIf="error && error === 404"> + <h2 *ngIf="errorStatus && errorStatus === 404"> {{ errorEnum.Other }} </h2> - <h2 *ngIf="error && error === 403"> + <h2 *ngIf="errorStatus && errorStatus === 403"> {{ errorEnum.Expired }} </h2> - <h2 *ngIf="error && error === 422"> + <h2 *ngIf="errorStatus && errorStatus === 422"> {{ errorEnum.AlreadyLinked }} </h2> - <h2 *ngIf="this.structureJoinedId && !error"> + <h2 *ngIf="this.structureJoined && !errorStatus"> L'utilisateur a été {{ isStructureJoinValidated === 'true' ? 'accepté' : 'refusé' }} dans la structure. </h2> - <div *ngIf="this.structureJoinedId && !error" class="subtitle"> + <div *ngIf="this.structureJoined && !errorStatus" class="subtitle"> Vous avez {{ isStructureJoinValidated === 'true' ? 'accepté' : 'refusé' }} la demande d'ajout dans la structure - {{ structureJoinedName }} + {{ structureJoined.structureName }} </div> - <div *ngIf="error && (error === 403 || error === 422)" class="subtitle"> + <div *ngIf="errorStatus && (errorStatus === 403 || errorStatus === 422)" class="subtitle"> Il semblerait que la demande d’adhésion ait déjà été traitée ou que le mail soit expiré. </div> </div> diff --git a/src/app/structure/structure-join/structure-join.component.ts b/src/app/structure/structure-join/structure-join.component.ts index d441729c3..5180bf1c8 100644 --- a/src/app/structure/structure-join/structure-join.component.ts +++ b/src/app/structure/structure-join/structure-join.component.ts @@ -20,9 +20,8 @@ export class StructureJoinComponent implements OnInit { public isStructureJoinValidated = null; public validationToken = null; public isLoading: boolean; - public structureJoinedId: string; - public structureJoinedName: string; - public error: any; + public structureJoined: Structure; + public errorStatus: number; public errorEnum = JoinErrors; constructor( @@ -52,11 +51,10 @@ export class StructureJoinComponent implements OnInit { if (this.isStructureJoinValidated !== null && this.validationToken) { this.usersService.validateJoinStructure(this.validationToken, this.isStructureJoinValidated).subscribe({ next: (res) => { - this.structureJoinedId = res.id; - this.structureJoinedName = res.name; + this.structureJoined = res; }, error: (err) => { - this.error = err.status; + this.errorStatus = err.status; console.error(err); this.isLoading = false; }, @@ -68,10 +66,10 @@ export class StructureJoinComponent implements OnInit { public handleFinish(): void { this.routerListener.goToPreviousUrl(); } - public handleCallback(): any { - if (this.structureJoinedId) { - return this.router.navigateByUrl(`/acteurs?id=${this.structureJoinedId}`); + public handleCallback(): void { + if (this.structureJoined) { + this.router.navigateByUrl(`/acteurs?structure=${this.structureJoined.permalink}`); } - return this.router.navigateByUrl(`/acteurs`); + this.router.navigateByUrl(`/acteurs`); } } diff --git a/src/sitemap.xml b/src/sitemap.xml index 2b2ff2cc9..42905c49d 100644 --- a/src/sitemap.xml +++ b/src/sitemap.xml @@ -1,34 +1,45 @@ <?xml version="1.0" encoding="UTF-8"?> -<urlset - xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 - http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> -<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com --> +<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> + <url> + <loc>https://resin.grandlyon.com/</loc> + <priority>1.00</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> + <url> + <loc>https://resin.grandlyon.com/actualites</loc> + <priority>0.80</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> -<url> - <loc>https://resin.grandlyon.com/</loc> - <priority>1.00</priority> - <lastmod>2021-05-04T13:28:32+00:00</lastmod> -</url> + <url> + <loc>https://resin.grandlyon.com/acteurs</loc> + <priority>0.80</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> -<url> - <loc>https://resin.grandlyon.com/news</loc> - <priority>0.80</priority> - <lastmod>2021-05-04T13:28:32+00:00</lastmod> -</url> + <url> + <loc>https://resin.grandlyon.com/orientation</loc> + <priority>0.80</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> -<url> - <loc>https://resin.grandlyon.com/acteurs</loc> - <priority>0.80</priority> - <lastmod>2021-05-04T13:28:32+00:00</lastmod> -</url> + <url> + <loc>https://resin.grandlyon.com/newsletter</loc> + <priority>0.64</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> -<url> - <loc>https://resin.grandlyon.com/page/qui-sommes-nous</loc> - <priority>0.64</priority> - <lastmod>2022-01-04T15:28:32+00:00</lastmod> -</url> + <url> + <loc>https://resin.grandlyon.com/mentions-legales</loc> + <priority>0.64</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> -</urlset> + <url> + <loc>https://resin.grandlyon.com/page/qui-sommes-nous</loc> + <priority>0.64</priority> + <lastmod>2024-05-28T15:47:00+00:00</lastmod> + </url> + +</urlset> \ No newline at end of file -- GitLab