feat(network): draw.io XML import

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-14 01:30:22 +00:00
parent 2a4220b496
commit 91cc9a4170
4 changed files with 240 additions and 1 deletions

View File

@@ -40,6 +40,7 @@ export default function NetworkDiagramsPage() {
const [menuOpenId, setMenuOpenId] = useState<string | null>(null)
const [confirmArchiveId, setConfirmArchiveId] = useState<string | null>(null)
const clientDropdownRef = useRef<HTMLDivElement>(null)
const drawioListImportRef = useRef<HTMLInputElement>(null)
useEffect(() => {
if (!clientDropdownOpen) return
@@ -129,6 +130,35 @@ export default function NetworkDiagramsPage() {
input.click()
}, [navigate])
const handleListDrawioImport = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (!file) return
e.target.value = ''
try {
const { parseDrawioXml } = await import('@/lib/drawio-import')
const text = await file.text()
const { nodes: importedNodes, edges: importedEdges, warnings } = parseDrawioXml(text)
const result = await networkDiagramsApi.importJson({
schemaVersion: 1,
name: file.name.replace(/\.drawio$/i, '') || 'Imported Diagram',
client_name: null,
description: null,
nodes: importedNodes,
edges: importedEdges,
})
const allWarnings = [...warnings, ...result.warnings]
if (allWarnings.length > 0) {
toast.warning(`Imported with ${allWarnings.length} warning(s)`)
} else {
toast.success('Imported successfully')
}
navigate(`/network-diagrams/${result.diagram.id}`)
} catch (err) {
const msg = err instanceof Error ? err.message : 'Unknown error'
toast.error(`Import failed: ${msg}`)
}
}, [navigate])
const formatDate = (dateStr: string) => {
return new Date(dateStr).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })
}
@@ -148,6 +178,20 @@ export default function NetworkDiagramsPage() {
<Upload size={14} />
Import
</button>
<input
ref={drawioListImportRef}
type="file"
accept=".drawio,.xml"
className="hidden"
onChange={handleListDrawioImport}
/>
<button
onClick={() => drawioListImportRef.current?.click()}
className="flex items-center gap-1.5 rounded border border-default px-3 py-2 text-sm text-primary hover:border-hover"
>
<Upload size={14} />
Import draw.io
</button>
<button
onClick={() => navigate('/network-diagrams/new')}
className="flex items-center gap-1.5 rounded bg-accent px-4 py-2 text-sm font-medium text-white hover:bg-accent/90"