Assets & Prozesse: Detail/Bearbeiten/Anlegen als Popups
- Wiederverwendbares, serverseitig gerendertes Modal (searchParams- gesteuert: ?detail= / ?edit= / ?new=1) — Browser-Zurück schließt, kein Client-State nötig - Assets: Read-only-Detail-Popup (Stammdaten, C/I/A, Abhängigkeiten, Prozesse, Risiken-Platzhalter), Bearbeiten-Popup (Formular + Abhängigkeiten verwalten + Löschen), Anlegen-Popup - Prozesse: "Bearbeiten" wechselt jetzt innerhalb des Popups in den Editiermodus (Stammdaten, Asset-Zuordnung, BIA, Löschen) statt auf die alte Detailseite zu springen; Anlegen ebenfalls als Popup - Server-Actions leiten auf die Popup-URLs zurück (Speichern im Bearbeiten-Popup → Detail-Popup; BIA-/Zuordnungs-Änderungen lassen das Popup offen); BIA-Formular remountet nach dem Speichern (key) - Alte Routen (/assets/[id], /assets/new, /processes/[id], …) leiten auf die Popup-URLs um Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,11 @@ import {
|
||||
Pill,
|
||||
Tag,
|
||||
} from "@/components/mockup-ui";
|
||||
import {
|
||||
AssetCreateModal,
|
||||
AssetDetailModal,
|
||||
AssetEditModal,
|
||||
} from "@/components/asset-modals";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -32,7 +37,7 @@ const STATUS_TONE = { ACTIVE: "ok", PLANNED: "info", RETIRED: "mut" } as const;
|
||||
export default async function AssetsPage({
|
||||
searchParams,
|
||||
}: {
|
||||
searchParams: Promise<{ q?: string; type?: string }>;
|
||||
searchParams: Promise<{ q?: string; type?: string; detail?: string; edit?: string; new?: string }>;
|
||||
}) {
|
||||
const session = await requireSession();
|
||||
requirePermission(session, "asset:read");
|
||||
@@ -41,7 +46,8 @@ export default async function AssetsPage({
|
||||
const tStatus = await getTranslations("assetStatus");
|
||||
const tc = await getTranslations("common");
|
||||
|
||||
const { q, type } = await searchParams;
|
||||
const params = await searchParams;
|
||||
const { q, type } = params;
|
||||
const activeType = ASSET_TYPES.includes(type as AssetType) ? (type as AssetType) : null;
|
||||
const db = dbForTenant(session.user.tenantId);
|
||||
|
||||
@@ -76,6 +82,36 @@ export default async function AssetsPage({
|
||||
|
||||
const canWrite = hasPermission(session, "asset:write");
|
||||
|
||||
// Popup-Zustand aus searchParams: ?detail= (read-only), ?edit=, ?new=1
|
||||
const modalId = params.edit && canWrite ? params.edit : params.detail;
|
||||
const modalAsset = modalId
|
||||
? await db.asset.findUnique({
|
||||
where: { id: modalId },
|
||||
include: {
|
||||
owner: { select: { name: true } },
|
||||
relationsFrom: { include: { relatedAsset: { select: { id: true, name: true } } } },
|
||||
relationsTo: { include: { asset: { select: { id: true, name: true } } } },
|
||||
processAssets: { include: { process: { select: { id: true, name: true } } } },
|
||||
},
|
||||
})
|
||||
: null;
|
||||
const users =
|
||||
canWrite && (params.edit || params.new)
|
||||
? await db.user.findMany({
|
||||
where: { status: "ACTIVE" },
|
||||
select: { id: true, name: true },
|
||||
orderBy: { name: "asc" },
|
||||
})
|
||||
: [];
|
||||
const otherAssets =
|
||||
canWrite && params.edit && modalAsset
|
||||
? await db.asset.findMany({
|
||||
where: { id: { not: modalAsset.id } },
|
||||
select: { id: true, name: true },
|
||||
orderBy: { name: "asc" },
|
||||
})
|
||||
: [];
|
||||
|
||||
const typeHref = (v: string | null) =>
|
||||
`/assets${v ? `?type=${v}` : ""}${q ? `${v ? "&" : "?"}q=${encodeURIComponent(q)}` : ""}`;
|
||||
|
||||
@@ -94,7 +130,7 @@ export default async function AssetsPage({
|
||||
{t("export")}
|
||||
</Button>
|
||||
{canWrite && (
|
||||
<Button nativeButton={false} render={<Link href="/assets/new" />}>
|
||||
<Button nativeButton={false} render={<Link href="/assets?new=1" />}>
|
||||
<Plus className="size-4" /> {t("newAsset")}
|
||||
</Button>
|
||||
)}
|
||||
@@ -167,7 +203,7 @@ export default async function AssetsPage({
|
||||
{assets.map((asset) => (
|
||||
<TableRow key={asset.id}>
|
||||
<TableCell>
|
||||
<Link href={`/assets/${asset.id}`} className="font-bold hover:underline">
|
||||
<Link href={`/assets?detail=${asset.id}`} className="font-bold hover:underline">
|
||||
{asset.name}
|
||||
</Link>
|
||||
</TableCell>
|
||||
@@ -193,6 +229,14 @@ export default async function AssetsPage({
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
{modalAsset && params.edit && canWrite ? (
|
||||
<AssetEditModal asset={modalAsset} users={users} otherAssets={otherAssets} />
|
||||
) : modalAsset ? (
|
||||
<AssetDetailModal asset={modalAsset} canWrite={canWrite} />
|
||||
) : params.new && canWrite ? (
|
||||
<AssetCreateModal users={users} />
|
||||
) : null}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user