feat(network): add undo/redo buttons to DiagramHeader

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-04-13 20:04:58 +00:00
parent b9c9bb548d
commit a392d24101
2 changed files with 47 additions and 24 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useCallback, useRef, useEffect } from 'react' import { useState, useCallback, useRef, useEffect } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { ChevronLeft, Save, Download, FileJson, Image, FileText } from 'lucide-react' import { ChevronLeft, Save, Download, FileJson, Image, FileText, Undo2, Redo2 } from 'lucide-react'
interface DiagramHeaderProps { interface DiagramHeaderProps {
name: string name: string
@@ -14,6 +14,10 @@ interface DiagramHeaderProps {
onExportPng: () => void onExportPng: () => void
onExportPdf: () => void onExportPdf: () => void
onExportJson: () => void onExportJson: () => void
onUndo: () => void
onRedo: () => void
canUndo: boolean
canRedo: boolean
} }
export function DiagramHeader({ export function DiagramHeader({
@@ -28,6 +32,10 @@ export function DiagramHeader({
onExportPng, onExportPng,
onExportPdf, onExportPdf,
onExportJson, onExportJson,
onUndo,
onRedo,
canUndo,
canRedo,
}: DiagramHeaderProps) { }: DiagramHeaderProps) {
const navigate = useNavigate() const navigate = useNavigate()
const [editing, setEditing] = useState(false) const [editing, setEditing] = useState(false)
@@ -88,6 +96,27 @@ export function DiagramHeader({
<div className="mx-2 h-5 w-px bg-border-default" /> <div className="mx-2 h-5 w-px bg-border-default" />
<div className="flex items-center gap-1">
<button
onClick={onUndo}
disabled={!canUndo}
title="Undo (Ctrl+Z)"
className="p-1.5 rounded text-muted-foreground hover:text-primary hover:bg-elevated disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
>
<Undo2 size={16} />
</button>
<button
onClick={onRedo}
disabled={!canRedo}
title="Redo (Ctrl+Y)"
className="p-1.5 rounded text-muted-foreground hover:text-primary hover:bg-elevated disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
>
<Redo2 size={16} />
</button>
</div>
<div className="mx-2 h-5 w-px bg-border-default" />
{editing ? ( {editing ? (
<input <input
ref={inputRef} ref={inputRef}

View File

@@ -628,29 +628,23 @@ function DiagramEditorInner() {
return ( return (
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
{(() => { <DiagramHeader
// eslint-disable-next-line @typescript-eslint/no-explicit-any name={name}
const DiagramHeaderAny = DiagramHeader as any clientName={clientName}
return ( isDirty={isDirty}
<DiagramHeaderAny isSaving={isSaving}
name={name} lastSavedAt={lastSavedAt}
clientName={clientName} diagramId={diagramId}
isDirty={isDirty} onNameChange={(n: string) => { setName(n); setIsDirty(true) }}
isSaving={isSaving} onSave={handleSave}
lastSavedAt={lastSavedAt} onExportPng={handleExportPng}
diagramId={diagramId} onExportPdf={handleExportPdf}
onNameChange={(n: string) => { setName(n); setIsDirty(true) }} onExportJson={handleExportJson}
onSave={handleSave} onUndo={undo}
onExportPng={handleExportPng} onRedo={redo}
onExportPdf={handleExportPdf} canUndo={canUndo}
onExportJson={handleExportJson} canRedo={canRedo}
onUndo={undo} />
onRedo={redo}
canUndo={canUndo}
canRedo={canRedo}
/>
)
})()}
<div className="flex flex-1 min-h-0"> <div className="flex flex-1 min-h-0">
<DeviceToolbar deviceTypes={deviceTypes} onDeviceTypesChange={loadDeviceTypes} /> <DeviceToolbar deviceTypes={deviceTypes} onDeviceTypesChange={loadDeviceTypes} />
<div className="flex flex-1 flex-col min-h-0"> <div className="flex flex-1 flex-col min-h-0">