@nocobase/client-v2 2.2.0-alpha.1 → 2.2.0-alpha.11

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 (334) hide show
  1. package/es/APIClient.d.ts +1 -3
  2. package/es/BaseApplication.d.ts +3 -0
  3. package/es/PluginSettingsManager.d.ts +33 -0
  4. package/es/RouteRepository.d.ts +29 -6
  5. package/es/RouterManager.d.ts +15 -0
  6. package/es/authRedirect.d.ts +1 -0
  7. package/es/collection-field-interface/CollectionFieldInterface.d.ts +1 -0
  8. package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +1 -0
  9. package/es/components/category-tabs/SortableCategoryTabs.d.ts +55 -0
  10. package/es/components/category-tabs/index.d.ts +9 -0
  11. package/es/components/form/JsonTextArea.d.ts +2 -1
  12. package/es/components/form/ScanInput/useCodeScanner.d.ts +3 -2
  13. package/es/components/form/TypedVariableInput.d.ts +31 -5
  14. package/es/components/form/VariableJsonTextArea.d.ts +19 -0
  15. package/es/components/form/filter/CollectionFilter.d.ts +2 -0
  16. package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
  17. package/es/components/form/filter/CollectionFilterPanel.d.ts +2 -0
  18. package/es/components/form/filter/index.d.ts +2 -0
  19. package/es/components/form/filter/useFilterActionProps.d.ts +2 -0
  20. package/es/components/form/index.d.ts +1 -0
  21. package/es/components/index.d.ts +2 -0
  22. package/es/entry-actions/EntryActionManager.d.ts +24 -0
  23. package/es/entry-actions/index.d.ts +9 -0
  24. package/es/flow/actions/afterSuccess.d.ts +8 -1
  25. package/es/flow/actions/index.d.ts +2 -2
  26. package/es/flow/actions/linkageRules.d.ts +2 -0
  27. package/es/flow/admin-shell/BaseLayoutModel.d.ts +6 -0
  28. package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +7 -0
  29. package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
  30. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
  31. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +3 -0
  32. package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
  33. package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +5 -0
  34. package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +2 -1
  35. package/es/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.d.ts +24 -0
  36. package/es/flow/admin-shell/admin-layout/index.d.ts +1 -0
  37. package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
  38. package/es/flow/admin-shell/admin-layout/useApplications.d.ts +7 -2
  39. package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
  40. package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
  41. package/es/flow/components/FieldAssignValueInput.d.ts +9 -0
  42. package/es/flow/components/FlowRoute.d.ts +2 -2
  43. package/es/flow/components/RunJSValueEditor.d.ts +1 -0
  44. package/es/flow/components/filter/FilterGroup.d.ts +1 -0
  45. package/es/flow/components/filter/VariableFilterItem.d.ts +6 -1
  46. package/es/flow/index.d.ts +1 -0
  47. package/es/flow/internal/registerDeviceTypeContext.d.ts +10 -0
  48. package/es/flow/models/base/ActionModelCore.d.ts +2 -0
  49. package/es/flow/models/base/BlockGridModel.d.ts +3 -0
  50. package/es/flow/models/base/GridModel.d.ts +1 -1
  51. package/es/flow/models/base/PageModel/PageModel.d.ts +12 -0
  52. package/es/flow/models/base/PageModel/PageModelTabBar.d.ts +22 -0
  53. package/es/flow/models/base/PageModel/PageTabModel.d.ts +12 -0
  54. package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +5 -0
  55. package/es/flow/models/blocks/form/FormBlockModel.d.ts +4 -0
  56. package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
  57. package/es/flow/models/blocks/form/submitHandler.d.ts +1 -1
  58. package/es/flow/models/blocks/form/value-runtime/rules.d.ts +21 -0
  59. package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +30 -0
  60. package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
  61. package/es/flow/models/blocks/js-block/JSBlock.d.ts +1 -0
  62. package/es/flow/models/blocks/table/TableActionsColumnModel.d.ts +1 -0
  63. package/es/flow/models/blocks/table/TableBlockModel.d.ts +1 -0
  64. package/es/flow/models/blocks/table/TableColumnModel.d.ts +1 -0
  65. package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +1 -1
  66. package/es/flow/models/blocks/table/dragSort/dragSortSettings.d.ts +2 -1
  67. package/es/flow/models/blocks/table/dragSort/dragSortUtils.d.ts +6 -4
  68. package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +2 -0
  69. package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +6 -0
  70. package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +15 -7
  71. package/es/flow/resolveViewParamsToViewList.d.ts +1 -1
  72. package/es/flow/routeTransientInputArgs.d.ts +14 -0
  73. package/es/flow/utils/dataScopeRowSnapshot.d.ts +59 -0
  74. package/es/flow/utils/dateTimeDisplayProps.d.ts +49 -0
  75. package/es/flow/utils/formValueDeps.d.ts +32 -0
  76. package/es/flow-compat/FieldValidation.d.ts +2 -1
  77. package/es/flow-compat/fieldValidationConstants.d.ts +1 -1
  78. package/es/flow-compat/routeTypes.d.ts +1 -0
  79. package/es/index.d.ts +8 -1
  80. package/es/index.mjs +367 -181
  81. package/es/utils/getRouteRuntimeVersion.d.ts +23 -0
  82. package/es/utils/index.d.ts +1 -0
  83. package/es/utils/markdownSanitize.d.ts +11 -0
  84. package/lib/index.js +367 -181
  85. package/lib/locale/languageCodes.js +3 -1
  86. package/package.json +9 -7
  87. package/src/APIClient.ts +1 -10
  88. package/src/Application.tsx +4 -0
  89. package/src/BaseApplication.tsx +13 -6
  90. package/src/PluginSettingsManager.ts +53 -0
  91. package/src/RouteRepository.ts +151 -24
  92. package/src/RouterManager.tsx +142 -1
  93. package/src/__tests__/PluginSettingsManager.test.ts +13 -0
  94. package/src/__tests__/RouteRepository.test.ts +239 -0
  95. package/src/__tests__/RouterManager.test.ts +125 -0
  96. package/src/__tests__/app.test.tsx +73 -0
  97. package/src/__tests__/authRedirect.test.ts +17 -0
  98. package/src/__tests__/browserChecker.test.ts +61 -0
  99. package/src/__tests__/exports.test.ts +16 -0
  100. package/src/__tests__/getRouteRuntimeVersion.test.ts +68 -0
  101. package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +234 -2
  102. package/src/__tests__/plugin-manager.test.tsx +44 -2
  103. package/src/__tests__/settings-center.test.tsx +40 -1
  104. package/src/authRedirect.ts +38 -0
  105. package/src/collection-field-interface/CollectionFieldInterface.ts +1 -0
  106. package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +1 -0
  107. package/src/collection-manager/field-configure.ts +1 -1
  108. package/src/collection-manager/field-validation.ts +1 -1
  109. package/src/collection-manager/interfaces/id.ts +1 -1
  110. package/src/collection-manager/interfaces/m2m.tsx +2 -2
  111. package/src/collection-manager/interfaces/m2o.tsx +2 -2
  112. package/src/collection-manager/interfaces/nanoid.ts +1 -1
  113. package/src/collection-manager/interfaces/o2m.tsx +2 -2
  114. package/src/collection-manager/interfaces/obo.tsx +2 -2
  115. package/src/collection-manager/interfaces/oho.tsx +2 -2
  116. package/src/collection-manager/interfaces/properties/index.ts +2 -2
  117. package/src/collection-manager/interfaces/uuid.ts +1 -1
  118. package/src/components/AppComponents.tsx +19 -3
  119. package/src/components/README.md +7 -1
  120. package/src/components/README.zh-CN.md +6 -1
  121. package/src/components/category-tabs/SortableCategoryTabs.tsx +210 -0
  122. package/src/components/category-tabs/index.ts +10 -0
  123. package/src/components/form/JsonTextArea.tsx +25 -11
  124. package/src/components/form/ScanInput/CodeScanner.tsx +79 -35
  125. package/src/components/form/ScanInput/__tests__/CodeScanner.test.tsx +101 -0
  126. package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +284 -11
  127. package/src/components/form/ScanInput/useCodeScanner.ts +332 -24
  128. package/src/components/form/TypedVariableInput.tsx +452 -101
  129. package/src/components/form/VariableJsonTextArea.tsx +175 -0
  130. package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
  131. package/src/components/form/__tests__/TypedVariableInput.test.tsx +364 -12
  132. package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
  133. package/src/components/form/filter/CollectionFilter.tsx +4 -0
  134. package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
  135. package/src/components/form/filter/CollectionFilterPanel.tsx +4 -0
  136. package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
  137. package/src/components/form/filter/__tests__/useFilterActionProps.test.tsx +95 -0
  138. package/src/components/form/filter/index.ts +2 -0
  139. package/src/components/form/filter/useFilterActionProps.ts +37 -6
  140. package/src/components/form/index.tsx +1 -0
  141. package/src/components/index.ts +2 -0
  142. package/src/entry-actions/EntryActionManager.ts +76 -0
  143. package/src/entry-actions/index.ts +10 -0
  144. package/src/flow/FlowPage.tsx +38 -3
  145. package/src/flow/__tests__/FlowPage.test.tsx +201 -27
  146. package/src/flow/__tests__/FlowRoute.test.tsx +1181 -80
  147. package/src/flow/__tests__/PluginFlowEngine.test.ts +58 -0
  148. package/src/flow/__tests__/getKey.test.ts +7 -0
  149. package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +34 -0
  150. package/src/flow/actions/__tests__/actionLinkageRules.forkProps.test.ts +115 -0
  151. package/src/flow/actions/__tests__/afterSuccess.test.ts +73 -0
  152. package/src/flow/actions/__tests__/dataScopeFilter.test.ts +120 -0
  153. package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +1124 -0
  154. package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +150 -1
  155. package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +135 -0
  156. package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +19 -5
  157. package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +92 -0
  158. package/src/flow/actions/__tests__/linkageRules.tab.test.ts +171 -0
  159. package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +7 -3
  160. package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +164 -0
  161. package/src/flow/actions/__tests__/subFormFieldLinkageRules.inputArgs.test.ts +2 -2
  162. package/src/flow/actions/afterSuccess.tsx +142 -3
  163. package/src/flow/actions/customVariable.tsx +1 -2
  164. package/src/flow/actions/dataScopeFilter.ts +20 -1
  165. package/src/flow/actions/dateTimeFormat.tsx +42 -28
  166. package/src/flow/actions/index.ts +3 -1
  167. package/src/flow/actions/linkageRules.tsx +209 -47
  168. package/src/flow/actions/linkageRulesFormValueRefresh.ts +22 -130
  169. package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
  170. package/src/flow/actions/openView.tsx +59 -5
  171. package/src/flow/actions/runjs.tsx +2 -14
  172. package/src/flow/actions/validation.tsx +62 -30
  173. package/src/flow/admin-shell/BaseLayoutModel.tsx +149 -3
  174. package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +187 -42
  175. package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +1020 -110
  176. package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +74 -14
  177. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +486 -0
  178. package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +64 -8
  179. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
  180. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
  181. package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
  182. package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
  183. package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +23 -9
  184. package/src/flow/admin-shell/admin-layout/AppListRender.tsx +13 -2
  185. package/src/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.tsx +289 -0
  186. package/src/flow/admin-shell/admin-layout/HelpLite.tsx +1 -3
  187. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +435 -0
  188. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
  189. package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +518 -2
  190. package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +214 -2
  191. package/src/flow/admin-shell/admin-layout/index.ts +1 -0
  192. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
  193. package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
  194. package/src/flow/admin-shell/admin-layout/useApplications.tsx +81 -12
  195. package/src/flow/common/Markdown/Display.tsx +14 -3
  196. package/src/flow/common/Markdown/Edit.tsx +19 -7
  197. package/src/flow/common/Markdown/style.ts +4 -0
  198. package/src/flow/components/BlockItemCard.tsx +2 -2
  199. package/src/flow/components/DefaultValue.tsx +1 -2
  200. package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
  201. package/src/flow/components/FieldAssignExactDatePicker.tsx +25 -11
  202. package/src/flow/components/FieldAssignRulesEditor.tsx +128 -21
  203. package/src/flow/components/FieldAssignValueInput.tsx +91 -20
  204. package/src/flow/components/FlowRoute.tsx +256 -53
  205. package/src/flow/components/RunJSValueEditor.tsx +9 -1
  206. package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +148 -2
  207. package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +508 -4
  208. package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
  209. package/src/flow/components/__tests__/fieldAssignOptions.test.ts +151 -3
  210. package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
  211. package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
  212. package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
  213. package/src/flow/components/fieldAssignOptions.ts +155 -27
  214. package/src/flow/components/filter/FilterGroup.tsx +33 -5
  215. package/src/flow/components/filter/VariableFilterItem.tsx +158 -10
  216. package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +45 -0
  217. package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +9 -0
  218. package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +70 -1
  219. package/src/flow/flows/editMarkdownFlow.tsx +1 -1
  220. package/src/flow/getViewDiffAndUpdateHidden.tsx +1 -0
  221. package/src/flow/index.ts +4 -1
  222. package/src/flow/internal/components/Markdown/util.ts +2 -1
  223. package/src/flow/internal/registerDeviceTypeContext.ts +39 -0
  224. package/src/flow/internal/utils/operatorSchemaHelper.ts +15 -1
  225. package/src/flow/models/actions/JSActionModel.tsx +2 -7
  226. package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
  227. package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
  228. package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
  229. package/src/flow/models/base/ActionModel.tsx +21 -8
  230. package/src/flow/models/base/ActionModelCore.tsx +11 -4
  231. package/src/flow/models/base/BlockGridModel.tsx +26 -0
  232. package/src/flow/models/base/CollectionBlockModel.tsx +6 -2
  233. package/src/flow/models/base/GridModel.tsx +38 -7
  234. package/src/flow/models/base/PageModel/PageModel.tsx +387 -50
  235. package/src/flow/models/base/PageModel/PageModelTabBar.tsx +114 -0
  236. package/src/flow/models/base/PageModel/PageTabModel.tsx +249 -18
  237. package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +817 -13
  238. package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.module-isolation.test.tsx +130 -0
  239. package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.test.tsx +118 -0
  240. package/src/flow/models/base/PageModel/__tests__/PageTabModel.test.ts +1075 -7
  241. package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
  242. package/src/flow/models/base/__tests__/ActionModelCore.render.test.tsx +37 -0
  243. package/src/flow/models/base/__tests__/BlockGridModel.selectSceneActivation.test.ts +124 -0
  244. package/src/flow/models/base/__tests__/CollectionBlockModel.addAppends.test.ts +41 -0
  245. package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
  246. package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
  247. package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +59 -6
  248. package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +27 -12
  249. package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
  250. package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +36 -0
  251. package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +143 -4
  252. package/src/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.tsx +1 -1
  253. package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +56 -1
  254. package/src/flow/models/blocks/form/EditFormModel.tsx +1 -0
  255. package/src/flow/models/blocks/form/FormActionModel.tsx +1 -1
  256. package/src/flow/models/blocks/form/FormBlockModel.tsx +7 -0
  257. package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
  258. package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
  259. package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
  260. package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
  261. package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +54 -1
  262. package/src/flow/models/blocks/form/submitHandler.ts +17 -3
  263. package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +940 -75
  264. package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
  265. package/src/flow/models/blocks/form/value-runtime/runtime.ts +348 -13
  266. package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
  267. package/src/flow/models/blocks/js-block/JSBlock.tsx +225 -9
  268. package/src/flow/models/blocks/js-block/__tests__/JSBlockModel.test.tsx +150 -0
  269. package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
  270. package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +38 -14
  271. package/src/flow/models/blocks/table/TableBlockModel.tsx +42 -19
  272. package/src/flow/models/blocks/table/TableColumnModel.tsx +72 -6
  273. package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +111 -1
  274. package/src/flow/models/blocks/table/__tests__/TableBlockModel.dragSort.test.ts +127 -0
  275. package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
  276. package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +12 -0
  277. package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +1 -0
  278. package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +243 -1
  279. package/src/flow/models/blocks/table/dragSort/dragSortHooks.tsx +28 -17
  280. package/src/flow/models/blocks/table/dragSort/dragSortSettings.ts +13 -6
  281. package/src/flow/models/blocks/table/dragSort/dragSortUtils.ts +15 -2
  282. package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +1 -1
  283. package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +31 -7
  284. package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +61 -17
  285. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +141 -19
  286. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
  287. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +197 -0
  288. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableFieldModel.reset.test.ts +180 -0
  289. package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -4
  290. package/src/flow/models/fields/AssociationFieldModel/__tests__/AssociationFieldModel.updateAssociation.test.ts +72 -0
  291. package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +23 -0
  292. package/src/flow/models/fields/ClickableFieldModel.tsx +5 -0
  293. package/src/flow/models/fields/DateTimeFieldModel/__tests__/DateTimeNoTzFieldModel.dateLimit.test.tsx +149 -0
  294. package/src/flow/models/fields/DateTimeFieldModel/dateLimit.ts +149 -113
  295. package/src/flow/models/fields/DisplayDateTimeFieldModel.tsx +29 -1
  296. package/src/flow/models/fields/InputFieldModel.tsx +40 -2
  297. package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
  298. package/src/flow/models/fields/JSFieldModel.tsx +2 -7
  299. package/src/flow/models/fields/JSItemModel.tsx +2 -14
  300. package/src/flow/models/fields/SelectFieldModel.tsx +6 -4
  301. package/src/flow/models/fields/TextareaFieldModel.tsx +72 -3
  302. package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
  303. package/src/flow/models/fields/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
  304. package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +117 -1
  305. package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
  306. package/src/flow/models/fields/__tests__/TextareaFieldModel.test.tsx +131 -0
  307. package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
  308. package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +20 -10
  309. package/src/flow/models/fields/mobile-components/MobileSelect.tsx +24 -12
  310. package/src/flow/models/topbar/TopbarActionModel.tsx +168 -10
  311. package/src/flow/resolveViewParamsToViewList.tsx +11 -3
  312. package/src/flow/routeTransientInputArgs.ts +27 -0
  313. package/src/flow/utils/__tests__/dateTimeFormat.test.ts +300 -0
  314. package/src/flow/utils/dataScopeFormValueClear.ts +219 -81
  315. package/src/flow/utils/dataScopeRowSnapshot.ts +616 -0
  316. package/src/flow/utils/dateTimeDisplayProps.ts +135 -0
  317. package/src/flow/utils/formValueDeps.ts +170 -0
  318. package/src/flow-compat/FieldValidation.tsx +122 -60
  319. package/src/flow-compat/Popover.tsx +43 -4
  320. package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
  321. package/src/flow-compat/fieldValidationConstants.ts +1 -1
  322. package/src/flow-compat/routeTypes.ts +1 -0
  323. package/src/index.ts +14 -1
  324. package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
  325. package/src/locale/languageCodes.ts +3 -1
  326. package/src/nocobase-buildin-plugin/index.tsx +63 -15
  327. package/src/settings-center/AdminSettingsLayout.tsx +10 -2
  328. package/src/settings-center/SystemSettingsPage.tsx +1 -2
  329. package/src/settings-center/plugin-manager/PluginCard.tsx +2 -2
  330. package/src/settings-center/plugin-manager/index.tsx +3 -0
  331. package/src/settings-center/utils.tsx +0 -6
  332. package/src/utils/getRouteRuntimeVersion.ts +185 -0
  333. package/src/utils/index.tsx +1 -0
  334. package/src/utils/markdownSanitize.ts +88 -0
@@ -0,0 +1,616 @@
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 type { FlowContext } from '@nocobase/flow-engine';
11
+ import { cloneDeep, isEqual } from 'lodash';
12
+ import { namePathToPathKey } from '../models/blocks/form/value-runtime/path';
13
+ import { getSubTableRowIdentity } from '../models/fields/AssociationFieldModel/SubTableFieldModel/rowIdentity';
14
+ import { getChangedPathsFromPayload, isNamePathPrefix, type FieldIndexEntry, type NamePath } from './formValueDeps';
15
+
16
+ export type FilterTargetKey = string | string[] | null | undefined;
17
+
18
+ export type RowIdentity = string;
19
+
20
+ export type RowScopedFieldIndexEntry = FieldIndexEntry & {
21
+ filterTargetKey?: FilterTargetKey;
22
+ };
23
+
24
+ export type RowScope = {
25
+ entries: RowScopedFieldIndexEntry[];
26
+ tailPath: NamePath;
27
+ identityTailPaths: NamePath[];
28
+ };
29
+
30
+ export type DataScopeValuePath = {
31
+ path: NamePath;
32
+ rowScope?: RowScope;
33
+ };
34
+
35
+ export type DataScopeStructuralPath = {
36
+ path: NamePath;
37
+ kind: 'index' | 'length';
38
+ rowScope?: RowScope;
39
+ };
40
+
41
+ export type DataScopeTriggerPath = {
42
+ path: NamePath;
43
+ includeChildren: boolean;
44
+ };
45
+
46
+ export type DataScopeClearDeps = {
47
+ wildcard: boolean;
48
+ valuePaths: DataScopeValuePath[];
49
+ structuralPaths: DataScopeStructuralPath[];
50
+ triggerPaths: DataScopeTriggerPath[];
51
+ };
52
+
53
+ export type DataScopeSnapshotValue = {
54
+ value: unknown;
55
+ rowIdentities?: Array<RowIdentity | null>;
56
+ rowDetached?: boolean;
57
+ };
58
+
59
+ export type DataScopeClearSnapshot = {
60
+ complete: boolean;
61
+ rowDetached: boolean;
62
+ rowMissing: boolean;
63
+ values: Map<string, DataScopeSnapshotValue>;
64
+ structures: Map<string, DataScopeSnapshotValue>;
65
+ };
66
+
67
+ export type DataScopeClearChangeStatus = {
68
+ status: 'changed' | 'unchanged' | 'unknown';
69
+ snapshot: DataScopeClearSnapshot | null;
70
+ };
71
+
72
+ function normalizeFilterTargetKey(raw: unknown): FilterTargetKey {
73
+ if (Array.isArray(raw)) {
74
+ const keys = raw.filter((key): key is string => typeof key === 'string' && !!key);
75
+ return keys.length ? keys : 'id';
76
+ }
77
+ return typeof raw === 'string' && raw ? raw : 'id';
78
+ }
79
+
80
+ function getAssociationTargetKey(field: any): FilterTargetKey {
81
+ return normalizeFilterTargetKey(
82
+ field?.targetCollection?.filterTargetKey ?? field?.targetCollection?.filterByTk ?? field?.targetKey,
83
+ );
84
+ }
85
+
86
+ function getRootCollection(ctx: FlowContext) {
87
+ const model: any = ctx.model;
88
+ return (
89
+ model?.context?.blockModel?.context?.collection ??
90
+ model?.context?.formBlock?.context?.collection ??
91
+ model?.context?.rootCollection ??
92
+ (ctx as any)?.rootCollection ??
93
+ (ctx as any)?.collection ??
94
+ model?.context?.collectionField?.collection ??
95
+ model?.context?.collection
96
+ );
97
+ }
98
+
99
+ function getFallbackTargetKey(ctx: FlowContext): FilterTargetKey {
100
+ const model: any = ctx.model;
101
+ return normalizeFilterTargetKey(
102
+ model?.context?.collection?.filterTargetKey ??
103
+ model?.context?.collection?.filterByTk ??
104
+ model?.context?.collectionField?.targetCollection?.filterTargetKey ??
105
+ model?.context?.collectionField?.targetCollection?.filterByTk ??
106
+ model?.context?.collectionField?.targetKey,
107
+ );
108
+ }
109
+
110
+ export function applyDataScopeFieldIndexTargetKeys(
111
+ ctx: FlowContext,
112
+ entries: FieldIndexEntry[],
113
+ ): RowScopedFieldIndexEntry[] {
114
+ let collection = getRootCollection(ctx);
115
+ const fallbackTargetKey = getFallbackTargetKey(ctx);
116
+ return entries.map((entry) => {
117
+ let filterTargetKey: FilterTargetKey = fallbackTargetKey;
118
+ if (collection?.getField) {
119
+ const field = collection.getField(entry.name);
120
+ if (field?.isAssociationField?.() || field?.targetCollection || field?.targetKey) {
121
+ filterTargetKey = getAssociationTargetKey(field);
122
+ collection = field?.targetCollection;
123
+ }
124
+ }
125
+ return { ...entry, filterTargetKey };
126
+ });
127
+ }
128
+
129
+ export function createDataScopeRowScope(
130
+ entries: RowScopedFieldIndexEntry[],
131
+ parentDepth: number,
132
+ tailPath: NamePath,
133
+ ): RowScope | undefined {
134
+ const targetIndex = entries.length - 1 - parentDepth;
135
+ if (targetIndex < 0) return undefined;
136
+ const targetEntry = entries[targetIndex];
137
+ const targetKey = targetEntry?.filterTargetKey;
138
+ const identityTailPaths = Array.isArray(targetKey)
139
+ ? targetKey.map((key) => [key])
140
+ : typeof targetKey === 'string' && targetKey
141
+ ? [[targetKey]]
142
+ : [];
143
+ return {
144
+ entries: entries.slice(0, targetIndex + 1).map((entry) => ({ ...entry })),
145
+ tailPath,
146
+ identityTailPaths,
147
+ };
148
+ }
149
+
150
+ function hasOwnValue(source: unknown, key: string | number) {
151
+ if (source == null) return false;
152
+ if (Array.isArray(source) && typeof key === 'number') {
153
+ return key >= 0 && key < source.length;
154
+ }
155
+ if (typeof source !== 'object') return false;
156
+ return Object.prototype.hasOwnProperty.call(source, key);
157
+ }
158
+
159
+ function getValueAtPath(source: unknown, path: NamePath): { found: boolean; value?: unknown } {
160
+ let cursor = source;
161
+ for (const seg of path) {
162
+ if (!hasOwnValue(cursor, seg)) {
163
+ return { found: false };
164
+ }
165
+ cursor = (cursor as Record<string | number, unknown>)[seg];
166
+ }
167
+ return { found: true, value: cursor };
168
+ }
169
+
170
+ function getSnapshotSourceFromPayload(payload: unknown) {
171
+ const payloadObj = payload as { allValuesSnapshot?: unknown; allValues?: unknown } | undefined;
172
+ return payloadObj?.allValuesSnapshot ?? payloadObj?.allValues;
173
+ }
174
+
175
+ function getRowIdentity(row: unknown, filterTargetKey: FilterTargetKey): RowIdentity | null {
176
+ if (!row || typeof row !== 'object') return null;
177
+ return getSubTableRowIdentity(row as Record<string, unknown>, filterTargetKey);
178
+ }
179
+
180
+ function getRowScopePath(rowScope: RowScope): NamePath {
181
+ const path: NamePath = [];
182
+ for (const entry of rowScope.entries) {
183
+ path.push(entry.name, entry.index);
184
+ }
185
+ return path;
186
+ }
187
+
188
+ function shouldRefreshRowIdentityFromPayload(
189
+ payload: unknown,
190
+ rowScope: RowScope,
191
+ previousValue?: DataScopeSnapshotValue,
192
+ changedPaths?: NamePath[],
193
+ ) {
194
+ if (previousValue?.rowDetached) return false;
195
+ const rowPath = getRowScopePath(rowScope);
196
+ if (!rowPath.length || !rowScope.identityTailPaths.length) return false;
197
+ const identityPaths = rowScope.identityTailPaths.map((path) => [...rowPath, ...path]);
198
+ return (changedPaths ?? getChangedPathsFromPayload(payload)).some((changedPath) =>
199
+ identityPaths.some((identityPath) => isNamePathPrefix(identityPath, changedPath)),
200
+ );
201
+ }
202
+
203
+ function findRowIndexByIdentity(
204
+ rows: unknown,
205
+ identity: RowIdentity | null | undefined,
206
+ filterTargetKey: FilterTargetKey,
207
+ ) {
208
+ if (!Array.isArray(rows) || !identity) return -1;
209
+ return rows.findIndex((row) => getRowIdentity(row, filterTargetKey) === identity);
210
+ }
211
+
212
+ function getRowScopedPathFromSource(
213
+ source: unknown,
214
+ rowScope: RowScope,
215
+ previousRowIdentities?: Array<RowIdentity | null>,
216
+ allowIndexFallbackOnIdentityMiss?: boolean,
217
+ ): {
218
+ found: boolean;
219
+ rowMissing?: boolean;
220
+ path?: NamePath;
221
+ rowIndex?: number;
222
+ rowIdentities?: Array<RowIdentity | null>;
223
+ } {
224
+ let currentPath: NamePath = [];
225
+ let currentRowIndex = -1;
226
+ const rowIdentities: Array<RowIdentity | null> = [];
227
+
228
+ for (let index = 0; index < rowScope.entries.length; index++) {
229
+ const entry = rowScope.entries[index];
230
+ const listPath = [...currentPath, entry.name];
231
+ const listResult = getValueAtPath(source, listPath);
232
+ if (!listResult.found) {
233
+ return { found: false };
234
+ }
235
+ if (!Array.isArray(listResult.value)) {
236
+ return { found: false };
237
+ }
238
+
239
+ const previousIdentity = previousRowIdentities?.[index];
240
+ const matchedIndex = findRowIndexByIdentity(listResult.value, previousIdentity, entry.filterTargetKey);
241
+ const rowIndex = matchedIndex >= 0 ? matchedIndex : entry.index;
242
+ if (rowIndex < 0 || rowIndex >= listResult.value.length) {
243
+ return previousIdentity ? { found: false, rowMissing: true } : { found: false };
244
+ }
245
+
246
+ const row = listResult.value[rowIndex];
247
+ if (previousIdentity && matchedIndex < 0 && !allowIndexFallbackOnIdentityMiss) {
248
+ return { found: false, rowMissing: true };
249
+ }
250
+
251
+ rowIdentities.push(getRowIdentity(row, entry.filterTargetKey));
252
+ currentRowIndex = rowIndex;
253
+ currentPath = [...listPath, rowIndex];
254
+ }
255
+
256
+ return {
257
+ found: true,
258
+ path: [...currentPath, ...rowScope.tailPath],
259
+ rowIndex: currentRowIndex,
260
+ rowIdentities,
261
+ };
262
+ }
263
+
264
+ function getPathValue(formBlock: any, payload: unknown, path: NamePath): { found: boolean; value?: unknown } {
265
+ const payloadSource = getSnapshotSourceFromPayload(payload);
266
+ const payloadValue = getValueAtPath(payloadSource, path);
267
+ if (payloadValue.found) {
268
+ return payloadValue;
269
+ }
270
+
271
+ const form = formBlock?.context?.form;
272
+ if (typeof form?.getFieldValue === 'function') {
273
+ return { found: true, value: form.getFieldValue(path) };
274
+ }
275
+
276
+ return getValueAtPath(formBlock?.context?.formValues, path);
277
+ }
278
+
279
+ function getRowScopedPathValue(
280
+ formBlock: any,
281
+ payload: unknown,
282
+ valuePath: DataScopeValuePath,
283
+ previousValue?: DataScopeSnapshotValue,
284
+ changedPaths?: NamePath[],
285
+ ): { found: boolean; rowMissing?: boolean; value?: unknown; rowIdentities?: Array<RowIdentity | null> } {
286
+ const rowScope = valuePath.rowScope;
287
+ if (!rowScope) {
288
+ return getPathValue(formBlock, payload, valuePath.path);
289
+ }
290
+ if (previousValue?.rowDetached) {
291
+ return { found: false, rowMissing: true };
292
+ }
293
+
294
+ const allowIndexFallbackOnIdentityMiss = shouldRefreshRowIdentityFromPayload(
295
+ payload,
296
+ rowScope,
297
+ previousValue,
298
+ changedPaths,
299
+ );
300
+ const sourceCandidates = [getSnapshotSourceFromPayload(payload), formBlock?.context?.formValues];
301
+ for (const source of sourceCandidates) {
302
+ const scopedPath = getRowScopedPathFromSource(
303
+ source,
304
+ rowScope,
305
+ previousValue?.rowIdentities,
306
+ allowIndexFallbackOnIdentityMiss,
307
+ );
308
+ if (scopedPath.rowMissing) {
309
+ return { found: false, rowMissing: true };
310
+ }
311
+ if (!scopedPath.found || !scopedPath.path) {
312
+ continue;
313
+ }
314
+ const result = getValueAtPath(source, scopedPath.path);
315
+ if (result.found) {
316
+ return {
317
+ found: true,
318
+ value: result.value,
319
+ rowIdentities: scopedPath.rowIdentities,
320
+ };
321
+ }
322
+ }
323
+
324
+ const form = formBlock?.context?.form;
325
+ if (typeof form?.getFieldValue === 'function') {
326
+ return {
327
+ found: true,
328
+ value: form.getFieldValue(valuePath.path),
329
+ rowIdentities: previousValue?.rowIdentities,
330
+ };
331
+ }
332
+
333
+ return { found: false };
334
+ }
335
+
336
+ function getStructuralLengthValue(value: unknown) {
337
+ return Array.isArray(value) ? value.length : value;
338
+ }
339
+
340
+ function getStructuralIndexValueFromList(
341
+ value: unknown,
342
+ structuralPath: DataScopeStructuralPath,
343
+ previousValue?: DataScopeSnapshotValue,
344
+ ): { found: boolean; rowMissing?: boolean; value?: unknown; rowIdentities?: Array<RowIdentity | null> } {
345
+ if (!Array.isArray(value)) {
346
+ return { found: true, value };
347
+ }
348
+
349
+ const previousRowIdentity = previousValue?.rowIdentities?.[previousValue.rowIdentities.length - 1];
350
+ const entry = structuralPath.rowScope?.entries[structuralPath.rowScope.entries.length - 1];
351
+ const matchedIndex = findRowIndexByIdentity(value, previousRowIdentity, entry?.filterTargetKey);
352
+ if (matchedIndex >= 0) {
353
+ return {
354
+ found: true,
355
+ value: matchedIndex,
356
+ rowIdentities: previousValue?.rowIdentities,
357
+ };
358
+ }
359
+
360
+ if (previousRowIdentity) {
361
+ return { found: false, rowMissing: true };
362
+ }
363
+
364
+ if (!entry || entry.index < 0 || entry.index >= value.length) {
365
+ return { found: false };
366
+ }
367
+
368
+ return {
369
+ found: true,
370
+ value: entry.index,
371
+ rowIdentities: [getRowIdentity(value[entry.index], entry.filterTargetKey)],
372
+ };
373
+ }
374
+
375
+ function getStructuralPathValue(
376
+ formBlock: any,
377
+ payload: unknown,
378
+ structuralPath: DataScopeStructuralPath,
379
+ previousValue?: DataScopeSnapshotValue,
380
+ changedPaths?: NamePath[],
381
+ ): { found: boolean; rowMissing?: boolean; value?: unknown; rowIdentities?: Array<RowIdentity | null> } {
382
+ if (structuralPath.kind === 'length') {
383
+ if (previousValue?.rowDetached) {
384
+ return { found: false, rowMissing: true };
385
+ }
386
+ let rowIdentities = previousValue?.rowIdentities;
387
+ const rowScope = structuralPath.rowScope;
388
+ if (rowScope) {
389
+ const allowIndexFallbackOnIdentityMiss = shouldRefreshRowIdentityFromPayload(
390
+ payload,
391
+ rowScope,
392
+ previousValue,
393
+ changedPaths,
394
+ );
395
+ const sourceCandidates = [getSnapshotSourceFromPayload(payload), formBlock?.context?.formValues];
396
+ for (const source of sourceCandidates) {
397
+ const scopedPath = getRowScopedPathFromSource(
398
+ source,
399
+ rowScope,
400
+ previousValue?.rowIdentities,
401
+ allowIndexFallbackOnIdentityMiss,
402
+ );
403
+ if (scopedPath.rowMissing) {
404
+ return { found: false, rowMissing: true };
405
+ }
406
+ if (scopedPath.found) {
407
+ rowIdentities = scopedPath.rowIdentities;
408
+ break;
409
+ }
410
+ }
411
+ }
412
+ const result = getPathValue(formBlock, payload, structuralPath.path);
413
+ return result.found ? { found: true, value: getStructuralLengthValue(result.value), rowIdentities } : result;
414
+ }
415
+ if (previousValue?.rowDetached) {
416
+ return { found: false, rowMissing: true };
417
+ }
418
+
419
+ const rowScope = structuralPath.rowScope;
420
+ if (rowScope) {
421
+ const allowIndexFallbackOnIdentityMiss = shouldRefreshRowIdentityFromPayload(
422
+ payload,
423
+ rowScope,
424
+ previousValue,
425
+ changedPaths,
426
+ );
427
+ const sourceCandidates = [getSnapshotSourceFromPayload(payload), formBlock?.context?.formValues];
428
+ for (const source of sourceCandidates) {
429
+ const scopedPath = getRowScopedPathFromSource(
430
+ source,
431
+ rowScope,
432
+ previousValue?.rowIdentities,
433
+ allowIndexFallbackOnIdentityMiss,
434
+ );
435
+ if (scopedPath.rowMissing) {
436
+ return { found: false, rowMissing: true };
437
+ }
438
+ if (scopedPath.found && typeof scopedPath.rowIndex === 'number') {
439
+ return {
440
+ found: true,
441
+ value: scopedPath.rowIndex,
442
+ rowIdentities: scopedPath.rowIdentities,
443
+ };
444
+ }
445
+ }
446
+ }
447
+
448
+ const result = getPathValue(formBlock, payload, structuralPath.path);
449
+ if (!result.found) {
450
+ return result;
451
+ }
452
+ return getStructuralIndexValueFromList(result.value, structuralPath, previousValue);
453
+ }
454
+
455
+ export function buildDepsSnapshot(
456
+ deps: DataScopeClearDeps,
457
+ formBlock: any,
458
+ payload?: unknown,
459
+ ): DataScopeClearSnapshot | null {
460
+ if (deps.wildcard) return null;
461
+
462
+ const snapshot: DataScopeClearSnapshot = {
463
+ complete: true,
464
+ rowDetached: false,
465
+ rowMissing: false,
466
+ values: new Map(),
467
+ structures: new Map(),
468
+ };
469
+
470
+ for (const valuePath of deps.valuePaths) {
471
+ const key = namePathToPathKey(valuePath.path);
472
+ const result = getRowScopedPathValue(formBlock, payload, valuePath);
473
+ if (result.rowMissing) {
474
+ snapshot.rowMissing = true;
475
+ snapshot.complete = false;
476
+ continue;
477
+ }
478
+ if (!result.found) {
479
+ snapshot.complete = false;
480
+ continue;
481
+ }
482
+ snapshot.values.set(key, {
483
+ value: cloneDeep(result.value),
484
+ rowIdentities: result.rowIdentities,
485
+ rowDetached: false,
486
+ });
487
+ }
488
+
489
+ for (const structuralPath of deps.structuralPaths) {
490
+ const result = getStructuralPathValue(formBlock, payload, structuralPath);
491
+ if (result.rowMissing) {
492
+ snapshot.rowMissing = true;
493
+ snapshot.complete = false;
494
+ continue;
495
+ }
496
+ if (!result.found) {
497
+ snapshot.complete = false;
498
+ continue;
499
+ }
500
+ snapshot.structures.set(`${structuralPath.kind}:${namePathToPathKey(structuralPath.path)}`, {
501
+ value: cloneDeep(result.value),
502
+ rowIdentities: result.rowIdentities,
503
+ rowDetached: false,
504
+ });
505
+ }
506
+
507
+ return snapshot;
508
+ }
509
+
510
+ function rebuildDepsSnapshot(
511
+ deps: DataScopeClearDeps,
512
+ formBlock: any,
513
+ payload: unknown,
514
+ previousSnapshot: DataScopeClearSnapshot,
515
+ changedPaths: NamePath[],
516
+ ): DataScopeClearSnapshot | null {
517
+ if (deps.wildcard) return null;
518
+
519
+ const snapshot: DataScopeClearSnapshot = {
520
+ complete: true,
521
+ rowDetached: false,
522
+ rowMissing: false,
523
+ values: new Map(),
524
+ structures: new Map(),
525
+ };
526
+
527
+ for (const valuePath of deps.valuePaths) {
528
+ const key = namePathToPathKey(valuePath.path);
529
+ const previousValue = previousSnapshot.values.get(key);
530
+ const result = getRowScopedPathValue(formBlock, payload, valuePath, previousValue, changedPaths);
531
+ if (result.rowMissing) {
532
+ snapshot.rowMissing = true;
533
+ snapshot.rowDetached = true;
534
+ if (previousValue) {
535
+ snapshot.values.set(key, { ...previousValue, rowDetached: true });
536
+ } else {
537
+ snapshot.complete = false;
538
+ }
539
+ continue;
540
+ }
541
+ if (!result.found) {
542
+ snapshot.complete = false;
543
+ continue;
544
+ }
545
+ snapshot.values.set(key, {
546
+ value: cloneDeep(result.value),
547
+ rowIdentities: result.rowIdentities ?? previousValue?.rowIdentities,
548
+ rowDetached: false,
549
+ });
550
+ }
551
+
552
+ for (const structuralPath of deps.structuralPaths) {
553
+ const key = `${structuralPath.kind}:${namePathToPathKey(structuralPath.path)}`;
554
+ const previousValue = previousSnapshot.structures.get(key);
555
+ const result = getStructuralPathValue(formBlock, payload, structuralPath, previousValue, changedPaths);
556
+ if (result.rowMissing) {
557
+ snapshot.rowMissing = true;
558
+ snapshot.rowDetached = true;
559
+ if (previousValue) {
560
+ snapshot.structures.set(key, { ...previousValue, rowDetached: true });
561
+ } else {
562
+ snapshot.complete = false;
563
+ }
564
+ continue;
565
+ }
566
+ if (!result.found) {
567
+ snapshot.complete = false;
568
+ continue;
569
+ }
570
+ snapshot.structures.set(key, {
571
+ value: cloneDeep(result.value),
572
+ rowIdentities: result.rowIdentities ?? previousValue?.rowIdentities,
573
+ rowDetached: false,
574
+ });
575
+ }
576
+
577
+ return snapshot;
578
+ }
579
+
580
+ function snapshotValuesEqual(prev: Map<string, DataScopeSnapshotValue>, next: Map<string, DataScopeSnapshotValue>) {
581
+ if (prev.size !== next.size) return false;
582
+ for (const [key, value] of prev.entries()) {
583
+ if (!next.has(key) || !isEqual(value.value, next.get(key)?.value)) {
584
+ return false;
585
+ }
586
+ }
587
+ return true;
588
+ }
589
+
590
+ export function getDepsChangeStatus(
591
+ deps: DataScopeClearDeps,
592
+ formBlock: any,
593
+ payload: unknown,
594
+ snapshot: DataScopeClearSnapshot | null,
595
+ ): DataScopeClearChangeStatus {
596
+ if (deps.wildcard || !snapshot?.complete) {
597
+ return { status: 'unknown', snapshot: buildDepsSnapshot(deps, formBlock, payload) };
598
+ }
599
+
600
+ const nextSnapshot = rebuildDepsSnapshot(deps, formBlock, payload, snapshot, getChangedPathsFromPayload(payload));
601
+ if (nextSnapshot?.rowMissing) {
602
+ return { status: 'unchanged', snapshot: { ...nextSnapshot, rowMissing: false } };
603
+ }
604
+ if (!nextSnapshot?.complete) {
605
+ return { status: 'unknown', snapshot: nextSnapshot };
606
+ }
607
+
608
+ const changed =
609
+ !snapshotValuesEqual(snapshot.values, nextSnapshot.values) ||
610
+ !snapshotValuesEqual(snapshot.structures, nextSnapshot.structures);
611
+
612
+ return {
613
+ status: changed ? 'changed' : 'unchanged',
614
+ snapshot: nextSnapshot,
615
+ };
616
+ }