Просмотр исходного кода

feat: workflow-line-entity add uiState and lineData (#421)

* feat: workflow-line-entity add uiState and lineData

* docs: history add startTransaction/endTransaction docs

* docs: move background.mdx
xiamidaxia 6 месяцев назад
Родитель
Сommit
ed18627760

+ 2 - 1
apps/docs/src/en/guide/advanced/_meta.json

@@ -22,5 +22,6 @@
   "custom-plugin",
   "custom-service",
   "custom-layer",
-  "form-materials"
+  "form-materials",
+  "background"
 ]

+ 0 - 0
apps/docs/src/en/guide/advanced/free-layout/background.mdx → apps/docs/src/en/guide/advanced/background.mdx


+ 1 - 2
apps/docs/src/en/guide/advanced/free-layout/_meta.json

@@ -3,6 +3,5 @@
   "node",
   "line",
   "port",
-  "sub-canvas",
-  "background"
+  "sub-canvas"
 ]

+ 17 - 1
apps/docs/src/en/guide/advanced/history.mdx

@@ -99,13 +99,29 @@ If some data changes triggered by the system do not want to be monitored by undo
 
 ```tsx pure
 const { history } = useClientContext();
+
 history.stop()
 // Do some operations that do not want to be captured, these changes will not be recorded in the operation stack
 ...
 history.start()
 ```
 
-### 1.3. Undo/Redo Call
+### 1.3. History Undo/Redo merge
+
+```tsx pure
+
+const { history } = useClientContext();
+
+history.startTransaction();
+
+// Any operations here will be merged into one
+...
+
+history.endTransaction();
+
+```
+
+### 1.4. Undo/Redo Call
 Undo/Redo is generally provided with two button entries on the interface, clicking which can trigger Undo and Redo, and the buttons themselves need to have the status of whether Undo/Redo is possible.
 
 ```tsx pure

+ 2 - 1
apps/docs/src/zh/guide/advanced/_meta.json

@@ -22,5 +22,6 @@
   "custom-plugin",
   "custom-service",
   "custom-layer",
-  "form-materials"
+  "form-materials",
+  "background"
 ]

+ 0 - 0
apps/docs/src/zh/guide/advanced/free-layout/background.mdx → apps/docs/src/zh/guide/advanced/background.mdx


+ 1 - 2
apps/docs/src/zh/guide/advanced/free-layout/_meta.json

@@ -3,6 +3,5 @@
   "node",
   "line",
   "port",
-  "sub-canvas",
-  "background"
+  "sub-canvas"
 ]

+ 17 - 1
apps/docs/src/zh/guide/advanced/history.mdx

@@ -99,13 +99,29 @@ export function useEditorProps() {
 
 ```tsx pure
 const { history } = useClientContext();
+
 history.stop()
 // 做一些不希望被捕获的操作, 这些变更不会被记录到操作栈
 ...
 history.start()
 ```
 
-### 1.3. Undo/Redo 调用
+### 1.3. History Undo/Redo 合并
+
+```tsx pure
+
+const { history } = useClientContext();
+
+history.startTransaction();
+
+// 这里的 任意操作都会被合并成一个
+...
+
+history.endTransaction();
+
+```
+
+### 1.4. Undo/Redo 调用
 一般 Undo/Redo 会在界面上提供两个按钮入口,点击了能触发 Undo 和 Redo,按钮本身需要有是否可以 Undo/Redo 的状态。
 
 ```tsx pure

+ 85 - 24
packages/canvas-engine/free-layout-core/src/entities/workflow-line-entity.ts

@@ -36,7 +36,16 @@ export interface WorkflowLineEntityOpts extends EntityOpts, WorkflowLinePortInfo
 export interface WorkflowLineInfo extends WorkflowLinePortInfo {
   drawingTo?: IPoint; // 正在画中的元素
   isDefaultLine?: boolean; // 是否为默认的线
-  highlightColor?: string; // 高亮显示
+}
+
+export interface WorkflowLineUIState {
+  hasError: boolean; //是否出错
+  flowing: boolean; // 流动
+  disabled: boolean; // 禁用
+  vertical: boolean; // 垂直模式
+  reverse: boolean; // 箭头反转
+  hideArrow: boolean; // 隐藏箭头
+  highlightColor: string; // 高亮显示
 }
 
 /**
@@ -62,9 +71,58 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
 
   private _to?: WorkflowNodeEntity;
 
-  private _processing = false;
+  private _lineData: any;
+
+  private _uiState: WorkflowLineUIState = {
+    hasError: false,
+    flowing: false,
+    disabled: false,
+    vertical: false,
+    hideArrow: false,
+    reverse: false,
+    highlightColor: '',
+  };
+
+  /**
+   * 线条的 UI 状态
+   */
+  get uiState(): WorkflowLineUIState {
+    return this._uiState;
+  }
+
+  /**
+   * 更新线条的 ui 状态
+   * @param newState
+   */
+  updateUIState(newState: Partial<WorkflowLineUIState>): void {
+    let changed = false;
+    Object.keys(newState).forEach((key: string) => {
+      const value: any = newState[key as keyof WorkflowLineUIState] as any;
+      if (this._uiState[key as keyof WorkflowLineUIState] !== value) {
+        (this._uiState as any)[key as keyof WorkflowLineUIState] = value;
+        changed = true;
+      }
+    });
+    if (changed) {
+      this.fireChange();
+    }
+  }
+
+  /**
+   * 线条的扩展数据
+   */
+  get lineData(): any {
+    return this._lineData;
+  }
 
-  private _hasError = false;
+  /**
+   * 更新线条扩展数据
+   * @param data
+   */
+  set lineData(data: any) {
+    this._lineData = data;
+    this.fireChange();
+  }
 
   public stackIndex = 0;
 
@@ -128,32 +186,33 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
 
   /**
    * 获取是否 testrun processing
+   * @deprecated  use `uiState.flowing` instead
    */
   get processing(): boolean {
-    return this._processing;
+    return this._uiState.flowing;
   }
 
   /**
    * 设置 testrun processing 状态
+   * @deprecated  use `uiState.flowing` instead
    */
   set processing(status: boolean) {
-    if (this._processing !== status) {
-      this._processing = status;
+    if (this._uiState.flowing !== status) {
+      this._uiState.flowing = status;
       this.fireChange();
     }
   }
 
   // 获取连线是否为错误态
   get hasError() {
-    return this._hasError;
+    return this.uiState.hasError;
   }
 
   // 设置连线的错误态
   set hasError(hasError: boolean) {
-    if (this._hasError !== hasError) {
-      this._hasError = hasError;
-      this.fireChange();
-    }
+    this.updateUIState({
+      hasError,
+    });
     if (this._node) {
       this._node.dataset.hasError = this.hasError ? 'true' : 'false';
     }
@@ -215,14 +274,13 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
   }
 
   get highlightColor(): string {
-    return this.info.highlightColor || '';
+    return this.uiState.highlightColor || '';
   }
 
-  set highlightColor(color) {
-    if (this.info.highlightColor !== color) {
-      this.info.highlightColor = color;
-      this.fireChange();
-    }
+  set highlightColor(highlightColor) {
+    this.updateUIState({
+      highlightColor,
+    });
   }
 
   /**
@@ -261,27 +319,27 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
 
   /** 是否反转箭头 */
   get reverse(): boolean {
-    return this.linesManager.isReverseLine(this);
+    return this.linesManager.isReverseLine(this, this.uiState.reverse);
   }
 
   /** 是否隐藏箭头 */
   get hideArrow(): boolean {
-    return this.linesManager.isHideArrowLine(this);
+    return this.linesManager.isHideArrowLine(this, this.uiState.hideArrow);
   }
 
   /** 是否流动 */
   get flowing(): boolean {
-    return this.linesManager.isFlowingLine(this);
+    return this.linesManager.isFlowingLine(this, this.uiState.flowing);
   }
 
   /** 是否禁用 */
   get disabled(): boolean {
-    return this.linesManager.isDisabledLine(this);
+    return this.linesManager.isDisabledLine(this, this.uiState.disabled);
   }
 
   /** 是否竖向 */
   get vertical(): boolean {
-    return this.linesManager.isVerticalLine(this);
+    return this.linesManager.isVerticalLine(this, this.uiState.vertical);
   }
 
   /** 获取线条渲染器类型 */
@@ -323,7 +381,7 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
     const { fromPort, toPort } = this;
 
     if (fromPort) {
-      this.hasError = this.linesManager.isErrorLine(fromPort, toPort);
+      this.hasError = this.linesManager.isErrorLine(fromPort, toPort, this.uiState.hasError);
     }
   }
 
@@ -352,12 +410,15 @@ export class WorkflowLineEntity extends Entity<WorkflowLineEntityOpts> {
   }
 
   toJSON(): WorkflowEdgeJSON {
-    const json = {
+    const json: WorkflowEdgeJSON = {
       sourceNodeID: this.info.from,
       targetNodeID: this.info.to!,
       sourcePortID: this.info.fromPort,
       targetPortID: this.info.toPort,
     };
+    if (this._lineData !== undefined) {
+      json.data = this._lineData;
+    }
     if (!json.sourcePortID) {
       delete json.sourcePortID;
     }

+ 1 - 1
packages/canvas-engine/free-layout-core/src/entities/workflow-port-entity.ts

@@ -130,7 +130,7 @@ export class WorkflowPortEntity extends Entity<WorkflowPortEntityOpts> {
   }
 
   isErrorPort() {
-    return (this.node.document as WorkflowDocument).isErrorPort(this);
+    return (this.node.document as WorkflowDocument).isErrorPort(this, this.hasError);
   }
 
   get point(): IPoint {

+ 1 - 0
packages/canvas-engine/free-layout-core/src/typings/workflow-edge.ts

@@ -11,4 +11,5 @@ export interface WorkflowEdgeJSON {
   targetNodeID: string;
   sourcePortID?: string | number;
   targetPortID?: string | number;
+  data?: any;
 }

+ 2 - 2
packages/canvas-engine/free-layout-core/src/workflow-document.ts

@@ -633,12 +633,12 @@ export class WorkflowDocument extends FlowDocument {
   /**
    * 判断端口是否为错误态
    */
-  isErrorPort(port: WorkflowPortEntity) {
+  isErrorPort(port: WorkflowPortEntity, defaultValue = false) {
     if (typeof this.options.isErrorPort === 'function') {
       return this.options.isErrorPort(port);
     }
 
-    return false;
+    return defaultValue;
   }
 
   /**

+ 12 - 12
packages/canvas-engine/free-layout-core/src/workflow-lines-manager.ts

@@ -261,51 +261,51 @@ export class WorkflowLinesManager {
     return this.toDispose.disposed;
   }
 
-  isErrorLine(fromPort: WorkflowPortEntity, toPort?: WorkflowPortEntity) {
+  isErrorLine(fromPort: WorkflowPortEntity, toPort?: WorkflowPortEntity, defaultValue?: boolean) {
     if (this.options.isErrorLine) {
       return this.options.isErrorLine(fromPort, toPort, this);
     }
 
-    return false;
+    return !!defaultValue;
   }
 
-  isReverseLine(line: WorkflowLineEntity): boolean {
+  isReverseLine(line: WorkflowLineEntity, defaultValue = false): boolean {
     if (this.options.isReverseLine) {
       return this.options.isReverseLine(line);
     }
 
-    return false;
+    return defaultValue;
   }
 
-  isHideArrowLine(line: WorkflowLineEntity): boolean {
+  isHideArrowLine(line: WorkflowLineEntity, defaultValue = false): boolean {
     if (this.options.isHideArrowLine) {
       return this.options.isHideArrowLine(line);
     }
 
-    return false;
+    return defaultValue;
   }
 
-  isFlowingLine(line: WorkflowLineEntity): boolean {
+  isFlowingLine(line: WorkflowLineEntity, defaultValue = false): boolean {
     if (this.options.isFlowingLine) {
       return this.options.isFlowingLine(line);
     }
 
-    return false;
+    return defaultValue;
   }
 
-  isDisabledLine(line: WorkflowLineEntity): boolean {
+  isDisabledLine(line: WorkflowLineEntity, defaultValue = false): boolean {
     if (this.options.isDisabledLine) {
       return this.options.isDisabledLine(line);
     }
-    return false;
+    return defaultValue;
   }
 
-  isVerticalLine(line: WorkflowLineEntity): boolean {
+  isVerticalLine(line: WorkflowLineEntity, defaultValue = false): boolean {
     if (this.options.isVerticalLine) {
       return this.options.isVerticalLine(line);
     }
 
-    return false;
+    return defaultValue;
   }
 
   setLineRenderType(line: WorkflowLineEntity): LineRenderType | undefined {