feat(admin): clone layout with cells, labels, and display attachments

Adds Clone Layout button to layout edit page. Duplicates the layout
with all cells, label bindings, and display attachments. Name gets
"(copy)" suffix with dedup.
This commit is contained in:
Mitchell R 2026-05-21 12:04:11 +02:00
parent 991c2f0cd5
commit 0ae161173a
No known key found for this signature in database
2 changed files with 10 additions and 0 deletions

View file

@ -1093,6 +1093,13 @@ export function registerAdminRoutes(app: H3, deps: AdminDeps): void {
return new Response(null, { status: 302, headers: { location: `/admin/layouts/${layoutId}` } });
});
app.post("/admin/layouts/:id/clone", (event) => {
const id = Number(getRouterParam(event, "id"));
const clone = deps.repo.cloneLayout(id);
notifyKiosks();
return new Response(null, { status: 302, headers: { location: `/admin/layouts/${clone.id}` } });
});
app.post("/admin/layouts/:id/delete", (event) => {
const id = Number(getRouterParam(event, "id"));
deps.repo.deleteLayout(id);

View file

@ -2422,6 +2422,9 @@ export function LayoutEditPage(props: LayoutEditPageProps) {
<button type="submit" class="btn btn-primary">Save</button>
<a href="/admin/layouts" class="btn btn-ghost" style="margin-left:0.5rem">Back</a>
</form>
<form method="post" action={`/admin/layouts/${l.id}/clone`} style="display:inline-block; margin-top:0.5rem">
<button type="submit" class="btn btn-ghost">Clone Layout</button>
</form>
<div style="margin-top:1rem; color:#666; font-size:0.85rem">
<div>Grid: {String(gridCols)}x{String(gridRows)}, {String(cells.length)} cell{cells.length !== 1 ? "s" : ""}</div>
<div>