@nocobase/flow-engine 2.0.0-beta.9 → 2.1.0-beta.1

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 (245) hide show
  1. package/lib/BlockScopedFlowEngine.js +0 -1
  2. package/lib/FlowDefinition.d.ts +2 -0
  3. package/lib/JSRunner.d.ts +6 -0
  4. package/lib/JSRunner.js +32 -2
  5. package/lib/ViewScopedFlowEngine.js +3 -0
  6. package/lib/acl/Acl.js +13 -3
  7. package/lib/components/FlowContextSelector.js +155 -10
  8. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +2 -1
  9. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +76 -15
  10. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +24 -4
  11. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +5 -1
  12. package/lib/components/variables/VariableInput.js +9 -4
  13. package/lib/components/variables/VariableTag.js +46 -39
  14. package/lib/components/variables/utils.d.ts +7 -0
  15. package/lib/components/variables/utils.js +42 -2
  16. package/lib/data-source/index.d.ts +7 -27
  17. package/lib/data-source/index.js +81 -51
  18. package/lib/executor/FlowExecutor.d.ts +2 -1
  19. package/lib/executor/FlowExecutor.js +163 -22
  20. package/lib/flowContext.d.ts +230 -7
  21. package/lib/flowContext.js +2267 -148
  22. package/lib/flowEngine.d.ts +21 -0
  23. package/lib/flowEngine.js +56 -8
  24. package/lib/flowI18n.js +6 -4
  25. package/lib/flowSettings.js +17 -11
  26. package/lib/index.d.ts +7 -1
  27. package/lib/index.js +21 -0
  28. package/lib/locale/en-US.json +9 -2
  29. package/lib/locale/index.d.ts +14 -0
  30. package/lib/locale/zh-CN.json +8 -1
  31. package/lib/models/CollectionFieldModel.d.ts +1 -0
  32. package/lib/models/CollectionFieldModel.js +3 -2
  33. package/lib/models/flowModel.js +12 -1
  34. package/lib/provider.js +5 -5
  35. package/lib/resources/baseRecordResource.d.ts +5 -0
  36. package/lib/resources/baseRecordResource.js +24 -0
  37. package/lib/resources/multiRecordResource.d.ts +1 -0
  38. package/lib/resources/multiRecordResource.js +11 -4
  39. package/lib/resources/singleRecordResource.js +2 -0
  40. package/lib/resources/sqlResource.d.ts +4 -3
  41. package/lib/resources/sqlResource.js +8 -3
  42. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +12 -2
  43. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +2 -2
  44. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  45. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  46. package/lib/runjs-context/contexts/JSItemRunJSContext.js +12 -2
  47. package/lib/runjs-context/contexts/base.js +706 -41
  48. package/lib/runjs-context/contributions.d.ts +33 -0
  49. package/lib/runjs-context/contributions.js +88 -0
  50. package/lib/runjs-context/helpers.js +12 -1
  51. package/lib/runjs-context/setup.js +6 -0
  52. package/lib/runjs-context/snippets/global/api-request.snippet.js +3 -3
  53. package/lib/runjs-context/snippets/global/import-esm.snippet.js +2 -3
  54. package/lib/runjs-context/snippets/global/query-selector.snippet.js +8 -3
  55. package/lib/runjs-context/snippets/global/require-amd.snippet.js +1 -1
  56. package/lib/runjs-context/snippets/index.d.ts +11 -1
  57. package/lib/runjs-context/snippets/index.js +61 -40
  58. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.js +10 -7
  59. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +3 -3
  60. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +2 -2
  61. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.js +2 -2
  62. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +2 -2
  63. package/lib/runjs-context/snippets/scene/block/render-react.snippet.js +1 -1
  64. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +1 -1
  65. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +1 -1
  66. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +5 -5
  67. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +6 -6
  68. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +3 -4
  69. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.js +1 -1
  70. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.js +20 -3
  71. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.js +1 -1
  72. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.js +1 -1
  73. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +3 -3
  74. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +3 -3
  75. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +2 -2
  76. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +1 -1
  77. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.js +2 -2
  78. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +6 -3
  79. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +3 -1
  80. package/lib/runjsLibs.d.ts +28 -0
  81. package/lib/runjsLibs.js +532 -0
  82. package/lib/scheduler/ModelOperationScheduler.d.ts +2 -0
  83. package/lib/scheduler/ModelOperationScheduler.js +25 -21
  84. package/lib/types.d.ts +27 -0
  85. package/lib/utils/associationObjectVariable.d.ts +2 -2
  86. package/lib/utils/createCollectionContextMeta.js +1 -0
  87. package/lib/utils/createEphemeralContext.js +2 -2
  88. package/lib/utils/dateVariable.d.ts +16 -0
  89. package/lib/utils/dateVariable.js +380 -0
  90. package/lib/utils/exceptions.d.ts +7 -0
  91. package/lib/utils/exceptions.js +10 -0
  92. package/lib/utils/index.d.ts +8 -3
  93. package/lib/utils/index.js +45 -0
  94. package/lib/utils/params-resolvers.js +16 -9
  95. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  96. package/lib/utils/resolveModuleUrl.js +65 -0
  97. package/lib/utils/resolveRunJSObjectValues.d.ts +16 -0
  98. package/lib/utils/resolveRunJSObjectValues.js +61 -0
  99. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  100. package/lib/utils/runjsModuleLoader.js +422 -0
  101. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  102. package/lib/utils/runjsTemplateCompat.js +743 -0
  103. package/lib/utils/runjsValue.d.ts +29 -0
  104. package/lib/utils/runjsValue.js +275 -0
  105. package/lib/utils/safeGlobals.d.ts +18 -8
  106. package/lib/utils/safeGlobals.js +164 -17
  107. package/lib/utils/schema-utils.d.ts +10 -0
  108. package/lib/utils/schema-utils.js +61 -0
  109. package/lib/views/createViewMeta.d.ts +0 -7
  110. package/lib/views/createViewMeta.js +19 -70
  111. package/lib/views/index.d.ts +1 -2
  112. package/lib/views/index.js +4 -3
  113. package/lib/views/useDialog.js +7 -2
  114. package/lib/views/useDrawer.js +7 -2
  115. package/lib/views/usePage.d.ts +4 -0
  116. package/lib/views/usePage.js +43 -6
  117. package/lib/views/usePopover.js +4 -1
  118. package/lib/views/viewEvents.d.ts +17 -0
  119. package/lib/views/viewEvents.js +90 -0
  120. package/package.json +4 -4
  121. package/src/BlockScopedFlowEngine.ts +2 -5
  122. package/src/JSRunner.ts +44 -2
  123. package/src/ViewScopedFlowEngine.ts +4 -0
  124. package/src/__tests__/JSRunner.test.ts +64 -0
  125. package/src/__tests__/createViewMeta.popup.test.ts +62 -1
  126. package/src/__tests__/flowContext.test.ts +693 -1
  127. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  128. package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
  129. package/src/__tests__/flowRunJSContextDefine.test.ts +63 -0
  130. package/src/__tests__/flowRuntimeContext.test.ts +2 -1
  131. package/src/__tests__/flowSettings.open.test.tsx +123 -19
  132. package/src/__tests__/runjsContext.test.ts +10 -7
  133. package/src/__tests__/runjsContextImplementations.test.ts +34 -3
  134. package/src/__tests__/runjsContextRuntime.test.ts +3 -3
  135. package/src/__tests__/runjsContributions.test.ts +89 -0
  136. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  137. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  138. package/src/__tests__/runjsLocales.test.ts +4 -1
  139. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  140. package/src/__tests__/runjsRuntimeFeatures.test.ts +166 -0
  141. package/src/__tests__/runjsSnippets.test.ts +40 -3
  142. package/src/acl/Acl.tsx +3 -3
  143. package/src/components/FlowContextSelector.tsx +208 -12
  144. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +2 -1
  145. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  146. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +109 -16
  147. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +41 -7
  148. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -2
  149. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +157 -5
  150. package/src/components/variables/VariableInput.tsx +12 -4
  151. package/src/components/variables/VariableTag.tsx +54 -45
  152. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +260 -3
  153. package/src/components/variables/__tests__/VariableTag.test.tsx +50 -0
  154. package/src/components/variables/__tests__/utils.test.ts +81 -3
  155. package/src/components/variables/utils.ts +67 -6
  156. package/src/data-source/index.ts +85 -110
  157. package/src/executor/FlowExecutor.ts +200 -23
  158. package/src/executor/__tests__/flowExecutor.test.ts +66 -0
  159. package/src/flowContext.ts +2986 -211
  160. package/src/flowEngine.ts +59 -8
  161. package/src/flowI18n.ts +7 -5
  162. package/src/flowSettings.ts +18 -12
  163. package/src/index.ts +14 -1
  164. package/src/locale/en-US.json +9 -2
  165. package/src/locale/zh-CN.json +8 -1
  166. package/src/models/CollectionFieldModel.tsx +3 -1
  167. package/src/models/__tests__/dispatchEvent.when.test.ts +554 -0
  168. package/src/models/__tests__/flowModel.test.ts +20 -4
  169. package/src/models/flowModel.tsx +13 -1
  170. package/src/provider.tsx +7 -6
  171. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  172. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  173. package/src/resources/baseRecordResource.ts +31 -0
  174. package/src/resources/multiRecordResource.ts +11 -4
  175. package/src/resources/singleRecordResource.ts +3 -0
  176. package/src/resources/sqlResource.ts +11 -6
  177. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +10 -0
  178. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +6 -2
  179. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  180. package/src/runjs-context/contexts/JSItemRunJSContext.ts +10 -0
  181. package/src/runjs-context/contexts/base.ts +715 -44
  182. package/src/runjs-context/contributions.ts +88 -0
  183. package/src/runjs-context/helpers.ts +11 -1
  184. package/src/runjs-context/setup.ts +6 -0
  185. package/src/runjs-context/snippets/global/api-request.snippet.ts +3 -3
  186. package/src/runjs-context/snippets/global/import-esm.snippet.ts +2 -3
  187. package/src/runjs-context/snippets/global/query-selector.snippet.ts +8 -3
  188. package/src/runjs-context/snippets/global/require-amd.snippet.ts +1 -1
  189. package/src/runjs-context/snippets/index.ts +75 -41
  190. package/src/runjs-context/snippets/scene/block/add-event-listener.snippet.ts +11 -13
  191. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +3 -3
  192. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +2 -2
  193. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +2 -2
  194. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +2 -2
  195. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +1 -1
  196. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +1 -1
  197. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +1 -1
  198. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +6 -11
  199. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +6 -6
  200. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +3 -4
  201. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +1 -1
  202. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +20 -3
  203. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +1 -1
  204. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +1 -1
  205. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +3 -3
  206. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +3 -3
  207. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +2 -2
  208. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +1 -1
  209. package/src/runjs-context/snippets/scene/form/render-basic.snippet.ts +3 -8
  210. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +6 -3
  211. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +3 -1
  212. package/src/runjsLibs.ts +622 -0
  213. package/src/scheduler/ModelOperationScheduler.ts +27 -21
  214. package/src/types.ts +38 -1
  215. package/src/utils/__tests__/dateVariable.test.ts +101 -0
  216. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  217. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  218. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  219. package/src/utils/__tests__/runjsValue.test.ts +44 -0
  220. package/src/utils/__tests__/safeGlobals.test.ts +57 -2
  221. package/src/utils/__tests__/utils.test.ts +95 -0
  222. package/src/utils/associationObjectVariable.ts +2 -2
  223. package/src/utils/createCollectionContextMeta.ts +1 -0
  224. package/src/utils/createEphemeralContext.ts +5 -4
  225. package/src/utils/dateVariable.ts +397 -0
  226. package/src/utils/exceptions.ts +11 -0
  227. package/src/utils/index.ts +37 -3
  228. package/src/utils/params-resolvers.ts +23 -9
  229. package/src/utils/resolveModuleUrl.ts +91 -0
  230. package/src/utils/resolveRunJSObjectValues.ts +46 -0
  231. package/src/utils/runjsModuleLoader.ts +553 -0
  232. package/src/utils/runjsTemplateCompat.ts +828 -0
  233. package/src/utils/runjsValue.ts +287 -0
  234. package/src/utils/safeGlobals.ts +188 -17
  235. package/src/utils/schema-utils.ts +79 -0
  236. package/src/views/__tests__/FlowView.usePage.test.tsx +54 -1
  237. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +35 -8
  238. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  239. package/src/views/createViewMeta.ts +22 -75
  240. package/src/views/index.tsx +1 -2
  241. package/src/views/useDialog.tsx +8 -1
  242. package/src/views/useDrawer.tsx +8 -1
  243. package/src/views/usePage.tsx +51 -5
  244. package/src/views/usePopover.tsx +4 -1
  245. package/src/views/viewEvents.ts +55 -0
@@ -37,7 +37,6 @@ function createBlockScopedEngine(parent) {
37
37
  local.setModelRepository(parent.modelRepository);
38
38
  }
39
39
  local.context.addDelegate(parent.context);
40
- const originalUnlink = local.unlinkFromStack.bind(local);
41
40
  local.unlinkFromStack = function() {
42
41
  const prev = local._previousEngine;
43
42
  const next = local._nextEngine;
@@ -419,6 +419,8 @@ export declare class FlowStep {
419
419
  scene?: import("./types").ActionScene | import("./types").ActionScene[];
420
420
  paramsRequired?: boolean;
421
421
  hideInSettings?: boolean | ((ctx: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>) => boolean | Promise<boolean>);
422
+ disabledInSettings?: boolean | ((ctx: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>) => boolean | Promise<boolean>);
423
+ disabledReasonInSettings?: string | ((ctx: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>) => string | Promise<string>);
422
424
  defineProperties?: Record<string, import("./flowContext").PropertyOptions> | ((ctx: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>) => Record<string, import("./flowContext").PropertyOptions> | Promise<Record<string, import("./flowContext").PropertyOptions>>);
423
425
  defineMethods?: Record<string, (this: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>, ...args: any[]) => any> | ((ctx: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>) => Record<string, (this: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>, ...args: any[]) => any> | Promise<Record<string, (this: import("./flowContext").FlowRuntimeContext<import(".").FlowModel<import("./types").DefaultStructure>, any>, ...args: any[]) => any>>);
424
426
  };
package/lib/JSRunner.d.ts CHANGED
@@ -11,6 +11,12 @@ export interface JSRunnerOptions {
11
11
  timeoutMs?: number;
12
12
  globals?: Record<string, any>;
13
13
  version?: string;
14
+ /**
15
+ * Enable RunJS template compatibility preprocessing for `{{ ... }}`.
16
+ * When enabled via `ctx.runjs(code, vars, { preprocessTemplates: true })` (default),
17
+ * the code will be rewritten to call `ctx.resolveJsonTemplate(...)` at runtime.
18
+ */
19
+ preprocessTemplates?: boolean;
14
20
  }
15
21
  export declare class JSRunner {
16
22
  private globals;
package/lib/JSRunner.js CHANGED
@@ -31,10 +31,12 @@ __export(JSRunner_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(JSRunner_exports);
33
33
  var import_ses = require("ses");
34
+ var import_exceptions = require("./utils/exceptions");
34
35
  const _JSRunner = class _JSRunner {
35
36
  globals;
36
37
  timeoutMs;
37
38
  constructor(options = {}) {
39
+ var _a, _b;
38
40
  const bindWindowFn = /* @__PURE__ */ __name((key) => {
39
41
  if (typeof window !== "undefined" && typeof window[key] === "function") {
40
42
  return window[key].bind(window);
@@ -42,13 +44,34 @@ const _JSRunner = class _JSRunner {
42
44
  const fn = globalThis[key];
43
45
  return typeof fn === "function" ? fn.bind(globalThis) : fn;
44
46
  }, "bindWindowFn");
47
+ const providedGlobals = options.globals || {};
48
+ const liftedGlobals = {};
49
+ if (!Object.prototype.hasOwnProperty.call(providedGlobals, "Blob")) {
50
+ try {
51
+ const blobCtor = (_a = providedGlobals.window) == null ? void 0 : _a.Blob;
52
+ if (typeof blobCtor !== "undefined") {
53
+ liftedGlobals.Blob = blobCtor;
54
+ }
55
+ } catch {
56
+ }
57
+ }
58
+ if (!Object.prototype.hasOwnProperty.call(providedGlobals, "URL")) {
59
+ try {
60
+ const urlCtor = (_b = providedGlobals.window) == null ? void 0 : _b.URL;
61
+ if (typeof urlCtor !== "undefined") {
62
+ liftedGlobals.URL = urlCtor;
63
+ }
64
+ } catch {
65
+ }
66
+ }
45
67
  this.globals = {
46
68
  console,
47
69
  setTimeout: bindWindowFn("setTimeout"),
48
70
  clearTimeout: bindWindowFn("clearTimeout"),
49
71
  setInterval: bindWindowFn("setInterval"),
50
72
  clearInterval: bindWindowFn("clearInterval"),
51
- ...options.globals || {}
73
+ ...liftedGlobals,
74
+ ...providedGlobals
52
75
  };
53
76
  this.timeoutMs = options.timeoutMs ?? 5e3;
54
77
  }
@@ -62,7 +85,8 @@ const _JSRunner = class _JSRunner {
62
85
  * 异步运行代码,带错误处理和超时机制
63
86
  */
64
87
  async run(code) {
65
- if (location == null ? void 0 : location.search.includes("skipRunJs=true")) {
88
+ const search = typeof location !== "undefined" ? location.search : void 0;
89
+ if (typeof search === "string" && search.includes("skipRunJs=true")) {
66
90
  return { success: true, value: null };
67
91
  }
68
92
  const wrapped = `(async () => {
@@ -81,6 +105,12 @@ const _JSRunner = class _JSRunner {
81
105
  const result = await Promise.race([task, timeoutPromise]);
82
106
  return { success: true, value: result };
83
107
  } catch (err) {
108
+ if (err instanceof import_exceptions.FlowExitException) {
109
+ throw err;
110
+ }
111
+ if (err instanceof import_exceptions.FlowExitAllException) {
112
+ throw err;
113
+ }
84
114
  console.error(err);
85
115
  return {
86
116
  success: false,
@@ -31,8 +31,10 @@ __export(ViewScopedFlowEngine_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(ViewScopedFlowEngine_exports);
33
33
  var import_flowEngine = require("./flowEngine");
34
+ var import_viewEvents = require("./views/viewEvents");
34
35
  function createViewScopedEngine(parent) {
35
36
  const local = new import_flowEngine.FlowEngine();
37
+ Object.defineProperty(local, import_viewEvents.ENGINE_SCOPE_KEY, { value: import_viewEvents.VIEW_ENGINE_SCOPE, configurable: true });
36
38
  if (parent.modelRepository) {
37
39
  local.setModelRepository(parent.modelRepository);
38
40
  }
@@ -48,6 +50,7 @@ function createViewScopedEngine(parent) {
48
50
  "_applyFlowCache",
49
51
  "executor",
50
52
  "context",
53
+ import_viewEvents.ENGINE_SCOPE_KEY,
51
54
  "previousEngine",
52
55
  "nextEngine",
53
56
  // 调度器与事件总线局部化
package/lib/acl/Acl.js CHANGED
@@ -7,9 +7,11 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
+ var __create = Object.create;
10
11
  var __defProp = Object.defineProperty;
11
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
13
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
13
15
  var __hasOwnProp = Object.prototype.hasOwnProperty;
14
16
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
15
17
  var __export = (target, all) => {
@@ -24,13 +26,21 @@ var __copyProps = (to, from, except, desc) => {
24
26
  }
25
27
  return to;
26
28
  };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
+ // If the importer is in node compatibility mode or this is not an ESM
31
+ // file that has been converted to a CommonJS file using a Babel-
32
+ // compatible transform (i.e. "__esModule" has not been set), then set
33
+ // "default" to the CommonJS "module.exports" for node compatibility.
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
27
37
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
38
  var Acl_exports = {};
29
39
  __export(Acl_exports, {
30
40
  ACL: () => ACL
31
41
  });
32
42
  module.exports = __toCommonJS(Acl_exports);
33
- var import_lodash = require("lodash");
43
+ var import_lodash = __toESM(require("lodash"));
34
44
  const _ACL = class _ACL {
35
45
  constructor(flowEngine) {
36
46
  this.flowEngine = flowEngine;
@@ -43,10 +53,10 @@ const _ACL = class _ACL {
43
53
  // 记录上一次用于鉴权的 token,用于识别登录态变更
44
54
  lastToken = null;
45
55
  setData(data) {
46
- this.data = data;
56
+ this.data = import_lodash.default.cloneDeep(data);
47
57
  }
48
58
  setMeta(data) {
49
- this.meta = data;
59
+ this.meta = import_lodash.default.cloneDeep(data);
50
60
  }
51
61
  async load() {
52
62
  var _a, _b, _c, _d;
@@ -57,6 +57,35 @@ const cascaderPopupAutoHeightClassName = import_css.css`
57
57
  max-height: 50vh;
58
58
  }
59
59
  `;
60
+ const normalizePath = /* @__PURE__ */ __name((path) => {
61
+ if (!Array.isArray(path)) {
62
+ return void 0;
63
+ }
64
+ return path.map((segment) => String(segment));
65
+ }, "normalizePath");
66
+ const getSelectedPathInfo = /* @__PURE__ */ __name((path, options) => {
67
+ var _a;
68
+ if (!Array.isArray(path) || path.length === 0) {
69
+ return { text: "", meta: void 0 };
70
+ }
71
+ const labels = [];
72
+ let currentOptions = options;
73
+ let selectedMeta;
74
+ for (const segment of path) {
75
+ const matchedOption = currentOptions.find((item) => String(item.value) === String(segment));
76
+ if (!matchedOption) {
77
+ break;
78
+ }
79
+ const label = typeof ((_a = matchedOption.meta) == null ? void 0 : _a.title) === "string" ? matchedOption.meta.title : typeof matchedOption.label === "string" ? matchedOption.label : String(matchedOption.value);
80
+ labels.push(label);
81
+ selectedMeta = matchedOption.meta;
82
+ currentOptions = Array.isArray(matchedOption.children) ? matchedOption.children : [];
83
+ }
84
+ return {
85
+ text: labels.join(" / "),
86
+ meta: selectedMeta
87
+ };
88
+ }, "getSelectedPathInfo");
60
89
  const FlowContextSelectorComponent = /* @__PURE__ */ __name(({
61
90
  value,
62
91
  onChange,
@@ -70,6 +99,7 @@ const FlowContextSelectorComponent = /* @__PURE__ */ __name(({
70
99
  ignoreFieldNames,
71
100
  ...cascaderProps
72
101
  }) => {
102
+ const { token } = import_antd.theme.useToken();
73
103
  const lastSelectedRef = (0, import_react.useRef)(null);
74
104
  const { resolvedMetaTree, loading } = (0, import_useResolvedMetaTree.useResolvedMetaTree)(metaTree);
75
105
  const flowCtx = (0, import_FlowContextProvider.useFlowContext)();
@@ -102,16 +132,28 @@ const FlowContextSelectorComponent = /* @__PURE__ */ __name(({
102
132
  [flowCtx]
103
133
  );
104
134
  const [updateFlag, setUpdateFlag] = (0, import_react.useState)(0);
135
+ const [searchText, setSearchText] = (0, import_react.useState)("");
136
+ const [dropdownOpen, setDropdownOpen] = (0, import_react.useState)(false);
137
+ const inlineFocusByPointerRef = (0, import_react.useRef)(false);
105
138
  const triggerUpdate = (0, import_react.useCallback)(() => setUpdateFlag((prev) => prev + 1), []);
139
+ const isSearchEnabled = showSearch || children === null;
106
140
  const options = (0, import_react.useMemo)(() => {
107
141
  if (!resolvedMetaTree) return [];
142
+ const refreshSeq = updateFlag;
108
143
  const base = (0, import_utils.buildContextSelectorItems)(resolvedMetaTree);
109
- return translateOptions(base).filter((item) => {
144
+ const filtered = translateOptions(base).filter((item) => {
110
145
  var _a;
111
146
  if (!ignoreFieldNames || ignoreFieldNames.length === 0) return true;
112
147
  return !ignoreFieldNames.includes(((_a = item.meta) == null ? void 0 : _a.name) || "");
113
148
  });
149
+ return refreshSeq >= 0 ? filtered : [];
114
150
  }, [resolvedMetaTree, updateFlag, translateOptions, ignoreFieldNames]);
151
+ const displayOptions = (0, import_react.useMemo)(() => {
152
+ if (!isSearchEnabled || !searchText.trim()) {
153
+ return options;
154
+ }
155
+ return (0, import_utils.filterLoadedContextSelectorItems)(options, searchText);
156
+ }, [isSearchEnabled, options, searchText]);
115
157
  const [tempSelectedPath, setTempSelectedPath] = (0, import_react.useState)([]);
116
158
  const handleLoadData = (0, import_react.useCallback)(
117
159
  async (selectedOptions) => {
@@ -147,18 +189,27 @@ const FlowContextSelectorComponent = /* @__PURE__ */ __name(({
147
189
  triggerUpdate();
148
190
  }
149
191
  },
150
- [triggerUpdate]
192
+ [triggerUpdate, translateOptions]
151
193
  );
152
194
  const currentPath = (0, import_react.useMemo)(() => {
153
- return customParseValueToPath(value);
195
+ return normalizePath(customParseValueToPath(value));
154
196
  }, [value, customParseValueToPath]);
155
197
  const effectivePath = (0, import_react.useMemo)(() => {
156
198
  if (!currentPath || currentPath.length === 0) return currentPath;
199
+ if (options.length === 0) {
200
+ return currentPath;
201
+ }
157
202
  const topValues = new Set(options.map((o) => String(o.value)));
158
203
  const needTrim = !topValues.has(String(currentPath[0]));
159
204
  const fixed = needTrim ? currentPath.slice(1) : currentPath;
160
205
  return fixed;
161
206
  }, [currentPath, options]);
207
+ const cascaderValue = (0, import_react.useMemo)(() => {
208
+ if (tempSelectedPath.length > 0) {
209
+ return tempSelectedPath;
210
+ }
211
+ return Array.isArray(effectivePath) ? effectivePath : void 0;
212
+ }, [effectivePath, tempSelectedPath]);
162
213
  const pathToPreload = (0, import_react.useMemo)(() => {
163
214
  const finalPath = effectivePath && effectivePath.length > 0 ? effectivePath : tempSelectedPath;
164
215
  return Array.isArray(finalPath) ? finalPath : [];
@@ -212,22 +263,116 @@ const FlowContextSelectorComponent = /* @__PURE__ */ __name(({
212
263
  const mergedPopupClassName = (0, import_react.useMemo)(() => {
213
264
  return (0, import_css.cx)(cascaderPopupAutoHeightClassName, cascaderProps.popupClassName);
214
265
  }, [cascaderProps.popupClassName]);
266
+ const cascaderSearchInputClassName = (0, import_react.useMemo)(() => {
267
+ return import_css.css`
268
+ padding: 8px;
269
+ border-bottom: 1px solid ${token.colorSplit};
270
+ `;
271
+ }, [token.colorSplit]);
272
+ const {
273
+ onDropdownVisibleChange: cascaderOnDropdownVisibleChange,
274
+ dropdownRender: cascaderDropdownRender,
275
+ ...restCascaderProps
276
+ } = cascaderProps;
277
+ const selectedPathInfo = (0, import_react.useMemo)(() => getSelectedPathInfo(effectivePath, options), [effectivePath, options]);
278
+ const mergedOpen = open !== void 0 ? open : children === null ? dropdownOpen : void 0;
279
+ const isDropdownVisible = !!mergedOpen;
280
+ const handleDropdownVisibleChange = (0, import_react.useCallback)(
281
+ (visible) => {
282
+ if (open === void 0) {
283
+ setDropdownOpen(visible);
284
+ }
285
+ if (!visible) {
286
+ setSearchText("");
287
+ }
288
+ cascaderOnDropdownVisibleChange == null ? void 0 : cascaderOnDropdownVisibleChange(visible);
289
+ },
290
+ [cascaderOnDropdownVisibleChange, open]
291
+ );
292
+ const renderDropdown = (0, import_react.useCallback)(
293
+ (menu) => {
294
+ const cascaderMenuNode = cascaderDropdownRender ? cascaderDropdownRender(menu) : menu;
295
+ const cascaderMenu = import_react.default.isValidElement(cascaderMenuNode) ? cascaderMenuNode : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, cascaderMenuNode);
296
+ if (!isSearchEnabled || children === null) {
297
+ return cascaderMenu;
298
+ }
299
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { className: cascaderSearchInputClassName }, /* @__PURE__ */ import_react.default.createElement(
300
+ import_antd.Input,
301
+ {
302
+ allowClear: true,
303
+ size: "small",
304
+ value: searchText,
305
+ placeholder: flowCtx.t("Search"),
306
+ onChange: (e) => setSearchText(e.target.value),
307
+ onKeyDown: (e) => e.stopPropagation()
308
+ }
309
+ )), cascaderMenu);
310
+ },
311
+ [cascaderDropdownRender, cascaderSearchInputClassName, children, flowCtx, isSearchEnabled, searchText]
312
+ );
313
+ const inlinePlaceholder = typeof restCascaderProps.placeholder === "string" ? restCascaderProps.placeholder : flowCtx.t("Search");
314
+ const hasSelectedPath = Array.isArray(effectivePath) && effectivePath.length > 0;
315
+ const handleInlineInputFocus = (0, import_react.useCallback)(() => {
316
+ if (open === void 0 && !inlineFocusByPointerRef.current) {
317
+ setDropdownOpen(true);
318
+ }
319
+ }, [open]);
320
+ const markInlineFocusByPointer = (0, import_react.useCallback)(() => {
321
+ inlineFocusByPointerRef.current = true;
322
+ }, []);
323
+ const resetInlineFocusByPointer = (0, import_react.useCallback)(() => {
324
+ inlineFocusByPointerRef.current = false;
325
+ }, []);
326
+ const handleInlineInputChange = (0, import_react.useCallback)(
327
+ (event) => {
328
+ const nextValue = event.target.value;
329
+ if (!isDropdownVisible && nextValue === "" && hasSelectedPath) {
330
+ setTempSelectedPath([]);
331
+ onChange == null ? void 0 : onChange("", void 0);
332
+ return;
333
+ }
334
+ if (open === void 0 && !isDropdownVisible) {
335
+ setDropdownOpen(true);
336
+ }
337
+ setSearchText(nextValue);
338
+ },
339
+ [hasSelectedPath, isDropdownVisible, onChange, open]
340
+ );
341
+ const inlinePathText = Array.isArray(effectivePath) ? effectivePath.join(" / ") : "";
342
+ const inlineInputValue = isDropdownVisible ? searchText : selectedPathInfo.text || inlinePathText;
215
343
  return /* @__PURE__ */ import_react.default.createElement(
216
344
  import_antd.Cascader,
217
345
  {
218
- ...cascaderProps,
219
- options,
220
- value: tempSelectedPath && tempSelectedPath.length > 0 ? tempSelectedPath : effectivePath,
346
+ ...restCascaderProps,
347
+ options: displayOptions,
348
+ value: cascaderValue,
221
349
  onChange: handleChange,
222
350
  loadData: handleLoadData,
223
351
  loading,
224
352
  changeOnSelect: !onlyLeafSelectable,
225
353
  expandTrigger: "click",
226
- open,
227
- showSearch: children === null,
228
- popupClassName: mergedPopupClassName
354
+ open: mergedOpen,
355
+ showSearch: false,
356
+ popupClassName: mergedPopupClassName,
357
+ dropdownRender: renderDropdown,
358
+ onDropdownVisibleChange: handleDropdownVisibleChange
229
359
  },
230
- children === null ? null : children || defaultChildren
360
+ children === null ? /* @__PURE__ */ import_react.default.createElement(
361
+ import_antd.Input,
362
+ {
363
+ allowClear: true,
364
+ value: inlineInputValue,
365
+ placeholder: inlinePlaceholder,
366
+ onMouseDown: markInlineFocusByPointer,
367
+ onMouseUp: resetInlineFocusByPointer,
368
+ onMouseLeave: resetInlineFocusByPointer,
369
+ onFocus: handleInlineInputFocus,
370
+ onBlur: resetInlineFocusByPointer,
371
+ onChange: handleInlineInputChange,
372
+ onKeyDown: (e) => e.stopPropagation(),
373
+ disabled: restCascaderProps.disabled
374
+ }
375
+ ) : children || defaultChildren
231
376
  );
232
377
  }, "FlowContextSelectorComponent");
233
378
  const FlowContextSelector = import_react.default.memo(FlowContextSelectorComponent);
@@ -73,7 +73,8 @@ const SwitchWithTitle = (0, import_reactive.observer)(
73
73
  setChecked(val);
74
74
  onChange == null ? void 0 : onChange({ [itemKey]: val });
75
75
  }, "handleChange");
76
- const handleWrapperClick = /* @__PURE__ */ __name(() => {
76
+ const handleWrapperClick = /* @__PURE__ */ __name((e) => {
77
+ e.stopPropagation();
77
78
  if (disabled) return;
78
79
  handleChange(!checked);
79
80
  }, "handleWrapperClick");
@@ -135,10 +135,19 @@ const componentMap = {
135
135
  const MenuLabelItem = /* @__PURE__ */ __name(({ title, uiMode, itemProps }) => {
136
136
  const type = (uiMode == null ? void 0 : uiMode.type) || uiMode;
137
137
  const Component = type ? componentMap[type] : null;
138
- if (!Component) {
139
- return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, title);
138
+ const disabled = !!(itemProps == null ? void 0 : itemProps.disabled);
139
+ const disabledReason = itemProps == null ? void 0 : itemProps.disabledReason;
140
+ const disabledIconColor = itemProps == null ? void 0 : itemProps.disabledIconColor;
141
+ const content = (() => {
142
+ if (!Component) {
143
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, title);
144
+ }
145
+ return /* @__PURE__ */ import_react.default.createElement(Component, { title, ...itemProps });
146
+ })();
147
+ if (!disabled) {
148
+ return content;
140
149
  }
141
- return /* @__PURE__ */ import_react.default.createElement(Component, { title, ...itemProps });
150
+ return /* @__PURE__ */ import_react.default.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 } }, content, /* @__PURE__ */ import_react.default.createElement(import_antd.Tooltip, { title: disabledReason, placement: "right", destroyTooltipOnHide: true }, /* @__PURE__ */ import_react.default.createElement(import_icons.QuestionCircleOutlined, { style: { color: disabledIconColor } })));
142
151
  }, "MenuLabelItem");
143
152
  const DefaultSettingsIcon = /* @__PURE__ */ __name(({
144
153
  model,
@@ -150,9 +159,16 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
150
159
  }) => {
151
160
  const { message } = import_antd.App.useApp();
152
161
  const t = (0, import_react.useMemo)(() => (0, import_utils.getT)(model), [model]);
162
+ const { token } = import_antd.theme.useToken();
163
+ const disabledIconColor = (token == null ? void 0 : token.colorTextTertiary) || (token == null ? void 0 : token.colorTextDescription) || (token == null ? void 0 : token.colorTextSecondary);
153
164
  const [visible, setVisible] = (0, import_react.useState)(false);
154
165
  const [refreshTick, setRefreshTick] = (0, import_react.useState)(0);
155
166
  const [extraMenuItems, setExtraMenuItems] = (0, import_react.useState)([]);
167
+ const [configurableFlowsAndSteps, setConfigurableFlowsAndSteps] = (0, import_react.useState)([]);
168
+ const [isLoading, setIsLoading] = (0, import_react.useState)(true);
169
+ const closeDropdown = (0, import_react.useCallback)(() => {
170
+ setVisible(false);
171
+ }, []);
156
172
  const handleOpenChange = (0, import_react.useCallback)((nextOpen, info) => {
157
173
  if (info.source === "trigger" || nextOpen) {
158
174
  (0, import_react.startTransition)(() => {
@@ -200,7 +216,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
200
216
  return () => {
201
217
  mounted = false;
202
218
  };
203
- }, [model, menuLevels, t, refreshTick, visible, message]);
219
+ }, [model, menuLevels, t, refreshTick, visible]);
204
220
  const copyUidToClipboard = (0, import_react.useCallback)(
205
221
  async (uid) => {
206
222
  var _a;
@@ -249,6 +265,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
249
265
  [model, copyUidToClipboard]
250
266
  );
251
267
  const handleDelete = (0, import_react.useCallback)(() => {
268
+ closeDropdown();
252
269
  import_antd.Modal.confirm({
253
270
  title: t("Confirm delete"),
254
271
  icon: /* @__PURE__ */ import_react.default.createElement(import_icons.ExclamationCircleOutlined, null),
@@ -269,7 +286,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
269
286
  }
270
287
  }
271
288
  });
272
- }, [model]);
289
+ }, [closeDropdown, model, t]);
273
290
  const handleStepConfiguration = (0, import_react.useCallback)(
274
291
  (key) => {
275
292
  const keyParts = key.split(":");
@@ -294,6 +311,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
294
311
  [flowKey, stepKey] = keyParts;
295
312
  }
296
313
  try {
314
+ closeDropdown();
297
315
  targetModel.openFlowSettings({
298
316
  flowKey,
299
317
  stepKey
@@ -302,23 +320,51 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
302
320
  console.log(t("Configuration popup cancelled or error"), ":", error);
303
321
  }
304
322
  },
305
- [model]
323
+ [closeDropdown, model, t]
324
+ );
325
+ const isStepMenuItemDisabled = (0, import_react.useCallback)(
326
+ (key) => {
327
+ const cleanKey = key.includes("-") && /^(.+)-\d+$/.test(key) ? key.replace(/-\d+$/, "") : key;
328
+ const keys = cleanKey.split(":");
329
+ let modelKey;
330
+ let flowKey;
331
+ let stepKey;
332
+ if (keys.length === 3) {
333
+ [modelKey, flowKey, stepKey] = keys;
334
+ } else if (keys.length === 2) {
335
+ [flowKey, stepKey] = keys;
336
+ } else {
337
+ return false;
338
+ }
339
+ return configurableFlowsAndSteps.some(({ flow, steps, modelKey: flowModelKey }) => {
340
+ const sameModel = (flowModelKey || void 0) === modelKey;
341
+ if (!sameModel || flow.key !== flowKey) return false;
342
+ return steps.some((stepInfo) => stepInfo.stepKey === stepKey && !!stepInfo.disabled);
343
+ });
344
+ },
345
+ [configurableFlowsAndSteps]
306
346
  );
307
347
  const handleMenuClick = (0, import_react.useCallback)(
308
348
  ({ key }) => {
309
349
  const originalKey = key;
310
350
  const cleanKey = key.includes("-") && /^(.+)-\d+$/.test(key) ? key.replace(/-\d+$/, "") : key;
311
351
  if (cleanKey.startsWith("copy-pop-uid:")) {
352
+ closeDropdown();
312
353
  handleCopyPopupUid(cleanKey);
313
354
  return;
314
355
  }
315
356
  const extra = extraMenuItems.find((it) => (it == null ? void 0 : it.key) === originalKey || (it == null ? void 0 : it.key) === cleanKey);
316
357
  if (extra == null ? void 0 : extra.onClick) {
358
+ closeDropdown();
317
359
  extra.onClick();
318
360
  return;
319
361
  }
362
+ if (isStepMenuItemDisabled(cleanKey)) {
363
+ return;
364
+ }
320
365
  switch (cleanKey) {
321
366
  case "copy-uid":
367
+ closeDropdown();
322
368
  handleCopyUid();
323
369
  break;
324
370
  case "delete":
@@ -329,7 +375,15 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
329
375
  break;
330
376
  }
331
377
  },
332
- [handleCopyUid, handleDelete, handleStepConfiguration, handleCopyPopupUid, extraMenuItems]
378
+ [
379
+ closeDropdown,
380
+ handleCopyUid,
381
+ handleDelete,
382
+ handleStepConfiguration,
383
+ handleCopyPopupUid,
384
+ extraMenuItems,
385
+ isStepMenuItemDisabled
386
+ ]
333
387
  );
334
388
  const getModelConfigurableFlowsAndSteps = (0, import_react.useCallback)(
335
389
  async (targetModel, modelKey) => {
@@ -347,6 +401,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
347
401
  if (await (0, import_utils.shouldHideStepInSettings)(targetModel, flow, actionStep)) {
348
402
  return null;
349
403
  }
404
+ const disabledState = await (0, import_utils.resolveStepDisabledInSettings)(targetModel, flow, actionStep);
350
405
  let uiMode = await (0, import_utils.resolveUiMode)(actionStep.uiMode, targetModel.context);
351
406
  const hasStepUiSchema = actionStep.uiSchema != null;
352
407
  let hasActionUiSchema = false;
@@ -384,7 +439,9 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
384
439
  title: t(stepTitle) || stepKey,
385
440
  modelKey,
386
441
  // 添加模型标识
387
- uiMode
442
+ uiMode,
443
+ disabled: disabledState.disabled,
444
+ disabledReason: disabledState.reason
388
445
  };
389
446
  })
390
447
  ).then((steps) => steps.filter(Boolean));
@@ -415,8 +472,6 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
415
472
  }
416
473
  return result;
417
474
  }, [model, menuLevels, getModelConfigurableFlowsAndSteps]);
418
- const [configurableFlowsAndSteps, setConfigurableFlowsAndSteps] = (0, import_react.useState)([]);
419
- const [isLoading, setIsLoading] = (0, import_react.useState)(true);
420
475
  (0, import_react.useEffect)(() => {
421
476
  const triggerRebuild = /* @__PURE__ */ __name(() => {
422
477
  setRefreshTick((v) => v + 1);
@@ -509,11 +564,15 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
509
564
  }
510
565
  }, "onChange"),
511
566
  ...(uiMode == null ? void 0 : uiMode.props) || {},
512
- itemKey: uiMode == null ? void 0 : uiMode.key
567
+ itemKey: uiMode == null ? void 0 : uiMode.key,
568
+ disabled: !!stepInfo.disabled,
569
+ disabledReason: stepInfo.disabledReason,
570
+ disabledIconColor
513
571
  };
514
572
  items.push({
515
573
  key: uniqueKey,
516
- label: /* @__PURE__ */ import_react.default.createElement(MenuLabelItem, { title: t(stepInfo.title), uiMode, itemProps })
574
+ label: /* @__PURE__ */ import_react.default.createElement(MenuLabelItem, { title: stepInfo.title, uiMode, itemProps }),
575
+ disabled: !!stepInfo.disabled
517
576
  });
518
577
  });
519
578
  if (flow.options.divider === "bottom") {
@@ -547,7 +606,8 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
547
606
  const uniqueKey = generateUniqueKey(`${flow.key}:${stepInfo.stepKey}`);
548
607
  items.push({
549
608
  key: uniqueKey,
550
- label: t(stepInfo.title)
609
+ label: stepInfo.disabled ? /* @__PURE__ */ import_react.default.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 } }, stepInfo.title, /* @__PURE__ */ import_react.default.createElement(import_antd.Tooltip, { title: stepInfo.disabledReason, placement: "right", destroyTooltipOnHide: true }, /* @__PURE__ */ import_react.default.createElement(import_icons.QuestionCircleOutlined, { style: { color: disabledIconColor } }))) : stepInfo.title,
610
+ disabled: !!stepInfo.disabled
551
611
  });
552
612
  });
553
613
  });
@@ -559,7 +619,8 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
559
619
  const uniqueKey = generateUniqueKey(`${modelKey}:${flow.key}:${stepInfo.stepKey}`);
560
620
  subMenuChildren.push({
561
621
  key: uniqueKey,
562
- label: t(stepInfo.title)
622
+ label: stepInfo.disabled ? /* @__PURE__ */ import_react.default.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 } }, stepInfo.title, /* @__PURE__ */ import_react.default.createElement(import_antd.Tooltip, { title: stepInfo.disabledReason, placement: "right", destroyTooltipOnHide: true }, /* @__PURE__ */ import_react.default.createElement(import_icons.QuestionCircleOutlined, { style: { color: disabledIconColor } }))) : stepInfo.title,
623
+ disabled: !!stepInfo.disabled
563
624
  });
564
625
  });
565
626
  });
@@ -573,7 +634,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
573
634
  }
574
635
  }
575
636
  return items;
576
- }, [configurableFlowsAndSteps, flattenSubMenus, t]);
637
+ }, [configurableFlowsAndSteps, disabledIconColor, flattenSubMenus, t]);
577
638
  const finalMenuItems = (0, import_react.useMemo)(() => {
578
639
  const items = [...menuItems];
579
640
  const commonExtras = extraMenuItems.filter((it) => it.group === "common-actions").sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));