feat: add auto layout functionality to workflow editor and toolbar

This commit is contained in:
mlogclub
2026-06-28 09:37:34 +08:00
parent 6a402cff78
commit a185a0a352
2 changed files with 32 additions and 0 deletions
@@ -6,6 +6,7 @@ import {
RotateCcwIcon,
SaveIcon,
SendIcon,
SparklesIcon,
Undo2Icon,
} from "lucide-react"
@@ -23,6 +24,8 @@ export function WorkflowEditorToolbar({
undoDisabled = false,
onRedo,
redoDisabled = false,
onAutoLayout,
autoLayoutDisabled = false,
onRestoreDefault,
restoreDefaultDisabled = false,
onValidate,
@@ -40,6 +43,8 @@ export function WorkflowEditorToolbar({
undoDisabled?: boolean
onRedo?: () => void
redoDisabled?: boolean
onAutoLayout?: () => void
autoLayoutDisabled?: boolean
onRestoreDefault?: () => void
restoreDefaultDisabled?: boolean
onValidate?: () => void
@@ -74,6 +79,10 @@ export function WorkflowEditorToolbar({
<Button type="button" variant="ghost" size="sm" className="h-7 px-2 text-xs" disabled={redoDisabled} onClick={onRedo}>
</Button>
<Button type="button" variant="ghost" size="sm" className="h-7 px-2 text-xs" disabled={autoLayoutDisabled} onClick={onAutoLayout}>
<SparklesIcon className="size-3.5" />
</Button>
<Button type="button" variant="ghost" size="sm" className="h-7 px-2 text-xs" disabled={restoreDefaultDisabled} onClick={onRestoreDefault}>
<RotateCcwIcon className="size-3.5" />
@@ -10,6 +10,7 @@ import {
type WorkflowJSON,
type WorkflowNodeJSON,
useClientContext,
usePlaygroundTools,
useService,
} from "@flowgram.ai/free-layout-editor"
@@ -151,8 +152,10 @@ function WorkflowEditorInner({
publishDisabled?: boolean
}) {
const context = useClientContext()
const playgroundTools = usePlaygroundTools()
const workflowDocument = useService(WorkflowDocument)
const selectService = useService(WorkflowSelectService)
const [autoLayouting, setAutoLayouting] = useState(false)
useEffect(() => {
const disposable = selectService.onSelectionChanged(() => {
@@ -192,6 +195,24 @@ function WorkflowEditorInner({
onDefinitionChange(context.document.toJSON() as AIWorkflowDefinition)
}
const autoLayout = async () => {
if (autoLayouting || definition.nodes.length < 2) {
return
}
setAutoLayouting(true)
try {
await playgroundTools.autoLayout({
enableAnimation: true,
animationDuration: 240,
disableFitView: true,
})
playgroundTools.fitView(true)
emitCurrentDefinition()
} finally {
setAutoLayouting(false)
}
}
const closeConfigPanel = () => {
selectService.clear()
onSelectNode("")
@@ -214,6 +235,8 @@ function WorkflowEditorInner({
undoDisabled={undoDisabled}
onRedo={onRedo}
redoDisabled={redoDisabled}
onAutoLayout={() => void autoLayout()}
autoLayoutDisabled={autoLayouting || definition.nodes.length < 2}
onRestoreDefault={onRestoreDefault}
restoreDefaultDisabled={restoreDefaultDisabled}
onValidate={onValidate}