fix(ui): сохранять контекст экспорта сертификатов IPsec
This commit is contained in:
1 parent
86ecf764ff
commit
74e7cd257d
7 files changed
+151
-67
No files matched your search
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
|
||||
import { IPSEC_MIN_PASSPHRASE, type IpsecCertBundle } from "@mmapp/contracts/ipsec"
|
||||
import { FormField, SectionTitle } from "@/components/form-kit"
|
||||
import { Button } from "@/components/ui/button"
|
||||
@@ -46,27 +46,19 @@ function IpsecCertSheet({
|
||||
onOpenChange,
|
||||
bundle,
|
||||
busy,
|
||||
error,
|
||||
onReexport,
|
||||
}: {
|
||||
open: boolean
|
||||
onOpenChange: (v: boolean) => void
|
||||
bundle: IpsecCertBundle | null
|
||||
busy?: boolean
|
||||
error?: string | null
|
||||
/** Перекачка с новой passphrase (серийник ключа остаётся на роутере). */
|
||||
onReexport?: (passphrase: string) => void | Promise<void>
|
||||
}) {
|
||||
const [passphrase, setPassphrase] = useState("")
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return
|
||||
const initial = bundle?.passphrase ?? ""
|
||||
queueMicrotask(() => setPassphrase(initial))
|
||||
}, [open, bundle])
|
||||
|
||||
const canDownload = useMemo(
|
||||
() => Boolean(bundle && passphrase.trim().length >= IPSEC_MIN_PASSPHRASE),
|
||||
[bundle, passphrase],
|
||||
)
|
||||
const passphrase = bundle?.passphrase ?? ""
|
||||
const canDownload = Boolean(bundle && !busy && passphrase.trim().length >= IPSEC_MIN_PASSPHRASE)
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={onOpenChange}>
|
||||
@@ -79,10 +71,10 @@ function IpsecCertSheet({
|
||||
</SheetHeader>
|
||||
|
||||
<div className="flex-1 min-w-0 overflow-y-auto overflow-x-hidden px-6 py-5 flex flex-col gap-5">
|
||||
{busy && <p role="status" className="text-sm text-muted-foreground">Загрузка сертификата…</p>}
|
||||
{error && <p role="alert" className="text-sm text-destructive">{error}</p>}
|
||||
{!bundle ? (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Бандл сертификата пуст — перезапустите экспорт с новой парольной фразой.
|
||||
</p>
|
||||
!busy && onReexport ? <Button variant="outline" onClick={() => void onReexport(randomPassphrase())}>Повторить экспорт</Button> : null
|
||||
) : (
|
||||
<>
|
||||
<div className="flex flex-col gap-4">
|
||||
@@ -100,17 +92,18 @@ function IpsecCertSheet({
|
||||
<Input
|
||||
className="font-mono"
|
||||
value={passphrase}
|
||||
onChange={(e) => setPassphrase(e.target.value)}
|
||||
readOnly
|
||||
aria-label="Пароль архива .p12"
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
variant="outline"
|
||||
title="Сгенерировать и перекачать"
|
||||
disabled={busy}
|
||||
aria-label="Сгенерировать и перекачать"
|
||||
disabled={busy || !onReexport}
|
||||
onClick={() => {
|
||||
const next = randomPassphrase()
|
||||
setPassphrase(next)
|
||||
if (onReexport) void onReexport(next)
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in new issue
Block a user