up embed, add export docs

This commit is contained in:
Tykayn 2025-11-03 00:37:35 +01:00 committed by tykayn
parent 912b4da08e
commit b18c2c5aec
7 changed files with 414 additions and 33 deletions

View file

@ -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;

View file

@ -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>
}

View file

@ -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 */

View file

@ -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;

View file

@ -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>

View file

@ -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: () => {