diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9f1d05bcf580f886740b32f9d9557680a5662c8e..993557771faefa1b05cc206b356954637ed0047f 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { PanelComponent } from './admin/components/panel/panel.component'; import { FormComponent } from './form/form.component'; import { AdminGuard } from './guards/admin.guard'; import { AuthGuard } from './guards/auth.guard'; +import { DeactivateGuard } from './guards/deactivate.guard'; import { HomeComponent } from './home/home.component'; import { LegalNoticeComponent } from './legal-notice/legal-notice.component'; import { ProfileComponent } from './profile/profile.component'; @@ -69,6 +70,7 @@ const routes: Routes = [ { path: 'create-structure', component: FormComponent, + canDeactivate: [DeactivateGuard], }, { path: '**', diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 89ece5601bdafe96a93b52dfe8fcf06770268dcc..7ca9f3b7903260c2bf15c9d54c1f9cc2902f5a41 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -29,6 +29,7 @@ import { ResetEmailComponent } from './reset-email/reset-email.component'; import { ResetPasswordComponent } from './reset-password/reset-password.component'; import { AdminModule } from './admin/admin.module'; import { AdminGuard } from './guards/admin.guard'; +import { DeactivateGuard } from './guards/deactivate.guard'; @NgModule({ declarations: [ @@ -57,6 +58,7 @@ import { AdminGuard } from './guards/admin.guard'; CustomBreakPointsProvider, AuthGuard, AdminGuard, + DeactivateGuard, ], bootstrap: [AppComponent], }) diff --git a/src/app/form/form.component.html b/src/app/form/form.component.html index 1da0881fb961dd886b17274aa5e6e38a075b99b7..4b95ee2d414f79f6ed7fe267638b4e28e1438839 100644 --- a/src/app/form/form.component.html +++ b/src/app/form/form.component.html @@ -1,15 +1,6 @@ <div class="form" fxLayout="column"> - <div *ngIf="showModalExit" class="modalExitContainer"> - <div class="modal"> - <div class="contentModal" fxLayout="column" fxLayoutAlign="space-around center"> - <h3>ATTENTION</h3> - <p>Il vous faudra de nouveau remplir le formulaire si vous quittez</p> - <div class="footerModal" fxLayout="row" fxLayoutAlign="space-around center"> - <button class="btn leave" (click)="leaveForm(showModalExit)">Quitter</button> - <button class="btn" (click)="leaveForm(null)">Annuler</button> - </div> - </div> - </div> + <div *ngIf="showConfirmationModal"> + <app-modal-confirmation (closeModalEvent)="hasRedirectionAccepted($event)"></app-modal-confirmation> </div> <app-menu-phone *ngIf="showMenu" (closeEvent)="closeMenu($event)"></app-menu-phone> <div class="header"> @@ -1006,7 +997,7 @@ *ngIf="currentPage == nbPagesForm && profile" class="btn unique" routerLink="/home" - [routerLinkActive]="'active'" + [state]="{ data: createdStructure }" > Voir ma structure </button> diff --git a/src/app/form/form.component.scss b/src/app/form/form.component.scss index 1d97f1229743d01efc988b796e694bb7ed84621d..09f51ccb285671c34d3f7c792b791934c0d680c8 100644 --- a/src/app/form/form.component.scss +++ b/src/app/form/form.component.scss @@ -461,51 +461,6 @@ img { margin-right: 12px; } -.modalExitContainer { - width: 100%; - height: 100%; - z-index: $modal-confirmation-z-index; - position: absolute; - content: ''; - top: 0; - background: rgba(0, 0, 0, 0.65); - .modal { - .contentModal { - width: 100%; - background: rgba(255, 255, 255, 1); - padding: 35px 20px 18px 20px; - h3 { - @include cn-bold-18; - color: $orange-warning; - } - p { - @include cn-bold-16; - color: $grey-1; - text-align: center; - } - .footerModal { - width: 100%; - margin-top: 14px; - @include cn-bold-16; - .btn { - width: 149px; - &.leave { - background: none; - color: $grey-1; - text-decoration: underline; - } - } - } - } - width: 350px; - margin: auto; - border-radius: 6px; - @include background-hash; - border: 1px solid $grey-4; - margin-top: 50vh; - transform: translateY(-50%); - } -} .asterisk { color: $secondary-color; } diff --git a/src/app/form/form.component.ts b/src/app/form/form.component.ts index 61c2ac54c2e497349ad82c3e39a43eb948a199a9..e2a9974e832705936a2c0057a4f954b733a43ec3 100644 --- a/src/app/form/form.component.ts +++ b/src/app/form/form.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; import { Structure } from '../models/structure.model'; import { Time } from '../models/time.model'; @@ -27,6 +27,8 @@ export class FormComponent implements OnInit { public profile: User; public structureForm: FormGroup; + public createdStructure: Structure; + public labelsQualifications: Category; public publics: Category; public accessModality: Category; @@ -50,7 +52,6 @@ export class FormComponent implements OnInit { public userAcceptSavedDate = false; public showMenu = false; - public showModalExit: string = null; //collapse var public showWebsite: boolean; public showSocialNetwork: boolean; @@ -534,27 +535,31 @@ export class FormComponent implements OnInit { } private createStructure(structure: Structure, user: User): void { - this.structureService.createStructure(structure, user).subscribe(() => { + this.structureService.createStructure(structure, user).subscribe((structure) => { this.currentPage++; + this.createdStructure = structure; }); } public toggleMenu(): void { this.showMenu = !this.showMenu; } - public leaveForm(route: string): void { - if (route) { - this.router.navigateByUrl(route); - } else { - this.showModalExit = null; - } + public closeMenu(): void { + this.showMenu = false; } - public closeMenu(route: string): void { - if (route) { - this.showModalExit = route; - } else { - this.showMenu = false; - } + public canExit(): Promise<boolean> { + return new Promise((resolve) => this.showModal(resolve)); + } + public showConfirmationModal = false; + private resolve: Function; + + private showModal(resolve: Function): void { + this.showConfirmationModal = true; + this.resolve = resolve; + } + public hasRedirectionAccepted(hasAccept: boolean): void { + this.resolve(hasAccept); + this.showConfirmationModal = false; } } diff --git a/src/app/guards/deactivate.guard.ts b/src/app/guards/deactivate.guard.ts new file mode 100644 index 0000000000000000000000000000000000000000..d8a74fa6cdb88ff54075743c9f14e7ec20c10561 --- /dev/null +++ b/src/app/guards/deactivate.guard.ts @@ -0,0 +1,27 @@ +import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { Observable, Subject } from 'rxjs'; + +export interface IDeactivateComponent { + canExit: () => Observable<boolean> | Promise<boolean> | boolean; +} + +/** + * Guard to confirm we are leaving. Otherwise stay at current route. + */ +@Injectable() +export class DeactivateGuard implements CanDeactivate<Object> { + component: Object; + route: ActivatedRouteSnapshot; + + constructor() {} + + canDeactivate( + component: IDeactivateComponent, + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot, + nextState: RouterStateSnapshot + ): Observable<boolean> | Promise<boolean> | boolean { + return component.canExit(); + } +} diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index 8581d388aeb33a43de6254d8564cd9ad3bfcfc6c..b2b2b512f33028994f6cfa6253219565fb643ab2 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -7,6 +7,7 @@ import { StructureService } from '../services/structure.service'; import { Filter } from '../structure-list/models/filter.model'; import { GeoJson } from '../map/models/geojson.model'; import { GeojsonService } from '../services/geojson.service'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-home', @@ -32,6 +33,9 @@ export class HomeComponent implements OnInit { } else { this.getStructures(null); } + if (history.state.data) { + this.currentStructure = new Structure(history.state.data); + } } public getStructures(filters: Filter[]): void { diff --git a/src/app/menu-phone/menu-phone.component.html b/src/app/menu-phone/menu-phone.component.html index 72aaf670c796de64c07280f6d32e8d772b115de1..8604d72d6e478f76027bb45245d586d18a3e1f5d 100644 --- a/src/app/menu-phone/menu-phone.component.html +++ b/src/app/menu-phone/menu-phone.component.html @@ -1,16 +1,16 @@ <div class="containerMenu" fxLayout="row"> - <div class="outside" (click)="closeMenu(null)"></div> + <div class="outside" (click)="closeMenu()"></div> <div class="contentMenu" fxLayout="column" fxLayoutAlign="space-between"> <div> <div class="titleFilter" fxLayout="row" fxLayoutAlign="space-between"> <span>Menu</span> - <div (click)="closeMenu(null)" class="ico-close-details"></div> + <div (click)="closeMenu()" class="ico-close-details"></div> </div> <div fxLayout="column" class="right-header" fxLayoutGap="3vw"> - <a (click)="closeMenu('home')" i18n>Les acteurs</a> + <a routerLink="/home" [routerLinkActive]="'active'" i18n>Les acteurs</a> <!-- <a routerLink="/resources" [routerLinkActive]="'active'" i18n>Ressources</a> <a routerLink="/projects" [routerLinkActive]="'active'" i18n>Projets</a> --> - <a (click)="closeMenu('about')" i18n>Qui sommes-nous ?</a> + <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <a *ngIf="isAdmin" routerLink="/admin" [routerLinkActive]="'active'">Administration</a> <!--<a routerLink="/login" [routerLinkActive]="'active'" i18n><span class="clickable ico-mglass purple"></span></a> diff --git a/src/app/menu-phone/menu-phone.component.ts b/src/app/menu-phone/menu-phone.component.ts index ecb50fa07fb3c472376e0370f4ce3aab193fa57f..75e6e902f20806ee516fd239d2a77e704f0cb9ee 100644 --- a/src/app/menu-phone/menu-phone.component.ts +++ b/src/app/menu-phone/menu-phone.component.ts @@ -10,11 +10,11 @@ import { AuthService } from '../services/auth.service'; export class MenuPhoneComponent implements OnInit { constructor(private authService: AuthService, private profileService: ProfileService) {} - @Output() closeEvent = new EventEmitter<string>(); + @Output() closeEvent = new EventEmitter<any>(); ngOnInit(): void {} - closeMenu(route: string): void { - this.closeEvent.emit(route); + closeMenu(): void { + this.closeEvent.emit(); } public get isLoggedIn(): boolean { diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 48ae27f2c929968f34ed88191d57960dbe9cd288..a196203fda3801b7d685b23b35d24e1a6869d95f 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -15,8 +15,7 @@ export class ProfileService { constructor(private http: HttpClient, private authService: AuthService) {} public async getProfile(): Promise<User> { - // Get profil by API only on first time - if (this.authService.isLoggedIn()) { + if (this.authService.isLoggedIn() && !this.currentProfile) { const profile = await this.http.get<User>(`${this.baseUrl}/profile`).toPromise(); this.currentProfile = profile; } diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts index 84fa9b04d543d2f6e79f6546d2cd65baa92164f1..7020169f324ce7a52bc93d9418826d73b5f7b270 100644 --- a/src/app/shared/components/index.ts +++ b/src/app/shared/components/index.ts @@ -12,6 +12,7 @@ import { CheckboxFormComponent } from './checkbox-form/checkbox-form.component'; import { HourPickerComponent } from './hour-picker/hour-picker.component'; import { CopyPasteComponent } from './hour-picker/copy-paste/copy-paste.component'; import { RadioFormComponent } from './radio-form/radio-form.component'; +import { ModalConfirmationComponent } from './modal-confirmation/modal-confirmation.component'; // tslint:disable-next-line: max-line-length export { @@ -29,6 +30,7 @@ export { HourPickerComponent, CopyPasteComponent, RadioFormComponent, + ModalConfirmationComponent, }; // tslint:disable-next-line:variable-name @@ -47,4 +49,5 @@ export const SharedComponents = [ HourPickerComponent, CopyPasteComponent, RadioFormComponent, + ModalConfirmationComponent, ]; diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.html b/src/app/shared/components/modal-confirmation/modal-confirmation.component.html new file mode 100644 index 0000000000000000000000000000000000000000..524906f25c9984a951cf102246b1dcf169df090a --- /dev/null +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.html @@ -0,0 +1,12 @@ +<div class="modalExitContainer"> + <div class="modal"> + <div class="contentModal" fxLayout="column" fxLayoutAlign="space-around center"> + <h3>ATTENTION</h3> + <p>Il vous faudra de nouveau remplir le formulaire si vous quittez</p> + <div class="footerModal" fxLayout="row" fxLayoutAlign="space-around center"> + <button class="btn leave" (click)="onConfirm()">Quitter</button> + <button class="btn" (click)="onDismiss()">Annuler</button> + </div> + </div> + </div> +</div> diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss b/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e089d14a6d88d37f0fc1d5aef6f6ef4f3b8afbb1 --- /dev/null +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss @@ -0,0 +1,58 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/shapes'; +@import '../../../../assets/scss/z-index'; + +.modalExitContainer { + width: 100%; + height: 100%; + z-index: $modal-confirmation-z-index; + position: absolute; + content: ''; + top: 0; + background: rgba(0, 0, 0, 0.65); + .modal { + .contentModal { + width: 100%; + background: rgba(255, 255, 255, 1); + padding: 35px 20px 18px 20px; + h3 { + @include cn-bold-18; + color: $orange-warning; + } + p { + @include cn-bold-16; + color: $grey-1; + text-align: center; + } + .footerModal { + width: 100%; + margin-top: 14px; + @include cn-bold-16; + .btn { + background: $secondary-color; + border-radius: 4px; + outline: none; + cursor: pointer; + border: 0; + color: $white; + height: 40px; + @include btn-bold; + width: 149px; + &.leave { + background: none; + color: $grey-1; + text-decoration: underline; + } + } + } + } + width: 350px; + margin: auto; + border-radius: 6px; + @include background-hash; + border: 1px solid $grey-4; + margin-top: 50vh; + transform: translateY(-50%); + } +} diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.spec.ts b/src/app/shared/components/modal-confirmation/modal-confirmation.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c52bf4395fc25ac143d0fdb649d06dbb461ae40 --- /dev/null +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ModalConfirmationComponent } from './modal-confirmation.component'; + +describe('ModalConfirmationComponent', () => { + let component: ModalConfirmationComponent; + let fixture: ComponentFixture<ModalConfirmationComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ModalConfirmationComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ModalConfirmationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts b/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba9b5dba2dac701e496758b7f302d76afae37dd5 --- /dev/null +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.ts @@ -0,0 +1,22 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { Subject } from 'rxjs'; + +@Component({ + selector: 'app-modal-confirmation', + templateUrl: './modal-confirmation.component.html', + styleUrls: ['./modal-confirmation.component.scss'], +}) +export class ModalConfirmationComponent implements OnInit { + constructor() {} + + @Output() closeModalEvent = new EventEmitter<boolean>(); + ngOnInit(): void {} + + onDismiss() { + this.closeModalEvent.emit(false); + } + + onConfirm() { + this.closeModalEvent.emit(true); + } +} diff --git a/src/app/user-verification/user-verification.component.html b/src/app/user-verification/user-verification.component.html index 1175295c10768842af062064721fc372f84abd57..aa9e1b2538ab361515b54ef492a6352906704cb9 100644 --- a/src/app/user-verification/user-verification.component.html +++ b/src/app/user-verification/user-verification.component.html @@ -20,7 +20,7 @@ </div> </div> <div class="btnSection"> - <button class="btn" routerLink="/home" [routerLinkActive]="'active'">Voir ma structure</button> + <button class="btn" routerLink="/home" [state]="{ data: structure }">Voir ma structure</button> </div> </div> <p *ngIf="verificationIssue">