@nocobase/flow-engine 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (597) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +30 -0
  3. package/lib/ContextPathProxy.d.ts +17 -0
  4. package/lib/ContextPathProxy.js +65 -0
  5. package/lib/ElementProxy.d.ts +17 -0
  6. package/lib/ElementProxy.js +93 -0
  7. package/lib/FlowContextProvider.d.ts +24 -0
  8. package/lib/FlowContextProvider.js +82 -0
  9. package/lib/FlowDefinition.d.ts +423 -0
  10. package/lib/FlowDefinition.js +257 -0
  11. package/lib/JSRunner.d.ts +32 -0
  12. package/lib/JSRunner.js +95 -0
  13. package/lib/ReactView.d.ts +20 -0
  14. package/lib/ReactView.js +120 -0
  15. package/lib/ViewScopedFlowEngine.d.ts +23 -0
  16. package/lib/ViewScopedFlowEngine.js +81 -0
  17. package/lib/acl/Acl.d.ts +31 -0
  18. package/lib/acl/Acl.js +115 -0
  19. package/lib/action-registry/BaseActionRegistry.d.ts +23 -0
  20. package/lib/action-registry/BaseActionRegistry.js +57 -0
  21. package/lib/action-registry/EngineActionRegistry.d.ts +20 -0
  22. package/lib/action-registry/EngineActionRegistry.js +47 -0
  23. package/lib/action-registry/ModelActionRegistry.d.ts +34 -0
  24. package/lib/action-registry/ModelActionRegistry.js +79 -0
  25. package/lib/components/DynamicFlowsEditor.d.ts +17 -0
  26. package/lib/components/DynamicFlowsEditor.js +49 -0
  27. package/lib/components/FieldModelRenderer.d.ts +10 -0
  28. package/lib/components/FieldModelRenderer.js +94 -0
  29. package/lib/components/FlowContextSelector.d.ts +11 -0
  30. package/lib/components/FlowContextSelector.js +221 -0
  31. package/lib/components/FlowErrorFallback.d.ts +25 -0
  32. package/lib/components/FlowErrorFallback.js +264 -0
  33. package/lib/components/FlowModelRenderer.d.ts +64 -0
  34. package/lib/components/FlowModelRenderer.js +254 -0
  35. package/lib/components/FormItem.d.ts +18 -0
  36. package/lib/components/FormItem.js +147 -0
  37. package/lib/components/common/FlowSettingsButton.d.ts +11 -0
  38. package/lib/components/common/FlowSettingsButton.js +66 -0
  39. package/lib/components/common/index.d.ts +9 -0
  40. package/lib/components/common/index.js +30 -0
  41. package/lib/components/common/withFlowDesignMode.d.ts +26 -0
  42. package/lib/components/common/withFlowDesignMode.js +61 -0
  43. package/lib/components/dnd/getMousePositionOnElement.d.ts +50 -0
  44. package/lib/components/dnd/getMousePositionOnElement.js +95 -0
  45. package/lib/components/dnd/index.d.ts +24 -0
  46. package/lib/components/dnd/index.js +164 -0
  47. package/lib/components/dnd/moveBlock.d.ts +33 -0
  48. package/lib/components/dnd/moveBlock.js +302 -0
  49. package/lib/components/index.d.ts +18 -0
  50. package/lib/components/index.js +48 -0
  51. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.d.ts +46 -0
  52. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +225 -0
  53. package/lib/components/settings/independents/dropdown/index.d.ts +9 -0
  54. package/lib/components/settings/independents/dropdown/index.js +30 -0
  55. package/lib/components/settings/independents/index.d.ts +1 -0
  56. package/lib/components/settings/independents/index.js +30 -0
  57. package/lib/components/settings/index.d.ts +10 -0
  58. package/lib/components/settings/index.js +32 -0
  59. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +24 -0
  60. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +501 -0
  61. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.d.ts +45 -0
  62. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +231 -0
  63. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +111 -0
  64. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +484 -0
  65. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.d.ts +26 -0
  66. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.js +342 -0
  67. package/lib/components/settings/wrappers/contextual/StepSettings.d.ts +23 -0
  68. package/lib/components/settings/wrappers/contextual/StepSettings.js +110 -0
  69. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.d.ts +20 -0
  70. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +206 -0
  71. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.d.ts +20 -0
  72. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.js +47 -0
  73. package/lib/components/settings/wrappers/contextual/index.d.ts +14 -0
  74. package/lib/components/settings/wrappers/contextual/index.js +40 -0
  75. package/lib/components/settings/wrappers/embedded/FlowSettings.d.ts +33 -0
  76. package/lib/components/settings/wrappers/embedded/FlowSettings.js +207 -0
  77. package/lib/components/settings/wrappers/embedded/FlowsSettings.d.ts +41 -0
  78. package/lib/components/settings/wrappers/embedded/FlowsSettings.js +84 -0
  79. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.d.ts +16 -0
  80. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +88 -0
  81. package/lib/components/settings/wrappers/embedded/index.d.ts +10 -0
  82. package/lib/components/settings/wrappers/embedded/index.js +32 -0
  83. package/lib/components/settings/wrappers/index.d.ts +2 -0
  84. package/lib/components/settings/wrappers/index.js +32 -0
  85. package/lib/components/subModel/AddSubModelButton.d.ts +62 -0
  86. package/lib/components/subModel/AddSubModelButton.js +415 -0
  87. package/lib/components/subModel/LazyDropdown.d.ts +55 -0
  88. package/lib/components/subModel/LazyDropdown.js +524 -0
  89. package/lib/components/subModel/index.d.ts +10 -0
  90. package/lib/components/subModel/index.js +32 -0
  91. package/lib/components/subModel/utils.d.ts +34 -0
  92. package/lib/components/subModel/utils.js +287 -0
  93. package/lib/components/variables/InlineVariableTag.d.ts +21 -0
  94. package/lib/components/variables/InlineVariableTag.js +123 -0
  95. package/lib/components/variables/SlateVariableEditor.d.ts +46 -0
  96. package/lib/components/variables/SlateVariableEditor.js +302 -0
  97. package/lib/components/variables/VariableInput.d.ts +11 -0
  98. package/lib/components/variables/VariableInput.js +322 -0
  99. package/lib/components/variables/VariableTag.d.ts +11 -0
  100. package/lib/components/variables/VariableTag.js +148 -0
  101. package/lib/components/variables/VariableTrigger.d.ts +20 -0
  102. package/lib/components/variables/VariableTrigger.js +136 -0
  103. package/lib/components/variables/index.d.ts +15 -0
  104. package/lib/components/variables/index.js +53 -0
  105. package/lib/components/variables/types.d.ts +93 -0
  106. package/lib/components/variables/types.js +24 -0
  107. package/lib/components/variables/useResolvedMetaTree.d.ts +19 -0
  108. package/lib/components/variables/useResolvedMetaTree.js +91 -0
  109. package/lib/components/variables/utils.d.ts +22 -0
  110. package/lib/components/variables/utils.js +177 -0
  111. package/lib/data-source/index.d.ts +180 -0
  112. package/lib/data-source/index.js +733 -0
  113. package/lib/data-source/jioToJoiSchema.d.ts +19 -0
  114. package/lib/data-source/jioToJoiSchema.js +114 -0
  115. package/lib/decorators/index.d.ts +9 -0
  116. package/lib/decorators/index.js +36 -0
  117. package/lib/decorators/largeField.d.ts +9 -0
  118. package/lib/decorators/largeField.js +42 -0
  119. package/lib/emitter.d.ts +16 -0
  120. package/lib/emitter.js +58 -0
  121. package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
  122. package/lib/event-registry/BaseEventRegistry.js +57 -0
  123. package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
  124. package/lib/event-registry/EngineEventRegistry.js +47 -0
  125. package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
  126. package/lib/event-registry/ModelEventRegistry.js +79 -0
  127. package/lib/executor/FlowExecutor.d.ts +26 -0
  128. package/lib/executor/FlowExecutor.js +262 -0
  129. package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
  130. package/lib/flow-registry/BaseFlowRegistry.js +86 -0
  131. package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
  132. package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
  133. package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
  134. package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
  135. package/lib/flow-registry/index.d.ts +11 -0
  136. package/lib/flow-registry/index.js +34 -0
  137. package/lib/flowContext.d.ts +215 -0
  138. package/lib/flowContext.js +1266 -0
  139. package/lib/flowEngine.d.ts +340 -0
  140. package/lib/flowEngine.js +781 -0
  141. package/lib/flowI18n.d.ts +46 -0
  142. package/lib/flowI18n.js +117 -0
  143. package/lib/flowSettings.d.ts +266 -0
  144. package/lib/flowSettings.js +850 -0
  145. package/lib/hooks/index.d.ts +14 -0
  146. package/lib/hooks/index.js +40 -0
  147. package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
  148. package/lib/hooks/useApplyAutoFlows.js +62 -0
  149. package/lib/hooks/useFlowModel.d.ts +29 -0
  150. package/lib/hooks/useFlowModel.js +72 -0
  151. package/lib/hooks/useFlowModelById.d.ts +11 -0
  152. package/lib/hooks/useFlowModelById.js +61 -0
  153. package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
  154. package/lib/hooks/useFlowSettingsContext.js +61 -0
  155. package/lib/hooks/useFlowStep.d.ts +17 -0
  156. package/lib/hooks/useFlowStep.js +56 -0
  157. package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
  158. package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
  159. package/lib/index.d.ts +27 -0
  160. package/lib/index.js +73 -0
  161. package/lib/locale/en-US.json +61 -0
  162. package/lib/locale/index.d.ts +141 -0
  163. package/lib/locale/index.js +70 -0
  164. package/lib/locale/zh-CN.json +61 -0
  165. package/lib/models/CollectionFieldModel.d.ts +50 -0
  166. package/lib/models/CollectionFieldModel.js +242 -0
  167. package/lib/models/DisplayItemModel.d.ts +12 -0
  168. package/lib/models/DisplayItemModel.js +41 -0
  169. package/lib/models/EditableItemModel.d.ts +12 -0
  170. package/lib/models/EditableItemModel.js +41 -0
  171. package/lib/models/FilterableItemModel.d.ts +12 -0
  172. package/lib/models/FilterableItemModel.js +41 -0
  173. package/lib/models/flowModel.d.ts +344 -0
  174. package/lib/models/flowModel.js +1133 -0
  175. package/lib/models/forkFlowModel.d.ts +83 -0
  176. package/lib/models/forkFlowModel.js +257 -0
  177. package/lib/models/index.d.ts +14 -0
  178. package/lib/models/index.js +40 -0
  179. package/lib/provider.d.ts +22 -0
  180. package/lib/provider.js +114 -0
  181. package/lib/resources/apiResource.d.ts +34 -0
  182. package/lib/resources/apiResource.js +153 -0
  183. package/lib/resources/baseRecordResource.d.ts +61 -0
  184. package/lib/resources/baseRecordResource.js +264 -0
  185. package/lib/resources/filterItem.d.ts +33 -0
  186. package/lib/resources/filterItem.js +93 -0
  187. package/lib/resources/flowResource.d.ts +45 -0
  188. package/lib/resources/flowResource.js +146 -0
  189. package/lib/resources/index.d.ts +15 -0
  190. package/lib/resources/index.js +42 -0
  191. package/lib/resources/multiRecordResource.d.ts +53 -0
  192. package/lib/resources/multiRecordResource.js +230 -0
  193. package/lib/resources/singleRecordResource.d.ts +23 -0
  194. package/lib/resources/singleRecordResource.js +111 -0
  195. package/lib/resources/sqlResource.d.ts +73 -0
  196. package/lib/resources/sqlResource.js +294 -0
  197. package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +38 -0
  198. package/lib/runjs-context/contexts/FlowRunJSContext.js +217 -0
  199. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +16 -0
  200. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +66 -0
  201. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +16 -0
  202. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +78 -0
  203. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +12 -0
  204. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +59 -0
  205. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +16 -0
  206. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +70 -0
  207. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +16 -0
  208. package/lib/runjs-context/contexts/JSItemRunJSContext.js +66 -0
  209. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +12 -0
  210. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +61 -0
  211. package/lib/runjs-context/contexts/LinkageRunJSContext.d.ts +12 -0
  212. package/lib/runjs-context/contexts/LinkageRunJSContext.js +62 -0
  213. package/lib/runjs-context/helpers.d.ts +17 -0
  214. package/lib/runjs-context/helpers.js +79 -0
  215. package/lib/runjs-context/index.d.ts +19 -0
  216. package/lib/runjs-context/index.js +57 -0
  217. package/lib/runjs-context/registry.d.ts +17 -0
  218. package/lib/runjs-context/registry.js +93 -0
  219. package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +16 -0
  220. package/lib/runjs-context/snippets/global/api-request-get.snippet.js +42 -0
  221. package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +16 -0
  222. package/lib/runjs-context/snippets/global/api-request-post.snippet.js +42 -0
  223. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +16 -0
  224. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +41 -0
  225. package/lib/runjs-context/snippets/global/copy-record-json.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/global/copy-record-json.snippet.js +42 -0
  227. package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.d.ts +11 -0
  228. package/lib/runjs-context/snippets/global/copy-to-clipboard.snippet.js +42 -0
  229. package/lib/runjs-context/snippets/global/log-json-record.snippet.d.ts +11 -0
  230. package/lib/runjs-context/snippets/global/log-json-record.snippet.js +42 -0
  231. package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
  232. package/lib/runjs-context/snippets/global/message-error.snippet.js +41 -0
  233. package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
  234. package/lib/runjs-context/snippets/global/message-success.snippet.js +41 -0
  235. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +16 -0
  236. package/lib/runjs-context/snippets/global/notification-open.snippet.js +43 -0
  237. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
  238. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +47 -0
  239. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
  240. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +47 -0
  241. package/lib/runjs-context/snippets/global/requireAsync.snippet.d.ts +16 -0
  242. package/lib/runjs-context/snippets/global/requireAsync.snippet.js +46 -0
  243. package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +16 -0
  244. package/lib/runjs-context/snippets/global/sleep.snippet.js +43 -0
  245. package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +16 -0
  246. package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +44 -0
  247. package/lib/runjs-context/snippets/global/view-navigation-push.snippet.d.ts +11 -0
  248. package/lib/runjs-context/snippets/global/view-navigation-push.snippet.js +44 -0
  249. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +16 -0
  250. package/lib/runjs-context/snippets/global/window-open.snippet.js +41 -0
  251. package/lib/runjs-context/snippets/index.d.ts +11 -0
  252. package/lib/runjs-context/snippets/index.js +94 -0
  253. package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +15 -0
  254. package/lib/runjs-context/snippets/libs/echarts-init.snippet.js +46 -0
  255. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +15 -0
  256. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.js +44 -0
  257. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +15 -0
  258. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.js +43 -0
  259. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +15 -0
  260. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +43 -0
  261. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +15 -0
  262. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +40 -0
  263. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +15 -0
  264. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.js +46 -0
  265. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +15 -0
  266. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +42 -0
  267. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +15 -0
  268. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js +46 -0
  269. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +15 -0
  270. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +41 -0
  271. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +15 -0
  272. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +41 -0
  273. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +15 -0
  274. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.js +46 -0
  275. package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.d.ts +11 -0
  276. package/lib/runjs-context/snippets/scene/jsblock/render-card.snippet.js +45 -0
  277. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +15 -0
  278. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.js +56 -0
  279. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +15 -0
  280. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.js +42 -0
  281. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +15 -0
  282. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.js +41 -0
  283. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +15 -0
  284. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.js +40 -0
  285. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +15 -0
  286. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.js +44 -0
  287. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +15 -0
  288. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.js +60 -0
  289. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +15 -0
  290. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.js +59 -0
  291. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +15 -0
  292. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.js +60 -0
  293. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +15 -0
  294. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.js +60 -0
  295. package/lib/runjs-context/snippets/types.d.ts +16 -0
  296. package/lib/runjs-context/snippets/types.js +24 -0
  297. package/lib/types.d.ts +398 -0
  298. package/lib/types.js +43 -0
  299. package/lib/utils/autoFlowError.d.ts +16 -0
  300. package/lib/utils/autoFlowError.js +53 -0
  301. package/lib/utils/constants.d.ts +29 -0
  302. package/lib/utils/constants.js +77 -0
  303. package/lib/utils/context.d.ts +40 -0
  304. package/lib/utils/context.js +63 -0
  305. package/lib/utils/createCollectionContextMeta.d.ts +11 -0
  306. package/lib/utils/createCollectionContextMeta.js +117 -0
  307. package/lib/utils/exceptions.d.ts +22 -0
  308. package/lib/utils/exceptions.js +62 -0
  309. package/lib/utils/flow-definitions.d.ts +11 -0
  310. package/lib/utils/flow-definitions.js +40 -0
  311. package/lib/utils/index.d.ts +22 -0
  312. package/lib/utils/index.js +117 -0
  313. package/lib/utils/inheritance.d.ts +16 -0
  314. package/lib/utils/inheritance.js +53 -0
  315. package/lib/utils/params-resolvers.d.ts +51 -0
  316. package/lib/utils/params-resolvers.js +309 -0
  317. package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
  318. package/lib/utils/parsePathnameToViewParams.js +84 -0
  319. package/lib/utils/safeGlobals.d.ts +16 -0
  320. package/lib/utils/safeGlobals.js +179 -0
  321. package/lib/utils/schema-utils.d.ts +40 -0
  322. package/lib/utils/schema-utils.js +161 -0
  323. package/lib/utils/serverContextParams.d.ts +28 -0
  324. package/lib/utils/serverContextParams.js +106 -0
  325. package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
  326. package/lib/utils/setupRuntimeContextSteps.js +88 -0
  327. package/lib/utils/translation.d.ts +18 -0
  328. package/lib/utils/translation.js +58 -0
  329. package/lib/utils/variablesParams.d.ts +51 -0
  330. package/lib/utils/variablesParams.js +150 -0
  331. package/lib/views/DialogComponent.d.ts +22 -0
  332. package/lib/views/DialogComponent.js +98 -0
  333. package/lib/views/DrawerComponent.d.ts +11 -0
  334. package/lib/views/DrawerComponent.js +101 -0
  335. package/lib/views/FlowView.d.ts +76 -0
  336. package/lib/views/FlowView.js +81 -0
  337. package/lib/views/PageComponent.d.ts +10 -0
  338. package/lib/views/PageComponent.js +167 -0
  339. package/lib/views/ViewNavigation.d.ts +45 -0
  340. package/lib/views/ViewNavigation.js +97 -0
  341. package/lib/views/createViewMeta.d.ts +16 -0
  342. package/lib/views/createViewMeta.js +171 -0
  343. package/lib/views/index.d.ts +13 -0
  344. package/lib/views/index.js +48 -0
  345. package/lib/views/useDialog.d.ts +32 -0
  346. package/lib/views/useDialog.js +199 -0
  347. package/lib/views/useDrawer.d.ts +33 -0
  348. package/lib/views/useDrawer.js +206 -0
  349. package/lib/views/usePage.d.ts +32 -0
  350. package/lib/views/usePage.js +193 -0
  351. package/lib/views/usePatchElement.d.ts +10 -0
  352. package/lib/views/usePatchElement.js +54 -0
  353. package/lib/views/usePopover.d.ts +17 -0
  354. package/lib/views/usePopover.js +159 -0
  355. package/package.json +37 -0
  356. package/src/ContextPathProxy.ts +45 -0
  357. package/src/ElementProxy.ts +69 -0
  358. package/src/FlowContextProvider.tsx +40 -0
  359. package/src/FlowDefinition.ts +275 -0
  360. package/src/JSRunner.ts +84 -0
  361. package/src/ReactView.tsx +104 -0
  362. package/src/ViewScopedFlowEngine.ts +75 -0
  363. package/src/__tests__/ElementProxy.test.ts +51 -0
  364. package/src/__tests__/JSRunner.test.ts +92 -0
  365. package/src/__tests__/ReactView.test.tsx +63 -0
  366. package/src/__tests__/context-path-proxy.test.ts +35 -0
  367. package/src/__tests__/flow-engine.test.ts +189 -0
  368. package/src/__tests__/flowContext.test.ts +2012 -0
  369. package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
  370. package/src/__tests__/flowI18n.test.ts +28 -0
  371. package/src/__tests__/flowModel.getFlows.test.ts +61 -0
  372. package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
  373. package/src/__tests__/flowRuntimeContext.test.ts +187 -0
  374. package/src/__tests__/flowSettings.open.test.tsx +1920 -0
  375. package/src/__tests__/flowSettings.test.ts +566 -0
  376. package/src/__tests__/globalFlowRegistry.test.ts +77 -0
  377. package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
  378. package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
  379. package/src/__tests__/path-aggregation.test.ts +85 -0
  380. package/src/__tests__/provider.test.tsx +28 -0
  381. package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
  382. package/src/__tests__/runjsContext.test.ts +60 -0
  383. package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
  384. package/src/acl/Acl.tsx +109 -0
  385. package/src/acl/__tests__/Acl.test.tsx +72 -0
  386. package/src/action-registry/BaseActionRegistry.ts +46 -0
  387. package/src/action-registry/EngineActionRegistry.ts +32 -0
  388. package/src/action-registry/ModelActionRegistry.ts +75 -0
  389. package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
  390. package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
  391. package/src/components/DynamicFlowsEditor.tsx +318 -0
  392. package/src/components/FieldModelRenderer.tsx +62 -0
  393. package/src/components/FlowContextSelector.tsx +255 -0
  394. package/src/components/FlowErrorFallback.tsx +316 -0
  395. package/src/components/FlowModelRenderer.tsx +428 -0
  396. package/src/components/FormItem.tsx +130 -0
  397. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
  398. package/src/components/common/FlowSettingsButton.tsx +30 -0
  399. package/src/components/common/index.ts +10 -0
  400. package/src/components/common/withFlowDesignMode.tsx +49 -0
  401. package/src/components/dnd/getMousePositionOnElement.ts +115 -0
  402. package/src/components/dnd/index.tsx +128 -0
  403. package/src/components/dnd/moveBlock.ts +379 -0
  404. package/src/components/index.ts +20 -0
  405. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
  406. package/src/components/settings/independents/dropdown/index.ts +10 -0
  407. package/src/components/settings/independents/index.ts +2 -0
  408. package/src/components/settings/index.ts +11 -0
  409. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
  410. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
  411. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
  412. package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
  413. package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
  414. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +217 -0
  415. package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
  416. package/src/components/settings/wrappers/contextual/index.ts +15 -0
  417. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
  418. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
  419. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
  420. package/src/components/settings/wrappers/embedded/index.ts +11 -0
  421. package/src/components/settings/wrappers/index.ts +5 -0
  422. package/src/components/subModel/AddSubModelButton.tsx +575 -0
  423. package/src/components/subModel/LazyDropdown.tsx +714 -0
  424. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
  425. package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
  426. package/src/components/subModel/__tests__/utils.test.ts +425 -0
  427. package/src/components/subModel/index.ts +12 -0
  428. package/src/components/subModel/utils.ts +278 -0
  429. package/src/components/variables/InlineVariableTag.tsx +97 -0
  430. package/src/components/variables/SlateVariableEditor.tsx +384 -0
  431. package/src/components/variables/VariableInput.tsx +342 -0
  432. package/src/components/variables/VariableTag.tsx +123 -0
  433. package/src/components/variables/VariableTrigger.tsx +116 -0
  434. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
  435. package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
  436. package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
  437. package/src/components/variables/__tests__/test-utils.tsx +62 -0
  438. package/src/components/variables/__tests__/utils.test.ts +310 -0
  439. package/src/components/variables/index.ts +16 -0
  440. package/src/components/variables/types.ts +100 -0
  441. package/src/components/variables/useResolvedMetaTree.ts +76 -0
  442. package/src/components/variables/utils.ts +192 -0
  443. package/src/data-source/__tests__/collection.test.ts +58 -0
  444. package/src/data-source/__tests__/index.test.ts +82 -0
  445. package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
  446. package/src/data-source/index.ts +812 -0
  447. package/src/data-source/jioToJoiSchema.ts +103 -0
  448. package/src/decorators/index.ts +10 -0
  449. package/src/decorators/largeField.ts +14 -0
  450. package/src/emitter.ts +33 -0
  451. package/src/event-registry/BaseEventRegistry.ts +40 -0
  452. package/src/event-registry/EngineEventRegistry.ts +26 -0
  453. package/src/event-registry/ModelEventRegistry.ts +69 -0
  454. package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
  455. package/src/executor/FlowExecutor.ts +256 -0
  456. package/src/executor/__tests__/eventStep.test.ts +157 -0
  457. package/src/executor/__tests__/flowExecutor.test.ts +163 -0
  458. package/src/flow-registry/BaseFlowRegistry.ts +91 -0
  459. package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
  460. package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
  461. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
  462. package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
  463. package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
  464. package/src/flow-registry/index.ts +12 -0
  465. package/src/flowContext.ts +1639 -0
  466. package/src/flowEngine.ts +905 -0
  467. package/src/flowI18n.ts +96 -0
  468. package/src/flowSettings.ts +1045 -0
  469. package/src/hooks/index.ts +15 -0
  470. package/src/hooks/useApplyAutoFlows.ts +51 -0
  471. package/src/hooks/useFlowModel.tsx +59 -0
  472. package/src/hooks/useFlowModelById.ts +37 -0
  473. package/src/hooks/useFlowSettingsContext.tsx +37 -0
  474. package/src/hooks/useFlowStep.tsx +19 -0
  475. package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
  476. package/src/index.ts +38 -0
  477. package/src/locale/en-US.json +61 -0
  478. package/src/locale/index.ts +38 -0
  479. package/src/locale/zh-CN.json +61 -0
  480. package/src/models/CollectionFieldModel.tsx +269 -0
  481. package/src/models/DisplayItemModel.tsx +13 -0
  482. package/src/models/EditableItemModel.tsx +13 -0
  483. package/src/models/FilterableItemModel.tsx +13 -0
  484. package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
  485. package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
  486. package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
  487. package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
  488. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
  489. package/src/models/__tests__/flowModel.test.ts +2746 -0
  490. package/src/models/__tests__/flowRegistry.test.ts +512 -0
  491. package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
  492. package/src/models/__tests__/model-actions.test.ts +70 -0
  493. package/src/models/__tests__/model-events.test.ts +69 -0
  494. package/src/models/flowModel.tsx +1398 -0
  495. package/src/models/forkFlowModel.ts +287 -0
  496. package/src/models/index.ts +17 -0
  497. package/src/provider.tsx +101 -0
  498. package/src/resources/__tests__/apiResource.test.ts +201 -0
  499. package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
  500. package/src/resources/__tests__/filterItem.test.ts +260 -0
  501. package/src/resources/__tests__/flowResource.test.ts +127 -0
  502. package/src/resources/apiResource.ts +148 -0
  503. package/src/resources/baseRecordResource.ts +279 -0
  504. package/src/resources/filterItem.ts +74 -0
  505. package/src/resources/flowResource.ts +143 -0
  506. package/src/resources/index.ts +17 -0
  507. package/src/resources/multiRecordResource.ts +219 -0
  508. package/src/resources/singleRecordResource.ts +83 -0
  509. package/src/resources/sqlResource.ts +299 -0
  510. package/src/runjs-context/contexts/FlowRunJSContext.ts +190 -0
  511. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +39 -0
  512. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +52 -0
  513. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +32 -0
  514. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +43 -0
  515. package/src/runjs-context/contexts/JSItemRunJSContext.ts +39 -0
  516. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +34 -0
  517. package/src/runjs-context/contexts/LinkageRunJSContext.ts +35 -0
  518. package/src/runjs-context/helpers.ts +56 -0
  519. package/src/runjs-context/index.ts +20 -0
  520. package/src/runjs-context/registry.ts +65 -0
  521. package/src/runjs-context/snippets/global/api-request-get.snippet.ts +20 -0
  522. package/src/runjs-context/snippets/global/api-request-post.snippet.ts +20 -0
  523. package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +19 -0
  524. package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +21 -0
  525. package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +21 -0
  526. package/src/runjs-context/snippets/global/log-json-record.snippet.ts +21 -0
  527. package/src/runjs-context/snippets/global/message-error.snippet.ts +20 -0
  528. package/src/runjs-context/snippets/global/message-success.snippet.ts +20 -0
  529. package/src/runjs-context/snippets/global/notification-open.snippet.ts +21 -0
  530. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +26 -0
  531. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +26 -0
  532. package/src/runjs-context/snippets/global/requireAsync.snippet.ts +24 -0
  533. package/src/runjs-context/snippets/global/sleep.snippet.ts +21 -0
  534. package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +22 -0
  535. package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +23 -0
  536. package/src/runjs-context/snippets/global/window-open.snippet.ts +19 -0
  537. package/src/runjs-context/snippets/index.ts +59 -0
  538. package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +24 -0
  539. package/src/runjs-context/snippets/scene/actions/collection-selected-count.snippet.ts +22 -0
  540. package/src/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.ts +21 -0
  541. package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +21 -0
  542. package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +18 -0
  543. package/src/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.ts +29 -0
  544. package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +20 -0
  545. package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +24 -0
  546. package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +19 -0
  547. package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +24 -0
  548. package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +24 -0
  549. package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +30 -0
  550. package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +34 -0
  551. package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +20 -0
  552. package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +19 -0
  553. package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +18 -0
  554. package/src/runjs-context/snippets/scene/jsitem/render-basic.snippet.ts +27 -0
  555. package/src/runjs-context/snippets/scene/linkage/set-disabled.snippet.ts +38 -0
  556. package/src/runjs-context/snippets/scene/linkage/set-field-value.snippet.ts +37 -0
  557. package/src/runjs-context/snippets/scene/linkage/set-required.snippet.ts +38 -0
  558. package/src/runjs-context/snippets/scene/linkage/toggle-visible.snippet.ts +38 -0
  559. package/src/runjs-context/snippets/types.ts +17 -0
  560. package/src/types.ts +474 -0
  561. package/src/utils/__tests__/context.test.ts +93 -0
  562. package/src/utils/__tests__/params-resolvers.test.ts +652 -0
  563. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
  564. package/src/utils/__tests__/safeGlobals.test.ts +29 -0
  565. package/src/utils/__tests__/utils.test.ts +1021 -0
  566. package/src/utils/__tests__/variablesParams.test.ts +52 -0
  567. package/src/utils/autoFlowError.ts +29 -0
  568. package/src/utils/constants.ts +60 -0
  569. package/src/utils/context.ts +70 -0
  570. package/src/utils/createCollectionContextMeta.ts +122 -0
  571. package/src/utils/exceptions.ts +36 -0
  572. package/src/utils/flow-definitions.ts +16 -0
  573. package/src/utils/index.ts +63 -0
  574. package/src/utils/inheritance.ts +39 -0
  575. package/src/utils/params-resolvers.ts +482 -0
  576. package/src/utils/parsePathnameToViewParams.ts +103 -0
  577. package/src/utils/safeGlobals.ts +188 -0
  578. package/src/utils/schema-utils.ts +201 -0
  579. package/src/utils/serverContextParams.ts +111 -0
  580. package/src/utils/setupRuntimeContextSteps.ts +89 -0
  581. package/src/utils/translation.ts +37 -0
  582. package/src/utils/variablesParams.ts +175 -0
  583. package/src/views/DialogComponent.tsx +79 -0
  584. package/src/views/DrawerComponent.tsx +72 -0
  585. package/src/views/FlowView.tsx +103 -0
  586. package/src/views/PageComponent.tsx +150 -0
  587. package/src/views/ViewNavigation.ts +122 -0
  588. package/src/views/__tests__/FlowView.test.ts +31 -0
  589. package/src/views/__tests__/ViewNavigation.test.ts +191 -0
  590. package/src/views/__tests__/usePatchElement.test.tsx +28 -0
  591. package/src/views/createViewMeta.ts +157 -0
  592. package/src/views/index.tsx +14 -0
  593. package/src/views/useDialog.tsx +192 -0
  594. package/src/views/useDrawer.tsx +205 -0
  595. package/src/views/usePage.tsx +182 -0
  596. package/src/views/usePatchElement.tsx +27 -0
  597. package/src/views/usePopover.tsx +131 -0
@@ -0,0 +1,1045 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { createForm, onFormValuesChange } from '@formily/core';
11
+ import { createSchemaField, FormProvider, ISchema } from '@formily/react';
12
+ import { define, observable, reaction } from '@formily/reactive';
13
+ import { Button, Collapse, Space, Tabs } from 'antd';
14
+ import _ from 'lodash';
15
+ import React from 'react';
16
+ import { DefaultSettingsIcon } from './components/settings/wrappers/contextual/DefaultSettingsIcon';
17
+ import { openStepSettingsDialog } from './components/settings/wrappers/contextual/StepSettingsDialog';
18
+ import { Emitter } from './emitter';
19
+ import { FlowRuntimeContext } from './flowContext';
20
+ import { FlowEngine, untracked } from '.';
21
+ import { FlowSettingsContextProvider, useFlowSettingsContext } from './hooks/useFlowSettingsContext';
22
+ import type { FlowModel } from './models';
23
+ import { StepSettingsDialogProps, ToolbarItemConfig } from './types';
24
+ import {
25
+ compileUiSchema,
26
+ FlowExitException,
27
+ getT,
28
+ resolveDefaultParams,
29
+ resolveStepUiSchema,
30
+ resolveUiMode,
31
+ setupRuntimeContextSteps,
32
+ } from './utils';
33
+ import { FlowStepContext } from './hooks/useFlowStep';
34
+
35
+ const Panel = Collapse.Panel;
36
+
37
+ /**
38
+ * 打开流程设置的参数接口
39
+ */
40
+ export interface FlowSettingsOpenOptions {
41
+ /** 目标模型实例(必填) */
42
+ model: FlowModel;
43
+ /** 是否打开预设(preset)步骤的配置 */
44
+ preset?: boolean;
45
+ /** 指定打开的单个流程 key(优先级高于 flowKeys) */
46
+ flowKey?: string;
47
+ /** 指定同时打开的多个流程 key(当 flowKey 存在时忽略) */
48
+ flowKeys?: string[];
49
+ /** 指定打开的步骤 key(配合 flowKey 使用) */
50
+ stepKey?: string;
51
+ /** 弹窗展现形式(drawer 或 dialog) */
52
+ uiMode?:
53
+ | 'dialog'
54
+ | 'drawer'
55
+ | 'embed'
56
+ | {
57
+ type?: 'dialog' | 'drawer' | 'embed';
58
+ props?: {
59
+ title?: string;
60
+ width?: number;
61
+ target?: any;
62
+ onOpen?: () => void;
63
+ onClose?: () => void;
64
+ /**
65
+ * 自定义弹窗底部内容
66
+ *
67
+ * 支持三种形式:
68
+ * 1. `React.ReactNode` - 直接替换整个底部内容
69
+ * 2. `Function` - 函数式自定义,接收原始底部内容和按钮组件,返回新的内容
70
+ * 3. `null` - 隐藏底部内容
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // 1. 直接替换底部内容
75
+ * footer: <div>Custom Footer</div>
76
+ *
77
+ * // 2. 函数式自定义 - 在原有按钮基础上添加内容
78
+ * footer: (originNode, { OkBtn, CancelBtn }) => (
79
+ * <div style={{ display: 'flex', justifyContent: 'space-between' }}>
80
+ * <span>Additional info</span>
81
+ * {originNode}
82
+ * </div>
83
+ * )
84
+ *
85
+ * // 3. 函数式自定义 - 完全重新组合按钮
86
+ * footer: (originNode, { OkBtn, CancelBtn }) => (
87
+ * <Space>
88
+ * <CancelBtn title="Close" />
89
+ * <Button type="link">Help</Button>
90
+ * <OkBtn title="Apply" />
91
+ * </Space>
92
+ * )
93
+ *
94
+ * // 4. 隐藏底部
95
+ * footer: null
96
+ * ```
97
+ */
98
+ footer?:
99
+ | React.ReactNode
100
+ | ((originNode: React.ReactNode, extra: { OkBtn: React.FC; CancelBtn: React.FC }) => React.ReactNode)
101
+ | null;
102
+ [key: string]: any;
103
+ };
104
+ };
105
+ /** 点击取消按钮后触发的回调(关闭后调用) */
106
+ onCancel?: () => void | Promise<void>;
107
+ /** 配置保存成功后触发的回调 */
108
+ onSaved?: () => void | Promise<void>;
109
+ }
110
+
111
+ export class FlowSettings {
112
+ public components: Record<string, any> = {};
113
+ public scopes: Record<string, any> = {};
114
+ private antdComponentsLoaded = false;
115
+ public enabled: boolean;
116
+ #forceEnabled = false; // 强制启用状态,主要用于设计模式下的强制启用
117
+ public toolbarItems: ToolbarItemConfig[] = [];
118
+ #emitter: Emitter = new Emitter();
119
+
120
+ constructor(engine: FlowEngine) {
121
+ // 初始默认为 false,由 SchemaComponentProvider 根据实际设计模式状态同步设置
122
+ this.enabled = false;
123
+ engine.context.defineProperty('flowSettingsEnabled', {
124
+ get: () => this.enabled,
125
+ cache: false,
126
+ });
127
+ // 添加默认的配置项目
128
+ this.addDefaultToolbarItems();
129
+
130
+ define(this, {
131
+ enabled: observable,
132
+ });
133
+ }
134
+
135
+ on(event: 'beforeOpen', callback: (...args: any[]) => void) {
136
+ this.#emitter.on(event, callback);
137
+ }
138
+
139
+ off(event: 'beforeOpen', callback: (...args: any[]) => void) {
140
+ this.#emitter.off(event, callback);
141
+ }
142
+
143
+ /**
144
+ * 添加默认的工具栏项目
145
+ * @private
146
+ */
147
+ private addDefaultToolbarItems(): void {
148
+ // 添加基础的配置菜单项目(原有的菜单功能)
149
+ this.toolbarItems.push({
150
+ key: 'settings-menu',
151
+ component: DefaultSettingsIcon,
152
+ sort: 0, // 默认为0,作为第一个添加的项目
153
+ });
154
+ }
155
+
156
+ /**
157
+ * 加载 FlowSettings 所需的资源。
158
+ * @returns {Promise<void>}
159
+ * @example
160
+ * await flowSettings.load();
161
+ */
162
+ public async load(): Promise<void> {
163
+ if (this.antdComponentsLoaded) {
164
+ console.log('FlowSettings: Antd components already loaded, skipping...');
165
+ return;
166
+ }
167
+
168
+ try {
169
+ // 动态导入 Antd 组件
170
+ const {
171
+ ArrayBase,
172
+ ArrayCards,
173
+ ArrayCollapse,
174
+ ArrayItems,
175
+ ArrayTable,
176
+ ArrayTabs,
177
+ Cascader,
178
+ Checkbox,
179
+ DatePicker,
180
+ Editable,
181
+ Form,
182
+ FormDialog,
183
+ FormDrawer,
184
+ FormButtonGroup,
185
+ FormCollapse,
186
+ FormGrid,
187
+ FormItem,
188
+ FormLayout,
189
+ FormStep,
190
+ FormTab,
191
+ Input,
192
+ NumberPicker,
193
+ Password,
194
+ PreviewText,
195
+ Radio,
196
+ Reset,
197
+ Select,
198
+ SelectTable,
199
+ Space,
200
+ Submit,
201
+ Switch,
202
+ TimePicker,
203
+ Transfer,
204
+ TreeSelect,
205
+ Upload,
206
+ } = await import('@formily/antd-v5');
207
+
208
+ // 单独导入 Button 组件
209
+ const { Button } = await import('antd');
210
+
211
+ // 注册基础组件
212
+ this.components.Form = Form;
213
+ this.components.FormDialog = FormDialog;
214
+ this.components.FormDrawer = FormDrawer;
215
+ this.components.FormItem = FormItem;
216
+ this.components.FormLayout = FormLayout;
217
+ this.components.FormGrid = FormGrid;
218
+ this.components.FormStep = FormStep;
219
+ this.components.FormTab = FormTab;
220
+ this.components.FormCollapse = FormCollapse;
221
+ this.components.FormButtonGroup = FormButtonGroup;
222
+
223
+ // 注册输入组件
224
+ this.components.Input = Input;
225
+ this.components.NumberPicker = NumberPicker;
226
+ this.components.Password = Password;
227
+
228
+ // 注册选择组件
229
+ this.components.Select = Select;
230
+ this.components.SelectTable = SelectTable;
231
+ this.components.Cascader = Cascader;
232
+ this.components.TreeSelect = TreeSelect;
233
+ this.components.Transfer = Transfer;
234
+
235
+ // 注册日期时间组件
236
+ this.components.DatePicker = DatePicker;
237
+ this.components.TimePicker = TimePicker;
238
+
239
+ // 注册选择组件
240
+ this.components.Checkbox = Checkbox;
241
+ this.components.Radio = Radio;
242
+ this.components.Switch = Switch;
243
+
244
+ // 注册数组组件
245
+ this.components.ArrayBase = ArrayBase;
246
+ this.components.ArrayCards = ArrayCards;
247
+ this.components.ArrayCollapse = ArrayCollapse;
248
+ this.components.ArrayItems = ArrayItems;
249
+ this.components.ArrayTable = ArrayTable;
250
+ this.components.ArrayTabs = ArrayTabs;
251
+
252
+ // 注册其他组件
253
+ this.components.Upload = Upload;
254
+ this.components.Space = Space;
255
+ this.components.Editable = Editable;
256
+ this.components.PreviewText = PreviewText;
257
+
258
+ // 注册按钮组件
259
+ this.components.Button = Button;
260
+ this.components.Submit = Submit;
261
+ this.components.Reset = Reset;
262
+
263
+ this.antdComponentsLoaded = true;
264
+ console.log('FlowSettings: Antd components loaded successfully');
265
+ } catch (error) {
266
+ console.error('FlowSettings: Failed to load Antd components:', error);
267
+ throw error;
268
+ }
269
+ }
270
+
271
+ /**
272
+ * 添加组件到 FlowSettings 的组件注册表中。
273
+ * 这些组件可以在 flow step 的 uiSchema 中使用。
274
+ * @param {Record<string, any>} components 要添加的组件对象
275
+ * @returns {void}
276
+ * @example
277
+ * flowSettings.registerComponents({ MyComponent, AnotherComponent });
278
+ */
279
+ public registerComponents(components: Record<string, any>): void {
280
+ Object.keys(components).forEach((name) => {
281
+ if (this.components[name]) {
282
+ console.warn(`FlowSettings: Component with name '${name}' is already registered and will be overwritten.`);
283
+ }
284
+ this.components[name] = components[name];
285
+ });
286
+ }
287
+
288
+ /**
289
+ * 添加作用域到 FlowSettings 的作用域注册表中。
290
+ * 这些作用域可以在 flow step 的 uiSchema 中使用。
291
+ * @param {Record<string, any>} scopes 要添加的作用域对象
292
+ * @returns {void}
293
+ * @example
294
+ * flowSettings.registerScopes({ useMyHook, myVariable, myFunction });
295
+ */
296
+ public registerScopes(scopes: Record<string, any>): void {
297
+ Object.keys(scopes).forEach((name) => {
298
+ if (this.scopes[name]) {
299
+ console.warn(`FlowSettings: Scope with name '${name}' is already registered and will be overwritten.`);
300
+ }
301
+ this.scopes[name] = scopes[name];
302
+ });
303
+ }
304
+
305
+ /**
306
+ * 启用流程设置组件的显示
307
+ * @example
308
+ * flowSettings.enable();
309
+ */
310
+ public enable(): void {
311
+ this.enabled = true;
312
+ }
313
+
314
+ public forceEnable() {
315
+ this.#forceEnabled = true;
316
+ this.enabled = true;
317
+ }
318
+
319
+ /**
320
+ * 禁用流程设置组件的显示
321
+ * @example
322
+ * flowSettings.disable();
323
+ */
324
+ public disable(): void {
325
+ if (this.#forceEnabled) {
326
+ return;
327
+ }
328
+ this.enabled = false;
329
+ }
330
+
331
+ public forceDisable() {
332
+ this.#forceEnabled = false;
333
+ this.enabled = false;
334
+ }
335
+
336
+ /**
337
+ * 添加扩展工具栏项目
338
+ * @param {ToolbarItemConfig} config 项目配置
339
+ * @example
340
+ * // 添加一个复制图标组件
341
+ * const CopyIcon = ({ model }) => {
342
+ * const handleCopy = () => {
343
+ * navigator.clipboard.writeText(model.uid);
344
+ * };
345
+ * return (
346
+ * <Tooltip title="复制">
347
+ * <CopyOutlined onClick={handleCopy} style={{ cursor: 'pointer', fontSize: 12 }} />
348
+ * </Tooltip>
349
+ * );
350
+ * };
351
+ *
352
+ * flowSettings.addToolbarItem({
353
+ * key: 'copy',
354
+ * component: CopyIcon,
355
+ * sort: 10 // 数字越小越靠右
356
+ * });
357
+ *
358
+ * // 添加下拉菜单项目组件
359
+ * const MoreActionsIcon = ({ model }) => {
360
+ * const menuItems = [
361
+ * { key: 'action1', label: '操作1', onClick: () => console.log('操作1', model) },
362
+ * { key: 'action2', label: '操作2', onClick: () => console.log('操作2', model) }
363
+ * ];
364
+ * return (
365
+ * <Dropdown menu={{ items: menuItems }} trigger={['hover']}>
366
+ * <MoreOutlined style={{ cursor: 'pointer', fontSize: 12 }} />
367
+ * </Dropdown>
368
+ * );
369
+ * };
370
+ *
371
+ * flowSettings.addToolbarItem({
372
+ * key: 'more-actions',
373
+ * component: MoreActionsIcon,
374
+ * visible: (model) => model.someCondition,
375
+ * sort: 20 // 数字越大越靠左
376
+ * });
377
+ */
378
+ public addToolbarItem(config: ToolbarItemConfig): void {
379
+ // 检查是否已存在相同 key 的项目
380
+ const existingIndex = this.toolbarItems.findIndex((item) => item.key === config.key);
381
+ if (existingIndex !== -1) {
382
+ console.warn(`FlowSettings: Toolbar item with key '${config.key}' already exists and will be replaced.`);
383
+ this.toolbarItems[existingIndex] = config;
384
+ } else {
385
+ this.toolbarItems.push(config);
386
+ }
387
+
388
+ // 按 sort 字段反向排序,sort 越小越靠右(先添加的在右边)
389
+ this.toolbarItems.sort((a, b) => (b.sort || 0) - (a.sort || 0));
390
+ }
391
+
392
+ /**
393
+ * 批量添加工具栏项目
394
+ * @param {ToolbarItemConfig[]} configs 项目配置数组
395
+ * @example
396
+ * flowSettings.addToolbarItems([
397
+ * { key: 'copy', component: CopyIcon, sort: 10 },
398
+ * { key: 'edit', component: EditIcon, sort: 20 }
399
+ * ]);
400
+ */
401
+ public addToolbarItems(configs: ToolbarItemConfig[]): void {
402
+ configs.forEach((config) => this.addToolbarItem(config));
403
+ }
404
+
405
+ /**
406
+ * 移除工具栏项目
407
+ * @param {string} key 项目的唯一标识
408
+ * @example
409
+ * flowSettings.removeToolbarItem('copy');
410
+ */
411
+ public removeToolbarItem(key: string): void {
412
+ const index = this.toolbarItems.findIndex((item) => item.key === key);
413
+ if (index !== -1) {
414
+ this.toolbarItems.splice(index, 1);
415
+ }
416
+ }
417
+
418
+ /**
419
+ * 获取所有工具栏项目配置
420
+ * @returns {ToolbarItemConfig[]} 所有项目配置
421
+ */
422
+ public getToolbarItems(): ToolbarItemConfig[] {
423
+ return [...this.toolbarItems];
424
+ }
425
+
426
+ /**
427
+ * 清空所有工具栏项目
428
+ * @example
429
+ * flowSettings.clearToolbarItems();
430
+ */
431
+ public clearToolbarItems(): void {
432
+ this.toolbarItems = [];
433
+ }
434
+
435
+ /**
436
+ * 显示单个步骤的配置界面
437
+ * @param {StepSettingsDialogProps} props 步骤设置对话框的属性
438
+ * @returns {Promise<any>} 返回表单提交的值
439
+ * @example
440
+ * const result = await flowSettings.openStepSettingsDialog({
441
+ * model: myModel,
442
+ * flowKey: 'myFlow',
443
+ * stepKey: 'myStep',
444
+ * dialogWidth: 800,
445
+ * dialogTitle: '自定义标题'
446
+ * });
447
+ */
448
+ public async openStepSettingsDialog(props: StepSettingsDialogProps): Promise<any> {
449
+ return await openStepSettingsDialog(props);
450
+ }
451
+
452
+ /**
453
+ * 渲染单个步骤的表单
454
+ * @private
455
+ * @param {any} uiSchema 步骤的 UI Schema
456
+ * @param {any} initialValues 表单初始值(在此方法中不直接使用,而是通过 form 实例获取)
457
+ * @param {any} flowEngine 流引擎实例,用于获取 scopes 和 components
458
+ * @param {any} form 表单实例(从外部传入以便统一管理)
459
+ * @returns {React.ReactElement} 渲染的表单元素
460
+ */
461
+ public renderStepForm({
462
+ uiSchema,
463
+ initialValues,
464
+ flowEngine,
465
+ form,
466
+ onFormValuesChange,
467
+ }: {
468
+ uiSchema: any;
469
+ initialValues: any;
470
+ flowEngine: any;
471
+ form?: any;
472
+ onFormValuesChange?: (form: any) => void;
473
+ }): React.ReactElement {
474
+ // 获取 scopes 和 components
475
+ const scopes = {
476
+ // 为 schema 表达式提供上下文能力(可在表达式中使用 useFlowSettingsContext 等)
477
+ useFlowSettingsContext,
478
+ ...(flowEngine?.flowSettings?.scopes || {}),
479
+ } as Record<string, any>;
480
+
481
+ // 包装为表单 schema(垂直布局),实际渲染时再进行 compile
482
+ const formSchema = {
483
+ type: 'object',
484
+ properties: {
485
+ layout: {
486
+ type: 'void',
487
+ 'x-component': 'FormLayout',
488
+ 'x-component-props': { layout: 'vertical' },
489
+ properties: uiSchema,
490
+ },
491
+ },
492
+ } as ISchema;
493
+
494
+ const compiledSchema = compileUiSchema(scopes, formSchema);
495
+ const SchemaField = createSchemaField();
496
+
497
+ return React.createElement(
498
+ FormProviderWithForm,
499
+ { form, initialValues, onFormValuesChange },
500
+ React.createElement(SchemaField as any, {
501
+ schema: compiledSchema,
502
+ components: flowEngine?.flowSettings?.components || {},
503
+ scope: scopes,
504
+ }),
505
+ );
506
+ }
507
+
508
+ /**
509
+ * 打开流程设置入口(聚合渲染多个 flow 的可配置步骤)
510
+ *
511
+ * 行为约定:
512
+ * - 必须提供 model 实例;用于解析 flow 定义、上下文与保存参数。
513
+ * - 当同时提供 flowKey 与 flowKeys 时,以 flowKey 为准(只处理单个 flow)。
514
+ * - 当提供 stepKey 时,应与某个 flowKey 组合使用;仅渲染该 flow 下命中的步骤。
515
+ * - 当外部明确指定了 flowKey + stepKey 且仅匹配到一个步骤时,采用“单步直出”表单(不使用折叠面板)。
516
+ * - 当未提供 stepKey,但最终仅匹配到一个步骤时,仍保持折叠面板的外观,以区别于上述“单步直出”样式。
517
+ * - uiMode 控制展示容器:'dialog' 或 'drawer',由 model.context.viewer 提供具体实现。
518
+ *
519
+ * 副作用:
520
+ * - 打开对应的视图容器;提交时逐步校验与保存每个 step 的参数,调用 before/after hooks,并最终触发 model.save()。
521
+ * - 通过 model.context.message 提示保存成功或错误信息。
522
+ *
523
+ * 参数:
524
+ * - options.model: FlowModel 实例(必填)。
525
+ * - options.preset?: 当为 true 时,仅渲染 flow 中标记了 preset=true 的步骤。
526
+ * - options.flowKey?: 目标 flow 的 key。
527
+ * - options.flowKeys?: 多个目标 flow 的 key 列表(当同时提供 flowKey 时被忽略)。
528
+ * - options.stepKey?: 目标步骤的 key(通常与 flowKey 搭配使用)。
529
+ * - options.uiMode?: 默认 'dialog'。
530
+ * - options.onCancel?: 取消按钮点击后触发的回调(无参数)。
531
+ * - options.onSaved?: 配置保存成功后触发的回调(无参数)。
532
+ *
533
+ * @param {FlowSettingsOpenOptions} options 打开选项
534
+ * @returns {Promise<boolean>} 是否成功打开弹窗
535
+ */
536
+ public async open(options: FlowSettingsOpenOptions): Promise<boolean> {
537
+ this.#emitter.emit('beforeOpen', options);
538
+ const { model, flowKey, flowKeys, stepKey, uiMode = 'dialog', preset, onCancel, onSaved } = options;
539
+
540
+ // 基础校验
541
+ if (!model) {
542
+ throw new Error('FlowSettings.open: model is required');
543
+ }
544
+
545
+ const t = getT(model);
546
+ const message = model.context?.message;
547
+
548
+ // 聚合渲染:准备需要处理的 flow 列表(flowKey 优先其余)
549
+ const allFlowsMap = model.getFlows();
550
+ const targetFlowKeys: string[] = (() => {
551
+ if (flowKey) return [flowKey];
552
+ if (Array.isArray(flowKeys) && flowKeys.length) return flowKeys;
553
+ return Array.from(allFlowsMap.keys());
554
+ })();
555
+
556
+ // 收集可配置的步骤:仅包含具备 uiSchema 且未被 hideInSettings 的步骤
557
+ type StepEntry = {
558
+ flowKey: string;
559
+ flowTitle: string;
560
+ stepKey: string;
561
+ stepTitle: string;
562
+ mergedUiSchema: any; // 合并后的 UI Schema(未包装)
563
+ initialValues: any;
564
+ previousParams: any;
565
+ beforeParamsSave?: Function;
566
+ afterParamsSave?: Function;
567
+ ctx: any; // FlowRuntimeContext
568
+ uiMode: any; // UI 模式
569
+ };
570
+
571
+ const entries: StepEntry[] = [];
572
+
573
+ // 确保 Formily 组件已就绪(SchemaField/控件/作用域等)
574
+ await this.load();
575
+
576
+ for (const fk of targetFlowKeys) {
577
+ const flow = model.getFlow(fk);
578
+ if (!flow) {
579
+ // 忽略无效 flowKey,但记录日志
580
+ console.warn(`FlowSettings.open: Flow with key '${fk}' not found`);
581
+ continue;
582
+ }
583
+
584
+ // 遍历步骤,筛选有可配置 UI 的步骤
585
+ for (const sk of Object.keys(flow.steps || {})) {
586
+ // 如明确指定了 stepKey,则仅处理对应步骤
587
+ if (stepKey && sk !== stepKey) continue;
588
+ const step = (flow.steps as any)[sk];
589
+ if (!preset && (!step || step.hideInSettings)) continue;
590
+ // 当指定仅打开预设步骤时,过滤掉未标记 preset 的步骤
591
+ if (preset && !step.preset) continue;
592
+
593
+ // 解析合并后的 uiSchema(包含 action 的 schema)
594
+ const mergedUiSchema = await resolveStepUiSchema(model, flow, step);
595
+ if (!mergedUiSchema || Object.keys(mergedUiSchema).length === 0) continue;
596
+
597
+ // 计算标题与 hooks
598
+ let stepTitle: string = step.title;
599
+ let beforeParamsSave = step.beforeParamsSave;
600
+ let afterParamsSave = step.afterParamsSave;
601
+ let actionDefaultParams: Record<string, any> = {};
602
+ let uiMode;
603
+ if (step.use) {
604
+ const action = (model as any).flowEngine?.getAction?.(step.use);
605
+ if (action) {
606
+ actionDefaultParams = action.defaultParams || {};
607
+ stepTitle = stepTitle || action.title;
608
+ beforeParamsSave = beforeParamsSave || action.beforeParamsSave;
609
+ afterParamsSave = afterParamsSave || action.afterParamsSave;
610
+ uiMode = action.uiMode;
611
+ }
612
+ }
613
+
614
+ // 构建 settings 上下文
615
+ const flowRuntimeContext = new FlowRuntimeContext(model as any, fk, 'settings');
616
+ setupRuntimeContextSteps(flowRuntimeContext as any, flow.steps, model as any, fk);
617
+ flowRuntimeContext.defineProperty('currentStep', { value: step });
618
+
619
+ // 解析默认值 + 当前参数
620
+ const modelStepParams = (model as any).getStepParams(fk, sk) || {};
621
+ const resolvedDefaultParams = await resolveDefaultParams(step.defaultParams, flowRuntimeContext as any);
622
+ const resolvedActionDefaults = await resolveDefaultParams(actionDefaultParams, flowRuntimeContext as any);
623
+ const initialValues = {
624
+ ...(resolvedActionDefaults || {}),
625
+ ...(resolvedDefaultParams || {}),
626
+ ...modelStepParams,
627
+ };
628
+
629
+ entries.push({
630
+ flowKey: fk,
631
+ flowTitle: t(flow.title) || fk,
632
+ stepKey: sk,
633
+ stepTitle: t(stepTitle) || sk,
634
+ initialValues,
635
+ previousParams: { ...(modelStepParams || {}) },
636
+ mergedUiSchema, // 存储合并后的 UI Schema,在 renderStepForm 中进行包装
637
+ beforeParamsSave,
638
+ afterParamsSave,
639
+ ctx: flowRuntimeContext,
640
+ uiMode: step.uiMode || uiMode,
641
+ });
642
+ }
643
+ }
644
+
645
+ if (entries.length === 0) {
646
+ if (!preset) {
647
+ message?.info?.(t('This model has no configurable flow settings'));
648
+ }
649
+ return false;
650
+ }
651
+
652
+ // 渲染视图(对话框/抽屉)
653
+ // 兼容新的 uiMode 定义:字符串或 { type, props }
654
+ const viewer = (model as any).context.viewer;
655
+ // 解析 uiMode,支持函数式
656
+ const resolvedUiMode =
657
+ entries.length === 1 ? await resolveUiMode(entries[0].uiMode || uiMode, entries[0].ctx) : uiMode;
658
+ const modeType = typeof resolvedUiMode === 'string' ? resolvedUiMode : resolvedUiMode.type || 'dialog';
659
+ const openView = viewer[modeType || 'dialog'].bind(viewer);
660
+ const flowEngine = (model as any).flowEngine as FlowEngine;
661
+ const scopes = {
662
+ // 为 schema 表达式提供上下文能力(可在表达式中使用 useFlowSettingsContext 等)
663
+ useFlowSettingsContext,
664
+ ...(flowEngine?.flowSettings?.scopes || {}),
665
+ } as Record<string, any>;
666
+
667
+ let modeProps: Record<string, any> =
668
+ typeof resolvedUiMode === 'object' && resolvedUiMode ? resolvedUiMode.props || {} : {};
669
+
670
+ if (modeType === 'embed') {
671
+ const target = document.querySelector<HTMLDivElement>('#nocobase-embed-container');
672
+ const onOpen = modeProps.onOpen;
673
+ const onClose = modeProps.onClose;
674
+
675
+ if (target) {
676
+ target.innerHTML = ''; // 清空容器内原有内容
677
+ }
678
+
679
+ modeProps = {
680
+ target,
681
+ styles: {
682
+ body: {
683
+ padding: flowEngine.context.themeToken?.padding,
684
+ },
685
+ },
686
+ ...modeProps,
687
+ onOpen() {
688
+ target.style.width = modeProps.width || '33.3%';
689
+ target.style.maxWidth = modeProps.maxWidth || '800px';
690
+ target.style.minWidth = modeProps.minWidth || '0px';
691
+ onOpen?.();
692
+ },
693
+ onClose() {
694
+ target.style.width = 'auto';
695
+ target.style.maxWidth = 'none';
696
+ target.style.minWidth = 'auto';
697
+ onClose?.();
698
+ },
699
+ };
700
+ }
701
+
702
+ // 将步骤分组到 flow 下,用于 Collapse 分组展示
703
+ const grouped: Record<string, { title: string; steps: StepEntry[] }> = {};
704
+ entries.forEach((e) => {
705
+ if (!grouped[e.flowKey]) grouped[e.flowKey] = { title: e.flowTitle, steps: [] };
706
+ grouped[e.flowKey].steps.push(e);
707
+ });
708
+
709
+ // 为每个步骤创建独立的表单实例,互不干扰
710
+ const forms = new Map<string, ReturnType<typeof createForm>>();
711
+ const keyOf = (e: { flowKey: string; stepKey: string }) => `${e.flowKey}::${e.stepKey}`;
712
+
713
+ entries.forEach((e) => {
714
+ const form = createForm({ initialValues: compileUiSchema(scopes, e.initialValues) });
715
+ forms.set(keyOf(e), form);
716
+ });
717
+
718
+ // 判定是否存在多个 flow
719
+ const flowKeysOrdered = Object.keys(grouped);
720
+ const multipleFlows = flowKeysOrdered.length > 1;
721
+
722
+ const getTitle = () => {
723
+ // 情况 A:明确指定了 flowKey + stepKey 且唯一匹配 => 返回 step 标题
724
+ if (flowKey && stepKey && entries.length === 1) {
725
+ return entries[0].stepTitle;
726
+ }
727
+
728
+ if (!multipleFlows && entries.length > 0) {
729
+ // 情况 B:只有一个flow且未指定stepKey => 返回第一个步骤标题
730
+ return entries[0].stepTitle;
731
+ }
732
+
733
+ // 情况 C:多 flow 分组渲染 => 返回空标题
734
+ return '';
735
+ };
736
+
737
+ const dispose = { value: () => {} };
738
+ // 支持 uiMode 函数中使用响应式对象
739
+ const autoUpdateViewProps = (step, currentDialog) => {
740
+ dispose.value = reaction(
741
+ () => {
742
+ return resolveUiMode(step.uiMode || uiMode, step.ctx);
743
+ },
744
+ (newValue) => {
745
+ newValue
746
+ .then((newUiMode: any) => {
747
+ if (_.isPlainObject(newUiMode?.props)) {
748
+ currentDialog.update(newUiMode.props);
749
+ }
750
+ })
751
+ .catch((error) => {
752
+ console.warn('Error resolving uiMode:', error);
753
+ });
754
+ },
755
+ );
756
+ };
757
+
758
+ openView({
759
+ // 默认标题与宽度可被传入的 props 覆盖
760
+ title: modeProps.title || getTitle(),
761
+ width: modeProps.width ?? 600,
762
+ destroyOnClose: true,
763
+ onClose: () => dispose.value(),
764
+ zIndex: 5000,
765
+ // 允许透传其它 props(如 maskClosable、footer 等),但确保 content 由我们接管
766
+ ...modeProps,
767
+ content: (currentView, viewCtx) => {
768
+ viewCtx?.defineMethod('getStepFormValues', (flowKey: string, stepKey: string) => {
769
+ return forms.get(keyOf({ flowKey, stepKey }))?.values;
770
+ });
771
+ // 渲染单个 step 表单(无 JSX):FormProvider + SchemaField
772
+ const renderStepForm = (entry: StepEntry) => {
773
+ const form = forms.get(keyOf(entry));
774
+ if (!form) return null;
775
+
776
+ entry.ctx.view = currentView;
777
+
778
+ return React.createElement(
779
+ FlowSettingsContextProvider as any,
780
+ { value: entry.ctx },
781
+ React.createElement(
782
+ FlowStepContext.Provider,
783
+ {
784
+ value: {
785
+ params: untracked(() => ({ ...entry.initialValues, ...form.values })),
786
+ path: `${model.uid}_${entry.flowKey}_${entry.stepKey}`,
787
+ },
788
+ },
789
+ this.renderStepForm({
790
+ uiSchema: entry.mergedUiSchema,
791
+ initialValues: entry.initialValues,
792
+ flowEngine,
793
+ form,
794
+ }),
795
+ ),
796
+ );
797
+ };
798
+
799
+ const renderStepPanels = (steps: StepEntry[]) =>
800
+ steps.map((s) => React.createElement(Panel, { header: s.stepTitle, key: keyOf(s) }, renderStepForm(s)));
801
+
802
+ // 生成 Tabs 的 items,每个 flow 一个 Tab,内容为其步骤的折叠面板(如果只有一个步骤,会显示成表单)
803
+ const toFlowTabItem = (fk: string) => {
804
+ const group = grouped[fk];
805
+ return {
806
+ key: fk,
807
+ label: t(group.title) || fk,
808
+ children:
809
+ group.steps.length > 1
810
+ ? React.createElement(
811
+ Collapse,
812
+ { defaultActiveKey: group.steps.map((s) => keyOf(s)) },
813
+ ...renderStepPanels(group.steps),
814
+ )
815
+ : renderStepForm(group.steps[0]),
816
+ };
817
+ };
818
+
819
+ const renderStepsContainer = (): React.ReactNode => {
820
+ // 情况 A:明确指定了 flowKey + stepKey 且唯一匹配 => 直出单步表单(不使用折叠面板)
821
+ if (flowKey && stepKey && entries.length === 1) {
822
+ const step = entries[0];
823
+ autoUpdateViewProps(step, currentView);
824
+ return renderStepForm(step);
825
+ }
826
+
827
+ if (!multipleFlows) {
828
+ const step = entries[0];
829
+ autoUpdateViewProps(step, currentView);
830
+ // 情况 B:未提供 stepKey 且仅有一个步骤 => 仍保持折叠面板外观(与情况 A 一致)
831
+ return renderStepForm(entries[0]);
832
+ }
833
+
834
+ // 情况 C:多 flow 分组渲染 => 使用 Tabs(每个 flow 一个 Tab)
835
+ const items = flowKeysOrdered.map((fk) => toFlowTabItem(fk));
836
+ const defaultActiveKey = flowKey && grouped[flowKey] ? flowKey : flowKeysOrdered[0];
837
+ return React.createElement(Tabs as any, { items, defaultActiveKey });
838
+ };
839
+
840
+ const onSaveAll = async () => {
841
+ try {
842
+ // 逐步提交并保存
843
+ // 顺序:submit -> setStepParams -> beforeParamsSave -> model.save -> afterParamsSave
844
+ for (const e of entries) {
845
+ const form = forms.get(keyOf(e));
846
+ if (!form) continue;
847
+ await form.submit();
848
+ const currentValues = form.values;
849
+ (model as any).setStepParams(e.flowKey, e.stepKey, currentValues);
850
+
851
+ if (typeof e.beforeParamsSave === 'function') {
852
+ await e.beforeParamsSave(e.ctx, currentValues, e.previousParams);
853
+ }
854
+ }
855
+
856
+ await model.saveStepParams();
857
+ message?.success?.(t('Configuration saved'));
858
+
859
+ for (const e of entries) {
860
+ const form = forms.get(keyOf(e));
861
+ if (!form) continue;
862
+ const currentValues = form.values;
863
+ if (typeof e.afterParamsSave === 'function') {
864
+ await e.afterParamsSave(e.ctx, currentValues, e.previousParams);
865
+ }
866
+ }
867
+
868
+ currentView.close();
869
+
870
+ // 触发保存成功回调
871
+ try {
872
+ await onSaved?.();
873
+ } catch (cbErr) {
874
+ console.error('FlowSettings.open: onSaved callback error', cbErr);
875
+ }
876
+ } catch (err) {
877
+ if (err instanceof FlowExitException) {
878
+ currentView.close();
879
+ return;
880
+ }
881
+ console.error('FlowSettings.open: save error', err);
882
+ message?.error?.(t('Error saving configuration, please check console'));
883
+ }
884
+ };
885
+
886
+ currentView.submit = onSaveAll;
887
+
888
+ const stepsEl = renderStepsContainer();
889
+ const Cancel = (props: { title?: string }) => {
890
+ return React.createElement(
891
+ Button,
892
+ {
893
+ onClick: async () => {
894
+ currentView.close();
895
+ try {
896
+ await onCancel?.();
897
+ } catch (cbErr) {
898
+ console.error('FlowSettings.open: onCancel callback error', cbErr);
899
+ }
900
+ },
901
+ },
902
+ props.title || t('Cancel'),
903
+ );
904
+ };
905
+ const Save = (props: { title?: string }) => {
906
+ return React.createElement(Button, { type: 'primary', onClick: onSaveAll }, props.title || t('Save'));
907
+ };
908
+
909
+ let footerButtons = React.createElement(
910
+ Space,
911
+ { align: 'end' },
912
+ React.createElement(Cancel),
913
+ React.createElement(Save),
914
+ );
915
+
916
+ if (modeProps.footer) {
917
+ footerButtons = _.isFunction(modeProps.footer)
918
+ ? modeProps.footer(footerButtons, {
919
+ OkBtn: Save,
920
+ CancelBtn: Cancel,
921
+ })
922
+ : modeProps.footer;
923
+ }
924
+
925
+ if (modeProps.footer === null) {
926
+ footerButtons = null;
927
+ }
928
+
929
+ let footerEl;
930
+ if (currentView.Footer) {
931
+ footerEl = React.createElement(currentView.Footer, null, footerButtons);
932
+ }
933
+
934
+ return React.createElement(React.Fragment, null, stepsEl, footerEl);
935
+ },
936
+ });
937
+
938
+ return true;
939
+ }
940
+
941
+ // =============================
942
+ // Dynamic flows editor (disabled)
943
+ // Kept as comments to preserve context
944
+ // =============================
945
+ /*
946
+ public async openDynamicFlowsEditor(
947
+ options: Pick<FlowSettingsOpenOptions, 'model' | 'uiMode' | 'onCancel'> & {
948
+ onSaved?: (flows: FlowDefinition[]) => void | Promise<void>;
949
+ },
950
+ ) {
951
+ const { model, uiMode = 'dialog', onCancel, onSaved } = options;
952
+ const t = getT(model);
953
+ const message = model.context?.message;
954
+
955
+ // 构造响应式 value(深度可变)
956
+ const base = model.getDynamicFlows() || [];
957
+ const reactiveFlows = observable(JSON.parse(JSON.stringify(base)));
958
+
959
+ // 打开视图
960
+ const viewer = (model as any).context.viewer;
961
+ const modeType: 'dialog' | 'drawer' = typeof uiMode === 'string' ? uiMode : uiMode.type;
962
+ const modeProps: Record<string, any> = typeof uiMode === 'object' && uiMode ? uiMode.props || {} : {};
963
+ const openView = viewer[modeType].bind(viewer);
964
+
965
+ openView({
966
+ title: modeProps.title,
967
+ width: modeProps.width ?? 800,
968
+ destroyOnClose: true,
969
+ ...modeProps,
970
+ content: (currentDialog) => {
971
+ const editorEl = React.createElement(DynamicFlowsEditor as any, { value: reactiveFlows, model });
972
+
973
+ const onSubmit = async () => {
974
+ try {
975
+ const plain = JSON.parse(JSON.stringify(reactiveFlows));
976
+ (model as any).setDynamicFlows(plain as FlowDefinition[]);
977
+ await (model as any).saveDynamicFlows();
978
+ message?.success?.(t('Configuration saved'));
979
+ currentDialog.close();
980
+ try {
981
+ await onSaved?.(plain);
982
+ } catch (cbErr) {
983
+ console.error('FlowSettings.openDynamicFlowsEditor: onSaved callback error', cbErr);
984
+ }
985
+ } catch (err) {
986
+ console.error('FlowSettings.openDynamicFlowsEditor: save error', err);
987
+ message?.error?.(t('Error saving configuration, please check console'));
988
+ }
989
+ };
990
+
991
+ const footer = React.createElement(
992
+ currentDialog.Footer,
993
+ null,
994
+ React.createElement(
995
+ Space,
996
+ { align: 'end' },
997
+ React.createElement(
998
+ Button,
999
+ {
1000
+ onClick: async () => {
1001
+ currentDialog.close();
1002
+ try {
1003
+ await onCancel?.();
1004
+ } catch (cbErr) {
1005
+ console.error('FlowSettings.openDynamicFlowsEditor: onCancel callback error', cbErr);
1006
+ }
1007
+ },
1008
+ },
1009
+ t('Cancel'),
1010
+ ),
1011
+ React.createElement(Button, { type: 'primary', onClick: onSubmit }, t('OK')),
1012
+ ),
1013
+ );
1014
+
1015
+ return React.createElement(React.Fragment, null, editorEl, footer);
1016
+ },
1017
+ });
1018
+ }
1019
+ */
1020
+ }
1021
+
1022
+ function FormProviderWithForm({
1023
+ children,
1024
+ form,
1025
+ initialValues,
1026
+ onFormValuesChange: _onFormValuesChange,
1027
+ }: {
1028
+ children?: React.ReactNode;
1029
+ form?: any;
1030
+ initialValues?: Record<string, any>;
1031
+ onFormValuesChange?: (form: any) => void;
1032
+ }) {
1033
+ const formInstanceRef = React.useRef<any>(form);
1034
+
1035
+ if (!formInstanceRef.current) {
1036
+ formInstanceRef.current = createForm({
1037
+ initialValues,
1038
+ effects() {
1039
+ onFormValuesChange(_onFormValuesChange);
1040
+ },
1041
+ });
1042
+ }
1043
+
1044
+ return React.createElement(FormProvider as any, { form: formInstanceRef.current }, children);
1045
+ }