@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
@@ -13,6 +13,113 @@ import { FlowSettingsContextProvider } from '@nocobase/flow-engine';
13
13
  import { describe, expect, it, vi } from 'vitest';
14
14
  import { fieldLinkageRules, linkageSetFieldProps, subFormLinkageSetFieldProps } from '../linkageRules';
15
15
 
16
+ const createSubFormFieldModel = ({
17
+ uid,
18
+ fieldPath,
19
+ hidden,
20
+ blockUid = 'block-1',
21
+ fieldIndex,
22
+ fieldPathArray,
23
+ }: {
24
+ uid: string;
25
+ fieldPath: string;
26
+ hidden: boolean;
27
+ blockUid?: string;
28
+ fieldIndex?: string[];
29
+ fieldPathArray?: Array<string | number>;
30
+ }) => ({
31
+ uid,
32
+ hidden,
33
+ props: {},
34
+ context: {
35
+ blockModel: { uid: blockUid },
36
+ ...(fieldIndex ? { fieldIndex } : {}),
37
+ ...(fieldPathArray ? { fieldPathArray } : {}),
38
+ },
39
+ forks: new Set(),
40
+ getStepParams: (flowKey: string, stepKey: string) => {
41
+ if (flowKey === 'fieldSettings' && stepKey === 'init') {
42
+ return { fieldPath };
43
+ }
44
+ },
45
+ setProps(key: any, value?: any) {
46
+ if (typeof key === 'string') {
47
+ this.props[key] = value;
48
+ } else {
49
+ this.props = { ...this.props, ...key };
50
+ }
51
+ },
52
+ });
53
+
54
+ const runSubFormFieldStateRule = async ({
55
+ state,
56
+ fieldUid,
57
+ fieldKey,
58
+ targetModel,
59
+ models,
60
+ }: {
61
+ state: 'visible' | 'hidden';
62
+ fieldUid: string;
63
+ fieldKey: string[];
64
+ targetModel: any;
65
+ models: any[];
66
+ }) => {
67
+ const formItemModel: any = {
68
+ uid: fieldUid,
69
+ forks: new Set([targetModel]),
70
+ getFork: vi.fn((key: string) => (key === `${fieldKey}:${fieldUid}` ? targetModel : undefined)),
71
+ };
72
+ const allModels = [formItemModel, ...models];
73
+ const ctx: any = {
74
+ app: {
75
+ jsonLogic: {
76
+ apply: vi.fn(() => true),
77
+ },
78
+ },
79
+ model: {
80
+ context: {
81
+ blockModel: { uid: 'block-1' },
82
+ fieldKey,
83
+ },
84
+ flowEngine: {
85
+ forEachModel: (visitor: (model: any) => void) => {
86
+ allModels.forEach(visitor);
87
+ },
88
+ },
89
+ },
90
+ engine: {
91
+ getModel: vi.fn((uid: string) => (uid === fieldUid ? formItemModel : undefined)),
92
+ forEachModel: (visitor: (model: any) => void) => {
93
+ allModels.forEach(visitor);
94
+ },
95
+ },
96
+ getAction: (name: string) => (name === 'subFormLinkageSetFieldProps' ? subFormLinkageSetFieldProps : null),
97
+ resolveJsonTemplate: vi.fn(async (value) => value),
98
+ };
99
+
100
+ await fieldLinkageRules.handler(ctx, {
101
+ value: [
102
+ {
103
+ key: 'rule-1',
104
+ enable: true,
105
+ condition: { logic: '$and', items: [] },
106
+ actions: [
107
+ {
108
+ key: 'action-1',
109
+ name: 'subFormLinkageSetFieldProps',
110
+ params: {
111
+ value: {
112
+ fields: [fieldUid],
113
+ state,
114
+ },
115
+ },
116
+ },
117
+ ],
118
+ },
119
+ ],
120
+ });
121
+ };
122
+
16
123
  describe('subFormLinkageSetFieldProps action', () => {
17
124
  it('should not throw when engine.getModel returns undefined', () => {
18
125
  const setProps = vi.fn();
@@ -144,6 +251,90 @@ describe('subFormLinkageSetFieldProps action', () => {
144
251
 
145
252
  expect(setProps).toHaveBeenCalledWith(forkModel, { options: selectedOptions });
146
253
  });
254
+
255
+ it('should sync hidden state when a subform field changes from hidden to visible', async () => {
256
+ const targetModel = createSubFormFieldModel({
257
+ uid: 'field-a',
258
+ fieldPath: 'a',
259
+ hidden: true,
260
+ fieldIndex: ['items:0'],
261
+ });
262
+ const collectedModel = createSubFormFieldModel({
263
+ uid: 'field-a-collected',
264
+ fieldPath: 'a',
265
+ hidden: true,
266
+ fieldPathArray: ['items', 0, 'a'],
267
+ });
268
+
269
+ await runSubFormFieldStateRule({
270
+ state: 'visible',
271
+ fieldUid: 'field-a',
272
+ fieldKey: ['items:0'],
273
+ targetModel,
274
+ models: [collectedModel],
275
+ });
276
+
277
+ expect(targetModel.hidden).toBe(false);
278
+ expect(collectedModel.hidden).toBe(false);
279
+ });
280
+
281
+ it('should sync hidden state when a subform field changes from visible to hidden', async () => {
282
+ const targetModel = createSubFormFieldModel({
283
+ uid: 'field-a',
284
+ fieldPath: 'a',
285
+ hidden: false,
286
+ fieldIndex: ['items:0'],
287
+ });
288
+ const collectedModel = createSubFormFieldModel({
289
+ uid: 'field-a-collected',
290
+ fieldPath: 'a',
291
+ hidden: false,
292
+ fieldPathArray: ['items', 0, 'a'],
293
+ });
294
+
295
+ await runSubFormFieldStateRule({
296
+ state: 'hidden',
297
+ fieldUid: 'field-a',
298
+ fieldKey: ['items:0'],
299
+ targetModel,
300
+ models: [collectedModel],
301
+ });
302
+
303
+ expect(targetModel.hidden).toBe(true);
304
+ expect(collectedModel.hidden).toBe(true);
305
+ });
306
+
307
+ it('should only sync hidden state for the current subform row', async () => {
308
+ const targetModel = createSubFormFieldModel({
309
+ uid: 'field-a',
310
+ fieldPath: 'a',
311
+ hidden: true,
312
+ fieldIndex: ['items:0'],
313
+ });
314
+ const row0CollectedModel = createSubFormFieldModel({
315
+ uid: 'field-a-row-0',
316
+ fieldPath: 'a',
317
+ hidden: true,
318
+ fieldPathArray: ['items', 0, 'a'],
319
+ });
320
+ const row1CollectedModel = createSubFormFieldModel({
321
+ uid: 'field-a-row-1',
322
+ fieldPath: 'a',
323
+ hidden: true,
324
+ fieldPathArray: ['items', 1, 'a'],
325
+ });
326
+
327
+ await runSubFormFieldStateRule({
328
+ state: 'visible',
329
+ fieldUid: 'field-a',
330
+ fieldKey: ['items:0'],
331
+ targetModel,
332
+ models: [row0CollectedModel, row1CollectedModel],
333
+ });
334
+
335
+ expect(row0CollectedModel.hidden).toBe(false);
336
+ expect(row1CollectedModel.hidden).toBe(true);
337
+ });
147
338
  });
148
339
 
149
340
  describe('linkageSetFieldProps action', () => {
@@ -46,7 +46,7 @@ describe('linkageRulesRefresh action', () => {
46
46
  expect(handler).not.toHaveBeenCalled();
47
47
  });
48
48
 
49
- it('runs linkage action on master model when forks are not mounted in runtime mode', async () => {
49
+ it('skips master model when forks can handle flow even if regular action buttons do not attach refs', async () => {
50
50
  const handler = vi.fn(async () => {});
51
51
  const model: any = {
52
52
  isFork: false,
@@ -74,6 +74,28 @@ describe('linkageRulesRefresh action', () => {
74
74
  flowKey: 'buttonSettings',
75
75
  });
76
76
 
77
+ expect(handler).not.toHaveBeenCalled();
78
+ });
79
+
80
+ it('runs linkage action on master model when no forks exist in runtime mode', async () => {
81
+ const handler = vi.fn(async () => {});
82
+ const model: any = {
83
+ isFork: false,
84
+ forks: new Set(),
85
+ getFlow: vi.fn(() => ({})),
86
+ getStepParams: vi.fn(() => ({ value: ['master-runtime'] })),
87
+ };
88
+ const ctx: any = {
89
+ model,
90
+ resolveJsonTemplate: vi.fn(async (p: any) => p),
91
+ getAction: vi.fn(() => ({ handler })),
92
+ };
93
+
94
+ await linkageRulesRefresh.handler(ctx, {
95
+ actionName: 'actionLinkageRules',
96
+ flowKey: 'buttonSettings',
97
+ });
98
+
77
99
  expect(handler).toHaveBeenCalledWith(ctx, { value: ['master-runtime'] });
78
100
  });
79
101
 
@@ -28,6 +28,7 @@ describe('openView action - subModelKey behavior', () => {
28
28
  flowEngine: { context: { themeToken: { colorBgLayout: '#fff' } } },
29
29
  },
30
30
  layoutContentElement: {},
31
+ layoutContext: { source: 'layout-context' },
31
32
  view: {},
32
33
  viewer: {
33
34
  open: vi.fn(async (_opts: any) => undefined),
@@ -90,6 +91,38 @@ describe('openView action - subModelKey behavior', () => {
90
91
  // FlowPage should receive parent model uid
91
92
  expect(capturedElement?.type).toBe(FlowPage);
92
93
  expect(capturedElement?.props?.parentId).toBe('parent-model-uid');
94
+ expect(capturedElement?.props).not.toHaveProperty('layoutContext');
93
95
  expect(capturedElement?.props?.pageModelClass).toBe('ChildPageModel');
94
96
  });
97
+
98
+ it('uses current layout child page model as default pageModelClass', async () => {
99
+ const { ctx } = createCtx();
100
+ ctx.layout = {
101
+ childPageModelClass: 'MobileChildPageModel',
102
+ };
103
+
104
+ let capturedElement: any;
105
+ (ctx.viewer.open as any).mockImplementation(async (opts) => {
106
+ const currentView = { close: vi.fn(), update: vi.fn() };
107
+ capturedElement = opts.content(currentView);
108
+ return undefined;
109
+ });
110
+
111
+ await openView.handler(ctx, { navigation: false });
112
+
113
+ expect(capturedElement?.type).toBe(FlowPage);
114
+ expect(capturedElement?.props?.pageModelClass).toBe('MobileChildPageModel');
115
+ });
116
+
117
+ it('uses current layout child page model in default params', async () => {
118
+ const { ctx } = createCtx();
119
+ ctx.layout = {
120
+ childPageModelClass: 'MobileChildPageModel',
121
+ };
122
+ ctx.getPropertyMetaTree = vi.fn(() => []);
123
+
124
+ await expect(openView.defaultParams(ctx)).resolves.toMatchObject({
125
+ pageModelClass: 'MobileChildPageModel',
126
+ });
127
+ });
95
128
  });
@@ -24,6 +24,10 @@ const getRecordPkValue = (value: any) => {
24
24
  export const aclCheck = defineAction({
25
25
  name: 'aclCheck',
26
26
  async handler(ctx, params) {
27
+ if (ctx.skipAclCheck) {
28
+ return;
29
+ }
30
+
27
31
  const result = await ctx.aclCheck({
28
32
  dataSourceKey: ctx.dataSource?.key,
29
33
  resourceName: ctx.collectionField?.collectionName || ctx.resourceName,
@@ -158,6 +158,10 @@ export const aclCheckRefresh = defineAction({
158
158
  // 先清理旧状态,避免翻页/fork 复用造成污染
159
159
  resetAclDerivedState(ctx);
160
160
 
161
+ if (ctx.skipAclCheck) {
162
+ return;
163
+ }
164
+
161
165
  if (strategy === 'formItem') {
162
166
  await runFormItemAclCheck(ctx);
163
167
  return;
@@ -33,7 +33,14 @@ export const dataScope = defineAction({
33
33
  return (
34
34
  <FilterGroup
35
35
  value={props.value}
36
- FilterItem={(p) => <VariableFilterItem {...p} model={flowContext.model} rightAsVariable />}
36
+ FilterItem={(p) => (
37
+ <VariableFilterItem
38
+ {...p}
39
+ model={flowContext.model}
40
+ rightAsVariable
41
+ maxAssociationFieldDepth={flowContext.model instanceof FieldModel ? undefined : 2}
42
+ />
43
+ )}
37
44
  />
38
45
  );
39
46
  },
@@ -17,7 +17,7 @@ export const dateTimeFormat = defineAction({
17
17
  name: 'dateDisplayFormat',
18
18
  uiSchema: (ctx) => {
19
19
  const { collectionField } = ctx.model.context as any;
20
- const type = collectionField.type;
20
+ const isTimeField = collectionField.type === 'time' || collectionField.interface === 'time';
21
21
  const timeFormatField = {
22
22
  type: 'string',
23
23
  title: '{{t("Time format")}}',
@@ -41,7 +41,7 @@ export const dateTimeFormat = defineAction({
41
41
  ],
42
42
  'x-reactions': [
43
43
  (field) => {
44
- if (type !== 'time') {
44
+ if (!isTimeField) {
45
45
  const { showTime, picker } = field.form.values || {};
46
46
  field.hidden = !showTime || picker !== 'date';
47
47
  }
@@ -49,7 +49,7 @@ export const dateTimeFormat = defineAction({
49
49
  ],
50
50
  };
51
51
 
52
- if (type === 'time') {
52
+ if (isTimeField) {
53
53
  return {
54
54
  timeFormat: timeFormatField,
55
55
  };
@@ -159,24 +159,28 @@ export const dateTimeFormat = defineAction({
159
159
  };
160
160
  },
161
161
  defaultParams: (ctx: any) => {
162
- const { showTime, dateFormat, timeFormat, picker }: any = {
162
+ const { showTime, dateFormat, format, timeFormat, picker }: any = {
163
163
  ...ctx.model.context.collectionField.getComponentProps(),
164
164
  ...ctx.model.props,
165
165
  };
166
+ const collectionField = ctx.model.context.collectionField;
167
+ const isTimeField = collectionField.type === 'time' || collectionField.interface === 'time';
166
168
  return {
167
169
  picker: picker || 'date',
168
170
  dateFormat: dateFormat || 'YYYY-MM-DD',
169
- timeFormat: timeFormat || 'HH:mm:ss',
171
+ timeFormat: timeFormat || (isTimeField ? format : undefined) || 'HH:mm:ss',
170
172
  showTime,
171
173
  };
172
174
  },
173
175
  handler(ctx: any, params) {
174
176
  const { collectionField } = ctx.model.context as any;
175
- const type = collectionField.type;
176
- if (type === 'time') {
177
+ const isTimeField = collectionField.type === 'time' || collectionField.interface === 'time';
178
+ if (isTimeField) {
179
+ const timeFormat = params?.timeFormat || params?.format || 'HH:mm:ss';
177
180
  ctx.model.setProps({
178
181
  ...params,
179
- format: params?.timeFormat,
182
+ timeFormat,
183
+ format: timeFormat,
180
184
  });
181
185
  } else {
182
186
  ctx.model.setProps({
@@ -1606,7 +1606,9 @@ const LinkageRulesUI = observer(
1606
1606
  <div style={{ paddingLeft: 12 }}>
1607
1607
  <FilterGroup
1608
1608
  value={rule.condition}
1609
- FilterItem={(props) => <LinkageFilterItem model={ctx.model} value={props.value} />}
1609
+ FilterItem={(props) => (
1610
+ <LinkageFilterItem model={ctx.model} value={props.value} maxAssociationFieldDepth={2} />
1611
+ )}
1610
1612
  />
1611
1613
  </div>
1612
1614
  </div>
@@ -1916,6 +1918,120 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
1916
1918
 
1917
1919
  return null;
1918
1920
  };
1921
+ const normalizeNamePathForKey = (namePath: any): Array<string | number> | null => {
1922
+ if (!Array.isArray(namePath) || !namePath.length) return null;
1923
+ const normalized = namePath.filter((seg) => typeof seg === 'string' || typeof seg === 'number') as Array<
1924
+ string | number
1925
+ >;
1926
+ return normalized.length ? normalized : null;
1927
+ };
1928
+ const getFieldIndexEntries = (fieldIndex: any): Array<{ name: string; index: number }> => {
1929
+ if (!Array.isArray(fieldIndex)) return [];
1930
+ return fieldIndex
1931
+ .map((entry) => {
1932
+ if (typeof entry !== 'string') return null;
1933
+ const [name, indexText] = entry.split(':');
1934
+ const index = Number(indexText);
1935
+ if (!name || !Number.isFinite(index)) return null;
1936
+ return { name, index };
1937
+ })
1938
+ .filter(Boolean) as Array<{ name: string; index: number }>;
1939
+ };
1940
+ const resolveIndexedRelativePath = (path: string, fieldIndex: any): Array<string | number> | null => {
1941
+ const pathSegs = parsePathString(path).filter((seg) => typeof seg === 'string' || typeof seg === 'number') as Array<
1942
+ string | number
1943
+ >;
1944
+ if (!pathSegs.length) return null;
1945
+
1946
+ const entries = getFieldIndexEntries(fieldIndex);
1947
+ if (!entries.length) return null;
1948
+
1949
+ const firstSeg = typeof pathSegs[0] === 'string' ? pathSegs[0] : '';
1950
+ const matchedEntryIndex = firstSeg ? entries.findIndex((entry) => entry.name === firstSeg) : -1;
1951
+ const prefixEntries = matchedEntryIndex >= 0 ? entries.slice(0, matchedEntryIndex) : entries;
1952
+ const remainingEntries = matchedEntryIndex >= 0 ? entries.slice(matchedEntryIndex) : [];
1953
+ const out: Array<string | number> = [];
1954
+
1955
+ prefixEntries.forEach((entry) => {
1956
+ out.push(entry.name, entry.index);
1957
+ });
1958
+
1959
+ let entryIndex = 0;
1960
+ pathSegs.forEach((seg, index) => {
1961
+ out.push(seg);
1962
+ const entry = remainingEntries[entryIndex];
1963
+ if (typeof seg !== 'string' || !entry || entry.name !== seg) return;
1964
+
1965
+ const nextSeg = pathSegs[index + 1];
1966
+ if (typeof nextSeg === 'number') {
1967
+ entryIndex += 1;
1968
+ return;
1969
+ }
1970
+ out.push(entry.index);
1971
+ entryIndex += 1;
1972
+ });
1973
+
1974
+ return out;
1975
+ };
1976
+ const getModelTargetPathKeys = (model: any): Set<string> => {
1977
+ const keys = new Set<string>();
1978
+ const fieldPathArray = normalizeNamePathForKey(model?.context?.fieldPathArray);
1979
+ if (fieldPathArray) {
1980
+ keys.add(namePathToPathKey(fieldPathArray));
1981
+ return keys;
1982
+ }
1983
+
1984
+ const targetPath = getModelTargetPathForPatch(model);
1985
+ if (targetPath) {
1986
+ const fieldIndexEntries = getFieldIndexEntries(model?.context?.fieldIndex);
1987
+ if (!fieldIndexEntries.length) {
1988
+ keys.add(`raw:${targetPath}`);
1989
+ }
1990
+
1991
+ const resolved = normalizeNamePathForKey(resolveDynamicNamePath(targetPath, model?.context?.fieldIndex));
1992
+ if (resolved) {
1993
+ keys.add(namePathToPathKey(resolved));
1994
+ }
1995
+
1996
+ const indexedRelativePath = resolveIndexedRelativePath(targetPath, model?.context?.fieldIndex);
1997
+ if (indexedRelativePath) {
1998
+ keys.add(namePathToPathKey(indexedRelativePath));
1999
+ }
2000
+ }
2001
+
2002
+ return keys;
2003
+ };
2004
+ const forEachModelIncludingForks = (visitor: (model: any) => void) => {
2005
+ const engine = (ctx as any)?.engine || ctx.model?.flowEngine;
2006
+ if (!engine?.forEachModel) return;
2007
+ engine.forEachModel((model: any) => {
2008
+ visitor(model);
2009
+
2010
+ const forks: any = model?.forks;
2011
+ if (forks && typeof forks.forEach === 'function') {
2012
+ forks.forEach((fork: any) => {
2013
+ if (!fork || fork.disposed) return;
2014
+ visitor(fork);
2015
+ });
2016
+ }
2017
+ });
2018
+ };
2019
+ const syncHiddenStateByTargetPath = (targetModel: any, hidden: boolean) => {
2020
+ const targetPathKeys = getModelTargetPathKeys(targetModel);
2021
+ if (!targetPathKeys.size) return;
2022
+
2023
+ const targetBlockUid = targetModel?.context?.blockModel?.uid;
2024
+ if (!targetBlockUid) return;
2025
+ forEachModelIncludingForks((model: any) => {
2026
+ if (!model || typeof model !== 'object') return;
2027
+ const modelBlockUid = model?.context?.blockModel?.uid;
2028
+ if (String(modelBlockUid) !== String(targetBlockUid)) return;
2029
+ const modelPathKeys = getModelTargetPathKeys(model);
2030
+ if (!Array.from(modelPathKeys).some((key) => targetPathKeys.has(key))) return;
2031
+
2032
+ model.hidden = hidden;
2033
+ });
2034
+ };
1919
2035
 
1920
2036
  // 1. 运行所有的联动规则
1921
2037
  for (const rule of linkageRules.filter((r) => r.enable)) {
@@ -1981,16 +2097,22 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
1981
2097
  }
1982
2098
  });
1983
2099
 
2100
+ const hiddenStatePatches: Array<{ model: any; hidden: boolean }> = [];
1984
2101
  mergedByUid.forEach((model: any, uid) => {
1985
2102
  const patchProps = mergedPropsByUid.get(uid) || {};
1986
2103
  const newProps = { ...model.__originalProps, ...patchProps };
2104
+ const prevHidden = !!model.hidden;
2105
+ const nextHidden = !!newProps.hiddenModel;
1987
2106
 
1988
2107
  model.setProps(_.omit(newProps, ['hiddenModel', 'value', 'hiddenText']));
1989
2108
  syncFieldOptionsToForks(model, patchProps);
1990
2109
  if (typeof model.setHidden === 'function') {
1991
2110
  model.setHidden(!!newProps.hiddenModel);
1992
2111
  } else {
1993
- model.hidden = !!newProps.hiddenModel;
2112
+ model.hidden = nextHidden;
2113
+ if (prevHidden !== nextHidden) {
2114
+ hiddenStatePatches.push({ model, hidden: nextHidden });
2115
+ }
1994
2116
  }
1995
2117
 
1996
2118
  if (newProps.required === true) {
@@ -2027,6 +2149,9 @@ const commonLinkageRulesHandler = async (ctx: FlowContext, params: any) => {
2027
2149
 
2028
2150
  model.__props = null;
2029
2151
  });
2152
+ hiddenStatePatches.forEach(({ model, hidden }) => {
2153
+ syncHiddenStateByTargetPath(model, hidden);
2154
+ });
2030
2155
 
2031
2156
  const allPatches = [...directValuePatches];
2032
2157
  if (!allPatches.length) return;
@@ -41,16 +41,15 @@ export const linkageRulesRefresh = defineAction({
41
41
  const flowSettingsEnabled = Boolean(
42
42
  (ctx as any)?.flowSettingsEnabled || (model as any)?.context?.flowSettingsEnabled,
43
43
  );
44
- const hasMountedForkWithFlow =
44
+ const hasForkWithFlow =
45
45
  !model?.isFork &&
46
46
  !!model?.forks?.size &&
47
47
  Array.from(model?.forks || []).some((fork: any) => {
48
48
  if (!fork || fork.disposed) return false;
49
- if (!fork?.context?.ref?.current) return false;
50
49
  return !!fork?.getFlow?.(flowKey);
51
50
  });
52
51
  const isMasterMounted = Boolean((model as any)?.context?.ref?.current);
53
- if (hasMountedForkWithFlow && !isMasterMounted && !flowSettingsEnabled) {
52
+ if (hasForkWithFlow && !isMasterMounted && !flowSettingsEnabled) {
54
53
  return;
55
54
  }
56
55
 
@@ -10,7 +10,7 @@
10
10
  import { defineAction, tExpr, FlowModelContext, FlowModel, FlowExitAllException } from '@nocobase/flow-engine';
11
11
  import React from 'react';
12
12
  import { FlowPage } from '../FlowPage';
13
- import { RootPageModel } from '../models';
13
+ import { PageModel, RootPageModel } from '../models';
14
14
  import _ from 'lodash';
15
15
 
16
16
  type DirtyAwareFlowModel = FlowModel & {
@@ -230,7 +230,7 @@ export const openView = defineAction({
230
230
  return {
231
231
  mode: 'drawer',
232
232
  size: 'medium',
233
- pageModelClass: 'ChildPageModel',
233
+ pageModelClass: ctx.layout?.childPageModelClass || 'ChildPageModel',
234
234
  uid: ctx.model?.uid,
235
235
  ...(filterByTkExpr ? { filterByTk: filterByTkExpr } : {}),
236
236
  ...(sourceIdExpr ? { sourceId: sourceIdExpr } : {}),
@@ -371,7 +371,8 @@ export const openView = defineAction({
371
371
  embed: {},
372
372
  };
373
373
 
374
- const pageModelClass = ctx.inputArgs.pageModelClass || params.pageModelClass || 'ChildPageModel';
374
+ const pageModelClass =
375
+ ctx.inputArgs.pageModelClass || params.pageModelClass || ctx.layout?.childPageModelClass || 'ChildPageModel';
375
376
  const size = ctx.inputArgs.size || params.size || 'medium';
376
377
  let pageModelUid: string | null = null;
377
378
  let pageModelRef: FlowModel | null = null;
@@ -414,7 +415,12 @@ export const openView = defineAction({
414
415
  associationName: runtimeAssociationName,
415
416
  tabUid: mergedTabUid,
416
417
  openerUids,
417
- pageActive: true, // 打开一个弹窗时,页面肯定是激活的
418
+ pageActive:
419
+ typeof inputArgs.pageActive === 'boolean'
420
+ ? inputArgs.pageActive
421
+ : typeof ctx.inputArgs.pageActive === 'boolean'
422
+ ? ctx.inputArgs.pageActive
423
+ : true,
418
424
  };
419
425
  // Ensure runtime keys propagate to view.inputArgs
420
426
  finalInputArgs.filterByTk = mergedFilterByTk;
@@ -477,6 +483,24 @@ export const openView = defineAction({
477
483
  });
478
484
  }
479
485
 
486
+ if (ctx.inputArgs.activateRef) {
487
+ ctx.inputArgs.activateRef.current = (forceRefresh = false) => {
488
+ currentView.inputArgs.pageActive = true;
489
+ if (pageModel instanceof PageModel) {
490
+ pageModel.activateCurrentTab(forceRefresh);
491
+ }
492
+ };
493
+ }
494
+
495
+ if (ctx.inputArgs.deactivateRef) {
496
+ ctx.inputArgs.deactivateRef.current = () => {
497
+ currentView.inputArgs.pageActive = false;
498
+ if (pageModel instanceof PageModel) {
499
+ pageModel.deactivateCurrentTab();
500
+ }
501
+ };
502
+ }
503
+
480
504
  Object.entries(defineProperties as Record<string, any>).forEach(([key, p]) => {
481
505
  pageModel.context.defineProperty(key, p);
482
506
  });
@@ -135,7 +135,7 @@ function SetTargetDataScope(props) {
135
135
  return (
136
136
  <FilterGroup
137
137
  value={props.value}
138
- FilterItem={(p) => <VariableFilterItem {...p} model={targetModel} rightAsVariable />}
138
+ FilterItem={(p) => <VariableFilterItem {...p} model={targetModel} rightAsVariable maxAssociationFieldDepth={2} />}
139
139
  />
140
140
  );
141
141
  }