diff --git a/front-end/src/app/synthesis-interface/synthesis-interface.component.html b/front-end/src/app/synthesis-interface/synthesis-interface.component.html
index 0bfd8c6..fae4fd6 100644
--- a/front-end/src/app/synthesis-interface/synthesis-interface.component.html
+++ b/front-end/src/app/synthesis-interface/synthesis-interface.component.html
@@ -1,7 +1,69 @@
-
-
+
+
+
+
+
+
+
+ {{ currentObservationsFeatureCollection.features.length }} observations
+
+
+
+ @for (
+ observation of currentObservationsFeatureCollection.features;
+ track observation.properties.id_event
+ ) {
+
+
+
+ {{ observation.properties.name_event }}
+ {{
+ observation.properties.date_event | date: "dd/MM/yyyy"
+ }}
+
+
+
+
+ }
+
+
+
diff --git a/front-end/src/app/synthesis-interface/synthesis-interface.component.scss b/front-end/src/app/synthesis-interface/synthesis-interface.component.scss
index 802c3c2..02d7101 100644
--- a/front-end/src/app/synthesis-interface/synthesis-interface.component.scss
+++ b/front-end/src/app/synthesis-interface/synthesis-interface.component.scss
@@ -1,13 +1,43 @@
+$panel-height: 50vh;
+
.tune-button-container {
width: 100%;
display: flex;
justify-content: center;
position: absolute;
- bottom: 16px;
+ bottom: calc(16px + 48px);
z-index: 400;
}
#map {
- height: 100%;
+ height: calc(100% - 48px);
width: 100%;
}
+
+.map-panel-open {
+ height: calc(100% - $panel-height) !important;
+}
+
+.tune-button-container-panel-open {
+ bottom: calc(16px + $panel-height);
+}
+
+.expansion-panel {
+ border-radius: unset !important;
+}
+
+.expansion-panel-open {
+ height: $panel-height;
+ mat-list {
+ overflow: scroll;
+ max-height: calc($panel-height - var(--mat-toolbar-standard-height) - 16px);
+ }
+}
+
+@media (max-width: 599px) {
+ .expansion-panel-open {
+ mat-list {
+ max-height: calc($panel-height - var(--mat-toolbar-mobile-height) - 16px);
+ }
+ }
+}
diff --git a/front-end/src/app/synthesis-interface/synthesis-interface.component.ts b/front-end/src/app/synthesis-interface/synthesis-interface.component.ts
index 0f85ad1..a536db3 100644
--- a/front-end/src/app/synthesis-interface/synthesis-interface.component.ts
+++ b/front-end/src/app/synthesis-interface/synthesis-interface.component.ts
@@ -1,18 +1,35 @@
-import { Component, afterNextRender, inject } from '@angular/core';
+import {
+ Component,
+ NgZone,
+ afterNextRender,
+ inject,
+ signal,
+} from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatToolbarModule } from '@angular/material/toolbar';
import { Router, RouterLink } from '@angular/router';
import slugify from 'slugify';
-
-import evenementsRemarquables from './evenements_remarquables.json';
import { MatDialog } from '@angular/material/dialog';
import { FilterDialog } from './dialogs/filter-dialog';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { CommonModule } from '@angular/common';
+import { MatListModule } from '@angular/material/list';
+
+import evenementsRemarquables from './evenements_remarquables.json';
@Component({
selector: 'app-synthesis-interface',
standalone: true,
- imports: [MatToolbarModule, MatIconModule, RouterLink, MatButtonModule],
+ imports: [
+ CommonModule,
+ MatToolbarModule,
+ MatIconModule,
+ RouterLink,
+ MatButtonModule,
+ MatExpansionModule,
+ MatListModule,
+ ],
templateUrl: './synthesis-interface.component.html',
styleUrl: './synthesis-interface.component.scss',
})
@@ -22,10 +39,20 @@ export class SynthesisInterfaceComponent {
L: any;
map: any;
observationsFeatureCollection = evenementsRemarquables;
+ currentObservationsFeatureCollection = evenementsRemarquables;
observationsLayer: any;
observationsClusterGroup: any;
router = inject(Router);
+ expansionPanelIsOpen = false;
+ bounds: any;
+ private ngZone = inject(NgZone);
+
+ handleObservationsWithinBoundsBind =
+ this.handleObservationsWithinBounds.bind(this);
+
+ slugify = slugify;
+
constructor() {
afterNextRender(() => {
this.initMap();
@@ -122,6 +149,9 @@ export class SynthesisInterfaceComponent {
this.observationsClusterGroup.addLayer(this.observationsLayer);
this.map.addLayer(this.observationsClusterGroup);
+
+ this.fitToCurrentObservations();
+ this.map.on('moveend', this.handleObservationsWithinBoundsBind);
}
openFilterDialog() {
@@ -138,4 +168,60 @@ export class SynthesisInterfaceComponent {
}
});
}
+
+ expansionPanelOpen() {
+ this.expansionPanelIsOpen = true;
+ }
+
+ expansionPanelClose() {
+ this.expansionPanelIsOpen = false;
+ }
+
+ expansionPanelAfterCollapse() {
+ this.map.invalidateSize();
+ }
+
+ expansionPanelAfterExpand() {
+ this.map.invalidateSize();
+ }
+
+ fitToCurrentObservations() {
+ this.bounds = this.L.default.latLngBounds(
+ this.currentObservationsFeatureCollection.features.map((feature) => [
+ feature.geometry.coordinates[1],
+ feature.geometry.coordinates[0],
+ ]),
+ );
+
+ this.bounds && this.map.fitBounds(this.bounds);
+ }
+
+ handleObservationsWithinBounds() {
+ this.ngZone.run(() => {
+ this.currentObservationsFeatureCollection = {
+ ...this.currentObservationsFeatureCollection,
+ features: this.observationsFeatureCollection.features.filter(
+ (feature) =>
+ this.map
+ .getBounds()
+ .contains(
+ this.L.default.latLng(
+ feature.geometry.coordinates[1],
+ feature.geometry.coordinates[0],
+ ),
+ ),
+ ),
+ };
+ });
+ }
+
+ handleObservationView(observation: any) {
+ this.map.setView(
+ [
+ observation.geometry.coordinates[1],
+ observation.geometry.coordinates[0],
+ ],
+ 19,
+ );
+ }
}
diff --git a/front-end/src/styles.scss b/front-end/src/styles.scss
index f3bfd0b..2b3f60d 100644
--- a/front-end/src/styles.scss
+++ b/front-end/src/styles.scss
@@ -5,6 +5,7 @@ body {
height: 100%;
}
body {
+ background-color: var(--mat-app-background-color);
margin: 0;
font-family: Roboto, "Helvetica Neue", sans-serif;
}