improvements
This commit is contained in:
61
src/App.tsx
61
src/App.tsx
@@ -33,7 +33,7 @@ import {
|
||||
} from "@/components/ui/context-menu"
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { ClipboardPaste, Code2, Moon, ScrollText, Sparkles, Sun, Variable } from 'lucide-react'
|
||||
import { DEFAULT_NODE_STYLE, genId, getDefaultDataForType } from './lib/flowUtils'
|
||||
import { DEFAULT_NODE_STYLE, getDefaultDataForType, getNextNodeId } from './lib/flowUtils'
|
||||
|
||||
const SNAP_GRID: [number, number] = [15, 15]
|
||||
const snapToGrid = (x: number, y: number): { x: number; y: number } => ({
|
||||
@@ -43,23 +43,23 @@ const snapToGrid = (x: number, y: number): { x: number; y: number } => ({
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{
|
||||
id: 'config-1',
|
||||
id: 'cfg_001',
|
||||
position: { x: 50, y: 50 },
|
||||
data: { plantuml: '@startuml\nactor User\nparticipant "Render" as R\nUser -> R : config\n@enduml\n' },
|
||||
data: { plantuml: '@startuml\nactor User\nparticipant "Render" as R\nUser -> R : config\n@enduml\n', title: 'config-cfg_001' },
|
||||
type: 'config',
|
||||
style: DEFAULT_NODE_STYLE.config,
|
||||
},
|
||||
{
|
||||
id: 'render-1',
|
||||
id: 'rnd_001',
|
||||
position: { x: 350, y: 80 },
|
||||
data: {},
|
||||
type: 'render',
|
||||
style: DEFAULT_NODE_STYLE.render,
|
||||
},
|
||||
].map((n) => ({ ...n, id: n.id ?? genId() }))
|
||||
]
|
||||
|
||||
const initialEdges: Edge[] = [
|
||||
{ id: 'e-config-render', source: 'config-1', target: 'render-1', type: 'animated' },
|
||||
{ id: 'e-cfg_001-rnd_001', source: 'cfg_001', target: 'rnd_001', type: 'animated' },
|
||||
]
|
||||
|
||||
export default function App() {
|
||||
@@ -67,6 +67,7 @@ export default function App() {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes)
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges)
|
||||
const [rfInstance, setRfInstance] = React.useState<any | null>(null)
|
||||
const [renamingNodeId, setRenamingNodeId] = React.useState<string | null>(null)
|
||||
|
||||
const wrapperRef = React.useRef<HTMLDivElement | null>(null)
|
||||
const lastClickRef = React.useRef<{ clientX: number; clientY: number } | null>(null)
|
||||
@@ -123,7 +124,6 @@ export default function App() {
|
||||
(type: string) => {
|
||||
const position = getMenuPosition()
|
||||
if (position == null) return
|
||||
const newId = genId()
|
||||
const typeMap: Record<string, Node['type']> = {
|
||||
config: 'config',
|
||||
render: 'render',
|
||||
@@ -131,15 +131,18 @@ export default function App() {
|
||||
function: 'function',
|
||||
}
|
||||
const nodeType = typeMap[type] ?? 'config'
|
||||
const dataMap = getDefaultDataForType(nodeType, newId)
|
||||
const newNode: Node = {
|
||||
id: newId,
|
||||
type: nodeType,
|
||||
position: { x: position.x, y: position.y },
|
||||
data: dataMap,
|
||||
style: DEFAULT_NODE_STYLE[nodeType] ?? DEFAULT_NODE_STYLE.config,
|
||||
}
|
||||
setNodes((nds) => nds.concat(newNode))
|
||||
setNodes((nds) => {
|
||||
const newId = getNextNodeId(nodeType, nds.map((n) => n.id))
|
||||
const dataMap = getDefaultDataForType(nodeType, newId)
|
||||
const newNode: Node = {
|
||||
id: newId,
|
||||
type: nodeType,
|
||||
position: { x: position.x, y: position.y },
|
||||
data: dataMap,
|
||||
style: DEFAULT_NODE_STYLE[nodeType] ?? DEFAULT_NODE_STYLE.config,
|
||||
}
|
||||
return nds.concat(newNode)
|
||||
})
|
||||
lastClickRef.current = null
|
||||
setContextTarget(null)
|
||||
},
|
||||
@@ -156,17 +159,19 @@ export default function App() {
|
||||
if (!text) return
|
||||
const raw = JSON.parse(text) as { id?: string; type?: string; data?: any; position?: { x: number; y: number }; style?: any }
|
||||
if (!raw || typeof raw.type !== 'string' || !VALID_NODE_TYPES.includes(raw.type as any)) return
|
||||
const newId = genId()
|
||||
const data = raw.data != null && typeof raw.data === 'object' ? { ...raw.data } : {}
|
||||
if (raw.type === 'config' && data.title != null) data.title = `config-${newId}`
|
||||
const newNode: Node = {
|
||||
id: newId,
|
||||
type: raw.type as Node['type'],
|
||||
position: { x: position.x, y: position.y },
|
||||
data,
|
||||
style: DEFAULT_NODE_STYLE[raw.type] ?? DEFAULT_NODE_STYLE.config,
|
||||
}
|
||||
setNodes((nds) => nds.concat(newNode))
|
||||
setNodes((nds) => {
|
||||
const newId = getNextNodeId(raw.type as Node['type'], nds.map((n) => n.id))
|
||||
const data = raw.data != null && typeof raw.data === 'object' ? { ...raw.data } : {}
|
||||
if (raw.type === 'config' && data.title != null) data.title = `config-${newId}`
|
||||
const newNode: Node = {
|
||||
id: newId,
|
||||
type: raw.type as Node['type'],
|
||||
position: { x: position.x, y: position.y },
|
||||
data,
|
||||
style: DEFAULT_NODE_STYLE[raw.type] ?? DEFAULT_NODE_STYLE.config,
|
||||
}
|
||||
return nds.concat(newNode)
|
||||
})
|
||||
lastClickRef.current = null
|
||||
setContextTarget(null)
|
||||
} catch {
|
||||
@@ -199,7 +204,7 @@ export default function App() {
|
||||
>
|
||||
{theme === 'dark' ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
|
||||
</Button>
|
||||
<FlowContext.Provider value={{ nodes, setNodes, edges, setEdges }}>
|
||||
<FlowContext.Provider value={{ nodes, setNodes, edges, setEdges, renamingNodeId, setRenamingNodeId }}>
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger asChild>
|
||||
<div style={{ width: '100%', height: '100%' }}>
|
||||
|
||||
Reference in New Issue
Block a user