diff --git a/.env.development b/.env.development index a79e5e979..d8fd1c42a 100644 --- a/.env.development +++ b/.env.development @@ -20,9 +20,8 @@ NEXT_PUBLIC_USE_MOCKS=true # Ein Unterordner in der dort hinter liegenden Ordnerstruktur (z.B. http://talasserver/talas5/nodemap/api/talas_v5_DB/ usw.) # kann bleiben da der Kunde diesen Unterordner talas:v5_db nicht ändert. #Füge in deiner .env.local Datei die folgende Zeile hinzu wenn du einen Unterordner verwenden möchtest mit entsprechende Bezeichnung. -# z.B. http://10.10.0.13/talas5/index.aspx -> NEXT_PUBLIC_BASE_PATH=/talas5 -# z.B. http://10.10.0.13/xyz/index.aspx -> NEXT_PUBLIC_BASE_PATH=/xyz -NEXT_PUBLIC_BASE_PATH=/talas5 -# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH= +# z.B. http://10.10.0.13/talas5/index.aspx -> basePath in config.json auf /talas5 setzen +# z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen +# basePath wird jetzt in public/config.json gepflegt # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.1.317 +NEXT_PUBLIC_APP_VERSION=1.1.318 diff --git a/.env.production b/.env.production index 4508d33ee..7a58ba5c9 100644 --- a/.env.production +++ b/.env.production @@ -20,10 +20,9 @@ NEXT_PUBLIC_USE_MOCKS=false # Ein Unterordner in der dort hinter liegenden Ordnerstruktur (z.B. http://talasserver/talas5/nodemap/api/talas_v5_DB/ usw.) # kann bleiben da der Kunde diesen Unterordner talas:v5_db nicht ändert. #Füge in deiner .env.local Datei die folgende Zeile hinzu wenn du einen Unterordner verwenden möchtest mit entsprechende Bezeichnung. -# z.B. http://10.10.0.13/talas5/index.aspx -> NEXT_PUBLIC_BASE_PATH=/talas5 -# z.B. http://10.10.0.13/xyz/index.aspx -> NEXT_PUBLIC_BASE_PATH=/xyz -NEXT_PUBLIC_BASE_PATH=/talas5 -# Oder leer lassen für direkten Zugriff -> NEXT_PUBLIC_BASE_PATH= +# z.B. http://10.10.0.13/talas5/index.aspx -> basePath in config.json auf /talas5 setzen +# z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen +# basePath wird jetzt in public/config.json gepflegt # App-Versionsnummer -NEXT_PUBLIC_APP_VERSION=1.1.317 +NEXT_PUBLIC_APP_VERSION=1.1.318 diff --git a/CHANGELOG.md b/CHANGELOG.md index 07ed13caa..21340c7d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -250,7 +250,7 @@ das Objekt selbst ### ♻️ Refactor - Alle hartkodierten `/talas5/`-Pfadangaben entfernt -- Dynamischer `basePath` eingeführt über `.env.local → NEXT_PUBLIC_BASE_PATH` +- Dynamischer `basePath` eingeführt über `public/config.json → basePath` - Unterstützt jetzt auch den Betrieb ohne Unterverzeichnis ### 🧠 Architektur diff --git a/config/paths.js b/config/paths.js index 31b2ab0da..27fa7c984 100644 --- a/config/paths.js +++ b/config/paths.js @@ -1,4 +1,11 @@ // config/paths.js -const basePathRaw = process.env.NEXT_PUBLIC_BASE_PATH || ""; -const BASE_PATH = basePathRaw.replace(/^\/|\/$/g, ""); -export const BASE_URL = BASE_PATH ? `/${BASE_PATH}` : ""; +let __configCache; +export async function getBaseUrl() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + const config = await res.json(); + const basePath = (config.basePath || "").replace(/^\/|\/$/g, ""); + __configCache = basePath ? `/${basePath}` : ""; + return __configCache; +} diff --git a/docs/architecture.md b/docs/architecture.md index 878c5c2f2..0607a1d55 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -87,7 +87,7 @@ sequenceDiagram - **Konfigurierbarer basePath:** - **Konfigurierbarer basePath:** - Pfad wie `/talas5` ist optional und kann per Umgebungsvariable `NEXT_PUBLIC_BASE_PATH` gesetzt + Pfad wie `/talas5` ist optional und wird jetzt in `public/config.json` als `basePath` gepflegt werden. Die Konfiguration erfolgt je nach Umgebung über: diff --git a/docs/config/paths.md b/docs/config/paths.md index 9d917df54..037355fbd 100644 --- a/docs/config/paths.md +++ b/docs/config/paths.md @@ -3,12 +3,12 @@ # 📁 paths.js Berechnet den sauberen `BASE_URL`-Pfad basierend auf `.env.production` oder -`.env.development → NEXT_PUBLIC_BASE_PATH`. +`public/config.json → basePath`. Entfernt führende und abschließende Slashes. ## Beispiel -Wenn `NEXT_PUBLIC_BASE_PATH = "/talas5/"`, wird `BASE_URL = "/talas5"` gesetzt. +Wenn `basePath = "/talas5/"` in config.json gesetzt ist, wird `BASE_URL = "/talas5"` verwendet. ```js const BASE_PATH = basePathRaw.replace(/^\/|\/$/g, ""); diff --git a/docs/guide/env.md b/docs/guide/env.md index b70b41321..69898c17a 100644 --- a/docs/guide/env.md +++ b/docs/guide/env.md @@ -12,17 +12,17 @@ NodeMap verwendet Umgebungsvariablen zur Steuerung von API-Verhalten, Serverpfad ## 🔧 Wichtige Variablen -| Variable | Beispielwert | Beschreibung | -| --------------------------- | ------------------- | --------------------------------------------------------------------- | -| `DB_HOST` | `localhost` | Adresse des Datenbankservers (MySQL) | -| `DB_PORT` | `3306` | Port für die Datenbankverbindung | -| `DB_NAME` | `talas` | Datenbankname | -| `DB_USER` | `root` | Benutzername für MySQL | -| `DB_PASSWORD` | `geheim` | Passwort für MySQL | -| `NEXT_PUBLIC_API_PORT_MODE` | `prod` oder `dev` | Steuert API-Routing bei Services (z. B. Portwechsel für lokal) | -| `NEXT_PUBLIC_USE_MOCKS` | `true` oder `false` | Aktiviert den Mockdaten-Modus über `/api/mocks/...` | -| `NEXT_PUBLIC_BASE_PATH` | `/talas5` oder leer | Optionaler Pfad, falls App unter Subpfad läuft (z. B. IIS) | -| `NEXT_PUBLIC_DEBUG` | `true` oder `false` | Aktiviert zusätzliche `console.log` Ausgaben für Debugging im Browser | +| Variable | Beispielwert | Beschreibung | +| --------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------- | +| `DB_HOST` | `localhost` | Adresse des Datenbankservers (MySQL) | +| `DB_PORT` | `3306` | Port für die Datenbankverbindung | +| `DB_NAME` | `talas` | Datenbankname | +| `DB_USER` | `root` | Benutzername für MySQL | +| `DB_PASSWORD` | `geheim` | Passwort für MySQL | +| `NEXT_PUBLIC_API_PORT_MODE` | `prod` oder `dev` | Steuert API-Routing bei Services (z. B. Portwechsel für lokal) | +| `NEXT_PUBLIC_USE_MOCKS` | `true` oder `false` | Aktiviert den Mockdaten-Modus über `/api/mocks/...` | +| `basePath` (in config.json) | `/talas5` oder leer | Optionaler Pfad, falls App unter Subpfad läuft (z. B. IIS). Wird jetzt in `public/config.json` gepflegt. | +| `NEXT_PUBLIC_DEBUG` | `true` oder `false` | Aktiviert zusätzliche `console.log` Ausgaben für Debugging im Browser | ## 📦 Beispiel `.env.production` @@ -34,7 +34,11 @@ DB_USER=root DB_PASSWORD=geheim NEXT_PUBLIC_API_PORT_MODE=prod NEXT_PUBLIC_USE_MOCKS=false -NEXT_PUBLIC_BASE_PATH=/talas5 +// public/config.json +{ + ... + "basePath": "/talas5" +} NEXT_PUBLIC_DEBUG=false ``` @@ -48,7 +52,11 @@ DB_USER=root DB_PASSWORD=geheim NEXT_PUBLIC_API_PORT_MODE=dev NEXT_PUBLIC_USE_MOCKS=true -NEXT_PUBLIC_BASE_PATH=/talas5 +// public/config.json +{ + ... + "basePath": "/talas5" +} NEXT_PUBLIC_DEBUG=true ``` diff --git a/package-lock.json b/package-lock.json index c73893d61..59c835ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "nodemap", - "version": "1.1.317", + "version": "1.1.318", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nodemap", - "version": "1.1.317", + "version": "1.1.318", "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", diff --git a/package.json b/package.json index 9e4f15e9e..f14fd24b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nodemap", - "version": "1.1.317", + "version": "1.1.318", "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", diff --git a/public/config.json b/public/config.json index 8f4b28924..97329c276 100644 --- a/public/config.json +++ b/public/config.json @@ -4,5 +4,6 @@ "local": "http://localhost/talas5/TileMap/mapTiles/{z}/{x}/{y}.png", "osm": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" }, - "active": "osm" + "active": "osm", + "basePath": "/talas5" } diff --git a/services/webservice/fetchGisLinesStatusService.js b/services/webservice/fetchGisLinesStatusService.js index 7a2216cb0..5c283f960 100644 --- a/services/webservice/fetchGisLinesStatusService.js +++ b/services/webservice/fetchGisLinesStatusService.js @@ -1,7 +1,17 @@ // /services/webservice/fetchGisLinesStatusService.js +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchGisLinesStatusService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisLinesStatus"; @@ -16,11 +26,9 @@ export const fetchGisLinesStatusService = async () => { } const mockData = await response.json(); - if (!Array.isArray(mockData.Statis)) { throw new Error("Ungültige Struktur: 'Status' fehlt im Mock"); } - return mockData.Statis; } else { const baseUrl = `${window.location.protocol}//${window.location.hostname}:80${basePath}/ClientData/WebServiceMap.asmx`; diff --git a/services/webservice/fetchGisStationsMeasurementsService.js b/services/webservice/fetchGisStationsMeasurementsService.js index 1e7efacb8..95c548fe6 100644 --- a/services/webservice/fetchGisStationsMeasurementsService.js +++ b/services/webservice/fetchGisStationsMeasurementsService.js @@ -1,6 +1,16 @@ +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchGisStationsMeasurementsService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisStationsMeasurements"; diff --git a/services/webservice/fetchGisStationsStaticDistrictService.js b/services/webservice/fetchGisStationsStaticDistrictService.js index 57054afb3..75b8043e3 100644 --- a/services/webservice/fetchGisStationsStaticDistrictService.js +++ b/services/webservice/fetchGisStationsStaticDistrictService.js @@ -5,9 +5,19 @@ * @returns {Promise} Liste mit Points[] * @throws {Error} bei Fehler oder ungültiger Antwortstruktur */ +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchGisStationsStaticDistrictService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisStationsStaticDistrict"; diff --git a/services/webservice/fetchGisStationsStatusDistrictService.js b/services/webservice/fetchGisStationsStatusDistrictService.js index 82d5e0d30..3bb03c83c 100644 --- a/services/webservice/fetchGisStationsStatusDistrictService.js +++ b/services/webservice/fetchGisStationsStatusDistrictService.js @@ -5,9 +5,19 @@ * @returns {Promise} Liste mit Statis[] * @throws {Error} bei Fehler oder ungültiger Antwortstruktur */ +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchGisStationsStatusDistrictService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisStationsStatusDistrict"; diff --git a/services/webservice/fetchGisSystemStaticService.js b/services/webservice/fetchGisSystemStaticService.js index 428b91c04..7d162f3d8 100644 --- a/services/webservice/fetchGisSystemStaticService.js +++ b/services/webservice/fetchGisSystemStaticService.js @@ -4,9 +4,19 @@ * @returns {Promise} Liste mit Systems[] * @throws {Error} bei Fehler oder ungültiger Antwortstruktur */ +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchGisSystemStaticService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisSystemStatic"; diff --git a/services/webservice/fetchUserRightsService.js b/services/webservice/fetchUserRightsService.js index 93fa0afb4..89fbc74e9 100644 --- a/services/webservice/fetchUserRightsService.js +++ b/services/webservice/fetchUserRightsService.js @@ -4,9 +4,19 @@ * @returns {Promise} Rechte-Array * @throws {Error} bei Lade- oder Strukturfehler */ +let __configCache; +async function getConfig() { + if (__configCache) return __configCache; + const res = await fetch("/config.json"); + if (!res.ok) throw new Error("config.json konnte nicht geladen werden"); + __configCache = await res.json(); + return __configCache; +} + export const fetchUserRightsService = async () => { const useMocks = process.env.NEXT_PUBLIC_USE_MOCKS === "true"; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + const config = await getConfig(); + const basePath = config.basePath || ""; if (useMocks) { const mockBasePath = "/api/mocks/webservice/gisSystemStatic"; diff --git a/utils/devices/createAndSetDevices.js b/utils/devices/createAndSetDevices.js index daa0240c4..23bc9bfee 100644 --- a/utils/devices/createAndSetDevices.js +++ b/utils/devices/createAndSetDevices.js @@ -35,7 +35,14 @@ export const createAndSetDevices = async ( setMarkersFunction([]); return; } - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + let basePath = ""; + try { + const res = await fetch("/config.json"); + if (res.ok) { + const config = await res.json(); + basePath = config.basePath || ""; + } + } catch (e) {} try { const state = store.getState(); diff --git a/utils/openInNewTab.js b/utils/openInNewTab.js index 2bb109ce9..202acffaa 100644 --- a/utils/openInNewTab.js +++ b/utils/openInNewTab.js @@ -1,7 +1,9 @@ // utils/openInNewTab.js -export function openInNewTab(e, target) { - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; +export async function openInNewTab(e, target) { + const res = await fetch("/config.json"); + const config = await res.json(); + const basePath = config.basePath || ""; const url = new URL(window.location.origin); const originWithoutPort = `${url.protocol}//${url.hostname}`; // ohne Port! diff --git a/utils/polylines/setupPolylines.js b/utils/polylines/setupPolylines.js index 4014ba702..30efa571c 100644 --- a/utils/polylines/setupPolylines.js +++ b/utils/polylines/setupPolylines.js @@ -17,7 +17,7 @@ import { updatePolylineCoordinatesThunk } from "../../redux/thunks/database/poly import { openInNewTab } from "../../utils/openInNewTab"; //-------------------------------------------- -export const setupPolylines = ( +export const setupPolylines = async ( map, linePositions, lineColors, @@ -29,7 +29,14 @@ export const setupPolylines = ( polylineVisible ) => { const mode = process.env.NEXT_PUBLIC_API_PORT_MODE; - const basePath = process.env.NEXT_PUBLIC_BASE_PATH || ""; + let basePath = ""; + try { + const res = await fetch("/config.json"); + if (res.ok) { + const config = await res.json(); + basePath = config.basePath || ""; + } + } catch (e) {} if (!polylineVisible) { //console.warn("Polylines deaktiviert - keine Zeichnung"); return { markers: [], polylines: [] };