fix(ui): выровнять экспорт WireGuard под ReUI Frame
Убрать дубль копирования, вынести CodeExportSheet и семантические токены. Открывать вкладку Peer при экспорте пира. Мигрировать VXLAN/Firewall/Containers/GRE. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -34,12 +34,13 @@ import { cn } from "@/lib/utils"
|
||||
import {
|
||||
PlusIcon, SearchIcon, ShieldIcon, ShieldOffIcon,
|
||||
ListFilterIcon, ArrowRightLeftIcon, WrenchIcon, LayersIcon,
|
||||
MoreHorizontalIcon, PencilIcon, Trash2Icon, CopyIcon, CodeXmlIcon,
|
||||
CheckIcon, PowerIcon, CheckCircleIcon,
|
||||
MoreHorizontalIcon, PencilIcon, Trash2Icon, CodeXmlIcon,
|
||||
PowerIcon, CheckCircleIcon,
|
||||
PlayIcon, SquareIcon, RotateCcwIcon, ZapIcon,
|
||||
CheckCircle2Icon, XCircleIcon, MinusCircleIcon, SkipForwardIcon,
|
||||
SlidersHorizontalIcon,
|
||||
} from "lucide-react"
|
||||
import { CodeExportSheet } from "@/components/reui-kit/code-export-sheet"
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -602,68 +603,28 @@ function RuleSheet({ open, onClose, initialRule, chainGroup }: {
|
||||
function ExportSheet({ open, onClose, rules }: {
|
||||
open: boolean; onClose: () => void; rules: FirewallRule[]
|
||||
}) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
// Derived from open — new timestamp each time modal opens, undefined when closed
|
||||
const timestamp = useMemo(
|
||||
() => open ? new Date().toLocaleString("ru") : undefined,
|
||||
[open],
|
||||
[open],
|
||||
)
|
||||
|
||||
const code = useMemo(() => generateRsc(rules, timestamp), [rules, timestamp])
|
||||
|
||||
function handleCopy() {
|
||||
const full = generateRsc(rules, new Date().toLocaleString("ru"))
|
||||
navigator.clipboard.writeText(full).then(() => {
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={(v) => { if (!v) onClose() }}>
|
||||
<SheetContent className="flex flex-col overflow-hidden p-0 gap-0 sm:max-w-2xl">
|
||||
<SheetHeader className="shrink-0 px-6 pt-5 pb-4 border-b">
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div>
|
||||
<SheetTitle>Экспорт Firewall</SheetTitle>
|
||||
<SheetDescription>RouterOS .rsc · /ip firewall filter, nat, mangle</SheetDescription>
|
||||
</div>
|
||||
<Button variant="outline" size="sm" className="shrink-0" onClick={handleCopy}>
|
||||
{copied
|
||||
? <><CheckIcon className="size-3.5 text-emerald-500" />Скопировано</>
|
||||
: <><CopyIcon className="size-3.5" />Копировать</>}
|
||||
</Button>
|
||||
</div>
|
||||
</SheetHeader>
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<pre className="px-6 py-5 text-[12px] font-mono leading-relaxed text-foreground/85 whitespace-pre select-all">
|
||||
{code.split("\n").map((line, i) => {
|
||||
const isComment = line.startsWith("#")
|
||||
const isSection = isComment && line.includes("──")
|
||||
const isKey = /^\s+[a-z]/.test(line)
|
||||
return (
|
||||
<span key={i} className={
|
||||
isSection ? "text-muted-foreground/50"
|
||||
: isComment ? "text-muted-foreground"
|
||||
: isKey ? "text-sky-400/90"
|
||||
: "text-foreground"
|
||||
}>
|
||||
{line}{"\n"}
|
||||
</span>
|
||||
)
|
||||
})}
|
||||
</pre>
|
||||
</div>
|
||||
<SheetFooter className="shrink-0 px-6 py-4 border-t flex-row gap-2">
|
||||
<SheetClose render={<Button variant="outline" className="flex-1" />}>Закрыть</SheetClose>
|
||||
<Button className="flex-1" onClick={handleCopy}>
|
||||
{copied ? <CheckIcon className="size-4" /> : <CopyIcon className="size-4" />}
|
||||
{copied ? "Скопировано" : "Копировать .rsc"}
|
||||
</Button>
|
||||
</SheetFooter>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
<CodeExportSheet
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
title="Экспорт Firewall"
|
||||
description="RouterOS .rsc · /ip firewall filter, nat, mangle"
|
||||
formats={[
|
||||
{
|
||||
id: "rsc",
|
||||
label: "MikroTik .rsc",
|
||||
filename: `firewall-${new Date().toISOString().slice(0, 10)}.rsc`,
|
||||
code,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user