From db710c43cf811e89ee493ae920b152cbde546f09 Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 6 Jul 2026 13:27:23 +0200 Subject: [PATCH] Asset-Inventar verlinkt Lieferanten/IT-Services ins Fach-Cockpit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Klick auf ein SUPPLIER-Asset öffnet /suppliers?detail=, ein IT_SERVICE-Asset /suppliers?tab=services&detail= statt der generischen Asset-Detailansicht - Routing ist profil-abhängig: nur Assets mit SupplierProfile/ITServiceProfile gehen ins Cockpit; profillose Alt-Assets (z. B. "Cloud-Hoster (IaaS)") bleiben in der normalen Asset-Detailansicht (kein Null-Zugriff auf refNo) - Direkte /assets?detail=/?edit=-Aufrufe solcher Assets werden serverseitig ins Cockpit umgeleitet, damit auch Links aus anderen Modulen dort landen Co-Authored-By: Claude Opus 4.8 --- src/app/(app)/assets/page.tsx | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/app/(app)/assets/page.tsx b/src/app/(app)/assets/page.tsx index bb05718..808722a 100644 --- a/src/app/(app)/assets/page.tsx +++ b/src/app/(app)/assets/page.tsx @@ -1,4 +1,5 @@ import Link from "next/link"; +import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { Plus, Search } from "lucide-react"; import type { AssetType } from "@prisma/client"; @@ -34,6 +35,22 @@ const ASSET_TYPES = ["INFORMATION", "SYSTEM", "APPLICATION", "LOCATION", "SUPPLI const STATUS_TONE = { ACTIVE: "ok", PLANNED: "info", RETIRED: "mut" } as const; +/** + * Lieferanten- und IT-Service-Assets werden in ihrem Fach-Cockpit geöffnet + * (sofern ein Fachprofil existiert), alle übrigen Assets in der normalen + * Asset-Detailansicht. + */ +function assetDetailHref(asset: { + id: string; + type: AssetType; + supplierProfile: { id: string } | null; + serviceProfile: { id: string } | null; +}) { + if (asset.type === "SUPPLIER" && asset.supplierProfile) return `/suppliers?detail=${asset.id}`; + if (asset.type === "IT_SERVICE" && asset.serviceProfile) return `/suppliers?tab=services&detail=${asset.id}`; + return `/assets?detail=${asset.id}`; +} + export default async function AssetsPage({ searchParams, }: { @@ -59,6 +76,8 @@ export default async function AssetsPage({ }, include: { owner: { select: { name: true } }, + supplierProfile: { select: { id: true } }, + serviceProfile: { select: { id: true } }, relationsFrom: { include: { relatedAsset: { select: { name: true } } }, take: 4, @@ -89,6 +108,8 @@ export default async function AssetsPage({ where: { id: modalId }, include: { owner: { select: { name: true } }, + supplierProfile: { select: { id: true } }, + serviceProfile: { select: { id: true } }, relationsFrom: { include: { relatedAsset: { @@ -112,6 +133,14 @@ export default async function AssetsPage({ }, }) : null; + + // Lieferanten/IT-Services im Fach-Cockpit öffnen, auch bei direktem Aufruf + // (nur wenn ein Fachprofil existiert; profillose Alt-Assets bleiben im Asset-Detail) + if (modalAsset && ((modalAsset.type === "SUPPLIER" && modalAsset.supplierProfile) || (modalAsset.type === "IT_SERVICE" && modalAsset.serviceProfile))) { + const base = modalAsset.type === "IT_SERVICE" ? "/suppliers?tab=services" : "/suppliers"; + redirect(`${base}${base.includes("?") ? "&" : "?"}${params.edit && canWrite ? "edit" : "detail"}=${modalAsset.id}`); + } + const users = canWrite && (params.edit || params.new) ? await db.user.findMany({ @@ -218,7 +247,7 @@ export default async function AssetsPage({ {assets.map((asset) => ( - + {asset.name}