@nocobase/client-v2 2.1.0-alpha.40 → 2.1.0-alpha.46

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 (338) hide show
  1. package/es/Application.d.ts +7 -0
  2. package/es/BaseApplication.d.ts +13 -0
  3. package/es/RouterManager.d.ts +1 -0
  4. package/es/authRedirect.d.ts +12 -0
  5. package/es/collection-field-interface/CollectionFieldInterface.d.ts +51 -15
  6. package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +82 -3
  7. package/es/collection-manager/field-configure.d.ts +80 -0
  8. package/es/collection-manager/field-validation.d.ts +43 -0
  9. package/es/collection-manager/filter-operators/index.d.ts +46 -0
  10. package/es/collection-manager/filter-operators/operators.d.ts +30 -0
  11. package/es/collection-manager/interfaces/checkbox.d.ts +1 -41
  12. package/es/collection-manager/interfaces/checkboxGroup.d.ts +12 -44
  13. package/es/collection-manager/interfaces/collection.d.ts +12 -51
  14. package/es/collection-manager/interfaces/color.d.ts +1 -16
  15. package/es/collection-manager/interfaces/createdAt.d.ts +1 -44
  16. package/es/collection-manager/interfaces/createdBy.d.ts +0 -4
  17. package/es/collection-manager/interfaces/dateOnly.d.ts +7 -44
  18. package/es/collection-manager/interfaces/datetime.d.ts +1 -44
  19. package/es/collection-manager/interfaces/datetimeNoTz.d.ts +1 -44
  20. package/es/collection-manager/interfaces/email.d.ts +1 -29
  21. package/es/collection-manager/interfaces/id.d.ts +1 -16
  22. package/es/collection-manager/interfaces/index.d.ts +2 -3
  23. package/es/collection-manager/interfaces/input.d.ts +1 -102
  24. package/es/collection-manager/interfaces/integer.d.ts +1 -95
  25. package/es/collection-manager/interfaces/json.d.ts +16 -7
  26. package/es/collection-manager/interfaces/m2m.d.ts +11 -19
  27. package/es/collection-manager/interfaces/m2o.d.ts +11 -19
  28. package/es/collection-manager/interfaces/markdown.d.ts +1 -63
  29. package/es/collection-manager/interfaces/multipleSelect.d.ts +12 -44
  30. package/es/collection-manager/interfaces/nanoid.d.ts +1 -34
  31. package/es/collection-manager/interfaces/number.d.ts +1 -87
  32. package/es/collection-manager/interfaces/o2m.d.ts +12 -24
  33. package/es/collection-manager/interfaces/obo.d.ts +207 -0
  34. package/es/collection-manager/interfaces/oho.d.ts +207 -0
  35. package/es/collection-manager/interfaces/password.d.ts +1 -56
  36. package/es/collection-manager/interfaces/percent.d.ts +1 -84
  37. package/es/collection-manager/interfaces/phone.d.ts +1 -25
  38. package/es/collection-manager/interfaces/properties/index.d.ts +0 -28
  39. package/es/collection-manager/interfaces/radioGroup.d.ts +1 -29
  40. package/es/collection-manager/interfaces/richText.d.ts +1 -63
  41. package/es/collection-manager/interfaces/select.d.ts +12 -44
  42. package/es/collection-manager/interfaces/snowflake-id.d.ts +1 -34
  43. package/es/collection-manager/interfaces/tableoid.d.ts +1 -10
  44. package/es/collection-manager/interfaces/textarea.d.ts +1 -51
  45. package/es/collection-manager/interfaces/time.d.ts +1 -16
  46. package/es/collection-manager/interfaces/types.d.ts +3 -12
  47. package/es/collection-manager/interfaces/unixTimestamp.d.ts +1 -44
  48. package/es/collection-manager/interfaces/updatedAt.d.ts +1 -44
  49. package/es/collection-manager/interfaces/updatedBy.d.ts +0 -4
  50. package/es/collection-manager/interfaces/url.d.ts +1 -20
  51. package/es/collection-manager/interfaces/uuid.d.ts +1 -34
  52. package/es/collection-manager/template-fields.d.ts +53 -0
  53. package/es/components/KeepAlive.d.ts +22 -0
  54. package/es/components/RouterBridge.d.ts +9 -0
  55. package/es/components/form/DialogFormLayout.d.ts +5 -29
  56. package/es/components/form/TypedVariableInput.d.ts +75 -0
  57. package/es/components/form/VariableInput.d.ts +53 -2
  58. package/es/components/form/filter/CollectionFilter.d.ts +49 -0
  59. package/es/components/form/filter/CollectionFilterItem.d.ts +49 -0
  60. package/es/components/form/filter/DateFilterDynamicComponent.d.ts +57 -0
  61. package/es/components/form/filter/FilterValueInput.d.ts +29 -0
  62. package/es/components/form/filter/index.d.ts +11 -0
  63. package/es/components/form/filter/useFilterActionProps.d.ts +96 -0
  64. package/es/components/form/index.d.ts +2 -0
  65. package/es/data-source/ExtendCollectionsProvider.d.ts +50 -0
  66. package/es/data-source/index.d.ts +9 -0
  67. package/es/flow/FlowPage.d.ts +2 -1
  68. package/es/flow/admin-shell/AdminLayoutRouteCoordinator.d.ts +8 -40
  69. package/es/flow/admin-shell/BaseLayoutModel.d.ts +89 -0
  70. package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +74 -0
  71. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +12 -0
  72. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +1 -0
  73. package/es/flow/admin-shell/admin-layout/AdminLayoutModel.d.ts +7 -92
  74. package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +11 -0
  75. package/es/flow/admin-shell/admin-layout/index.d.ts +3 -0
  76. package/es/flow/admin-shell/admin-layout/useApplications.d.ts +3 -2
  77. package/es/flow/admin-shell/useAdminLayoutRoutePage.d.ts +2 -2
  78. package/es/flow/admin-shell/useLayoutRoutePage.d.ts +23 -0
  79. package/es/flow/components/ConditionBuilder.d.ts +1 -0
  80. package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
  81. package/es/flow/components/FieldAssignValueInput.d.ts +1 -0
  82. package/es/flow/components/FlowRoute.d.ts +10 -1
  83. package/es/flow/components/fieldAssignOptions.d.ts +10 -0
  84. package/es/flow/components/filter/LinkageFilterItem.d.ts +1 -0
  85. package/es/flow/components/filter/VariableFilterItem.d.ts +1 -0
  86. package/es/flow/components/filter/index.d.ts +2 -0
  87. package/es/flow/components/filter/metaTreeAssociationDepth.d.ts +13 -0
  88. package/es/flow/components/filter/useFilterOptions.d.ts +66 -0
  89. package/es/flow/index.d.ts +4 -0
  90. package/es/flow/models/base/AssociationFieldGroupModel.d.ts +2 -33
  91. package/es/flow/models/base/PageModel/PageModel.d.ts +3 -1
  92. package/es/flow/models/blocks/assign-form/assignFieldValuesFlow.d.ts +92 -0
  93. package/es/flow/models/blocks/assign-form/index.d.ts +1 -0
  94. package/es/flow/models/blocks/form/FormActionGroupModel.d.ts +1 -0
  95. package/es/flow/models/blocks/form/FormActionModel.d.ts +9 -2
  96. package/es/flow/models/blocks/table/TableBlockModel.d.ts +10 -0
  97. package/es/flow/models/blocks/table/TableColumnModel.d.ts +2 -0
  98. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.d.ts +1 -1
  99. package/es/flow-compat/passwordUtils.d.ts +1 -1
  100. package/es/index.d.ts +6 -0
  101. package/es/index.mjs +552 -459
  102. package/es/layout-manager/LayoutContentRoute.d.ts +14 -0
  103. package/es/layout-manager/LayoutManager.d.ts +22 -0
  104. package/es/layout-manager/LayoutRoute.d.ts +14 -0
  105. package/es/layout-manager/index.d.ts +13 -0
  106. package/es/layout-manager/types.d.ts +20 -0
  107. package/es/layout-manager/utils.d.ts +14 -0
  108. package/es/nocobase-buildin-plugin/index.d.ts +3 -10
  109. package/es/settings-center/index.d.ts +1 -1
  110. package/es/settings-center/plugin-manager/BulkEnableButton.d.ts +15 -0
  111. package/es/settings-center/plugin-manager/PluginCard.d.ts +15 -0
  112. package/es/settings-center/plugin-manager/PluginDetail.d.ts +16 -0
  113. package/es/settings-center/{PluginManagerPage.d.ts → plugin-manager/index.d.ts} +1 -7
  114. package/es/settings-center/plugin-manager/types.d.ts +34 -0
  115. package/lib/index.js +552 -459
  116. package/package.json +8 -7
  117. package/src/Application.tsx +51 -12
  118. package/src/BaseApplication.tsx +32 -0
  119. package/src/PluginSettingsManager.ts +1 -1
  120. package/src/RouterManager.tsx +17 -1
  121. package/src/__tests__/PluginSettingsManager.test.ts +41 -2
  122. package/src/__tests__/app.test.tsx +17 -1
  123. package/src/__tests__/globalDeps.test.ts +1 -0
  124. package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +50 -2
  125. package/src/__tests__/plugin-manager.test.tsx +177 -0
  126. package/src/__tests__/settings-center.test.tsx +24 -2
  127. package/src/authRedirect.ts +43 -0
  128. package/src/collection-field-interface/CollectionFieldInterface.ts +71 -77
  129. package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +201 -4
  130. package/src/collection-manager/field-configure.ts +548 -0
  131. package/src/collection-manager/field-validation.ts +195 -0
  132. package/src/collection-manager/filter-operators/index.ts +176 -0
  133. package/src/collection-manager/{interfaces/properties → filter-operators}/operators.ts +24 -13
  134. package/src/collection-manager/interfaces/checkbox.ts +2 -9
  135. package/src/collection-manager/interfaces/checkboxGroup.ts +2 -10
  136. package/src/collection-manager/interfaces/collection.ts +2 -15
  137. package/src/collection-manager/interfaces/color.ts +2 -2
  138. package/src/collection-manager/interfaces/createdAt.ts +2 -2
  139. package/src/collection-manager/interfaces/createdBy.ts +1 -12
  140. package/src/collection-manager/interfaces/dateOnly.ts +8 -2
  141. package/src/collection-manager/interfaces/datetime.ts +2 -2
  142. package/src/collection-manager/interfaces/datetimeNoTz.ts +2 -2
  143. package/src/collection-manager/interfaces/email.ts +2 -9
  144. package/src/collection-manager/interfaces/id.ts +1 -2
  145. package/src/collection-manager/interfaces/index.ts +2 -3
  146. package/src/collection-manager/interfaces/input.ts +2 -133
  147. package/src/collection-manager/interfaces/integer.ts +2 -71
  148. package/src/collection-manager/interfaces/json.tsx +17 -11
  149. package/src/collection-manager/interfaces/m2m.tsx +0 -21
  150. package/src/collection-manager/interfaces/m2o.tsx +0 -22
  151. package/src/collection-manager/interfaces/markdown.ts +2 -51
  152. package/src/collection-manager/interfaces/multipleSelect.ts +2 -14
  153. package/src/collection-manager/interfaces/nanoid.ts +2 -2
  154. package/src/collection-manager/interfaces/number.ts +2 -85
  155. package/src/collection-manager/interfaces/o2m.tsx +1 -22
  156. package/src/collection-manager/interfaces/obo.tsx +145 -0
  157. package/src/collection-manager/interfaces/oho.tsx +145 -0
  158. package/src/collection-manager/interfaces/password.ts +2 -44
  159. package/src/collection-manager/interfaces/percent.ts +2 -74
  160. package/src/collection-manager/interfaces/phone.ts +2 -2
  161. package/src/collection-manager/interfaces/properties/index.ts +0 -133
  162. package/src/collection-manager/interfaces/radioGroup.ts +2 -2
  163. package/src/collection-manager/interfaces/richText.ts +2 -51
  164. package/src/collection-manager/interfaces/select.ts +2 -14
  165. package/src/collection-manager/interfaces/snowflake-id.ts +2 -2
  166. package/src/collection-manager/interfaces/tableoid.ts +1 -2
  167. package/src/collection-manager/interfaces/textarea.ts +2 -51
  168. package/src/collection-manager/interfaces/time.ts +2 -2
  169. package/src/collection-manager/interfaces/types.ts +4 -12
  170. package/src/collection-manager/interfaces/unixTimestamp.tsx +2 -2
  171. package/src/collection-manager/interfaces/updatedAt.ts +2 -2
  172. package/src/collection-manager/interfaces/updatedBy.ts +1 -12
  173. package/src/collection-manager/interfaces/url.ts +2 -4
  174. package/src/collection-manager/interfaces/uuid.ts +2 -2
  175. package/src/collection-manager/template-fields.ts +109 -0
  176. package/src/components/KeepAlive.tsx +131 -0
  177. package/src/components/README.md +138 -6
  178. package/src/components/README.zh-CN.md +138 -7
  179. package/src/components/RouterBridge.tsx +28 -4
  180. package/src/components/__tests__/KeepAlive.test.tsx +63 -0
  181. package/src/components/__tests__/RouterBridge.test.tsx +27 -0
  182. package/src/components/form/DialogFormLayout.tsx +5 -29
  183. package/src/components/form/TypedVariableInput.tsx +441 -0
  184. package/src/components/form/VariableInput.tsx +101 -28
  185. package/src/components/form/__tests__/TypedVariableInput.test.tsx +152 -0
  186. package/src/components/form/__tests__/VariableInput.test.ts +85 -0
  187. package/src/components/form/filter/CollectionFilter.tsx +111 -0
  188. package/src/components/form/filter/CollectionFilterItem.tsx +184 -0
  189. package/src/components/form/filter/DateFilterDynamicComponent.tsx +283 -0
  190. package/src/components/form/filter/FilterValueInput.tsx +198 -0
  191. package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +247 -0
  192. package/src/components/form/filter/__tests__/DateFilterDynamicComponent.test.tsx +148 -0
  193. package/src/components/form/filter/__tests__/FilterValueInput.test.tsx +243 -0
  194. package/src/components/form/filter/__tests__/compileFilterGroup.test.ts +146 -0
  195. package/src/components/form/filter/index.ts +13 -0
  196. package/src/components/form/filter/useFilterActionProps.ts +203 -0
  197. package/src/components/form/index.tsx +2 -0
  198. package/src/data-source/ExtendCollectionsProvider.tsx +144 -0
  199. package/src/data-source/__tests__/ExtendCollectionsProvider.test.tsx +264 -0
  200. package/src/data-source/index.ts +10 -0
  201. package/src/flow/FlowPage.tsx +35 -7
  202. package/src/flow/__tests__/FlowPage.test.tsx +79 -0
  203. package/src/flow/__tests__/FlowRoute.test.tsx +537 -3
  204. package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +100 -0
  205. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +191 -0
  206. package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +23 -1
  207. package/src/flow/actions/__tests__/openView.subModelKey.test.tsx +33 -0
  208. package/src/flow/actions/aclCheck.tsx +4 -0
  209. package/src/flow/actions/aclCheckRefresh.tsx +4 -0
  210. package/src/flow/actions/dataScope.tsx +8 -1
  211. package/src/flow/actions/dateTimeFormat.tsx +12 -8
  212. package/src/flow/actions/linkageRules.tsx +127 -2
  213. package/src/flow/actions/linkageRulesRefresh.tsx +2 -3
  214. package/src/flow/actions/openView.tsx +28 -4
  215. package/src/flow/actions/setTargetDataScope.tsx +1 -1
  216. package/src/flow/admin-shell/AdminLayoutRouteCoordinator.ts +11 -329
  217. package/src/flow/admin-shell/BaseLayoutModel.tsx +455 -0
  218. package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +502 -0
  219. package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +547 -3
  220. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +35 -7
  221. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +160 -0
  222. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +15 -13
  223. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +28 -201
  224. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +11 -2
  225. package/src/flow/admin-shell/admin-layout/AppListRender.tsx +139 -0
  226. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +76 -27
  227. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +149 -27
  228. package/src/flow/admin-shell/admin-layout/index.ts +3 -0
  229. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +11 -0
  230. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +2 -4
  231. package/src/flow/admin-shell/admin-layout/useApplications.tsx +34 -1
  232. package/src/flow/admin-shell/useAdminLayoutRoutePage.ts +10 -26
  233. package/src/flow/admin-shell/useLayoutRoutePage.ts +61 -0
  234. package/src/flow/common/Markdown/Edit.tsx +32 -4
  235. package/src/flow/components/AdminLayout.tsx +4 -154
  236. package/src/flow/components/ConditionBuilder.tsx +12 -2
  237. package/src/flow/components/FieldAssignRulesEditor.tsx +37 -46
  238. package/src/flow/components/FieldAssignValueInput.tsx +8 -4
  239. package/src/flow/components/FlowRoute.tsx +105 -15
  240. package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +112 -1
  241. package/src/flow/components/__tests__/fieldAssignOptions.test.ts +71 -1
  242. package/src/flow/components/code-editor/__tests__/runjsCompletions.test.ts +272 -27
  243. package/src/flow/components/code-editor/runjsCompletions.ts +490 -9
  244. package/src/flow/components/fieldAssignOptions.ts +23 -6
  245. package/src/flow/components/filter/LinkageFilterItem.tsx +22 -9
  246. package/src/flow/components/filter/VariableFilterItem.tsx +27 -9
  247. package/src/flow/components/filter/__tests__/fieldsToOptions.test.ts +48 -0
  248. package/src/flow/components/filter/__tests__/metaTreeAssociationDepth.test.ts +60 -0
  249. package/src/flow/components/filter/fieldsToOptions.ts +9 -4
  250. package/src/flow/components/filter/index.ts +3 -0
  251. package/src/flow/components/filter/metaTreeAssociationDepth.ts +69 -0
  252. package/src/flow/components/filter/useFilterOptions.ts +102 -0
  253. package/src/flow/index.ts +4 -0
  254. package/src/flow/models/actions/FilterActionModel.tsx +15 -3
  255. package/src/flow/models/actions/UpdateRecordActionModel.tsx +14 -95
  256. package/src/flow/models/actions/UpdateRecordActionUtils.ts +4 -7
  257. package/src/flow/models/actions/__tests__/AssignFormRefill.test.ts +116 -1
  258. package/src/flow/models/base/ActionModel.tsx +8 -1
  259. package/src/flow/models/base/AssociationFieldGroupModel.tsx +20 -3
  260. package/src/flow/models/base/GridModel.tsx +1 -1
  261. package/src/flow/models/base/PageModel/ChildPageModel.tsx +5 -1
  262. package/src/flow/models/base/PageModel/PageModel.tsx +51 -18
  263. package/src/flow/models/base/PageModel/RootPageModel.tsx +6 -13
  264. package/src/flow/models/base/PageModel/__tests__/ChildPageModel.test.ts +12 -0
  265. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +102 -1
  266. package/src/flow/models/base/RouteModel.tsx +1 -1
  267. package/src/flow/models/base/__tests__/AssociationFieldGroupModel.test.ts +86 -0
  268. package/src/flow/models/base/__tests__/GridModel.render.test.tsx +53 -0
  269. package/src/flow/models/blocks/assign-form/AssignFormGridModel.tsx +12 -3
  270. package/src/flow/models/blocks/assign-form/AssignFormItemModel.tsx +77 -6
  271. package/src/flow/models/blocks/assign-form/__tests__/assignFieldValuesFlow.editor.test.tsx +216 -0
  272. package/src/flow/models/blocks/assign-form/assignFieldValuesFlow.tsx +308 -0
  273. package/src/flow/models/blocks/assign-form/index.ts +1 -0
  274. package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +1 -1
  275. package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +6 -1
  276. package/src/flow/models/blocks/filter-manager/flow-actions/connectFields.tsx +48 -6
  277. package/src/flow/models/blocks/form/FormActionGroupModel.tsx +14 -0
  278. package/src/flow/models/blocks/form/FormActionModel.tsx +30 -3
  279. package/src/flow/models/blocks/form/FormAssociationItemModel.tsx +9 -0
  280. package/src/flow/models/blocks/form/FormItemModel.tsx +17 -1
  281. package/src/flow/models/blocks/form/__tests__/FormActionGroupModel.test.ts +46 -0
  282. package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
  283. package/src/flow/models/blocks/form/__tests__/FormItemModel.defineChildren.test.ts +27 -2
  284. package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +71 -0
  285. package/src/flow/models/blocks/form/submitHandler.ts +8 -1
  286. package/src/flow/models/blocks/form/submitValues.ts +4 -1
  287. package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +29 -0
  288. package/src/flow/models/blocks/form/value-runtime/runtime.ts +5 -1
  289. package/src/flow/models/blocks/table/TableBlockModel.tsx +118 -16
  290. package/src/flow/models/blocks/table/TableColumnModel.tsx +15 -5
  291. package/src/flow/models/blocks/table/TableCustomColumnModel.tsx +2 -2
  292. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +114 -0
  293. package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +18 -0
  294. package/src/flow/models/fields/AssociationFieldModel/SubFormFieldModel.tsx +7 -1
  295. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +6 -7
  296. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +1 -1
  297. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -5
  298. package/src/flow/models/fields/ClickableFieldModel.tsx +9 -1
  299. package/src/flow/models/fields/CollectionSelectorFieldModel.tsx +8 -2
  300. package/src/flow/models/fields/DisplayEnumFieldModel.tsx +8 -2
  301. package/src/flow/models/fields/DisplayTimeFieldModel.tsx +1 -1
  302. package/src/flow/models/fields/TimeFieldModel.tsx +1 -1
  303. package/src/flow/models/fields/__tests__/TimeFieldModel.test.tsx +61 -0
  304. package/src/flow/models/fields/mobile-components/MobileDatePicker.tsx +19 -3
  305. package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +5 -3
  306. package/src/flow/models/fields/mobile-components/__tests__/MobileDatePicker.test.tsx +94 -0
  307. package/src/flow/models/fields/mobile-components/__tests__/MobileSelect.test.tsx +70 -0
  308. package/src/flow/models/topbar/TopbarActionModel.tsx +1 -1
  309. package/src/flow/utils/__tests__/dateTimeFormat.test.ts +91 -0
  310. package/src/index.ts +6 -0
  311. package/src/layout-manager/LayoutContentRoute.tsx +90 -0
  312. package/src/layout-manager/LayoutManager.tsx +185 -0
  313. package/src/layout-manager/LayoutRoute.tsx +138 -0
  314. package/src/layout-manager/__tests__/LayoutManager.test.tsx +335 -0
  315. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +473 -0
  316. package/src/layout-manager/index.ts +14 -0
  317. package/src/layout-manager/types.ts +22 -0
  318. package/src/layout-manager/utils.ts +37 -0
  319. package/src/nocobase-buildin-plugin/index.tsx +69 -67
  320. package/src/nocobase-buildin-plugin/plugins/LocalePlugin.ts +1 -0
  321. package/src/settings-center/index.ts +1 -1
  322. package/src/settings-center/plugin-manager/BulkEnableButton.tsx +111 -0
  323. package/src/settings-center/plugin-manager/PluginCard.tsx +270 -0
  324. package/src/settings-center/plugin-manager/PluginDetail.tsx +195 -0
  325. package/src/settings-center/plugin-manager/index.tsx +254 -0
  326. package/src/settings-center/plugin-manager/types.ts +35 -0
  327. package/src/settings-center/utils.tsx +8 -1
  328. package/src/theme/__tests__/globalStyles.test.ts +24 -0
  329. package/src/theme/globalStyles.ts +10 -0
  330. package/src/utils/globalDeps.ts +2 -0
  331. package/es/collection-manager/interfaces/linkTo.d.ts +0 -90
  332. package/es/collection-manager/interfaces/o2o.d.ts +0 -621
  333. package/es/collection-manager/interfaces/properties/operators.d.ts +0 -294
  334. package/es/collection-manager/interfaces/subTable.d.ts +0 -172
  335. package/src/collection-manager/interfaces/linkTo.ts +0 -120
  336. package/src/collection-manager/interfaces/o2o.tsx +0 -561
  337. package/src/collection-manager/interfaces/subTable.ts +0 -218
  338. package/src/settings-center/PluginManagerPage.tsx +0 -162
@@ -9,7 +9,12 @@
9
9
 
10
10
  import { Completion } from '@codemirror/autocomplete';
11
11
  import { EditorView } from '@codemirror/view';
12
- import { getRunJSDocFor, setupRunJSContexts, listSnippetsForContext } from '@nocobase/flow-engine';
12
+ import {
13
+ getRunJSDocFor,
14
+ setupRunJSContexts,
15
+ listSnippetsForContext,
16
+ type RunJSDocCompletionDoc,
17
+ } from '@nocobase/flow-engine';
13
18
  import { formatDocInfo } from './formatDocInfo';
14
19
 
15
20
  export type SnippetEntry = {
@@ -23,6 +28,483 @@ export type SnippetEntry = {
23
28
  scenes?: string[];
24
29
  };
25
30
 
31
+ type StaticCompletionEntry = {
32
+ label: string;
33
+ type: Completion['type'];
34
+ detail?: string;
35
+ info?: string;
36
+ insertText?: string;
37
+ boost?: number;
38
+ requires?: Array<'element'>;
39
+ };
40
+
41
+ const NON_ELEMENT_COMPLETION_SCENES = new Set(['eventFlow', 'formValue', 'linkage']);
42
+
43
+ const normalizeScenes = (scene?: string | string[]): string[] =>
44
+ (Array.isArray(scene) ? scene : scene ? [scene] : [])
45
+ .map((sceneName) => (typeof sceneName === 'string' ? sceneName.trim() : ''))
46
+ .filter(Boolean);
47
+
48
+ const hasRunJSElementContext = (doc: any, apiInfos: any, requestedScenes: string[]): boolean => {
49
+ if (requestedScenes.some((sceneName) => NON_ELEMENT_COMPLETION_SCENES.has(sceneName))) return false;
50
+ return !!((doc as any)?.properties?.element || (apiInfos as any)?.element);
51
+ };
52
+
53
+ const usesCtxElement = (text?: string): boolean => typeof text === 'string' && /\bctx\.element\b/.test(text);
54
+
55
+ const satisfiesCompletionRequirements = (
56
+ completionSpec: Pick<RunJSDocCompletionDoc, 'requires'> | undefined,
57
+ capabilities: { element: boolean },
58
+ ): boolean => {
59
+ if (!completionSpec?.requires?.length) return true;
60
+ return completionSpec.requires.every((requirement) => requirement !== 'element' || capabilities.element);
61
+ };
62
+
63
+ const createApply = (insertText?: string) => (view: EditorView, _completion: Completion, from: number, to: number) => {
64
+ if (!insertText) return;
65
+ view.dispatch({
66
+ changes: { from, to, insert: insertText },
67
+ selection: { anchor: from + insertText.length },
68
+ scrollIntoView: true,
69
+ });
70
+ };
71
+
72
+ const staticEntry = ({ label, type, detail, info, insertText, boost = 85 }: StaticCompletionEntry): Completion =>
73
+ ({
74
+ label,
75
+ type,
76
+ detail,
77
+ info,
78
+ boost,
79
+ apply: insertText ? createApply(insertText) : undefined,
80
+ }) as Completion;
81
+
82
+ const SAFE_GLOBAL_COMPLETIONS: StaticCompletionEntry[] = [
83
+ {
84
+ label: 'window.open()',
85
+ type: 'function',
86
+ detail: '(url: string, target?: string, features?: string) => Window | null',
87
+ info: 'Open a safe http/https/about:blank URL in a new tab.',
88
+ insertText: "window.open('https://example.com')",
89
+ boost: 105,
90
+ },
91
+ {
92
+ label: 'window.addEventListener()',
93
+ type: 'function',
94
+ detail: '(type: string, listener: EventListener) => void',
95
+ info: 'Attach a listener to the safe window proxy.',
96
+ insertText: "window.addEventListener('resize', () => {})",
97
+ boost: 105,
98
+ },
99
+ {
100
+ label: 'window.setTimeout()',
101
+ type: 'function',
102
+ detail: '(handler: Function, timeout?: number) => number',
103
+ insertText: 'window.setTimeout(() => {}, 0)',
104
+ boost: 100,
105
+ },
106
+ {
107
+ label: 'window.clearTimeout()',
108
+ type: 'function',
109
+ detail: '(id?: number) => void',
110
+ insertText: 'window.clearTimeout(timer)',
111
+ boost: 100,
112
+ },
113
+ {
114
+ label: 'window.setInterval()',
115
+ type: 'function',
116
+ detail: '(handler: Function, timeout?: number) => number',
117
+ insertText: 'window.setInterval(() => {}, 1000)',
118
+ boost: 100,
119
+ },
120
+ {
121
+ label: 'window.clearInterval()',
122
+ type: 'function',
123
+ detail: '(id?: number) => void',
124
+ insertText: 'window.clearInterval(timer)',
125
+ boost: 100,
126
+ },
127
+ {
128
+ label: 'window.FormData',
129
+ type: 'class',
130
+ detail: 'FormData constructor',
131
+ insertText: 'new window.FormData()',
132
+ boost: 95,
133
+ },
134
+ { label: 'window.Blob', type: 'class', detail: 'Blob constructor', insertText: 'window.Blob', boost: 95 },
135
+ { label: 'window.URL', type: 'class', detail: 'URL constructor', insertText: 'window.URL', boost: 95 },
136
+ { label: 'window.location.origin', type: 'property', detail: 'string', boost: 100 },
137
+ { label: 'window.location.protocol', type: 'property', detail: 'string', boost: 100 },
138
+ { label: 'window.location.host', type: 'property', detail: 'string', boost: 100 },
139
+ { label: 'window.location.hostname', type: 'property', detail: 'string', boost: 100 },
140
+ { label: 'window.location.port', type: 'property', detail: 'string', boost: 100 },
141
+ { label: 'window.location.pathname', type: 'property', detail: 'string', boost: 100 },
142
+ {
143
+ label: 'window.location.assign()',
144
+ type: 'function',
145
+ detail: '(url: string) => void',
146
+ insertText: "window.location.assign('/path')",
147
+ boost: 105,
148
+ },
149
+ {
150
+ label: 'window.location.replace()',
151
+ type: 'function',
152
+ detail: '(url: string) => void',
153
+ insertText: "window.location.replace('/path')",
154
+ boost: 105,
155
+ },
156
+ {
157
+ label: 'window.location.reload()',
158
+ type: 'function',
159
+ detail: '() => void',
160
+ insertText: 'window.location.reload()',
161
+ boost: 110,
162
+ },
163
+ {
164
+ label: 'window.location.href =',
165
+ type: 'snippet',
166
+ detail: 'safe assignment only',
167
+ info: 'RunJS allows assigning window.location.href, but reading href is blocked.',
168
+ insertText: "window.location.href = '/path'",
169
+ boost: 95,
170
+ },
171
+ {
172
+ label: 'document.createElement()',
173
+ type: 'function',
174
+ detail: '(tagName: string) => HTMLElement',
175
+ insertText: "document.createElement('div')",
176
+ boost: 105,
177
+ },
178
+ {
179
+ label: 'document.querySelector()',
180
+ type: 'function',
181
+ detail: '(selectors: string) => Element | null',
182
+ insertText: "document.querySelector('.selector')",
183
+ boost: 105,
184
+ },
185
+ {
186
+ label: 'document.querySelectorAll()',
187
+ type: 'function',
188
+ detail: '(selectors: string) => NodeListOf<Element>',
189
+ insertText: "document.querySelectorAll('.selector')",
190
+ boost: 105,
191
+ },
192
+ {
193
+ label: 'navigator.clipboard.writeText()',
194
+ type: 'function',
195
+ detail: '(text: string) => Promise<void>',
196
+ insertText: "await navigator.clipboard.writeText('text')",
197
+ boost: 105,
198
+ },
199
+ { label: 'navigator.onLine', type: 'property', detail: 'boolean', boost: 100 },
200
+ { label: 'navigator.language', type: 'property', detail: 'string', boost: 100 },
201
+ { label: 'navigator.languages', type: 'property', detail: 'string[]', boost: 100 },
202
+ {
203
+ label: 'console.log()',
204
+ type: 'function',
205
+ detail: '(...args: any[]) => void',
206
+ insertText: "console.log('message')",
207
+ boost: 95,
208
+ },
209
+ {
210
+ label: 'console.info()',
211
+ type: 'function',
212
+ detail: '(...args: any[]) => void',
213
+ insertText: "console.info('message')",
214
+ boost: 95,
215
+ },
216
+ {
217
+ label: 'console.warn()',
218
+ type: 'function',
219
+ detail: '(...args: any[]) => void',
220
+ insertText: "console.warn('message')",
221
+ boost: 95,
222
+ },
223
+ {
224
+ label: 'console.error()',
225
+ type: 'function',
226
+ detail: '(...args: any[]) => void',
227
+ insertText: "console.error('message')",
228
+ boost: 95,
229
+ },
230
+ {
231
+ label: 'setTimeout()',
232
+ type: 'function',
233
+ detail: '(handler: Function, timeout?: number) => number',
234
+ insertText: 'setTimeout(() => {}, 0)',
235
+ boost: 95,
236
+ },
237
+ {
238
+ label: 'clearTimeout()',
239
+ type: 'function',
240
+ detail: '(id?: number) => void',
241
+ insertText: 'clearTimeout(timer)',
242
+ boost: 95,
243
+ },
244
+ {
245
+ label: 'setInterval()',
246
+ type: 'function',
247
+ detail: '(handler: Function, timeout?: number) => number',
248
+ insertText: 'setInterval(() => {}, 1000)',
249
+ boost: 95,
250
+ },
251
+ {
252
+ label: 'clearInterval()',
253
+ type: 'function',
254
+ detail: '(id?: number) => void',
255
+ insertText: 'clearInterval(timer)',
256
+ boost: 95,
257
+ },
258
+ { label: 'Blob', type: 'class', detail: 'Blob constructor', insertText: 'Blob', boost: 90 },
259
+ { label: 'URL', type: 'class', detail: 'URL constructor', insertText: 'URL', boost: 90 },
260
+ ];
261
+
262
+ const RUNJS_RUNTIME_COMPLETIONS: StaticCompletionEntry[] = [
263
+ {
264
+ label: 'ctx.runjs()',
265
+ type: 'function',
266
+ detail: '(code: string, variables?: object, options?: object) => Promise<any>',
267
+ insertText: "await ctx.runjs('return 1')",
268
+ boost: 105,
269
+ },
270
+ {
271
+ label: 'ctx.loadCSS()',
272
+ type: 'function',
273
+ detail: '(href: string) => Promise<void>',
274
+ insertText: "await ctx.loadCSS('https://example.com/style.css')",
275
+ boost: 105,
276
+ },
277
+ {
278
+ label: 'ctx.previewRunJS()',
279
+ type: 'function',
280
+ detail: '(code: string, version?: string) => Promise<PreviewRunJSResult>',
281
+ insertText: "await ctx.previewRunJS('console.log(1)', 'v2')",
282
+ boost: 105,
283
+ },
284
+ {
285
+ label: 'ctx.requireAsync()',
286
+ type: 'function',
287
+ detail: '(url: string) => Promise<any>',
288
+ insertText: "const lib = await ctx.requireAsync('https://cdn.example.com/lib.umd.js')",
289
+ boost: 100,
290
+ },
291
+ {
292
+ label: 'ctx.importAsync()',
293
+ type: 'function',
294
+ detail: '(url: string) => Promise<any>',
295
+ insertText: "const mod = await ctx.importAsync('lodash-es')",
296
+ boost: 100,
297
+ },
298
+ {
299
+ label: 'ctx.t()',
300
+ type: 'function',
301
+ detail: '(key: string, options?: object) => string',
302
+ insertText: "ctx.t('Hello')",
303
+ boost: 100,
304
+ },
305
+ {
306
+ label: 'ctx.resolveJsonTemplate()',
307
+ type: 'function',
308
+ detail: '(template: any) => Promise<any>',
309
+ insertText: "await ctx.resolveJsonTemplate({ value: '{{ctx.record.id}}' })",
310
+ boost: 100,
311
+ },
312
+ {
313
+ label: 'ctx.sql.run()',
314
+ type: 'function',
315
+ detail: '(sql: string, options?: SQLRunOptions) => Promise<any>',
316
+ insertText: "await ctx.sql.run('SELECT 1', { type: 'selectRows' })",
317
+ boost: 100,
318
+ },
319
+ {
320
+ label: 'ctx.sql.save()',
321
+ type: 'function',
322
+ detail: '(data: { uid: string; sql: string; dataSourceKey?: string }) => Promise<void>',
323
+ insertText: "await ctx.sql.save({ uid: 'sql-uid', sql: 'SELECT 1' })",
324
+ boost: 95,
325
+ },
326
+ {
327
+ label: 'ctx.sql.runById()',
328
+ type: 'function',
329
+ detail: '(uid: string, options?: SQLRunOptions) => Promise<any>',
330
+ insertText: "await ctx.sql.runById('sql-uid', { type: 'selectRows' })",
331
+ boost: 100,
332
+ },
333
+ {
334
+ label: 'ctx.sql.destroy()',
335
+ type: 'function',
336
+ detail: '(uid: string) => Promise<void>',
337
+ insertText: "await ctx.sql.destroy('sql-uid')",
338
+ boost: 95,
339
+ },
340
+ {
341
+ label: 'ctx.logger.info()',
342
+ type: 'function',
343
+ detail: 'Pino logger info',
344
+ insertText: "ctx.logger.info({ foo: 1 }, 'message')",
345
+ boost: 95,
346
+ },
347
+ {
348
+ label: 'ctx.logger.warn()',
349
+ type: 'function',
350
+ detail: 'Pino logger warn',
351
+ insertText: "ctx.logger.warn({ foo: 1 }, 'message')",
352
+ boost: 95,
353
+ },
354
+ {
355
+ label: 'ctx.logger.error()',
356
+ type: 'function',
357
+ detail: 'Pino logger error',
358
+ insertText: "ctx.logger.error({ err }, 'message')",
359
+ boost: 95,
360
+ },
361
+ {
362
+ label: 'ctx.logger.debug()',
363
+ type: 'function',
364
+ detail: 'Pino logger debug',
365
+ insertText: "ctx.logger.debug({ foo: 1 }, 'message')",
366
+ boost: 95,
367
+ },
368
+ {
369
+ label: 'ctx.logger.child()',
370
+ type: 'function',
371
+ detail: '(bindings: object) => Logger',
372
+ insertText: "ctx.logger.child({ module: 'runjs' })",
373
+ boost: 90,
374
+ },
375
+ {
376
+ label: 'ctx.libs.React.createElement()',
377
+ type: 'function',
378
+ detail: 'React.createElement',
379
+ insertText: "ctx.libs.React.createElement('div', null, 'Hello')",
380
+ boost: 90,
381
+ },
382
+ {
383
+ label: 'ctx.libs.React.useState()',
384
+ type: 'function',
385
+ detail: 'React.useState',
386
+ insertText: 'ctx.libs.React.useState(initialValue)',
387
+ boost: 90,
388
+ },
389
+ {
390
+ label: 'ctx.libs.React.useEffect()',
391
+ type: 'function',
392
+ detail: 'React.useEffect',
393
+ insertText: 'ctx.libs.React.useEffect(() => {}, [])',
394
+ boost: 90,
395
+ },
396
+ {
397
+ label: 'ctx.libs.React.useMemo()',
398
+ type: 'function',
399
+ detail: 'React.useMemo',
400
+ insertText: 'ctx.libs.React.useMemo(() => value, [])',
401
+ boost: 85,
402
+ },
403
+ {
404
+ label: 'ctx.libs.React.useCallback()',
405
+ type: 'function',
406
+ detail: 'React.useCallback',
407
+ insertText: 'ctx.libs.React.useCallback(() => {}, [])',
408
+ boost: 85,
409
+ },
410
+ {
411
+ label: 'ctx.libs.ReactDOM.createRoot()',
412
+ type: 'function',
413
+ detail: 'ReactDOM.createRoot',
414
+ insertText: 'ctx.libs.ReactDOM.createRoot(ctx.element.__el)',
415
+ boost: 90,
416
+ requires: ['element'],
417
+ },
418
+ { label: 'ctx.libs.antd.Button', type: 'class', detail: 'Ant Design Button', boost: 90 },
419
+ { label: 'ctx.libs.antd.Table', type: 'class', detail: 'Ant Design Table', boost: 90 },
420
+ { label: 'ctx.libs.antd.Form', type: 'class', detail: 'Ant Design Form', boost: 90 },
421
+ { label: 'ctx.libs.antd.Input', type: 'class', detail: 'Ant Design Input', boost: 90 },
422
+ { label: 'ctx.libs.antd.Select', type: 'class', detail: 'Ant Design Select', boost: 90 },
423
+ { label: 'ctx.libs.antd.Modal', type: 'class', detail: 'Ant Design Modal', boost: 90 },
424
+ { label: 'ctx.libs.dayjs()', type: 'function', detail: 'dayjs', insertText: 'ctx.libs.dayjs()', boost: 90 },
425
+ {
426
+ label: 'ctx.libs.lodash.get()',
427
+ type: 'function',
428
+ detail: 'lodash.get',
429
+ insertText: "ctx.libs.lodash.get(obj, 'a.b')",
430
+ boost: 90,
431
+ },
432
+ {
433
+ label: 'ctx.libs.lodash.set()',
434
+ type: 'function',
435
+ detail: 'lodash.set',
436
+ insertText: "ctx.libs.lodash.set(obj, 'a.b', value)",
437
+ boost: 85,
438
+ },
439
+ {
440
+ label: 'ctx.libs.lodash.debounce()',
441
+ type: 'function',
442
+ detail: 'lodash.debounce',
443
+ insertText: 'ctx.libs.lodash.debounce(() => {}, 300)',
444
+ boost: 85,
445
+ },
446
+ {
447
+ label: 'ctx.libs.lodash.cloneDeep()',
448
+ type: 'function',
449
+ detail: 'lodash.cloneDeep',
450
+ insertText: 'ctx.libs.lodash.cloneDeep(value)',
451
+ boost: 85,
452
+ },
453
+ {
454
+ label: 'ctx.libs.formula.SUM()',
455
+ type: 'function',
456
+ detail: 'Formula.js SUM',
457
+ insertText: 'ctx.libs.formula.SUM(1, 2, 3)',
458
+ boost: 85,
459
+ },
460
+ {
461
+ label: 'ctx.libs.formula.AVERAGE()',
462
+ type: 'function',
463
+ detail: 'Formula.js AVERAGE',
464
+ insertText: 'ctx.libs.formula.AVERAGE(1, 2, 3)',
465
+ boost: 85,
466
+ },
467
+ {
468
+ label: 'ctx.libs.math.evaluate()',
469
+ type: 'function',
470
+ detail: 'mathjs evaluate',
471
+ insertText: "ctx.libs.math.evaluate('2 + 3')",
472
+ boost: 85,
473
+ },
474
+ {
475
+ label: 'ctx.libs.math.round()',
476
+ type: 'function',
477
+ detail: 'mathjs round',
478
+ insertText: 'ctx.libs.math.round(value, 2)',
479
+ boost: 85,
480
+ },
481
+ {
482
+ label: 'ctx.React.createElement()',
483
+ type: 'function',
484
+ detail: 'React.createElement alias',
485
+ insertText: "ctx.React.createElement('div', null, 'Hello')",
486
+ boost: 80,
487
+ },
488
+ {
489
+ label: 'ctx.ReactDOM.createRoot()',
490
+ type: 'function',
491
+ detail: 'ReactDOM.createRoot alias',
492
+ insertText: 'ctx.ReactDOM.createRoot(ctx.element.__el)',
493
+ boost: 80,
494
+ requires: ['element'],
495
+ },
496
+ { label: 'ctx.antd.Button', type: 'class', detail: 'Ant Design Button alias', boost: 80 },
497
+ { label: 'ctx.antd.Modal', type: 'class', detail: 'Ant Design Modal alias', boost: 80 },
498
+ { label: 'ctx.dayjs()', type: 'function', detail: 'dayjs alias', insertText: 'ctx.dayjs()', boost: 80 },
499
+ ];
500
+
501
+ function buildStaticRuntimeCompletions(capabilities: { element: boolean }): Completion[] {
502
+ return [...SAFE_GLOBAL_COMPLETIONS, ...RUNJS_RUNTIME_COMPLETIONS]
503
+ .filter((entry) => satisfiesCompletionRequirements(entry, capabilities))
504
+ .filter((entry) => capabilities.element || !usesCtxElement(entry.insertText))
505
+ .map(staticEntry);
506
+ }
507
+
26
508
  export async function buildRunJSCompletions(
27
509
  hostCtx: any,
28
510
  version = 'v1',
@@ -31,6 +513,7 @@ export async function buildRunJSCompletions(
31
513
  completions: Completion[];
32
514
  entries: SnippetEntry[];
33
515
  }> {
516
+ const requestedScenes = normalizeScenes(scene);
34
517
  const isFunctionLikeDocNode = (node: any, completionSpec: any): boolean => {
35
518
  if (!node || typeof node !== 'object' || Array.isArray(node)) return false;
36
519
  const type = typeof (node as any).type === 'string' ? String((node as any).type) : '';
@@ -56,7 +539,7 @@ export async function buildRunJSCompletions(
56
539
  let apiInfos: any = null;
57
540
  try {
58
541
  if (hostCtx && typeof (hostCtx as any).getApiInfos === 'function') {
59
- apiInfos = await (hostCtx as any).getApiInfos({ version });
542
+ apiInfos = await (hostCtx as any).getApiInfos({ version, includeCompletion: true });
60
543
  }
61
544
  } catch (_) {
62
545
  apiInfos = null;
@@ -73,10 +556,12 @@ export async function buildRunJSCompletions(
73
556
  };
74
557
  const docApis = { ...((doc as any)?.properties || {}), ...normalizeMethodsRecord((doc as any)?.methods) };
75
558
  const apisSource = { ...(apiInfos && typeof apiInfos === 'object' ? apiInfos : {}), ...(docApis || {}) };
76
- const completions: Completion[] = [];
559
+ const hasElementContext = hasRunJSElementContext(doc, apiInfos, requestedScenes);
560
+ const completions: Completion[] = buildStaticRuntimeCompletions({ element: hasElementContext });
77
561
  const priorityRoots = new Set(['api', 'resource', 'viewer', 'record', 'formValues', 'popup']);
78
562
  const hiddenDecisionCache = new Map<string, { hideSelf: boolean; hideSubpaths: string[] }>();
79
563
  const hiddenPathPrefixes = new Set<string>();
564
+ if (!hasElementContext) hiddenPathPrefixes.add('ctx.element');
80
565
 
81
566
  const isHiddenByPaths = (label: string) => {
82
567
  if (!label || typeof label !== 'string') return false;
@@ -201,6 +686,8 @@ export async function buildRunJSCompletions(
201
686
  const insertText =
202
687
  completionSpec?.insertText ??
203
688
  (root === 'popup' ? `await ctx.getVar('${ctxLabel}')` : isCallable ? `${ctxLabel}()` : undefined);
689
+ if (!satisfiesCompletionRequirements(completionSpec, { element: hasElementContext })) continue;
690
+ if (!hasElementContext && usesCtxElement(insertText)) continue;
204
691
  const apply = insertText
205
692
  ? (view: EditorView, _completion: Completion, from: number, to: number) => {
206
693
  view.dispatch({
@@ -235,12 +722,6 @@ export async function buildRunJSCompletions(
235
722
  entries = [];
236
723
  }
237
724
 
238
- const requestedScenes = Array.isArray(scene)
239
- ? scene.filter((s): s is string => typeof s === 'string' && s.trim().length > 0)
240
- : scene
241
- ? [scene]
242
- : [];
243
-
244
725
  const filteredEntries = requestedScenes.length
245
726
  ? entries.filter((entry) => {
246
727
  if (entry.scenes?.length) {
@@ -76,10 +76,15 @@ function getCollectionFromFormBlockModel(model: any): CollectionLike | null {
76
76
  return collection && typeof collection === 'object' ? (collection as CollectionLike) : null;
77
77
  }
78
78
 
79
- function buildRootOptionsFromCollection(
79
+ export function buildFieldAssignCascaderOptionsFromCollection(
80
80
  collection: CollectionLike | null,
81
81
  t: (key: string) => string,
82
+ options: {
83
+ associationDepth?: number;
84
+ maxAssociationFieldDepth?: number;
85
+ } = {},
82
86
  ): FieldAssignCascaderOption[] {
87
+ const { associationDepth = 0, maxAssociationFieldDepth = 2 } = options;
83
88
  const fields = typeof collection?.getFields === 'function' ? collection.getFields() || [] : [];
84
89
  const out: FieldAssignCascaderOption[] = [];
85
90
  for (const rawField of fields) {
@@ -88,6 +93,7 @@ function buildRootOptionsFromCollection(
88
93
  name?: unknown;
89
94
  title?: unknown;
90
95
  interface?: unknown;
96
+ target?: unknown;
91
97
  isAssociationField?: () => boolean;
92
98
  targetCollection?: any;
93
99
  };
@@ -99,8 +105,11 @@ function buildRootOptionsFromCollection(
99
105
  if (!name) continue;
100
106
  const title = t(typeof f.title === 'string' ? f.title : name);
101
107
 
102
- const isAssoc = !!f.isAssociationField?.();
108
+ const isAssoc = !!(f.isAssociationField?.() || f.target || f.targetCollection);
103
109
  const hasTarget = !!f.targetCollection;
110
+ if (isAssoc && associationDepth >= maxAssociationFieldDepth) {
111
+ continue;
112
+ }
104
113
 
105
114
  out.push({
106
115
  label: title,
@@ -138,8 +147,9 @@ export function collectFieldAssignCascaderOptions(options: {
138
147
  t: (key: string) => string;
139
148
  /** 子表单模型递归深度(FormItemModel 层级);默认不限制(只受实际配置与循环引用约束) */
140
149
  maxFormItemDepth?: number;
150
+ maxAssociationFieldDepth?: number;
141
151
  }): FieldAssignCascaderOption[] {
142
- const { formBlockModel, t, maxFormItemDepth = Number.POSITIVE_INFINITY } = options;
152
+ const { formBlockModel, t, maxFormItemDepth = Number.POSITIVE_INFINITY, maxAssociationFieldDepth = 2 } = options;
143
153
 
144
154
  const rootItems = formBlockModel?.subModels?.grid?.subModels?.items || [];
145
155
  const rootCollection = getCollectionFromFormBlockModel(formBlockModel);
@@ -167,9 +177,14 @@ export function collectFieldAssignCascaderOptions(options: {
167
177
 
168
178
  const fieldModel = item?.subModels?.field;
169
179
  const childItems = fieldModel?.subModels?.grid?.subModels?.items;
170
- const cf: CollectionField | undefined = fieldModel?.context?.collectionField;
171
- const isAssociation = !!cf?.isAssociationField?.();
180
+ const cf: (CollectionField & { target?: unknown; targetCollection?: unknown }) | undefined =
181
+ fieldModel?.context?.collectionField;
182
+ const isAssociation = !!(cf?.isAssociationField?.() || cf?.target || cf?.targetCollection);
172
183
  const hasTargetCollection = !!cf?.targetCollection;
184
+ const associationDepth = isAssociation ? targetPath.split('.').filter(Boolean).length : 0;
185
+ if (isAssociation && associationDepth > maxAssociationFieldDepth) {
186
+ continue;
187
+ }
173
188
 
174
189
  // 1) 子表单/子表单列表:递归展开已配置字段(支持无限深度)。
175
190
  //
@@ -207,6 +222,8 @@ export function collectFieldAssignCascaderOptions(options: {
207
222
  };
208
223
 
209
224
  const configuredOptions = walkItems(rootItems, 1);
210
- const allFieldOptions = buildRootOptionsFromCollection(rootCollection, t);
225
+ const allFieldOptions = buildFieldAssignCascaderOptionsFromCollection(rootCollection, t, {
226
+ maxAssociationFieldDepth,
227
+ });
211
228
  return mergeRootOptions(configuredOptions, allFieldOptions);
212
229
  }
@@ -30,6 +30,7 @@ import {
30
30
  } from '../../internal/utils/enumOptionsUtils';
31
31
  import { mergeItemMetaTreeForAssignValue } from '../FieldAssignValueInput';
32
32
  import { resolveOperatorComponent } from '../../internal/utils/operatorSchemaHelper';
33
+ import { limitAssociationMetaTree } from './metaTreeAssociationDepth';
33
34
 
34
35
  const { DateFilterDynamicComponent: DateFilterDynamicComponentLazy } = lazy(
35
36
  () => import('../../models/blocks/filter-form/fields/date-time/components/DateFilterDynamicComponent'),
@@ -49,6 +50,14 @@ export interface LinkageFilterItemProps {
49
50
  model: FlowModel;
50
51
  /** 向变量树额外注入节点(置于根部) */
51
52
  extraMetaTree?: MetaTreeNode[];
53
+ maxAssociationFieldDepth?: number;
54
+ }
55
+
56
+ function limitMetaTreeIfNeeded(nodes: MetaTreeNode[], maxAssociationFieldDepth?: number) {
57
+ if (typeof maxAssociationFieldDepth !== 'number') {
58
+ return nodes;
59
+ }
60
+ return limitAssociationMetaTree(nodes, { maxAssociationDepth: maxAssociationFieldDepth });
52
61
  }
53
62
 
54
63
  function createStaticInputRenderer(
@@ -221,7 +230,7 @@ export async function enhanceMetaTreeWithFilterableChildren(
221
230
  * LinkageFilterItem:左/右均为可变量输入,适用于联动规则等“前端逻辑”场景
222
231
  */
223
232
  export const LinkageFilterItem: React.FC<LinkageFilterItemProps> = observer((props) => {
224
- const { value, model, extraMetaTree } = props;
233
+ const { value, model, extraMetaTree, maxAssociationFieldDepth } = props;
225
234
  const ctx = useFlowViewContext();
226
235
  const t = model.translate;
227
236
  const { path: leftPath, operator: selectedOperator, value: rightOperandValue } = value || {};
@@ -386,13 +395,16 @@ export const LinkageFilterItem: React.FC<LinkageFilterItemProps> = observer((pro
386
395
  return async () => {
387
396
  const baseMetaTree = (model?.context.getPropertyMetaTree() || ctx.getPropertyMetaTree()) as MetaTreeNode[];
388
397
  const mergedMetaTree = mergeExtraMetaTreeWithBase(baseMetaTree, extraMetaTree);
389
- return [
390
- { title: t('Constant'), name: 'constant', type: 'string', paths: ['constant'] },
391
- { title: t('Null'), name: 'null', type: 'object', paths: ['null'] },
392
- ...mergedMetaTree,
393
- ];
398
+ return limitMetaTreeIfNeeded(
399
+ [
400
+ { title: t('Constant'), name: 'constant', type: 'string', paths: ['constant'] },
401
+ { title: t('Null'), name: 'null', type: 'object', paths: ['null'] },
402
+ ...mergedMetaTree,
403
+ ],
404
+ maxAssociationFieldDepth,
405
+ );
394
406
  };
395
- }, [ctx, model, t, extraMetaTree]);
407
+ }, [ctx, model, t, extraMetaTree, maxAssociationFieldDepth]);
396
408
 
397
409
  // 左侧变量树:默认整棵 ctx(不追加 Constant/Null),确保可获取字段 interface
398
410
  const leftMetaTreeGetter = useCallback(async () => {
@@ -403,8 +415,9 @@ export const LinkageFilterItem: React.FC<LinkageFilterItemProps> = observer((pro
403
415
  getFlowFieldInterfaceOptions(name, model.context.dataSourceManager, model.context.app?.dataSourceManager) as
404
416
  | FieldInterfaceDef
405
417
  | undefined;
406
- return await enhanceMetaTreeWithFilterableChildren(merged, getFieldInterface);
407
- }, [ctx, model, extraMetaTree]);
418
+ const enhanced = await enhanceMetaTreeWithFilterableChildren(merged, getFieldInterface);
419
+ return limitMetaTreeIfNeeded(enhanced, maxAssociationFieldDepth);
420
+ }, [ctx, model, extraMetaTree, maxAssociationFieldDepth]);
408
421
 
409
422
  // 右侧 converters:常量/空值特殊处理;变量沿用默认(表达式)
410
423
  const rightSideConverters = useMemo<Converters>(() => {