From c09093b572ef08c1db9a0a2b2309def70c83d555 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 14 Oct 2026 13:17:00 +0000 Subject: [PATCH] =?UTF-8?q?fix(portal):=20Modul-Kachel-Links=20dynamisch?= =?UTF-8?q?=20statt=20hartkodiertem=20localhost=20aufl=C3=B6sen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5 --- web/portal/app/ModuleGrid.test.tsx | 16 +++++++++++++++- web/portal/app/ModuleGrid.tsx | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/web/portal/app/ModuleGrid.test.tsx b/web/portal/app/ModuleGrid.test.tsx index e92ab96d..9910978a 100644 --- a/web/portal/app/ModuleGrid.test.tsx +++ b/web/portal/app/ModuleGrid.test.tsx @@ -1,5 +1,5 @@ import { describe, expect, it, vi } from "vitest"; -import { fetchVisibleModules } from "./ModuleGrid"; +import { fetchVisibleModules, resolveModuleHref } from "./ModuleGrid"; describe("fetchVisibleModules", () => { it("ruft die Portal-eigene Route mit tenant/role auf und gibt die Modulliste zurueck", async () => { @@ -22,3 +22,17 @@ describe("fetchVisibleModules", () => { expect(modules).toEqual([]); }); }); + +describe("resolveModuleHref", () => { + it("ersetzt localhost durch den echten Hostnamen", () => { + expect(resolveModuleHref("http://localhost:3107/", "192.168.1.204")).toBe("http://192.168.1.204:3107/"); + }); + + it("laesst Nicht-localhost-Hrefs unveraendert", () => { + expect(resolveModuleHref("http://dms.example.com:3107/", "192.168.1.204")).toBe("http://dms.example.com:3107/"); + }); + + it("laesst localhost unveraendert wenn das Portal selbst auf localhost laeuft", () => { + expect(resolveModuleHref("http://localhost:3107/", "localhost")).toBe("http://localhost:3107/"); + }); +}); diff --git a/web/portal/app/ModuleGrid.tsx b/web/portal/app/ModuleGrid.tsx index 1a0b3162..c28b7556 100644 --- a/web/portal/app/ModuleGrid.tsx +++ b/web/portal/app/ModuleGrid.tsx @@ -23,6 +23,21 @@ export async function fetchVisibleModules( return body.modules ?? []; } +export function resolveModuleHref( + href: string, + currentHostname: string = typeof window !== "undefined" ? window.location.hostname : "localhost" +): string { + try { + const url = new URL(href); + if (url.hostname === "localhost" && currentHostname !== "localhost") { + url.hostname = currentHostname; + } + return url.toString(); + } catch { + return href; + } +} + type State = | { status: "loading" } | { status: "error"; message: string } @@ -76,7 +91,7 @@ export function ModuleGrid() { {state.modules.map((mod) => (