Browse Source

feat: fixed layout supports drag and drop to add branches (#896)

chenjiawei.inizio 3 tháng trước cách đây
mục cha
commit
b2491c1c81

+ 29 - 1
apps/demo-fixed-layout-simple/src/components/node-add-panel.tsx

@@ -5,6 +5,7 @@
 
 import React from 'react';
 
+import { nanoid } from 'nanoid';
 import { useStartDragNode } from '@flowgram.ai/fixed-layout-editor';
 
 import { nodeRegistries } from '../node-registries';
@@ -12,7 +13,7 @@ import { useAddNode } from '../hooks/use-add-node';
 
 export const NodeAddPanel: React.FC = (props) => {
   const { startDrag } = useStartDragNode();
-  const { handleAdd } = useAddNode();
+  const { handleAdd, handleAddBranch } = useAddNode();
 
   return (
     <div className="demo-fixed-sidebar">
@@ -41,6 +42,33 @@ export const NodeAddPanel: React.FC = (props) => {
           </div>
         );
       })}
+      <div
+        key={'branch'}
+        className="demo-fixed-card"
+        onMouseDown={(e) => {
+          e.stopPropagation();
+          return startDrag(
+            e,
+            {
+              dragJSON: {
+                id: `branch_${nanoid(5)}`,
+                type: 'block',
+                data: {
+                  title: 'New Branch',
+                  content: '',
+                },
+              },
+              isBranch: true,
+              onCreateNode: async (json, dropNode) => handleAddBranch(json, dropNode),
+            },
+            {
+              disableDragScroll: true,
+            }
+          );
+        }}
+      >
+        branch
+      </div>
     </div>
   );
 };

+ 9 - 0
apps/demo-fixed-layout-simple/src/hooks/use-add-node.tsx

@@ -30,7 +30,16 @@ export const useAddNode = () => {
     return entity;
   };
 
+  const handleAddBranch = (addProps: FlowNodeJSON, dropNode: FlowNodeEntity) => {
+    const index = dropNode.index + 1;
+    const entity = flowOperationService.addBlock(dropNode.originParent!, addProps, {
+      index,
+    });
+    return entity;
+  };
+
   return {
     handleAdd,
+    handleAddBranch,
   };
 };

+ 11 - 0
packages/canvas-engine/document/src/entities/flow-renderer-state-entity.ts

@@ -20,6 +20,7 @@ interface FlowRendererState {
   nodeDragIdsWithChildren?: string[]; // 批量拖拽(含子节点)
   dragLabelSide?: LABEL_SIDE_TYPE;
   dragging?: boolean;
+  isBranch?: boolean;
 }
 /**
  * 渲染相关的全局状态管理
@@ -60,6 +61,16 @@ export class FlowRendererStateEntity extends ConfigEntity<
     });
   }
 
+  get isBranch() {
+    return this.config.isBranch;
+  }
+
+  setIsBranch(isBranch: boolean) {
+    this.updateConfig({
+      isBranch,
+    });
+  }
+
   getDragLabelSide(): LABEL_SIDE_TYPE | undefined {
     return this.config.dragLabelSide;
   }

+ 5 - 1
packages/canvas-engine/document/src/services/flow-drag-service.ts

@@ -61,7 +61,7 @@ export class FlowDragService {
 
   // 是否在拖拽分支
   get isDragBranch(): boolean {
-    return this.dragStartNode?.isInlineBlock;
+    return this.renderState.isBranch || this.dragStartNode?.isInlineBlock;
   }
 
   // 拖拽的所有节点及其自节点
@@ -178,6 +178,10 @@ export class FlowDragService {
    * @param side 分支的前面还是后面
    */
   isDroppableBranch(node: FlowNodeEntity, side: LABEL_SIDE_TYPE = LABEL_SIDE_TYPE.NORMAL_BRANCH) {
+    // 外部添加拖拽标识,默认所有分支均可添加
+    if (this.renderState.isBranch) {
+      return true;
+    }
     // 拖拽的是分支
     if (this.isDragBranch) {
       if (

+ 14 - 2
packages/canvas-engine/renderer/src/layers/flow-drag-layer.tsx

@@ -266,7 +266,11 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
 
       if (activatedNodeId) {
         if (this.flowDragService.isDragBranch) {
-          this.flowDragService.dropBranch();
+          if (this.dragJSON) {
+            await this.flowDragService.dropCreateNode(this.dragJSON, this.onCreateNode);
+          } else {
+            this.flowDragService.dropBranch();
+          }
         } else {
           if (this.dragJSON) {
             await this.flowDragService.dropCreateNode(this.dragJSON, this.onCreateNode);
@@ -280,6 +284,7 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
       // 清空碰撞 id
       this.flowRenderStateEntity.setNodeDroppingId('');
       this.flowRenderStateEntity.setDragLabelSide();
+      this.flowRenderStateEntity.setIsBranch(false);
       this.dragStartEntity = undefined;
       this.dragEntities = [];
 
@@ -313,7 +318,13 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
    */
   async startDrag(
     e: { clientX: number; clientY: number },
-    { dragStartEntity: startEntityFromProps, dragEntities, dragJSON, onCreateNode }: StartDragProps,
+    {
+      dragStartEntity: startEntityFromProps,
+      dragEntities,
+      dragJSON,
+      isBranch,
+      onCreateNode,
+    }: StartDragProps,
     options?: {
       dragOffsetX?: number;
       dragOffsetY?: number;
@@ -328,6 +339,7 @@ export class FlowDragLayer extends Layer<FlowDragOptions> {
     this.disableDragScroll = Boolean(options?.disableDragScroll);
     this.dragJSON = dragJSON;
     this.onCreateNode = onCreateNode;
+    this.flowRenderStateEntity.setIsBranch(Boolean(isBranch));
 
     this.dragOffset.x = options?.dragOffsetX || DEFAULT_DRAG_OFFSET_X;
     this.dragOffset.y = options?.dragOffsetY || DEFAULT_DRAG_OFFSET_Y;