@nocobase/client-v2 2.1.0-beta.9 → 2.1.0

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 (1371) hide show
  1. package/es/APIClient.d.ts +16 -0
  2. package/es/Application.d.ts +54 -0
  3. package/es/BaseApplication.d.ts +197 -0
  4. package/es/PinnedPluginListContext.d.ts +22 -0
  5. package/es/Plugin.d.ts +59 -0
  6. package/es/PluginManager.d.ts +48 -0
  7. package/es/PluginSettingsManager.d.ts +206 -0
  8. package/es/RouteRepository.d.ts +124 -0
  9. package/{lib → es}/RouterManager.d.ts +27 -13
  10. package/{lib → es}/WebSocketClient.d.ts +3 -3
  11. package/es/acl/ACLProvider.d.ts +81 -0
  12. package/es/acl/createAclSnippetAllow.d.ts +16 -0
  13. package/es/acl/index.d.ts +11 -0
  14. package/es/acl/useAclSnippets.d.ts +16 -0
  15. package/es/ai/ai-manager.d.ts +15 -0
  16. package/es/ai/index.d.ts +12 -0
  17. package/{lib/components → es/ai/skills-manager}/index.d.ts +1 -2
  18. package/es/ai/skills-manager/types.d.ts +23 -0
  19. package/es/ai/tools-manager/hooks/context.d.ts +17 -0
  20. package/es/ai/tools-manager/hooks/index.d.ts +11 -0
  21. package/es/ai/tools-manager/hooks/provider.d.ts +16 -0
  22. package/es/ai/tools-manager/index.d.ts +20 -0
  23. package/es/ai/tools-manager/types.d.ts +90 -0
  24. package/es/ai/utils.d.ts +10 -0
  25. package/es/authRedirect.d.ts +68 -0
  26. package/es/collection-field-interface/CollectionFieldInterface.d.ts +107 -0
  27. package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +188 -0
  28. package/es/collection-manager/field-configure.d.ts +80 -0
  29. package/es/collection-manager/field-validation.d.ts +43 -0
  30. package/es/collection-manager/filter-operators/index.d.ts +47 -0
  31. package/es/collection-manager/filter-operators/operators.d.ts +30 -0
  32. package/es/collection-manager/interfaces/checkbox.d.ts +47 -0
  33. package/es/collection-manager/interfaces/checkboxGroup.d.ts +106 -0
  34. package/es/collection-manager/interfaces/collection.d.ts +106 -0
  35. package/es/collection-manager/interfaces/color.d.ts +47 -0
  36. package/es/collection-manager/interfaces/createdAt.d.ts +53 -0
  37. package/es/collection-manager/interfaces/createdBy.d.ts +59 -0
  38. package/es/collection-manager/interfaces/dateOnly.d.ts +66 -0
  39. package/es/collection-manager/interfaces/datetime.d.ts +78 -0
  40. package/es/collection-manager/interfaces/datetimeNoTz.d.ts +78 -0
  41. package/es/collection-manager/interfaces/email.d.ts +59 -0
  42. package/es/collection-manager/interfaces/icon.d.ts +44 -0
  43. package/es/collection-manager/interfaces/id.d.ts +56 -0
  44. package/es/collection-manager/interfaces/index.d.ts +48 -0
  45. package/es/collection-manager/interfaces/input.d.ts +86 -0
  46. package/es/collection-manager/interfaces/integer.d.ts +92 -0
  47. package/es/collection-manager/interfaces/json.d.ts +71 -0
  48. package/es/collection-manager/interfaces/m2m.d.ts +260 -0
  49. package/es/collection-manager/interfaces/m2o.d.ts +207 -0
  50. package/es/collection-manager/interfaces/markdown.d.ts +46 -0
  51. package/es/collection-manager/interfaces/multipleSelect.d.ts +109 -0
  52. package/es/collection-manager/interfaces/nanoid.d.ts +98 -0
  53. package/es/collection-manager/interfaces/number.d.ts +101 -0
  54. package/es/collection-manager/interfaces/o2m.d.ts +231 -0
  55. package/es/collection-manager/interfaces/obo.d.ts +207 -0
  56. package/es/collection-manager/interfaces/oho.d.ts +207 -0
  57. package/es/collection-manager/interfaces/password.d.ts +57 -0
  58. package/es/collection-manager/interfaces/percent.d.ts +74 -0
  59. package/es/collection-manager/interfaces/phone.d.ts +61 -0
  60. package/es/collection-manager/interfaces/properties/index.d.ts +117 -0
  61. package/es/collection-manager/interfaces/radioGroup.d.ts +106 -0
  62. package/es/collection-manager/interfaces/richText.d.ts +48 -0
  63. package/es/collection-manager/interfaces/select.d.ts +107 -0
  64. package/es/collection-manager/interfaces/snowflake-id.d.ts +84 -0
  65. package/es/collection-manager/interfaces/tableoid.d.ts +50 -0
  66. package/es/collection-manager/interfaces/textarea.d.ts +57 -0
  67. package/es/collection-manager/interfaces/time.d.ts +49 -0
  68. package/es/collection-manager/interfaces/types.d.ts +29 -0
  69. package/es/collection-manager/interfaces/unixTimestamp.d.ts +81 -0
  70. package/es/collection-manager/interfaces/updatedAt.d.ts +53 -0
  71. package/es/collection-manager/interfaces/updatedBy.d.ts +59 -0
  72. package/es/collection-manager/interfaces/url.d.ts +53 -0
  73. package/es/collection-manager/interfaces/utils/index.d.ts +14 -0
  74. package/es/collection-manager/interfaces/uuid.d.ts +87 -0
  75. package/es/collection-manager/template-fields.d.ts +53 -0
  76. package/es/components/AppComponents.d.ts +27 -0
  77. package/es/components/Icon.d.ts +24 -0
  78. package/es/components/KeepAlive.d.ts +22 -0
  79. package/es/components/PoweredBy.d.ts +18 -0
  80. package/{lib → es}/components/RouterBridge.d.ts +9 -0
  81. package/es/components/SwitchLanguage.d.ts +11 -0
  82. package/es/components/form/DialogFormLayout.d.ts +51 -0
  83. package/es/components/form/DrawerFormLayout.d.ts +49 -0
  84. package/es/components/form/EnvVariableInput.d.ts +44 -0
  85. package/es/components/form/FileSizeInput.d.ts +27 -0
  86. package/es/components/form/JsonTextArea.d.ts +18 -0
  87. package/es/components/form/PasswordInput.d.ts +40 -0
  88. package/es/components/form/RemoteSelect.d.ts +79 -0
  89. package/es/components/form/ScanInput/CodeScanner.d.ts +18 -0
  90. package/es/components/form/ScanInput/ScanBox.d.ts +12 -0
  91. package/es/components/form/ScanInput/ScanInput.d.ts +18 -0
  92. package/es/components/form/ScanInput/index.d.ts +11 -0
  93. package/es/components/form/ScanInput/types.d.ts +10 -0
  94. package/es/components/form/ScanInput/useCodeScanner.d.ts +31 -0
  95. package/es/components/form/TypedVariableInput.d.ts +75 -0
  96. package/es/components/form/VariableInput.d.ts +124 -0
  97. package/es/components/form/createFormRegistry.d.ts +33 -0
  98. package/es/components/form/filter/CollectionFilter.d.ts +51 -0
  99. package/es/components/form/filter/CollectionFilterItem.d.ts +53 -0
  100. package/es/components/form/filter/CollectionFilterPanel.d.ts +38 -0
  101. package/es/components/form/filter/DateFilterDynamicComponent.d.ts +57 -0
  102. package/es/components/form/filter/FilterValueInput.d.ts +34 -0
  103. package/es/components/form/filter/index.d.ts +13 -0
  104. package/es/components/form/filter/useFilterActionProps.d.ts +99 -0
  105. package/es/components/form/index.d.ts +20 -0
  106. package/es/components/form/table/RowOverlayPreview.d.ts +27 -0
  107. package/es/components/form/table/SelectionCell.d.ts +36 -0
  108. package/es/components/form/table/Table.d.ts +82 -0
  109. package/es/components/form/table/constants.d.ts +15 -0
  110. package/es/components/form/table/dnd/SortableRow.d.ts +40 -0
  111. package/{lib/hooks → es/components/form/table/dnd}/index.d.ts +1 -3
  112. package/es/components/form/table/index.d.ts +9 -0
  113. package/es/components/form/table/styles.d.ts +51 -0
  114. package/es/components/form/table/utils.d.ts +44 -0
  115. package/es/components/index.d.ts +17 -0
  116. package/es/css-variable/CSSVariableProvider.d.ts +15 -0
  117. package/es/data-source/ExtendCollectionsProvider.d.ts +50 -0
  118. package/es/data-source/index.d.ts +9 -0
  119. package/es/flow/FlowModelRepository.d.ts +36 -0
  120. package/es/flow/FlowPage.d.ts +21 -0
  121. package/es/flow/actions/aclCheck.d.ts +9 -0
  122. package/es/flow/actions/aclCheckRefresh.d.ts +9 -0
  123. package/es/flow/actions/afterSuccess.d.ts +9 -0
  124. package/es/flow/actions/blockHeight.d.ts +9 -0
  125. package/es/flow/actions/columnFixed.d.ts +9 -0
  126. package/es/flow/actions/confirm.d.ts +9 -0
  127. package/es/flow/actions/customVariable.d.ts +9 -0
  128. package/es/flow/actions/dataLoadingMode.d.ts +9 -0
  129. package/es/flow/actions/dataScope.d.ts +9 -0
  130. package/es/flow/actions/dataScopeFilter.d.ts +9 -0
  131. package/es/flow/actions/dateRangeLimit.d.ts +9 -0
  132. package/es/flow/actions/dateTimeFormat.d.ts +9 -0
  133. package/es/flow/actions/displayFieldComponent.d.ts +19 -0
  134. package/es/flow/actions/fieldComponent.d.ts +9 -0
  135. package/es/flow/actions/filterFormDefaultValues.d.ts +9 -0
  136. package/es/flow/actions/formAssignRules.d.ts +9 -0
  137. package/es/flow/actions/index.d.ts +41 -0
  138. package/es/flow/actions/layout.d.ts +10 -0
  139. package/es/flow/actions/linkageRules.d.ts +25 -0
  140. package/es/flow/actions/linkageRulesFormValueRefresh.d.ts +10 -0
  141. package/es/flow/actions/linkageRulesRefresh.d.ts +9 -0
  142. package/es/flow/actions/navigateToURL.d.ts +9 -0
  143. package/es/flow/actions/numberFormat.d.ts +9 -0
  144. package/es/flow/actions/openView.d.ts +15 -0
  145. package/es/flow/actions/overflowMode.d.ts +9 -0
  146. package/es/flow/actions/pattern.d.ts +9 -0
  147. package/es/flow/actions/refreshTargetBlocks.d.ts +9 -0
  148. package/es/flow/actions/renderMode.d.ts +9 -0
  149. package/es/flow/actions/required.d.ts +9 -0
  150. package/es/flow/actions/runjs.d.ts +9 -0
  151. package/es/flow/actions/setTargetDataScope.d.ts +10 -0
  152. package/es/flow/actions/showMessage.d.ts +9 -0
  153. package/es/flow/actions/showNotification.d.ts +9 -0
  154. package/es/flow/actions/sortingRules.d.ts +9 -0
  155. package/es/flow/actions/titleField.d.ts +9 -0
  156. package/es/flow/actions/validation.d.ts +9 -0
  157. package/es/flow/admin-shell/AdminLayoutRouteCoordinator.d.ts +19 -0
  158. package/es/flow/admin-shell/BaseLayoutModel.d.ts +89 -0
  159. package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +74 -0
  160. package/es/flow/admin-shell/admin-layout/AdminLayoutCompat.d.ts +112 -0
  161. package/es/flow/admin-shell/admin-layout/AdminLayoutComponent.d.ts +10 -0
  162. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +12 -0
  163. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +108 -0
  164. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +65 -0
  165. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +167 -0
  166. package/es/flow/admin-shell/admin-layout/AdminLayoutModel.d.ts +72 -0
  167. package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +31 -0
  168. package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +11 -0
  169. package/es/flow/admin-shell/admin-layout/HelpLite.d.ts +13 -0
  170. package/es/flow/admin-shell/admin-layout/PinnedPluginListLite.d.ts +15 -0
  171. package/es/flow/admin-shell/admin-layout/ResetThemeTokenAndKeepAlgorithm.d.ts +13 -0
  172. package/es/flow/admin-shell/admin-layout/TopbarActionsBar.d.ts +25 -0
  173. package/es/flow/admin-shell/admin-layout/constants.d.ts +9 -0
  174. package/es/flow/admin-shell/admin-layout/flowSettingsPreference.d.ts +23 -0
  175. package/es/flow/admin-shell/admin-layout/index.d.ts +22 -0
  176. package/es/flow/admin-shell/admin-layout/mobile-layout.d.ts +12 -0
  177. package/es/flow/admin-shell/admin-layout/mobileMenuNavigation.d.ts +15 -0
  178. package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +47 -0
  179. package/es/flow/admin-shell/admin-layout/useApplications.d.ts +13 -0
  180. package/es/flow/admin-shell/useAdminLayoutRoutePage.d.ts +28 -0
  181. package/es/flow/admin-shell/useLayoutRoutePage.d.ts +23 -0
  182. package/es/flow/common/Liquid.d.ts +33 -0
  183. package/es/flow/common/Markdown/Display.d.ts +9 -0
  184. package/es/flow/common/Markdown/Edit.d.ts +23 -0
  185. package/es/flow/common/Markdown/Markdown.d.ts +24 -0
  186. package/es/flow/common/Markdown/style.d.ts +14 -0
  187. package/es/flow/common/Markdown/useCDN.d.ts +9 -0
  188. package/es/flow/components/AdminLayout.d.ts +11 -0
  189. package/es/flow/components/BlockItemCard.d.ts +16 -0
  190. package/es/flow/components/ConditionBuilder.d.ts +18 -0
  191. package/es/flow/components/DefaultValue.d.ts +20 -0
  192. package/es/flow/components/DynamicFlowsIcon.d.ts +13 -0
  193. package/es/flow/components/EllipsisWithTooltip.d.ts +17 -0
  194. package/es/flow/components/ExpiresRadio/index.d.ts +12 -0
  195. package/es/flow/components/FieldAssignEditor.d.ts +32 -0
  196. package/es/flow/components/FieldAssignExactDatePicker.d.ts +23 -0
  197. package/es/flow/components/FieldAssignRulesEditor.d.ts +73 -0
  198. package/es/flow/components/FieldAssignValueInput.d.ts +89 -0
  199. package/es/flow/components/FlowRoute.d.ts +37 -0
  200. package/es/flow/components/Grid/index.d.ts +28 -0
  201. package/es/flow/components/JsonEditor.d.ts +19 -0
  202. package/es/flow/components/RunJSValueEditor.d.ts +19 -0
  203. package/{lib/hooks/useApp.d.ts → es/flow/components/SkeletonFallback.d.ts} +2 -2
  204. package/es/flow/components/TextAreaWithContextSelector.d.ts +45 -0
  205. package/es/flow/components/code-editor/core/EditorCore.d.ts +25 -0
  206. package/es/flow/components/code-editor/core/tooltipParent.d.ts +9 -0
  207. package/es/flow/components/code-editor/errorHelpers.d.ts +17 -0
  208. package/es/flow/components/code-editor/extension/CodeEditorExtension.d.ts +14 -0
  209. package/es/flow/components/code-editor/extension/index.d.ts +9 -0
  210. package/es/flow/components/code-editor/formatDocInfo.d.ts +17 -0
  211. package/es/flow/components/code-editor/hooks/useCodeRunner.d.ts +23 -0
  212. package/es/flow/components/code-editor/hooks/useRunJSDocCompletions.d.ts +15 -0
  213. package/es/flow/components/code-editor/htmlCompletion.d.ts +11 -0
  214. package/es/flow/components/code-editor/index.d.ts +32 -0
  215. package/es/flow/components/code-editor/javascriptCompletion.d.ts +11 -0
  216. package/es/flow/components/code-editor/javascriptHtmlTemplate.d.ts +16 -0
  217. package/es/flow/components/code-editor/jsxCompletion.d.ts +10 -0
  218. package/es/flow/components/code-editor/linter.d.ts +19 -0
  219. package/es/flow/components/code-editor/panels/LogsPanel.d.ts +15 -0
  220. package/es/flow/components/code-editor/panels/RightExtra.d.ts +18 -0
  221. package/es/flow/components/code-editor/panels/SnippetsDrawer.d.ts +18 -0
  222. package/es/flow/components/code-editor/resolveScenes.d.ts +10 -0
  223. package/es/flow/components/code-editor/runjsCompletionSource.d.ts +20 -0
  224. package/es/flow/components/code-editor/runjsCompletions.d.ts +23 -0
  225. package/es/flow/components/code-editor/runjsDiagnostics.d.ts +46 -0
  226. package/es/flow/components/code-editor/types.d.ts +33 -0
  227. package/es/flow/components/drag-drop/Sortable.d.ts +12 -0
  228. package/es/flow/components/drag-drop/SortableItem.d.ts +12 -0
  229. package/es/flow/components/drag-drop/index.d.ts +10 -0
  230. package/es/flow/components/fieldAssignOptions.d.ts +33 -0
  231. package/es/flow/components/filter/FilterContainer.d.ts +67 -0
  232. package/es/flow/components/filter/FilterGroup.d.ts +66 -0
  233. package/es/flow/components/filter/FilterItem.d.ts +40 -0
  234. package/es/flow/components/filter/LinkageFilterItem.d.ts +52 -0
  235. package/es/flow/components/filter/VariableFilterItem.d.ts +38 -0
  236. package/es/flow/components/filter/fieldsToOptions.d.ts +9 -0
  237. package/es/flow/components/filter/index.d.ts +18 -0
  238. package/es/flow/components/filter/metaTreeAssociationDepth.d.ts +13 -0
  239. package/es/flow/components/filter/useFilterOptions.d.ts +66 -0
  240. package/es/flow/components/index.d.ts +14 -0
  241. package/es/flow/components/placeholders/BlockPlaceholder.d.ts +11 -0
  242. package/es/flow/components/placeholders/FieldPlaceholder.d.ts +10 -0
  243. package/es/flow/components/useAssociationTitleFieldSync.d.ts +13 -0
  244. package/es/flow/flows/editMarkdownFlow.d.ts +10 -0
  245. package/es/flow/flows/openViewFlow.d.ts +17 -0
  246. package/es/flow/formily/ReactiveField.d.ts +19 -0
  247. package/es/flow/formily/index.d.ts +8 -0
  248. package/es/flow/getViewDiffAndUpdateHidden.d.ts +21 -0
  249. package/es/flow/index.d.ts +35 -0
  250. package/es/flow/internal/components/Markdown/DisplayMarkdown.d.ts +10 -0
  251. package/es/flow/internal/components/Markdown/markdown-it-plugins/mermaidPlugin.d.ts +13 -0
  252. package/es/flow/internal/components/Markdown/md.d.ts +11 -0
  253. package/es/flow/internal/components/Markdown/style.d.ts +9 -0
  254. package/es/flow/internal/components/Markdown/util.d.ts +15 -0
  255. package/es/flow/internal/constants/HeightMode.d.ts +13 -0
  256. package/es/flow/internal/index.d.ts +11 -0
  257. package/es/flow/internal/utils/associationValueCoercion.d.ts +15 -0
  258. package/es/flow/internal/utils/dateTimeUtils.d.ts +10 -0
  259. package/es/flow/internal/utils/enumOptionsUtils.d.ts +30 -0
  260. package/es/flow/internal/utils/modelUtils.d.ts +27 -0
  261. package/es/flow/internal/utils/operatorSchemaHelper.d.ts +38 -0
  262. package/es/flow/internal/utils/rebuildFieldSubModel.d.ts +34 -0
  263. package/es/flow/internal/utils/saveStepParamsWithSubModels.d.ts +11 -0
  264. package/es/flow/internal/utils/titleFieldQuickSync.d.ts +36 -0
  265. package/es/flow/models/actions/AddChildActionModel.d.ts +16 -0
  266. package/es/flow/models/actions/AddNewActionModel.d.ts +16 -0
  267. package/es/flow/models/actions/AssociateActionModel.d.ts +19 -0
  268. package/es/flow/models/actions/AssociationActionUtils.d.ts +22 -0
  269. package/es/flow/models/actions/BulkDeleteActionModel.d.ts +16 -0
  270. package/es/flow/models/actions/DeleteActionModel.d.ts +15 -0
  271. package/es/flow/models/actions/DisassociateActionModel.d.ts +16 -0
  272. package/es/flow/models/actions/EditActionModel.d.ts +16 -0
  273. package/es/flow/models/actions/ExpandCollapseActionModel.d.ts +19 -0
  274. package/es/flow/models/actions/FilterActionModel.d.ts +26 -0
  275. package/es/flow/models/actions/JSActionModel.d.ts +13 -0
  276. package/es/flow/models/actions/JSCollectionActionModel.d.ts +14 -0
  277. package/es/flow/models/actions/JSItemActionModel.d.ts +19 -0
  278. package/es/flow/models/actions/JSRecordActionModel.d.ts +14 -0
  279. package/es/flow/models/actions/LinkActionModel.d.ts +15 -0
  280. package/es/flow/models/actions/LinkActionUtils.d.ts +34 -0
  281. package/es/flow/models/actions/PopupCollectionActionModel.d.ts +14 -0
  282. package/es/flow/models/actions/RefreshActionModel.d.ts +14 -0
  283. package/es/flow/models/actions/UpdateRecordActionModel.d.ts +27 -0
  284. package/es/flow/models/actions/UpdateRecordActionUtils.d.ts +12 -0
  285. package/es/flow/models/actions/ViewActionModel.d.ts +15 -0
  286. package/es/flow/models/actions/index.d.ts +27 -0
  287. package/es/flow/models/actions/joinUrlSearch.d.ts +12 -0
  288. package/es/flow/models/base/ActionGroupModel.d.ts +9 -0
  289. package/es/flow/models/base/ActionGroupModelCore.d.ts +29 -0
  290. package/es/flow/models/base/ActionModel.d.ts +9 -0
  291. package/es/flow/models/base/ActionModelCore.d.ts +51 -0
  292. package/es/flow/models/base/AssociationFieldGroupModel.d.ts +18 -0
  293. package/es/flow/models/base/BlockGridModel.d.ts +22 -0
  294. package/es/flow/models/base/BlockModel.d.ts +57 -0
  295. package/es/flow/models/base/CollectionActionModel.d.ts +12 -0
  296. package/es/flow/models/base/CollectionBlockModel.d.ts +71 -0
  297. package/es/flow/models/base/CommonItemModel.d.ts +11 -0
  298. package/es/flow/models/base/DataBlockModel.d.ts +12 -0
  299. package/es/flow/models/base/FieldModel.d.ts +17 -0
  300. package/es/flow/models/base/FilterBlockModel.d.ts +12 -0
  301. package/es/flow/models/base/GridModel.d.ts +120 -0
  302. package/es/flow/models/base/PageModel/ChildPageModel.d.ts +21 -0
  303. package/es/flow/models/base/PageModel/MainPageModel.d.ts +17 -0
  304. package/es/flow/models/base/PageModel/OldPageModel.d.ts +21 -0
  305. package/es/flow/models/base/PageModel/PageModel.d.ts +59 -0
  306. package/es/flow/models/base/PageModel/PageTabModel.d.ts +42 -0
  307. package/es/flow/models/base/PageModel/RootPageModel.d.ts +33 -0
  308. package/es/flow/models/base/PageModel/SubPageModel.d.ts +17 -0
  309. package/es/flow/models/base/PageModel/closeGuard.d.ts +31 -0
  310. package/{lib → es/flow/models/base/PageModel}/index.d.ts +6 -6
  311. package/es/flow/models/base/PopupActionModel.d.ts +13 -0
  312. package/es/flow/models/base/RecordActionModel.d.ts +12 -0
  313. package/es/flow/models/base/RouteModel.d.ts +11 -0
  314. package/es/flow/models/base/index.d.ts +24 -0
  315. package/es/flow/models/blocks/assign-form/AssignFormGridModel.d.ts +15 -0
  316. package/es/flow/models/blocks/assign-form/AssignFormItemModel.d.ts +22 -0
  317. package/es/flow/models/blocks/assign-form/AssignFormModel.d.ts +26 -0
  318. package/es/flow/models/blocks/assign-form/assignFieldValuesFlow.d.ts +92 -0
  319. package/es/flow/models/blocks/assign-form/index.d.ts +12 -0
  320. package/es/flow/models/blocks/details/DetailsAssociationFieldGroupModel.d.ts +12 -0
  321. package/es/flow/models/blocks/details/DetailsBlockModel.d.ts +41 -0
  322. package/es/flow/models/blocks/details/DetailsCustomItemModel.d.ts +13 -0
  323. package/es/flow/models/blocks/details/DetailsGridModel.d.ts +33 -0
  324. package/es/flow/models/blocks/details/DetailsItemModel.d.ts +60 -0
  325. package/es/flow/models/blocks/details/DetailsJSFieldItemModel.d.ts +19 -0
  326. package/es/flow/models/blocks/details/index.d.ts +14 -0
  327. package/es/flow/models/blocks/details/utils.d.ts +16 -0
  328. package/es/flow/models/blocks/filter-form/FieldModelSelect.d.ts +10 -0
  329. package/es/flow/models/blocks/filter-form/FieldOperatorSelect.d.ts +10 -0
  330. package/es/flow/models/blocks/filter-form/FilterFormActionGroupModel.d.ts +13 -0
  331. package/es/flow/models/blocks/filter-form/FilterFormActionModel.d.ts +11 -0
  332. package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +51 -0
  333. package/es/flow/models/blocks/filter-form/FilterFormCollapseActionModel.d.ts +18 -0
  334. package/es/flow/models/blocks/filter-form/FilterFormCustomItemModel.d.ts +13 -0
  335. package/es/flow/models/blocks/filter-form/FilterFormGridModel.d.ts +53 -0
  336. package/es/flow/models/blocks/filter-form/FilterFormItemModel.d.ts +59 -0
  337. package/es/flow/models/blocks/filter-form/FilterFormJSActionModel.d.ts +11 -0
  338. package/es/flow/models/blocks/filter-form/FilterFormResetActionModel.d.ts +13 -0
  339. package/es/flow/models/blocks/filter-form/FilterFormSubmitActionModel.d.ts +15 -0
  340. package/es/flow/models/blocks/filter-form/SourceCascader.d.ts +10 -0
  341. package/es/flow/models/blocks/filter-form/customFieldOperators.d.ts +34 -0
  342. package/es/flow/models/blocks/filter-form/fields/FieldComponentProps.d.ts +13 -0
  343. package/es/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.d.ts +52 -0
  344. package/es/flow/models/blocks/filter-form/fields/FilterFormCustomRecordSelectFieldModel.d.ts +20 -0
  345. package/es/flow/models/blocks/filter-form/fields/FilterFormFieldModel.d.ts +11 -0
  346. package/es/flow/models/blocks/filter-form/fields/FilterFormRecordSelectFieldModel.d.ts +12 -0
  347. package/es/flow/models/blocks/filter-form/fields/date-time/DateOnlyFilterFieldModel.d.ts +14 -0
  348. package/es/flow/models/blocks/filter-form/fields/date-time/DateTimeFilterFieldModel.d.ts +13 -0
  349. package/es/flow/models/blocks/filter-form/fields/date-time/DateTimeNoTzFilterFieldModel.d.ts +13 -0
  350. package/es/flow/models/blocks/filter-form/fields/date-time/DateTimeTzFilterFieldModel.d.ts +14 -0
  351. package/es/flow/models/blocks/filter-form/fields/date-time/components/DateFilterDynamicComponent.d.ts +10 -0
  352. package/es/flow/models/blocks/filter-form/fields/date-time/components/FilterDatePicker.d.ts +10 -0
  353. package/es/flow/models/blocks/filter-form/fields/date-time/components/FilterRangePicker.d.ts +10 -0
  354. package/es/flow/models/blocks/filter-form/fields/date-time/index.d.ts +12 -0
  355. package/es/flow/models/blocks/filter-form/fields/index.d.ts +13 -0
  356. package/es/flow/models/blocks/filter-form/index.d.ts +23 -0
  357. package/es/flow/models/blocks/filter-form/legacyDefaultValueMigration.d.ts +13 -0
  358. package/es/flow/models/blocks/filter-form/valueNormalization.d.ts +17 -0
  359. package/es/flow/models/blocks/filter-manager/FilterManager.d.ts +145 -0
  360. package/es/flow/models/blocks/filter-manager/flow-actions/connectFields.d.ts +10 -0
  361. package/es/flow/models/blocks/filter-manager/flow-actions/customizeFilterRender.d.ts +10 -0
  362. package/es/flow/models/blocks/filter-manager/flow-actions/defaultOperator.d.ts +9 -0
  363. package/es/flow/models/blocks/filter-manager/flow-actions/index.d.ts +12 -0
  364. package/es/flow/models/blocks/filter-manager/flow-actions/operatorComponentProps.d.ts +10 -0
  365. package/es/flow/models/blocks/filter-manager/index.d.ts +11 -0
  366. package/es/flow/models/blocks/filter-manager/utils.d.ts +43 -0
  367. package/es/flow/models/blocks/form/CreateFormModel.d.ts +22 -0
  368. package/es/flow/models/blocks/form/EditFormModel.d.ts +26 -0
  369. package/es/flow/models/blocks/form/FormActionGroupModel.d.ts +14 -0
  370. package/es/flow/models/blocks/form/FormActionModel.d.ts +28 -0
  371. package/es/flow/models/blocks/form/FormAssociationFieldGroupModel.d.ts +12 -0
  372. package/es/flow/models/blocks/form/FormAssociationItemModel.d.ts +39 -0
  373. package/es/flow/models/blocks/form/FormBlockModel.d.ts +96 -0
  374. package/es/flow/models/blocks/form/FormCustomItemModel.d.ts +13 -0
  375. package/es/flow/models/blocks/form/FormGridModel.d.ts +35 -0
  376. package/es/flow/models/blocks/form/FormItemModel.d.ts +39 -0
  377. package/es/flow/models/blocks/form/FormJSFieldItemModel.d.ts +18 -0
  378. package/es/flow/models/blocks/form/JSFormActionModel.d.ts +11 -0
  379. package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +44 -0
  380. package/es/flow/models/blocks/form/assignRulesUpdateAssociationValues.d.ts +18 -0
  381. package/es/flow/models/blocks/form/dynamicNamePath.d.ts +19 -0
  382. package/es/flow/models/blocks/form/index.d.ts +21 -0
  383. package/es/flow/models/blocks/form/legacyDefaultValueMigration.d.ts +13 -0
  384. package/es/flow/models/blocks/form/submitHandler.d.ts +9 -0
  385. package/es/flow/models/blocks/form/submitValues.d.ts +40 -0
  386. package/es/flow/models/blocks/form/value-runtime/conditions.d.ts +9 -0
  387. package/es/flow/models/blocks/form/value-runtime/deps.d.ts +23 -0
  388. package/es/flow/models/blocks/form/value-runtime/form-patch.d.ts +19 -0
  389. package/es/flow/models/blocks/form/value-runtime/index.d.ts +11 -0
  390. package/es/flow/models/blocks/form/value-runtime/path.d.ts +25 -0
  391. package/es/flow/models/blocks/form/value-runtime/rules.d.ts +137 -0
  392. package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +95 -0
  393. package/es/flow/models/blocks/form/value-runtime/types.d.ts +62 -0
  394. package/es/flow/models/blocks/form/value-runtime/utils.d.ts +12 -0
  395. package/es/flow/models/blocks/index.d.ts +15 -0
  396. package/es/flow/models/blocks/js-block/JSBlock.d.ts +16 -0
  397. package/es/flow/models/blocks/js-block/index.d.ts +9 -0
  398. package/es/flow/models/blocks/shared/filterOperators.d.ts +9 -0
  399. package/es/flow/models/blocks/shared/legacyDefaultValueMigrationBase.d.ts +21 -0
  400. package/es/flow/models/blocks/table/JSColumnModel.d.ts +21 -0
  401. package/es/flow/models/blocks/table/TableActionsColumnModel.d.ts +18 -0
  402. package/es/flow/models/blocks/table/TableAssociationFieldGroupModel.d.ts +12 -0
  403. package/es/flow/models/blocks/table/TableBlockModel.d.ts +79 -0
  404. package/es/flow/models/blocks/table/TableColumnModel.d.ts +31 -0
  405. package/es/flow/models/blocks/table/TableCustomColumnModel.d.ts +12 -0
  406. package/es/flow/models/blocks/table/TableJSFieldItemModel.d.ts +19 -0
  407. package/es/flow/models/blocks/table/TableSelectModel.d.ts +22 -0
  408. package/es/flow/models/blocks/table/dragSort/dragSortComponents.d.ts +9 -0
  409. package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +17 -0
  410. package/es/flow/models/blocks/table/dragSort/dragSortSettings.d.ts +39 -0
  411. package/es/flow/models/blocks/table/dragSort/dragSortUtils.d.ts +37 -0
  412. package/es/flow/models/blocks/table/dragSort/index.d.ts +12 -0
  413. package/es/flow/models/blocks/table/index.d.ts +16 -0
  414. package/es/flow/models/blocks/table/sortUtils.d.ts +32 -0
  415. package/es/flow/models/blocks/table/utils.d.ts +18 -0
  416. package/es/flow/models/blocks/utils/transformChildrenToJS.d.ts +42 -0
  417. package/es/flow/models/fields/AssociationFieldModel/AssociationFieldModel.d.ts +5 -0
  418. package/es/flow/models/fields/AssociationFieldModel/CascadeSelectFieldModel.d.ts +45 -0
  419. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableActionGroupModel.d.ts +11 -0
  420. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableActionsColumnModel.d.ts +19 -0
  421. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.d.ts +30 -0
  422. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableEditActionModel.d.ts +29 -0
  423. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableFormSubmitActionModel.d.ts +18 -0
  424. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableRemoveActionModel.d.ts +14 -0
  425. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/popupSubTableBeforeClose.d.ts +25 -0
  426. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/blocks/PopupSubTableFormModel.d.ts +36 -0
  427. package/es/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/index.d.ts +17 -0
  428. package/es/flow/models/fields/AssociationFieldModel/RecordPickerFieldModel.d.ts +59 -0
  429. package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +46 -0
  430. package/es/flow/models/fields/AssociationFieldModel/SubFormFieldModel.d.ts +32 -0
  431. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +42 -0
  432. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.d.ts +10 -0
  433. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.d.ts +19 -0
  434. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/rowIdentity.d.ts +18 -0
  435. package/es/flow/models/fields/AssociationFieldModel/index.d.ts +15 -0
  436. package/es/flow/models/fields/AssociationFieldModel/itemChain.d.ts +99 -0
  437. package/es/flow/models/fields/AssociationFieldModel/recordSelectSettingsUtils.d.ts +9 -0
  438. package/es/flow/models/fields/AssociationFieldModel/recordSelectShared.d.ts +48 -0
  439. package/es/flow/models/fields/CheckboxFieldModel.d.ts +13 -0
  440. package/es/flow/models/fields/CheckboxGroupFieldModel.d.ts +13 -0
  441. package/es/flow/models/fields/ClickableFieldModel.d.ts +28 -0
  442. package/es/flow/models/fields/CollectionSelectorFieldModel.d.ts +13 -0
  443. package/es/flow/models/fields/ColorFieldModel.d.ts +14 -0
  444. package/es/flow/models/fields/DateTimeFieldModel/DateOnlyFieldModel.d.ts +7 -0
  445. package/es/flow/models/fields/DateTimeFieldModel/DateTimeFieldModel.d.ts +3 -0
  446. package/es/flow/models/fields/DateTimeFieldModel/DateTimeNoTzFieldModel.d.ts +6 -0
  447. package/es/flow/models/fields/DateTimeFieldModel/DateTimeTzFieldModel.d.ts +7 -0
  448. package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +20 -0
  449. package/es/flow/models/fields/DateTimeFieldModel/index.d.ts +11 -0
  450. package/es/flow/models/fields/DisplayAssociationField/DisplaySubItemFieldModel.d.ts +26 -0
  451. package/es/flow/models/fields/DisplayAssociationField/DisplaySubListFieldModel.d.ts +26 -0
  452. package/es/flow/models/fields/DisplayAssociationField/DisplaySubTableFieldModel.d.ts +20 -0
  453. package/es/flow/models/fields/DisplayAssociationField/displaySubListUtils.d.ts +14 -0
  454. package/es/flow/models/fields/DisplayAssociationField/index.d.ts +11 -0
  455. package/es/flow/models/fields/DisplayCheckboxFieldModel.d.ts +13 -0
  456. package/es/flow/models/fields/DisplayColorFieldModel.d.ts +13 -0
  457. package/es/flow/models/fields/DisplayDateTimeFieldModel.d.ts +13 -0
  458. package/es/flow/models/fields/DisplayEnumFieldModel.d.ts +20 -0
  459. package/es/flow/models/fields/DisplayHtmlFieldModel.d.ts +13 -0
  460. package/es/flow/models/fields/DisplayIconFieldModel.d.ts +13 -0
  461. package/es/flow/models/fields/DisplayJSONFieldModel.d.ts +14 -0
  462. package/es/flow/models/fields/DisplayNumberFieldModel.d.ts +33 -0
  463. package/es/flow/models/fields/DisplayPasswordFieldModel.d.ts +13 -0
  464. package/es/flow/models/fields/DisplayPercentFieldModel.d.ts +13 -0
  465. package/es/flow/models/fields/DisplayTextFieldModel.d.ts +14 -0
  466. package/es/flow/models/fields/DisplayTimeFieldModel.d.ts +13 -0
  467. package/es/flow/models/fields/DisplayTitleFieldModel.d.ts +18 -0
  468. package/es/flow/models/fields/DisplayURLFieldModel.d.ts +13 -0
  469. package/es/flow/models/fields/DividerItemModel.d.ts +13 -0
  470. package/es/flow/models/fields/IconFieldModel.d.ts +13 -0
  471. package/es/flow/models/fields/InputFieldModel.d.ts +13 -0
  472. package/es/flow/models/fields/JSEditableFieldModel.d.ts +31 -0
  473. package/es/flow/models/fields/JSFieldModel.d.ts +50 -0
  474. package/es/flow/models/fields/JSItemModel.d.ts +27 -0
  475. package/es/flow/models/fields/JsonFieldModel.d.ts +6 -0
  476. package/es/flow/models/fields/MarkdownItemModel.d.ts +14 -0
  477. package/es/flow/models/fields/NumberFieldModel.d.ts +15 -0
  478. package/es/flow/models/fields/PasswordFieldModel.d.ts +13 -0
  479. package/es/flow/models/fields/PercentFieldModel.d.ts +14 -0
  480. package/es/flow/models/fields/RadioGroupFieldModel.d.ts +13 -0
  481. package/es/flow/models/fields/RichTextFieldModel/index.d.ts +14 -0
  482. package/es/flow/models/fields/RichTextFieldModel/registerFontSize.d.ts +9 -0
  483. package/es/flow/models/fields/RichTextFieldModel/registerImageResize.d.ts +9 -0
  484. package/es/flow/models/fields/RichTextFieldModel/registerSmartBreak.d.ts +12 -0
  485. package/es/flow/models/fields/RichTextFieldModel/style.d.ts +9 -0
  486. package/es/flow/models/fields/SelectFieldModel.d.ts +13 -0
  487. package/es/flow/models/fields/TextareaFieldModel.d.ts +13 -0
  488. package/es/flow/models/fields/TimeFieldModel.d.ts +5 -0
  489. package/es/flow/models/fields/VariableFieldFormModel.d.ts +18 -0
  490. package/es/flow/models/fields/index.d.ts +47 -0
  491. package/es/flow/models/fields/mobile-components/MobileDatePicker.d.ts +10 -0
  492. package/es/flow/models/fields/mobile-components/MobileLazySelect.d.ts +11 -0
  493. package/es/flow/models/fields/mobile-components/MobileSelect.d.ts +10 -0
  494. package/es/flow/models/fields/mobile-components/MobileTimePicker.d.ts +10 -0
  495. package/es/flow/models/index.d.ts +13 -0
  496. package/es/flow/models/topbar/TopbarActionModel.d.ts +114 -0
  497. package/es/flow/models/topbar/UserCenterTopbarActionModel.d.ts +68 -0
  498. package/es/flow/models/topbar/index.d.ts +10 -0
  499. package/es/flow/models/utils/displayValueUtils.d.ts +12 -0
  500. package/es/flow/models/utils/resolveRunJsParams.d.ts +19 -0
  501. package/es/flow/resolveViewParamsToViewList.d.ts +20 -0
  502. package/es/flow/system-settings/SystemSettingsSource.d.ts +97 -0
  503. package/es/flow/system-settings/index.d.ts +10 -0
  504. package/es/flow/system-settings/useSystemSettings.d.ts +30 -0
  505. package/es/flow/utils/actionCapability.d.ts +60 -0
  506. package/es/flow/utils/blockUtils.d.ts +16 -0
  507. package/es/flow/utils/dataScopeFormValueClear.d.ts +14 -0
  508. package/es/flow/utils/dispatchEventDeep.d.ts +20 -0
  509. package/es/flow/utils/index.d.ts +11 -0
  510. package/es/flow/utils/pagination.d.ts +29 -0
  511. package/es/flow/utils/useJsonTemplateResolver.d.ts +9 -0
  512. package/es/flow-compat/ColorPicker.d.ts +15 -0
  513. package/es/flow-compat/FieldValidation.d.ts +31 -0
  514. package/es/flow-compat/HighPerformanceSpin.d.ts +11 -0
  515. package/es/flow-compat/Icon.d.ts +10 -0
  516. package/es/flow-compat/IconPicker.d.ts +19 -0
  517. package/es/flow-compat/Password.d.ts +16 -0
  518. package/es/flow-compat/PasswordStrength.d.ts +16 -0
  519. package/es/flow-compat/Popover.d.ts +12 -0
  520. package/es/flow-compat/data.d.ts +22 -0
  521. package/es/flow-compat/date.d.ts +114 -0
  522. package/es/flow-compat/fieldValidationConstants.d.ts +383 -0
  523. package/es/flow-compat/index.d.ts +27 -0
  524. package/es/flow-compat/lazy.d.ts +17 -0
  525. package/es/flow-compat/operators.d.ts +582 -0
  526. package/es/flow-compat/passwordUtils.d.ts +9 -0
  527. package/es/flow-compat/routeTypes.d.ts +56 -0
  528. package/es/flow-compat/useFullscreenOverlay.d.ts +20 -0
  529. package/es/flow-compat/zIndexContext.d.ts +12 -0
  530. package/es/hooks/index.d.ts +13 -0
  531. package/es/hooks/useApp.d.ts +12 -0
  532. package/es/hooks/useCurrentAppInfo.d.ts +9 -0
  533. package/{lib → es}/hooks/usePlugin.d.ts +2 -2
  534. package/{lib → es}/hooks/useRouter.d.ts +1 -1
  535. package/es/i18n.d.ts +22 -0
  536. package/es/index.d.ts +41 -0
  537. package/es/index.mjs +1254 -0
  538. package/es/index.mjs.LICENSE.txt +1 -0
  539. package/es/json-logic/globalOperators.d.ts +11 -0
  540. package/es/layout-manager/LayoutContentRoute.d.ts +14 -0
  541. package/es/layout-manager/LayoutManager.d.ts +22 -0
  542. package/es/layout-manager/LayoutRoute.d.ts +14 -0
  543. package/es/layout-manager/index.d.ts +13 -0
  544. package/es/layout-manager/types.d.ts +20 -0
  545. package/es/layout-manager/utils.d.ts +14 -0
  546. package/es/locale/languageCodes.d.ts +13 -0
  547. package/es/nocobase-buildin-plugin/index.d.ts +42 -0
  548. package/es/nocobase-buildin-plugin/plugins/LocalePlugin.d.ts +15 -0
  549. package/es/nocobase-buildin-plugin/plugins/dayjsLocale.d.ts +76 -0
  550. package/es/nocobase-buildin-plugin/plugins/loadConstrueLocale.d.ts +9 -0
  551. package/es/settings-center/AdminSettingsLayout.d.ts +24 -0
  552. package/es/settings-center/AdminSettingsLayoutModel.d.ts +28 -0
  553. package/es/settings-center/SystemSettingsPage.d.ts +17 -0
  554. package/es/settings-center/index.d.ts +13 -0
  555. package/es/settings-center/plugin-manager/BulkEnableButton.d.ts +15 -0
  556. package/es/settings-center/plugin-manager/PluginCard.d.ts +15 -0
  557. package/es/settings-center/plugin-manager/PluginDetail.d.ts +16 -0
  558. package/es/settings-center/plugin-manager/index.d.ts +11 -0
  559. package/es/settings-center/plugin-manager/types.d.ts +34 -0
  560. package/es/settings-center/utils.d.ts +94 -0
  561. package/es/theme/AntdAppProvider.d.ts +18 -0
  562. package/es/theme/compatOldTheme.d.ts +11 -0
  563. package/es/theme/customAlgorithm.d.ts +12 -0
  564. package/es/theme/defaultTheme.d.ts +11 -0
  565. package/es/theme/globalStyles.d.ts +9 -0
  566. package/es/theme/index.d.ts +36 -0
  567. package/es/theme/type.d.ts +41 -0
  568. package/es/utils/appVersionHTML.d.ts +10 -0
  569. package/es/utils/globalDeps.d.ts +20 -0
  570. package/{lib → es}/utils/index.d.ts +2 -1
  571. package/{lib → es}/utils/remotePlugins.d.ts +9 -10
  572. package/lib/index.js +1254 -40
  573. package/lib/index.js.LICENSE.txt +1 -0
  574. package/lib/locale/languageCodes.js +96 -0
  575. package/package.json +39 -5
  576. package/src/APIClient.ts +68 -0
  577. package/src/Application.tsx +117 -421
  578. package/src/BaseApplication.tsx +698 -0
  579. package/src/PinnedPluginListContext.tsx +33 -0
  580. package/src/Plugin.ts +24 -8
  581. package/src/PluginManager.ts +34 -19
  582. package/src/PluginSettingsManager.ts +505 -98
  583. package/src/RouteRepository.ts +247 -0
  584. package/src/RouterManager.tsx +79 -18
  585. package/src/WebSocketClient.ts +4 -4
  586. package/src/__tests__/PluginSettingsManager.test.ts +286 -0
  587. package/src/__tests__/PoweredBy.test.tsx +130 -0
  588. package/src/__tests__/app.test.tsx +373 -37
  589. package/src/__tests__/authRedirect.test.ts +287 -0
  590. package/src/__tests__/browserChecker.test.ts +112 -0
  591. package/src/__tests__/dataSourceRuntime.test.tsx +55 -0
  592. package/src/__tests__/globalDeps.test.ts +37 -0
  593. package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +221 -0
  594. package/src/__tests__/plugin-manager.test.tsx +177 -0
  595. package/src/__tests__/plugin.test.ts +61 -0
  596. package/src/__tests__/remotePlugins.test.ts +313 -0
  597. package/src/__tests__/settings-center.test.tsx +415 -0
  598. package/src/__tests__/useCurrentRoles.test.tsx +100 -0
  599. package/src/acl/ACLProvider.tsx +284 -0
  600. package/src/acl/__tests__/createAclSnippetAllow.test.ts +42 -0
  601. package/src/acl/createAclSnippetAllow.ts +33 -0
  602. package/src/acl/index.ts +12 -0
  603. package/src/acl/useAclSnippets.ts +25 -0
  604. package/src/ai/ai-manager.ts +19 -0
  605. package/src/ai/index.ts +13 -0
  606. package/src/ai/skills-manager/index.ts +10 -0
  607. package/src/ai/skills-manager/types.ts +26 -0
  608. package/src/ai/tools-manager/hooks/context.ts +20 -0
  609. package/src/ai/tools-manager/hooks/index.ts +22 -0
  610. package/src/ai/tools-manager/hooks/provider.tsx +53 -0
  611. package/src/ai/tools-manager/index.ts +42 -0
  612. package/src/ai/tools-manager/types.ts +106 -0
  613. package/src/ai/utils.ts +12 -0
  614. package/src/authRedirect.ts +279 -0
  615. package/src/collection-field-interface/CollectionFieldInterface.ts +201 -0
  616. package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +374 -0
  617. package/src/collection-manager/field-configure.ts +548 -0
  618. package/src/collection-manager/field-validation.ts +195 -0
  619. package/src/collection-manager/filter-operators/index.ts +203 -0
  620. package/src/collection-manager/filter-operators/operators.ts +363 -0
  621. package/src/collection-manager/interfaces/checkbox.ts +34 -0
  622. package/src/collection-manager/interfaces/checkboxGroup.ts +37 -0
  623. package/src/collection-manager/interfaces/collection.ts +40 -0
  624. package/src/collection-manager/interfaces/color.ts +34 -0
  625. package/src/collection-manager/interfaces/createdAt.ts +41 -0
  626. package/src/collection-manager/interfaces/createdBy.ts +69 -0
  627. package/src/collection-manager/interfaces/dateOnly.ts +54 -0
  628. package/src/collection-manager/interfaces/datetime.ts +66 -0
  629. package/src/collection-manager/interfaces/datetimeNoTz.ts +66 -0
  630. package/src/collection-manager/interfaces/email.ts +40 -0
  631. package/src/collection-manager/interfaces/icon.ts +31 -0
  632. package/src/collection-manager/interfaces/id.ts +60 -0
  633. package/src/collection-manager/interfaces/index.ts +50 -0
  634. package/src/collection-manager/interfaces/input.ts +93 -0
  635. package/src/collection-manager/interfaces/integer.ts +66 -0
  636. package/src/collection-manager/interfaces/json.tsx +80 -0
  637. package/src/collection-manager/interfaces/m2m.tsx +241 -0
  638. package/src/collection-manager/interfaces/m2o.tsx +174 -0
  639. package/src/collection-manager/interfaces/markdown.ts +35 -0
  640. package/src/collection-manager/interfaces/multipleSelect.ts +40 -0
  641. package/src/collection-manager/interfaces/nanoid.ts +82 -0
  642. package/src/collection-manager/interfaces/number.ts +90 -0
  643. package/src/collection-manager/interfaces/o2m.tsx +196 -0
  644. package/src/collection-manager/interfaces/obo.tsx +145 -0
  645. package/src/collection-manager/interfaces/oho.tsx +145 -0
  646. package/src/collection-manager/interfaces/password.ts +38 -0
  647. package/src/collection-manager/interfaces/percent.ts +106 -0
  648. package/src/collection-manager/interfaces/phone.ts +43 -0
  649. package/src/collection-manager/interfaces/properties/index.ts +449 -0
  650. package/src/collection-manager/interfaces/radioGroup.ts +37 -0
  651. package/src/collection-manager/interfaces/richText.ts +35 -0
  652. package/src/collection-manager/interfaces/select.ts +38 -0
  653. package/src/collection-manager/interfaces/snowflake-id.ts +61 -0
  654. package/src/collection-manager/interfaces/tableoid.ts +52 -0
  655. package/src/collection-manager/interfaces/textarea.ts +44 -0
  656. package/src/collection-manager/interfaces/time.ts +37 -0
  657. package/src/collection-manager/interfaces/types.ts +33 -0
  658. package/src/collection-manager/interfaces/unixTimestamp.tsx +68 -0
  659. package/src/collection-manager/interfaces/updatedAt.ts +41 -0
  660. package/src/collection-manager/interfaces/updatedBy.ts +68 -0
  661. package/src/collection-manager/interfaces/url.ts +46 -0
  662. package/src/collection-manager/interfaces/utils/index.ts +20 -0
  663. package/src/collection-manager/interfaces/uuid.ts +72 -0
  664. package/src/collection-manager/template-fields.ts +109 -0
  665. package/src/components/AppComponents.tsx +245 -0
  666. package/src/components/Icon.tsx +68 -0
  667. package/src/components/KeepAlive.tsx +131 -0
  668. package/src/components/PoweredBy.tsx +71 -0
  669. package/src/components/README.md +446 -0
  670. package/src/components/README.zh-CN.md +443 -0
  671. package/src/components/RouterBridge.tsx +28 -4
  672. package/src/components/SwitchLanguage.tsx +48 -0
  673. package/src/components/__tests__/KeepAlive.test.tsx +63 -0
  674. package/src/components/__tests__/RouterBridge.test.tsx +27 -0
  675. package/src/components/form/DialogFormLayout.tsx +87 -0
  676. package/src/components/form/DrawerFormLayout.tsx +84 -0
  677. package/src/components/form/EnvVariableInput.tsx +91 -0
  678. package/src/components/form/FileSizeInput.tsx +105 -0
  679. package/src/components/form/JsonTextArea.tsx +129 -0
  680. package/src/components/form/PasswordInput.tsx +211 -0
  681. package/src/components/form/RemoteSelect.tsx +137 -0
  682. package/src/components/form/ScanInput/CodeScanner.tsx +219 -0
  683. package/src/components/form/ScanInput/ScanBox.tsx +30 -0
  684. package/src/components/form/ScanInput/ScanInput.tsx +150 -0
  685. package/src/components/form/ScanInput/__tests__/ScanInput.test.tsx +119 -0
  686. package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +123 -0
  687. package/src/components/form/ScanInput/index.ts +12 -0
  688. package/src/components/form/ScanInput/types.ts +12 -0
  689. package/src/components/form/ScanInput/useCodeScanner.ts +136 -0
  690. package/src/components/form/TypedVariableInput.tsx +441 -0
  691. package/src/components/form/VariableInput.tsx +250 -0
  692. package/src/components/form/__tests__/EnvVariableInput.test.tsx +175 -0
  693. package/src/components/form/__tests__/TypedVariableInput.test.tsx +152 -0
  694. package/src/components/form/__tests__/VariableInput.test.ts +85 -0
  695. package/src/components/form/createFormRegistry.ts +60 -0
  696. package/src/components/form/filter/CollectionFilter.tsx +115 -0
  697. package/src/components/form/filter/CollectionFilterItem.tsx +192 -0
  698. package/src/components/form/filter/CollectionFilterPanel.tsx +97 -0
  699. package/src/components/form/filter/DateFilterDynamicComponent.tsx +283 -0
  700. package/src/components/form/filter/FilterValueInput.tsx +223 -0
  701. package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +247 -0
  702. package/src/components/form/filter/__tests__/DateFilterDynamicComponent.test.tsx +148 -0
  703. package/src/components/form/filter/__tests__/FilterValueInput.test.tsx +282 -0
  704. package/src/components/form/filter/__tests__/compileFilterGroup.test.ts +221 -0
  705. package/src/components/form/filter/index.ts +15 -0
  706. package/src/components/form/filter/useFilterActionProps.ts +267 -0
  707. package/src/components/form/index.tsx +21 -0
  708. package/src/components/form/table/RowOverlayPreview.tsx +51 -0
  709. package/src/components/form/table/SelectionCell.tsx +72 -0
  710. package/src/components/form/table/Table.tsx +280 -0
  711. package/src/components/form/table/__tests__/Table.pagination.test.tsx +80 -0
  712. package/src/components/form/table/constants.ts +16 -0
  713. package/src/components/form/table/dnd/SortableRow.tsx +106 -0
  714. package/src/components/form/table/dnd/index.ts +10 -0
  715. package/src/components/form/table/index.tsx +13 -0
  716. package/src/components/form/table/styles.ts +129 -0
  717. package/src/components/form/table/utils.ts +75 -0
  718. package/src/components/index.ts +7 -0
  719. package/src/css-variable/CSSVariableProvider.tsx +117 -0
  720. package/src/data-source/ExtendCollectionsProvider.tsx +144 -0
  721. package/src/data-source/__tests__/ExtendCollectionsProvider.test.tsx +264 -0
  722. package/src/data-source/index.ts +10 -0
  723. package/src/flow/FlowModelRepository.ts +222 -0
  724. package/src/flow/FlowPage.tsx +146 -0
  725. package/src/flow/__tests__/FlowModelRepository.test.ts +61 -0
  726. package/src/flow/__tests__/FlowPage.test.tsx +79 -0
  727. package/src/flow/__tests__/FlowRoute.test.tsx +1007 -0
  728. package/src/flow/__tests__/getKey.test.ts +61 -0
  729. package/src/flow/__tests__/getViewDiff.test.ts +180 -0
  730. package/src/flow/__tests__/helpers/mockFlowApp.ts +49 -0
  731. package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +278 -0
  732. package/src/flow/actions/__tests__/aclCheckRefresh.test.ts +129 -0
  733. package/src/flow/actions/__tests__/actionLinkageRules.race.repro.test.ts +244 -0
  734. package/src/flow/actions/__tests__/dataLoadingMode.test.tsx +69 -0
  735. package/src/flow/actions/__tests__/dataScope.leftMetaTree.test.tsx +192 -0
  736. package/src/flow/actions/__tests__/dataScopeFilter.test.ts +237 -0
  737. package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +96 -0
  738. package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +1016 -0
  739. package/src/flow/actions/__tests__/formAssignRules.legacyMigration.test.tsx +173 -0
  740. package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +470 -0
  741. package/src/flow/actions/__tests__/linkageRules.assignFieldOptions.test.tsx +56 -0
  742. package/src/flow/actions/__tests__/linkageRules.formValueDrivenRefresh.test.ts +443 -0
  743. package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +100 -0
  744. package/src/flow/actions/__tests__/linkageRules.menu.test.ts +90 -0
  745. package/src/flow/actions/__tests__/linkageRules.runjsTemplateResolution.test.ts +71 -0
  746. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +1142 -0
  747. package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +228 -0
  748. package/src/flow/actions/__tests__/openView.beforeClose.test.tsx +263 -0
  749. package/src/flow/actions/__tests__/openView.closeDestroy.test.tsx +95 -0
  750. package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +152 -0
  751. package/src/flow/actions/__tests__/openView.subModelKey.test.tsx +128 -0
  752. package/src/flow/actions/__tests__/pattern.test.ts +324 -0
  753. package/src/flow/actions/__tests__/setTargetDataScope.leftMetaTree.test.tsx +225 -0
  754. package/src/flow/actions/__tests__/showMessageNotification.test.ts +79 -0
  755. package/src/flow/actions/__tests__/sortingRules.test.ts +22 -0
  756. package/src/flow/actions/__tests__/subFormFieldLinkageRules.inputArgs.test.ts +173 -0
  757. package/src/flow/actions/__tests__/titleField.test.ts +45 -0
  758. package/src/flow/actions/aclCheck.tsx +50 -0
  759. package/src/flow/actions/aclCheckRefresh.tsx +172 -0
  760. package/src/flow/actions/afterSuccess.tsx +138 -0
  761. package/src/flow/actions/blockHeight.tsx +77 -0
  762. package/src/flow/actions/columnFixed.tsx +35 -0
  763. package/src/flow/actions/confirm.tsx +63 -0
  764. package/src/flow/actions/customVariable.tsx +399 -0
  765. package/src/flow/actions/dataLoadingMode.tsx +61 -0
  766. package/src/flow/actions/dataScope.tsx +73 -0
  767. package/src/flow/actions/dataScopeFilter.ts +70 -0
  768. package/src/flow/actions/dateRangeLimit.tsx +66 -0
  769. package/src/flow/actions/dateTimeFormat.tsx +192 -0
  770. package/src/flow/actions/displayFieldComponent.tsx +103 -0
  771. package/src/flow/actions/fieldComponent.tsx +114 -0
  772. package/src/flow/actions/filterFormDefaultValues.tsx +154 -0
  773. package/src/flow/actions/formAssignRules.tsx +132 -0
  774. package/src/flow/actions/index.ts +58 -0
  775. package/src/flow/actions/layout.tsx +107 -0
  776. package/src/flow/actions/linkageRules.tsx +2915 -0
  777. package/src/flow/actions/linkageRulesFormValueRefresh.ts +486 -0
  778. package/src/flow/actions/linkageRulesRefresh.tsx +83 -0
  779. package/src/flow/actions/navigateToURL.tsx +142 -0
  780. package/src/flow/actions/numberFormat.tsx +145 -0
  781. package/src/flow/actions/openView.tsx +537 -0
  782. package/src/flow/actions/overflowMode.tsx +36 -0
  783. package/src/flow/actions/pattern.tsx +180 -0
  784. package/src/flow/actions/refreshTargetBlocks.tsx +91 -0
  785. package/src/flow/actions/renderMode.tsx +42 -0
  786. package/src/flow/actions/required.tsx +70 -0
  787. package/src/flow/actions/runjs.tsx +48 -0
  788. package/src/flow/actions/setTargetDataScope.tsx +141 -0
  789. package/src/flow/actions/showMessage.tsx +155 -0
  790. package/src/flow/actions/showNotification.tsx +179 -0
  791. package/src/flow/actions/sortingRules.tsx +124 -0
  792. package/src/flow/actions/titleField.tsx +148 -0
  793. package/src/flow/actions/validation.tsx +77 -0
  794. package/src/flow/admin-shell/AdminLayoutRouteCoordinator.ts +27 -0
  795. package/src/flow/admin-shell/BaseLayoutModel.tsx +455 -0
  796. package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +502 -0
  797. package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +661 -0
  798. package/src/flow/admin-shell/admin-layout/AdminLayoutCompat.tsx +326 -0
  799. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +713 -0
  800. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +160 -0
  801. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +339 -0
  802. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +832 -0
  803. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +903 -0
  804. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +168 -0
  805. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +140 -0
  806. package/src/flow/admin-shell/admin-layout/AppListRender.tsx +139 -0
  807. package/src/flow/admin-shell/admin-layout/HelpLite.tsx +167 -0
  808. package/src/flow/admin-shell/admin-layout/PinnedPluginListLite.tsx +129 -0
  809. package/src/flow/admin-shell/admin-layout/ResetThemeTokenAndKeepAlgorithm.tsx +30 -0
  810. package/src/flow/admin-shell/admin-layout/TopbarActionsBar.tsx +211 -0
  811. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +2341 -0
  812. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +406 -0
  813. package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +211 -0
  814. package/src/flow/admin-shell/admin-layout/__tests__/flowSettingsPreference.test.ts +44 -0
  815. package/src/flow/admin-shell/admin-layout/constants.ts +10 -0
  816. package/src/flow/admin-shell/admin-layout/flowSettingsPreference.ts +54 -0
  817. package/src/flow/admin-shell/admin-layout/index.ts +23 -0
  818. package/src/flow/admin-shell/admin-layout/mobile-layout.tsx +35 -0
  819. package/src/flow/admin-shell/admin-layout/mobileMenuNavigation.ts +30 -0
  820. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +374 -0
  821. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +280 -0
  822. package/src/flow/admin-shell/admin-layout/useApplications.tsx +48 -0
  823. package/src/flow/admin-shell/useAdminLayoutRoutePage.ts +40 -0
  824. package/src/flow/admin-shell/useLayoutRoutePage.ts +61 -0
  825. package/src/flow/common/Liquid.tsx +148 -0
  826. package/src/flow/common/Markdown/Display.tsx +213 -0
  827. package/src/flow/common/Markdown/Edit.tsx +465 -0
  828. package/src/flow/common/Markdown/Markdown.tsx +44 -0
  829. package/src/flow/common/Markdown/style.ts +53 -0
  830. package/src/flow/common/Markdown/useCDN.ts +21 -0
  831. package/src/flow/components/AdminLayout.tsx +17 -0
  832. package/src/flow/components/BlockItemCard.tsx +204 -0
  833. package/src/flow/components/ConditionBuilder.tsx +50 -0
  834. package/src/flow/components/DefaultValue.tsx +738 -0
  835. package/src/flow/components/DynamicFlowsIcon.tsx +838 -0
  836. package/src/flow/components/EllipsisWithTooltip.tsx +106 -0
  837. package/src/flow/components/ExpiresRadio/index.tsx +139 -0
  838. package/src/flow/components/FieldAssignEditor.tsx +80 -0
  839. package/src/flow/components/FieldAssignExactDatePicker.tsx +225 -0
  840. package/src/flow/components/FieldAssignRulesEditor.tsx +1006 -0
  841. package/src/flow/components/FieldAssignValueInput.tsx +1491 -0
  842. package/src/flow/components/FlowRoute.tsx +276 -0
  843. package/src/flow/components/Grid/index.tsx +204 -0
  844. package/src/flow/components/JsonEditor.tsx +53 -0
  845. package/src/flow/components/RunJSValueEditor.tsx +50 -0
  846. package/src/flow/components/SkeletonFallback.tsx +19 -0
  847. package/src/flow/components/TextAreaWithContextSelector.tsx +163 -0
  848. package/src/flow/components/__tests__/DefaultValue.test.tsx +1289 -0
  849. package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +380 -0
  850. package/src/flow/components/__tests__/FieldAssignExactDatePicker.test.tsx +121 -0
  851. package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +946 -0
  852. package/src/flow/components/__tests__/FieldAssignValueInput.exactDate.test.tsx +180 -0
  853. package/src/flow/components/__tests__/FieldAssignValueInput.path.test.ts +298 -0
  854. package/src/flow/components/__tests__/fieldAssignOptions.test.ts +167 -0
  855. package/src/flow/components/code-editor/__tests__/SnippetsDrawer.test.tsx +51 -0
  856. package/src/flow/components/code-editor/__tests__/errorHelpers.test.ts +37 -0
  857. package/src/flow/components/code-editor/__tests__/javascriptHtmlTemplate.test.ts +101 -0
  858. package/src/flow/components/code-editor/__tests__/linter.test.ts +124 -0
  859. package/src/flow/components/code-editor/__tests__/resolveScenes.test.ts +44 -0
  860. package/src/flow/components/code-editor/__tests__/runjsCompletionSource.test.ts +251 -0
  861. package/src/flow/components/code-editor/__tests__/runjsCompletions.test.ts +490 -0
  862. package/src/flow/components/code-editor/__tests__/runjsDiagnostics.test.ts +256 -0
  863. package/src/flow/components/code-editor/__tests__/runjsLocales.test.ts +24 -0
  864. package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +354 -0
  865. package/src/flow/components/code-editor/core/EditorCore.tsx +216 -0
  866. package/src/flow/components/code-editor/core/tooltipParent.ts +28 -0
  867. package/src/flow/components/code-editor/errorHelpers.ts +92 -0
  868. package/src/flow/components/code-editor/extension/CodeEditorExtension.tsx +23 -0
  869. package/src/flow/components/code-editor/extension/index.ts +10 -0
  870. package/src/flow/components/code-editor/formatDocInfo.ts +98 -0
  871. package/src/flow/components/code-editor/hooks/useCodeRunner.ts +365 -0
  872. package/src/flow/components/code-editor/hooks/useRunJSDocCompletions.ts +41 -0
  873. package/src/flow/components/code-editor/htmlCompletion.ts +155 -0
  874. package/src/flow/components/code-editor/index.tsx +291 -0
  875. package/src/flow/components/code-editor/javascriptCompletion.ts +121 -0
  876. package/src/flow/components/code-editor/javascriptHtmlTemplate.ts +68 -0
  877. package/src/flow/components/code-editor/jsxCompletion.ts +244 -0
  878. package/src/flow/components/code-editor/linter.ts +949 -0
  879. package/src/flow/components/code-editor/panels/LogsPanel.tsx +68 -0
  880. package/src/flow/components/code-editor/panels/RightExtra.tsx +71 -0
  881. package/src/flow/components/code-editor/panels/SnippetsDrawer.tsx +104 -0
  882. package/src/flow/components/code-editor/resolveScenes.ts +38 -0
  883. package/src/flow/components/code-editor/runjsCompletionSource.ts +456 -0
  884. package/src/flow/components/code-editor/runjsCompletions.ts +787 -0
  885. package/src/flow/components/code-editor/runjsDiagnostics.ts +1141 -0
  886. package/src/flow/components/code-editor/types.ts +37 -0
  887. package/src/flow/components/drag-drop/Sortable.tsx +48 -0
  888. package/src/flow/components/drag-drop/SortableItem.tsx +28 -0
  889. package/src/flow/components/drag-drop/index.ts +11 -0
  890. package/src/flow/components/fieldAssignOptions.ts +229 -0
  891. package/src/flow/components/filter/FilterContainer.tsx +123 -0
  892. package/src/flow/components/filter/FilterGroup.tsx +320 -0
  893. package/src/flow/components/filter/FilterItem.tsx +144 -0
  894. package/src/flow/components/filter/LinkageFilterItem.tsx +533 -0
  895. package/src/flow/components/filter/VariableFilterItem.tsx +700 -0
  896. package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +143 -0
  897. package/src/flow/components/filter/__tests__/LinkageFilterItem.metaTree.test.ts +167 -0
  898. package/src/flow/components/filter/__tests__/LinkageFilterItem.test.tsx +405 -0
  899. package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +196 -0
  900. package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +497 -0
  901. package/src/flow/components/filter/__tests__/fieldsToOptions.test.ts +48 -0
  902. package/src/flow/components/filter/__tests__/metaTreeAssociationDepth.test.ts +60 -0
  903. package/src/flow/components/filter/fieldsToOptions.ts +76 -0
  904. package/src/flow/components/filter/index.ts +20 -0
  905. package/src/flow/components/filter/metaTreeAssociationDepth.ts +69 -0
  906. package/src/flow/components/filter/useFilterOptions.ts +102 -0
  907. package/src/flow/components/index.tsx +16 -0
  908. package/src/flow/components/placeholders/BlockPlaceholder.tsx +129 -0
  909. package/src/flow/components/placeholders/FieldPlaceholder.tsx +32 -0
  910. package/src/flow/components/placeholders/__tests__/BlockPlaceholder.test.tsx +105 -0
  911. package/src/flow/components/useAssociationTitleFieldSync.ts +49 -0
  912. package/src/flow/flows/editMarkdownFlow.tsx +143 -0
  913. package/src/flow/flows/openViewFlow.ts +89 -0
  914. package/src/flow/formily/ReactiveField.tsx +106 -0
  915. package/src/flow/formily/index.tsx +8 -0
  916. package/src/flow/getViewDiffAndUpdateHidden.tsx +86 -0
  917. package/src/flow/index.ts +113 -0
  918. package/src/flow/internal/components/Markdown/DisplayMarkdown.tsx +85 -0
  919. package/src/flow/internal/components/Markdown/markdown-it-plugins/mermaidPlugin.ts +85 -0
  920. package/src/flow/internal/components/Markdown/md.ts +24 -0
  921. package/src/flow/internal/components/Markdown/style.ts +165 -0
  922. package/src/flow/internal/components/Markdown/util.ts +45 -0
  923. package/src/flow/internal/constants/HeightMode.ts +14 -0
  924. package/src/flow/internal/index.ts +16 -0
  925. package/src/flow/internal/utils/__tests__/associationValueCoercion.test.ts +57 -0
  926. package/src/flow/internal/utils/__tests__/enumOptionsUtils.test.ts +68 -0
  927. package/src/flow/internal/utils/__tests__/modelUtils.test.ts +66 -0
  928. package/src/flow/internal/utils/__tests__/rebuildFieldSubModel.test.ts +184 -0
  929. package/src/flow/internal/utils/__tests__/titleFieldQuickSync.test.ts +94 -0
  930. package/src/flow/internal/utils/associationValueCoercion.ts +29 -0
  931. package/src/flow/internal/utils/dateTimeUtils.ts +53 -0
  932. package/src/flow/internal/utils/enumOptionsUtils.ts +103 -0
  933. package/src/flow/internal/utils/modelUtils.ts +158 -0
  934. package/src/flow/internal/utils/operatorSchemaHelper.ts +137 -0
  935. package/src/flow/internal/utils/rebuildFieldSubModel.ts +110 -0
  936. package/src/flow/internal/utils/saveStepParamsWithSubModels.ts +40 -0
  937. package/src/flow/internal/utils/titleFieldQuickSync.ts +95 -0
  938. package/src/flow/models/actions/AddChildActionModel.tsx +69 -0
  939. package/src/flow/models/actions/AddNewActionModel.tsx +32 -0
  940. package/src/flow/models/actions/AssociateActionModel.tsx +196 -0
  941. package/src/flow/models/actions/AssociationActionUtils.ts +104 -0
  942. package/src/flow/models/actions/BulkDeleteActionModel.tsx +61 -0
  943. package/src/flow/models/actions/DeleteActionModel.tsx +61 -0
  944. package/src/flow/models/actions/DisassociateActionModel.tsx +57 -0
  945. package/src/flow/models/actions/EditActionModel.tsx +31 -0
  946. package/src/flow/models/actions/ExpandCollapseActionModel.tsx +113 -0
  947. package/src/flow/models/actions/FilterActionModel.tsx +340 -0
  948. package/src/flow/models/actions/JSActionModel.tsx +84 -0
  949. package/src/flow/models/actions/JSCollectionActionModel.tsx +90 -0
  950. package/src/flow/models/actions/JSItemActionModel.tsx +166 -0
  951. package/src/flow/models/actions/JSRecordActionModel.tsx +90 -0
  952. package/src/flow/models/actions/LinkActionModel.tsx +198 -0
  953. package/src/flow/models/actions/LinkActionUtils.ts +65 -0
  954. package/src/flow/models/actions/PopupCollectionActionModel.tsx +25 -0
  955. package/src/flow/models/actions/RefreshActionModel.tsx +45 -0
  956. package/src/flow/models/actions/UpdateRecordActionModel.tsx +120 -0
  957. package/src/flow/models/actions/UpdateRecordActionUtils.ts +86 -0
  958. package/src/flow/models/actions/ViewActionModel.tsx +31 -0
  959. package/src/flow/models/actions/__tests__/AssignFormRefill.test.ts +170 -0
  960. package/src/flow/models/actions/__tests__/AssociationActionModel.test.ts +313 -0
  961. package/src/flow/models/actions/__tests__/JSItemActionModel.test.tsx +85 -0
  962. package/src/flow/models/actions/__tests__/LinkActionModel.test.ts +110 -0
  963. package/src/flow/models/actions/__tests__/UpdateRecordActionModel.test.ts +72 -0
  964. package/src/flow/models/actions/index.ts +29 -0
  965. package/src/flow/models/actions/joinUrlSearch.ts +42 -0
  966. package/src/flow/models/base/ActionGroupModel.tsx +10 -0
  967. package/src/flow/models/base/ActionGroupModelCore.tsx +117 -0
  968. package/src/flow/models/base/ActionModel.tsx +149 -0
  969. package/src/flow/models/base/ActionModelCore.tsx +182 -0
  970. package/src/flow/models/base/AssociationFieldGroupModel.tsx +117 -0
  971. package/src/flow/models/base/BlockGridModel.tsx +144 -0
  972. package/src/flow/models/base/BlockModel.tsx +247 -0
  973. package/src/flow/models/base/CollectionActionModel.tsx +23 -0
  974. package/src/flow/models/base/CollectionBlockModel.tsx +714 -0
  975. package/src/flow/models/base/CommonItemModel.tsx +12 -0
  976. package/src/flow/models/base/DataBlockModel.tsx +41 -0
  977. package/src/flow/models/base/FieldModel.tsx +26 -0
  978. package/src/flow/models/base/FilterBlockModel.tsx +15 -0
  979. package/src/flow/models/base/GridModel.tsx +1363 -0
  980. package/src/flow/models/base/PageModel/ChildPageModel.tsx +118 -0
  981. package/src/flow/models/base/PageModel/MainPageModel.tsx +32 -0
  982. package/src/flow/models/base/PageModel/OldPageModel.tsx +97 -0
  983. package/src/flow/models/base/PageModel/PageModel.tsx +531 -0
  984. package/src/flow/models/base/PageModel/PageTabModel.tsx +259 -0
  985. package/src/flow/models/base/PageModel/RootPageModel.tsx +189 -0
  986. package/src/flow/models/base/PageModel/SubPageModel.tsx +32 -0
  987. package/src/flow/models/base/PageModel/__tests__/ChildPageModel.test.ts +208 -0
  988. package/src/flow/models/base/PageModel/__tests__/PageModel.beforeCloseGuard.test.ts +111 -0
  989. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +927 -0
  990. package/src/flow/models/base/PageModel/__tests__/PageTabModel.test.ts +225 -0
  991. package/src/flow/models/base/PageModel/__tests__/RootPageModel.test.ts +358 -0
  992. package/src/flow/models/base/PageModel/closeGuard.ts +48 -0
  993. package/src/flow/models/base/PageModel/index.tsx +16 -0
  994. package/src/flow/models/base/PopupActionModel.tsx +26 -0
  995. package/src/flow/models/base/RecordActionModel.tsx +23 -0
  996. package/src/flow/models/base/RouteModel.tsx +29 -0
  997. package/src/flow/models/base/__tests__/ActionGroupModel.test.ts +200 -0
  998. package/src/flow/models/base/__tests__/AssociationFieldGroupModel.test.ts +86 -0
  999. package/src/flow/models/base/__tests__/BlockGridModel.dragOverlayConfig.test.ts +44 -0
  1000. package/src/flow/models/base/__tests__/BlockGridModel.newScene.test.ts +37 -0
  1001. package/src/flow/models/base/__tests__/BlockGridModel.selectSceneAddBlock.test.ts +83 -0
  1002. package/src/flow/models/base/__tests__/CollectionBlockModel.capability.test.ts +96 -0
  1003. package/src/flow/models/base/__tests__/CollectionBlockModel.dirtyRefresh.association.test.ts +110 -0
  1004. package/src/flow/models/base/__tests__/CollectionBlockModel.initialBeforeRenderRefresh.test.ts +131 -0
  1005. package/src/flow/models/base/__tests__/CollectionBlockModel.newScene.associatedRecordsVisibility.test.ts +161 -0
  1006. package/src/flow/models/base/__tests__/CollectionBlockModel.title.test.ts +127 -0
  1007. package/src/flow/models/base/__tests__/GridModel.computeOverlayRect.test.ts +452 -0
  1008. package/src/flow/models/base/__tests__/GridModel.dragOverlay.test.ts +129 -0
  1009. package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +384 -0
  1010. package/src/flow/models/base/__tests__/GridModel.mergeRows.test.ts +107 -0
  1011. package/src/flow/models/base/__tests__/GridModel.recalculateGridSizes.test.ts +67 -0
  1012. package/src/flow/models/base/__tests__/GridModel.render.test.tsx +53 -0
  1013. package/src/flow/models/base/__tests__/GridModel.resizeLayout.test.ts +124 -0
  1014. package/src/flow/models/base/__tests__/GridModel.visibleLayout.test.ts +329 -0
  1015. package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +58 -0
  1016. package/src/flow/models/base/index.ts +26 -0
  1017. package/src/flow/models/blocks/assign-form/AssignFormGridModel.tsx +170 -0
  1018. package/src/flow/models/blocks/assign-form/AssignFormItemModel.tsx +480 -0
  1019. package/src/flow/models/blocks/assign-form/AssignFormModel.tsx +96 -0
  1020. package/src/flow/models/blocks/assign-form/__tests__/assignFieldValuesFlow.editor.test.tsx +216 -0
  1021. package/src/flow/models/blocks/assign-form/assignFieldValuesFlow.tsx +308 -0
  1022. package/src/flow/models/blocks/assign-form/index.ts +13 -0
  1023. package/src/flow/models/blocks/details/DetailsAssociationFieldGroupModel.tsx +18 -0
  1024. package/src/flow/models/blocks/details/DetailsBlockModel.tsx +404 -0
  1025. package/src/flow/models/blocks/details/DetailsCustomItemModel.tsx +51 -0
  1026. package/src/flow/models/blocks/details/DetailsGridModel.tsx +106 -0
  1027. package/src/flow/models/blocks/details/DetailsItemModel.tsx +389 -0
  1028. package/src/flow/models/blocks/details/DetailsJSFieldItemModel.tsx +37 -0
  1029. package/src/flow/models/blocks/details/__tests__/DetailsBlockModel.blockHeight.test.tsx +139 -0
  1030. package/src/flow/models/blocks/details/__tests__/DetailsBlockModel.initialPaginationChangeRefresh.test.ts +128 -0
  1031. package/src/flow/models/blocks/details/__tests__/DetailsItemModel.value.test.ts +49 -0
  1032. package/src/flow/models/blocks/details/index.ts +16 -0
  1033. package/src/flow/models/blocks/details/utils.ts +67 -0
  1034. package/src/flow/models/blocks/filter-form/FieldModelSelect.tsx +59 -0
  1035. package/src/flow/models/blocks/filter-form/FieldOperatorSelect.tsx +109 -0
  1036. package/src/flow/models/blocks/filter-form/FilterFormActionGroupModel.tsx +15 -0
  1037. package/src/flow/models/blocks/filter-form/FilterFormActionModel.tsx +12 -0
  1038. package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +686 -0
  1039. package/src/flow/models/blocks/filter-form/FilterFormCollapseActionModel.tsx +132 -0
  1040. package/src/flow/models/blocks/filter-form/FilterFormCustomItemModel.tsx +42 -0
  1041. package/src/flow/models/blocks/filter-form/FilterFormGridModel.tsx +422 -0
  1042. package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +822 -0
  1043. package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +72 -0
  1044. package/src/flow/models/blocks/filter-form/FilterFormResetActionModel.tsx +52 -0
  1045. package/src/flow/models/blocks/filter-form/FilterFormSubmitActionModel.tsx +49 -0
  1046. package/src/flow/models/blocks/filter-form/SourceCascader.tsx +137 -0
  1047. package/src/flow/models/blocks/filter-form/__tests__/FilterFormBlockModel.cleanup.test.ts +138 -0
  1048. package/src/flow/models/blocks/filter-form/__tests__/FilterFormGridModel.onModelCreated.test.ts +247 -0
  1049. package/src/flow/models/blocks/filter-form/__tests__/FilterFormGridModel.toggleFormFieldsCollapse.test.ts +457 -0
  1050. package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +334 -0
  1051. package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.getFilterValue.test.ts +177 -0
  1052. package/src/flow/models/blocks/filter-form/__tests__/customFieldOperators.test.tsx +665 -0
  1053. package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +388 -0
  1054. package/src/flow/models/blocks/filter-form/__tests__/legacyDefaultValueMigration.test.ts +110 -0
  1055. package/src/flow/models/blocks/filter-form/__tests__/valueNormalization.test.ts +50 -0
  1056. package/src/flow/models/blocks/filter-form/customFieldOperators.ts +236 -0
  1057. package/src/flow/models/blocks/filter-form/fields/FieldComponentProps.tsx +488 -0
  1058. package/src/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.tsx +411 -0
  1059. package/src/flow/models/blocks/filter-form/fields/FilterFormCustomRecordSelectFieldModel.tsx +543 -0
  1060. package/src/flow/models/blocks/filter-form/fields/FilterFormFieldModel.tsx +12 -0
  1061. package/src/flow/models/blocks/filter-form/fields/FilterFormRecordSelectFieldModel.tsx +85 -0
  1062. package/src/flow/models/blocks/filter-form/fields/__tests__/FilterFormCustomFieldModel.recordSelect.test.tsx +651 -0
  1063. package/src/flow/models/blocks/filter-form/fields/date-time/DateOnlyFilterFieldModel.tsx +42 -0
  1064. package/src/flow/models/blocks/filter-form/fields/date-time/DateTimeFilterFieldModel.tsx +17 -0
  1065. package/src/flow/models/blocks/filter-form/fields/date-time/DateTimeNoTzFilterFieldModel.tsx +30 -0
  1066. package/src/flow/models/blocks/filter-form/fields/date-time/DateTimeTzFilterFieldModel.tsx +48 -0
  1067. package/src/flow/models/blocks/filter-form/fields/date-time/components/DateFilterDynamicComponent.tsx +184 -0
  1068. package/src/flow/models/blocks/filter-form/fields/date-time/components/FilterDatePicker.tsx +108 -0
  1069. package/src/flow/models/blocks/filter-form/fields/date-time/components/FilterRangePicker.tsx +84 -0
  1070. package/src/flow/models/blocks/filter-form/fields/date-time/components/__tests__/FilterDatePickers.test.tsx +121 -0
  1071. package/src/flow/models/blocks/filter-form/fields/date-time/index.ts +13 -0
  1072. package/src/flow/models/blocks/filter-form/fields/index.ts +14 -0
  1073. package/src/flow/models/blocks/filter-form/index.ts +25 -0
  1074. package/src/flow/models/blocks/filter-form/legacyDefaultValueMigration.ts +36 -0
  1075. package/src/flow/models/blocks/filter-form/valueNormalization.ts +92 -0
  1076. package/src/flow/models/blocks/filter-manager/FilterManager.ts +602 -0
  1077. package/src/flow/models/blocks/filter-manager/__tests__/FilterManager.bindToTarget.test.ts +446 -0
  1078. package/src/flow/models/blocks/filter-manager/__tests__/FilterManager.test.ts +972 -0
  1079. package/src/flow/models/blocks/filter-manager/__tests__/FilterManager.unbindFromTarget.test.ts +242 -0
  1080. package/src/flow/models/blocks/filter-manager/__tests__/getDefaultOperator.test.ts +103 -0
  1081. package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +148 -0
  1082. package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/defaultOperator.test.tsx +143 -0
  1083. package/src/flow/models/blocks/filter-manager/flow-actions/connectFields.tsx +530 -0
  1084. package/src/flow/models/blocks/filter-manager/flow-actions/customizeFilterRender.tsx +48 -0
  1085. package/src/flow/models/blocks/filter-manager/flow-actions/defaultOperator.tsx +46 -0
  1086. package/src/flow/models/blocks/filter-manager/flow-actions/index.ts +13 -0
  1087. package/src/flow/models/blocks/filter-manager/flow-actions/operatorComponentProps.tsx +37 -0
  1088. package/src/flow/models/blocks/filter-manager/index.ts +13 -0
  1089. package/src/flow/models/blocks/filter-manager/utils.ts +210 -0
  1090. package/src/flow/models/blocks/form/CreateFormModel.tsx +124 -0
  1091. package/src/flow/models/blocks/form/EditFormModel.tsx +298 -0
  1092. package/src/flow/models/blocks/form/FormActionGroupModel.tsx +29 -0
  1093. package/src/flow/models/blocks/form/FormActionModel.tsx +139 -0
  1094. package/src/flow/models/blocks/form/FormAssociationFieldGroupModel.tsx +18 -0
  1095. package/src/flow/models/blocks/form/FormAssociationItemModel.tsx +368 -0
  1096. package/src/flow/models/blocks/form/FormBlockModel.tsx +739 -0
  1097. package/src/flow/models/blocks/form/FormCustomItemModel.tsx +54 -0
  1098. package/src/flow/models/blocks/form/FormGridModel.tsx +106 -0
  1099. package/src/flow/models/blocks/form/FormItemModel.tsx +510 -0
  1100. package/src/flow/models/blocks/form/FormJSFieldItemModel.tsx +36 -0
  1101. package/src/flow/models/blocks/form/JSFormActionModel.tsx +85 -0
  1102. package/src/flow/models/blocks/form/QuickEditFormModel.tsx +303 -0
  1103. package/src/flow/models/blocks/form/__tests__/FormActionGroupModel.test.ts +46 -0
  1104. package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +882 -0
  1105. package/src/flow/models/blocks/form/__tests__/FormItemModel.defineChildren.test.ts +133 -0
  1106. package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +69 -0
  1107. package/src/flow/models/blocks/form/__tests__/assignRulesUpdateAssociationValues.test.ts +81 -0
  1108. package/src/flow/models/blocks/form/__tests__/dynamicNamePath.test.ts +33 -0
  1109. package/src/flow/models/blocks/form/__tests__/legacyDefaultValueMigration.test.ts +138 -0
  1110. package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +71 -0
  1111. package/src/flow/models/blocks/form/__tests__/submitValues.test.ts +224 -0
  1112. package/src/flow/models/blocks/form/assignRulesUpdateAssociationValues.ts +73 -0
  1113. package/src/flow/models/blocks/form/dynamicNamePath.ts +68 -0
  1114. package/src/flow/models/blocks/form/index.tsx +23 -0
  1115. package/src/flow/models/blocks/form/legacyDefaultValueMigration.ts +32 -0
  1116. package/src/flow/models/blocks/form/submitHandler.ts +70 -0
  1117. package/src/flow/models/blocks/form/submitValues.ts +230 -0
  1118. package/src/flow/models/blocks/form/value-runtime/__tests__/deps.test.ts +28 -0
  1119. package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +3465 -0
  1120. package/src/flow/models/blocks/form/value-runtime/__tests__/subtable-nested.test.ts +103 -0
  1121. package/src/flow/models/blocks/form/value-runtime/conditions.ts +22 -0
  1122. package/src/flow/models/blocks/form/value-runtime/deps.ts +181 -0
  1123. package/src/flow/models/blocks/form/value-runtime/form-patch.ts +83 -0
  1124. package/src/flow/models/blocks/form/value-runtime/index.ts +12 -0
  1125. package/src/flow/models/blocks/form/value-runtime/path.ts +144 -0
  1126. package/src/flow/models/blocks/form/value-runtime/rules.ts +1935 -0
  1127. package/src/flow/models/blocks/form/value-runtime/runtime.ts +1219 -0
  1128. package/src/flow/models/blocks/form/value-runtime/types.ts +72 -0
  1129. package/src/flow/models/blocks/form/value-runtime/utils.ts +25 -0
  1130. package/src/flow/models/blocks/index.ts +17 -0
  1131. package/src/flow/models/blocks/js-block/JSBlock.tsx +180 -0
  1132. package/src/flow/models/blocks/js-block/index.ts +10 -0
  1133. package/src/flow/models/blocks/shared/filterOperators.ts +14 -0
  1134. package/src/flow/models/blocks/shared/legacyDefaultValueMigrationBase.ts +192 -0
  1135. package/src/flow/models/blocks/table/JSColumnModel.tsx +307 -0
  1136. package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +243 -0
  1137. package/src/flow/models/blocks/table/TableAssociationFieldGroupModel.tsx +18 -0
  1138. package/src/flow/models/blocks/table/TableBlockModel.tsx +1203 -0
  1139. package/src/flow/models/blocks/table/TableColumnModel.tsx +574 -0
  1140. package/src/flow/models/blocks/table/TableCustomColumnModel.tsx +116 -0
  1141. package/src/flow/models/blocks/table/TableJSFieldItemModel.tsx +38 -0
  1142. package/src/flow/models/blocks/table/TableSelectModel.tsx +85 -0
  1143. package/src/flow/models/blocks/table/__tests__/JSColumnModel.test.tsx +51 -0
  1144. package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +282 -0
  1145. package/src/flow/models/blocks/table/__tests__/TableBlockModel.blockHeight.test.tsx +120 -0
  1146. package/src/flow/models/blocks/table/__tests__/TableBlockModel.popupSourceId.test.ts +87 -0
  1147. package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +49 -0
  1148. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowClick.test.ts +69 -0
  1149. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +114 -0
  1150. package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +221 -0
  1151. package/src/flow/models/blocks/table/__tests__/TableSelectModel.test.ts +41 -0
  1152. package/src/flow/models/blocks/table/__tests__/sortUtils.test.ts +58 -0
  1153. package/src/flow/models/blocks/table/dragSort/dragSortComponents.tsx +10 -0
  1154. package/src/flow/models/blocks/table/dragSort/dragSortHooks.tsx +130 -0
  1155. package/src/flow/models/blocks/table/dragSort/dragSortSettings.ts +62 -0
  1156. package/src/flow/models/blocks/table/dragSort/dragSortUtils.ts +57 -0
  1157. package/src/flow/models/blocks/table/dragSort/index.ts +13 -0
  1158. package/src/flow/models/blocks/table/index.ts +18 -0
  1159. package/src/flow/models/blocks/table/sortUtils.ts +52 -0
  1160. package/src/flow/models/blocks/table/utils.ts +125 -0
  1161. package/src/flow/models/blocks/utils/__tests__/transformChildrenToJS.test.ts +216 -0
  1162. package/src/flow/models/blocks/utils/transformChildrenToJS.ts +158 -0
  1163. package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +47 -0
  1164. package/src/flow/models/fields/AssociationFieldModel/CascadeSelectFieldModel.tsx +822 -0
  1165. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableActionGroupModel.tsx +19 -0
  1166. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableActionsColumnModel.tsx +212 -0
  1167. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +913 -0
  1168. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableEditActionModel.tsx +383 -0
  1169. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableFormSubmitActionModel.tsx +121 -0
  1170. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/PopupSubTableRemoveActionModel.tsx +101 -0
  1171. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/__tests__/popupSubTableBeforeClose.test.ts +98 -0
  1172. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/actions/popupSubTableBeforeClose.ts +158 -0
  1173. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/blocks/PopupSubTableFormModel.tsx +235 -0
  1174. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/index.tsx +18 -0
  1175. package/src/flow/models/fields/AssociationFieldModel/RecordPickerFieldModel.tsx +599 -0
  1176. package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +1009 -0
  1177. package/src/flow/models/fields/AssociationFieldModel/SubFormFieldModel.tsx +655 -0
  1178. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +1054 -0
  1179. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +306 -0
  1180. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +211 -0
  1181. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableField.refresh.test.tsx +122 -0
  1182. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +401 -0
  1183. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/rowIdentity.ts +70 -0
  1184. package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +309 -0
  1185. package/src/flow/models/fields/AssociationFieldModel/__tests__/SubTableRowIdentity.test.ts +45 -0
  1186. package/src/flow/models/fields/AssociationFieldModel/__tests__/recordSelectShared.fieldNames.test.ts +60 -0
  1187. package/src/flow/models/fields/AssociationFieldModel/index.tsx +16 -0
  1188. package/src/flow/models/fields/AssociationFieldModel/itemChain.ts +362 -0
  1189. package/src/flow/models/fields/AssociationFieldModel/recordSelectSettingsUtils.ts +20 -0
  1190. package/src/flow/models/fields/AssociationFieldModel/recordSelectShared.tsx +283 -0
  1191. package/src/flow/models/fields/CheckboxFieldModel.tsx +31 -0
  1192. package/src/flow/models/fields/CheckboxGroupFieldModel.tsx +25 -0
  1193. package/src/flow/models/fields/ClickableFieldModel.tsx +355 -0
  1194. package/src/flow/models/fields/CollectionSelectorFieldModel.tsx +100 -0
  1195. package/src/flow/models/fields/ColorFieldModel.tsx +61 -0
  1196. package/src/flow/models/fields/DateTimeFieldModel/DateOnlyFieldModel.tsx +70 -0
  1197. package/src/flow/models/fields/DateTimeFieldModel/DateTimeFieldModel.tsx +30 -0
  1198. package/src/flow/models/fields/DateTimeFieldModel/DateTimeNoTzFieldModel.tsx +62 -0
  1199. package/src/flow/models/fields/DateTimeFieldModel/DateTimeTzFieldModel.tsx +105 -0
  1200. package/src/flow/models/fields/DateTimeFieldModel/__tests__/DateTimeNoTzFieldModel.dateLimit.test.tsx +242 -0
  1201. package/src/flow/models/fields/DateTimeFieldModel/dateLimit.ts +152 -0
  1202. package/src/flow/models/fields/DateTimeFieldModel/index.ts +12 -0
  1203. package/src/flow/models/fields/DisplayAssociationField/DisplaySubItemFieldModel.tsx +70 -0
  1204. package/src/flow/models/fields/DisplayAssociationField/DisplaySubListFieldModel.tsx +136 -0
  1205. package/src/flow/models/fields/DisplayAssociationField/DisplaySubTableFieldModel.tsx +271 -0
  1206. package/src/flow/models/fields/DisplayAssociationField/__tests__/DisplaySubListFieldModel.utils.test.ts +41 -0
  1207. package/src/flow/models/fields/DisplayAssociationField/displaySubListUtils.ts +29 -0
  1208. package/src/flow/models/fields/DisplayAssociationField/index.tsx +12 -0
  1209. package/src/flow/models/fields/DisplayCheckboxFieldModel.tsx +36 -0
  1210. package/src/flow/models/fields/DisplayColorFieldModel.tsx +45 -0
  1211. package/src/flow/models/fields/DisplayDateTimeFieldModel.tsx +59 -0
  1212. package/src/flow/models/fields/DisplayEnumFieldModel.tsx +174 -0
  1213. package/src/flow/models/fields/DisplayHtmlFieldModel.tsx +39 -0
  1214. package/src/flow/models/fields/DisplayIconFieldModel.tsx +24 -0
  1215. package/src/flow/models/fields/DisplayJSONFieldModel.tsx +114 -0
  1216. package/src/flow/models/fields/DisplayNumberFieldModel.tsx +239 -0
  1217. package/src/flow/models/fields/DisplayPasswordFieldModel.tsx +30 -0
  1218. package/src/flow/models/fields/DisplayPercentFieldModel.tsx +165 -0
  1219. package/src/flow/models/fields/DisplayTextFieldModel.tsx +51 -0
  1220. package/src/flow/models/fields/DisplayTimeFieldModel.tsx +47 -0
  1221. package/src/flow/models/fields/DisplayTitleFieldModel.tsx +112 -0
  1222. package/src/flow/models/fields/DisplayURLFieldModel.tsx +41 -0
  1223. package/src/flow/models/fields/DividerItemModel.tsx +115 -0
  1224. package/src/flow/models/fields/IconFieldModel.tsx +172 -0
  1225. package/src/flow/models/fields/InputFieldModel.tsx +120 -0
  1226. package/src/flow/models/fields/JSEditableFieldModel.tsx +415 -0
  1227. package/src/flow/models/fields/JSFieldModel.tsx +224 -0
  1228. package/src/flow/models/fields/JSItemModel.tsx +163 -0
  1229. package/src/flow/models/fields/JsonFieldModel.tsx +121 -0
  1230. package/src/flow/models/fields/MarkdownItemModel.tsx +68 -0
  1231. package/src/flow/models/fields/NumberFieldModel.tsx +68 -0
  1232. package/src/flow/models/fields/PasswordFieldModel.tsx +53 -0
  1233. package/src/flow/models/fields/PercentFieldModel.tsx +53 -0
  1234. package/src/flow/models/fields/RadioGroupFieldModel.tsx +26 -0
  1235. package/src/flow/models/fields/RichTextFieldModel/index.tsx +115 -0
  1236. package/src/flow/models/fields/RichTextFieldModel/registerFontSize.tsx +18 -0
  1237. package/src/flow/models/fields/RichTextFieldModel/registerImageResize.tsx +56 -0
  1238. package/src/flow/models/fields/RichTextFieldModel/registerSmartBreak.tsx +90 -0
  1239. package/src/flow/models/fields/RichTextFieldModel/style.ts +493 -0
  1240. package/src/flow/models/fields/SelectFieldModel.tsx +166 -0
  1241. package/src/flow/models/fields/TextareaFieldModel.tsx +31 -0
  1242. package/src/flow/models/fields/TimeFieldModel.tsx +66 -0
  1243. package/src/flow/models/fields/VariableFieldFormModel.tsx +67 -0
  1244. package/src/flow/models/fields/__tests__/ClickableFieldModel.test.ts +288 -0
  1245. package/src/flow/models/fields/__tests__/DisplayEnumFieldModel.test.tsx +39 -0
  1246. package/src/flow/models/fields/__tests__/DisplayJSONFieldModel.test.tsx +36 -0
  1247. package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +116 -0
  1248. package/src/flow/models/fields/__tests__/JSEditableFieldModel.test.tsx +307 -0
  1249. package/src/flow/models/fields/__tests__/TimeFieldModel.test.tsx +61 -0
  1250. package/src/flow/models/fields/index.ts +52 -0
  1251. package/src/flow/models/fields/mobile-components/MobileDatePicker.tsx +125 -0
  1252. package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +321 -0
  1253. package/src/flow/models/fields/mobile-components/MobileSelect.tsx +102 -0
  1254. package/src/flow/models/fields/mobile-components/MobileTimePicker.tsx +37 -0
  1255. package/src/flow/models/fields/mobile-components/__tests__/MobileDatePicker.test.tsx +94 -0
  1256. package/src/flow/models/fields/mobile-components/__tests__/MobileSelect.test.tsx +312 -0
  1257. package/src/flow/models/index.ts +14 -0
  1258. package/src/flow/models/topbar/TopbarActionModel.tsx +414 -0
  1259. package/src/flow/models/topbar/UserCenterTopbarActionModel.tsx +592 -0
  1260. package/src/flow/models/topbar/index.ts +11 -0
  1261. package/src/flow/models/utils/displayValueUtils.ts +57 -0
  1262. package/src/flow/models/utils/resolveRunJsParams.ts +24 -0
  1263. package/src/flow/resolveViewParamsToViewList.tsx +79 -0
  1264. package/src/flow/system-settings/SystemSettingsSource.ts +155 -0
  1265. package/src/flow/system-settings/index.ts +11 -0
  1266. package/src/flow/system-settings/useSystemSettings.tsx +86 -0
  1267. package/src/flow/utils/__tests__/actionCapability.test.ts +79 -0
  1268. package/src/flow/utils/__tests__/dateTimeFormat.test.ts +91 -0
  1269. package/src/flow/utils/__tests__/dispatchEventDeep.test.ts +72 -0
  1270. package/src/flow/utils/__tests__/pagination.test.ts +64 -0
  1271. package/src/flow/utils/actionCapability.ts +150 -0
  1272. package/src/flow/utils/blockUtils.ts +32 -0
  1273. package/src/flow/utils/dataScopeFormValueClear.ts +278 -0
  1274. package/src/flow/utils/dispatchEventDeep.ts +66 -0
  1275. package/src/flow/utils/index.ts +12 -0
  1276. package/src/flow/utils/pagination.ts +110 -0
  1277. package/src/flow/utils/useJsonTemplateResolver.ts +25 -0
  1278. package/src/flow-compat/ColorPicker.tsx +88 -0
  1279. package/src/flow-compat/FieldValidation.tsx +598 -0
  1280. package/src/flow-compat/HighPerformanceSpin.tsx +45 -0
  1281. package/src/flow-compat/Icon.tsx +11 -0
  1282. package/src/flow-compat/IconPicker.tsx +186 -0
  1283. package/src/flow-compat/Password.tsx +78 -0
  1284. package/src/flow-compat/PasswordStrength.tsx +27 -0
  1285. package/src/flow-compat/Popover.tsx +60 -0
  1286. package/src/flow-compat/data.ts +43 -0
  1287. package/src/flow-compat/date.ts +116 -0
  1288. package/src/flow-compat/fieldValidationConstants.ts +305 -0
  1289. package/src/flow-compat/index.ts +34 -0
  1290. package/src/flow-compat/lazy.tsx +110 -0
  1291. package/src/flow-compat/operators.ts +367 -0
  1292. package/src/flow-compat/passwordUtils.ts +153 -0
  1293. package/src/flow-compat/routeTypes.ts +61 -0
  1294. package/src/flow-compat/useFullscreenOverlay.ts +139 -0
  1295. package/src/flow-compat/zIndexContext.tsx +28 -0
  1296. package/src/hooks/index.ts +2 -0
  1297. package/src/hooks/useApp.ts +5 -3
  1298. package/src/hooks/useCurrentAppInfo.ts +36 -0
  1299. package/src/hooks/usePlugin.ts +2 -2
  1300. package/src/i18n.ts +25 -0
  1301. package/src/index.ts +28 -0
  1302. package/src/json-logic/globalOperators.js +731 -0
  1303. package/src/layout-manager/LayoutContentRoute.tsx +90 -0
  1304. package/src/layout-manager/LayoutManager.tsx +185 -0
  1305. package/src/layout-manager/LayoutRoute.tsx +138 -0
  1306. package/src/layout-manager/__tests__/LayoutManager.test.tsx +335 -0
  1307. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +473 -0
  1308. package/src/layout-manager/index.ts +14 -0
  1309. package/src/layout-manager/types.ts +22 -0
  1310. package/src/layout-manager/utils.ts +37 -0
  1311. package/src/locale/languageCodes.ts +83 -0
  1312. package/src/nocobase-buildin-plugin/index.tsx +374 -0
  1313. package/src/nocobase-buildin-plugin/plugins/LocalePlugin.ts +62 -0
  1314. package/src/nocobase-buildin-plugin/plugins/dayjsLocale.ts +77 -0
  1315. package/src/nocobase-buildin-plugin/plugins/loadConstrueLocale.ts +182 -0
  1316. package/src/react-is.d.ts +12 -0
  1317. package/src/settings-center/AdminSettingsLayout.tsx +333 -0
  1318. package/src/settings-center/AdminSettingsLayoutModel.tsx +32 -0
  1319. package/src/settings-center/SystemSettingsPage.tsx +298 -0
  1320. package/src/settings-center/index.ts +14 -0
  1321. package/src/settings-center/plugin-manager/BulkEnableButton.tsx +111 -0
  1322. package/src/settings-center/plugin-manager/PluginCard.tsx +270 -0
  1323. package/src/settings-center/plugin-manager/PluginDetail.tsx +195 -0
  1324. package/src/settings-center/plugin-manager/index.tsx +254 -0
  1325. package/src/settings-center/plugin-manager/types.ts +35 -0
  1326. package/src/settings-center/utils.tsx +284 -0
  1327. package/src/theme/AntdAppProvider.tsx +52 -0
  1328. package/src/theme/__tests__/globalStyles.test.ts +24 -0
  1329. package/src/theme/compatOldTheme.ts +21 -0
  1330. package/src/theme/customAlgorithm.ts +43 -0
  1331. package/src/theme/defaultTheme.ts +32 -0
  1332. package/src/theme/globalStyles.ts +31 -0
  1333. package/src/theme/index.tsx +105 -0
  1334. package/src/theme/type.ts +50 -0
  1335. package/src/utils/appVersionHTML.ts +28 -0
  1336. package/src/utils/globalDeps.ts +107 -0
  1337. package/src/utils/index.tsx +10 -4
  1338. package/src/utils/remotePlugins.ts +131 -48
  1339. package/src/utils/requirejs.ts +1 -1
  1340. package/lib/Application.d.ts +0 -124
  1341. package/lib/Application.js +0 -489
  1342. package/lib/MockApplication.js +0 -96
  1343. package/lib/Plugin.d.ts +0 -33
  1344. package/lib/Plugin.js +0 -89
  1345. package/lib/PluginManager.d.ts +0 -46
  1346. package/lib/PluginManager.js +0 -114
  1347. package/lib/PluginSettingsManager.d.ts +0 -67
  1348. package/lib/PluginSettingsManager.js +0 -148
  1349. package/lib/RouterManager.js +0 -198
  1350. package/lib/WebSocketClient.js +0 -217
  1351. package/lib/components/BlankComponent.js +0 -48
  1352. package/lib/components/MainComponent.js +0 -54
  1353. package/lib/components/RouterBridge.js +0 -66
  1354. package/lib/components/RouterContextCleaner.js +0 -61
  1355. package/lib/components/index.js +0 -32
  1356. package/lib/context.js +0 -38
  1357. package/lib/hooks/index.js +0 -34
  1358. package/lib/hooks/useApp.js +0 -41
  1359. package/lib/hooks/usePlugin.js +0 -42
  1360. package/lib/hooks/useRouter.js +0 -41
  1361. package/lib/utils/index.js +0 -79
  1362. package/lib/utils/remotePlugins.js +0 -131
  1363. package/lib/utils/requirejs.js +0 -1361
  1364. package/lib/utils/types.js +0 -28
  1365. /package/{lib → es}/MockApplication.d.ts +0 -0
  1366. /package/{lib → es}/components/BlankComponent.d.ts +0 -0
  1367. /package/{lib → es}/components/MainComponent.d.ts +0 -0
  1368. /package/{lib → es}/components/RouterContextCleaner.d.ts +0 -0
  1369. /package/{lib → es}/context.d.ts +0 -0
  1370. /package/{lib → es}/utils/requirejs.d.ts +0 -0
  1371. /package/{lib → es}/utils/types.d.ts +0 -0
@@ -0,0 +1,2341 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
12
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
13
+ import { FlowEngine, FlowEngineProvider } from '@nocobase/flow-engine';
14
+ import { observer } from '@nocobase/flow-engine';
15
+ import { MemoryRouter } from 'react-router-dom';
16
+ import { NocoBaseDesktopRouteType } from '../../../../flow-compat';
17
+ import {
18
+ AdminLayoutMenuItemRenderer,
19
+ AdminLayoutMenuItemModel,
20
+ AdminLayoutModel,
21
+ ADMIN_LAYOUT_MODEL_UID,
22
+ getAdminLayoutMenuMovePositionOptions,
23
+ normalizeAdminLayoutMenuLegacyVariables,
24
+ openAdminLayoutMenuLink,
25
+ resolveAdminLayoutMenuLink,
26
+ resolveAdminLayoutMenuDragMoveOptionsFromEvent,
27
+ resolveAdminLayoutMenuDragMoveOptions,
28
+ } from '..';
29
+
30
+ const { navigateMock } = vi.hoisted(() => ({
31
+ navigateMock: vi.fn(),
32
+ }));
33
+
34
+ vi.mock('../../../../application/CustomRouterContextProvider', async (importOriginal) => {
35
+ const actual = await importOriginal<typeof import('@nocobase/client/src/application/CustomRouterContextProvider')>();
36
+ return {
37
+ ...actual,
38
+ useNavigateNoUpdate: () => navigateMock,
39
+ useRouterBasename: () => '/apps/demo',
40
+ };
41
+ });
42
+
43
+ describe('AdminLayoutModel menu items', () => {
44
+ let engine: FlowEngine;
45
+ let modalConfirmMock: ReturnType<typeof vi.fn>;
46
+
47
+ beforeEach(() => {
48
+ // Fixtures mount the modern client under the `v2` segment; tell the
49
+ // runtime-prefix helper so v2-runtime detection matches.
50
+ (globalThis.window as any).__nocobase_modern_client_prefix__ = 'v2';
51
+ engine = new FlowEngine();
52
+ modalConfirmMock = vi.fn().mockResolvedValue(true);
53
+ engine.registerModels({
54
+ AdminLayoutModel,
55
+ AdminLayoutMenuItemModel,
56
+ });
57
+ engine.context.defineProperty('routeRepository', {
58
+ value: {
59
+ listAccessible: () => [],
60
+ createRoute: vi.fn(),
61
+ updateRoute: vi.fn(),
62
+ deleteRoute: vi.fn(),
63
+ moveRoute: vi.fn(),
64
+ refreshAccessible: vi.fn(),
65
+ },
66
+ });
67
+ engine.context.defineProperty('api', {
68
+ value: {
69
+ auth: {
70
+ role: 'admin',
71
+ token: 'token-1',
72
+ },
73
+ request: vi.fn(),
74
+ resource: vi.fn(() => ({})),
75
+ },
76
+ });
77
+ engine.context.defineProperty('router', {
78
+ value: {
79
+ navigate: vi.fn(),
80
+ },
81
+ });
82
+ engine.context.defineProperty('location', {
83
+ value: {
84
+ pathname: '/admin/current-page',
85
+ search: '?from=header',
86
+ },
87
+ });
88
+ engine.context.defineProperty('app', {
89
+ value: {
90
+ getPublicPath: () => '/apps/demo/v2/',
91
+ router: {
92
+ getBasename: () => '/apps/demo/v2',
93
+ },
94
+ components: {},
95
+ scopes: {},
96
+ },
97
+ });
98
+ engine.context.defineProperty('modal', {
99
+ value: {
100
+ confirm: modalConfirmMock,
101
+ },
102
+ });
103
+ engine.context.defineProperty('t', {
104
+ value: (text) => text,
105
+ });
106
+ navigateMock.mockReset();
107
+ vi.spyOn(window, 'open').mockImplementation(() => null);
108
+ });
109
+
110
+ afterEach(() => {
111
+ delete (globalThis.window as any).__nocobase_modern_client_prefix__;
112
+ });
113
+
114
+ const createRoute = (options?: Partial<import('../../../../flow-compat').NocoBaseDesktopRoute>) => ({
115
+ id: 1,
116
+ title: 'Page 1',
117
+ schemaUid: 'page-1',
118
+ type: NocoBaseDesktopRouteType.page,
119
+ ...options,
120
+ });
121
+
122
+ it('should normalize legacy variables only inside template expressions', () => {
123
+ expect(normalizeAdminLayoutMenuLegacyVariables('https://a.com?id={{ $user.id }}')).toBe(
124
+ 'https://a.com?id={{ ctx.user.id }}',
125
+ );
126
+ expect(normalizeAdminLayoutMenuLegacyVariables('prefix-{{ currentUser.name }}-{{ $nRole }}')).toBe(
127
+ 'prefix-{{ ctx.user.name }}-{{ ctx.role }}',
128
+ );
129
+ expect(normalizeAdminLayoutMenuLegacyVariables('https://a.com/currentUser/profile')).toBe(
130
+ 'https://a.com/currentUser/profile',
131
+ );
132
+ });
133
+
134
+ it('should resolve admin-layout link with FlowContext variables', async () => {
135
+ engine.context.defineProperty('user', {
136
+ value: {
137
+ id: 7,
138
+ name: 'Jane',
139
+ },
140
+ });
141
+
142
+ const result = await resolveAdminLayoutMenuLink({
143
+ context: engine.context as any,
144
+ href: 'https://www.nocobase.com/docs?role={{ ctx.role }}',
145
+ params: [
146
+ { name: 'userId', value: '{{ ctx.user.id }}' },
147
+ { name: 'userName', value: 'user-{{ ctx.user.name }}' },
148
+ ],
149
+ });
150
+
151
+ expect(result).toBe('https://www.nocobase.com/docs?role=admin&userId=7&userName=user-Jane');
152
+ });
153
+
154
+ it('should keep legacy variable syntax working in admin-layout link parser', async () => {
155
+ engine.context.defineProperty('user', {
156
+ value: {
157
+ id: 9,
158
+ },
159
+ });
160
+
161
+ const result = await resolveAdminLayoutMenuLink({
162
+ context: engine.context as any,
163
+ href: 'https://www.nocobase.com/docs',
164
+ params: [
165
+ { name: 'userId', value: '{{ $user.id }}' },
166
+ { name: 'legacyUserId', value: '{{ currentUser.id }}' },
167
+ { name: 'role', value: '{{ $nRole }}' },
168
+ { name: 'token', value: '{{ $nToken }}' },
169
+ { name: 'from', value: '{{ $nURLSearchParams.from }}' },
170
+ ],
171
+ });
172
+
173
+ expect(result).toBe('https://www.nocobase.com/docs?userId=9&legacyUserId=9&role=admin&token=token-1&from=header');
174
+ });
175
+
176
+ it('should keep falsy values except null and undefined in query params', async () => {
177
+ const result = await resolveAdminLayoutMenuLink({
178
+ context: engine.context as any,
179
+ href: 'https://www.nocobase.com/docs',
180
+ params: [
181
+ { name: 'zero', value: 0 },
182
+ { name: 'bool', value: false },
183
+ { name: 'empty', value: '' },
184
+ { name: 'nil', value: null },
185
+ { name: 'undef', value: undefined },
186
+ ],
187
+ });
188
+
189
+ expect(result).toBe('https://www.nocobase.com/docs?zero=0&bool=false&empty=');
190
+ });
191
+
192
+ it('should append query params into hash route url', async () => {
193
+ engine.context.defineProperty('role', {
194
+ value: 'admin',
195
+ });
196
+
197
+ const result = await resolveAdminLayoutMenuLink({
198
+ context: engine.context as any,
199
+ href: '/admin#/?tab=1',
200
+ params: [{ name: 'role', value: '{{ ctx.role }}' }],
201
+ });
202
+
203
+ expect(result).toBe('/admin#/?tab=1&role=admin');
204
+ });
205
+
206
+ it('should sync route tree into menuItems subModels and cleanup stale branches', () => {
207
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
208
+ uid: 'admin-layout-model',
209
+ use: AdminLayoutModel,
210
+ });
211
+
212
+ adminLayoutModel.syncMenuRoutes([
213
+ {
214
+ id: 1,
215
+ title: 'Group',
216
+ type: NocoBaseDesktopRouteType.group,
217
+ children: [
218
+ {
219
+ id: 11,
220
+ title: 'Page 1',
221
+ schemaUid: 'page-1',
222
+ type: NocoBaseDesktopRouteType.flowPage,
223
+ },
224
+ ],
225
+ },
226
+ {
227
+ id: 2,
228
+ title: 'Link',
229
+ type: NocoBaseDesktopRouteType.link,
230
+ },
231
+ ]);
232
+
233
+ expect(adminLayoutModel.subModels.menuItems).toHaveLength(2);
234
+ expect(adminLayoutModel.subModels.menuItems?.[0]).toBeInstanceOf(AdminLayoutMenuItemModel);
235
+ expect(adminLayoutModel.subModels.menuItems?.[0].subModels.menuItems).toHaveLength(1);
236
+ expect(adminLayoutModel.subModels.menuItems?.[0].subModels.menuItems?.[0].props.route).toMatchObject({
237
+ title: 'Page 1',
238
+ schemaUid: 'page-1',
239
+ });
240
+
241
+ const staleGroupUid = adminLayoutModel.subModels.menuItems?.[0].uid;
242
+
243
+ adminLayoutModel.syncMenuRoutes([
244
+ {
245
+ id: 2,
246
+ title: 'Link',
247
+ type: NocoBaseDesktopRouteType.link,
248
+ },
249
+ ]);
250
+
251
+ expect(adminLayoutModel.subModels.menuItems).toHaveLength(1);
252
+ expect(adminLayoutModel.subModels.menuItems?.[0].props.route).toMatchObject({
253
+ title: 'Link',
254
+ type: NocoBaseDesktopRouteType.link,
255
+ });
256
+ expect(engine.getModel(staleGroupUid)).toBeUndefined();
257
+ });
258
+
259
+ it('should generate ProLayout route tree from menu models', () => {
260
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
261
+ uid: 'admin-layout-model',
262
+ use: AdminLayoutModel,
263
+ });
264
+
265
+ adminLayoutModel.syncMenuRoutes([
266
+ {
267
+ id: 1,
268
+ title: 'Group',
269
+ type: NocoBaseDesktopRouteType.group,
270
+ children: [
271
+ {
272
+ id: 11,
273
+ title: 'Page 1',
274
+ schemaUid: 'page-1',
275
+ type: NocoBaseDesktopRouteType.flowPage,
276
+ },
277
+ ],
278
+ },
279
+ {
280
+ id: 2,
281
+ title: 'Link',
282
+ type: NocoBaseDesktopRouteType.link,
283
+ },
284
+ ]);
285
+
286
+ const route = adminLayoutModel.toProLayoutRoute({
287
+ designable: false,
288
+ isMobile: false,
289
+ t: (title) => title,
290
+ });
291
+
292
+ expect(route.path).toBe('/');
293
+ expect(route.children).toHaveLength(2);
294
+ expect(route.children[0].path).toBe('/admin/1');
295
+ expect(route.children[0].redirect).toBe('/admin/page-1');
296
+ expect(route.children[0]._runtimePath).toBe('/apps/demo/v2/admin/page-1');
297
+ expect(route.children[0]._navigationMode).toBe('spa');
298
+ expect(route.children[0]._isLegacy).toBe(false);
299
+ expect(route.children[0]._depth).toBe(0);
300
+ expect(route.children[0]._route).toMatchObject({ id: 1, type: NocoBaseDesktopRouteType.group });
301
+ expect(route.children[0]._model).toBe(adminLayoutModel.subModels.menuItems?.[0]);
302
+ expect(route.children[0].routes).toHaveLength(1);
303
+ expect(route.children[0].routes?.[0].path).toBe('/admin/page-1');
304
+ expect(route.children[0].routes?.[0].redirect).toBe('/admin/page-1');
305
+ expect(route.children[0].routes?.[0]._runtimePath).toBe('/apps/demo/v2/admin/page-1');
306
+ expect(route.children[0].routes?.[0]._navigationMode).toBe('spa');
307
+ expect(route.children[0].routes?.[0]._depth).toBe(1);
308
+ expect(route.children[0].routes?.[0]._route).toMatchObject({
309
+ schemaUid: 'page-1',
310
+ type: NocoBaseDesktopRouteType.flowPage,
311
+ });
312
+ expect(route.children[0].routes?.[0]._model).toBe(
313
+ adminLayoutModel.subModels.menuItems?.[0].subModels.menuItems?.[0],
314
+ );
315
+ expect(route.children[1].path).toBe('/admin/__admin_layout__/link/2');
316
+ expect(route.children[1]._depth).toBe(0);
317
+ expect(route.children[1]._route).toMatchObject({ id: 2, type: NocoBaseDesktopRouteType.link });
318
+ expect(route.children[1]._model).toBe(adminLayoutModel.subModels.menuItems?.[1]);
319
+ });
320
+
321
+ it('should filter legacy page menu routes but keep empty groups in v2 admin layout', () => {
322
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
323
+ uid: 'admin-layout-model',
324
+ use: AdminLayoutModel,
325
+ });
326
+
327
+ adminLayoutModel.syncMenuRoutes([
328
+ {
329
+ id: 1,
330
+ title: 'Legacy page',
331
+ schemaUid: 'legacy-page',
332
+ type: NocoBaseDesktopRouteType.page,
333
+ },
334
+ {
335
+ id: 2,
336
+ title: 'Legacy only group',
337
+ type: NocoBaseDesktopRouteType.group,
338
+ children: [
339
+ {
340
+ id: 21,
341
+ title: 'Nested legacy page',
342
+ schemaUid: 'nested-legacy-page',
343
+ type: NocoBaseDesktopRouteType.page,
344
+ },
345
+ ],
346
+ },
347
+ {
348
+ id: 3,
349
+ title: 'Mixed group',
350
+ type: NocoBaseDesktopRouteType.group,
351
+ children: [
352
+ {
353
+ id: 31,
354
+ title: 'Nested legacy page',
355
+ schemaUid: 'nested-legacy-page-2',
356
+ type: NocoBaseDesktopRouteType.page,
357
+ },
358
+ {
359
+ id: 32,
360
+ title: 'Nested flow page',
361
+ schemaUid: 'nested-flow-page',
362
+ type: NocoBaseDesktopRouteType.flowPage,
363
+ },
364
+ ],
365
+ },
366
+ {
367
+ id: 4,
368
+ title: 'Link',
369
+ type: NocoBaseDesktopRouteType.link,
370
+ },
371
+ ]);
372
+
373
+ const route = adminLayoutModel.toProLayoutRoute({
374
+ designable: false,
375
+ isMobile: false,
376
+ t: (title) => title,
377
+ });
378
+
379
+ expect(route.children).toHaveLength(3);
380
+ expect(route.children[0]).toMatchObject({
381
+ path: '/admin/2',
382
+ redirect: '/admin/2',
383
+ _runtimePath: null,
384
+ _navigationMode: 'spa',
385
+ _isLegacy: false,
386
+ });
387
+ expect(route.children[0].routes).toBeUndefined();
388
+ expect(route.children[1]).toMatchObject({
389
+ path: '/admin/3',
390
+ redirect: '/admin/nested-flow-page',
391
+ _runtimePath: '/apps/demo/v2/admin/nested-flow-page',
392
+ _navigationMode: 'spa',
393
+ _isLegacy: false,
394
+ });
395
+ expect(route.children[1].routes).toHaveLength(1);
396
+ expect(route.children[1].routes?.[0]).toMatchObject({
397
+ path: '/admin/nested-flow-page',
398
+ _runtimePath: '/apps/demo/v2/admin/nested-flow-page',
399
+ _navigationMode: 'spa',
400
+ _isLegacy: false,
401
+ });
402
+ expect(route.children[2]).toMatchObject({
403
+ path: '/admin/__admin_layout__/link/4',
404
+ });
405
+ });
406
+
407
+ it('should resolve modern flowPage menu runtime target to v2 path', () => {
408
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
409
+ uid: 'menu-item-flow-page',
410
+ use: AdminLayoutMenuItemModel,
411
+ props: {
412
+ route: {
413
+ id: 1,
414
+ title: 'Flow page',
415
+ schemaUid: 'flow-page-1',
416
+ type: NocoBaseDesktopRouteType.flowPage,
417
+ },
418
+ },
419
+ });
420
+
421
+ expect(
422
+ model.toProLayoutRoute({
423
+ designable: false,
424
+ isMobile: false,
425
+ t: (title) => title,
426
+ }),
427
+ ).toMatchObject({
428
+ _runtimePath: '/apps/demo/v2/admin/flow-page-1',
429
+ _navigationMode: 'spa',
430
+ _isLegacy: false,
431
+ });
432
+ });
433
+
434
+ it('should keep sub app page menu runtime target inside spa when basename does not include /v2/', () => {
435
+ engine.context.defineProperty('app', {
436
+ value: {
437
+ getPublicPath: () => '/apps/demo/',
438
+ router: {
439
+ getBasename: () => '/apps/demo',
440
+ },
441
+ components: {},
442
+ scopes: {},
443
+ },
444
+ });
445
+
446
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
447
+ uid: 'menu-item-sub-app-page',
448
+ use: AdminLayoutMenuItemModel,
449
+ props: {
450
+ route: {
451
+ id: 1,
452
+ title: 'Sub app page',
453
+ schemaUid: 'sub-app-page-1',
454
+ type: NocoBaseDesktopRouteType.page,
455
+ },
456
+ },
457
+ });
458
+
459
+ expect(
460
+ model.toProLayoutRoute({
461
+ designable: false,
462
+ isMobile: false,
463
+ t: (title) => title,
464
+ }),
465
+ ).toMatchObject({
466
+ _runtimePath: '/apps/demo/admin/sub-app-page-1',
467
+ _navigationMode: 'spa',
468
+ _isLegacy: false,
469
+ });
470
+ });
471
+
472
+ it('should not guess runtime path when page schemaUid is missing', () => {
473
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
474
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
475
+ uid: 'menu-item-missing-schema',
476
+ use: AdminLayoutMenuItemModel,
477
+ props: {
478
+ route: {
479
+ id: 1,
480
+ title: 'Broken page',
481
+ type: NocoBaseDesktopRouteType.page,
482
+ },
483
+ },
484
+ });
485
+
486
+ expect(
487
+ model.toProLayoutRoute({
488
+ designable: false,
489
+ isMobile: false,
490
+ t: (title) => title,
491
+ }),
492
+ ).toMatchObject({
493
+ _runtimePath: null,
494
+ disabled: true,
495
+ });
496
+ expect(warn).toHaveBeenCalledWith(
497
+ '[NocoBase] Admin route runtime target:',
498
+ 'Missing schemaUid.',
499
+ expect.objectContaining({ type: NocoBaseDesktopRouteType.page }),
500
+ );
501
+ });
502
+
503
+ it('should render document menu item as native anchor and use assign on left click', () => {
504
+ const assign = vi.fn();
505
+ Object.defineProperty(window, 'location', {
506
+ configurable: true,
507
+ value: {
508
+ ...window.location,
509
+ assign,
510
+ },
511
+ });
512
+
513
+ render(
514
+ React.createElement(
515
+ FlowEngineProvider,
516
+ { engine },
517
+ React.createElement(
518
+ MemoryRouter,
519
+ { initialEntries: ['/admin/current-page'] },
520
+ React.createElement(AdminLayoutMenuItemRenderer, {
521
+ renderType: 'item',
522
+ item: {
523
+ name: 'Legacy page',
524
+ path: '/admin/legacy-page',
525
+ _runtimePath: '/apps/demo/admin/legacy-page',
526
+ _navigationMode: 'document',
527
+ _isLegacy: true,
528
+ _route: {
529
+ type: NocoBaseDesktopRouteType.page,
530
+ title: 'Legacy page',
531
+ schemaUid: 'legacy-page',
532
+ options: {},
533
+ },
534
+ _model: { context: engine.context } as any,
535
+ },
536
+ dom: React.createElement('span', null, 'Legacy page'),
537
+ options: { isMobile: false, collapsed: false },
538
+ }),
539
+ ),
540
+ ),
541
+ );
542
+
543
+ const link = screen.getByRole('link', { name: 'Legacy page' });
544
+ expect(link).toHaveAttribute('href', '/apps/demo/admin/legacy-page');
545
+
546
+ fireEvent.click(link, { button: 0 });
547
+
548
+ return waitFor(() => {
549
+ expect(assign).toHaveBeenCalledWith('/apps/demo/admin/legacy-page');
550
+ expect(modalConfirmMock).not.toHaveBeenCalled();
551
+ expect(navigateMock).not.toHaveBeenCalled();
552
+ });
553
+ });
554
+
555
+ it('should keep native anchor behavior for modifier click on legacy menu item', () => {
556
+ vi.useFakeTimers();
557
+ const assign = vi.fn();
558
+ Object.defineProperty(window, 'location', {
559
+ configurable: true,
560
+ value: {
561
+ ...window.location,
562
+ assign,
563
+ },
564
+ });
565
+
566
+ render(
567
+ React.createElement(
568
+ FlowEngineProvider,
569
+ { engine },
570
+ React.createElement(
571
+ MemoryRouter,
572
+ { initialEntries: ['/admin/current-page'] },
573
+ React.createElement(AdminLayoutMenuItemRenderer, {
574
+ renderType: 'item',
575
+ item: {
576
+ name: 'Legacy page',
577
+ path: '/admin/legacy-page',
578
+ _runtimePath: '/apps/demo/admin/legacy-page',
579
+ _navigationMode: 'document',
580
+ _isLegacy: true,
581
+ _route: {
582
+ type: NocoBaseDesktopRouteType.page,
583
+ title: 'Legacy page',
584
+ schemaUid: 'legacy-page',
585
+ options: {},
586
+ },
587
+ _model: { context: engine.context } as any,
588
+ },
589
+ dom: React.createElement('span', null, 'Legacy page'),
590
+ options: { isMobile: false, collapsed: false },
591
+ }),
592
+ ),
593
+ ),
594
+ );
595
+
596
+ try {
597
+ fireEvent.click(screen.getByRole('link', { name: 'Legacy page' }), { metaKey: true, button: 0 });
598
+
599
+ expect(assign).not.toHaveBeenCalled();
600
+ expect(navigateMock).not.toHaveBeenCalled();
601
+ expect(modalConfirmMock).not.toHaveBeenCalled();
602
+ vi.clearAllTimers();
603
+ } finally {
604
+ vi.useRealTimers();
605
+ }
606
+ });
607
+
608
+ it('should not ask for confirmation before document navigation', async () => {
609
+ modalConfirmMock.mockResolvedValue(false);
610
+ const assign = vi.fn();
611
+ Object.defineProperty(window, 'location', {
612
+ configurable: true,
613
+ value: {
614
+ ...window.location,
615
+ assign,
616
+ },
617
+ });
618
+
619
+ render(
620
+ React.createElement(
621
+ FlowEngineProvider,
622
+ { engine },
623
+ React.createElement(
624
+ MemoryRouter,
625
+ { initialEntries: ['/admin/current-page'] },
626
+ React.createElement(AdminLayoutMenuItemRenderer, {
627
+ renderType: 'item',
628
+ item: {
629
+ name: 'Legacy page',
630
+ path: '/admin/legacy-page',
631
+ _runtimePath: '/apps/demo/admin/legacy-page',
632
+ _navigationMode: 'document',
633
+ _isLegacy: true,
634
+ _route: {
635
+ type: NocoBaseDesktopRouteType.page,
636
+ title: 'Legacy page',
637
+ schemaUid: 'legacy-page',
638
+ options: {},
639
+ },
640
+ _model: { context: engine.context } as any,
641
+ },
642
+ dom: React.createElement('span', null, 'Legacy page'),
643
+ options: { isMobile: false, collapsed: false },
644
+ }),
645
+ ),
646
+ ),
647
+ );
648
+
649
+ fireEvent.click(screen.getByRole('link', { name: 'Legacy page' }), { button: 0 });
650
+
651
+ await waitFor(() => {
652
+ expect(assign).toHaveBeenCalledWith('/apps/demo/admin/legacy-page');
653
+ });
654
+ expect(modalConfirmMock).not.toHaveBeenCalled();
655
+ expect(navigateMock).not.toHaveBeenCalled();
656
+ });
657
+
658
+ it('should render modern menu item with router internal href under basename', () => {
659
+ render(
660
+ React.createElement(
661
+ FlowEngineProvider,
662
+ { engine },
663
+ React.createElement(
664
+ MemoryRouter,
665
+ { initialEntries: ['/admin/current-page'] },
666
+ React.createElement(AdminLayoutMenuItemRenderer, {
667
+ renderType: 'item',
668
+ item: {
669
+ name: 'Flow page',
670
+ path: '/admin/flow-page-1',
671
+ _runtimePath: '/apps/demo/v2/admin/flow-page-1',
672
+ _navigationMode: 'spa',
673
+ _isLegacy: false,
674
+ _route: {
675
+ type: NocoBaseDesktopRouteType.flowPage,
676
+ title: 'Flow page',
677
+ schemaUid: 'flow-page-1',
678
+ options: {},
679
+ },
680
+ },
681
+ dom: React.createElement('span', null, 'Flow page'),
682
+ options: { isMobile: false, collapsed: false },
683
+ }),
684
+ ),
685
+ ),
686
+ );
687
+
688
+ expect(screen.getByRole('link', { name: 'Flow page' })).toHaveAttribute('href', '/apps/demo/v2/admin/flow-page-1');
689
+ });
690
+
691
+ it('should render legacy group target as native anchor', () => {
692
+ render(
693
+ React.createElement(
694
+ FlowEngineProvider,
695
+ { engine },
696
+ React.createElement(
697
+ MemoryRouter,
698
+ { initialEntries: ['/admin/current-page'] },
699
+ React.createElement(AdminLayoutMenuItemRenderer, {
700
+ renderType: 'group',
701
+ item: {
702
+ name: 'Legacy group',
703
+ path: '/admin/group-1',
704
+ _runtimePath: '/apps/demo/admin/legacy-page',
705
+ _navigationMode: 'document',
706
+ _isLegacy: true,
707
+ _route: {
708
+ type: NocoBaseDesktopRouteType.group,
709
+ title: 'Legacy group',
710
+ schemaUid: 'group-1',
711
+ options: {},
712
+ },
713
+ _model: { context: engine.context } as any,
714
+ },
715
+ dom: React.createElement('span', null, 'Legacy group'),
716
+ options: { isMobile: false, collapsed: false },
717
+ }),
718
+ ),
719
+ ),
720
+ );
721
+
722
+ expect(screen.queryByRole('link', { name: 'Legacy group' })).toBeNull();
723
+ expect(screen.getByRole('link', { name: 'Legacy group-landing-entry' })).toHaveAttribute(
724
+ 'href',
725
+ '/apps/demo/admin/legacy-page',
726
+ );
727
+ });
728
+
729
+ it('should navigate legacy group only through explicit landing entry', () => {
730
+ const assign = vi.fn();
731
+ Object.defineProperty(window, 'location', {
732
+ configurable: true,
733
+ value: {
734
+ ...window.location,
735
+ assign,
736
+ },
737
+ });
738
+
739
+ render(
740
+ React.createElement(
741
+ FlowEngineProvider,
742
+ { engine },
743
+ React.createElement(
744
+ MemoryRouter,
745
+ { initialEntries: ['/admin/current-page'] },
746
+ React.createElement(AdminLayoutMenuItemRenderer, {
747
+ renderType: 'group',
748
+ item: {
749
+ name: 'Legacy group',
750
+ path: '/admin/group-1',
751
+ _runtimePath: '/apps/demo/admin/legacy-page',
752
+ _navigationMode: 'document',
753
+ _isLegacy: true,
754
+ _route: {
755
+ type: NocoBaseDesktopRouteType.group,
756
+ title: 'Legacy group',
757
+ schemaUid: 'group-1',
758
+ options: {},
759
+ },
760
+ _model: { context: engine.context } as any,
761
+ },
762
+ dom: React.createElement('span', null, 'Legacy group'),
763
+ options: { isMobile: false, collapsed: false },
764
+ }),
765
+ ),
766
+ ),
767
+ );
768
+
769
+ fireEvent.click(screen.getByText('Legacy group'));
770
+ expect(assign).not.toHaveBeenCalled();
771
+
772
+ fireEvent.click(screen.getByRole('link', { name: 'Legacy group-landing-entry' }), { button: 0 });
773
+ return waitFor(() => {
774
+ expect(assign).toHaveBeenCalledWith('/apps/demo/admin/legacy-page');
775
+ expect(modalConfirmMock).not.toHaveBeenCalled();
776
+ });
777
+ });
778
+
779
+ it('should render modern group landing entry with v2 href', () => {
780
+ render(
781
+ React.createElement(
782
+ FlowEngineProvider,
783
+ { engine },
784
+ React.createElement(
785
+ MemoryRouter,
786
+ { initialEntries: ['/admin/current-page'] },
787
+ React.createElement(AdminLayoutMenuItemRenderer, {
788
+ renderType: 'group',
789
+ item: {
790
+ name: 'Flow group',
791
+ path: '/admin/group-2',
792
+ _runtimePath: '/apps/demo/v2/admin/flow-page-1',
793
+ _navigationMode: 'spa',
794
+ _isLegacy: false,
795
+ _route: {
796
+ type: NocoBaseDesktopRouteType.group,
797
+ title: 'Flow group',
798
+ schemaUid: 'group-2',
799
+ options: {},
800
+ },
801
+ },
802
+ dom: React.createElement('span', null, 'Flow group'),
803
+ options: { isMobile: false, collapsed: false },
804
+ }),
805
+ ),
806
+ ),
807
+ );
808
+
809
+ expect(screen.getByRole('link', { name: 'Flow group-landing-entry' })).toHaveAttribute(
810
+ 'href',
811
+ '/apps/demo/v2/admin/flow-page-1',
812
+ );
813
+ });
814
+
815
+ it('should insert designer buttons in expected positions', () => {
816
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
817
+ uid: 'admin-layout-model',
818
+ use: AdminLayoutModel,
819
+ });
820
+
821
+ adminLayoutModel.syncMenuRoutes([
822
+ {
823
+ id: 1,
824
+ title: 'Group',
825
+ type: NocoBaseDesktopRouteType.group,
826
+ children: [
827
+ {
828
+ id: 11,
829
+ title: 'Page 1',
830
+ schemaUid: 'page-1',
831
+ type: NocoBaseDesktopRouteType.flowPage,
832
+ },
833
+ ],
834
+ },
835
+ ]);
836
+
837
+ const desktopRoute = adminLayoutModel.toProLayoutRoute({
838
+ designable: true,
839
+ isMobile: false,
840
+ t: (title) => title,
841
+ });
842
+
843
+ expect(desktopRoute.children[0].key).toBe('x-designer-button');
844
+ expect(desktopRoute.children[0].path).toBe('/admin/__admin_layout__/designer/admin-layout-model');
845
+ expect(React.isValidElement(desktopRoute.children[0].name)).toBe(true);
846
+ expect(desktopRoute.children[1].routes?.[1].key).toBe('x-designer-button');
847
+ expect(desktopRoute.children[1].routes?.[1].path).toBe('/admin/__admin_layout__/designer/1');
848
+
849
+ const mobileRoute = adminLayoutModel.toProLayoutRoute({
850
+ designable: true,
851
+ isMobile: true,
852
+ t: (title) => title,
853
+ });
854
+
855
+ expect(mobileRoute.children[mobileRoute.children.length - 1].key).toBe('x-designer-button');
856
+ expect(mobileRoute.children[mobileRoute.children.length - 1].path).toBe(
857
+ '/admin/__admin_layout__/designer/admin-layout-model',
858
+ );
859
+ expect(mobileRoute.children[0].routes?.[1].key).toBe('x-designer-button');
860
+ expect(mobileRoute.children[0].routes?.[1].path).toBe('/admin/__admin_layout__/designer/1');
861
+ expect(desktopRoute.children[0]._launcherModel).toBe(adminLayoutModel);
862
+ expect(desktopRoute.children[1].routes?.[1]._launcherModel).toBe(adminLayoutModel.subModels.menuItems?.[0]);
863
+ });
864
+
865
+ it('should update ProLayout route result after menuItems sync in observer render', async () => {
866
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
867
+ uid: 'admin-layout-model',
868
+ use: AdminLayoutModel,
869
+ });
870
+
871
+ const RouteReader = observer(() => {
872
+ const route = adminLayoutModel.toProLayoutRoute({
873
+ designable: true,
874
+ isMobile: false,
875
+ t: (title) => title,
876
+ });
877
+
878
+ return React.createElement('div', { 'data-testid': 'route-length' }, String(route.children.length));
879
+ });
880
+
881
+ render(React.createElement(RouteReader));
882
+
883
+ expect(screen.getByTestId('route-length').textContent).toBe('1');
884
+
885
+ act(() => {
886
+ adminLayoutModel.syncMenuRoutes([
887
+ {
888
+ id: 1,
889
+ title: 'Page 1',
890
+ schemaUid: 'page-1',
891
+ type: NocoBaseDesktopRouteType.flowPage,
892
+ },
893
+ ]);
894
+ });
895
+
896
+ await waitFor(() => {
897
+ expect(screen.getByTestId('route-length').textContent).toBe('2');
898
+ });
899
+ });
900
+
901
+ it('should expose menu linkage rules only for existing menu items', async () => {
902
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
903
+ expect(menuSettingsFlow?.steps?.hidden).toBeUndefined();
904
+ expect(menuSettingsFlow?.steps?.linkageRules?.use).toBe('menuLinkageRules');
905
+
906
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
907
+ uid: 'menu-item-linkage-settings',
908
+ use: AdminLayoutMenuItemModel,
909
+ props: {
910
+ route: createRoute(),
911
+ },
912
+ });
913
+ const creationModel = engine.createModel<AdminLayoutMenuItemModel>({
914
+ uid: 'menu-item-linkage-creation-settings',
915
+ use: AdminLayoutMenuItemModel,
916
+ props: {
917
+ creationMeta: {
918
+ menuType: 'link',
919
+ source: 'header',
920
+ },
921
+ },
922
+ });
923
+ const hideInSettings = menuSettingsFlow?.steps?.linkageRules?.hideInSettings as
924
+ | ((ctx: any) => Promise<boolean>)
925
+ | undefined;
926
+
927
+ await expect(hideInSettings?.({ model })).resolves.toBe(false);
928
+ await expect(hideInSettings?.({ model: creationModel })).resolves.toBe(true);
929
+ });
930
+
931
+ it('should persist menu linkage rules through flowModels and route flag', async () => {
932
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
933
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
934
+ engine.context.routeRepository.updateRoute = updateRoute;
935
+
936
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
937
+ uid: 'menu-item-linkage-persist',
938
+ use: AdminLayoutMenuItemModel,
939
+ props: {
940
+ route: createRoute(),
941
+ },
942
+ });
943
+
944
+ model.setStepParams('menuSettings', 'linkageRules', {
945
+ value: [
946
+ { key: 'r1', title: 'Hide menu item', enable: true, condition: { logic: '$and', items: [] }, actions: [] },
947
+ ],
948
+ });
949
+
950
+ await model.saveStepParams();
951
+
952
+ expect(saveModel).toHaveBeenCalledWith(model, { onlyStepParams: true });
953
+ expect(updateRoute).toHaveBeenCalledWith(1, {
954
+ options: {
955
+ hasPersistedMenuInstanceFlow: true,
956
+ },
957
+ });
958
+ });
959
+
960
+ it('should save menu linkage rules without serializing runtime render props', async () => {
961
+ type SerializedFlowModel = Record<string, unknown> & {
962
+ props?: Record<string, unknown>;
963
+ subModels?: unknown;
964
+ };
965
+ const save = vi.fn(
966
+ async (targetModel: { serialize: () => SerializedFlowModel }, options?: { onlyStepParams?: boolean }) => {
967
+ const data = targetModel.serialize();
968
+ if (options?.onlyStepParams) {
969
+ delete data.subModels;
970
+ }
971
+
972
+ expect(data.props?.item).toBeUndefined();
973
+ expect(data.props?.dom).toBeUndefined();
974
+ expect(data.props?.options).toBeUndefined();
975
+ expect(data.props?.renderType).toBeUndefined();
976
+ expect(() => JSON.stringify(data)).not.toThrow();
977
+ return data;
978
+ },
979
+ );
980
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
981
+ engine.setModelRepository({ save } as Parameters<FlowEngine['setModelRepository']>[0]);
982
+ engine.context.routeRepository.updateRoute = updateRoute;
983
+
984
+ const route = createRoute();
985
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
986
+ uid: 'menu-item-linkage-runtime-props',
987
+ use: AdminLayoutMenuItemModel,
988
+ props: {
989
+ route,
990
+ },
991
+ });
992
+ const item = {
993
+ name: 'Page 1',
994
+ path: '/admin/page-1',
995
+ _route: route,
996
+ _model: model,
997
+ };
998
+
999
+ model.setProps({
1000
+ item,
1001
+ dom: React.createElement('span', null, 'Page 1'),
1002
+ renderType: 'item',
1003
+ options: { collapsed: false },
1004
+ });
1005
+ model.setStepParams('menuSettings', 'linkageRules', {
1006
+ value: [
1007
+ {
1008
+ key: 'r1',
1009
+ title: 'Hide menu item',
1010
+ enable: true,
1011
+ condition: { logic: '$and', items: [] },
1012
+ actions: [{ key: 'a1', name: 'linkageSetMenuItemProps', params: { value: 'hidden' } }],
1013
+ },
1014
+ ],
1015
+ });
1016
+
1017
+ await model.saveStepParams();
1018
+
1019
+ expect(save).toHaveBeenCalledWith(model, { onlyStepParams: true });
1020
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1021
+ options: {
1022
+ hasPersistedMenuInstanceFlow: true,
1023
+ },
1024
+ });
1025
+ });
1026
+
1027
+ it('should clear persisted menu linkage rules when no persisted state remains', async () => {
1028
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
1029
+ const destroy = vi.fn().mockResolvedValue(true);
1030
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1031
+ engine.setModelRepository({ destroy } as any);
1032
+ engine.context.routeRepository.updateRoute = updateRoute;
1033
+
1034
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1035
+ uid: 'menu-item-linkage-clear',
1036
+ use: AdminLayoutMenuItemModel,
1037
+ props: {
1038
+ route: createRoute({
1039
+ options: {
1040
+ hasPersistedMenuInstanceFlow: true,
1041
+ },
1042
+ }),
1043
+ },
1044
+ });
1045
+
1046
+ model.setStepParams('menuSettings', 'linkageRules', { value: [] });
1047
+ await model.saveStepParams();
1048
+
1049
+ expect(saveModel).not.toHaveBeenCalled();
1050
+ expect(destroy).toHaveBeenCalledWith('menu-item-linkage-clear');
1051
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1052
+ options: undefined,
1053
+ });
1054
+ });
1055
+
1056
+ it('should restore menu linkage rules and rerender after hydrate', async () => {
1057
+ engine.context.defineProperty('flowSettingsEnabled', {
1058
+ value: true,
1059
+ });
1060
+ engine.setModelRepository({
1061
+ findOne: vi.fn().mockResolvedValue({
1062
+ uid: 'menu-item-linkage-hydrate',
1063
+ use: 'AdminLayoutMenuItemModel',
1064
+ stepParams: {
1065
+ menuSettings: {
1066
+ linkageRules: {
1067
+ value: [
1068
+ {
1069
+ key: 'r1',
1070
+ title: 'Persisted linkage',
1071
+ enable: true,
1072
+ condition: { logic: '$and', items: [] },
1073
+ actions: [],
1074
+ },
1075
+ ],
1076
+ },
1077
+ },
1078
+ },
1079
+ }),
1080
+ } as any);
1081
+ const rerenderSpy = vi.spyOn(AdminLayoutMenuItemModel.prototype, 'rerender').mockResolvedValue(undefined as any);
1082
+
1083
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1084
+ uid: 'menu-item-linkage-hydrate',
1085
+ use: AdminLayoutMenuItemModel,
1086
+ props: {
1087
+ route: createRoute(),
1088
+ },
1089
+ });
1090
+
1091
+ await waitFor(() => {
1092
+ expect(model.getStepParams('menuSettings', 'linkageRules')).toMatchObject({
1093
+ value: [{ key: 'r1' }],
1094
+ });
1095
+ });
1096
+ expect(rerenderSpy).toHaveBeenCalledTimes(1);
1097
+ });
1098
+
1099
+ it('should hide menu route dynamically in runtime mode and refresh layout route tree', () => {
1100
+ const adminLayoutModel = engine.createModel<AdminLayoutModel>({
1101
+ uid: ADMIN_LAYOUT_MODEL_UID,
1102
+ use: AdminLayoutModel,
1103
+ });
1104
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1105
+ uid: 'menu-item-dynamic-hidden',
1106
+ use: AdminLayoutMenuItemModel,
1107
+ props: {
1108
+ route: createRoute(),
1109
+ },
1110
+ });
1111
+
1112
+ const refreshBefore = adminLayoutModel.menuRouteRefreshVersion;
1113
+
1114
+ model.setHidden(true);
1115
+ const runtimeRoute = model.toProLayoutRoute({
1116
+ designable: false,
1117
+ isMobile: false,
1118
+ t: (title) => title,
1119
+ });
1120
+ const designableRoute = model.toProLayoutRoute({
1121
+ designable: true,
1122
+ isMobile: false,
1123
+ t: (title) => title,
1124
+ });
1125
+
1126
+ expect(runtimeRoute).toBeNull();
1127
+ expect(designableRoute?.hideInMenu).toBeFalsy();
1128
+ expect(adminLayoutModel.menuRouteRefreshVersion).toBe(refreshBefore + 1);
1129
+ });
1130
+
1131
+ it('should render hidden menu item with opacity and keep original title in config mode', () => {
1132
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1133
+ uid: 'menu-item-hidden-in-config',
1134
+ use: AdminLayoutMenuItemModel,
1135
+ props: {
1136
+ route: createRoute(),
1137
+ },
1138
+ });
1139
+
1140
+ model.setProps({
1141
+ item: {
1142
+ name: 'Page 1',
1143
+ path: '/admin/page-1',
1144
+ _route: createRoute(),
1145
+ _model: model,
1146
+ },
1147
+ dom: React.createElement('span', null, 'Page 1'),
1148
+ options: { isMobile: false, collapsed: false },
1149
+ renderType: 'item',
1150
+ });
1151
+
1152
+ const rendered = (model as any).renderHiddenInConfig();
1153
+
1154
+ expect(rendered?.props?.style).toMatchObject({ opacity: 0.3 });
1155
+ expect(rendered?.props?.children?.props?.dom?.props?.children).toBe('Page 1');
1156
+ });
1157
+
1158
+ it('should keep variable-aware editors for link menu settings', async () => {
1159
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1160
+ uid: 'menu-item-link-edit',
1161
+ use: AdminLayoutMenuItemModel,
1162
+ props: {
1163
+ route: {
1164
+ id: 1,
1165
+ title: 'Link 1',
1166
+ schemaUid: 'link-1',
1167
+ type: NocoBaseDesktopRouteType.link,
1168
+ options: {
1169
+ href: '{{ ctx.url }}',
1170
+ params: [{ name: 'foo', value: { type: 'number', value: 1 } }],
1171
+ },
1172
+ },
1173
+ },
1174
+ });
1175
+
1176
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
1177
+ const editUiSchema = menuSettingsFlow?.steps?.edit?.uiSchema as ((ctx: any) => Promise<any>) | undefined;
1178
+ const schema = await editUiSchema?.({ model, t: (text) => text });
1179
+
1180
+ expect(schema?.href?.['x-component']).toBe('FlowSettingsVariableTextArea');
1181
+ expect(schema?.params?.items?.properties?.space?.properties?.value?.['x-component']).toBe(
1182
+ 'FlowSettingsVariableTextArea',
1183
+ );
1184
+ expect(schema?.params?.items?.properties?.space?.properties?.value?.['x-component-props']).toMatchObject({
1185
+ rows: 1,
1186
+ maxRows: 1,
1187
+ useTypedConstant: true,
1188
+ changeOnSelect: true,
1189
+ });
1190
+ expect(schema?.href?.['x-component-props']).toMatchObject({
1191
+ rows: 1,
1192
+ maxRows: 1,
1193
+ });
1194
+ });
1195
+
1196
+ it('should keep creation flow defaults compatible with launcher source', async () => {
1197
+ const headerModel = engine.createModel<AdminLayoutMenuItemModel>({
1198
+ uid: 'menu-item-create-link-header',
1199
+ use: AdminLayoutMenuItemModel,
1200
+ props: {
1201
+ creationMeta: {
1202
+ menuType: 'link',
1203
+ source: 'header',
1204
+ },
1205
+ },
1206
+ });
1207
+ const insertModel = engine.createModel<AdminLayoutMenuItemModel>({
1208
+ uid: 'menu-item-create-link-insert',
1209
+ use: AdminLayoutMenuItemModel,
1210
+ props: {
1211
+ creationMeta: {
1212
+ menuType: 'link',
1213
+ source: 'insert',
1214
+ insertPosition: 'afterEnd',
1215
+ targetRoute: {
1216
+ id: 2,
1217
+ title: 'Page 2',
1218
+ schemaUid: 'page-2',
1219
+ type: NocoBaseDesktopRouteType.page,
1220
+ },
1221
+ },
1222
+ },
1223
+ });
1224
+
1225
+ const menuCreationFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuCreation');
1226
+ const defaultParams = menuCreationFlow?.steps?.basic?.defaultParams as ((ctx: any) => Promise<any>) | undefined;
1227
+ const uiSchema = menuCreationFlow?.steps?.basic?.uiSchema as ((ctx: any) => Promise<any>) | undefined;
1228
+
1229
+ expect(await defaultParams?.({ model: headerModel })).toEqual({
1230
+ openInNewWindow: true,
1231
+ });
1232
+ expect(await defaultParams?.({ model: insertModel })).toEqual({});
1233
+
1234
+ const schema = await uiSchema?.({ model: headerModel, t: (text) => text });
1235
+ expect(schema?.href?.['x-component']).toBe('FlowSettingsVariableTextArea');
1236
+ expect(schema?.params?.items?.properties?.space?.properties?.value?.['x-component']).toBe(
1237
+ 'FlowSettingsVariableTextArea',
1238
+ );
1239
+ });
1240
+
1241
+ it('should persist root link creation through menuCreation flow', async () => {
1242
+ const createRoute = vi.fn().mockResolvedValue({
1243
+ data: {
1244
+ data: {
1245
+ id: 88,
1246
+ },
1247
+ },
1248
+ });
1249
+ engine.context.routeRepository.createRoute = createRoute;
1250
+
1251
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1252
+ uid: 'menu-item-create-link-root',
1253
+ use: AdminLayoutMenuItemModel,
1254
+ props: {
1255
+ creationMeta: {
1256
+ menuType: 'link',
1257
+ source: 'header',
1258
+ },
1259
+ },
1260
+ });
1261
+
1262
+ model.setStepParams('menuCreation', 'basic', {
1263
+ title: 'Docs',
1264
+ icon: 'LinkOutlined',
1265
+ href: 'https://www.nocobase.com',
1266
+ params: [{ name: 'from', value: 'admin' }],
1267
+ openInNewWindow: true,
1268
+ });
1269
+
1270
+ await model.save();
1271
+
1272
+ expect(createRoute).toHaveBeenCalledWith(
1273
+ expect.objectContaining({
1274
+ type: NocoBaseDesktopRouteType.link,
1275
+ title: 'Docs',
1276
+ icon: 'LinkOutlined',
1277
+ options: {
1278
+ href: 'https://www.nocobase.com',
1279
+ params: [{ name: 'from', value: 'admin' }],
1280
+ openInNewWindow: true,
1281
+ },
1282
+ }),
1283
+ undefined,
1284
+ );
1285
+ });
1286
+
1287
+ it('should persist creation session during saveStepParams and avoid duplicate route creation on save', async () => {
1288
+ const createRoute = vi.fn().mockResolvedValue({
1289
+ data: {
1290
+ data: {
1291
+ id: 88,
1292
+ },
1293
+ },
1294
+ });
1295
+ engine.context.routeRepository.createRoute = createRoute;
1296
+
1297
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1298
+ uid: 'menu-item-create-link-save-step-params',
1299
+ use: AdminLayoutMenuItemModel,
1300
+ props: {
1301
+ creationMeta: {
1302
+ menuType: 'link',
1303
+ source: 'header',
1304
+ },
1305
+ },
1306
+ });
1307
+
1308
+ model.setStepParams('menuCreation', 'basic', {
1309
+ title: 'Docs',
1310
+ href: 'https://www.nocobase.com',
1311
+ openInNewWindow: true,
1312
+ });
1313
+
1314
+ await model.saveStepParams();
1315
+ await model.save();
1316
+
1317
+ expect(createRoute).toHaveBeenCalledTimes(1);
1318
+ });
1319
+
1320
+ it('should persist insert flow page creation through menuCreation flow', async () => {
1321
+ const createRoute = vi.fn().mockResolvedValue({
1322
+ data: {
1323
+ data: {
1324
+ id: 99,
1325
+ },
1326
+ },
1327
+ });
1328
+ const moveRoute = vi.fn().mockResolvedValue(undefined);
1329
+ const request = vi.fn().mockResolvedValue(undefined);
1330
+
1331
+ engine.context.routeRepository.createRoute = createRoute;
1332
+ engine.context.routeRepository.moveRoute = moveRoute;
1333
+ engine.context.api.request = request;
1334
+
1335
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1336
+ uid: 'menu-item-create-flow-page-insert',
1337
+ use: AdminLayoutMenuItemModel,
1338
+ props: {
1339
+ creationMeta: {
1340
+ menuType: 'flowPage',
1341
+ source: 'insert',
1342
+ insertPosition: 'beforeBegin',
1343
+ targetRoute: {
1344
+ id: 1,
1345
+ parentId: 10,
1346
+ title: 'Current page',
1347
+ schemaUid: 'current-page',
1348
+ type: NocoBaseDesktopRouteType.page,
1349
+ },
1350
+ },
1351
+ },
1352
+ });
1353
+
1354
+ model.setStepParams('menuCreation', 'basic', {
1355
+ title: 'New page',
1356
+ icon: 'AppstoreOutlined',
1357
+ });
1358
+
1359
+ await model.save();
1360
+
1361
+ expect(createRoute).toHaveBeenCalledWith(
1362
+ expect.objectContaining({
1363
+ parentId: 10,
1364
+ type: NocoBaseDesktopRouteType.flowPage,
1365
+ title: 'New page',
1366
+ icon: 'AppstoreOutlined',
1367
+ }),
1368
+ {
1369
+ refreshAfterMutation: false,
1370
+ },
1371
+ );
1372
+ expect(moveRoute).toHaveBeenCalledWith({
1373
+ sourceId: 99,
1374
+ targetId: 1,
1375
+ sortField: 'sort',
1376
+ method: 'insertBefore',
1377
+ });
1378
+ expect(request).not.toHaveBeenCalled();
1379
+ });
1380
+
1381
+ it('should persist insert step using selected menu type', async () => {
1382
+ const createRoute = vi.fn().mockResolvedValue({
1383
+ data: {
1384
+ data: {
1385
+ id: 66,
1386
+ },
1387
+ },
1388
+ });
1389
+ const moveRoute = vi.fn().mockResolvedValue(undefined);
1390
+
1391
+ engine.context.routeRepository.createRoute = createRoute;
1392
+ engine.context.routeRepository.moveRoute = moveRoute;
1393
+
1394
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1395
+ uid: 'menu-item-insert-step',
1396
+ use: AdminLayoutMenuItemModel,
1397
+ props: {
1398
+ route: {
1399
+ id: 1,
1400
+ parentId: 10,
1401
+ title: 'Current page',
1402
+ schemaUid: 'current-page',
1403
+ type: NocoBaseDesktopRouteType.page,
1404
+ },
1405
+ },
1406
+ });
1407
+
1408
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
1409
+ await menuSettingsFlow?.steps?.insertBefore?.beforeParamsSave?.(
1410
+ { model } as any,
1411
+ {
1412
+ menuType: 'group',
1413
+ title: 'New group',
1414
+ icon: 'FolderOutlined',
1415
+ },
1416
+ {},
1417
+ );
1418
+
1419
+ expect(createRoute).toHaveBeenCalledWith(
1420
+ expect.objectContaining({
1421
+ type: NocoBaseDesktopRouteType.group,
1422
+ title: 'New group',
1423
+ icon: 'FolderOutlined',
1424
+ parentId: 10,
1425
+ }),
1426
+ {
1427
+ refreshAfterMutation: false,
1428
+ },
1429
+ );
1430
+ expect(moveRoute).toHaveBeenCalledWith({
1431
+ sourceId: 66,
1432
+ targetId: 1,
1433
+ sortField: 'sort',
1434
+ method: 'insertBefore',
1435
+ });
1436
+ });
1437
+
1438
+ it('should not persist admin layout menu models through flowEngine.saveModel when saving step params', async () => {
1439
+ const saveModel = vi.spyOn(engine, 'saveModel');
1440
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1441
+ uid: 'menu-item-save-step-params-existing',
1442
+ use: AdminLayoutMenuItemModel,
1443
+ props: {
1444
+ route: createRoute(),
1445
+ },
1446
+ });
1447
+
1448
+ await model.saveStepParams();
1449
+
1450
+ expect(saveModel).not.toHaveBeenCalled();
1451
+ });
1452
+
1453
+ it('should persist admin layout menu instance flows through flowEngine.saveModel', async () => {
1454
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
1455
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1456
+ uid: 'menu-item-save-step-params-with-instance-flow',
1457
+ use: AdminLayoutMenuItemModel,
1458
+ props: {
1459
+ route: createRoute(),
1460
+ },
1461
+ flowRegistry: {
1462
+ beforeRender: {
1463
+ title: 'Before render',
1464
+ steps: {},
1465
+ },
1466
+ },
1467
+ });
1468
+
1469
+ model.flowRegistry.removeFlow('beforeRender');
1470
+
1471
+ await model.saveStepParams();
1472
+
1473
+ expect(saveModel).toHaveBeenCalledTimes(1);
1474
+ expect(saveModel).toHaveBeenCalledWith(model, { onlyStepParams: true });
1475
+ });
1476
+
1477
+ it('should hydrate persisted instance flows for admin layout menu models', async () => {
1478
+ engine.context.defineProperty('flowSettingsEnabled', {
1479
+ value: true,
1480
+ });
1481
+ engine.setModelRepository({
1482
+ findOne: vi.fn().mockResolvedValue({
1483
+ uid: 'menu-item-page-1',
1484
+ use: 'AdminLayoutMenuItemModel',
1485
+ stepParams: {
1486
+ beforeRender: {
1487
+ edit: {
1488
+ title: 'Persisted flow',
1489
+ },
1490
+ },
1491
+ },
1492
+ flowRegistry: {
1493
+ beforeRender: {
1494
+ title: 'Before render',
1495
+ steps: {},
1496
+ },
1497
+ },
1498
+ }),
1499
+ } as any);
1500
+
1501
+ const rerenderSpy = vi.spyOn(AdminLayoutMenuItemModel.prototype, 'rerender').mockResolvedValue(undefined as any);
1502
+
1503
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1504
+ uid: 'menu-item-page-1',
1505
+ use: AdminLayoutMenuItemModel,
1506
+ props: {
1507
+ route: createRoute(),
1508
+ },
1509
+ });
1510
+
1511
+ await waitFor(() => {
1512
+ expect(model.getFlow('beforeRender')).toBeDefined();
1513
+ expect(model.getStepParams('beforeRender', 'edit')).toMatchObject({
1514
+ title: 'Persisted flow',
1515
+ });
1516
+ });
1517
+
1518
+ expect(rerenderSpy).toHaveBeenCalledTimes(1);
1519
+ });
1520
+
1521
+ it('should not hydrate persisted instance flows for admin layout menu models in runtime mode when route is not marked', async () => {
1522
+ const findOne = vi.fn().mockResolvedValue({
1523
+ uid: 'menu-item-page-1',
1524
+ flowRegistry: {
1525
+ beforeRender: {
1526
+ title: 'Before render',
1527
+ steps: {},
1528
+ },
1529
+ },
1530
+ });
1531
+
1532
+ engine.setModelRepository({ findOne } as any);
1533
+
1534
+ engine.createModel<AdminLayoutMenuItemModel>({
1535
+ uid: 'menu-item-page-1',
1536
+ use: AdminLayoutMenuItemModel,
1537
+ props: {
1538
+ route: createRoute(),
1539
+ },
1540
+ });
1541
+
1542
+ await waitFor(() => {
1543
+ expect(findOne).not.toHaveBeenCalled();
1544
+ });
1545
+ });
1546
+
1547
+ it('should hydrate persisted instance flows in runtime mode when route is marked and rerender beforeRender flow', async () => {
1548
+ const findOne = vi.fn().mockResolvedValue({
1549
+ uid: 'menu-item-page-1',
1550
+ stepParams: {
1551
+ beforeRender: {
1552
+ edit: {
1553
+ title: 'Persisted flow',
1554
+ },
1555
+ },
1556
+ },
1557
+ flowRegistry: {
1558
+ beforeRender: {
1559
+ title: 'Before render',
1560
+ steps: {},
1561
+ },
1562
+ },
1563
+ });
1564
+ const rerenderSpy = vi.spyOn(AdminLayoutMenuItemModel.prototype, 'rerender').mockResolvedValue(undefined as any);
1565
+
1566
+ engine.setModelRepository({ findOne } as any);
1567
+
1568
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1569
+ uid: 'menu-item-page-1',
1570
+ use: AdminLayoutMenuItemModel,
1571
+ props: {
1572
+ route: createRoute({
1573
+ options: {
1574
+ hasPersistedMenuInstanceFlow: true,
1575
+ },
1576
+ }),
1577
+ },
1578
+ });
1579
+
1580
+ await waitFor(() => {
1581
+ expect(findOne).toHaveBeenCalledWith({ uid: 'menu-item-page-1' });
1582
+ expect(model.getFlow('beforeRender')).toBeDefined();
1583
+ expect(model.getStepParams('beforeRender', 'edit')).toMatchObject({
1584
+ title: 'Persisted flow',
1585
+ });
1586
+ });
1587
+
1588
+ expect(rerenderSpy).toHaveBeenCalledTimes(1);
1589
+ });
1590
+
1591
+ it('should write route persisted flag when first instance flow is added', async () => {
1592
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
1593
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1594
+ engine.context.routeRepository.updateRoute = updateRoute;
1595
+
1596
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1597
+ uid: 'menu-item-first-instance-flow',
1598
+ use: AdminLayoutMenuItemModel,
1599
+ props: {
1600
+ route: createRoute(),
1601
+ },
1602
+ });
1603
+
1604
+ model.flowRegistry.addFlow('beforeRender', {
1605
+ title: 'Before render',
1606
+ steps: {},
1607
+ });
1608
+
1609
+ await model.saveStepParams();
1610
+
1611
+ expect(saveModel).toHaveBeenCalledWith(model, { onlyStepParams: true });
1612
+ expect(updateRoute).toHaveBeenCalledTimes(1);
1613
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1614
+ options: {
1615
+ hasPersistedMenuInstanceFlow: true,
1616
+ },
1617
+ });
1618
+ });
1619
+
1620
+ it('should keep route persisted flag unchanged when only step params change', async () => {
1621
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
1622
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1623
+ engine.context.routeRepository.updateRoute = updateRoute;
1624
+
1625
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1626
+ uid: 'menu-item-step-params-only',
1627
+ use: AdminLayoutMenuItemModel,
1628
+ props: {
1629
+ route: createRoute({
1630
+ options: {
1631
+ hasPersistedMenuInstanceFlow: true,
1632
+ },
1633
+ }),
1634
+ },
1635
+ flowRegistry: {
1636
+ beforeRender: {
1637
+ title: 'Before render',
1638
+ steps: {},
1639
+ },
1640
+ },
1641
+ });
1642
+
1643
+ model.setStepParams('beforeRender', 'edit', {
1644
+ title: 'Updated params',
1645
+ });
1646
+
1647
+ await model.saveStepParams();
1648
+
1649
+ expect(saveModel).toHaveBeenCalledWith(model, { onlyStepParams: true });
1650
+ expect(updateRoute).not.toHaveBeenCalled();
1651
+ });
1652
+
1653
+ it('should preserve persisted flow flag when updating normal menu options', async () => {
1654
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1655
+ engine.context.routeRepository.updateRoute = updateRoute;
1656
+
1657
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1658
+ uid: 'menu-item-link-edit',
1659
+ use: AdminLayoutMenuItemModel,
1660
+ props: {
1661
+ route: createRoute({
1662
+ type: NocoBaseDesktopRouteType.link,
1663
+ options: {
1664
+ hasPersistedMenuInstanceFlow: true,
1665
+ href: 'https://old.example.com',
1666
+ },
1667
+ }),
1668
+ },
1669
+ });
1670
+
1671
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
1672
+ await menuSettingsFlow?.steps?.edit?.beforeParamsSave?.(
1673
+ { model } as any,
1674
+ {
1675
+ title: 'Docs',
1676
+ href: 'https://www.nocobase.com',
1677
+ params: [{ name: 'from', value: 'admin' }],
1678
+ openInNewWindow: true,
1679
+ },
1680
+ {},
1681
+ );
1682
+
1683
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1684
+ title: 'Docs',
1685
+ icon: undefined,
1686
+ options: {
1687
+ hasPersistedMenuInstanceFlow: true,
1688
+ href: 'https://www.nocobase.com',
1689
+ params: [{ name: 'from', value: 'admin' }],
1690
+ openInNewWindow: true,
1691
+ },
1692
+ });
1693
+ });
1694
+
1695
+ it('should clear route persisted flag after deleting the last instance flow and stop runtime hydrate afterwards', async () => {
1696
+ const saveModel = vi.spyOn(engine, 'saveModel').mockResolvedValue(undefined as any);
1697
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1698
+ const destroy = vi.fn().mockResolvedValue(true);
1699
+ const findOne = vi.fn().mockResolvedValue({
1700
+ uid: 'menu-item-runtime-after-clear',
1701
+ flowRegistry: {
1702
+ beforeRender: {
1703
+ title: 'Before render',
1704
+ steps: {},
1705
+ },
1706
+ },
1707
+ });
1708
+
1709
+ engine.context.routeRepository.updateRoute = updateRoute;
1710
+ engine.setModelRepository({ destroy } as any);
1711
+
1712
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1713
+ uid: 'menu-item-last-instance-flow',
1714
+ use: AdminLayoutMenuItemModel,
1715
+ props: {
1716
+ route: createRoute({
1717
+ options: {
1718
+ hasPersistedMenuInstanceFlow: true,
1719
+ },
1720
+ }),
1721
+ },
1722
+ flowRegistry: {
1723
+ beforeRender: {
1724
+ title: 'Before render',
1725
+ steps: {},
1726
+ },
1727
+ },
1728
+ });
1729
+
1730
+ model.flowRegistry.removeFlow('beforeRender');
1731
+ await model.saveStepParams();
1732
+
1733
+ expect(saveModel).not.toHaveBeenCalled();
1734
+ expect(destroy).toHaveBeenCalledWith('menu-item-last-instance-flow');
1735
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1736
+ options: undefined,
1737
+ });
1738
+
1739
+ engine.setModelRepository({ findOne } as any);
1740
+
1741
+ const runtimeModel = engine.createModel<AdminLayoutMenuItemModel>({
1742
+ uid: 'menu-item-runtime-after-clear',
1743
+ use: AdminLayoutMenuItemModel,
1744
+ props: {
1745
+ route: createRoute(),
1746
+ },
1747
+ });
1748
+
1749
+ await waitFor(() => {
1750
+ expect(runtimeModel.getFlow('beforeRender')).toBeUndefined();
1751
+ expect(findOne).not.toHaveBeenCalledWith({ uid: 'menu-item-runtime-after-clear' });
1752
+ });
1753
+ });
1754
+
1755
+ it('should not hydrate deleted persisted menu flows when reopening in config mode', async () => {
1756
+ const updateRoute = vi.fn().mockResolvedValue(undefined);
1757
+ const save = vi.fn().mockResolvedValue(undefined);
1758
+ const destroy = vi.fn().mockImplementation(async (uid: string) => {
1759
+ persistedModels.delete(uid);
1760
+ return true;
1761
+ });
1762
+ const findOne = vi.fn().mockImplementation(async ({ uid }) => persistedModels.get(uid) || null);
1763
+ const persistedModels = new Map<string, any>([
1764
+ [
1765
+ 'menu-item-config-reopen',
1766
+ {
1767
+ uid: 'menu-item-config-reopen',
1768
+ flowRegistry: {
1769
+ beforeRender: {
1770
+ title: 'Before render',
1771
+ steps: {},
1772
+ },
1773
+ },
1774
+ },
1775
+ ],
1776
+ ]);
1777
+
1778
+ engine.context.defineProperty('flowSettingsEnabled', {
1779
+ value: true,
1780
+ });
1781
+ engine.context.routeRepository.updateRoute = updateRoute;
1782
+ engine.setModelRepository({ findOne, save, destroy } as any);
1783
+
1784
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1785
+ uid: 'menu-item-config-reopen',
1786
+ use: AdminLayoutMenuItemModel,
1787
+ props: {
1788
+ route: createRoute({
1789
+ options: {
1790
+ hasPersistedMenuInstanceFlow: true,
1791
+ },
1792
+ }),
1793
+ },
1794
+ flowRegistry: {
1795
+ beforeRender: {
1796
+ title: 'Before render',
1797
+ steps: {},
1798
+ },
1799
+ },
1800
+ });
1801
+
1802
+ await waitFor(() => {
1803
+ expect(model.getFlow('beforeRender')).toBeDefined();
1804
+ });
1805
+
1806
+ model.flowRegistry.removeFlow('beforeRender');
1807
+ await model.saveStepParams();
1808
+
1809
+ expect(save).not.toHaveBeenCalled();
1810
+ expect(destroy).toHaveBeenCalledWith('menu-item-config-reopen');
1811
+ expect(updateRoute).toHaveBeenCalledWith(1, {
1812
+ options: undefined,
1813
+ });
1814
+
1815
+ findOne.mockClear();
1816
+ engine.removeModelWithSubModels('menu-item-config-reopen');
1817
+
1818
+ const reopenedModel = engine.createModel<AdminLayoutMenuItemModel>({
1819
+ uid: 'menu-item-config-reopen',
1820
+ use: AdminLayoutMenuItemModel,
1821
+ props: {
1822
+ route: createRoute(),
1823
+ },
1824
+ });
1825
+
1826
+ await waitFor(() => {
1827
+ expect(findOne).toHaveBeenCalledWith({ uid: 'menu-item-config-reopen' });
1828
+ expect(reopenedModel.getFlow('beforeRender')).toBeUndefined();
1829
+ });
1830
+ });
1831
+
1832
+ it('should hydrate only marked menus in mixed runtime menu scenarios', async () => {
1833
+ const findOne = vi.fn().mockImplementation(async ({ uid }) => ({
1834
+ uid,
1835
+ flowRegistry: {
1836
+ beforeRender: {
1837
+ title: `Flow for ${uid}`,
1838
+ steps: {},
1839
+ },
1840
+ },
1841
+ }));
1842
+
1843
+ engine.setModelRepository({ findOne } as any);
1844
+
1845
+ engine.createModel<AdminLayoutMenuItemModel>({
1846
+ uid: 'menu-item-unmarked',
1847
+ use: AdminLayoutMenuItemModel,
1848
+ props: {
1849
+ route: createRoute({ id: 11, schemaUid: 'page-11' }),
1850
+ },
1851
+ });
1852
+ const markedModel = engine.createModel<AdminLayoutMenuItemModel>({
1853
+ uid: 'menu-item-marked',
1854
+ use: AdminLayoutMenuItemModel,
1855
+ props: {
1856
+ route: createRoute({
1857
+ id: 12,
1858
+ schemaUid: 'page-12',
1859
+ options: {
1860
+ hasPersistedMenuInstanceFlow: true,
1861
+ },
1862
+ }),
1863
+ },
1864
+ });
1865
+
1866
+ await waitFor(() => {
1867
+ expect(findOne).toHaveBeenCalledTimes(1);
1868
+ expect(findOne).toHaveBeenCalledWith({ uid: 'menu-item-marked' });
1869
+ expect(markedModel.getFlow('beforeRender')).toBeDefined();
1870
+ });
1871
+ });
1872
+
1873
+ it('should expose insert steps and only show insert inner for groups', async () => {
1874
+ const groupModel = engine.createModel<AdminLayoutMenuItemModel>({
1875
+ uid: 'menu-item-group',
1876
+ use: AdminLayoutMenuItemModel,
1877
+ props: {
1878
+ route: {
1879
+ id: 1,
1880
+ title: 'Group 1',
1881
+ schemaUid: 'group-1',
1882
+ type: NocoBaseDesktopRouteType.group,
1883
+ },
1884
+ },
1885
+ });
1886
+ const pageModel = engine.createModel<AdminLayoutMenuItemModel>({
1887
+ uid: 'menu-item-page',
1888
+ use: AdminLayoutMenuItemModel,
1889
+ props: {
1890
+ route: {
1891
+ id: 2,
1892
+ title: 'Page 2',
1893
+ schemaUid: 'page-2',
1894
+ type: NocoBaseDesktopRouteType.page,
1895
+ },
1896
+ },
1897
+ });
1898
+
1899
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
1900
+ const insertBeforeUiSchema = menuSettingsFlow?.steps?.insertBefore?.uiSchema as
1901
+ | ((ctx: any) => Promise<any>)
1902
+ | undefined;
1903
+ const insertBeforeDefaultParams = menuSettingsFlow?.steps?.insertBefore?.defaultParams as
1904
+ | ((ctx: any) => Promise<any>)
1905
+ | undefined;
1906
+ const insertInnerHide = menuSettingsFlow?.steps?.insertInner?.hideInSettings as
1907
+ | ((ctx: any) => Promise<boolean>)
1908
+ | undefined;
1909
+ const schema = await insertBeforeUiSchema?.({ model: groupModel, t: (text) => text });
1910
+ const defaultParams = await insertBeforeDefaultParams?.({ model: groupModel, t: (text) => text });
1911
+
1912
+ expect(defaultParams?.menuType).toBe('flowPage');
1913
+ expect(schema?.menuType?.['x-component']).toBe('Radio.Group');
1914
+ expect(schema?.menuType?.enum).toEqual([
1915
+ { label: 'Group', value: 'group' },
1916
+ { label: 'Page', value: 'flowPage' },
1917
+ { label: 'Link', value: 'link' },
1918
+ ]);
1919
+ expect(schema?.href?.['x-reactions']).toMatchObject({
1920
+ dependencies: ['menuType'],
1921
+ });
1922
+ await expect(insertInnerHide?.({ model: groupModel })).resolves.toBe(false);
1923
+ await expect(insertInnerHide?.({ model: pageModel })).resolves.toBe(true);
1924
+ });
1925
+
1926
+ it('should delete current route and navigate to sibling route', async () => {
1927
+ const deleteRoute = vi.fn().mockResolvedValue(undefined);
1928
+ const removeSchema = vi.fn().mockResolvedValue(undefined);
1929
+ const navigate = vi.fn();
1930
+ const assign = vi.fn();
1931
+
1932
+ Object.defineProperty(window, 'location', {
1933
+ configurable: true,
1934
+ value: {
1935
+ ...window.location,
1936
+ assign,
1937
+ },
1938
+ });
1939
+ engine.context.routeRepository.deleteRoute = deleteRoute;
1940
+ engine.context.routeRepository.listAccessible = () => [
1941
+ {
1942
+ id: 1,
1943
+ title: 'Current page',
1944
+ schemaUid: 'current-page',
1945
+ type: NocoBaseDesktopRouteType.page,
1946
+ },
1947
+ {
1948
+ id: 2,
1949
+ title: 'Next page',
1950
+ schemaUid: 'next-page',
1951
+ type: NocoBaseDesktopRouteType.flowPage,
1952
+ },
1953
+ ];
1954
+ engine.context.api.resource = vi.fn(() => ({
1955
+ 'remove/current-page': removeSchema,
1956
+ }));
1957
+ engine.context.router.navigate = navigate;
1958
+
1959
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
1960
+ uid: 'menu-item-delete',
1961
+ use: AdminLayoutMenuItemModel,
1962
+ props: {
1963
+ route: {
1964
+ id: 1,
1965
+ title: 'Current page',
1966
+ schemaUid: 'current-page',
1967
+ type: NocoBaseDesktopRouteType.page,
1968
+ },
1969
+ },
1970
+ });
1971
+
1972
+ await model.destroy();
1973
+
1974
+ expect(deleteRoute).toHaveBeenCalledWith(1);
1975
+ expect(removeSchema).not.toHaveBeenCalled();
1976
+ expect(assign).not.toHaveBeenCalled();
1977
+ expect(navigate).toHaveBeenCalledWith('/apps/demo/v2/admin/next-page');
1978
+ });
1979
+
1980
+ it('should match current route with router basename before navigating away after delete', async () => {
1981
+ const deleteRoute = vi.fn().mockResolvedValue(undefined);
1982
+ const removeSchema = vi.fn().mockResolvedValue(undefined);
1983
+ const navigate = vi.fn();
1984
+ const assign = vi.fn();
1985
+
1986
+ Object.defineProperty(window, 'location', {
1987
+ configurable: true,
1988
+ value: {
1989
+ ...window.location,
1990
+ assign,
1991
+ },
1992
+ });
1993
+ engine.context.routeRepository.deleteRoute = deleteRoute;
1994
+ engine.context.routeRepository.listAccessible = () => [
1995
+ {
1996
+ id: 1,
1997
+ title: 'Current page',
1998
+ schemaUid: 'current-page',
1999
+ type: NocoBaseDesktopRouteType.page,
2000
+ },
2001
+ {
2002
+ id: 2,
2003
+ title: 'Next page',
2004
+ schemaUid: 'next-page',
2005
+ type: NocoBaseDesktopRouteType.flowPage,
2006
+ },
2007
+ ];
2008
+ engine.context.api.resource = vi.fn(() => ({
2009
+ 'remove/current-page': removeSchema,
2010
+ }));
2011
+ engine.context.location.pathname = '/apps/demo/v2/admin/current-page';
2012
+ engine.context.defineProperty('router', {
2013
+ value: {
2014
+ basename: '/apps/demo/v2',
2015
+ navigate,
2016
+ },
2017
+ });
2018
+
2019
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
2020
+ uid: 'menu-item-delete-with-basename',
2021
+ use: AdminLayoutMenuItemModel,
2022
+ props: {
2023
+ route: {
2024
+ id: 1,
2025
+ title: 'Current page',
2026
+ schemaUid: 'current-page',
2027
+ type: NocoBaseDesktopRouteType.page,
2028
+ },
2029
+ },
2030
+ });
2031
+
2032
+ await model.destroy();
2033
+
2034
+ expect(deleteRoute).toHaveBeenCalledWith(1);
2035
+ expect(removeSchema).not.toHaveBeenCalled();
2036
+ expect(assign).not.toHaveBeenCalled();
2037
+ expect(navigate).toHaveBeenCalledWith('/admin/next-page');
2038
+ });
2039
+
2040
+ it('should reject inner move when target is not a group', async () => {
2041
+ const moveRoute = vi.fn().mockResolvedValue(undefined);
2042
+ engine.context.routeRepository.moveRoute = moveRoute;
2043
+
2044
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
2045
+ uid: 'menu-item-invalid-inner-target',
2046
+ use: AdminLayoutMenuItemModel,
2047
+ props: {
2048
+ route: {
2049
+ id: 1,
2050
+ title: 'Page 1',
2051
+ schemaUid: 'page-1',
2052
+ type: NocoBaseDesktopRouteType.page,
2053
+ },
2054
+ },
2055
+ });
2056
+
2057
+ await expect(model.moveMenuRoute('2||page', 'beforeEnd')).rejects.toThrow('Only groups support inner moves');
2058
+ expect(moveRoute).not.toHaveBeenCalled();
2059
+ });
2060
+
2061
+ it('should only expose inner position for group targets and disable self-inner', () => {
2062
+ expect(getAdminLayoutMenuMovePositionOptions(undefined, 1, (text) => text)).toEqual([
2063
+ { label: 'Before', value: 'beforeBegin' },
2064
+ { label: 'After', value: 'afterEnd' },
2065
+ ]);
2066
+
2067
+ expect(getAdminLayoutMenuMovePositionOptions('2||group', 1, (text) => text)).toEqual([
2068
+ { label: 'Before', value: 'beforeBegin' },
2069
+ { label: 'After', value: 'afterEnd' },
2070
+ { label: 'Inner', value: 'beforeEnd', disabled: false },
2071
+ ]);
2072
+
2073
+ expect(getAdminLayoutMenuMovePositionOptions('1||group', 1, (text) => text)).toEqual([
2074
+ { label: 'Before', value: 'beforeBegin' },
2075
+ { label: 'After', value: 'afterEnd' },
2076
+ { label: 'Inner', value: 'beforeEnd', disabled: true },
2077
+ ]);
2078
+ });
2079
+
2080
+ it('should compile variable-backed route titles in move-to tree', async () => {
2081
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
2082
+ uid: 'menu-item-move-tree',
2083
+ use: AdminLayoutMenuItemModel,
2084
+ props: {
2085
+ route: {
2086
+ id: 1,
2087
+ title: 'Page 1',
2088
+ schemaUid: 'page-1',
2089
+ type: NocoBaseDesktopRouteType.page,
2090
+ },
2091
+ },
2092
+ });
2093
+
2094
+ const menuSettingsFlow = AdminLayoutMenuItemModel.globalFlowRegistry.getFlow('menuSettings');
2095
+ const moveToUiSchema = menuSettingsFlow?.steps?.moveTo?.uiSchema as ((ctx: any) => Promise<any>) | undefined;
2096
+ const resolveJsonTemplate = vi.fn(async () => 'Translated title');
2097
+ const schema = await moveToUiSchema?.({
2098
+ model,
2099
+ t: (text) => text,
2100
+ routeRepository: {
2101
+ listAccessible: () => [
2102
+ {
2103
+ id: 2,
2104
+ title: '{{route.title}}',
2105
+ schemaUid: 'page-2',
2106
+ type: NocoBaseDesktopRouteType.page,
2107
+ },
2108
+ ],
2109
+ },
2110
+ resolveJsonTemplate,
2111
+ });
2112
+
2113
+ expect(resolveJsonTemplate).toHaveBeenCalledWith('{{route.title}}');
2114
+ expect(schema?.target?.enum).toEqual([
2115
+ {
2116
+ label: 'Translated title',
2117
+ value: '2||page',
2118
+ children: undefined,
2119
+ },
2120
+ ]);
2121
+ });
2122
+
2123
+ it('should reject moving a group inside itself', async () => {
2124
+ const moveRoute = vi.fn().mockResolvedValue(undefined);
2125
+ engine.context.routeRepository.moveRoute = moveRoute;
2126
+
2127
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
2128
+ uid: 'menu-item-invalid-inner-self',
2129
+ use: AdminLayoutMenuItemModel,
2130
+ props: {
2131
+ route: {
2132
+ id: 1,
2133
+ title: 'Group 1',
2134
+ schemaUid: 'group-1',
2135
+ type: NocoBaseDesktopRouteType.group,
2136
+ },
2137
+ },
2138
+ });
2139
+
2140
+ await expect(model.moveMenuRoute('1||group', 'beforeEnd')).rejects.toThrow(
2141
+ 'A menu group cannot be moved inside itself',
2142
+ );
2143
+ expect(moveRoute).not.toHaveBeenCalled();
2144
+ });
2145
+
2146
+ it('should refresh routes when insert move fails after route creation', async () => {
2147
+ const createRoute = vi.fn().mockResolvedValue({
2148
+ data: {
2149
+ data: {
2150
+ id: 99,
2151
+ },
2152
+ },
2153
+ });
2154
+ const moveRoute = vi.fn().mockRejectedValue(new Error('move failed'));
2155
+ const refreshAccessible = vi.fn().mockResolvedValue(undefined);
2156
+
2157
+ engine.context.routeRepository.createRoute = createRoute;
2158
+ engine.context.routeRepository.moveRoute = moveRoute;
2159
+ engine.context.routeRepository.refreshAccessible = refreshAccessible;
2160
+
2161
+ const model = engine.createModel<AdminLayoutMenuItemModel>({
2162
+ uid: 'menu-item-insert-refresh',
2163
+ use: AdminLayoutMenuItemModel,
2164
+ props: {
2165
+ route: {
2166
+ id: 1,
2167
+ title: 'Page 1',
2168
+ schemaUid: 'page-1',
2169
+ parentId: 10,
2170
+ type: NocoBaseDesktopRouteType.page,
2171
+ },
2172
+ },
2173
+ });
2174
+
2175
+ await expect(
2176
+ model.createRouteForInsert(
2177
+ {
2178
+ type: NocoBaseDesktopRouteType.link,
2179
+ title: 'Link',
2180
+ schemaUid: 'link-99',
2181
+ },
2182
+ 'beforeBegin',
2183
+ ),
2184
+ ).rejects.toThrow('move failed');
2185
+
2186
+ expect(createRoute).toHaveBeenCalled();
2187
+ expect(moveRoute).toHaveBeenCalled();
2188
+ expect(refreshAccessible).toHaveBeenCalledTimes(1);
2189
+ });
2190
+
2191
+ it('should use parsed url for same-window link navigation', async () => {
2192
+ await openAdminLayoutMenuLink({
2193
+ context: engine.context as any,
2194
+ href: 'https://www.nocobase.com/docs',
2195
+ params: [{ name: 'from', value: 'admin' }],
2196
+ openInNewWindow: false,
2197
+ isMobile: false,
2198
+ closeMobileMenu: vi.fn(),
2199
+ navigate: navigateMock,
2200
+ basenameOfCurrentRouter: '/apps/demo',
2201
+ });
2202
+
2203
+ expect(window.open).toHaveBeenCalledWith('https://www.nocobase.com/docs?from=admin', '_self');
2204
+ });
2205
+
2206
+ it('should open parsed link url with noopener and noreferrer', async () => {
2207
+ await openAdminLayoutMenuLink({
2208
+ context: engine.context as any,
2209
+ href: 'https://www.nocobase.com/docs',
2210
+ params: [{ name: 'from', value: 'admin' }],
2211
+ openInNewWindow: true,
2212
+ isMobile: false,
2213
+ closeMobileMenu: vi.fn(),
2214
+ navigate: navigateMock,
2215
+ basenameOfCurrentRouter: '/apps/demo',
2216
+ });
2217
+
2218
+ expect(window.open).toHaveBeenCalledWith(
2219
+ 'https://www.nocobase.com/docs?from=admin',
2220
+ '_blank',
2221
+ 'noopener,noreferrer',
2222
+ );
2223
+ });
2224
+
2225
+ it('should resolve sibling move options for non-group drag target', () => {
2226
+ const activeModel = engine.createModel<AdminLayoutMenuItemModel>({
2227
+ uid: 'drag-source-page',
2228
+ use: AdminLayoutMenuItemModel,
2229
+ props: {
2230
+ route: {
2231
+ id: 1,
2232
+ title: 'Page 1',
2233
+ schemaUid: 'page-1',
2234
+ type: NocoBaseDesktopRouteType.page,
2235
+ },
2236
+ },
2237
+ });
2238
+ const overModel = engine.createModel<AdminLayoutMenuItemModel>({
2239
+ uid: 'drag-target-page',
2240
+ use: AdminLayoutMenuItemModel,
2241
+ props: {
2242
+ route: {
2243
+ id: 2,
2244
+ title: 'Page 2',
2245
+ schemaUid: 'page-2',
2246
+ type: NocoBaseDesktopRouteType.page,
2247
+ },
2248
+ },
2249
+ });
2250
+
2251
+ expect(resolveAdminLayoutMenuDragMoveOptions(activeModel, overModel)).toEqual({
2252
+ sourceId: 1,
2253
+ targetId: 2,
2254
+ sortField: 'sort',
2255
+ });
2256
+ });
2257
+
2258
+ it('should ignore drag end events without active or over ids', () => {
2259
+ const getModel = vi.fn();
2260
+
2261
+ expect(
2262
+ resolveAdminLayoutMenuDragMoveOptionsFromEvent({ getModel } as any, {
2263
+ active: { id: 'drag-source-page' },
2264
+ over: null,
2265
+ }),
2266
+ ).toBeUndefined();
2267
+ expect(
2268
+ resolveAdminLayoutMenuDragMoveOptionsFromEvent({ getModel } as any, {
2269
+ active: undefined,
2270
+ over: { id: 'drag-target-page' },
2271
+ }),
2272
+ ).toBeUndefined();
2273
+ expect(getModel).not.toHaveBeenCalled();
2274
+ });
2275
+
2276
+ it('should keep page drag on group target as sibling reorder', () => {
2277
+ const activeModel = engine.createModel<AdminLayoutMenuItemModel>({
2278
+ uid: 'drag-source-page-into-group',
2279
+ use: AdminLayoutMenuItemModel,
2280
+ props: {
2281
+ route: {
2282
+ id: 1,
2283
+ title: 'Page 1',
2284
+ schemaUid: 'page-1',
2285
+ type: NocoBaseDesktopRouteType.page,
2286
+ },
2287
+ },
2288
+ });
2289
+ const overModel = engine.createModel<AdminLayoutMenuItemModel>({
2290
+ uid: 'drag-target-group',
2291
+ use: AdminLayoutMenuItemModel,
2292
+ props: {
2293
+ route: {
2294
+ id: 10,
2295
+ title: 'Group 1',
2296
+ schemaUid: 'group-1',
2297
+ type: NocoBaseDesktopRouteType.group,
2298
+ },
2299
+ },
2300
+ });
2301
+
2302
+ expect(resolveAdminLayoutMenuDragMoveOptions(activeModel, overModel)).toEqual({
2303
+ sourceId: 1,
2304
+ targetId: 10,
2305
+ sortField: 'sort',
2306
+ });
2307
+ });
2308
+
2309
+ it('should keep group drag on group target as sibling reorder', () => {
2310
+ const activeModel = engine.createModel<AdminLayoutMenuItemModel>({
2311
+ uid: 'drag-source-group',
2312
+ use: AdminLayoutMenuItemModel,
2313
+ props: {
2314
+ route: {
2315
+ id: 1,
2316
+ title: 'Group 1',
2317
+ schemaUid: 'group-1',
2318
+ type: NocoBaseDesktopRouteType.group,
2319
+ },
2320
+ },
2321
+ });
2322
+ const overModel = engine.createModel<AdminLayoutMenuItemModel>({
2323
+ uid: 'drag-target-group-2',
2324
+ use: AdminLayoutMenuItemModel,
2325
+ props: {
2326
+ route: {
2327
+ id: 2,
2328
+ title: 'Group 2',
2329
+ schemaUid: 'group-2',
2330
+ type: NocoBaseDesktopRouteType.group,
2331
+ },
2332
+ },
2333
+ });
2334
+
2335
+ expect(resolveAdminLayoutMenuDragMoveOptions(activeModel, overModel)).toEqual({
2336
+ sourceId: 1,
2337
+ targetId: 2,
2338
+ sortField: 'sort',
2339
+ });
2340
+ });
2341
+ });