up embed, add export docs
This commit is contained in:
parent
912b4da08e
commit
b18c2c5aec
7 changed files with 414 additions and 33 deletions
|
|
@ -406,6 +406,21 @@ export class AllEvents implements OnInit, OnDestroy {
|
|||
if (this.map) this.map.flyTo({ center: this.originalCoords, zoom: Math.max(this.map.getZoom() || 12, 12) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Centre la carte sur un point avec zoom
|
||||
* @param coords Coordonnées [longitude, latitude]
|
||||
* @param zoom Niveau de zoom (défaut: 14)
|
||||
*/
|
||||
centerOn(coords: [number, number], zoom: number = 14) {
|
||||
if (this.map && coords && coords.length >= 2) {
|
||||
this.map.flyTo({
|
||||
center: coords,
|
||||
zoom: zoom,
|
||||
duration: 1000
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateUrlFromMap() {
|
||||
if (!this.map) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="embed-view-container">
|
||||
<div class="embed-view-container" [class.dark-theme]="isDarkTheme">
|
||||
<div class="embed-header">
|
||||
<h2>Événements OEDB</h2>
|
||||
</div>
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
</div>
|
||||
} @else {
|
||||
<div class="embed-events-list">
|
||||
@for (event of events; track event.id) {
|
||||
<div class="embed-event-item">
|
||||
@for (event of events; track event.id || event.properties?.id) {
|
||||
<a [href]="getEventUrl(event)" class="embed-event-item" [attr.aria-label]="event.properties?.label || event.properties?.name || 'Événement sans nom'">
|
||||
<div class="embed-event-header">
|
||||
<h3 class="embed-event-title">
|
||||
{{event.properties?.label || event.properties?.name || 'Événement sans nom'}}
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@
|
|||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: background-color 0.3s ease, color 0.3s ease;
|
||||
|
||||
&.dark-theme {
|
||||
background: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-header {
|
||||
|
|
@ -40,6 +46,11 @@
|
|||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.dark-theme & {
|
||||
border-color: #34495e;
|
||||
border-top-color: #667eea;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
|
|
@ -50,10 +61,19 @@
|
|||
.embed-error {
|
||||
color: #e74c3c;
|
||||
background: #fdf2f2;
|
||||
|
||||
.dark-theme & {
|
||||
color: #ff6b6b;
|
||||
background: #3d2525;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-empty {
|
||||
color: #6c757d;
|
||||
|
||||
.dark-theme & {
|
||||
color: #95a5a6;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-events-list {
|
||||
|
|
@ -66,18 +86,33 @@
|
|||
}
|
||||
|
||||
.embed-event-item {
|
||||
display: block;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
transition: all 0.2s ease;
|
||||
border-left: 4px solid #667eea;
|
||||
}
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
|
||||
.embed-event-item:hover {
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(2px);
|
||||
.dark-theme & {
|
||||
background: #34495e;
|
||||
border-color: #4a5568;
|
||||
|
||||
&:hover {
|
||||
background: #3d4a5e;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(2px);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-event-header {
|
||||
|
|
@ -94,6 +129,10 @@
|
|||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
flex: 1;
|
||||
|
||||
.dark-theme & {
|
||||
color: #ecf0f1;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-event-type {
|
||||
|
|
@ -115,12 +154,20 @@
|
|||
.embed-event-date,
|
||||
.embed-event-location {
|
||||
color: #6c757d;
|
||||
|
||||
.dark-theme & {
|
||||
color: #95a5a6;
|
||||
}
|
||||
}
|
||||
|
||||
.embed-event-description {
|
||||
color: #495057;
|
||||
margin-top: 8px;
|
||||
line-height: 1.5;
|
||||
|
||||
.dark-theme & {
|
||||
color: #bdc3c7;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import { ActivatedRoute } from '@angular/router';
|
|||
import { OedbApi } from '../../../services/oedb-api';
|
||||
|
||||
interface OedbEvent {
|
||||
id: string;
|
||||
id?: string;
|
||||
properties: {
|
||||
id?: string;
|
||||
label?: string;
|
||||
name?: string;
|
||||
what?: string;
|
||||
|
|
@ -31,13 +32,40 @@ export class EmbedView implements OnInit {
|
|||
events: OedbEvent[] = [];
|
||||
isLoading = true;
|
||||
error: string | null = null;
|
||||
isDarkTheme = false;
|
||||
homeUrl = '/';
|
||||
|
||||
ngOnInit() {
|
||||
this.route.queryParams.subscribe(params => {
|
||||
// Détecter le thème depuis les query params ou préférence système
|
||||
this.detectTheme(params);
|
||||
this.loadEvents(params);
|
||||
});
|
||||
}
|
||||
|
||||
detectTheme(params: any) {
|
||||
if (params.theme) {
|
||||
this.isDarkTheme = params.theme === 'dark';
|
||||
} else {
|
||||
// Détecter depuis la préférence système
|
||||
if (typeof window !== 'undefined' && window.matchMedia) {
|
||||
this.isDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
}
|
||||
}
|
||||
|
||||
// Appliquer le thème au body
|
||||
if (typeof document !== 'undefined') {
|
||||
document.body.classList.toggle('dark-theme', this.isDarkTheme);
|
||||
}
|
||||
}
|
||||
|
||||
getEventUrl(event: OedbEvent): string {
|
||||
// L'ID peut être à la racine du Feature ou dans properties.id
|
||||
const eventId = event.id || event.properties?.id;
|
||||
if (!eventId) return '#';
|
||||
return `${this.homeUrl}?id=${encodeURIComponent(eventId)}`;
|
||||
}
|
||||
|
||||
loadEvents(params: any) {
|
||||
this.isLoading = true;
|
||||
this.error = null;
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@
|
|||
}
|
||||
@if (!showTable && !showUnlocatedList) {
|
||||
<div class="map">
|
||||
<app-all-events [features]="filteredFeatures" [selected]="selected" [selectMode]="selectionMode"
|
||||
<app-all-events #allEventsMap [features]="filteredFeatures" [selected]="selected" [selectMode]="selectionMode"
|
||||
(selection)="onSelection($event)" (select)="onSelect($event)" (pickCoords)="onPickCoords($event)"
|
||||
(mapMove)="onMapMove($event)"></app-all-events>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, inject, signal, OnDestroy, OnInit} from '@angular/core';
|
||||
import {Component, inject, signal, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {Router, RouterLink} from '@angular/router';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {Menu} from './menu/menu';
|
||||
|
|
@ -38,6 +38,8 @@ export class Home implements OnInit, OnDestroy {
|
|||
router = inject(Router);
|
||||
private osmAuth = inject(OsmAuth);
|
||||
|
||||
@ViewChild('allEventsMap') allEventsMap!: AllEvents;
|
||||
|
||||
features: Array<any> = [];
|
||||
filteredFeatures: Array<any> = [];
|
||||
selected: any | null = null;
|
||||
|
|
@ -273,6 +275,24 @@ export class Home implements OnInit, OnDestroy {
|
|||
this.features = f ? [f] : [];
|
||||
this.filteredFeatures = this.features;
|
||||
this.updateAvailableWhatTypes();
|
||||
// Sélectionner automatiquement l'événement et ouvrir le panel d'édition
|
||||
if (f) {
|
||||
this.selected = f;
|
||||
this.showEditForm = true;
|
||||
this.showOptions = true; // Afficher aussi le panel d'options
|
||||
|
||||
// Zoomer sur le marqueur de l'événement si la géométrie est disponible
|
||||
const geometry = f.geometry;
|
||||
if (geometry && geometry.type === 'Point' && geometry.coordinates && geometry.coordinates.length >= 2) {
|
||||
const [lng, lat] = geometry.coordinates;
|
||||
// Attendre que la carte soit initialisée avant de zoomer
|
||||
setTimeout(() => {
|
||||
if (this.allEventsMap) {
|
||||
this.allEventsMap.centerOn([lng, lat], 16); // Zoom élevé pour voir le marqueur de près
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
this.isLoading = false;
|
||||
},
|
||||
error: () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue