From 553c303b93ed8bb7019eef8cf7b66fbebcb2e3dd Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Tue, 26 Jan 2021 15:24:11 +0100 Subject: [PATCH 1/4] feat(structure): add admin delete --- src/app/services/structure.service.ts | 7 +++++- .../structure-details.component.html | 5 +++- .../structure-details.component.ts | 23 +++++++++++++++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/app/services/structure.service.ts b/src/app/services/structure.service.ts index f767540dc..97caee520 100644 --- a/src/app/services/structure.service.ts +++ b/src/app/services/structure.service.ts @@ -40,8 +40,13 @@ export class StructureService { } public getStructure(id: string): Observable<Structure> { - return this.http.get(`${this.baseUrl}/${id}`).pipe(map((item: any) => new Structure(item))); + return this.http.get<Structure>(`${this.baseUrl}/${id}`); } + + public delete(id: string): Observable<Structure> { + return this.http.delete<Structure>(`${this.baseUrl}/${id}`); + } + public getStructures(filters: Filter[]): Observable<Structure[]> { if (filters && filters.length > 0) { let requestUrl = `${this.baseUrl}/search`; diff --git a/src/app/structure-list/components/structure-details/structure-details.component.html b/src/app/structure-list/components/structure-details/structure-details.component.html index 0d2659880..4a5fabdf3 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.html +++ b/src/app/structure-list/components/structure-details/structure-details.component.html @@ -9,7 +9,7 @@ <div class="structrue-details-container" *ngIf="structure && !isLoading"> <!-- Header info --> <div fxLayout="row" fxLayoutAlign="end center"> - <div (click)="close()" class="ico-close-details"></div> + <div (click)="close(false)" class="ico-close-details"></div> </div> <div fxLayout="row" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="8px"> <div fxLayout="column" fxLayoutGap="10px" fxFlex="100%"> @@ -92,6 +92,9 @@ > Modifier cette structure </a> + <a *ngIf="profileService.isAdmin()" (click)="deleteStructure()" class="primary" tabindex="0"> + Supprimer cette structure + </a> </div> <div> {{ structure.description }} 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 747ca0402..e714b327b 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 @@ -5,7 +5,7 @@ import { Category } from '../../models/category.model'; import { AccessModality } from '../../enum/access-modality.enum'; import { SearchService } from '../../services/search.service'; import * as _ from 'lodash'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { PrintService } from '../../../shared/service/print.service'; import { Equipment } from '../../enum/equipment.enum'; import { typeStructureEnum } from '../../../shared/enum/typeStructure.enum'; @@ -41,13 +41,14 @@ export class StructureDetailsComponent implements OnInit { public currentProfile: User = null; constructor( - route: ActivatedRoute, private printService: PrintService, private searchService: SearchService, private structureService: StructureService, private tclService: TclService, private profileService: ProfileService, - private authService: AuthService + private authService: AuthService, + private route: ActivatedRoute, + private router: Router ) { route.url.subscribe((url) => { if (url[0].path === 'structure') { @@ -103,8 +104,8 @@ export class StructureDetailsComponent implements OnInit { } } - public close(): void { - this.closeDetails.emit(true); + public close(refreshRequired: boolean): void { + this.closeDetails.emit(refreshRequired); } public print(): void { @@ -116,6 +117,18 @@ export class StructureDetailsComponent implements OnInit { this.displayForm(); } + public deleteStructure(): void { + this.structureService.delete(this.structure._id).subscribe((res) => { + this.reload(); + }); + } + + private reload(): void { + this.router.routeReuseStrategy.shouldReuseRoute = () => false; + this.router.onSameUrlNavigation = 'reload'; + this.router.navigate(['./'], { relativeTo: this.route }); + } + public claimStructure(): void { this.isEditMode = false; this.displayForm(); -- GitLab From aae176e28103b98aee31db3a716364088a1a24de Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Tue, 26 Jan 2021 16:40:02 +0100 Subject: [PATCH 2/4] feat: update app-modal for handling confirmation buttons --- .../components/modal/modal-type.enum.ts | 4 ++++ .../components/modal/modal.component.html | 18 ++++++++++++++---- .../components/modal/modal.component.scss | 3 +++ .../components/modal/modal.component.ts | 9 ++++++--- .../components/search/search.component.html | 2 ++ .../components/search/search.component.ts | 2 ++ .../structure-details.component.html | 9 ++++++++- .../structure-details.component.ts | 19 +++++++++++++++---- 8 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 src/app/shared/components/modal/modal-type.enum.ts diff --git a/src/app/shared/components/modal/modal-type.enum.ts b/src/app/shared/components/modal/modal-type.enum.ts new file mode 100644 index 000000000..2dedc045e --- /dev/null +++ b/src/app/shared/components/modal/modal-type.enum.ts @@ -0,0 +1,4 @@ +export enum AppModalType { + information = 1, + confirmation = 2, +} diff --git a/src/app/shared/components/modal/modal.component.html b/src/app/shared/components/modal/modal.component.html index 44094a5b8..c482f44e9 100644 --- a/src/app/shared/components/modal/modal.component.html +++ b/src/app/shared/components/modal/modal.component.html @@ -1,15 +1,25 @@ <div class="cModal" [ngClass]="openned ? 'oModal' : ''"> - <div (clickOutside)="closeModal()"> + <div (clickOutside)="closeModal(false)"> <p>{{ content }}</p> - <footer class="footer"> + <div *ngIf="modalType && modalType === modalTypeEnum.information" class="footer"> <a - (click)="closeModal()" + (click)="closeModal(false)" href="https://services.formulaireextranet.grandlyon.com/saisie-fiche-structure/" tabindex="0" target="_blank" rel="noreferrer noopener" >Continuer vers le formulaire</a > - </footer> + </div> + <div + *ngIf="this.modalType && this.modalType === modalTypeEnum.confirmation" + fxLayout="row" + fxLayoutAlign="center" + fxLayoutGap="20px" + class="footer" + > + <a (click)="closeModal(false)" tabindex="0">Annuler</a> + <button (click)="closeModal(true)">Confirmer</button> + </div> </div> </div> diff --git a/src/app/shared/components/modal/modal.component.scss b/src/app/shared/components/modal/modal.component.scss index 5d12fa764..412a482e4 100644 --- a/src/app/shared/components/modal/modal.component.scss +++ b/src/app/shared/components/modal/modal.component.scss @@ -36,3 +36,6 @@ } padding: 28px; } +button { + @include btn-search-filter; +} diff --git a/src/app/shared/components/modal/modal.component.ts b/src/app/shared/components/modal/modal.component.ts index b4a3566e3..539f775a7 100644 --- a/src/app/shared/components/modal/modal.component.ts +++ b/src/app/shared/components/modal/modal.component.ts @@ -1,4 +1,5 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AppModalType } from './modal-type.enum'; @Component({ selector: 'app-modal', @@ -10,10 +11,12 @@ export class ModalComponent implements OnInit { @Input() public openned: boolean; @Input() public content: string; - @Output() closed = new EventEmitter(); + @Input() public modalType: AppModalType; + @Output() closed = new EventEmitter<boolean>(); + public modalTypeEnum = AppModalType; ngOnInit(): void {} - public closeModal(): void { - this.closed.emit(); + public closeModal(value: boolean): void { + this.closed.emit(value); } } diff --git a/src/app/structure-list/components/search/search.component.html b/src/app/structure-list/components/search/search.component.html index fe3bc0e48..565f49826 100644 --- a/src/app/structure-list/components/search/search.component.html +++ b/src/app/structure-list/components/search/search.component.html @@ -109,6 +109,8 @@ <a (click)="openConfirmationModal()" class="primary right" tabindex="0">Ajouter une structure</a> </div> <app-modal + *ngIf="isConfirmationModalOpen" + [modalType]="modalType.information" [openned]="isConfirmationModalOpen" [content]="confirmationModalContent" (closed)="closeConfirmationModal()" diff --git a/src/app/structure-list/components/search/search.component.ts b/src/app/structure-list/components/search/search.component.ts index d54028a50..ea832db99 100644 --- a/src/app/structure-list/components/search/search.component.ts +++ b/src/app/structure-list/components/search/search.component.ts @@ -3,6 +3,7 @@ import { FormBuilder, FormGroup } from '@angular/forms'; import { forkJoin } from 'rxjs'; import { GeoJson } from '../../../map/models/geojson.model'; import { GeojsonService } from '../../../services/geojson.service'; +import { AppModalType } from '../../../shared/components/modal/modal-type.enum'; import { TypeModal } from '../../enum/typeModal.enum'; import { Category } from '../../models/category.model'; import { Filter } from '../../models/filter.model'; @@ -23,6 +24,7 @@ export class SearchComponent implements OnInit { } @Output() searchEvent = new EventEmitter(); + public modalType = AppModalType; // Form search input public searchForm: FormGroup; diff --git a/src/app/structure-list/components/structure-details/structure-details.component.html b/src/app/structure-list/components/structure-details/structure-details.component.html index 4a5fabdf3..30a0aef4d 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.html +++ b/src/app/structure-list/components/structure-details/structure-details.component.html @@ -92,7 +92,7 @@ > Modifier cette structure </a> - <a *ngIf="profileService.isAdmin()" (click)="deleteStructure()" class="primary" tabindex="0"> + <a *ngIf="profileService.isAdmin()" (click)="toggleDeleteModal()" class="primary" tabindex="0"> Supprimer cette structure </a> </div> @@ -278,3 +278,10 @@ </div> </div> </div> +<app-modal + *ngIf="deleteModalOpenned" + [modalType]="modalType.confirmation" + [openned]="deleteModalOpenned" + [content]="'Voulez-vous vraiment supprimer cette structure ?'" + (closed)="deleteStructure($event)" +></app-modal> 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 e714b327b..750e813b6 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 @@ -16,6 +16,7 @@ import { ProfileService } from '../../../profile/services/profile.service'; import { User } from '../../../models/user.model'; import { AuthService } from '../../../services/auth.service'; import { PublicCategorie } from '../../enum/public.enum'; +import { AppModalType } from '../../../shared/components/modal/modal-type.enum'; @Component({ selector: 'app-structure-details', templateUrl: './structure-details.component.html', @@ -39,6 +40,8 @@ export class StructureDetailsComponent implements OnInit { public isLoading: boolean = false; public isEditMode: boolean = false; public currentProfile: User = null; + public deleteModalOpenned = false; + public modalType = AppModalType; constructor( private printService: PrintService, @@ -117,10 +120,18 @@ export class StructureDetailsComponent implements OnInit { this.displayForm(); } - public deleteStructure(): void { - this.structureService.delete(this.structure._id).subscribe((res) => { - this.reload(); - }); + public toggleDeleteModal(): void { + this.deleteModalOpenned = !this.deleteModalOpenned; + } + + public deleteStructure(shouldDelete: boolean): void { + console.log('DELETE', shouldDelete); + this.toggleDeleteModal(); + if (shouldDelete) { + this.structureService.delete(this.structure._id).subscribe((res) => { + this.reload(); + }); + } } private reload(): void { -- GitLab From f1e447d16de017bb5d04bb7d01d66bb39bc85175 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Tue, 26 Jan 2021 16:47:46 +0100 Subject: [PATCH 3/4] clean: remove unused --- src/app/shared/components/modal/modal.component.ts | 5 ++--- .../structure-details/structure-details.component.ts | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/shared/components/modal/modal.component.ts b/src/app/shared/components/modal/modal.component.ts index 539f775a7..07f877266 100644 --- a/src/app/shared/components/modal/modal.component.ts +++ b/src/app/shared/components/modal/modal.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { AppModalType } from './modal-type.enum'; @Component({ @@ -6,7 +6,7 @@ import { AppModalType } from './modal-type.enum'; templateUrl: './modal.component.html', styleUrls: ['./modal.component.scss'], }) -export class ModalComponent implements OnInit { +export class ModalComponent { constructor() {} @Input() public openned: boolean; @@ -14,7 +14,6 @@ export class ModalComponent implements OnInit { @Input() public modalType: AppModalType; @Output() closed = new EventEmitter<boolean>(); public modalTypeEnum = AppModalType; - ngOnInit(): void {} public closeModal(value: boolean): void { this.closed.emit(value); 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 750e813b6..0f7026f17 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 @@ -8,7 +8,6 @@ import * as _ from 'lodash'; import { ActivatedRoute, Router } from '@angular/router'; import { PrintService } from '../../../shared/service/print.service'; import { Equipment } from '../../enum/equipment.enum'; -import { typeStructureEnum } from '../../../shared/enum/typeStructure.enum'; import { StructureService } from '../../../services/structure.service'; import { TclService } from '../../../services/tcl.service'; import { TclStopPoint } from '../../../models/tclStopPoint.model'; @@ -125,7 +124,6 @@ export class StructureDetailsComponent implements OnInit { } public deleteStructure(shouldDelete: boolean): void { - console.log('DELETE', shouldDelete); this.toggleDeleteModal(); if (shouldDelete) { this.structureService.delete(this.structure._id).subscribe((res) => { -- GitLab From 180886584651e3b2e259c9212b607ddf02f37ac1 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Wed, 27 Jan 2021 09:13:44 +0100 Subject: [PATCH 4/4] fix: remove duplicated event emitter --- .../components/search/search.component.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/app/structure-list/components/search/search.component.ts b/src/app/structure-list/components/search/search.component.ts index 5a4d7ef47..56c38e623 100644 --- a/src/app/structure-list/components/search/search.component.ts +++ b/src/app/structure-list/components/search/search.component.ts @@ -21,16 +21,7 @@ export class SearchComponent implements OnInit, OnChanges { @Output() locatationReset: EventEmitter<boolean> = new EventEmitter<boolean>(); @Output() locatationTrigger: EventEmitter<boolean> = new EventEmitter<boolean>(); @Input() locate = false; - - constructor(public searchService: SearchService, private fb: FormBuilder, private geoJsonService: GeojsonService) { - this.searchForm = this.fb.group({ - searchTerm: '', - }); - } - - @Output() searchEvent = new EventEmitter(); public modalType = AppModalType; - // Form search input public searchForm: FormGroup; // Modal variable @@ -48,10 +39,14 @@ export class SearchComponent implements OnInit, OnChanges { public confirmationModalContent = 'Afin d’ajouter votre structure,vous allez être redirigé vers le formulaire Grand Lyon à remplir.'; + constructor(public searchService: SearchService, private fb: FormBuilder, private geoJsonService: GeojsonService) { + this.searchForm = this.fb.group({ + searchTerm: '', + }); + } ngOnInit(): void { // Will store the different categories this.categories = []; - this.checkedModulesFilter = new Array(); } -- GitLab