import Link from "next/link"; import { getTranslations } from "next-intl/server"; import { Plus } from "lucide-react"; import { requireSession } from "@/server/auth"; import { dbForTenant } from "@/server/db"; import { hasPermission, requirePermission } from "@/server/rbac"; import { Button } from "@/components/ui/button"; import { CriticalityPill, PageHead, SectTitle, Tag } from "@/components/mockup-ui"; import { ProcessCreateModal, ProcessDetailModal, ProcessEditModal, } from "@/components/process-modals"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; const PROCESS_INCLUDE = { owner: { select: { name: true } }, bia: true, processAssets: { include: { asset: { select: { id: true, name: true, type: true, confidentiality: true, integrity: true, availability: true, owner: { select: { name: true } }, }, }, }, }, } as const; export default async function ProcessesPage({ searchParams, }: { searchParams: Promise<{ detail?: string; edit?: string; new?: string }>; }) { const session = await requireSession(); requirePermission(session, "bia:read"); const t = await getTranslations("processes"); const tAssets = await getTranslations("assets"); const tCrit = await getTranslations("criticality"); const tCat = await getTranslations("processCategory"); const tc = await getTranslations("common"); const params = await searchParams; const db = dbForTenant(session.user.tenantId); const canWrite = hasPermission(session, "bia:write"); const processes = await db.process.findMany({ include: { owner: { select: { name: true } }, bia: { select: { criticality: true, rtoHours: true, rpoHours: true, mtdHours: true } }, }, orderBy: { name: "asc" }, take: 200, }); // Popup-Zustand aus searchParams: ?detail= (read-only), ?edit=, ?new=1 const modalId = params.edit && canWrite ? params.edit : params.detail; const modalProcess = modalId ? await db.process.findUnique({ where: { id: modalId }, include: PROCESS_INCLUDE }) : null; const users = canWrite && (params.edit || params.new) ? await db.user.findMany({ where: { status: "ACTIVE" }, select: { id: true, name: true }, orderBy: { name: "asc" }, }) : []; // Zugeordnete Risiken: direkt am Prozess ODER an einem seiner Assets const modalRisks = modalProcess ? await db.risk.findMany({ where: { OR: [ { processId: modalProcess.id }, { riskAssets: { some: { assetId: { in: modalProcess.processAssets.map((pa) => pa.assetId) } } } }, ], }, select: { id: true, refNo: true, title: true, score: true }, orderBy: { score: "desc" }, }) : []; const availableAssets = canWrite && params.edit && modalProcess ? await db.asset.findMany({ where: { id: { notIn: modalProcess.processAssets.map((pa) => pa.assetId) } }, select: { id: true, name: true }, orderBy: { name: "asc" }, }) : []; const hours = (v: number | null | undefined) => (v != null ? `${v} h` : tc("none")); return (
{canWrite && ( )} } />
{t("process")} {t("category")} {t("owner")} RTO RPO MTD {t("criticality")} {processes.length === 0 && ( {t("empty")} )} {processes.map((process) => ( {process.name} {tCat(process.category)} {process.owner?.name ?? tc("none")} {hours(process.bia?.rtoHours)} {hours(process.bia?.rpoHours)} {hours(process.bia?.mtdHours)} {process.bia ? ( ) : ( {t("noBia")} )} ))}
{modalProcess && params.edit && canWrite ? ( ) : modalProcess ? ( ) : params.new && canWrite ? ( ) : null}
); }