瀏覽代碼

feat(core): add flowing field to LineColor interface (#370)

Co-authored-by: husky-dot <xiaozhi@xiaozhideMacBook-Pro.local>
小智 7 月之前
父節點
當前提交
02e48ebdd9

+ 29 - 0
CHANGELOG.md

@@ -0,0 +1,29 @@
+# Changelog
+
+## [Unreleased]
+
+### Added
+
+- Add `flowing` field to `LineColor` interface for configuring flowing line colors
+  - Added `flowing: string` field to `LineColor` interface
+  - Added `LineColors.FLOWING` enum value with default color
+  - Updated `WorkflowLinesManager.getLineColor()` to support flowing state
+  - Updated demo configurations to include flowing color examples
+  - Added comprehensive test coverage for flowing line functionality
+
+### Features
+
+- Lines can now be colored differently when in flowing state (e.g., during workflow execution)
+- Priority order: hidden > error > highlight > drawing > hovered > selected > flowing > default
+- Backward compatible with existing line color configurations
+
+### Demo Updates
+
+- Updated `apps/demo-free-layout` to include flowing color configuration
+- Added CSS variable support: `var(--g-workflow-line-color-flowing,#4d53e8)`
+
+### Tests
+
+- Added test cases for flowing line color functionality
+- Verified priority ordering with other line states
+- Ensured backward compatibility

+ 1 - 0
apps/demo-free-layout/src/hooks/use-editor-props.tsx

@@ -83,6 +83,7 @@ export function useEditorProps(
         hovered: 'var(--g-workflow-line-color-hover,#37d0ff)',
         selected: 'var(--g-workflow-line-color-selected,#37d0ff)',
         error: 'var(--g-workflow-line-color-error,red)',
+        flowing: 'var(--g-workflow-line-color-flowing,#4d53e8)',
       },
       /*
        * Check whether the line can be added

+ 2 - 1
apps/docs/src/en/guide/advanced/free-layout/line.mdx

@@ -170,6 +170,7 @@ function App() {
         hovered: '#37d0ff',
         selected: '#37d0ff',
         error: 'red',
+        flowing: '#ff6b35', // Color for flowing lines (e.g., during workflow execution)
       },
       // ...others
   }
@@ -180,7 +181,6 @@ function App() {
   )
 }
 ```
-
 ### 2. Limit Single Output Port to One Line
 
 <img loading="lazy" style={{ width: 500, margin: '0 auto' }} className="invert-img" src="/free-layout/line-limit.gif"/>
@@ -318,3 +318,4 @@ function SomeReact() {
 }
 ```
 
+

+ 65 - 0
packages/canvas-engine/free-layout-core/__tests__/workflow-lines-manager.test.ts

@@ -7,6 +7,7 @@ import {
   WorkflowDocumentOptions,
   WorkflowLineRenderData,
   WorkflowSimpleLineContribution,
+  LineColors,
 } from '../src';
 import { createWorkflowContainer } from './mocks';
 describe('workflow-lines-manager', () => {
@@ -171,4 +172,68 @@ describe('workflow-lines-manager', () => {
       expect((e as Error).message).toBe('[setToPort] only support drawing line.');
     }
   });
+
+  describe('flowing line support', () => {
+    it('should return flowing color when line is flowing', () => {
+      const documentOptions: WorkflowDocumentOptions = {
+        lineColor: {
+          flowing: '#ff0000', // 自定义流动颜色
+        },
+        isFlowingLine: () => true,
+      };
+
+      Object.assign(linesManager, { options: documentOptions });
+
+      const line = linesManager.createLine({
+        from: 'start_0',
+        to: 'end_0',
+      });
+
+      expect(line).toBeDefined();
+      expect(linesManager.isFlowingLine(line!)).toBe(true);
+      expect(linesManager.getLineColor(line!)).toBe('#ff0000');
+    });
+
+    it('should use default flowing color when no custom color provided', () => {
+      const documentOptions: WorkflowDocumentOptions = {
+        isFlowingLine: () => true,
+      };
+
+      Object.assign(linesManager, { options: documentOptions });
+
+      const line = linesManager.createLine({
+        from: 'start_0',
+        to: 'end_0',
+      });
+
+      expect(line).toBeDefined();
+      expect(linesManager.isFlowingLine(line!)).toBe(true);
+      expect(linesManager.getLineColor(line!)).toBe(LineColors.FLOWING);
+    });
+
+    it('should prioritize selected/hovered over flowing', () => {
+      const documentOptions: WorkflowDocumentOptions = {
+        lineColor: {
+          flowing: '#ff0000',
+          selected: '#00ff00',
+        },
+        isFlowingLine: () => true,
+      };
+
+      Object.assign(linesManager, { options: documentOptions });
+
+      const line = linesManager.createLine({
+        from: 'start_0',
+        to: 'end_0',
+      });
+
+      // 模拟选中状态
+      linesManager.selectService.select(line!);
+
+      expect(line).toBeDefined();
+      expect(linesManager.isFlowingLine(line!)).toBe(true);
+      // 选中状态应该优先于流动状态
+      expect(linesManager.getLineColor(line!)).toBe('#00ff00');
+    });
+  });
 });

+ 2 - 0
packages/canvas-engine/free-layout-core/src/typings/workflow-line.ts

@@ -21,6 +21,7 @@ export interface LineColor {
   hovered: string;
   selected: string;
   error: string;
+  flowing: string;
 }
 
 export enum LineColors {
@@ -30,6 +31,7 @@ export enum LineColors {
   HOVER = 'var(--g-workflow-line-color-hover,#37d0ff)',
   SELECTED = 'var(--g-workflow-line-color-selected,#37d0ff)',
   ERROR = 'var(--g-workflow-line-color-error,red)',
+  FLOWING = 'var(--g-workflow-line-color-flowing,#4d53e8)', // 流动线条,默认使用主题色
 }
 
 export interface WorkflowLineRenderContribution {

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

@@ -86,6 +86,7 @@ export class WorkflowLinesManager {
       drawing: LineColors.DRAWING,
       hovered: LineColors.HOVER,
       selected: LineColors.SELECTED,
+      flowing: LineColors.FLOWING,
     };
     if (this.options.lineColor) {
       Object.assign(color, this.options.lineColor);
@@ -336,6 +337,10 @@ export class WorkflowLinesManager {
     if (this.selectService.isSelected(line.id)) {
       return this.lineColor.selected;
     }
+    // 检查是否为流动线条
+    if (this.isFlowingLine(line)) {
+      return this.lineColor.flowing;
+    }
     return this.lineColor.default;
   }