Die Vorlagen-Logik aus #019 war bisher nur per Seed und Service erreichbar. Admins koennen eigene Vorlagen jetzt anlegen, eingebaute anpassen und eigene archivieren; jede Rolle sieht die Liste, weil Operatoren die Vorlagen im Assistenten wiedererkennen sollen. Die Vorschau nutzt im Browser dieselben reinen Funktionen wie der Server (platzhalterErsetzen, optionenPruefen, sudoersInhalt). So sieht der Admin vor dem Speichern, was in authorized_keys, ~/.ssh/config und sudoers landen wuerde; verbindlich prueft weiterhin der Server. Voller sudo-Zugang bekommt einen deutlichen Hinweis, weil er root gleichkommt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { Archive } from "lucide-react";
|
|
import { useActionState, useRef } from "react";
|
|
import { Button, Formularfehler } from "@/components/ui";
|
|
import type { FormularZustand } from "@/server/actions/formular";
|
|
import { vorlageArchivierenAktion } from "@/server/actions/vorlagen";
|
|
|
|
/** Archivieren mit Rueckfrage (#019), gleiches Muster wie bei Hosts (#008). */
|
|
export function VorlageArchivierenDialog({ vorlageId, name }: { vorlageId: string; name: string }) {
|
|
const dialog = useRef<HTMLDialogElement>(null);
|
|
const [zustand, aktion, laeuft] = useActionState<FormularZustand, FormData>(vorlageArchivierenAktion, {});
|
|
|
|
return (
|
|
<>
|
|
<Button
|
|
variante="gefahr"
|
|
icon={<Archive className="size-4" />}
|
|
onClick={() => dialog.current?.showModal()}
|
|
>
|
|
Vorlage archivieren
|
|
</Button>
|
|
<dialog
|
|
ref={dialog}
|
|
aria-labelledby="archivieren-titel"
|
|
className="border-border-strong bg-surface text-text rounded-karte m-auto w-[calc(100%-32px)] max-w-md border p-5 backdrop:bg-black/70 sm:p-6"
|
|
>
|
|
<form action={aktion} className="flex flex-col gap-4">
|
|
<input type="hidden" name="id" value={vorlageId} />
|
|
<h2 id="archivieren-titel" className="text-[17px] font-semibold">
|
|
„{name}“ archivieren?
|
|
</h2>
|
|
<p className="text-muted text-[14.5px]">
|
|
Die Vorlage steht im Assistenten nicht mehr zur Auswahl. Schlüssel, die mit ihr angelegt wurden,
|
|
bleiben unverändert; das Protokoll bleibt erhalten.
|
|
</p>
|
|
<Formularfehler text={zustand.fehler} />
|
|
<div className="flex flex-wrap justify-end gap-2.5">
|
|
<Button onClick={() => dialog.current?.close()}>Abbrechen</Button>
|
|
<Button type="submit" variante="gefahr" disabled={laeuft}>
|
|
{laeuft ? "Archiviere …" : "Archivieren"}
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</dialog>
|
|
</>
|
|
);
|
|
}
|