Seed-Daten per Fetch von externem Server laden, UI-Sprachumschalter (DE/EN) und KI-Übersetzungs-Prompt-Generator ergänzen
- Beispieldaten werden nicht mehr eingebettet (data/seed.js entfernt), sondern beim ersten Start per fetch(EventMap.config.SEED_DATA_URL) von einem externen, selbst gehosteten Server geladen (siehe ADR 0001, Revision 2026-07-28). - Neuer UI-Sprachumschalter (Deutsch/Englisch) für die Bedienoberfläche: js/i18n/strings.js + js/i18n/i18n.js, Sprachwahl im Menü, Persistenz über settings.language, Retranslation ohne Reload. - Neuer Menüpunkt "Ausflugsziel übersetzen (KI)": erzeugt einen Prompt, der eine externe KI bittet, Name/Beschreibungen eines bestehenden Ortes ins Englische, Spanische oder Französische zu übersetzen (js/ai/translatePromptBuilder.js, js/ui/translatePromptGenerator.js). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,17 +76,31 @@ Abhängigkeiten zugreifen kann.
|
||||
Überschreibungen) und macht Abhängigkeiten weniger explizit als
|
||||
`import`-Statements – sie ergeben sich aus der Script-Reihenfolge in
|
||||
`index.html`, die entsprechend sorgfältig gepflegt werden muss.
|
||||
- **Behobenes Restrisiko:** Ursprünglich lud `js/store/store.js` die
|
||||
Beispieldaten per `fetch('data/seed.json')`, was unter `file://`
|
||||
- **Behobenes Restrisiko (2026-07-24):** Ursprünglich lud `js/store/store.js`
|
||||
die Beispieldaten per `fetch('data/seed.json')`, was unter `file://`
|
||||
(insbesondere in Chrome/Chromium) von der Same-Origin-Policy blockiert
|
||||
wird. Die Seed-Daten wurden daher von `data/seed.json` nach
|
||||
`data/seed.js` verschoben und liegen dort als eingebettetes
|
||||
`data/seed.js` verschoben und lagen dort als eingebettetes
|
||||
`<script>`-Objekt (`EventMap.data.SEED_PLACES`), das wie jede andere
|
||||
JS-Datei klassisch eingebunden wird. `initStore()` ist dadurch wieder
|
||||
synchron; `fetch()` kommt aktuell an keiner Stelle der Anwendung mehr
|
||||
vor. Für spätere Phasen (z.B. KI-JSON-Import) ist zu beachten: Datei-Uploads
|
||||
über `<input type="file">` + `FileReader` sind unproblematisch unter
|
||||
`file://`, ein `fetch()` auf lokale Dateien dagegen nicht.
|
||||
JS-Datei klassisch eingebunden wurde. `initStore()` war dadurch
|
||||
synchron. Für spätere Phasen (z.B. KI-JSON-Import) gilt weiterhin:
|
||||
Datei-Uploads über `<input type="file">` + `FileReader` sind
|
||||
unproblematisch unter `file://`, ein `fetch()` auf *lokale* Dateien
|
||||
dagegen nicht.
|
||||
- **Revision (2026-07-28):** `data/seed.js` wurde aus dem Repo entfernt.
|
||||
Die Beispieldaten werden jetzt beim allerersten Start per
|
||||
`fetch(EventMap.config.SEED_DATA_URL)` von einem externen, selbst
|
||||
gehosteten Server geladen (siehe `js/store/store.js`,
|
||||
`loadSeedPlaces()`/`initStore()`). Das ist kein Rückfall in das oben
|
||||
beschriebene Problem, da sich die Same-Origin-Blockade unter `file://`
|
||||
nur auf *lokale* Dateien bezieht – ein `fetch()` auf eine entfernte
|
||||
`https://`-URL funktioniert auch von `file://` aus, sofern der Server
|
||||
passende CORS-Header (`Access-Control-Allow-Origin`) sendet.
|
||||
`initStore()` ist dadurch wieder asynchron (`main.js` awaitet es
|
||||
bereits). Schlägt der Download fehl (offline, fehlende CORS-Header,
|
||||
Server nicht erreichbar), startet die App bewusst mit einer leeren
|
||||
Places-Liste und zeigt einen Hinweis im Status-Banner statt die
|
||||
gesamte Initialisierung abzubrechen.
|
||||
- Es gibt keinen automatischen Minify-/Tree-Shaking-Schritt; die
|
||||
Dateigröße im Produktivbetrieb ist etwas größer als mit Bundler, was für
|
||||
den Umfang dieser Anwendung akzeptabel ist.
|
||||
|
||||
+15
-12
@@ -33,7 +33,6 @@ js/models/ place.js (Normalisierung), schema.js (Feldstruktur/Defaults)
|
||||
js/map/ mapController.js, markers.js, geolocation.js
|
||||
js/ui/ list.js (Ergebnisliste; weitere UI-Module folgen in späteren Phasen)
|
||||
js/utils/ dom.js, geo.js, id.js
|
||||
data/seed.js Beispieldaten (10 Ausflugsziele, wird nur beim allerersten Start geladen)
|
||||
vendor/ lokal vendorte Leaflet-Bibliotheken (JS/CSS/Bildassets)
|
||||
docs/ dieser Plan, ADRs
|
||||
```
|
||||
@@ -53,8 +52,9 @@ aus `anforderung.md` (siehe dortiger Abschnitt "Vorgabe für das KI-JSON"):
|
||||
- `website`, `image`, `rating`, `tags[]`, `source`, `sourceVerified`
|
||||
- Intern generiert: `id` (UUID), `createdAt`, `updatedAt` (ISO-Strings)
|
||||
|
||||
`js/models/place.js` normalisiert rohe Objekte (aus `data/seed.js` oder späteren
|
||||
Importen) zu diesem vollständigen internen Format; die Kategorie wird dabei
|
||||
`js/models/place.js` normalisiert rohe Objekte (aus den per `EventMap.config.SEED_DATA_URL`
|
||||
nachgeladenen Beispieldaten oder späteren Importen) zu diesem vollständigen internen
|
||||
Format; die Kategorie wird dabei
|
||||
immer auf eine gültige Kategorie-`id` (Slug, siehe `js/config/categories.js`)
|
||||
aufgelöst – entweder direkt (falls schon ein Slug vorliegt) oder über das
|
||||
Label (z.B. `"Spielplatz"` → `spielplatz`), wie es die KI liefern würde.
|
||||
@@ -75,9 +75,12 @@ state = { places, filters: null, userLocation: null, selectedPlaceId: null }
|
||||
|
||||
- `subscribe(fn)` registriert Listener, `setState(patch)` merged den State und
|
||||
benachrichtigt alle Subscriber.
|
||||
- `initStore()` lädt beim Start persistierte Daten aus LocalStorage
|
||||
(`js/store/storage.js`). Ist noch nichts gespeichert, wird `data/seed.js`
|
||||
geladen, normalisiert und einmalig persistiert.
|
||||
- `initStore()` (async) lädt beim Start persistierte Daten aus LocalStorage
|
||||
(`js/store/storage.js`). Ist noch nichts gespeichert, werden die Beispieldaten
|
||||
per `fetch(EventMap.config.SEED_DATA_URL)` nachgeladen, normalisiert und
|
||||
einmalig persistiert. Schlägt der Download fehl (offline, CORS, Server nicht
|
||||
erreichbar), startet die App mit einer leeren Places-Liste und zeigt einen
|
||||
Hinweis im Status-Banner an, statt die Initialisierung abzubrechen.
|
||||
- Einstellungen (`lastFilters`, `lastMapView`, `userConsentGeo`, `defaultCenter`)
|
||||
werden getrennt über `getSettings()`/`updateSettings()` verwaltet und im
|
||||
Key `eventmap.settings.v1` persistiert.
|
||||
@@ -143,12 +146,12 @@ Die App verwendet klassische `<script>`-Tags statt ES-Module (siehe
|
||||
`index.html`** direkt aus dem lokal synchronisierten Ordner öffnen
|
||||
(`file://...`) – ein lokaler HTTP-Server ist dafür nicht mehr nötig.
|
||||
|
||||
Die Beispieldaten liegen in `data/seed.js` als eingebettetes
|
||||
`<script>`-Objekt (`EventMap.data.SEED_PLACES`) statt als `.json`-Datei,
|
||||
da `fetch()` auf lokale Dateien über `file://` in manchen Browsern
|
||||
(insbesondere Chrome/Chromium) blockiert wird. `initStore()` liest die
|
||||
Seed-Daten dadurch synchron direkt aus dem globalen Namespace, ganz ohne
|
||||
`fetch()`.
|
||||
Die Beispieldaten liegen nicht im Repo, sondern werden beim allerersten Start
|
||||
(leerer LocalStorage) per `fetch(EventMap.config.SEED_DATA_URL)` von einem
|
||||
externen Server geladen (siehe `docs/adr/0001-vanilla-esm.md`). Das
|
||||
funktioniert auch unter `file://`, da die Same-Origin-Blockade in Chrome/Chromium
|
||||
nur `fetch()` auf *lokale* Dateien betrifft, nicht auf entfernte `https://`-URLs
|
||||
(vorausgesetzt der Server sendet passende CORS-Header).
|
||||
|
||||
## Phasenübersicht
|
||||
|
||||
|
||||
Reference in New Issue
Block a user