Asset-Inventar verlinkt Lieferanten/IT-Services ins Fach-Cockpit

- 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 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 13:27:23 +02:00
co-authored by Claude Opus 4.8
parent ee4e554554
commit db710c43cf
+30 -1
View File
@@ -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) => (
<TableRow key={asset.id}>
<TableCell>
<Link href={`/assets?detail=${asset.id}`} className="font-bold hover:underline">
<Link href={assetDetailHref(asset)} className="font-bold hover:underline">
{asset.name}
</Link>
</TableCell>