utils.mock.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import React from 'react';
  6. import { ContainerModule, interfaces } from 'inversify';
  7. import {
  8. WorkflowBezierLineContribution,
  9. WorkflowFoldLineContribution,
  10. } from '@flowgram.ai/free-lines-plugin';
  11. import { AutoLayoutService } from '@flowgram.ai/free-auto-layout-plugin';
  12. import { WorkflowAutoLayoutTool } from '../src/tools';
  13. import {
  14. FlowDocumentContainerModule,
  15. FlowNodeBaseType,
  16. FreeLayoutProps,
  17. PlaygroundEntityContext,
  18. PlaygroundMockTools,
  19. PlaygroundReactProvider,
  20. WorkflowDocument,
  21. WorkflowDocumentContainerModule,
  22. WorkflowJSON,
  23. WorkflowLinesManager,
  24. } from '../src';
  25. const MockContainerModule = new ContainerModule((bind, unbind, isBound, rebind) => {
  26. bind(AutoLayoutService).toSelf().inSingletonScope();
  27. });
  28. /**
  29. * 创建基本的 Container
  30. */
  31. export function createWorkflowContainer(opts: FreeLayoutProps): interfaces.Container {
  32. const container = PlaygroundMockTools.createContainer([
  33. FlowDocumentContainerModule,
  34. WorkflowDocumentContainerModule,
  35. MockContainerModule,
  36. ]);
  37. container.bind(WorkflowAutoLayoutTool).toSelf().inSingletonScope();
  38. const linesManager = container.get(WorkflowLinesManager);
  39. linesManager
  40. .registerContribution(WorkflowBezierLineContribution)
  41. .registerContribution(WorkflowFoldLineContribution);
  42. return container;
  43. }
  44. export const baseJSON: WorkflowJSON = {
  45. nodes: [
  46. {
  47. id: 'start_0',
  48. type: 'start',
  49. meta: {
  50. position: { x: 0, y: 0 },
  51. },
  52. data: undefined,
  53. },
  54. {
  55. id: 'condition_0',
  56. type: 'condition',
  57. meta: {
  58. position: { x: 400, y: 0 },
  59. },
  60. data: undefined,
  61. },
  62. {
  63. id: 'end_0',
  64. type: 'end',
  65. meta: {
  66. position: { x: 800, y: 0 },
  67. },
  68. data: undefined,
  69. },
  70. ],
  71. edges: [
  72. {
  73. sourceNodeID: 'start_0',
  74. targetNodeID: 'condition_0',
  75. },
  76. {
  77. sourceNodeID: 'condition_0',
  78. sourcePortID: 'if',
  79. targetNodeID: 'end_0',
  80. },
  81. {
  82. sourceNodeID: 'condition_0',
  83. sourcePortID: 'else',
  84. targetNodeID: 'end_0',
  85. },
  86. ],
  87. };
  88. export const nestJSON: WorkflowJSON = {
  89. nodes: [
  90. ...baseJSON.nodes,
  91. {
  92. id: 'loop_0',
  93. type: 'loop',
  94. meta: {
  95. position: { x: 1200, y: 0 },
  96. },
  97. data: undefined,
  98. blocks: [
  99. {
  100. id: 'break_0',
  101. type: 'break',
  102. meta: {
  103. position: { x: 0, y: 0 },
  104. },
  105. data: undefined,
  106. },
  107. {
  108. id: 'variable_0',
  109. type: 'variable',
  110. meta: {
  111. position: { x: 400, y: 0 },
  112. },
  113. data: undefined,
  114. },
  115. ],
  116. edges: [
  117. {
  118. sourceNodeID: 'break_0',
  119. targetNodeID: 'variable_0',
  120. },
  121. ],
  122. },
  123. ],
  124. edges: [...baseJSON.edges],
  125. };
  126. export async function createDocument(params?: {
  127. json: WorkflowJSON;
  128. opts: FreeLayoutProps;
  129. }): Promise<{
  130. document: WorkflowDocument;
  131. container: interfaces.Container;
  132. }> {
  133. const { json = baseJSON, opts = {} } = params || {};
  134. const container = createWorkflowContainer(opts);
  135. const document = container.get<WorkflowDocument>(WorkflowDocument);
  136. await document.fromJSON(json);
  137. return {
  138. document,
  139. container,
  140. };
  141. }
  142. export function createHookWrapper(
  143. container: interfaces.Container,
  144. entityId: string = 'start_0'
  145. ): any {
  146. // eslint-disable-next-line react/display-name
  147. return ({ children }: any) => (
  148. <PlaygroundReactProvider playgroundContainer={container}>
  149. <PlaygroundEntityContext.Provider value={container.get(WorkflowDocument).getNode(entityId)}>
  150. {children}
  151. </PlaygroundEntityContext.Provider>
  152. </PlaygroundReactProvider>
  153. );
  154. }
  155. export async function createSubCanvasNodes(document: WorkflowDocument) {
  156. await document.fromJSON({ nodes: [], edges: [] });
  157. const loopNode = await document.createWorkflowNode({
  158. id: 'loop_0',
  159. type: 'loop',
  160. meta: {
  161. position: { x: -100, y: 0 },
  162. subCanvas: () => {
  163. const parentNode = document.getNode('loop_0');
  164. const canvasNode = document.getNode('subCanvas_0');
  165. if (!parentNode || !canvasNode) {
  166. return;
  167. }
  168. return {
  169. isCanvas: false,
  170. parentNode,
  171. canvasNode,
  172. };
  173. },
  174. },
  175. });
  176. const subCanvasNode = await document.createWorkflowNode({
  177. id: 'subCanvas_0',
  178. type: FlowNodeBaseType.SUB_CANVAS,
  179. meta: {
  180. position: { x: 100, y: 0 },
  181. subCanvas: () => ({
  182. isCanvas: true,
  183. parentNode: document.getNode('loop_0')!,
  184. canvasNode: document.getNode('subCanvas_0')!,
  185. }),
  186. },
  187. });
  188. document.linesManager.createLine({
  189. from: loopNode.id,
  190. to: subCanvasNode.id,
  191. });
  192. const variableNode = await document.createWorkflowNode(
  193. {
  194. id: 'variable_0',
  195. type: 'variable',
  196. meta: {
  197. position: { x: 0, y: 0 },
  198. },
  199. },
  200. false,
  201. subCanvasNode.id
  202. );
  203. return {
  204. loopNode,
  205. subCanvasNode,
  206. variableNode,
  207. };
  208. }