Преглед на файлове

feat(auto-layout): support layout for specified container nodes (#844)

Louis Young преди 3 месеца
родител
ревизия
d058e5894a

+ 14 - 0
apps/demo-free-layout/src/components/node-menu/index.tsx

@@ -8,6 +8,7 @@ import { FC, useCallback, useState, type MouseEvent } from 'react';
 import {
   delay,
   useClientContext,
+  usePlaygroundTools,
   useService,
   WorkflowDragService,
   WorkflowNodeEntity,
@@ -35,6 +36,7 @@ export const NodeMenu: FC<NodeMenuProps> = ({ node, deleteNode, updateTitleEdit
   const selectService = useService(WorkflowSelectService);
   const dragService = useService(WorkflowDragService);
   const canMoveOut = nodeIntoContainerService.canMoveOutContainer(node);
+  const tools = usePlaygroundTools();
 
   const rerenderMenu = useCallback(() => {
     // force destroy component - 强制销毁组件触发重新渲染
@@ -87,6 +89,15 @@ export const NodeMenu: FC<NodeMenuProps> = ({ node, deleteNode, updateTitleEdit
     updateTitleEdit(true);
   }, [updateTitleEdit]);
 
+  const handleAutoLayout = useCallback(async () => {
+    await tools.autoLayout({
+      containerNode: node,
+      enableAnimation: true,
+      animationDuration: 1000,
+      disableFitView: true,
+    });
+  }, [tools]);
+
   if (!visible) {
     return <></>;
   }
@@ -102,6 +113,9 @@ export const NodeMenu: FC<NodeMenuProps> = ({ node, deleteNode, updateTitleEdit
           <Dropdown.Item onClick={handleCopy} disabled={registry.meta!.copyDisable === true}>
             Create Copy
           </Dropdown.Item>
+          {registry.meta.isContainer && (
+            <Dropdown.Item onClick={handleAutoLayout}>Auto Layout</Dropdown.Item>
+          )}
           <Dropdown.Item
             onClick={handleDelete}
             disabled={!!(registry.canDelete?.(clientContext, node) || registry.meta!.deleteDisable)}

+ 1 - 0
packages/plugins/free-auto-layout-plugin/src/layout/type.ts

@@ -102,6 +102,7 @@ export interface LayoutParams {
 }
 
 export interface LayoutOptions {
+  containerNode?: WorkflowNodeEntity;
   getFollowNode?: GetFollowNode;
   enableAnimation?: boolean;
   animationDuration?: number;

+ 4 - 3
packages/plugins/free-auto-layout-plugin/src/services.ts

@@ -39,9 +39,10 @@ export class AutoLayoutService {
       ...DefaultLayoutOptions,
       ...options,
     };
-    const root = this.createLayoutNode(this.document.root, options);
-    const layouts = await this.layoutNode(root, layoutOptions);
-    const rect = this.getLayoutNodeRect(root);
+    const containerNode = layoutOptions.containerNode ?? this.document.root;
+    const container = this.createLayoutNode(containerNode, options);
+    const layouts = await this.layoutNode(container, layoutOptions);
+    const rect = this.getLayoutNodeRect(container);
     const positionPromise = layouts.map((layout) => layout.position());
     const fitViewPromise = this.fitView(layoutOptions, rect);
     await Promise.all([...positionPromise, fitViewPromise]);