diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7bc8c50b98678283500e2a244d53ad3d4442b331..84b07b7d48f60f3414cf0894c105481155a2c237 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,28 +1,28 @@ import { NgModule } from '@angular/core'; -import { Routes, RouterModule, Route } from '@angular/router'; -import { PageComponent } from './page/page.component'; +import { Route, RouterModule, Routes } from '@angular/router'; +import { CartoComponent } from './carto/carto.component'; import { ContactComponent } from './contact/contact.component'; +import { FooterComponent } from './footer/footer.component'; +import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component'; +import { OrientationFormComponent } from './form/orientation-form/orientation-form.component'; import { FormComponent } from './form/structure-form/form.component'; import { AdminGuard } from './guards/admin.guard'; import { AuthGuard } from './guards/auth.guard'; import { DeactivateGuard } from './guards/deactivate.guard'; -import { CartoComponent } from './carto/carto.component'; +import { RoleGuard } from './guards/role.guard'; import { LegalNoticeComponent } from './legal-notice/legal-notice.component'; +import { LoginComponent } from './login/login.component'; +import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component'; +import { PageComponent } from './page/page.component'; import { ResetEmailComponent } from './reset-email/reset-email.component'; import { ResetPasswordComponent } from './reset-password/reset-password.component'; +import { StructureResolver } from './resolvers/structure.resolver'; import { TempUserResolver } from './resolvers/temp-user.resolver'; +import { PasswordFormComponent } from './shared/components'; +import { RouteRole } from './shared/enum/routeRole.enum'; import { StructureJoinComponent } from './structure-join/structure-join.component'; import { StructureDetailsComponent } from './structure-list/components/structure-details/structure-details.component'; import { StructureListComponent } from './structure-list/structure-list.component'; -import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component'; -import { OrientationFormComponent } from './form/orientation-form/orientation-form.component'; -import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component'; -import { StructureResolver } from './resolvers/structure.resolver'; -import { RoleGuard } from './guards/role.guard'; -import { RouteRole } from './shared/enum/routeRole.enum'; -import { LoginComponent } from './login/login.component'; -import { PasswordFormComponent } from './shared/components'; -import { FooterComponent } from './footer/footer.component'; const footerOutletRoute: Route = { path: '', @@ -53,7 +53,17 @@ const routes: Routes = [ }, { path: 'acteurs', - component: CartoComponent, + children: [ + { + path: '', + component: CartoComponent, + }, + { + path: '', + outlet: 'left-pane', + component: StructureDetailsComponent, + }, + ], }, { path: 'login', @@ -148,6 +158,12 @@ const routes: Routes = [ loadChildren: () => import('./profile/profile.module').then((m) => m.ProfileModule), }, footerOutletRoute, + { + path: '', + outlet: 'left-pane', + data: { fullScreen: true }, + component: StructureDetailsComponent, + }, ], }, { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 18b020c871714621fe5a113e798f8d958c594bd1..7534c609808246e9c6beea2482b76fa12850933e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -12,7 +12,7 @@ import { PrintService } from './shared/service/print.service'; styleUrls: ['./app.component.scss'], }) export class AppComponent implements OnInit { - title = 'pamn'; + title = 'resin'; constructor( public printService: PrintService, diff --git a/src/app/carto/carto.component.ts b/src/app/carto/carto.component.ts index 504278456993b2c798db7b2c798a28dbf43b622e..73c34c04f50bbc8b91a333f9e8fd7eb600def831 100644 --- a/src/app/carto/carto.component.ts +++ b/src/app/carto/carto.component.ts @@ -1,15 +1,14 @@ import { Component, OnInit } from '@angular/core'; import { Meta } from '@angular/platform-browser'; +import { ActivatedRoute } from '@angular/router'; import * as _ from 'lodash'; - +import { GeoJson } from '../map/models/geojson.model'; import { Structure } from '../models/structure.model'; +import { GeojsonService } from '../services/geojson.service'; import { StructureService } from '../services/structure.service'; +import { ButtonType } from '../shared/components/button/buttonType.enum'; import { Filter } from '../structure-list/models/filter.model'; -import { GeoJson } from '../map/models/geojson.model'; -import { GeojsonService } from '../services/geojson.service'; import { CustomRegExp } from '../utils/CustomRegExp'; -import { ActivatedRoute } from '@angular/router'; -import { ButtonType } from '../shared/components/button/buttonType.enum'; @Component({ selector: 'app-carto', diff --git a/src/app/form/orientation-form/orientation-form.component.html b/src/app/form/orientation-form/orientation-form.component.html index 7a1546da6d160cd049cf5e461629254617451eb9..edf353772d0169e09b945dccf3f39cb2c6f2209d 100644 --- a/src/app/form/orientation-form/orientation-form.component.html +++ b/src/app/form/orientation-form/orientation-form.component.html @@ -460,9 +460,9 @@ (closeDetails)="closeDetails()" ></app-structure-details> -<app-orientation-modal +<!-- <app-orientation-modal *ngIf="displayModal" [openned]="true" (closed)="closeFinishModal($event)" (previousPage)="previousPage()" -></app-orientation-modal> +></app-orientation-modal> --> diff --git a/src/app/form/orientation-form/orientation-form.component.ts b/src/app/form/orientation-form/orientation-form.component.ts index f8b0c289133aa69a912cfcd65b39994fd82a2975..f7f6ee11905d6b70c4761ce473194e2fa2d9db2b 100644 --- a/src/app/form/orientation-form/orientation-form.component.ts +++ b/src/app/form/orientation-form/orientation-form.component.ts @@ -74,7 +74,6 @@ export class OrientationFormComponent implements OnInit { public showFormation: boolean; public multiPrint: boolean = false; - public displayModal = false; public structuresList: Structure[]; public structuresToPrint: Structure[] = []; @@ -545,12 +544,4 @@ export class OrientationFormComponent implements OnInit { onWindowAfterPrint() { this.multiPrint = false; } - - public displayFinishModal(): void { - this.displayModal = true; - } - - public closeFinishModal(): void { - this.displayModal = false; - } } diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index cb88411cf76a29528d35839e0bdd4c37758efefb..9666d18f5542f97b5b2ec3740c78003be600e95b 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -1,12 +1,12 @@ import { Component, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; -import L, { latLng, MapOptions, geoJSON, tileLayer, Map, latLngBounds, layerGroup } from 'leaflet'; +import L, { geoJSON, latLng, layerGroup, Map, MapOptions, tileLayer } from 'leaflet'; +import * as _ from 'lodash'; +import metropole from '../../../assets/geojson/metropole.json'; import { Structure } from '../../models/structure.model'; import { GeojsonService } from '../../services/geojson.service'; -import { MapService } from '../services/map.service'; -import * as _ from 'lodash'; import { GeoJsonProperties } from '../models/geoJsonProperties.model'; +import { MapService } from '../services/map.service'; import { MarkerType } from './markerType.enum'; -import metropole from '../../../assets/geojson/metropole.json'; import { ZoomLevel } from './zoomLevel.enum'; @Component({ @@ -28,6 +28,7 @@ export class MapComponent implements OnChanges { public map: Map; public mapOptions: MapOptions; + public zoomOptions = { animate: true, duration: 0.5 }; // Add listener on the popup button to show details of structure @HostListener('document:click', ['$event']) @@ -126,7 +127,7 @@ export class MapComponent implements OnChanges { } }, (err) => { - this.map.setView(this.mapOptions.center, this.mapOptions.zoom); + this.map.flyTo(this.mapOptions.center, this.mapOptions.zoom, this.zoomOptions); } ); } @@ -137,7 +138,7 @@ export class MapComponent implements OnChanges { */ public centerOnCoordinates(coords: [number, number]): void { this.mapService.createMarker(coords[1], coords[0], MarkerType.user, 'userLocation').addTo(this.map); - this.map.setView(new L.LatLng(coords[1], coords[0]), ZoomLevel.userPosition); + this.map.flyTo(new L.LatLng(coords[1], coords[0]), ZoomLevel.userPosition, this.zoomOptions); } /** @@ -290,10 +291,8 @@ export class MapComponent implements OnChanges { private centerLeafletMapOnMarker(markerId: string): void { if (this.mapService.getMarker(markerId)) { const marker = this.mapService.getMarker(markerId); - const latLngs = [marker.getLatLng()]; - const markerBounds = latLngBounds(latLngs); - // paddingTopLeft is used for centering marker because of structure details pane - this.map.fitBounds(markerBounds, { paddingTopLeft: [300, 0] }); + const latLngs = marker.getLatLng(); + this.map.flyTo(new L.LatLng(latLngs.lat, latLngs.lng), ZoomLevel.max, this.zoomOptions); } } diff --git a/src/app/shared/components/svg-icon/svg-icon.component.scss b/src/app/shared/components/svg-icon/svg-icon.component.scss index 96eb211f89649753ba21e0c836aae4e67a906379..bbafc583b13fc1d0e9d7eeed6c940508334e4f88 100644 --- a/src/app/shared/components/svg-icon/svg-icon.component.scss +++ b/src/app/shared/components/svg-icon/svg-icon.component.scss @@ -33,6 +33,10 @@ width: 32px; height: 32px; } + &.icon-52 { + width: 52px; + height: 52px; + } &.icon-40 { width: 40px; height: 40px; 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 d07ab3fd8d1809ee90266825b7a446866f309bf8..11f5e19fbcdeef4e435fbba7ecb35c1863d0f0cf 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 @@ -1,17 +1,22 @@ -<div class="structure-details-container" *ngIf="structure && !isLoading"> - <!-- Header info --> - <div class="structure-details-title" fxLayout="row" fxLayoutAlign="space-evenly center"> - <h1 class="bold">{{ structure.structureName }}</h1> - <div class="ico-close"> - <div (click)="close()" class="ico-close-details"></div> +<div class="structure-details" [ngClass]="{ fullScreen: fullScreen === true }" [@slideInOut] *ngIf="structure"> + <div class="structure-details-container"> + <!-- Header info --> + <div class="structure-details-title" fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="space-evenly center"> + <app-svg-icon [type]="'ico'" [icon]="'structureAvatar'" [iconClass]="'icon-52'"></app-svg-icon> + <h1 class="bold">{{ structure.structureName }}</h1> + <div class="ico-close"> + <div (click)="close()" class="ico-close-details"></div> + </div> </div> - </div> - <!-- Content --> - <div class="structure-details-content"> - <!-- Action buttons bar --> - <div class="structure-buttons hide-on-print" fxLayout="row" fxLayoutAlign="space-evenly"> - <!-- Voir le conseiller numérique - Hidden until functionnality is developed --> - <!--div class="clickableDiv" role="button" tabindex="0"> + <div class="structure-details-content" fxLayout="row" fxLayoutAlign="center center" *ngIf="isLoading"> + <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt /> + </div> + <!-- Content --> + <div class="structure-details-content" *ngIf="!isLoading"> + <!-- Action buttons bar --> + <div class="structure-buttons hide-on-print" fxLayout="row" fxLayoutAlign="space-evenly"> + <!-- Voir le conseiller numérique - Hidden until functionnality is developed --> + <!--div class="clickableDiv" role="button" tabindex="0"> <app-svg-icon class="icon" [type]="'ico'" @@ -21,490 +26,496 @@ ></app-svg-icon> <div class="iconTitle">Voir le conseiller numérique</div> </div--> - <!-- Voir le site --> - <div *ngIf="structure.website" class="clickableDiv" role="button" (click)="goToWebsite()" tabindex="0"> - <app-svg-icon class="icon" [type]="'ico'" [icon]="'web'" [iconClass]="'icon-32'"></app-svg-icon> - <div class="iconTitle">Voir le site</div> - </div> - <!-- Voir la plaquette - Hidden until functionnality is developed --> - <!--div class="clickableDiv" role="button" tabindex="0"> + <!-- Voir le site --> + <div *ngIf="structure.website" class="clickableDiv" role="button" (click)="goToWebsite()" tabindex="0"> + <app-svg-icon class="icon" [type]="'ico'" [icon]="'web'" [iconClass]="'icon-32'"></app-svg-icon> + <div class="iconTitle">Voir le site</div> + </div> + <!-- Voir la plaquette - Hidden until functionnality is developed --> + <!--div class="clickableDiv" role="button" tabindex="0"> <app-svg-icon class="icon" [type]="'ico'" [icon]="'docs'" [iconClass]="'icon-32'"></app-svg-icon> <div class="iconTitle">Voir la plaquette</div> </div--> - <!-- Imprimer --> - <div role="button" class="printButton clickableDiv" (click)="print()" tabindex="0"> - <app-svg-icon class="icon" [type]="'ico'" [icon]="'printStructure'" [iconClass]="'icon-32'"></app-svg-icon> - <div class="iconTitle">Imprimer</div> - </div> - <!-- Signaler une erreur --> - <div class="clickableDiv" role="button" (click)="displayModalError()" tabindex="0"> - <app-svg-icon class="icon" [type]="'ico'" [icon]="'watch'" [iconClass]="'icon-32'"></app-svg-icon> - <div class="iconTitle">Signaler une erreur</div> - </div> - <!-- Je travaille ici --> - <div - *ngIf="!profileService.isLinkedToStructure(structure._id)" - class="clickableDiv" - role="button" - (click)="handleJoin()" - tabindex="0" - > - <app-svg-icon class="icon" [type]="'ico'" [icon]="'workhere'" [iconClass]="'icon-32'"></app-svg-icon> - <div class="iconTitle">Je travaille ici</div> - </div> - <!-- Modifier la structure --> - <div - *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()" - class="clickableDiv" - role="button" - (click)="handleModify()" - tabindex="0" - > - <app-svg-icon class="icon" [type]="'ico'" [icon]="'modifyStructure'" [iconClass]="'icon-32'"></app-svg-icon> - <div class="iconTitle">Modifier cette structure</div> + <!-- Imprimer --> + <div role="button" class="printButton clickableDiv" (click)="print()" tabindex="0"> + <app-svg-icon class="icon" [type]="'ico'" [icon]="'printStructure'" [iconClass]="'icon-32'"></app-svg-icon> + <div class="iconTitle">Imprimer</div> + </div> + <!-- Signaler une erreur --> + <div class="clickableDiv" role="button" (click)="displayModalError()" tabindex="0"> + <app-svg-icon class="icon" [type]="'ico'" [icon]="'watch'" [iconClass]="'icon-32'"></app-svg-icon> + <div class="iconTitle">Signaler une erreur</div> + </div> + <!-- Je travaille ici --> + <div + *ngIf="!profileService.isLinkedToStructure(structure._id)" + class="clickableDiv" + role="button" + (click)="handleJoin()" + tabindex="0" + > + <app-svg-icon class="icon" [type]="'ico'" [icon]="'workhere'" [iconClass]="'icon-32'"></app-svg-icon> + <div class="iconTitle">Je travaille ici</div> + </div> + <!-- Modifier la structure --> + <div + *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()" + class="clickableDiv" + role="button" + (click)="handleModify()" + tabindex="0" + > + <app-svg-icon class="icon" [type]="'ico'" [icon]="'modifyStructure'" [iconClass]="'icon-32'"></app-svg-icon> + <div class="iconTitle">Modifier cette structure</div> + </div> </div> - </div> - <!-- Admin menu --> - <div *ngIf="profileService.isAdmin()" class="structure-details-block hide-on-print"> - Administrateur(s) de cette structure: - <div *ngIf="structureAdmins.length === 0">Aucun administrateur</div> - <div *ngIf="structureAdmins.length > 0"> - <div *ngFor="let structureAdmin of structureAdmins"> - {{ structureAdmin.email }} + <!-- Admin menu --> + <div *ngIf="profileService.isAdmin()" class="structure-details-block hide-on-print"> + Administrateur(s) de cette structure: + <div *ngIf="structureAdmins.length === 0">Aucun administrateur</div> + <div *ngIf="structureAdmins.length > 0"> + <div *ngFor="let structureAdmin of structureAdmins"> + {{ structureAdmin.email }} + </div> </div> + <a (click)="toggleDeleteModal()" class="primary" tabindex="0"> Supprimer cette structure </a> </div> - <a (click)="toggleDeleteModal()" class="primary" tabindex="0"> Supprimer cette structure </a> - </div> - <div class="structure-details-block"> - <div fxLayout="column" fxLayoutGap="10px"> - <!-- Informations--> - <div fxLayout="column"> - <h2>Informations</h2> - <div class="info-block"> - <div *ngIf="structure.getLabelTypeStructure()"> - {{ structure.getLabelTypeStructure() }} - </div> - <div *ngIf="structure.structureName"> - {{ structure.structureName }} - </div> - <div *ngIf="structure.address"> - {{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }} - </div> - <div *ngIf="structure.contactPhone"> - {{ structure.contactPhone | phone }} + <div class="structure-details-block"> + <div fxLayout="column" fxLayoutGap="10px"> + <!-- Informations--> + <div fxLayout="column"> + <h2>Informations</h2> + <div class="info-block"> + <div *ngIf="structure.getLabelTypeStructure()"> + {{ structure.getLabelTypeStructure() }} + </div> + <div *ngIf="structure.structureName"> + {{ structure.structureName }} + </div> + <div *ngIf="structure.address"> + {{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }} + </div> + <div *ngIf="structure.contactPhone"> + {{ structure.contactPhone | phone }} + </div> + <div *ngIf="structure.contactMail && structure.contactMail !== 'unknown@unknown.com'"> + <a href="mailto:{{ structure.contactMail }}">{{ structure.contactMail }}</a> + </div> </div> - <div *ngIf="structure.contactMail && structure.contactMail !== 'unknown@unknown.com'"> - <a href="mailto:{{ structure.contactMail }}">{{ structure.contactMail }}</a> + <!-- Social networks--> + <div *ngIf="structure.hasSocialNetwork()" fxLayout="row" fxLayoutAlign="none baseline" fxLayoutGap="4px"> + <a + *ngIf="structure.facebook" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.facebook" + > + <app-svg-icon + [type]="'ico'" + [icon]="'facebook'" + [title]="'Facebook'" + [iconClass]="'icon-30'" + ></app-svg-icon + ></a> + <a + *ngIf="structure.twitter" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.twitter" + > + <app-svg-icon + [type]="'ico'" + [icon]="'twitter'" + [title]="'Twitter'" + [iconClass]="'icon-30'" + ></app-svg-icon + ></a> + <a + *ngIf="structure.instagram" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.instagram" + > + <app-svg-icon + [type]="'ico'" + [icon]="'instagram'" + [title]="'Instagram'" + [iconClass]="'icon-30'" + ></app-svg-icon + ></a> + <a + *ngIf="structure.linkedin" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.linkedin" + > + <app-svg-icon + [type]="'ico'" + [icon]="'linkedin'" + [title]="'Linkedin'" + [iconClass]="'icon-30'" + ></app-svg-icon + ></a> </div> </div> - <!-- Social networks--> - <div *ngIf="structure.hasSocialNetwork()" fxLayout="row" fxLayoutAlign="none baseline" fxLayoutGap="4px"> - <a - *ngIf="structure.facebook" - target="_blank" - class="custom-link" - rel="noopener noreferrer" - [href]="'http://' + structure.facebook" - > - <app-svg-icon - [type]="'ico'" - [icon]="'facebook'" - [title]="'Facebook'" - [iconClass]="'icon-30'" - ></app-svg-icon - ></a> - <a - *ngIf="structure.twitter" - target="_blank" - class="custom-link" - rel="noopener noreferrer" - [href]="'http://' + structure.twitter" - > - <app-svg-icon [type]="'ico'" [icon]="'twitter'" [title]="'Twitter'" [iconClass]="'icon-30'"></app-svg-icon - ></a> - <a - *ngIf="structure.instagram" - target="_blank" - class="custom-link" - rel="noopener noreferrer" - [href]="'http://' + structure.instagram" - > - <app-svg-icon - [type]="'ico'" - [icon]="'instagram'" - [title]="'Instagram'" - [iconClass]="'icon-30'" - ></app-svg-icon - ></a> - <a - *ngIf="structure.linkedin" - target="_blank" - class="custom-link" - rel="noopener noreferrer" - [href]="'http://' + structure.linkedin" - > - <app-svg-icon - [type]="'ico'" - [icon]="'linkedin'" - [title]="'Linkedin'" - [iconClass]="'icon-30'" - ></app-svg-icon - ></a> - </div> + </div> + <div *ngIf="structure.description" class="description">{{ structure.description }}</div> + <div *ngIf="structure.lockdownActivity" class="info"> + {{ structure.lockdownActivity }} </div> </div> - <div *ngIf="structure.description" class="description">{{ structure.description }}</div> - <div *ngIf="structure.lockdownActivity" class="info"> - {{ structure.lockdownActivity }} - </div> - </div> - <div - *ngIf="structure.accessModality.length > 0 || structure.hours.hasData() || structure.remoteAccompaniment" - class="structure-details-block" - fxLayout="column" - > - <div class="hours-services-block"> - <!-- Opening Hours --> - <div *ngIf="structure.hours.hasData()" fxLayout="column"> - <h2>Horaires</h2> - <div fxLayout="column" class="opening-hours"> - <div *ngFor="let day of structure.hours | keyvalue: keepOriginalOrder"> - <div *ngIf="day.value.open" class="opening-hour" fxLayout="row" fxLayoutAlign="flex-start flex-start"> - <h4 class="day">{{ day.key | day }}</h4> - <div class="opening-time" fxLayout="column" fxLayoutAlign="none flex-start"> - <div *ngFor="let timeRange of day.value.time" class="daily-opening-time"> - <p *ngIf="timeRange.opening"> - {{ timeRange.formatOpeningDate() }} - {{ timeRange.formatClosingDate() }} - </p> + <div + *ngIf="structure.accessModality.length > 0 || structure.hours.hasData() || structure.remoteAccompaniment" + class="structure-details-block" + fxLayout="column" + > + <div class="hours-services-block"> + <!-- Opening Hours --> + <div *ngIf="structure.hours.hasData()" fxLayout="column"> + <h2>Horaires</h2> + <div fxLayout="column" class="opening-hours"> + <div *ngFor="let day of structure.hours | keyvalue: keepOriginalOrder"> + <div *ngIf="day.value.open" class="opening-hour" fxLayout="row" fxLayoutAlign="flex-start flex-start"> + <h4 class="day">{{ day.key | day }}</h4> + <div class="opening-time" fxLayout="column" fxLayoutAlign="none flex-start"> + <div *ngFor="let timeRange of day.value.time" class="daily-opening-time"> + <p *ngIf="timeRange.opening"> + {{ timeRange.formatOpeningDate() }} - {{ timeRange.formatClosingDate() }} + </p> + </div> </div> </div> </div> </div> </div> - </div> - <!-- services --> - <div *ngIf="structure.accessModality.length > 0" fxLayout="column"> - <h2>Services</h2> - <div fxLayout="column" fxLayoutGap="10px" class="services-block"> - <div fxLayout="column" fxLayoutGap="8px"> + <!-- services --> + <div *ngIf="structure.accessModality.length > 0" fxLayout="column"> + <h2>Services</h2> + <div fxLayout="column" fxLayoutGap="10px" class="services-block"> + <div fxLayout="column" fxLayoutGap="8px"> + <div + fxLayout="row" + fxLayoutAlign="none flex-end" + fxLayoutGap="8px" + *ngFor="let acces of structure.accessModality" + > + <p>{{ getAccessLabel(acces) }}</p> + </div> + <p *ngIf="structure.pmrAccess">Accessible aux personnes à mobilité réduite</p> + </div> <div + *ngFor="let public of structure.publics" fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="8px" - *ngFor="let acces of structure.accessModality" > - <p>{{ getAccessLabel(acces) }}</p> + <p>{{ getPublicLabel(public) }}</p> + </div> + <div + *ngFor="let accompaniment of structure.publicsAccompaniment" + fxLayout="row" + fxLayoutAlign="none flex-end" + fxLayoutGap="8px" + > + <p>{{ accompaniment }}</p> </div> - <p *ngIf="structure.pmrAccess">Accessible aux personnes à mobilité réduite</p> - </div> - <div - *ngFor="let public of structure.publics" - fxLayout="row" - fxLayoutAlign="none flex-end" - fxLayoutGap="8px" - > - <p>{{ getPublicLabel(public) }}</p> - </div> - <div - *ngFor="let accompaniment of structure.publicsAccompaniment" - fxLayout="row" - fxLayoutAlign="none flex-end" - fxLayoutGap="8px" - > - <p>{{ accompaniment }}</p> </div> </div> </div> - </div> - <div *ngIf="structure.exceptionalClosures" class="bold-info"> - <p class="description">{{ structure.exceptionalClosures }}</p> - </div> - <div *ngIf="structure.remoteAccompaniment" class="bold-info"> - <h3>Cette structure propose un accompagnement à distance.</h3> - </div> - </div> - - <!-- Labellisation --> - <div - *ngIf="structure.labelsQualifications.length" - fxLayout="column" - class="structure-details-block" - fxLayoutAlign="baseline baseline" - fxLayoutGap="12px" - > - <h2>Labellisations</h2> - <div class="wrapper"> - <div *ngFor="let labels of structure.labelsQualifications"> - <app-logo-card [name]="labels"></app-logo-card> + <div *ngIf="structure.exceptionalClosures" class="bold-info"> + <p class="description">{{ structure.exceptionalClosures }}</p> + </div> + <div *ngIf="structure.remoteAccompaniment" class="bold-info"> + <h3>Cette structure propose un accompagnement à distance.</h3> </div> </div> - </div> - <!-- Aides numérique --> - <div - *ngIf="structure.proceduresAccompaniment.length || structure.otherDescription" - fxLayout="column" - class="structure-details-block" - fxLayoutAlign="baseline baseline" - fxLayoutGap="12px" - > - <h2>Aides numérique</h2> - <div fxLayout="column"> + <!-- Labellisation --> + <div + *ngIf="structure.labelsQualifications.length" + fxLayout="column" + class="structure-details-block" + fxLayoutAlign="baseline baseline" + fxLayoutGap="12px" + > + <h2>Labellisations</h2> <div class="wrapper"> - <div *ngFor="let accompagnement of structure.proceduresAccompaniment"> - <app-logo-card *ngIf="accompagnement != 'autres'" [name]="accompagnement"></app-logo-card> + <div *ngFor="let labels of structure.labelsQualifications"> + <app-logo-card [name]="labels"></app-logo-card> </div> </div> - <p *ngIf="structure.otherDescription" fxLayout="column"> - {{ structure.otherDescription }} - </p> </div> - </div> - <!-- Formation --> - <div - *ngIf=" - isBaseSkills() || isAccessRights() || isParentingHelp() || isSocialAndProfessional() || isDigitalSecurity() - " - fxLayout="column" - class="structure-details-block noSeparator" - fxLayoutAlign="baseline baseline" - > - <h2>Formations</h2> - <div *ngIf="structure.freeWorkShop"> - <span *ngIf="multipleWorkshop()" class="bold-info">L'accès à ces formations est gratuit</span> - <span *ngIf="!multipleWorkshop()" class="bold-info">L'accès à cette formation est gratuit</span> - </div> - <div class="formationDetails"> - <!--Toggle BaseSkills--> - <div *ngIf="isBaseSkills()" class="collapse" [ngClass]="{ notCollapsed: !showBaseSkills }"> - <div fxLayout="column"> - <div - class="collapseHeader" - fxLayout="row" - fxLayoutGap="20px" - fxLayoutAlign=" center" - (click)="toggleBaseSkills()" - > - <div class="titleCollapse">Compétences de base</div> - <div class="logo"> - <svg class="show" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> - </svg> - <svg class="hide" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> - </svg> - </div> - </div> - <div *ngIf="showBaseSkills" class="detailsContainer" [@slideInOut]> - <div class="details" *ngFor="let skill of baseSkills">{{ skill.text }}</div> + <!-- Aides numérique --> + <div + *ngIf="structure.proceduresAccompaniment.length || structure.otherDescription" + fxLayout="column" + class="structure-details-block" + fxLayoutAlign="baseline baseline" + fxLayoutGap="12px" + > + <h2>Aides numérique</h2> + <div fxLayout="column"> + <div class="wrapper"> + <div *ngFor="let accompagnement of structure.proceduresAccompaniment"> + <app-logo-card *ngIf="accompagnement != 'autres'" [name]="accompagnement"></app-logo-card> </div> </div> + <p *ngIf="structure.otherDescription" fxLayout="column"> + {{ structure.otherDescription }} + </p> </div> - <!--Toggle accessRights--> - <div *ngIf="isAccessRights()" class="collapse" [ngClass]="{ notCollapsed: !showAccessRights }"> - <div fxLayout="column"> - <div - class="collapseHeader" - fxLayout="row" - fxLayoutGap="20px" - fxLayoutAlign=" center" - (click)="toggleAccessRights()" - > - <div class="titleCollapse">Accès aux droits</div> - <div class="logo"> - <svg class="show" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> - </svg> - <svg class="hide" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> - </svg> + </div> + + <!-- Formation --> + <div + *ngIf=" + isBaseSkills() || isAccessRights() || isParentingHelp() || isSocialAndProfessional() || isDigitalSecurity() + " + fxLayout="column" + class="structure-details-block noSeparator" + fxLayoutAlign="baseline baseline" + > + <h2>Formations</h2> + <div *ngIf="structure.freeWorkShop"> + <span *ngIf="multipleWorkshop()" class="bold-info">L'accès à ces formations est gratuit</span> + <span *ngIf="!multipleWorkshop()" class="bold-info">L'accès à cette formation est gratuit</span> + </div> + <div class="formationDetails"> + <!--Toggle BaseSkills--> + <div *ngIf="isBaseSkills()" class="collapse" [ngClass]="{ notCollapsed: !showBaseSkills }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleBaseSkills()" + > + <div class="titleCollapse">Compétences de base</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> + </svg> + </div> + </div> + <div class="detailsContainer" [@show]="showBaseSkills"> + <div class="details" *ngFor="let skill of baseSkills">{{ skill.text }}</div> </div> - </div> - <div *ngIf="showAccessRights" class="detailsContainer" [@slideInOut]> - <div class="details" *ngFor="let rights of accessRights">{{ rights.text }}</div> </div> </div> - </div> - <!--Toggle parentingHelp--> - <div *ngIf="isParentingHelp()" class="collapse" [ngClass]="{ notCollapsed: !showParentingHelp }"> - <div fxLayout="column"> - <div - class="collapseHeader" - fxLayout="row" - fxLayoutGap="20px" - fxLayoutAlign=" center" - (click)="toggleParentingHelp()" - > - <div class="titleCollapse">Aide à la parentalité</div> - <div class="logo"> - <svg class="show" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> - </svg> - <svg class="hide" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> - </svg> + <!--Toggle accessRights--> + <div *ngIf="isAccessRights()" class="collapse" [ngClass]="{ notCollapsed: !showAccessRights }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleAccessRights()" + > + <div class="titleCollapse">Accès aux droits</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> + </svg> + </div> + </div> + <div class="detailsContainer" [@show]="showAccessRights"> + <div class="details" *ngFor="let rights of accessRights">{{ rights.text }}</div> </div> - </div> - <div *ngIf="showParentingHelp" class="detailsContainer" [@slideInOut]> - <div class="details" *ngFor="let help of parentingHelp">{{ help.text }}</div> </div> </div> - </div> - <!--Toggle socialAndProfessional--> - <div - *ngIf="isSocialAndProfessional()" - class="collapse" - [ngClass]="{ notCollapsed: !showSocialAndProfessional }" - > - <div fxLayout="column"> - <div - class="collapseHeader" - fxLayout="row" - fxLayoutGap="20px" - fxLayoutAlign=" center" - (click)="toggleSocialAndProfessional()" - > - <div class="titleCollapse">Insertion sociale et professionnelle</div> - <div class="logo"> - <svg class="show" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> - </svg> - <svg class="hide" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> - </svg> + <!--Toggle parentingHelp--> + <div *ngIf="isParentingHelp()" class="collapse" [ngClass]="{ notCollapsed: !showParentingHelp }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleParentingHelp()" + > + <div class="titleCollapse">Aide à la parentalité</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> + </svg> + </div> + </div> + <div class="detailsContainer" [@show]="showParentingHelp"> + <div class="details" *ngFor="let help of parentingHelp">{{ help.text }}</div> </div> - </div> - <div *ngIf="showSocialAndProfessional" class="detailsContainer" [@slideInOut]> - <div class="details" *ngFor="let skill of socialAndProfessional">{{ skill.text }}</div> </div> </div> - </div> - <!--Toggle digitalSecurity--> - <div *ngIf="isDigitalSecurity()" class="collapse" [ngClass]="{ notCollapsed: !showDigitalSecurity }"> - <div fxLayout="column"> - <div - class="collapseHeader" - fxLayout="row" - fxLayoutGap="20px" - fxLayoutAlign=" center" - (click)="toggleDigitalSecurity()" - > - <div class="titleCollapse">Culture et sécurité numérique</div> - <div class="logo"> - <svg class="show" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> - </svg> - <svg class="hide" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> - </svg> + <!--Toggle socialAndProfessional--> + <div + *ngIf="isSocialAndProfessional()" + class="collapse" + [ngClass]="{ notCollapsed: !showSocialAndProfessional }" + > + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleSocialAndProfessional()" + > + <div class="titleCollapse">Insertion sociale et professionnelle</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> + </svg> + </div> + </div> + <div class="detailsContainer" [@show]="showSocialAndProfessional"> + <div class="details" *ngFor="let skill of socialAndProfessional">{{ skill.text }}</div> </div> </div> - <div *ngIf="showDigitalSecurity" class="detailsContainer" [@slideInOut]> - <div class="details" *ngFor="let skill of digitalCultureSecurity">{{ skill.text }}</div> + </div> + <!--Toggle digitalSecurity--> + <div *ngIf="isDigitalSecurity()" class="collapse" [ngClass]="{ notCollapsed: !showDigitalSecurity }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleDigitalSecurity()" + > + <div class="titleCollapse">Culture et sécurité numérique</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#unfold'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#fold'"></use> + </svg> + </div> + </div> + <div class="detailsContainer" [@show]="showDigitalSecurity"> + <div class="details" *ngFor="let skill of digitalCultureSecurity">{{ skill.text }}</div> + </div> </div> </div> </div> </div> - </div> - <!-- Matériel et wifi --> - <div - *ngIf="structure.hasEquipments()" - fxLayout="column" - class="structure-details-block" - fxLayoutAlign="baseline baseline" - > - <h2>Matériel et wifi</h2> - <div fxLayout="column"> - <div *ngIf="filterOnlyEquipments(structure.equipmentsAndServices).includes('wifiEnAccesLibre')"> - {{ getEquipmentsLabel('wifiEnAccesLibre') }} + <!-- Matériel et wifi --> + <div + *ngIf="structure.hasEquipments()" + fxLayout="column" + class="structure-details-block" + fxLayoutAlign="baseline baseline" + > + <h2>Matériel et wifi</h2> + <div fxLayout="column"> + <div *ngIf="filterOnlyEquipments(structure.equipmentsAndServices).includes('wifiEnAccesLibre')"> + {{ getEquipmentsLabel('wifiEnAccesLibre') }} + </div> + <p *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" class="no-margin-bottom"> + <span *ngIf="equipement == 'ordinateurs' && structure.nbComputers" + >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbComputers }}</span + > + <span *ngIf="equipement == 'tablettes' && structure.nbTablets" + >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbTablets }}</span + > + <span *ngIf="equipement == 'bornesNumeriques' && structure.nbNumericTerminal"> + {{ getEquipmentsLabel(equipement) }} : {{ structure.nbNumericTerminal }}</span + > + <span *ngIf="equipement == 'imprimantes' && structure.nbPrinters" + >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbPrinters }}</span + > + <span *ngIf="equipement == 'scanners' && structure.nbScanners" + >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbScanners }}</span + > + </p> </div> - <p *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" class="no-margin-bottom"> - <span *ngIf="equipement == 'ordinateurs' && structure.nbComputers" - >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbComputers }}</span - > - <span *ngIf="equipement == 'tablettes' && structure.nbTablets" - >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbTablets }}</span - > - <span *ngIf="equipement == 'bornesNumeriques' && structure.nbNumericTerminal"> - {{ getEquipmentsLabel(equipement) }} : {{ structure.nbNumericTerminal }}</span - > - <span *ngIf="equipement == 'imprimantes' && structure.nbPrinters" - >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbPrinters }}</span - > - <span *ngIf="equipement == 'scanners' && structure.nbScanners" - >{{ getEquipmentsLabel(equipement) }} : {{ structure.nbScanners }}</span - > - </p> </div> - </div> - <!-- Transport --> - <div - *ngIf="tclStopPoints.length" - fxLayout="column" - class="structure-details-block noSeparator" - fxLayoutAlign="baseline baseline" - > - <h2>Accès</h2> - <div fxLayout="column wrap" fxLayoutGap="24px"> - <div *ngFor="let tclStop of tclStopPoints | slice: 0:3"> - {{ tclStop.name }} - <div fxLayout="row wrap" fxLayoutGap="16px"> - <p *ngFor="let sub of tclStop.subLines"> - <app-svg-icon [type]="'tcl'" [icon]="sub" [iconClass]="'icon-75'"></app-svg-icon> - </p> - <p *ngFor="let tram of tclStop.tramLines"> - <app-svg-icon [type]="'tcl'" [icon]="tram" [iconClass]="'icon-75'"></app-svg-icon> - </p> - <p *ngFor="let bus of tclStop.busLines"> - <app-svg-icon [type]="'tcl'" [icon]="bus" [iconClass]="'icon-75'"></app-svg-icon> - </p> + <!-- Transport --> + <div + *ngIf="tclStopPoints.length" + fxLayout="column" + class="structure-details-block noSeparator" + fxLayoutAlign="baseline baseline" + > + <h2>Accès</h2> + <div fxLayout="column wrap" fxLayoutGap="24px"> + <div *ngFor="let tclStop of tclStopPoints | slice: 0:3"> + {{ tclStop.name }} + <div fxLayout="row wrap" fxLayoutGap="16px"> + <p *ngFor="let sub of tclStop.subLines"> + <app-svg-icon [type]="'tcl'" [icon]="sub" [iconClass]="'icon-75'"></app-svg-icon> + </p> + <p *ngFor="let tram of tclStop.tramLines"> + <app-svg-icon [type]="'tcl'" [icon]="tram" [iconClass]="'icon-75'"></app-svg-icon> + </p> + <p *ngFor="let bus of tclStop.busLines"> + <app-svg-icon [type]="'tcl'" [icon]="bus" [iconClass]="'icon-75'"></app-svg-icon> + </p> + </div> </div> </div> </div> - </div> - <!-- Mise à jour --> - <div fxLayout="column" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="20px"> - <div fxLayout="row" fxLayoutAlign="none flex-start" fxLayoutGap="13px"> - <p class="updated">Mise à jour le {{ structure.updatedAt | date: 'mediumDate' }}</p> + <!-- Mise à jour --> + <div fxLayout="column" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="20px"> + <div fxLayout="row" fxLayoutAlign="none flex-start" fxLayoutGap="13px"> + <p class="updated">Mise à jour le {{ structure.updatedAt | date: 'mediumDate' }}</p> + </div> </div> </div> - </div> - <app-modal-confirmation - [openned]="deleteModalOpenned" - [content]="'Voulez-vous vraiment supprimer cette structure ?'" - (closed)="deleteStructure($event)" - ></app-modal-confirmation> + <app-modal-confirmation + [openned]="deleteModalOpenned" + [content]="'Voulez-vous vraiment supprimer cette structure ?'" + (closed)="deleteStructure($event)" + ></app-modal-confirmation> - <app-modal-confirmation - [openned]="claimModalOpenned" - [content]=" - 'Voulez-vous vraiment revendiquer cette structure ? Une demande sera envoyée à l\'administrateur pour validation' - " - (closed)="claimStructure($event)" - ></app-modal-confirmation> + <app-modal-confirmation + [openned]="claimModalOpenned" + [content]=" + 'Voulez-vous vraiment revendiquer cette structure ? Une demande sera envoyée à l\'administrateur pour validation' + " + (closed)="claimStructure($event)" + ></app-modal-confirmation> - <app-modal-confirmation - [openned]="joinModalOpenned" - [content]=" - 'Voulez-vous vraiment rejoindre cette structure ? Une demande sera envoyée aux membres pour validation' - " - (closed)="joinStructure($event)" - ></app-modal-confirmation> + <app-modal-confirmation + [openned]="joinModalOpenned" + [content]=" + 'Voulez-vous vraiment rejoindre cette structure ? Une demande sera envoyée aux membres pour validation' + " + (closed)="joinStructure($event)" + ></app-modal-confirmation> - <app-text-input-modal - [openned]="structureErrorModalOpenned" - [placeholder]="'Décrivez l\'erreur ici. Ex: Horaires faux...'" - [content]=" - 'Voulez-vous notifier res\'in d\'une erreur sur la fiche de cet acteur ? Votre commentaire sera envoyé à l\'acteur en question ainsi qu\'aux administrateurs.' - " - (closed)="sendErrorEmail($event)" - (newContent)="sendErrorEmail($event)" - ></app-text-input-modal> + <app-text-input-modal + [openned]="structureErrorModalOpenned" + [placeholder]="'Décrivez l\'erreur ici. Ex: Horaires faux...'" + [content]=" + 'Voulez-vous notifier res\'in d\'une erreur sur la fiche de cet acteur ? Votre commentaire sera envoyé à l\'acteur en question ainsi qu\'aux administrateurs.' + " + (closed)="sendErrorEmail($event)" + (newContent)="sendErrorEmail($event)" + ></app-text-input-modal> + </div> </div> diff --git a/src/app/structure-list/components/structure-details/structure-details.component.scss b/src/app/structure-list/components/structure-details/structure-details.component.scss index 46c315d9ce8dab0dbf39064d7aba79eb91bc3198..a55589857f97b496445ca3b5c54e61d8ec8c38b7 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.scss +++ b/src/app/structure-list/components/structure-details/structure-details.component.scss @@ -2,6 +2,7 @@ @import '../../../../assets/scss/typography'; @import '../../../../assets/scss/breakpoint'; @import '../../../../assets/scss/layout'; +@import '../../../../assets/scss/z-index'; a { padding: unset; @@ -31,12 +32,14 @@ h3 { } .structure-details-container { - position: relative; - height: 100%; - width: calc(100% - 1px); + position: absolute; + z-index: $structure-details-z-index; + height: calc(100vh - $header-height - 1px); // -1 is to prevent limit case + width: 100%; background-color: $white; overflow: hidden; border-bottom: 1px solid $grey-5; + border-right: 1px solid $grey-5; } .structure-details-title { @@ -174,8 +177,6 @@ h3 { width: 95% !important; } &.notCollapsed { - margin-bottom: 8px; - height: 40px; border-bottom: 2px solid $grey-8; .logo { .hide { @@ -215,6 +216,7 @@ h3 { margin: 8px 0px; padding: 8px 0; background-color: $grey-8; + overflow: hidden; } .details { padding: 8px 16px; @@ -257,7 +259,15 @@ p, } @media print { - .structure-details-container { + .structure-details { + height: unset !important; + overflow: hidden; + z-index: unset; + width: unset; + position: unset !important; + } + .structure-details-container, + .structure-details-content { background-color: unset; z-index: unset; position: unset; @@ -275,3 +285,36 @@ p, display: none !important; } } + +@keyframes fadeBackground { + 0% { + background-color: $modal-background-transparent; + } + 100% { + background-color: $modal-background; + } +} +.fullScreen { + width: calc(100% + 600px) !important; + background-color: $modal-background; + animation: fadeBackground 0.5s; + max-width: unset !important; + @media #{$tablet} { + width: 100% !important; + } +} +.structure-details { + position: fixed; + z-index: $structure-details-z-index; + height: calc(100vh - $header-height); + width: 100%; + max-width: 600px; + + .structure-details-container { + max-width: 600px; + opacity: 1 !important; + @media #{$tablet} { + max-width: unset; + } + } +} 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 f5079f795d5fb0c1b7a5bacf275fa00be257000b..1271fa67b42879d448f8bbb126182ce3d46da7cb 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 @@ -1,22 +1,23 @@ +import { animate, AUTO_STYLE, state, style, transition, trigger } from '@angular/animations'; +import { Location } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Structure } from '../../../models/structure.model'; -import { Module } from '../../models/module.model'; -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, Router } from '@angular/router'; -import { PrintService } from '../../../shared/service/print.service'; -import { Equipment } from '../../enum/equipment.enum'; -import { StructureService } from '../../../services/structure.service'; -import { TclService } from '../../../services/tcl.service'; +import * as _ from 'lodash'; +import { Owner } from '../../../models/owner.model'; +import { Structure } from '../../../models/structure.model'; import { TclStopPoint } from '../../../models/tclStopPoint.model'; -import { ProfileService } from '../../../profile/services/profile.service'; import { User } from '../../../models/user.model'; +import { ProfileService } from '../../../profile/services/profile.service'; import { AuthService } from '../../../services/auth.service'; +import { StructureService } from '../../../services/structure.service'; +import { TclService } from '../../../services/tcl.service'; +import { PrintService } from '../../../shared/service/print.service'; +import { AccessModality } from '../../enum/access-modality.enum'; +import { Equipment } from '../../enum/equipment.enum'; import { PublicCategorie } from '../../enum/public.enum'; -import { Owner } from '../../../models/owner.model'; -import { style, animate, transition, trigger, group } from '@angular/animations'; +import { Category } from '../../models/category.model'; +import { Module } from '../../models/module.model'; +import { SearchService } from '../../services/search.service'; @Component({ selector: 'app-structure-details', @@ -24,14 +25,21 @@ import { style, animate, transition, trigger, group } from '@angular/animations' styleUrls: ['./structure-details.component.scss'], animations: [ trigger('slideInOut', [ + transition(':enter', [style({ left: '-600px' }), animate('200ms ease-in', style({ left: '0' }))]), + transition(':leave', [animate('200ms ease-in', style({ left: '-600px' }))]), + ]), + trigger('fadeInOut', [ transition(':enter', [ - style({ height: '0', opacity: 0 }), - group([animate(200, style({ height: '*' })), animate('200ms ease-in-out', style({ opacity: '1' }))]), - ]), - transition(':leave', [ - style({ height: '*', opacity: 1 }), - group([animate(1, style({ height: 0 })), animate(1, style({ opacity: '0' }))]), + style({ backgroundColor: 'rgb(00, 00, 00, 0)' }), + animate('200ms ease-in', style({ backgroundColor: 'rgb(00, 00, 00, 0.6)' })), ]), + transition(':leave', [animate('200ms ease-in', style({ backgroundColor: 'rgb(00, 00, 00, 0)' }))]), + ]), + trigger('show', [ + state('true', style({ height: AUTO_STYLE, visibility: AUTO_STYLE, margin: '8px 0' })), + state('false', style({ height: '0px', visibility: 'hidden', margin: '0' })), + transition('true => false', animate('300ms ease-out')), + transition('false => true', animate('300ms ease-out')), ]), ], }) @@ -50,23 +58,25 @@ export class StructureDetailsComponent implements OnInit { public parentingHelp: Module[]; public socialAndProfessional: Module[]; public digitalCultureSecurity: Module[]; - public showBaseSkills: boolean; - public showAccessRights: boolean; - public showParentingHelp: boolean; - public showSocialAndProfessional: boolean; - public showDigitalSecurity: boolean; + public showBaseSkills = false; + public showAccessRights = false; + public showParentingHelp = false; + public showSocialAndProfessional = false; + public showDigitalSecurity = false; public tclStopPoints: TclStopPoint[] = []; public printMode = false; public isClaimed: boolean = null; - public isLoading: boolean = false; + public isLoading = true; public currentProfile: User = null; public deleteModalOpenned = false; public claimModalOpenned = false; public structureErrorModalOpenned = false; public joinModalOpenned = false; public structureAdmins: Owner[] = []; + public fullScreen = false; constructor( + private location: Location, private printService: PrintService, private searchService: SearchService, private structureService: StructureService, @@ -76,16 +86,40 @@ export class StructureDetailsComponent implements OnInit { private route: ActivatedRoute, private router: Router ) { - route.url.subscribe((url) => { - if (url[0].path === 'structure') { - this.structure = this.printService.structure; + this.route.url.subscribe((url) => { + if (url.length > 0 && url[0].path === 'structure') { + this.structure = new Structure(this.printService.structure); this.printMode = true; + // Display formations for printing + this.toggleAccessRights(); + this.toggleBaseSkills(); + this.toggleDigitalSecurity(); + this.toggleParentingHelp(); + this.toggleSocialAndProfessional(); + this.initForm(); } }); } async ngOnInit(): Promise<void> { - this.isLoading = true; + this.route.queryParams.subscribe((queryParams) => { + if (queryParams.id) { + this.structureService.getStructure(queryParams.id).subscribe((structure) => { + this.structure = new Structure(structure); + this.initForm(); + }); + } else if (!this.printMode) { + this.structure = null; + } + }); + this.route.data.subscribe((data) => { + if (data.fullScreen) { + this.fullScreen = true; + } + }); + } + + private async initForm(): Promise<void> { if (this.userIsLoggedIn()) { this.currentProfile = await this.profileService.getProfile(); @@ -150,7 +184,7 @@ export class StructureDetailsComponent implements OnInit { public close(): void { this.route.url.subscribe((urls) => { - if (urls[0].path != 'orientation') { + if (urls.length > 0 && urls[0].path !== 'orientation') { this.router.navigate(['/acteurs'], { relativeTo: this.route, queryParams: { @@ -159,7 +193,14 @@ export class StructureDetailsComponent implements OnInit { queryParamsHandling: 'merge', }); } else { - this.closeDetails.emit(); + this.isLoading = true; + this.router.navigate(['./'], { + relativeTo: this.route, + queryParams: { + id: null, + }, + queryParamsHandling: 'merge', + }); } }); } 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 82f2d6c14afa5d4ef0856f76e0900e03e9207de0..fafe341d5c9efaf8495ef5e2b8f8f1b47dcf81a1 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 @@ -1,12 +1,12 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ButtonType } from '../../../shared/components/button/buttonType.enum'; import { TypeModal } from '../../enum/typeModal.enum'; import { Category } from '../../models/category.model'; import { Filter } from '../../models/filter.model'; import { Module } from '../../models/module.model'; import { SearchService } from '../../services/search.service'; -import { ActivatedRoute, Router } from '@angular/router'; -import { ButtonType } from '../../../shared/components/button/buttonType.enum'; @Component({ selector: 'app-structure-list-search', diff --git a/src/app/structure-list/structure-list.component.html b/src/app/structure-list/structure-list.component.html index e3ef2465bfd6ffacf866ce154a66bd1987aaf2ff..68eda11340e9105ce29b7ea00c10858c0b54e24e 100644 --- a/src/app/structure-list/structure-list.component.html +++ b/src/app/structure-list/structure-list.component.html @@ -25,11 +25,3 @@ <p *ngIf="structureList && structureList.length <= 0">Il n'y a aucune réponse correspondant à votre recherche</p> </div> </div> - -<app-structure-details - class="structureList-details" - *ngIf="showStructureDetails" - [structure]="structure" - (closeDetails)="closeDetails()" - (updatedStructure)="emitUpdatedStructure($event)" -></app-structure-details> diff --git a/src/app/structure-list/structure-list.component.scss b/src/app/structure-list/structure-list.component.scss index da4cbbfb66126ff8943fdf654954399ff96fa3af..b8108121d4b2ce054cebaacb8247e14670da3e9a 100644 --- a/src/app/structure-list/structure-list.component.scss +++ b/src/app/structure-list/structure-list.component.scss @@ -29,14 +29,6 @@ border-bottom: unset !important; } -.structureList-details { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: inherit; -} - @media print { .listCard { display: none; diff --git a/src/app/structure-list/structure-list.component.spec.ts b/src/app/structure-list/structure-list.component.spec.ts index 4d8e9351f21c91b2115bf0c7cffc283533290adb..77af804ccc53702dee9100089cf6bed6fe7f6d19 100644 --- a/src/app/structure-list/structure-list.component.spec.ts +++ b/src/app/structure-list/structure-list.component.spec.ts @@ -1,8 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { OpeningDay } from '../models/openingDay.model'; import { Structure } from '../models/structure.model'; -import { Filter } from './models/filter.model'; - import { StructureListComponent } from './structure-list.component'; describe('StructureListComponent', () => { @@ -167,20 +165,11 @@ describe('StructureListComponent', () => { expect(component).toBeTruthy(); }); - it('should emit filters', () => { - const arr: Filter[] = []; - spyOn(component.searchEvent, 'emit'); - component.fetchResults(arr); - expect(component.searchEvent.emit).toHaveBeenCalled(); - expect(component.searchEvent.emit).toHaveBeenCalledWith(arr); - }); - it('should emit id structure and update variables to open details', () => { spyOn(component.selectedMarkerId, 'emit'); component.showDetails(structure); expect(component.selectedMarkerId.emit).toHaveBeenCalled(); expect(component.selectedMarkerId.emit).toHaveBeenCalledWith(structure._id); - expect(component.showStructureDetails).toBe(true); expect(component.structure).toBe(structure); }); @@ -189,7 +178,6 @@ describe('StructureListComponent', () => { component.closeDetails(); expect(component.selectedMarkerId.emit).toHaveBeenCalled(); expect(component.selectedMarkerId.emit).toHaveBeenCalledWith(); - expect(component.showStructureDetails).toBe(false); }); it('should emit id structure to display map marker', () => { diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts index 11aeae7da25deb5c52149e5eb8d50d422dab521c..df44ef9e3d900f8e1451bfc45becc5a68e27b670 100644 --- a/src/app/structure-list/structure-list.component.ts +++ b/src/app/structure-list/structure-list.component.ts @@ -1,11 +1,10 @@ -import { Component, EventEmitter, Input, Output, OnChanges, SimpleChanges } from '@angular/core'; -import { Structure } from '../models/structure.model'; -import { GeoJson } from '../map/models/geojson.model'; -import * as _ from 'lodash'; +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; 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 { ButtonType } from '../shared/components/button/buttonType.enum'; -import { AuthService } from '../services/auth.service'; @Component({ selector: 'app-structure-list', @@ -21,7 +20,6 @@ export class StructureListComponent implements OnChanges { @Output() public updatedStructure: EventEmitter<Structure> = new EventEmitter<Structure>(); public buttonTypeEnum = ButtonType; - public showStructureDetails = false; public structure: Structure; constructor( @@ -67,14 +65,12 @@ export class StructureListComponent implements OnChanges { } public showDetails(event: Structure): void { - this.showStructureDetails = true; this.structure = event; this.selectedMarkerId.emit(this.structure._id); } public closeDetails(): void { this.selectedMarkerId.emit(); - this.showStructureDetails = false; } public handleCardHover(structure: Structure): void { @@ -84,8 +80,4 @@ export class StructureListComponent implements OnChanges { public mouseLeave(): void { this.displayMapMarkerId.emit(undefined); } - - public emitUpdatedStructure(s: Structure): void { - this.updatedStructure.emit(s); - } } diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index d327ba0062a2577bdb29b8838d2e775ef8fbc241..269660abcc522d87b0f211149db5d47a08ce005f 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -424,6 +424,31 @@ <path d="M28.0279 27.0279C28.5486 27.5486 28.6541 28.2873 28.2636 28.6778C27.8731 29.0683 27.1344 28.9628 26.6137 28.4421L11.5287 13.3572C11.008 12.8365 10.9025 12.0978 11.293 11.7072C11.6836 11.3167 12.4223 11.4222 12.943 11.9429L28.0279 27.0279Z" fill="#333333"/> </symbol> +<symbol id="structureAvatar" fill="none" width="52" height="52" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"> +<path d="M0 4a4 4 0 0 1 4-4h44a4 4 0 0 1 4 4v44a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4Z" fill="#fff"/> +<path d="M7.4 34.5c-.5.3-.5.8 0 1L24 45.4a2 2 0 0 0 2 0l17.6-10.2c.5-.3.5-.8 0-1l-16.8-9.8c-.5-.3-1.3-.3-1.9 0L7.4 34.5Z" fill="#DA3635"/> +<path d="M38.2 19.7v14.8l-13 7.4V27.1l13-7.4Z" fill="#fff"/> +<path d="M38.2 19.7v14.8l-13 7.4V27.1l13-7.4Z" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m25.3 27-13-7.3 13-7.5 13 7.5-13 7.4Z" fill="#fff" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m25.3 26-11-6.3 11-6.3 11 6.3-11 6.3Z" fill="#fff" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="M12.4 19.7v14.8l12.9 7.4V27.1l-13-7.4Z" fill="#fff"/> +<path d="M12.4 19.7v14.8l12.9 7.4V27.1l-13-7.4Z" fill="#BDBDBD" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m25.3 10.5 13 7.5-13 7.4-13-7.4 13-7.5Zm11 7.5-11-6.3-11 6.3 11 6.3 11-6.3Z" fill="#fff" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="M38.2 18v2.6l-13 7.4v-2.6l13-7.4Z" fill="#fff"/> +<path d="M38.2 20.6V18l-13 7.4V28" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="M25.3 25.4v2.5l-13-7.4V18l13 7.4Z" fill="#BDBDBD"/> +<path d="M25.3 27.9v-2.5l-13-7.4v2.5" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="M25.3 11.7v1.7l-9.5 5.4-1.5-.8 11-6.3Z" fill="#fff" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m36.3 18-11-6.3v1.7l9.5 5.4 1.5-.8ZM29 28.2l.1 11.6 6-3.4V24.8l-6 3.4ZM18 24.8v4.6l-3.3-1.9V23l3.3 2ZM23 27.6V32l-3.4-1.9v-4.5l3.3 1.9ZM18 31.1v4.6l-3.4-1.9v-4.6l3.4 2ZM22.9 33.9v4.5l-3.3-1.9V32l3.3 2Z" fill="#fff" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m38.2 18-13 7.6" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="M24.9 25.1 12 17.8l13.3-8 12.8 7.4-13.3 8Z" fill="#E9E9E9"/> +<path d="M25.6 10.1a.5.5 0 0 1 .5.9l-.5-.9Zm-13.1 8.2a.5.5 0 1 1-.5-1l.5 1Zm-.5-1 13.6-7.2.5.9-13.6 7.3-.5-1Z" fill="#706F6F"/> +<path d="M38.2 17a.5.5 0 0 1-.5.8l.5-.9Zm-12.4-6.1a.5.5 0 1 1 .5-1l-.5 1Zm11.9 6.9-12-7 .6-.8 11.9 7-.5.8ZM25.2 25.3a.5.5 0 0 1-.5.9l.5-.9Zm-12.9-6.6a.5.5 0 1 1 .5-.8l-.5.8Zm12.4 7.5-12.4-7.5.5-.8 12.4 7.4-.5.9Z" fill="#706F6F"/> +<path d="M26 27.8 16 16.1l16-8.2 9.6 11-15.5 9Z" fill="#fff" stroke="#696969" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m8.6 17.8 7.5-1.7 16-8.2L23 9.6 8.6 17.8Z" fill="#E9E9E9" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +<path d="m8.6 17.8 8-1.7 9.5 11.7-17.5-10Z" fill="#BDBDBD" stroke="#706F6F" stroke-miterlimit="10" stroke-linejoin="round"/> +</symbol> + <symbol id="profile" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M22.7499 24.492V21.3125C22.7499 20.4008 22.3878 19.5265 21.7431 18.8818C21.0985 18.2372 20.2241 17.875 19.3124 17.875H12.4375C11.5258 17.875 10.6515 18.2372 10.0068 18.8818C9.36216 19.5265 9 20.4008 9 21.3125V24.492" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> <path d="M15.875 15.625C18.1877 15.625 20.0625 13.7502 20.0625 11.4375C20.0625 9.1248 18.1877 7.25 15.875 7.25C13.5623 7.25 11.6875 9.1248 11.6875 11.4375C11.6875 13.7502 13.5623 15.625 15.875 15.625Z" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> @@ -442,5 +467,4 @@ </defs> </symbol> - </svg>