Lieferanten-/IT-Service-Cockpit direkt auf der Asset-Seite öffnen
Statt beim Klick auf ein Lieferanten-/IT-Service-Asset zur Lieferanten-Seite zu wechseln, wird das Fach-Cockpit jetzt als Popup auf /assets gerendert; Schließen, Bearbeiten, Speichern und Löschen bleiben auf der Asset-Seite. - backHref-Prop an SupplierDetail/Edit- und ServiceDetail/Edit-Modal: alle Schließen-/Bearbeiten-/Abbrechen-Links leiten sich davon ab (Default /suppliers) - withQuery-Helper (lib/supplier) für korrekte ?/&-Verkettung - updateSupplier/updateService lesen returnTo (verstecktes Feld) und leiten dorthin zurück; deleteSupplier/deleteService bekommen returnTo-Parameter - Kind-Actions revalidieren zusätzlich /assets, damit das Popup dort aktuell bleibt - SUPPLIER_INCLUDE/SERVICE_INCLUDE in lib/supplier-include ausgelagert und von beiden Seiten genutzt - assets/page.tsx bestimmt die Popup-Art vorab (supplier/service/asset) und rendert das passende Cockpit mit backHref="/assets"; profillose Alt-Assets bleiben Assets Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { requireSession } from "@/server/auth";
|
||||
import { dbForTenant, prisma } from "@/server/db";
|
||||
import { requirePermission } from "@/server/rbac";
|
||||
import { writeAuditLog } from "@/server/audit";
|
||||
import { withQuery } from "@/lib/supplier";
|
||||
|
||||
const level = z.coerce.number().int().min(1).max(4);
|
||||
|
||||
@@ -73,10 +74,11 @@ export async function updateService(assetId: string, formData: FormData) {
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "it_service", entityId: assetId, before, after: { ...asset, ...profile } });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
redirect(`/suppliers?tab=services&detail=${assetId}`);
|
||||
const returnTo = (formData.get("returnTo") as string) || "/suppliers?tab=services";
|
||||
redirect(withQuery(returnTo, "detail", assetId));
|
||||
}
|
||||
|
||||
export async function deleteService(assetId: string) {
|
||||
export async function deleteService(assetId: string, returnTo: string = "/suppliers?tab=services") {
|
||||
const session = await requireSession();
|
||||
requirePermission(session, "supplier:write");
|
||||
const db = dbForTenant(session.user.tenantId);
|
||||
@@ -86,7 +88,7 @@ export async function deleteService(assetId: string) {
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "delete", entity: "it_service", entityId: assetId, before });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
redirect("/suppliers?tab=services");
|
||||
redirect(returnTo);
|
||||
}
|
||||
|
||||
export async function addRaci(assetId: string, formData: FormData) {
|
||||
@@ -107,6 +109,7 @@ export async function addRaci(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "service_raci", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
/** Verantwortung einer RACI-Zeile per Klick ändern (PROVIDER/US/SHARED durchschalten). */
|
||||
@@ -120,6 +123,7 @@ export async function cycleRaci(assetId: string, raciId: string) {
|
||||
await db.serviceControlResponsibility.update({ where: { id: raciId }, data: { responsibility: next[row.responsibility] } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "service_raci", entityId: assetId, after: { responsibility: next[row.responsibility] } });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function deleteRaci(assetId: string, raciId: string) {
|
||||
@@ -129,4 +133,5 @@ export async function deleteRaci(assetId: string, raciId: string) {
|
||||
await db.serviceControlResponsibility.delete({ where: { id: raciId } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "delete", entity: "service_raci", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { requireSession } from "@/server/auth";
|
||||
import { dbForTenant, prisma } from "@/server/db";
|
||||
import { requirePermission } from "@/server/rbac";
|
||||
import { writeAuditLog } from "@/server/audit";
|
||||
import { withQuery } from "@/lib/supplier";
|
||||
|
||||
const level = z.coerce.number().int().min(1).max(4);
|
||||
|
||||
@@ -110,10 +111,11 @@ export async function updateSupplier(assetId: string, formData: FormData) {
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "supplier", entityId: assetId, before, after: { ...asset, ...profile } });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
redirect(`/suppliers?detail=${assetId}`);
|
||||
const returnTo = (formData.get("returnTo") as string) || "/suppliers";
|
||||
redirect(withQuery(returnTo, "detail", assetId));
|
||||
}
|
||||
|
||||
export async function deleteSupplier(assetId: string) {
|
||||
export async function deleteSupplier(assetId: string, returnTo: string = "/suppliers") {
|
||||
const session = await requireSession();
|
||||
requirePermission(session, "supplier:write");
|
||||
const db = dbForTenant(session.user.tenantId);
|
||||
@@ -123,7 +125,7 @@ export async function deleteSupplier(assetId: string) {
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "delete", entity: "supplier", entityId: assetId, before });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
redirect("/suppliers");
|
||||
redirect(returnTo);
|
||||
}
|
||||
|
||||
async function ensure(session: Awaited<ReturnType<typeof requireSession>>, assetId: string) {
|
||||
@@ -154,6 +156,7 @@ export async function addContract(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "contract", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function addNda(assetId: string, formData: FormData) {
|
||||
@@ -174,6 +177,7 @@ export async function addNda(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "nda", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function addEvidence(assetId: string, formData: FormData) {
|
||||
@@ -193,6 +197,7 @@ export async function addEvidence(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "supplier_evidence", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function addAssessment(assetId: string, formData: FormData) {
|
||||
@@ -212,6 +217,7 @@ export async function addAssessment(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "supplier_assessment", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function addDecision(assetId: string, formData: FormData) {
|
||||
@@ -230,6 +236,7 @@ export async function addDecision(assetId: string, formData: FormData) {
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "create", entity: "management_decision", entityId: assetId });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
/** Gate-Kompensation: echtes Risiko im Risikomodul anlegen und mit dem Lieferanten verknüpfen. */
|
||||
@@ -282,6 +289,7 @@ export async function approveMaturity(assetId: string, computed: number, formDat
|
||||
});
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "update", entity: "maturity_assessment", entityId: assetId, after: { computed, isbValue, justification } });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
export async function deleteChild(
|
||||
@@ -303,4 +311,5 @@ export async function deleteChild(
|
||||
await map[kind].delete({ where: { id } });
|
||||
await writeAuditLog({ tenantId: session.user.tenantId, actorId: session.user.id, action: "delete", entity: `supplier_${kind}`, entityId: id });
|
||||
revalidatePath("/suppliers");
|
||||
revalidatePath("/assets");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user