Browse Source

feat: history support enableChangeNode option & rm unused code (#906)

hanchayi 3 months ago
parent
commit
f073a694f7

+ 0 - 14
packages/canvas-engine/document/src/typings/flow-operation.ts

@@ -21,7 +21,6 @@ export enum OperationType {
   moveChildNodes = 'moveChildNodes',
   addNodes = 'addNodes',
   deleteNodes = 'deleteNodes',
-  changeNode = 'changeNode',
   addChildNode = 'addChildNode',
   deleteChildNode = 'deleteChildNode',
   addNode = 'addNode',
@@ -107,18 +106,6 @@ export interface DeleteNodesOperation {
   value: AddOrDeleteNodesOperationValue;
 }
 
-export interface ChangeNodeOperationValue {
-  id: string;
-  path: string;
-  oldValue: any;
-  value: any;
-}
-
-export interface ChangeNodeOperation {
-  type: OperationType.changeNode;
-  value: ChangeNodeOperationValue;
-}
-
 export interface MoveChildNodesOperationValue {
   nodeIds: string[];
   fromParentId: string;
@@ -190,7 +177,6 @@ export type FlowOperation =
   | MoveNodesOperation
   | AddNodesOperation
   | DeleteNodesOperation
-  | ChangeNodeOperation
   | MoveBlockOperation
   | AddChildNodeOperation
   | DeleteChildNodeOperation

+ 1 - 1
packages/client/editor/src/preset/editor-default-preset.ts

@@ -65,7 +65,7 @@ export function createDefaultPreset<CTX extends EditorPluginContext = EditorPlug
         plugins.push(createNodeVariablePlugin({}));
       }
 
-      if (opts.history?.enable) {
+      if (opts.history?.enable && opts.history?.enableChangeNode !== false) {
         plugins.push(createHistoryNodePlugin({}));
       }
     }

+ 1 - 0
packages/common/history/src/create-history-plugin.ts

@@ -10,6 +10,7 @@ import { HistoryContainerModule } from './history-container-module';
 
 export interface HistoryPluginOptions<T = PluginContext> {
   enable?: boolean;
+  enableChangeNode?: boolean;
   onApply?: (ctx: T, operation: Operation) => void;
 }
 

+ 0 - 37
packages/plugins/fixed-history-plugin/src/create-fixed-history-plugin.ts

@@ -3,12 +3,10 @@
  * SPDX-License-Identifier: MIT
  */
 
-import { isEqual } from 'lodash-es';
 import { interfaces } from 'inversify';
 import { bindContributions } from '@flowgram.ai/utils';
 import { HistoryContainerModule, OperationService } from '@flowgram.ai/history';
 import { OperationContribution } from '@flowgram.ai/history';
-import { FlowNodeFormData } from '@flowgram.ai/form-core';
 import { FlowOperationBaseService } from '@flowgram.ai/document';
 import { FlowDocument } from '@flowgram.ai/document';
 import { definePluginCreator } from '@flowgram.ai/core';
@@ -34,7 +32,6 @@ export const createFixedHistoryPlugin = definePluginCreator<FixedHistoryPluginOp
   },
   onInit(ctx, opts): void {
     const fixedHistoryService = ctx.get<FixedHistoryService>(FixedHistoryService);
-    const fixedFormDataService = ctx.get<FixedHistoryFormDataService>(FixedHistoryFormDataService);
     fixedHistoryService.setSource(ctx);
     const document = ctx.get<FlowDocument>(FlowDocument);
 
@@ -58,40 +55,6 @@ export const createFixedHistoryPlugin = definePluginCreator<FixedHistoryPluginOp
     if (opts.onApply) {
       ctx.get(OperationService).onApply(opts.onApply.bind(null, ctx));
     }
-
-    if (!opts?.enableChangeNode) {
-      return;
-    }
-
-    document.onNodeCreate(({ node, data }) => {
-      const formData = node.getData<FlowNodeFormData>(FlowNodeFormData);
-      fixedFormDataService.setCache(formData, '/', data.data);
-
-      formData.formModel.onInitialized(() => {
-        formData.onDetailChange((event) => {
-          let { path, initialized } = event;
-
-          if (path !== '/') {
-            path.split('/').filter(Boolean)[0];
-          }
-
-          const value = fixedFormDataService.getFormItemValue(formData, path);
-          const oldValue = fixedFormDataService.getCache(formData, path);
-
-          if (isEqual(value, oldValue)) {
-            return;
-          }
-          if (initialized) {
-            fixedHistoryService.changeFormData(node, {
-              path,
-              value,
-              oldValue,
-            });
-          }
-          fixedFormDataService.setCache(formData, path, value);
-        });
-      });
-    });
   },
   containerModules: [HistoryContainerModule],
 });

+ 0 - 54
packages/plugins/fixed-history-plugin/src/operation-metas/change-node.ts

@@ -1,54 +0,0 @@
-/**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
-
-import { ChangeNodeOperationValue, OperationType } from '@flowgram.ai/document';
-import { PluginContext } from '@flowgram.ai/core';
-import { OperationMeta } from '@flowgram.ai/history';
-
-import { FixedHistoryFormDataService } from '../services';
-import { baseOperationMeta } from './base';
-
-export const changeNodeOperationMeta: OperationMeta<ChangeNodeOperationValue, PluginContext, void> =
-  {
-    ...baseOperationMeta,
-    type: OperationType.changeNode,
-    inverse: op => ({
-      ...op,
-      value: { ...op.value, value: op.value.oldValue, oldValue: op.value.value },
-    }),
-    apply: (operation, ctx) => {
-      const fixedFormDataService = ctx.get<FixedHistoryFormDataService>(
-        FixedHistoryFormDataService,
-      );
-      const formData = fixedFormDataService.getFormDataByNodeId(operation.value.id);
-
-      if (!formData) {
-        return;
-      }
-
-      fixedFormDataService.setFormItemValue(formData, operation.value.path, operation.value.value);
-    },
-    shouldMerge: (op, prev) => {
-      const mergable =
-        prev &&
-        prev?.value?.path === op.value?.path &&
-        prev?.type === OperationType.changeNode &&
-        ['string', 'number'].includes(typeof op.value.value);
-
-      if (!mergable) {
-        return false;
-      }
-      return {
-        type: OperationType.changeNode,
-        value: { ...op.value, oldValue: prev.value.oldValue, value: op.value.value },
-      };
-    },
-    getLabel: op => {
-      const value = op.value;
-      return `将节点${value.id}的${value.path.split('/').filter(Boolean).join('.')}属性修改为${
-        value.value
-      }`;
-    },
-  };

+ 0 - 2
packages/plugins/fixed-history-plugin/src/operation-metas/index.ts

@@ -14,7 +14,6 @@ import { deleteFromNodeOperationMeta } from './delete-from-node';
 import { deleteChildNodeOperationMeta } from './delete-child-node';
 import { deleteBlockOperationMeta } from './delete-block';
 import { createGroupOperationMeta } from './create-group';
-import { changeNodeOperationMeta } from './change-node';
 import { addNodesOperationMeta } from './add-nodes';
 import { addNodeOperationMeta } from './add-node';
 import { addFromNodeOperationMeta } from './add-from-node';
@@ -31,7 +30,6 @@ export const operationMetas = [
   moveNodesOperationMeta,
   deleteNodesOperationMeta,
   addNodesOperationMeta,
-  changeNodeOperationMeta,
   moveBlockOperationMeta,
   addChildNodeOperationMeta,
   deleteChildNodeOperationMeta,

+ 0 - 20
packages/plugins/fixed-history-plugin/src/services/fixed-history-service.ts

@@ -16,7 +16,6 @@ import {
   OperationType,
 } from '@flowgram.ai/document';
 import { FlowDocument } from '@flowgram.ai/document';
-import { ChangeNodeOperationValue } from '@flowgram.ai/document';
 import { FlowOperationBaseService } from '@flowgram.ai/document';
 import { PluginContext } from '@flowgram.ai/core';
 
@@ -295,25 +294,6 @@ export class FixedHistoryService implements IHistoryDocument {
     });
   }
 
-  /**
-   * 修改节点
-   * @param node 节点
-   * @returns
-   */
-  changeFormData(node: FlowNodeEntity, data: Omit<ChangeNodeOperationValue, 'id'>): void {
-    return this.historyService.pushOperation(
-      {
-        type: OperationType.changeNode,
-        value: {
-          ...data,
-          id: node.id,
-        },
-        uri: this.config.getNodeURI(node.id),
-      },
-      { noApply: true }
-    );
-  }
-
   /**
    * 移动节点
    * @param node 被移动的节点

+ 0 - 1
packages/plugins/fixed-history-plugin/src/types.ts

@@ -55,6 +55,5 @@ export interface FixedHistoryPluginOptions<CTX extends PluginContext = PluginCon
   getBlockLabel?: (ctx: CTX) => GetBlockLabel;
   getNodeURI?: (ctx: CTX) => GetNodeURI;
   operationMetas?: OperationMeta[];
-  enableChangeNode?: boolean;
   uri?: string | any;
 }

+ 1 - 3
packages/plugins/free-history-plugin/src/create-free-history-plugin.ts

@@ -3,13 +3,12 @@
  * SPDX-License-Identifier: MIT
  */
 
-import { bindContributions, definePluginCreator } from '@flowgram.ai/core';
 import { HistoryContainerModule, OperationContribution } from '@flowgram.ai/history';
+import { bindContributions, definePluginCreator } from '@flowgram.ai/core';
 
 import { type FreeHistoryPluginOptions } from './types';
 import { HistoryEntityManager } from './history-entity-manager';
 import { DragNodesHandler } from './handlers/drag-nodes-handler';
-import { ChangeNodeDataHandler } from './handlers/change-node-data-handler';
 import { ChangeContentHandler } from './handlers/change-content-handler';
 import { FreeHistoryRegisters } from './free-history-registers';
 import { FreeHistoryManager } from './free-history-manager';
@@ -22,7 +21,6 @@ export const createFreeHistoryPlugin = definePluginCreator<FreeHistoryPluginOpti
     bind(FreeHistoryManager).toSelf().inSingletonScope();
     bind(HistoryEntityManager).toSelf().inSingletonScope();
     bind(DragNodesHandler).toSelf().inSingletonScope();
-    bind(ChangeNodeDataHandler).toSelf().inSingletonScope();
     bind(ChangeContentHandler).toSelf().inSingletonScope();
   },
   onInit(ctx, opts): void {

+ 2 - 32
packages/plugins/free-history-plugin/src/free-history-manager.ts

@@ -4,9 +4,8 @@
  */
 
 /* eslint-disable @typescript-eslint/naming-convention */
-import { cloneDeep } from 'lodash-es';
-import { injectable, inject, optional } from 'inversify';
-import { DisposableCollection, Disposable } from '@flowgram.ai/utils';
+import { injectable, inject } from 'inversify';
+import { DisposableCollection } from '@flowgram.ai/utils';
 import { HistoryService } from '@flowgram.ai/history';
 import {
   WorkflowDocument,
@@ -14,15 +13,12 @@ import {
   WorkflowDragService,
   WorkflowOperationBaseService,
 } from '@flowgram.ai/free-layout-core';
-import { FlowNodeFormData } from '@flowgram.ai/form-core';
-import { FormManager } from '@flowgram.ai/form-core';
 import { OperationType } from '@flowgram.ai/document';
 import { type PluginContext, PositionData } from '@flowgram.ai/core';
 
 import { DragNodeOperationValue, type FreeHistoryPluginOptions, FreeOperationType } from './types';
 import { HistoryEntityManager } from './history-entity-manager';
 import { DragNodesHandler } from './handlers/drag-nodes-handler';
-import { ChangeNodeDataHandler } from './handlers/change-node-data-handler';
 import { ChangeContentHandler } from './handlers/change-content-handler';
 
 /**
@@ -33,19 +29,12 @@ export class FreeHistoryManager {
   @inject(DragNodesHandler)
   private _dragNodesHandler: DragNodesHandler;
 
-  @inject(ChangeNodeDataHandler)
-  private _changeNodeDataHandler: ChangeNodeDataHandler;
-
   @inject(ChangeContentHandler)
   private _changeContentHandler: ChangeContentHandler;
 
   @inject(HistoryEntityManager)
   private _entityManager: HistoryEntityManager;
 
-  @inject(FormManager)
-  @optional()
-  private _formManager?: FormManager;
-
   private _toDispose: DisposableCollection = new DisposableCollection();
 
   @inject(WorkflowOperationBaseService)
@@ -76,25 +65,6 @@ export class FreeHistoryManager {
           this._entityManager.addEntityData(positionData);
         }
       }),
-      this._formManager
-        ? this._formManager.onFormModelWillInit(({ model, data }) => {
-            const node = model.flowNodeEntity;
-            const formData = node.getData<FlowNodeFormData>(FlowNodeFormData);
-
-            if (formData) {
-              this._entityManager.setValue(formData, cloneDeep(data));
-
-              this._toDispose.push(
-                formData.onDetailChange((event) => {
-                  this._changeNodeDataHandler.handle({
-                    ...event,
-                    node,
-                  });
-                })
-              );
-            }
-          })
-        : Disposable.NULL,
       document.onContentChange((event) => {
         this._changeContentHandler.handle(event, ctx);
       }),

+ 0 - 80
packages/plugins/free-history-plugin/src/handlers/change-node-data-handler.ts

@@ -1,80 +0,0 @@
-/**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
-
-/* eslint-disable @typescript-eslint/naming-convention */
-import { cloneDeep, get, isEqual, set } from 'lodash-es';
-import { injectable, inject } from 'inversify';
-import { HistoryService } from '@flowgram.ai/history';
-import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
-import { FlowNodeFormData, type DetailChangeEvent } from '@flowgram.ai/form-core';
-import { type FlowNodeEntity } from '@flowgram.ai/document';
-
-import { FreeOperationType, type IHandler } from '../types';
-import { HistoryEntityManager } from '../history-entity-manager';
-import { FreeHistoryConfig } from '../free-history-config';
-
-export interface ChangeNodeDataEvent extends DetailChangeEvent {
-  node: FlowNodeEntity;
-}
-
-@injectable()
-export class ChangeNodeDataHandler implements IHandler<ChangeNodeDataEvent> {
-  @inject(HistoryService)
-  private _historyService: HistoryService;
-
-  @inject(WorkflowDocument) document: WorkflowDocument;
-
-  @inject(HistoryEntityManager)
-  private _entityManager: HistoryEntityManager;
-
-  @inject(FreeHistoryConfig)
-  private _config: FreeHistoryConfig;
-
-  handle(event: ChangeNodeDataEvent) {
-    const { path, value, initialized, node } = event;
-    const formData = node.getData<FlowNodeFormData>(FlowNodeFormData);
-    const oldValue = this._entityManager.getValue(formData) as object;
-    const propPath = path.split('/').filter(Boolean).join('.');
-
-    const propOldValue = propPath ? get(oldValue, propPath) : oldValue;
-    if (isEqual(value, propOldValue)) {
-      return;
-    }
-
-    if (initialized) {
-      let operationPath = path;
-      let operationValue = cloneDeep(value);
-      let operationOldValue = propOldValue;
-      // 只存储一层的数据,因为formModel无法获取数组下的某项的值
-      if (path !== '/') {
-        const clonedOldValue = cloneDeep(oldValue);
-        set(clonedOldValue, propPath, value);
-        operationPath = path.split('/').filter(Boolean)[0];
-        operationValue = get(clonedOldValue, operationPath);
-        operationOldValue = get(oldValue, operationPath);
-      }
-
-      this._historyService.pushOperation(
-        {
-          type: FreeOperationType.changeNodeData,
-          value: {
-            id: node.id,
-            path: operationPath,
-            value: operationValue,
-            oldValue: operationOldValue,
-          },
-          uri: this._config.getNodeURI(node.id),
-        },
-        { noApply: true }
-      );
-    }
-
-    if (propPath) {
-      set(oldValue, propPath, cloneDeep(value));
-    } else {
-      this._entityManager.setValue(formData, cloneDeep(value));
-    }
-  }
-}

+ 0 - 79
packages/plugins/free-history-plugin/src/operation-metas/change-node-data.ts

@@ -1,79 +0,0 @@
-/**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
-
-import { FlowNodeFormData } from '@flowgram.ai/form-core';
-import { type PluginContext } from '@flowgram.ai/core';
-import { WorkflowDocument } from '@flowgram.ai/free-layout-core';
-import { type OperationMeta } from '@flowgram.ai/history';
-
-import { FreeOperationType, type ChangeNodeDataValue } from '../types';
-import { baseOperationMeta } from './base';
-
-export const changeNodeDataOperationMeta: OperationMeta<ChangeNodeDataValue, PluginContext, void> =
-  {
-    ...baseOperationMeta,
-    type: FreeOperationType.changeNodeData,
-    inverse: op => ({
-      ...op,
-      value: {
-        ...op.value,
-        value: op.value.oldValue,
-        oldValue: op.value.value,
-      },
-    }),
-    apply: (operation, ctx: PluginContext) => {
-      const document = ctx.get<WorkflowDocument>(WorkflowDocument);
-      const node = document.getNode(operation.value.id);
-
-      if (!node) {
-        return;
-      }
-      const formData = node.getData(FlowNodeFormData);
-
-      if (!formData) {
-        return;
-      }
-
-      let { path } = operation.value;
-      if (path.endsWith('/') && path !== '/') {
-        path = path.slice(0, -1);
-      }
-
-      if (!path.startsWith('/')) {
-        path = `/${path}`;
-      }
-
-      const formItem = formData.formModel.getFormItemByPath(path);
-
-      if (!formItem) {
-        return;
-      }
-      formItem.value = operation.value.value;
-    },
-    shouldMerge: (op, prev, element) => {
-      if (!prev) {
-        return false;
-      }
-
-      if (Date.now() - element.getTimestamp() < 500) {
-        if (
-          op.type === prev.type && // 相同类型
-          op.value.id === prev.value.id && // 相同节点
-          op.value?.path === prev.value?.path // 相同路径
-        ) {
-          return {
-            type: op.type,
-            value: {
-              ...op.value,
-              value: op.value.value,
-              oldValue: prev.value.oldValue,
-            },
-          };
-        }
-        return true;
-      }
-      return false;
-    },
-  };

+ 0 - 2
packages/plugins/free-history-plugin/src/operation-metas/index.ts

@@ -8,7 +8,6 @@ import { moveChildNodesOperationMeta } from './move-child-nodes';
 import { dragNodesOperationMeta } from './drag-nodes';
 import { deleteNodeOperationMeta } from './delete-node';
 import { deleteLineOperationMeta } from './delete-line';
-import { changeNodeDataOperationMeta } from './change-node-data';
 import { changeLineDataOperationMeta } from './change-line-data';
 import { addNodeOperationMeta } from './add-node';
 import { addLineOperationMeta } from './add-line';
@@ -18,7 +17,6 @@ export const operationMetas = [
   deleteLineOperationMeta,
   addNodeOperationMeta,
   deleteNodeOperationMeta,
-  changeNodeDataOperationMeta,
   resetLayoutOperationMeta,
   dragNodesOperationMeta,
   moveChildNodesOperationMeta,

+ 0 - 5
packages/plugins/free-history-plugin/src/types.ts

@@ -121,11 +121,6 @@ export interface ChangeLineDataValue {
   oldValue: unknown;
 }
 
-export interface ChangeNodeDataOperation extends Operation {
-  type: FreeOperationType.changeNodeData;
-  value: ChangeNodeDataValue;
-}
-
 /**
  * 将node转成json
  */