@rebasepro/admin 0.8.0 → 0.9.1-canary.09aaf62

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 (408) hide show
  1. package/README.md +26 -26
  2. package/dist/{CollectionEditorDialog-BO_aQ-Z4.js → CollectionEditorDialog-DbPpDDwb.js} +40 -18
  3. package/dist/CollectionEditorDialog-DbPpDDwb.js.map +1 -0
  4. package/dist/{PropertyEditView-DKzOpMjR.js → PropertyEditView-DfJbZ67t.js} +81 -73
  5. package/dist/PropertyEditView-DfJbZ67t.js.map +1 -0
  6. package/dist/{RouterCollectionsStudioView-BQTIExjA.js → RouterCollectionsStudioView-C6XQ7Il5.js} +5 -5
  7. package/dist/RouterCollectionsStudioView-C6XQ7Il5.js.map +1 -0
  8. package/dist/collection_editor/_cms_internals.d.ts +3 -3
  9. package/dist/collection_editor/api/generateCollectionApi.d.ts +8 -8
  10. package/dist/collection_editor/extensibility_types.d.ts +3 -3
  11. package/dist/collection_editor/index.d.ts +2 -2
  12. package/dist/collection_editor/pgColumnToProperty.d.ts +3 -3
  13. package/dist/collection_editor/serializable_types.d.ts +7 -7
  14. package/dist/collection_editor/serializable_utils.d.ts +8 -8
  15. package/dist/collection_editor/types/collection_editor_controller.d.ts +5 -5
  16. package/dist/collection_editor/types/collection_inference.d.ts +2 -2
  17. package/dist/collection_editor/types/config_controller.d.ts +7 -7
  18. package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +2 -2
  19. package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +2 -2
  20. package/dist/collection_editor/ui/KanbanSetupAction.d.ts +2 -2
  21. package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +2 -2
  22. package/dist/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.d.ts +3 -3
  23. package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +2 -2
  24. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +4 -4
  25. package/dist/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
  26. package/dist/collection_editor/ui/collection_editor/CollectionJsonImportDialog.d.ts +2 -2
  27. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +4 -4
  28. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +2 -2
  29. package/dist/collection_editor/ui/collection_editor/CollectionsStudioView.d.ts +2 -2
  30. package/dist/collection_editor/ui/collection_editor/EntityActionsEditTab.d.ts +2 -2
  31. package/dist/collection_editor/ui/collection_editor/GeneralSettingsForm.d.ts +2 -2
  32. package/dist/collection_editor/ui/collection_editor/GetCodeDialog.d.ts +2 -2
  33. package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +5 -5
  34. package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +3 -3
  35. package/dist/collection_editor/ui/collection_editor/SwitchControl.d.ts +1 -1
  36. package/dist/collection_editor/ui/collection_editor/templates/blog_template.d.ts +2 -2
  37. package/dist/collection_editor/ui/collection_editor/templates/pages_template.d.ts +2 -2
  38. package/dist/collection_editor/ui/collection_editor/templates/products_template.d.ts +2 -2
  39. package/dist/collection_editor/ui/collection_editor/templates/users_template.d.ts +2 -2
  40. package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +2 -2
  41. package/dist/collection_editor/useSafeSnackbarController.d.ts +1 -1
  42. package/dist/collection_editor/validateCollectionJson.d.ts +2 -2
  43. package/dist/collection_editor_ui.js +5 -5
  44. package/dist/collection_editor_ui.js.map +1 -1
  45. package/dist/components/CollectionPanel.d.ts +4 -4
  46. package/dist/components/{EntityCollectionTable/EntityCollectionRowActions.d.ts → CollectionTableBinding/CollectionRowActions.d.ts} +3 -3
  47. package/dist/components/CollectionTableBinding/CollectionTableBinding.d.ts +28 -0
  48. package/dist/components/{EntityCollectionTable/EntityCollectionTableProps.d.ts → CollectionTableBinding/CollectionTableBindingProps.d.ts} +2 -2
  49. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableMultipleRelationField.d.ts +2 -2
  50. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableReferenceField.d.ts +2 -2
  51. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationField.d.ts +2 -2
  52. package/dist/components/CollectionTableBinding/index.d.ts +6 -0
  53. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCell.d.ts +1 -1
  54. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/common.d.ts +2 -2
  55. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/PopupFormField.d.ts +3 -3
  56. package/dist/components/{EntityCollectionTable → CollectionTableBinding}/table_bindings.d.ts +1 -1
  57. package/dist/components/{EntityCollectionView/EntityBoardCard.d.ts → CollectionViewBinding/BoardCardBinding.d.ts} +8 -8
  58. package/dist/components/{EntityCollectionView/EntityCollectionBoardView.d.ts → CollectionViewBinding/CollectionBoardViewBinding.d.ts} +4 -4
  59. package/dist/components/{EntityCollectionView/EntityCollectionCardView.d.ts → CollectionViewBinding/CollectionCardViewBinding.d.ts} +5 -5
  60. package/dist/components/{EntityCollectionView/EntityCollectionListView.d.ts → CollectionViewBinding/CollectionListViewBinding.d.ts} +4 -4
  61. package/dist/components/{EntityCollectionView/EntityCollectionViewActions.d.ts → CollectionViewBinding/CollectionViewActions.d.ts} +4 -4
  62. package/dist/components/{EntityCollectionView/EntityCollectionView.d.ts → CollectionViewBinding/CollectionViewBinding.d.ts} +4 -4
  63. package/dist/components/{EntityCollectionView/EntityCollectionViewStartActions.d.ts → CollectionViewBinding/CollectionViewStartActions.d.ts} +4 -4
  64. package/dist/components/CollectionViewBinding/EntityCardBinding.d.ts +21 -0
  65. package/dist/components/{EntityCollectionView → CollectionViewBinding}/SplitListView.d.ts +3 -3
  66. package/dist/components/{EntityCollectionView → CollectionViewBinding}/hooks/useCollectionInlineEditor.d.ts +3 -3
  67. package/dist/components/{EntityCollectionView → CollectionViewBinding}/hooks/useKanbanDragAndDrop.d.ts +2 -2
  68. package/dist/components/{EntityCollectionView → CollectionViewBinding}/useBoardDataController.d.ts +2 -2
  69. package/dist/components/{EntityCollectionView/useEntityPreviewSlots.d.ts → CollectionViewBinding/usePreviewSlots.d.ts} +5 -5
  70. package/dist/components/DeleteEntityDialog.d.ts +4 -4
  71. package/dist/components/{EntityDetailView.d.ts → DetailViewBinding.d.ts} +5 -5
  72. package/dist/components/EditFormActions.d.ts +3 -0
  73. package/dist/components/{EntityEditView.d.ts → EditViewBinding.d.ts} +9 -9
  74. package/dist/components/{EntityPreview.d.ts → EntityPreviewBinding.d.ts} +13 -13
  75. package/dist/components/EntityViewBinding.d.ts +13 -0
  76. package/dist/components/{EntityJsonPreview.d.ts → JsonPreviewBinding.d.ts} +1 -1
  77. package/dist/components/{RebaseCMS.d.ts → RebaseAdmin.d.ts} +2 -2
  78. package/dist/components/RebaseLayout.d.ts +5 -4
  79. package/dist/components/RebaseNavigation.d.ts +1 -1
  80. package/dist/components/RebaseShell.d.ts +1 -0
  81. package/dist/components/ReferenceTable/{EntitySelectionTable.d.ts → SelectionTableBinding.d.ts} +5 -5
  82. package/dist/components/SelectableTable/SelectableTable.d.ts +6 -6
  83. package/dist/components/SelectableTable/SelectableTableContext.d.ts +3 -3
  84. package/dist/components/SelectableTable/SelectionStore.d.ts +2 -2
  85. package/dist/components/SelectableTable/filters/BooleanFilterField.d.ts +6 -1
  86. package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +7 -1
  87. package/dist/components/SelectableTable/filters/FilterFieldBinding.d.ts +40 -0
  88. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +7 -1
  89. package/dist/components/SelectableTable/filters/RelationFilterField.d.ts +7 -1
  90. package/dist/components/SelectableTable/filters/StringNumberFilterField.d.ts +7 -1
  91. package/dist/components/SideDialogs.d.ts +1 -1
  92. package/dist/components/SidePanelBinding.d.ts +11 -0
  93. package/dist/components/{SideEntityProvider.d.ts → SidePanelProvider.d.ts} +7 -7
  94. package/dist/components/history/EntityHistoryEntry.d.ts +2 -2
  95. package/dist/components/history/LastEditedByIndicator.d.ts +2 -2
  96. package/dist/components/index.d.ts +15 -14
  97. package/dist/contexts/SidePanelControllerContext.d.ts +3 -0
  98. package/dist/data_export/export/ExportCollectionAction.d.ts +3 -3
  99. package/dist/data_import/components/ImportSaveInProgress.d.ts +2 -2
  100. package/dist/editor.js +1 -1
  101. package/dist/editor.js.map +1 -1
  102. package/dist/form/EntityForm.d.ts +1 -1
  103. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  104. package/dist/form/components/LocalChangesMenu.d.ts +1 -1
  105. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  106. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
  107. package/dist/form/form_utils.d.ts +2 -2
  108. package/dist/{history-B3cqBzEV.js → history-GSa4BgDt.js} +7 -7
  109. package/dist/history-GSa4BgDt.js.map +1 -0
  110. package/dist/hooks/index.d.ts +4 -4
  111. package/dist/hooks/navigation/contexts/CollectionRegistryContext.d.ts +2 -2
  112. package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +5 -5
  113. package/dist/hooks/navigation/useNavigationResolution.d.ts +4 -4
  114. package/dist/hooks/navigation/useResolvedCollections.d.ts +7 -7
  115. package/dist/hooks/navigation/useTopLevelNavigation.d.ts +2 -2
  116. package/dist/hooks/navigation/utils.d.ts +5 -5
  117. package/dist/hooks/useBuildSidePanel.d.ts +6 -0
  118. package/dist/hooks/useCMSContext.d.ts +2 -2
  119. package/dist/hooks/{useEntityHistory.d.ts → useHistory.d.ts} +1 -1
  120. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  121. package/dist/hooks/{useEntitySelectionDialog.d.ts → useSelectionDialog.d.ts} +2 -2
  122. package/dist/hooks/useSideDialogsController.d.ts +1 -1
  123. package/dist/hooks/useSidePanel.d.ts +11 -0
  124. package/dist/index.d.ts +2 -2
  125. package/dist/index.js +2 -2
  126. package/dist/{src-cxV1ODRG.js → src-B8WuGSPZ.js} +886 -692
  127. package/dist/src-B8WuGSPZ.js.map +1 -0
  128. package/dist/types/components/EntityFormActionsProps.d.ts +2 -2
  129. package/dist/types/components/EntityFormProps.d.ts +3 -3
  130. package/dist/types/components/formex.d.ts +1 -1
  131. package/dist/types/fields.d.ts +2 -2
  132. package/dist/util/dataControllerAdapter.d.ts +2 -5
  133. package/dist/util/navigation_utils.d.ts +6 -6
  134. package/dist/util/previews.d.ts +3 -3
  135. package/dist/util/property_utils.d.ts +2 -2
  136. package/dist/util/{entity_view_constants.d.ts → view_constants.d.ts} +1 -1
  137. package/package.json +12 -17
  138. package/src/collection_editor/ConfigControllerProvider.tsx +11 -11
  139. package/src/collection_editor/_cms_internals.ts +3 -3
  140. package/src/collection_editor/api/generateCollectionApi.ts +8 -8
  141. package/src/collection_editor/extensibility_types.ts +3 -3
  142. package/src/collection_editor/index.ts +3 -3
  143. package/src/collection_editor/pgColumnToProperty.ts +3 -3
  144. package/src/collection_editor/serializable_types.ts +8 -8
  145. package/src/collection_editor/serializable_utils.ts +17 -17
  146. package/src/collection_editor/types/collection_editor_controller.tsx +5 -5
  147. package/src/collection_editor/types/collection_inference.ts +2 -2
  148. package/src/collection_editor/types/config_controller.tsx +7 -7
  149. package/src/collection_editor/ui/AddKanbanColumnAction.tsx +3 -3
  150. package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +3 -3
  151. package/src/collection_editor/ui/EditorCollectionAction.tsx +3 -3
  152. package/src/collection_editor/ui/EditorCollectionActionStart.tsx +3 -3
  153. package/src/collection_editor/ui/EditorEntityAction.tsx +3 -3
  154. package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +1 -1
  155. package/src/collection_editor/ui/KanbanSetupAction.tsx +3 -3
  156. package/src/collection_editor/ui/MissingReferenceWidget.tsx +1 -1
  157. package/src/collection_editor/ui/NewCollectionButton.tsx +1 -1
  158. package/src/collection_editor/ui/NewCollectionCard.tsx +1 -1
  159. package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -3
  160. package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +6 -6
  161. package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +6 -6
  162. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +29 -29
  163. package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +5 -5
  164. package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +2 -2
  165. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +10 -10
  166. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +38 -7
  167. package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -3
  168. package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +3 -3
  169. package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +3 -3
  170. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +4 -4
  171. package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +5 -5
  172. package/src/collection_editor/ui/collection_editor/EntityActionsSelectDialog.tsx +1 -1
  173. package/src/collection_editor/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +1 -1
  174. package/src/collection_editor/ui/collection_editor/EnumForm.tsx +2 -2
  175. package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +7 -7
  176. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +5 -5
  177. package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +4 -4
  178. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +9 -9
  179. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +46 -37
  180. package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +2 -2
  181. package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +1 -1
  182. package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +7 -7
  183. package/src/collection_editor/ui/collection_editor/SwitchControl.tsx +1 -1
  184. package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +4 -4
  185. package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.tsx +4 -4
  186. package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +1 -1
  187. package/src/collection_editor/ui/collection_editor/properties/BooleanPropertyField.tsx +1 -1
  188. package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +2 -2
  189. package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +2 -2
  190. package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +2 -2
  191. package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
  192. package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +2 -2
  193. package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +2 -2
  194. package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -2
  195. package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +3 -3
  196. package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +1 -1
  197. package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +2 -2
  198. package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +2 -2
  199. package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +1 -1
  200. package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +1 -1
  201. package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +1 -1
  202. package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +1 -1
  203. package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +1 -1
  204. package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
  205. package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +2 -2
  206. package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +2 -2
  207. package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +2 -2
  208. package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +2 -2
  209. package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +2 -2
  210. package/src/collection_editor/ui/collection_editor/templates/products_template.ts +2 -2
  211. package/src/collection_editor/ui/collection_editor/templates/users_template.ts +2 -2
  212. package/src/collection_editor/useJsonCollectionsConfigController.tsx +13 -13
  213. package/src/collection_editor/useLocalCollectionsConfigController.tsx +4 -4
  214. package/src/collection_editor/useSafeSnackbarController.ts +1 -1
  215. package/src/collection_editor/validateCollectionJson.ts +3 -3
  216. package/src/components/AdminModeSyncer.tsx +1 -1
  217. package/src/components/ArrayContainer.tsx +1 -1
  218. package/src/components/ClearFilterSortButton.tsx +1 -1
  219. package/src/components/CollectionPanel.tsx +14 -17
  220. package/src/components/{EntityCollectionTable/EntityCollectionRowActions.tsx → CollectionTableBinding/CollectionRowActions.tsx} +8 -8
  221. package/src/components/{EntityCollectionTable/EntityCollectionTable.tsx → CollectionTableBinding/CollectionTableBinding.tsx} +13 -13
  222. package/src/components/{EntityCollectionTable/EntityCollectionTableProps.tsx → CollectionTableBinding/CollectionTableBindingProps.tsx} +2 -2
  223. package/src/components/{EntityCollectionTable → CollectionTableBinding}/PropertyTableCell.tsx +1 -1
  224. package/src/components/{EntityCollectionTable → CollectionTableBinding}/column_utils.tsx +1 -1
  225. package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableMultipleRelationField.tsx +7 -7
  226. package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableReferenceField.tsx +10 -10
  227. package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationField.tsx +7 -7
  228. package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableStorageUpload.tsx +1 -1
  229. package/src/components/CollectionTableBinding/index.tsx +14 -0
  230. package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/CollectionTableToolbar.tsx +1 -1
  231. package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCell.tsx +2 -2
  232. package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCellActions.tsx +1 -1
  233. package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/common.tsx +2 -2
  234. package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/PopupFormField.tsx +6 -6
  235. package/src/components/{EntityCollectionTable → CollectionTableBinding}/table_bindings.tsx +1 -1
  236. package/src/components/{EntityCollectionView/EntityBoardCard.tsx → CollectionViewBinding/BoardCardBinding.tsx} +17 -17
  237. package/src/components/{EntityCollectionView/EntityCollectionBoardView.tsx → CollectionViewBinding/CollectionBoardViewBinding.tsx} +17 -16
  238. package/src/components/{EntityCollectionView/EntityCollectionCardView.tsx → CollectionViewBinding/CollectionCardViewBinding.tsx} +9 -9
  239. package/src/components/{EntityCollectionView/EntityCollectionListView.tsx → CollectionViewBinding/CollectionListViewBinding.tsx} +15 -15
  240. package/src/components/{EntityCollectionView/EntityCollectionViewActions.tsx → CollectionViewBinding/CollectionViewActions.tsx} +7 -7
  241. package/src/components/{EntityCollectionView/EntityCollectionView.tsx → CollectionViewBinding/CollectionViewBinding.tsx} +107 -92
  242. package/src/components/{EntityCollectionView/EntityCollectionViewStartActions.tsx → CollectionViewBinding/CollectionViewStartActions.tsx} +6 -6
  243. package/src/components/{EntityCollectionView/EntityCard.tsx → CollectionViewBinding/EntityCardBinding.tsx} +12 -12
  244. package/src/components/{EntityCollectionView → CollectionViewBinding}/FiltersDialog.tsx +49 -72
  245. package/src/components/{EntityCollectionView → CollectionViewBinding}/SplitListView.tsx +10 -10
  246. package/src/components/{EntityCollectionView → CollectionViewBinding}/ViewModeToggle.tsx +1 -1
  247. package/src/components/{EntityCollectionView → CollectionViewBinding}/hooks/useCollectionInlineEditor.ts +6 -6
  248. package/src/components/{EntityCollectionView → CollectionViewBinding}/hooks/useKanbanDragAndDrop.ts +5 -5
  249. package/src/components/{EntityCollectionView → CollectionViewBinding}/useBoardDataController.tsx +25 -13
  250. package/src/components/{EntityCollectionView/useEntityPreviewSlots.ts → CollectionViewBinding/usePreviewSlots.ts} +9 -9
  251. package/src/components/DefaultAppBar.tsx +3 -3
  252. package/src/components/DefaultDrawer.tsx +3 -3
  253. package/src/components/DeleteEntityDialog.tsx +7 -7
  254. package/src/components/{EntityDetailView.tsx → DetailViewBinding.tsx} +28 -31
  255. package/src/components/DrawerNavigationGroup.tsx +2 -2
  256. package/src/components/{EntityEditViewFormActions.tsx → EditFormActions.tsx} +16 -16
  257. package/src/components/{EntityEditView.tsx → EditViewBinding.tsx} +34 -37
  258. package/src/components/{EntityPreview.tsx → EntityPreviewBinding.tsx} +30 -30
  259. package/src/components/{EntityView.tsx → EntityViewBinding.tsx} +7 -7
  260. package/src/components/HomePage/ContentHomePage.tsx +4 -4
  261. package/src/components/HomePage/FavouritesView.tsx +1 -1
  262. package/src/components/HomePage/NavigationCardBinding.tsx +4 -4
  263. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  264. package/src/components/HomePage/RenameGroupDialog.tsx +1 -1
  265. package/src/components/{EntityJsonPreview.tsx → JsonPreviewBinding.tsx} +2 -2
  266. package/src/components/{RebaseCMS.tsx → RebaseAdmin.tsx} +6 -5
  267. package/src/components/RebaseAuthGate.tsx +2 -2
  268. package/src/components/RebaseLayout.tsx +7 -13
  269. package/src/components/RebaseNavigation.tsx +35 -11
  270. package/src/components/RebaseRouteDefs.tsx +2 -2
  271. package/src/components/RebaseShell.tsx +2 -1
  272. package/src/components/ReferenceTable/{EntitySelectionTable.tsx → SelectionTableBinding.tsx} +27 -24
  273. package/src/components/ReferenceWidget.tsx +4 -4
  274. package/src/components/RelationSelector.tsx +15 -13
  275. package/src/components/SearchIconsView.tsx +2 -2
  276. package/src/components/SelectableTable/SelectableTable.tsx +35 -88
  277. package/src/components/SelectableTable/SelectableTableContext.tsx +3 -3
  278. package/src/components/SelectableTable/SelectionStore.ts +4 -4
  279. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +10 -2
  280. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +34 -13
  281. package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +187 -0
  282. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +22 -8
  283. package/src/components/SelectableTable/filters/RelationFilterField.tsx +17 -3
  284. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +67 -13
  285. package/src/components/SideDialogs.tsx +4 -4
  286. package/src/components/{EntitySidePanel.tsx → SidePanelBinding.tsx} +20 -20
  287. package/src/components/{SideEntityProvider.tsx → SidePanelProvider.tsx} +17 -17
  288. package/src/components/UserSelector.tsx +1 -1
  289. package/src/components/admin/CreationResultDialog.tsx +6 -3
  290. package/src/components/app/Scaffold.tsx +6 -2
  291. package/src/components/common/default_entity_actions.tsx +132 -34
  292. package/src/components/field_configs.tsx +1 -1
  293. package/src/components/history/EntityHistoryEntry.tsx +3 -3
  294. package/src/components/history/EntityHistoryView.tsx +7 -7
  295. package/src/components/history/LastEditedByIndicator.tsx +4 -4
  296. package/src/components/index.ts +16 -15
  297. package/src/contexts/SidePanelControllerContext.tsx +5 -0
  298. package/src/data_export/export/BasicExportAction.tsx +1 -1
  299. package/src/data_export/export/ExportCollectionAction.tsx +5 -5
  300. package/src/data_import/components/DataNewPropertiesMapping.tsx +1 -1
  301. package/src/data_import/components/ImportFileUpload.tsx +1 -1
  302. package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +1 -1
  303. package/src/data_import/components/ImportSaveInProgress.tsx +4 -4
  304. package/src/data_import/import/ImportCollectionAction.tsx +6 -6
  305. package/src/data_import/utils/data.ts +4 -4
  306. package/src/data_import/utils/get_properties_mapping.ts +1 -1
  307. package/src/editor/components/image-bubble.tsx +1 -1
  308. package/src/editor/components/table-bubble.tsx +1 -1
  309. package/src/editor/editor.tsx +1 -1
  310. package/src/editor/selectors/link-selector.tsx +1 -1
  311. package/src/editor/selectors/node-selector.tsx +1 -1
  312. package/src/form/EntityForm.tsx +6 -6
  313. package/src/form/EntityFormActions.tsx +4 -4
  314. package/src/form/EntityFormBinding.tsx +10 -10
  315. package/src/form/PropertyFieldBinding.tsx +7 -7
  316. package/src/form/components/ErrorFocus.tsx +1 -1
  317. package/src/form/components/LocalChangesMenu.tsx +3 -3
  318. package/src/form/components/StorageItemPreview.tsx +1 -1
  319. package/src/form/components/StorageUploadProgress.tsx +3 -3
  320. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +1 -1
  321. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -5
  322. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
  323. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  324. package/src/form/field_bindings/KeyValueFieldBinding.tsx +21 -21
  325. package/src/form/field_bindings/MapFieldBinding.tsx +1 -1
  326. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +2 -2
  327. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +3 -3
  328. package/src/form/field_bindings/ReferenceFieldBinding.tsx +7 -7
  329. package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
  330. package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
  331. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +3 -3
  332. package/src/form/form_utils.ts +3 -3
  333. package/src/hooks/index.ts +4 -4
  334. package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -2
  335. package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +11 -11
  336. package/src/hooks/navigation/useBuildNavigationStateController.tsx +5 -5
  337. package/src/hooks/navigation/useNavigationResolution.ts +28 -13
  338. package/src/hooks/navigation/useResolvedCollections.ts +8 -8
  339. package/src/hooks/navigation/useTopLevelNavigation.ts +2 -2
  340. package/src/hooks/navigation/utils.ts +5 -5
  341. package/src/hooks/{useBuildSideEntityController.tsx → useBuildSidePanel.tsx} +29 -29
  342. package/src/hooks/useCMSContext.tsx +7 -7
  343. package/src/hooks/{useEntityHistory.ts → useHistory.ts} +2 -2
  344. package/src/hooks/useResolvedNavigationFrom.tsx +10 -5
  345. package/src/hooks/{useEntitySelectionDialog.tsx → useSelectionDialog.tsx} +7 -7
  346. package/src/hooks/useSideDialogsController.tsx +1 -1
  347. package/src/hooks/useSidePanel.tsx +13 -0
  348. package/src/index.ts +15 -15
  349. package/src/preview/PropertyPreview.tsx +2 -2
  350. package/src/preview/components/DatePreview.tsx +1 -1
  351. package/src/preview/components/EnumValuesChip.tsx +1 -1
  352. package/src/preview/components/ImagePreview.tsx +1 -1
  353. package/src/preview/components/ReferencePreview.tsx +11 -11
  354. package/src/preview/components/RelationPreview.tsx +13 -12
  355. package/src/preview/components/StorageThumbnail.tsx +1 -1
  356. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
  357. package/src/preview/property_previews/ArrayOneOfPreview.tsx +1 -1
  358. package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
  359. package/src/routes/RebaseRoute.tsx +12 -12
  360. package/src/types/components/EntityFormActionsProps.tsx +2 -2
  361. package/src/types/components/EntityFormProps.tsx +3 -3
  362. package/src/types/components/formex.tsx +1 -1
  363. package/src/types/fields.tsx +2 -2
  364. package/src/util/dataControllerAdapter.ts +9 -15
  365. package/src/util/navigation_utils.ts +7 -7
  366. package/src/util/previews.ts +7 -5
  367. package/src/util/property_utils.tsx +2 -2
  368. package/src/util/{entity_view_constants.ts → view_constants.ts} +1 -1
  369. package/dist/CollectionEditorDialog-BO_aQ-Z4.js.map +0 -1
  370. package/dist/PropertyEditView-DKzOpMjR.js.map +0 -1
  371. package/dist/RouterCollectionsStudioView-BQTIExjA.js.map +0 -1
  372. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +0 -28
  373. package/dist/components/EntityCollectionTable/index.d.ts +0 -6
  374. package/dist/components/EntityCollectionView/EntityCard.d.ts +0 -21
  375. package/dist/components/EntityEditViewFormActions.d.ts +0 -3
  376. package/dist/components/EntitySidePanel.d.ts +0 -11
  377. package/dist/components/EntityView.d.ts +0 -13
  378. package/dist/contexts/SideEntityControllerContext.d.ts +0 -3
  379. package/dist/history-B3cqBzEV.js.map +0 -1
  380. package/dist/hooks/useBuildSideEntityController.d.ts +0 -6
  381. package/dist/hooks/useSideEntityController.d.ts +0 -11
  382. package/dist/src-cxV1ODRG.js.map +0 -1
  383. package/src/components/EntityCollectionTable/index.tsx +0 -14
  384. package/src/contexts/SideEntityControllerContext.tsx +0 -5
  385. package/src/hooks/useSideEntityController.tsx +0 -13
  386. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/PropertyTableCell.d.ts +0 -0
  387. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/column_utils.d.ts +0 -0
  388. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationSelectorField.d.ts +0 -0
  389. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableStorageUpload.d.ts +0 -0
  390. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableSelect.d.ts +0 -0
  391. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableUserSelect.d.ts +0 -0
  392. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/CollectionTableToolbar.d.ts +0 -0
  393. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/EntityTableCellActions.d.ts +0 -0
  394. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useDraggable.d.ts +0 -0
  395. /package/dist/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useWindowSize.d.ts +0 -0
  396. /package/dist/components/{EntityCollectionView → CollectionViewBinding}/FilterPresetsButton.d.ts +0 -0
  397. /package/dist/components/{EntityCollectionView → CollectionViewBinding}/FiltersDialog.d.ts +0 -0
  398. /package/dist/components/{EntityCollectionView → CollectionViewBinding}/ViewModeToggle.d.ts +0 -0
  399. /package/dist/components/{EntityCollectionView → CollectionViewBinding}/useSelectionController.d.ts +0 -0
  400. /package/dist/components/{EntityCollectionView → CollectionViewBinding}/utils.d.ts +0 -0
  401. /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/TableRelationSelectorField.tsx +0 -0
  402. /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableSelect.tsx +0 -0
  403. /package/src/components/{EntityCollectionTable → CollectionTableBinding}/fields/VirtualTableUserSelect.tsx +0 -0
  404. /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useDraggable.tsx +0 -0
  405. /package/src/components/{EntityCollectionTable → CollectionTableBinding}/internal/popup_field/useWindowSize.tsx +0 -0
  406. /package/src/components/{EntityCollectionView → CollectionViewBinding}/FilterPresetsButton.tsx +0 -0
  407. /package/src/components/{EntityCollectionView → CollectionViewBinding}/useSelectionController.tsx +0 -0
  408. /package/src/components/{EntityCollectionView → CollectionViewBinding}/utils.ts +0 -0
@@ -3,9 +3,9 @@ import * as React$1 from "react";
3
3
  import React, { Suspense, createContext, createElement, forwardRef, lazy, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { deepEqual } from "fast-equals";
5
5
  import { Alert, AlertCircleIcon, AlertTriangleIcon, AlignLeftIcon, ArrowLeftIcon, ArrowRightToLineIcon, Avatar, Badge, BooleanSwitchWithLabel, Button, CHIP_COLORS, CalendarIcon, Card, CardView, CenteredView, CheckCircleIcon, CheckIcon, Checkbox, ChevronDownIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ChevronsUpDownIcon, Chip, CircleIcon, CircularProgress, CircularProgressCenter, CodeIcon, Collapse, ColumnsIcon, Container, CopyIcon, DateTimeField, Dialog, DialogActions, DialogContent, DialogTitle, DownloadIcon, ErrorBoundary, ExpandablePanel, ExternalLinkIcon, EyeIcon, EyeOffIcon, FileTextIcon, FileUpload, FilterChip, FilterIcon, FilterXIcon, FlagIcon, FolderUpIcon, FunctionSquareIcon, GlobeIcon, HandleIcon, HashIcon, HistoryIcon, IconButton, ImageOffIcon, KanbanIcon, KanbanView, KeyRoundIcon, Label, LayoutGridIcon, LinkIcon, ListIcon, ListOrderedIcon, ListView, LoaderIcon, LoadingButton, LogOutIcon, MailIcon, Markdown, Maximize2Icon, Menu, MenuIcon, MenuItem, MinusIcon, MoonIcon, MoreVerticalIcon, MultiSelect, MultiSelectItem, PencilIcon, PlusIcon, Popover, PopoverPrimitive, Portal, QuoteIcon, RadioGroup, RadioGroupItem, RefreshCwIcon, RepeatIcon, ResizablePanels, Rows3Icon, SearchBar, SearchIcon, Select, SelectItem, Separator, SettingsIcon, Sheet, Skeleton, StarIcon, SunIcon, SunMoonIcon, Tab, Table, TableBody, TableCell, TableHeader, TableIcon, TableRow, TableView, Tabs, TextField, TextIcon, TextareaAutosize, ToggleButtonGroup, Tooltip, Trash2Icon, Typography, UploadIcon, UserIcon, VirtualTableDateField, VirtualTableInput, VirtualTableInput as VirtualTableInput$1, VirtualTableNumberInput, VirtualTableSwitch, VoteIcon, XCircleIcon, XIcon, cls, coolIconKeys, createVirtualTableSelectionStore, debounce, defaultBorderMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, focusedDisabled, getColorSchemeForSeed, iconSize, lucideIcons, paperMixin, useDebouncedCallback, useInjectStyles, useOutsideAlerter } from "@rebasepro/ui";
6
- import { CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, addInitialSlash, buildRoutedRebaseData, canReadCollection, enumToObjectEntries, getArrayResolvedProperties, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEntityImagePreviewPropertyKey, getLabelOrConfigFrom, getLastSegment, getLastSegment as getLastSegment$1, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, isHidden, isPropertyBuilder, isReadOnly, normalizeToEntityRelation, removeInitialAndTrailingSlashes, removeInitialAndTrailingSlashes as removeInitialAndTrailingSlashes$1, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionPathIds as resolveCollectionPathIds$1, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveProperty, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource } from "@rebasepro/common";
7
- import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, CollectionComponentOverrideProvider, ConfirmationDialog, CustomizationControllerContext, DEFAULT_PAGE_SIZE, ErrorTooltip, ErrorView, FORM_CONTAINER_WIDTH, IconForView, LanguageToggle, LoginView, NotFoundPage, PluginProviderStack, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StorageSourceContext, StudioBridgeRegistryProvider, UIReferenceView, UnsavedChangesDialog, UserDisplay, UserSettingsView, buildCollapsedDefaults, buildEnumLabel, createFormexStub, deleteEntityWithCallbacks, flattenKeys, getColorScheme, getColumnKeysForProperty, getEntityFromCache, getEntityFromMemoryCache, getFormFieldKeys, getIcon, getRowHeight, iconsSearch, removeEntityFromCache, removeEntityFromMemoryCache, resolveComponentRef, saveEntityToCache, saveEntityToMemoryCache, saveEntityWithCallbacks, useAdminModeController, useAnalyticsController, useApiConfig, useAuthController, useBridgeRegistration, useBuildLocalConfigurationPersistence, useCollapsedGroups, useColumnIds, useComponentOverride, useCustomizationController, useData, useDataSources, useDataTableController, useEntityFetch, useLargeLayout, useModeController, usePermissions, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRelationSelector, useRestoreScroll, useScrollRestoration, useSlot, useSnackbarController, useStorageSource, useStorageSources, useStorageUploadController, useTranslation, useUnsavedChangesDialog, useUserConfigurationPersistence } from "@rebasepro/core";
8
- import { Field, Formex, getIn, setIn, useCreateFormex, useFormex } from "@rebasepro/formex";
6
+ import { CollectionRegistry, DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE, addInitialSlash, buildRoutedRebaseData, canReadCollection, enumToObjectEntries, getArrayResolvedProperties, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultValueFor, getDefaultValueFortype, getDefaultValuesFor, getEntityImagePreviewPropertyKey, getLabelOrConfigFrom, getLastSegment, getLastSegment as getLastSegment$1, getLocalChangesBackup, getNavigationEntriesFromPath, getParentReferencesFromPath, getReferenceFrom, getRelationFrom, getSubcollections, getTableName, isHidden, isPropertyBuilder, isReadOnly, normalizeToEntityRelation, removeInitialAndTrailingSlashes, removeInitialAndTrailingSlashes as removeInitialAndTrailingSlashes$1, removeInitialSlash, removeTrailingSlash, resolveArrayProperties, resolveCollectionPathIds, resolveCollectionPathIds as resolveCollectionPathIds$1, resolveDataSource, resolveDefaultSelectedView, resolveEnumValues, resolveFilterOperators, resolveProperty, resolveRelationProperty, resolveStorageFilenameString, resolveStoragePathString, resolveStorageSource } from "@rebasepro/common";
7
+ import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, CollectionResolverRegistrationContext, CollectionScopeProvider, CustomizationControllerContext, DEFAULT_PAGE_SIZE, ErrorTooltip, ErrorView, FORM_CONTAINER_WIDTH, IconForView, LanguageToggle, LoginView, NotFoundPage, PluginProviderStack, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StorageSourceContext, StudioBridgeRegistryProvider, UIReferenceView, UnsavedChangesDialog, UserDisplay, UserSettingsView, buildCollapsedDefaults, buildEnumLabel, createFormexStub, deleteEntityWithCallbacks, flattenKeys, getColorScheme, getColumnKeysForProperty, getEntityFromCache, getEntityFromMemoryCache, getFormFieldKeys, getIcon, getRelationIncludeParams, getRowHeight, iconsSearch, removeEntityFromCache, removeEntityFromMemoryCache, resolveComponentRef, saveEntityToCache, saveEntityToMemoryCache, saveEntityWithCallbacks, useAdminModeController, useAnalyticsController, useApiConfig, useAuthController, useBridgeRegistration, useBuildLocalConfigurationPersistence, useCollapsedGroups, useCollectionScope, useColumnIds, useComponentOverride, useCustomizationController, useData, useDataSources, useDataTableController, useFetch, useLargeLayout, useModeController, usePermissions, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRelationSelector, useResolvedComponent, useRestoreScroll, useScrollRestoration, useSlot, useSnackbarController, useStorageSource, useStorageSources, useStorageUploadController, useTranslation, useUnsavedChangesDialog, useUserConfigurationPersistence } from "@rebasepro/app";
8
+ import { Field, Formex, getIn, setIn, useCreateFormex, useFormex } from "@rebasepro/forms";
9
9
  import { z } from "zod";
10
10
  import { defaultDateFormat, getArrayValuesCount, getHashValue, getValueInPath, hydrateRegExp, isObject, mergeDeep, prettifyIdentifier, randomString, slugify, toArray } from "@rebasepro/utils";
11
11
  import { EntityReference, EntityRelation, GeoPoint, Vector, getCollectionDataPath, getDataSourceCapabilities } from "@rebasepro/types";
@@ -20,7 +20,7 @@ import { restrictToVerticalAxis, restrictToWindowEdges } from "@dnd-kit/modifier
20
20
  import { SortableContext, arrayMove, defaultAnimateLayoutChanges, horizontalListSortingStrategy, rectSortingStrategy, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
21
21
  import { CSS } from "@dnd-kit/utilities";
22
22
  import ExcelJS from "exceljs";
23
- import { buildEntityPropertiesFromData, inferTypeFromValue } from "@rebasepro/schema-inference";
23
+ import { buildEntityPropertiesFromData, inferTypeFromValue } from "@rebasepro/inference";
24
24
  import { generateKeyBetween, generateNKeysBetween } from "fractional-indexing";
25
25
  import Fuse from "fuse.js";
26
26
  import { format } from "date-fns";
@@ -350,7 +350,7 @@ function buildBottomActions$1({ savingError, entity, path, formActions, collecti
350
350
  path: path ?? getCollectionDataPath(collection),
351
351
  collection,
352
352
  context: void 0,
353
- sideEntityController: void 0,
353
+ sidePanelController: void 0,
354
354
  openEntityMode,
355
355
  navigateBack,
356
356
  formContext
@@ -1100,7 +1100,7 @@ function getEntityTitlePropertyKey(collection, propertyConfigs) {
1100
1100
  if (property && !isPropertyBuilder(property)) {
1101
1101
  const prop = property;
1102
1102
  if (prop && typeof prop === "object" && "isId" in prop && Boolean(prop.isId) || key === "id" || isHiddenProperty(prop)) continue;
1103
- if (prop.type === "relation" || prop.type === "string") return key;
1103
+ if (prop.type === "relation" || prop.type === "string" && !isStorageProperty$1(prop)) return key;
1104
1104
  }
1105
1105
  }
1106
1106
  let firstStringCandidate;
@@ -1160,15 +1160,15 @@ function resolveTitleToString(title) {
1160
1160
  }
1161
1161
  }
1162
1162
  //#endregion
1163
- //#region src/components/EntityPreview.tsx
1163
+ //#region src/components/EntityPreviewBinding.tsx
1164
1164
  /**
1165
- * This component contains the main logic and content for displaying an entity preview,
1166
- * without any container wrapper. Used internally by EntityPreview.
1165
+ * This component contains the main logic and content for displaying a entity preview,
1166
+ * without any container wrapper. Used internally by EntityPreviewBinding.
1167
1167
  */
1168
- function EntityPreviewData({ actions, collection: collectionProp, previewKeys, size = "medium", includeId = true, onSideEntityClick, includeTitle = true, includeEntityLink = true, includeImage = true, entity }) {
1168
+ function EntityPreviewBindingData({ actions, collection: collectionProp, previewKeys, size = "medium", includeId = true, onSidePanelClick, includeTitle = true, includeEntityLink = true, includeImage = true, entity }) {
1169
1169
  const authController = useAuthController();
1170
1170
  const analyticsController = useAnalyticsController();
1171
- const sideEntityController = useSideEntityController();
1171
+ const sidePanelController = useSidePanel();
1172
1172
  const customizationController = useCustomizationController();
1173
1173
  const collectionRegistryController = useCollectionRegistryController();
1174
1174
  const collection = collectionProp ?? collectionRegistryController.getCollection(entity.path);
@@ -1265,12 +1265,12 @@ function EntityPreviewData({ actions, collection: collectionProp, previewKeys, s
1265
1265
  onClick: (e) => {
1266
1266
  e.stopPropagation();
1267
1267
  e.preventDefault();
1268
- onSideEntityClick?.(entity);
1268
+ onSidePanelClick?.(entity);
1269
1269
  analyticsController.onAnalyticsEvent?.("entity_click_from_reference", {
1270
1270
  path: entity.path,
1271
1271
  entityId: entity.id
1272
1272
  });
1273
- sideEntityController.open({
1273
+ sidePanelController.open({
1274
1274
  entityId: entity.id,
1275
1275
  path: entity.path,
1276
1276
  collection,
@@ -1288,15 +1288,15 @@ function EntityPreviewData({ actions, collection: collectionProp, previewKeys, s
1288
1288
  ] });
1289
1289
  }
1290
1290
  /**
1291
- * This view is used to display a preview of an entity.
1291
+ * This view is used to display a preview of a entity.
1292
1292
  * It is used by default in reference fields and whenever a reference is displayed.
1293
1293
  */
1294
- function EntityPreview({ actions, disabled, hover, collection, previewKeys, onClick, size = "medium", includeId = true, includeTitle = true, includeEntityLink = true, includeImage = true, onSideEntityClick, entity }) {
1294
+ function EntityPreviewBinding({ actions, disabled, hover, collection, previewKeys, onClick, size = "medium", includeId = true, includeTitle = true, includeEntityLink = true, includeImage = true, onSidePanelClick, entity }) {
1295
1295
  return /* @__PURE__ */ jsx(EntityPreviewContainer, {
1296
1296
  onClick: disabled ? void 0 : onClick,
1297
1297
  hover: disabled ? void 0 : hover,
1298
1298
  size,
1299
- children: /* @__PURE__ */ jsx(EntityPreviewData, {
1299
+ children: /* @__PURE__ */ jsx(EntityPreviewBindingData, {
1300
1300
  actions,
1301
1301
  collection,
1302
1302
  previewKeys,
@@ -1305,7 +1305,7 @@ function EntityPreview({ actions, disabled, hover, collection, previewKeys, onCl
1305
1305
  includeTitle,
1306
1306
  includeEntityLink,
1307
1307
  includeImage,
1308
- onSideEntityClick,
1308
+ onSidePanelClick,
1309
1309
  entity
1310
1310
  })
1311
1311
  });
@@ -1389,16 +1389,16 @@ function ReferencePreviewInternal(props) {
1389
1389
  ...props,
1390
1390
  collection
1391
1391
  });
1392
- if (collection?.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
1393
- overrides: collection.components,
1392
+ if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
1393
+ collection,
1394
1394
  children: content
1395
1395
  });
1396
1396
  return content;
1397
1397
  }
1398
1398
  function ReferencePreviewExisting({ reference, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover, textOnly }) {
1399
- const ResolvedEntityPreview = useComponentOverride("Entity.Preview", EntityPreview);
1399
+ const ResolvedEntityPreview = useComponentOverride("EntityPreview", EntityPreviewBinding);
1400
1400
  const customizationController = useCustomizationController();
1401
- const { entity, dataLoading, dataLoadingError } = useEntityFetch({
1401
+ const { entity, dataLoading, dataLoadingError } = useFetch({
1402
1402
  path: reference.path,
1403
1403
  entityId: reference.id,
1404
1404
  collection,
@@ -1488,8 +1488,8 @@ function ArrayOfReferencesPreview({ propertyKey, value, property, size }) {
1488
1488
  });
1489
1489
  }
1490
1490
  //#endregion
1491
- //#region src/components/EntityView.tsx
1492
- function EntityView({ entity, collection, path, className }) {
1491
+ //#region src/components/EntityViewBinding.tsx
1492
+ function EntityViewBinding({ entity, collection, path, className }) {
1493
1493
  const customizationController = useCustomizationController();
1494
1494
  const properties = collection.properties;
1495
1495
  return /* @__PURE__ */ jsx("div", {
@@ -1560,8 +1560,8 @@ function resolvedSelectedEntityView(customViews, customizationController, select
1560
1560
  };
1561
1561
  }
1562
1562
  //#endregion
1563
- //#region src/components/EntityJsonPreview.tsx
1564
- function EntityJsonPreview({ values }) {
1563
+ //#region src/components/JsonPreviewBinding.tsx
1564
+ function JsonPreviewBinding({ values }) {
1565
1565
  const code = JSON.stringify(values, null, " ");
1566
1566
  const { mode } = useModeController();
1567
1567
  const preRef = useRef(null);
@@ -1588,17 +1588,17 @@ function EntityJsonPreview({ values }) {
1588
1588
  });
1589
1589
  }
1590
1590
  //#endregion
1591
- //#region src/util/entity_view_constants.ts
1591
+ //#region src/util/view_constants.ts
1592
1592
  /**
1593
- * Shared tab value constants used by EntityEditView and EntityDetailView.
1593
+ * Shared tab value constants used by EditViewBinding and DetailViewBinding.
1594
1594
  */
1595
1595
  var MAIN_TAB_VALUE = "__main_##Q$SC^#S6";
1596
1596
  var JSON_TAB_VALUE = "__json";
1597
1597
  //#endregion
1598
- //#region src/components/EntityDetailView.tsx
1599
- var EntityHistoryView$1 = lazy(() => import("./history-B3cqBzEV.js").then((m) => ({ default: m.EntityHistoryView })));
1600
- function EntityDetailView({ entityId, ...props }) {
1601
- const { entity, dataLoading, dataLoadingError } = useEntityFetch({
1598
+ //#region src/components/DetailViewBinding.tsx
1599
+ var EntityHistoryView$1 = lazy(() => import("./history-GSa4BgDt.js").then((m) => ({ default: m.EntityHistoryView })));
1600
+ function DetailViewBinding({ entityId, ...props }) {
1601
+ const { entity, dataLoading, dataLoadingError } = useFetch({
1602
1602
  path: props.path,
1603
1603
  entityId,
1604
1604
  collection: props.collection,
@@ -1609,20 +1609,19 @@ function EntityDetailView({ entityId, ...props }) {
1609
1609
  variant: "label",
1610
1610
  children: "Entity not found"
1611
1611
  }) });
1612
- const content = /* @__PURE__ */ jsx(EntityDetailViewInner, {
1612
+ const content = /* @__PURE__ */ jsx(DetailViewBindingInner, {
1613
1613
  ...props,
1614
1614
  entityId,
1615
1615
  entity,
1616
1616
  dataLoading
1617
1617
  });
1618
- if (props.collection.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
1619
- overrides: props.collection.components,
1618
+ return /* @__PURE__ */ jsx(CollectionScopeProvider, {
1619
+ collection: props.collection,
1620
1620
  children: content
1621
1621
  });
1622
- return content;
1623
1622
  }
1624
- function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onTabChange, onEditClick, entity, dataLoading, layout = "full_screen", barActions }) {
1625
- const ResolvedCollectionView = useComponentOverride("Collection.View", EntityCollectionView);
1623
+ function DetailViewBindingInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onTabChange, onEditClick, entity, dataLoading, layout = "full_screen", barActions }) {
1624
+ const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
1626
1625
  const { t } = useTranslation();
1627
1626
  const context = useRebaseContext();
1628
1627
  const urlController = useUrlController();
@@ -1771,7 +1770,7 @@ function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, c
1771
1770
  const jsonView = activeTab === "__json" || jsonTabMounted ? /* @__PURE__ */ jsx("div", {
1772
1771
  className: cls("relative flex-1 h-full overflow-auto w-full", { "hidden": activeTab !== JSON_TAB_VALUE }),
1773
1772
  role: "tabpanel",
1774
- children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityJsonPreview, { values: usedEntity?.values ?? {} }) })
1773
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(JsonPreviewBinding, { values: usedEntity?.values ?? {} }) })
1775
1774
  }, "json_view") : null;
1776
1775
  const historyView = includeHistoryView && activeTab === "__rebase_history" ? /* @__PURE__ */ jsx("div", {
1777
1776
  className: "relative flex-1 h-full overflow-auto w-full",
@@ -1836,7 +1835,7 @@ function EntityDetailViewInner({ path, entityId, selectedTab: selectedTabProp, c
1836
1835
  formContext: readOnlyFormContext
1837
1836
  })
1838
1837
  }) });
1839
- return /* @__PURE__ */ jsx(Fragment, { children: usedEntity && /* @__PURE__ */ jsx(EntityView, {
1838
+ return /* @__PURE__ */ jsx(Fragment, { children: usedEntity && /* @__PURE__ */ jsx(EntityViewBinding, {
1840
1839
  entity: usedEntity,
1841
1840
  collection,
1842
1841
  path
@@ -2092,16 +2091,16 @@ function useCellSelected(store, propertyKey, entityPath, entityId) {
2092
2091
  entityPath,
2093
2092
  entityId
2094
2093
  };
2095
- const getSnapshot = useCallback(() => {
2096
- const cell = store.getSnapshot();
2094
+ const getEntity = useCallback(() => {
2095
+ const cell = store.getEntity();
2097
2096
  if (!cell) return false;
2098
2097
  const s = selectorRef.current;
2099
2098
  return cell.propertyKey === s.propertyKey && cell.entityPath === s.entityPath && cell.entityId === s.entityId;
2100
2099
  }, [store]);
2101
- return useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
2100
+ return useSyncExternalStore(store.subscribe, getEntity, getEntity);
2102
2101
  }
2103
2102
  //#endregion
2104
- //#region src/components/EntityCollectionTable/fields/VirtualTableSelect.tsx
2103
+ //#region src/components/CollectionTableBinding/fields/VirtualTableSelect.tsx
2105
2104
  function VirtualTableSelect(props) {
2106
2105
  const { enumValues, internalValue, disabled, small, focused, updateValue, multiple, valueType } = props;
2107
2106
  const validValue = Array.isArray(internalValue) && multiple || !Array.isArray(internalValue) && !multiple;
@@ -2489,7 +2488,7 @@ var UserSelector = React$1.forwardRef(({ value, size = "medium", onValueChange,
2489
2488
  });
2490
2489
  UserSelector.displayName = "UserSelector";
2491
2490
  //#endregion
2492
- //#region src/components/EntityCollectionTable/fields/VirtualTableUserSelect.tsx
2491
+ //#region src/components/CollectionTableBinding/fields/VirtualTableUserSelect.tsx
2493
2492
  function VirtualTableUserSelect(props) {
2494
2493
  const { internalValue, disabled, small, focused, updateValue, multiple } = props;
2495
2494
  return /* @__PURE__ */ jsx(UserSelector, {
@@ -2571,7 +2570,7 @@ function StorageUploadProgress({ storagePath, entry, metadata, onFileUploadCompl
2571
2570
  });
2572
2571
  }
2573
2572
  //#endregion
2574
- //#region src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx
2573
+ //#region src/components/CollectionTableBinding/internal/EntityTableCellActions.tsx
2575
2574
  function EntityTableCellActions({ showError, disabled, showExpandIcon, selected, openPopup, children }) {
2576
2575
  const ref = useRef(null);
2577
2576
  const doOpenPopup = useCallback(() => {
@@ -2621,7 +2620,7 @@ function EntityTableCellActions({ showError, disabled, showExpandIcon, selected,
2621
2620
  }) });
2622
2621
  }
2623
2622
  //#endregion
2624
- //#region src/components/EntityCollectionTable/fields/TableStorageUpload.tsx
2623
+ //#region src/components/CollectionTableBinding/fields/TableStorageUpload.tsx
2625
2624
  var dropZoneClasses$1 = "max-w-full box-border relative pt-[2px] items-center border border-transparent outline-hidden rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
2626
2625
  var activeDropClasses$1 = "pt-0 border-2 border-solid";
2627
2626
  var acceptDropClasses$1 = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500 bg-green-50 dark:bg-green-900";
@@ -2777,7 +2776,7 @@ function TableStorageItemPreview({ propertyKey, property, value, size, entity })
2777
2776
  });
2778
2777
  }
2779
2778
  //#endregion
2780
- //#region src/hooks/useEntitySelectionDialog.tsx
2779
+ //#region src/hooks/useSelectionDialog.tsx
2781
2780
  /**
2782
2781
  * This hook is used to open a side dialog that allows the selection
2783
2782
  * of entities under a given path.
@@ -2788,17 +2787,17 @@ function TableStorageItemPreview({ propertyKey, property, value, size, entity })
2788
2787
  * This is the same hook used internally when a reference property is defined.
2789
2788
  * @group Hooks and utilities
2790
2789
  */
2791
- function useEntitySelectionDialog(referenceDialogProps) {
2790
+ function useSelectionDialog(referenceDialogProps) {
2792
2791
  const navigation = useCollectionRegistryController();
2793
2792
  const sideDialogsController = useSideDialogsController();
2794
2793
  const open = useCallback(() => {
2795
2794
  if (referenceDialogProps.path) {
2796
2795
  let usedCollection = referenceDialogProps.collection;
2797
2796
  if (!usedCollection) usedCollection = navigation.getCollection(referenceDialogProps.path);
2798
- if (!usedCollection) throw Error("Not able to resolve the collection in useEntitySelectionDialog. Make sure a collection is registered in path " + referenceDialogProps.path);
2797
+ if (!usedCollection) throw Error("Not able to resolve the collection in useSelectionDialog. Make sure a collection is registered in path " + referenceDialogProps.path);
2799
2798
  sideDialogsController.open({
2800
2799
  key: `reference_${referenceDialogProps.path}`,
2801
- component: /* @__PURE__ */ jsx(EntitySelectionTable, {
2800
+ component: /* @__PURE__ */ jsx(SelectionTableBinding, {
2802
2801
  collection: usedCollection,
2803
2802
  ...referenceDialogProps
2804
2803
  }),
@@ -2822,7 +2821,7 @@ function useEntitySelectionDialog(referenceDialogProps) {
2822
2821
  }), [open, close]);
2823
2822
  }
2824
2823
  //#endregion
2825
- //#region src/components/EntityCollectionTable/fields/TableReferenceField.tsx
2824
+ //#region src/components/CollectionTableBinding/fields/TableReferenceField.tsx
2826
2825
  var DefaultMissingReference$1 = () => null;
2827
2826
  function TableReferenceFieldResolver(props) {
2828
2827
  const ResolvedMissingReference = useComponentOverride("Entity.MissingReference", DefaultMissingReference$1);
@@ -2842,8 +2841,8 @@ function TableReferenceField(props) {
2842
2841
  ...props,
2843
2842
  collection
2844
2843
  });
2845
- if (collection?.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
2846
- overrides: collection.components,
2844
+ if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
2845
+ collection,
2847
2846
  children: content
2848
2847
  });
2849
2848
  return content;
@@ -2853,7 +2852,7 @@ var TableReferenceFieldInternal = React.memo(function TableReferenceFieldInterna
2853
2852
  const onSingleEntitySelected = useCallback((entity) => {
2854
2853
  updateValue(entity ? getReferenceFrom(entity) : null);
2855
2854
  }, [updateValue]);
2856
- const referenceDialogController = useEntitySelectionDialog({
2855
+ const referenceDialogController = useSelectionDialog({
2857
2856
  multiselect,
2858
2857
  path,
2859
2858
  collection,
@@ -2921,7 +2920,7 @@ var TableReferenceFieldInternal = React.memo(function TableReferenceFieldInterna
2921
2920
  });
2922
2921
  }, deepEqual);
2923
2922
  //#endregion
2924
- //#region src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx
2923
+ //#region src/components/CollectionTableBinding/fields/TableMultipleRelationField.tsx
2925
2924
  function TableMultipleRelationField(props) {
2926
2925
  const collection = props.relation.target();
2927
2926
  return /* @__PURE__ */ jsx(TableMultipleRelationFieldInternal, {
@@ -2936,7 +2935,7 @@ var TableMultipleRelationFieldInternal = React.memo(function TableMultipleRelati
2936
2935
  updateValue(entities.map((e) => getRelationFrom(e)));
2937
2936
  }, [updateValue]);
2938
2937
  const selectedEntityIds = value.map((ref) => ref.id);
2939
- const relationDialogController = useEntitySelectionDialog({
2938
+ const relationDialogController = useSelectionDialog({
2940
2939
  multiselect: true,
2941
2940
  path: getCollectionDataPath(collection),
2942
2941
  collection,
@@ -2980,7 +2979,7 @@ var TableMultipleRelationFieldInternal = React.memo(function TableMultipleRelati
2980
2979
  });
2981
2980
  }, deepEqual);
2982
2981
  //#endregion
2983
- //#region src/components/EntityCollectionTable/fields/TableRelationField.tsx
2982
+ //#region src/components/CollectionTableBinding/fields/TableRelationField.tsx
2984
2983
  function TableRelationField(props) {
2985
2984
  const collection = props.relation.target();
2986
2985
  if (props.relation?.cardinality === "many") return /* @__PURE__ */ jsx(TableMultipleRelationField, {
@@ -3010,7 +3009,7 @@ var TableRelationFieldInternal = React.memo(function TableRelationFieldInternal(
3010
3009
  updateValue(entities.map((e) => getRelationFrom(e)));
3011
3010
  }, [updateValue]);
3012
3011
  const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => ref.id) : internalValue.id ? [internalValue.id] : [] : [];
3013
- const relationDialogController = useEntitySelectionDialog({
3012
+ const relationDialogController = useSelectionDialog({
3014
3013
  multiselect,
3015
3014
  path: getCollectionDataPath(collection),
3016
3015
  collection,
@@ -3075,22 +3074,22 @@ var TableRelationFieldInternal = React.memo(function TableRelationFieldInternal(
3075
3074
  });
3076
3075
  }, deepEqual);
3077
3076
  //#endregion
3078
- //#region src/hooks/useSideEntityController.tsx
3079
- var SideEntityControllerContext = React.createContext({});
3077
+ //#region src/hooks/useSidePanel.tsx
3078
+ var SidePanelControllerContext = React.createContext({});
3080
3079
  /**
3081
- * Use this hook to retrieve an entity controller that allows you to open
3082
- * a side dialog to edit an entity.
3080
+ * Use this hook to retrieve a entity controller that allows you to open
3081
+ * a side dialog to edit a entity.
3083
3082
  *
3084
- * @see SideEntityController
3083
+ * @see SidePanelController
3085
3084
  * @group Hooks and utilities
3086
3085
  */
3087
- var useSideEntityController = () => useContext(SideEntityControllerContext);
3086
+ var useSidePanel = () => useContext(SidePanelControllerContext);
3088
3087
  //#endregion
3089
3088
  //#region src/components/RelationSelector.tsx
3090
3089
  var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChange, invisible, disabled, placeholder, useChips = true, className, relation, fixedFilter, pageSize, emptyPlaceholder, searchPlaceholder = "Search...", noResultsText = "No relations found.", loadingText = "Loading..." }, ref) => {
3091
3090
  const collection = relation.target();
3092
3091
  const dataClient = useData();
3093
- const sideEntityController = useSideEntityController();
3092
+ const sidePanelController = useSidePanel();
3094
3093
  const multiple = relation.cardinality === "many";
3095
3094
  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
3096
3095
  const isPopoverOpenRef = useRef(false);
@@ -3374,12 +3373,12 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
3374
3373
  children: selectedItems.map((item) => {
3375
3374
  if (!useChips || !multiple) return /* @__PURE__ */ jsx("div", {
3376
3375
  className: "flex flex-row items-center gap-1 truncate",
3377
- children: item.data ? /* @__PURE__ */ jsx(EntityPreviewData, {
3376
+ children: item.data ? /* @__PURE__ */ jsx(EntityPreviewBindingData, {
3378
3377
  size: "medium",
3379
3378
  entity: item.data,
3380
3379
  includeEntityLink: false,
3381
3380
  includeId: false,
3382
- onSideEntityClick: closePopover
3381
+ onSidePanelClick: closePopover
3383
3382
  }) : /* @__PURE__ */ jsx("span", {
3384
3383
  className: "text-sm truncate",
3385
3384
  children: item.label
@@ -3388,7 +3387,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
3388
3387
  return /* @__PURE__ */ jsxs(Chip, {
3389
3388
  size: "small",
3390
3389
  className: cls("flex flex-row items-center gap-1 truncate"),
3391
- children: [item.data ? /* @__PURE__ */ jsx(EntityPreviewData, {
3390
+ children: [item.data ? /* @__PURE__ */ jsx(EntityPreviewBindingData, {
3392
3391
  size: "smallest",
3393
3392
  entity: item.data,
3394
3393
  includeEntityLink: false,
@@ -3422,7 +3421,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
3422
3421
  e.preventDefault();
3423
3422
  const entity = selectedItems[0].data;
3424
3423
  setIsPopoverOpen(false);
3425
- sideEntityController.open({
3424
+ sidePanelController.open({
3426
3425
  entityId: entity.id,
3427
3426
  path: entity.path,
3428
3427
  collection,
@@ -3524,7 +3523,7 @@ var RelationSelector = React$1.forwardRef(({ value, size = "medium", onValueChan
3524
3523
  className: cls("flex flex-row items-center gap-1.5 m-1 p-1 rounded-xs cursor-pointer ring-offset-transparent", isSelected && "bg-surface-accent-200 dark:bg-surface-accent-950", "aria-selected:outline-hidden aria-selected:ring-2 aria-selected:ring-primary/75 aria-selected:ring-offset-2 aria-selected:bg-surface-accent-100 dark:aria-selected:bg-surface-accent-900"),
3525
3524
  children: [multiple && /* @__PURE__ */ jsx(InnerCheckBox, { checked: isSelected }), item.data ? /* @__PURE__ */ jsx("div", {
3526
3525
  className: "flex flex-row items-center gap-2 min-w-0 w-full",
3527
- children: /* @__PURE__ */ jsx(EntityPreviewData, {
3526
+ children: /* @__PURE__ */ jsx(EntityPreviewBindingData, {
3528
3527
  size: multiple ? "smallest" : "medium",
3529
3528
  entity: item.data,
3530
3529
  includeId: false,
@@ -3574,7 +3573,7 @@ function InnerCheckBox({ checked }) {
3574
3573
  });
3575
3574
  }
3576
3575
  //#endregion
3577
- //#region src/components/EntityCollectionTable/fields/TableRelationSelectorField.tsx
3576
+ //#region src/components/CollectionTableBinding/fields/TableRelationSelectorField.tsx
3578
3577
  /** Thin wrapper around RelationSelector for table cells */
3579
3578
  function TableRelationSelectorField({ disabled = false, internalValue, updateValue, relation, fixedFilter, size = "medium" }) {
3580
3579
  return /* @__PURE__ */ jsx(RelationSelector, {
@@ -3587,7 +3586,7 @@ function TableRelationSelectorField({ disabled = false, internalValue, updateVal
3587
3586
  });
3588
3587
  }
3589
3588
  //#endregion
3590
- //#region src/components/EntityCollectionTable/table_bindings.tsx
3589
+ //#region src/components/CollectionTableBinding/table_bindings.tsx
3591
3590
  function isStorageProperty(property) {
3592
3591
  if (property.type === "string" && property.ui?.markdown) return false;
3593
3592
  if (property.type === "string" && property.storage) return true;
@@ -3820,7 +3819,7 @@ function RelationSelectorBindingComponent({ propertyKey, internalValue, updateVa
3820
3819
  });
3821
3820
  }
3822
3821
  //#endregion
3823
- //#region src/components/EntityCollectionTable/internal/EntityTableCell.tsx
3822
+ //#region src/components/CollectionTableBinding/internal/EntityTableCell.tsx
3824
3823
  var TableCellInner = ({ justifyContent, scrollable, faded, fullHeight, children }) => {
3825
3824
  return /* @__PURE__ */ jsx("div", {
3826
3825
  className: cls("flex flex-col max-h-full w-full", { "items-start": faded || scrollable }),
@@ -3981,7 +3980,7 @@ function useClearRestoreValue({ property, value, setValue }) {
3981
3980
  }, [property]);
3982
3981
  }
3983
3982
  //#endregion
3984
- //#region src/components/EntityCollectionTable/PropertyTableCell.tsx
3983
+ //#region src/components/CollectionTableBinding/PropertyTableCell.tsx
3985
3984
  var PropertyTableCell = React.memo(function PropertyTableCell({ propertyKey, customFieldValidator, value, property, align, width, height, path, entity, readonly, disabled: disabledProp, enablePopupIcon = true, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable, frozen }) {
3986
3985
  const { onValueChange, size, selectionStore, select, setPopupCell } = useSelectableTableController();
3987
3986
  const dummySelectionStore = useMemo(() => createSelectionStore(), []);
@@ -4197,7 +4196,7 @@ function areEqual(prevProps, nextProps) {
4197
4196
  return prevProps.height === nextProps.height && prevProps.propertyKey === nextProps.propertyKey && prevProps.align === nextProps.align && prevProps.width === nextProps.width && deepEqual(prevProps.property, nextProps.property) && deepEqual(prevProps.value, nextProps.value) && prevProps.entity.id === nextProps.entity.id && prevProps.entity.path === nextProps.entity.path && prevProps.isDragging === nextProps.isDragging && prevProps.isDraggable === nextProps.isDraggable && prevProps.frozen === nextProps.frozen;
4198
4197
  }
4199
4198
  //#endregion
4200
- //#region src/components/EntityCollectionTable/EntityCollectionRowActions.tsx
4199
+ //#region src/components/CollectionTableBinding/CollectionRowActions.tsx
4201
4200
  /**
4202
4201
  *
4203
4202
  * @param entity
@@ -4211,9 +4210,9 @@ function areEqual(prevProps, nextProps) {
4211
4210
  *
4212
4211
  * @group Collection components
4213
4212
  */
4214
- var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, collection, path, width, frozen, isSelected, selectionEnabled, size, highlightEntity, onCollectionChange, unhighlightEntity, actions = [], hideId, selectionController, openEntityMode, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable }) {
4213
+ var CollectionRowActions = function CollectionRowActions({ entity, collection, path, width, frozen, isSelected, selectionEnabled, size, highlightEntity, onCollectionChange, unhighlightEntity, actions = [], hideId, selectionController, openEntityMode, sortableNodeRef, sortableStyle, sortableAttributes, isDragging, isDraggable }) {
4215
4214
  const context = useCMSContext();
4216
- const sideEntityCtrl = context.sideEntityController;
4215
+ const sidePanelCtrl = context.sidePanelController;
4217
4216
  const { t } = useTranslation();
4218
4217
  const onCheckedChange = useCallback((checked) => {
4219
4218
  selectionController?.toggleEntitySelection(entity, checked);
@@ -4250,7 +4249,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
4250
4249
  path,
4251
4250
  collection,
4252
4251
  context,
4253
- sideEntityController: sideEntityCtrl,
4252
+ sidePanelController: sidePanelCtrl,
4254
4253
  selectionController,
4255
4254
  highlightEntity,
4256
4255
  unhighlightEntity,
@@ -4285,7 +4284,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
4285
4284
  path,
4286
4285
  collection,
4287
4286
  context,
4288
- sideEntityController: sideEntityCtrl,
4287
+ sidePanelController: sidePanelCtrl,
4289
4288
  selectionController,
4290
4289
  highlightEntity,
4291
4290
  unhighlightEntity,
@@ -4329,7 +4328,7 @@ var EntityCollectionRowActions = function EntityCollectionRowActions({ entity, c
4329
4328
  return content;
4330
4329
  };
4331
4330
  //#endregion
4332
- //#region src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx
4331
+ //#region src/components/CollectionTableBinding/internal/CollectionTableToolbar.tsx
4333
4332
  function CollectionTableToolbar({ actions, actionsStart, loading, onTextSearch, title, viewModeToggle, initialSearchText, compact = false }) {
4334
4333
  const largeLayout = useLargeLayout();
4335
4334
  const { t } = useTranslation();
@@ -4372,7 +4371,7 @@ function CollectionTableToolbar({ actions, actionsStart, loading, onTextSearch,
4372
4371
  });
4373
4372
  }
4374
4373
  //#endregion
4375
- //#region src/components/EntityCollectionTable/internal/common.tsx
4374
+ //#region src/components/CollectionTableBinding/internal/common.tsx
4376
4375
  function getTableCellAlignment(property) {
4377
4376
  if (property.type === "boolean") return "center";
4378
4377
  else if (property.type === "number") {
@@ -4409,7 +4408,7 @@ function getSubcollectionColumnId(collection) {
4409
4408
  return `subcollection:${collection.slug}`;
4410
4409
  }
4411
4410
  //#endregion
4412
- //#region src/components/EntityCollectionTable/column_utils.tsx
4411
+ //#region src/components/CollectionTableBinding/column_utils.tsx
4413
4412
  function propertiesToColumns({ properties, sortable, fixedFilter, AdditionalHeaderWidget }) {
4414
4413
  const disabledFilter = Boolean(fixedFilter);
4415
4414
  return Object.entries(properties).flatMap(([key, property]) => getColumnKeysForProperty(property, key)).map(({ key, disabled }) => {
@@ -4458,140 +4457,8 @@ function filterableProperty(property, partOfArray = false) {
4458
4457
  ].includes(property.type);
4459
4458
  }
4460
4459
  //#endregion
4461
- //#region src/components/SelectableTable/filters/ReferenceFilterField.tsx
4462
- var operationLabels$3 = {
4463
- "==": "==",
4464
- "!=": "!=",
4465
- ">": ">",
4466
- "<": "<",
4467
- ">=": ">=",
4468
- "<=": "<=",
4469
- in: "In",
4470
- "not-in": "Not in",
4471
- "array-contains": "Contains",
4472
- "array-contains-any": "Contains Any"
4473
- };
4474
- var multipleSelectOperations$3 = [
4475
- "array-contains-any",
4476
- "in",
4477
- "not-in"
4478
- ];
4479
- function ReferenceFilterField({ value, setValue, isArray, path, includeId = true, previewProperties, setHidden }) {
4480
- const { t } = useTranslation();
4481
- const possibleOperations = isArray ? ["array-contains"] : [
4482
- "==",
4483
- "!=",
4484
- ">",
4485
- "<",
4486
- ">=",
4487
- "<="
4488
- ];
4489
- if (isArray) possibleOperations.push("array-contains-any");
4490
- else possibleOperations.push("in", "not-in");
4491
- const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
4492
- const [operation, setOperation] = useState(fieldOperation);
4493
- const [internalValue, setInternalValue] = useState(fieldValue);
4494
- const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => {
4495
- if (!(ref?.isEntityReference && ref?.isEntityReference())) return null;
4496
- return ref.id;
4497
- }).filter(Boolean) : [internalValue.id] : [];
4498
- function updateFilter(op, val) {
4499
- const prevOpIsArray = multipleSelectOperations$3.includes(operation);
4500
- const newOpIsArray = multipleSelectOperations$3.includes(op);
4501
- let newValue = val;
4502
- if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? newValue && !Array.isArray(newValue) && newValue.isEntityReference?.() ? [newValue] : [] : void 0;
4503
- setOperation(op);
4504
- setInternalValue(newValue);
4505
- const hasNewValue = newValue !== null && Array.isArray(newValue) ? newValue.length > 0 : newValue !== void 0;
4506
- if (op && hasNewValue) setValue([op, newValue]);
4507
- else setValue(void 0);
4508
- }
4509
- const collectionRegistryController = useCollectionRegistryController();
4510
- const collection = useMemo(() => {
4511
- return path ? collectionRegistryController.getCollection(path) : void 0;
4512
- }, [path]);
4513
- const onSingleEntitySelected = (entity) => {
4514
- updateFilter(operation, getReferenceFrom(entity));
4515
- };
4516
- const onMultipleEntitiesSelected = (entities) => {
4517
- updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
4518
- };
4519
- const multiple = multipleSelectOperations$3.includes(operation);
4520
- const referenceDialogController = useEntitySelectionDialog({
4521
- multiselect: multiple,
4522
- path,
4523
- collection,
4524
- onSingleEntitySelected,
4525
- onMultipleEntitiesSelected,
4526
- selectedEntityIds,
4527
- onClose: () => {
4528
- setHidden(false);
4529
- }
4530
- });
4531
- const doOpenDialog = () => {
4532
- setHidden(true);
4533
- referenceDialogController.open();
4534
- };
4535
- const buildEntry = (reference) => {
4536
- return /* @__PURE__ */ jsx(ReferencePreview, {
4537
- disabled: !path,
4538
- previewProperties,
4539
- size: "medium",
4540
- onClick: doOpenDialog,
4541
- reference,
4542
- hover: true,
4543
- includeId,
4544
- includeEntityLink: false
4545
- });
4546
- };
4547
- return /* @__PURE__ */ jsxs("div", {
4548
- className: "flex w-full flex-row",
4549
- children: [/* @__PURE__ */ jsx("div", {
4550
- className: "w-[100px]",
4551
- children: /* @__PURE__ */ jsx(Select, {
4552
- value: operation,
4553
- size: "medium",
4554
- fullWidth: true,
4555
- onValueChange: (value) => {
4556
- updateFilter(value, internalValue);
4557
- },
4558
- renderValue: (op) => operationLabels$3[op],
4559
- children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
4560
- value: op,
4561
- children: operationLabels$3[op]
4562
- }, op))
4563
- })
4564
- }), /* @__PURE__ */ jsxs("div", {
4565
- className: "grow ml-2 h-full gap-2 flex flex-col",
4566
- children: [
4567
- internalValue && Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: internalValue.map((ref, index) => buildEntry(ref)) }),
4568
- internalValue && !Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: buildEntry(internalValue) }),
4569
- (!internalValue || Array.isArray(internalValue) && internalValue.length === 0) && /* @__PURE__ */ jsx(Button, {
4570
- onClick: doOpenDialog,
4571
- size: "medium",
4572
- className: "h-full w-full",
4573
- children: multiple ? t("select_references") : t("select_reference")
4574
- }),
4575
- !isArray && /* @__PURE__ */ jsxs(Label, {
4576
- className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 bg-surface-50 dark:bg-surface-900 hover:bg-surface-100 dark:hover:bg-surface-800",
4577
- htmlFor: "null-filter",
4578
- children: [/* @__PURE__ */ jsx(Checkbox, {
4579
- id: "null-filter",
4580
- checked: internalValue === null,
4581
- size: "small",
4582
- onCheckedChange: (checked) => {
4583
- if (internalValue !== null) updateFilter(operation, null);
4584
- else updateFilter(operation, void 0);
4585
- }
4586
- }), t("filter_for_null_values")]
4587
- })
4588
- ]
4589
- })]
4590
- });
4591
- }
4592
- //#endregion
4593
4460
  //#region src/components/SelectableTable/filters/StringNumberFilterField.tsx
4594
- var operationLabels$2 = {
4461
+ var operationLabels$3 = {
4595
4462
  "==": "==",
4596
4463
  "!=": "!=",
4597
4464
  ">": ">",
@@ -4602,40 +4469,62 @@ var operationLabels$2 = {
4602
4469
  "not-in": "Not in",
4603
4470
  "array-contains": "Contains",
4604
4471
  "array-contains-any": "Any",
4605
- "is-null": "Is null"
4472
+ "ilike": "Contains",
4473
+ "not-ilike": "Not contains",
4474
+ "is-null": "Is null",
4475
+ "is-not-null": "Is not null"
4606
4476
  };
4607
- var multipleSelectOperations$2 = [
4477
+ var multipleSelectOperations$3 = [
4608
4478
  "array-contains-any",
4609
4479
  "in",
4610
4480
  "not-in"
4611
4481
  ];
4612
- function StringNumberFilterField({ name, value, setValue, type, isArray, enumValues, title }) {
4482
+ /** Operators that match a substring, wrapped in SQL wildcards (`%value%`). */
4483
+ var containsOperations = ["ilike", "not-ilike"];
4484
+ /** Strip the surrounding `%` wildcards a contains-filter adds, for display. */
4485
+ function unwrapContains(value) {
4486
+ if (typeof value !== "string") return "";
4487
+ return value.replace(/^%/, "").replace(/%$/, "");
4488
+ }
4489
+ function StringNumberFilterField({ name, value, setValue, type, isArray, enumValues, title, operators }) {
4613
4490
  const { t } = useTranslation();
4614
- const possibleOperations = isArray ? ["array-contains"] : [
4491
+ let possibleOperations = isArray ? ["array-contains"] : [
4615
4492
  "==",
4616
4493
  "!=",
4617
4494
  ">",
4618
4495
  "<",
4619
4496
  ">=",
4620
4497
  "<=",
4621
- "is-null"
4498
+ "is-null",
4499
+ "is-not-null"
4622
4500
  ];
4501
+ if (!isArray && !enumValues && type === "string") possibleOperations.push("ilike", "not-ilike");
4623
4502
  if (enumValues) if (isArray) possibleOperations.push("array-contains-any");
4624
4503
  else possibleOperations.push("in", "not-in");
4504
+ if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
4625
4505
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
4626
- const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
4627
- const [internalValue, setInternalValue] = useState(fieldValue);
4628
- const isNullOperation = operation === "is-null";
4506
+ const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation === "!=" && fieldValue === null ? "is-not-null" : fieldOperation);
4507
+ const [internalValue, setInternalValue] = useState(containsOperations.includes(fieldOperation) ? unwrapContains(fieldValue) : fieldValue);
4508
+ const isNullOperation = operation === "is-null" || operation === "is-not-null";
4509
+ if (possibleOperations.length === 0) return null;
4629
4510
  function updateFilter(op, val) {
4630
- if (op === "is-null") {
4511
+ if (op === "is-null" || op === "is-not-null") {
4631
4512
  setOperation(op);
4632
4513
  setInternalValue(null);
4633
- setValue(["==", null]);
4514
+ setValue([op, null]);
4515
+ return;
4516
+ }
4517
+ if (op === "ilike" || op === "not-ilike") {
4518
+ const raw = typeof val === "string" ? val : "";
4519
+ setOperation(op);
4520
+ setInternalValue(raw);
4521
+ if (raw.length > 0) setValue([op, `%${raw}%`]);
4522
+ else setValue(void 0);
4634
4523
  return;
4635
4524
  }
4636
4525
  let newValue = val;
4637
- const prevOpIsArray = multipleSelectOperations$2.includes(operation);
4638
- const newOpIsArray = multipleSelectOperations$2.includes(op);
4526
+ const prevOpIsArray = multipleSelectOperations$3.includes(operation);
4527
+ const newOpIsArray = multipleSelectOperations$3.includes(op);
4639
4528
  if (prevOpIsArray !== newOpIsArray) if (newOpIsArray) if (typeof val === "string") newValue = [val];
4640
4529
  else if (typeof val === "number") newValue = [val];
4641
4530
  else newValue = [];
@@ -4647,7 +4536,7 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
4647
4536
  if (op && hasNewValue) setValue([op, newValue]);
4648
4537
  else setValue(void 0);
4649
4538
  }
4650
- const multiple = multipleSelectOperations$2.includes(operation);
4539
+ const multiple = multipleSelectOperations$3.includes(operation);
4651
4540
  return /* @__PURE__ */ jsxs("div", {
4652
4541
  className: "flex w-full",
4653
4542
  children: [/* @__PURE__ */ jsx("div", {
@@ -4660,10 +4549,10 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
4660
4549
  onValueChange: (value) => {
4661
4550
  updateFilter(value, internalValue);
4662
4551
  },
4663
- renderValue: (op) => operationLabels$2[op],
4552
+ renderValue: (op) => operationLabels$3[op],
4664
4553
  children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
4665
4554
  value: op,
4666
- children: operationLabels$2[op]
4555
+ children: operationLabels$3[op]
4667
4556
  }, op))
4668
4557
  })
4669
4558
  }), /* @__PURE__ */ jsxs("div", {
@@ -4743,8 +4632,9 @@ function StringNumberFilterField({ name, value, setValue, type, isArray, enumVal
4743
4632
  }
4744
4633
  //#endregion
4745
4634
  //#region src/components/SelectableTable/filters/BooleanFilterField.tsx
4746
- function BooleanFilterField({ name, title, value, setValue }) {
4635
+ function BooleanFilterField({ name, title, value, setValue, operators }) {
4747
4636
  const { t } = useTranslation();
4637
+ if (operators && !operators.includes("==")) return null;
4748
4638
  function updateFilter(val) {
4749
4639
  if (val !== void 0) setValue(["==", val]);
4750
4640
  else setValue(void 0);
@@ -4763,7 +4653,7 @@ function BooleanFilterField({ name, title, value, setValue }) {
4763
4653
  }
4764
4654
  //#endregion
4765
4655
  //#region src/components/SelectableTable/filters/DateTimeFilterField.tsx
4766
- var operationLabels$1 = {
4656
+ var operationLabels$2 = {
4767
4657
  "==": "==",
4768
4658
  "!=": "!=",
4769
4659
  ">": ">",
@@ -4774,34 +4664,38 @@ var operationLabels$1 = {
4774
4664
  in: "in",
4775
4665
  "array-contains": "Contains",
4776
4666
  "array-contains-any": "Any",
4777
- "is-null": "Is null"
4667
+ "is-null": "Is null",
4668
+ "is-not-null": "Is not null"
4778
4669
  };
4779
- var multipleSelectOperations$1 = ["array-contains-any", "in"];
4780
- function DateTimeFilterField({ name, isArray, mode, value, setValue, title, timezone }) {
4670
+ var multipleSelectOperations$2 = ["array-contains-any", "in"];
4671
+ function DateTimeFilterField({ name, isArray, mode, value, setValue, title, timezone, operators }) {
4781
4672
  const { locale } = useCustomizationController();
4782
- const possibleOperations = isArray ? ["array-contains"] : [
4673
+ let possibleOperations = isArray ? ["array-contains"] : [
4783
4674
  "==",
4784
4675
  "!=",
4785
4676
  ">",
4786
4677
  "<",
4787
4678
  ">=",
4788
4679
  "<=",
4789
- "is-null"
4680
+ "is-null",
4681
+ "is-not-null"
4790
4682
  ];
4683
+ if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
4791
4684
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
4792
- const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
4685
+ const [operation, setOperation] = useState(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation === "!=" && fieldValue === null ? "is-not-null" : fieldOperation);
4793
4686
  const [internalValue, setInternalValue] = useState(fieldValue);
4794
- const isNullOperation = operation === "is-null";
4687
+ const isNullOperation = operation === "is-null" || operation === "is-not-null";
4688
+ if (possibleOperations.length === 0) return null;
4795
4689
  function updateFilter(op, val) {
4796
- if (op === "is-null") {
4690
+ if (op === "is-null" || op === "is-not-null") {
4797
4691
  setOperation(op);
4798
4692
  setInternalValue(null);
4799
- setValue(["==", null]);
4693
+ setValue([op, null]);
4800
4694
  return;
4801
4695
  }
4802
4696
  let newValue = val;
4803
- const prevOpIsArray = multipleSelectOperations$1.includes(operation);
4804
- const newOpIsArray = multipleSelectOperations$1.includes(op);
4697
+ const prevOpIsArray = multipleSelectOperations$2.includes(operation);
4698
+ const newOpIsArray = multipleSelectOperations$2.includes(op);
4805
4699
  if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? val ? [val] : [] : void 0;
4806
4700
  setOperation(op);
4807
4701
  setInternalValue(Array.isArray(newValue) ? newValue[0] ?? null : newValue);
@@ -4820,10 +4714,10 @@ function DateTimeFilterField({ name, isArray, mode, value, setValue, title, time
4820
4714
  onValueChange: (value) => {
4821
4715
  updateFilter(value, internalValue);
4822
4716
  },
4823
- renderValue: (op) => operationLabels$1[op],
4717
+ renderValue: (op) => operationLabels$2[op],
4824
4718
  children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
4825
4719
  value: op,
4826
- children: operationLabels$1[op]
4720
+ children: operationLabels$2[op]
4827
4721
  }, op))
4828
4722
  })
4829
4723
  }), /* @__PURE__ */ jsx("div", {
@@ -4844,6 +4738,140 @@ function DateTimeFilterField({ name, isArray, mode, value, setValue, title, time
4844
4738
  });
4845
4739
  }
4846
4740
  //#endregion
4741
+ //#region src/components/SelectableTable/filters/ReferenceFilterField.tsx
4742
+ var operationLabels$1 = {
4743
+ "==": "==",
4744
+ "!=": "!=",
4745
+ ">": ">",
4746
+ "<": "<",
4747
+ ">=": ">=",
4748
+ "<=": "<=",
4749
+ in: "In",
4750
+ "not-in": "Not in",
4751
+ "array-contains": "Contains",
4752
+ "array-contains-any": "Contains Any"
4753
+ };
4754
+ var multipleSelectOperations$1 = [
4755
+ "array-contains-any",
4756
+ "in",
4757
+ "not-in"
4758
+ ];
4759
+ function ReferenceFilterField({ value, setValue, isArray, path, includeId = true, previewProperties, setHidden, operators }) {
4760
+ const { t } = useTranslation();
4761
+ let possibleOperations = isArray ? ["array-contains"] : [
4762
+ "==",
4763
+ "!=",
4764
+ ">",
4765
+ "<",
4766
+ ">=",
4767
+ "<="
4768
+ ];
4769
+ if (isArray) possibleOperations.push("array-contains-any");
4770
+ else possibleOperations.push("in", "not-in");
4771
+ if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
4772
+ const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
4773
+ const [operation, setOperation] = useState(fieldOperation);
4774
+ const [internalValue, setInternalValue] = useState(fieldValue);
4775
+ const selectedEntityIds = internalValue ? Array.isArray(internalValue) ? internalValue.map((ref) => {
4776
+ if (!(ref?.isEntityReference && ref?.isEntityReference())) return null;
4777
+ return ref.id;
4778
+ }).filter(Boolean) : [internalValue.id] : [];
4779
+ function updateFilter(op, val) {
4780
+ const prevOpIsArray = multipleSelectOperations$1.includes(operation);
4781
+ const newOpIsArray = multipleSelectOperations$1.includes(op);
4782
+ let newValue = val;
4783
+ if (prevOpIsArray !== newOpIsArray) newValue = newOpIsArray ? newValue && !Array.isArray(newValue) && newValue.isEntityReference?.() ? [newValue] : [] : void 0;
4784
+ setOperation(op);
4785
+ setInternalValue(newValue);
4786
+ const hasNewValue = newValue !== null && Array.isArray(newValue) ? newValue.length > 0 : newValue !== void 0;
4787
+ if (op && hasNewValue) setValue([op, newValue]);
4788
+ else setValue(void 0);
4789
+ }
4790
+ const collectionRegistryController = useCollectionRegistryController();
4791
+ const collection = useMemo(() => {
4792
+ return path ? collectionRegistryController.getCollection(path) : void 0;
4793
+ }, [path]);
4794
+ const onSingleEntitySelected = (entity) => {
4795
+ updateFilter(operation, getReferenceFrom(entity));
4796
+ };
4797
+ const onMultipleEntitiesSelected = (entities) => {
4798
+ updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
4799
+ };
4800
+ const multiple = multipleSelectOperations$1.includes(operation);
4801
+ const referenceDialogController = useSelectionDialog({
4802
+ multiselect: multiple,
4803
+ path,
4804
+ collection,
4805
+ onSingleEntitySelected,
4806
+ onMultipleEntitiesSelected,
4807
+ selectedEntityIds,
4808
+ onClose: () => {
4809
+ setHidden(false);
4810
+ }
4811
+ });
4812
+ const doOpenDialog = () => {
4813
+ setHidden(true);
4814
+ referenceDialogController.open();
4815
+ };
4816
+ const buildEntry = (reference) => {
4817
+ return /* @__PURE__ */ jsx(ReferencePreview, {
4818
+ disabled: !path,
4819
+ previewProperties,
4820
+ size: "medium",
4821
+ onClick: doOpenDialog,
4822
+ reference,
4823
+ hover: true,
4824
+ includeId,
4825
+ includeEntityLink: false
4826
+ });
4827
+ };
4828
+ if (possibleOperations.length === 0) return null;
4829
+ return /* @__PURE__ */ jsxs("div", {
4830
+ className: "flex w-full flex-row",
4831
+ children: [/* @__PURE__ */ jsx("div", {
4832
+ className: "w-[100px]",
4833
+ children: /* @__PURE__ */ jsx(Select, {
4834
+ value: operation,
4835
+ size: "medium",
4836
+ fullWidth: true,
4837
+ onValueChange: (value) => {
4838
+ updateFilter(value, internalValue);
4839
+ },
4840
+ renderValue: (op) => operationLabels$1[op],
4841
+ children: possibleOperations.map((op) => /* @__PURE__ */ jsx(SelectItem, {
4842
+ value: op,
4843
+ children: operationLabels$1[op]
4844
+ }, op))
4845
+ })
4846
+ }), /* @__PURE__ */ jsxs("div", {
4847
+ className: "grow ml-2 h-full gap-2 flex flex-col",
4848
+ children: [
4849
+ internalValue && Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: internalValue.map((ref, index) => buildEntry(ref)) }),
4850
+ internalValue && !Array.isArray(internalValue) && /* @__PURE__ */ jsx("div", { children: buildEntry(internalValue) }),
4851
+ (!internalValue || Array.isArray(internalValue) && internalValue.length === 0) && /* @__PURE__ */ jsx(Button, {
4852
+ onClick: doOpenDialog,
4853
+ size: "medium",
4854
+ className: "h-full w-full",
4855
+ children: multiple ? t("select_references") : t("select_reference")
4856
+ }),
4857
+ !isArray && /* @__PURE__ */ jsxs(Label, {
4858
+ className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 bg-surface-50 dark:bg-surface-900 hover:bg-surface-100 dark:hover:bg-surface-800",
4859
+ htmlFor: "null-filter",
4860
+ children: [/* @__PURE__ */ jsx(Checkbox, {
4861
+ id: "null-filter",
4862
+ checked: internalValue === null,
4863
+ size: "small",
4864
+ onCheckedChange: (checked) => {
4865
+ if (internalValue !== null) updateFilter(operation, null);
4866
+ else updateFilter(operation, void 0);
4867
+ }
4868
+ }), t("filter_for_null_values")]
4869
+ })
4870
+ ]
4871
+ })]
4872
+ });
4873
+ }
4874
+ //#endregion
4847
4875
  //#region src/components/SelectableTable/filters/RelationFilterField.tsx
4848
4876
  var operationLabels = {
4849
4877
  "==": "==",
@@ -4862,9 +4890,9 @@ var multipleSelectOperations = [
4862
4890
  "in",
4863
4891
  "not-in"
4864
4892
  ];
4865
- function RelationFilterField({ value, setValue, relation, name: _name, hidden: _hidden, setHidden: _setHidden }) {
4893
+ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _hidden, setHidden: _setHidden, operators }) {
4866
4894
  const manyRelation = relation.cardinality === "many";
4867
- const possibleOperations = manyRelation ? ["array-contains", "array-contains-any"] : [
4895
+ let possibleOperations = manyRelation ? ["array-contains", "array-contains-any"] : [
4868
4896
  "==",
4869
4897
  "!=",
4870
4898
  ">",
@@ -4874,6 +4902,7 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
4874
4902
  "in",
4875
4903
  "not-in"
4876
4904
  ];
4905
+ if (operators) possibleOperations = possibleOperations.filter((op) => operators.includes(op));
4877
4906
  const [fieldOperation, fieldValue] = value || [possibleOperations[0], void 0];
4878
4907
  const [operation, setOperation] = useState(fieldOperation);
4879
4908
  const [internalValue, setInternalValue] = useState(fieldValue);
@@ -4905,6 +4934,7 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
4905
4934
  }
4906
4935
  updateFilter(operation, newVal);
4907
4936
  };
4937
+ if (possibleOperations.length === 0) return null;
4908
4938
  return /* @__PURE__ */ jsxs("div", {
4909
4939
  className: "flex flex-row",
4910
4940
  children: [/* @__PURE__ */ jsx("div", {
@@ -4946,28 +4976,146 @@ function RelationFilterField({ value, setValue, relation, name: _name, hidden: _
4946
4976
  });
4947
4977
  }
4948
4978
  //#endregion
4979
+ //#region src/components/SelectableTable/filters/FilterFieldBinding.tsx
4980
+ /**
4981
+ * The single entry point for rendering a collection filter field.
4982
+ * Used by both the table header filters ({@link SelectableTable}) and the
4983
+ * Filters dialog.
4984
+ *
4985
+ * Resolution order:
4986
+ * 1. `property.ui.Filter` — per-property replacement (rendered even when the
4987
+ * resolved operator list is empty; the component owns filterability).
4988
+ * 2. `components["Collection.FilterField"]` — collection-level or app-level
4989
+ * override (wrap mode supported via `OriginalComponent`).
4990
+ * 3. Built-in field dispatched by property type.
4991
+ *
4992
+ * The operators handed to the field are the intersection of the engine's
4993
+ * capabilities, the property-type defaults, and `property.ui.filterOperators`
4994
+ * (see `resolveFilterOperators`). When that intersection is empty and no
4995
+ * per-property `Filter` is set, nothing is rendered.
4996
+ *
4997
+ * @group Components
4998
+ */
4999
+ function FilterFieldBinding({ propertyKey, property, engine, value, setValue, hidden, setHidden }) {
5000
+ const isArray = property.type === "array";
5001
+ const ofVal = isArray ? property.of : void 0;
5002
+ const baseProperty = isArray ? Array.isArray(ofVal) ? ofVal[0] : ofVal : property;
5003
+ const scopeCollection = useCollectionScope();
5004
+ const ResolvedFilterField = useComponentOverride("Collection.FilterField", DefaultFilterField);
5005
+ const PropertyFilter = useResolvedComponent(baseProperty?.ui?.Filter);
5006
+ if (!baseProperty) return null;
5007
+ const operators = resolveFilterOperators({
5008
+ property: baseProperty,
5009
+ isArray,
5010
+ engine: engine ?? scopeCollection?.engine
5011
+ });
5012
+ const bindingProps = {
5013
+ propertyKey,
5014
+ property: baseProperty,
5015
+ isArray,
5016
+ operators,
5017
+ value,
5018
+ setValue,
5019
+ title: property.name,
5020
+ hidden,
5021
+ setHidden
5022
+ };
5023
+ if (PropertyFilter) return /* @__PURE__ */ jsx(Suspense, {
5024
+ fallback: null,
5025
+ children: /* @__PURE__ */ jsx(PropertyFilter, { ...bindingProps })
5026
+ });
5027
+ if (operators.length === 0) return null;
5028
+ return /* @__PURE__ */ jsx(ResolvedFilterField, { ...bindingProps });
5029
+ }
5030
+ /**
5031
+ * Built-in filter field dispatch by property type. This is the
5032
+ * `OriginalComponent` received by `"Collection.FilterField"` overrides in
5033
+ * wrap mode.
5034
+ */
5035
+ function DefaultFilterField({ propertyKey, property, isArray, operators, value, setValue, title, hidden, setHidden }) {
5036
+ if (property.type === "reference") {
5037
+ const referenceProperty = property;
5038
+ return /* @__PURE__ */ jsx(ReferenceFilterField, {
5039
+ value,
5040
+ setValue,
5041
+ name: propertyKey,
5042
+ isArray,
5043
+ operators,
5044
+ path: referenceProperty.path,
5045
+ title,
5046
+ includeId: referenceProperty.includeId,
5047
+ previewProperties: referenceProperty.ui?.previewProperties,
5048
+ hidden: hidden ?? false,
5049
+ setHidden: setHidden ?? (() => void 0)
5050
+ });
5051
+ }
5052
+ if (property.type === "relation") {
5053
+ const relation = property.relation;
5054
+ if (!relation) return null;
5055
+ return /* @__PURE__ */ jsx(RelationFilterField, {
5056
+ value,
5057
+ setValue,
5058
+ name: propertyKey,
5059
+ operators,
5060
+ relation,
5061
+ hidden: hidden ?? false,
5062
+ setHidden: setHidden ?? (() => void 0)
5063
+ });
5064
+ }
5065
+ if (property.type === "number" || property.type === "string") {
5066
+ const enumValues = property.enum ? enumToObjectEntries(property.enum) : void 0;
5067
+ return /* @__PURE__ */ jsx(StringNumberFilterField, {
5068
+ value,
5069
+ setValue,
5070
+ name: propertyKey,
5071
+ type: property.type,
5072
+ isArray,
5073
+ operators,
5074
+ enumValues,
5075
+ title
5076
+ });
5077
+ }
5078
+ if (property.type === "boolean") return /* @__PURE__ */ jsx(BooleanFilterField, {
5079
+ value,
5080
+ setValue,
5081
+ name: propertyKey,
5082
+ operators,
5083
+ title
5084
+ });
5085
+ if (property.type === "date") return /* @__PURE__ */ jsx(DateTimeFilterField, {
5086
+ value,
5087
+ setValue,
5088
+ name: propertyKey,
5089
+ mode: property.mode,
5090
+ isArray,
5091
+ operators,
5092
+ title
5093
+ });
5094
+ return null;
5095
+ }
5096
+ //#endregion
4949
5097
  //#region src/components/SelectableTable/SelectableTable.tsx
4950
5098
  /**
4951
5099
  * This component is in charge of rendering a collection table with a high
4952
5100
  * degree of customization.
4953
5101
  *
4954
- * This component is used internally by {@link EntityCollectionView} and
5102
+ * This component is used internally by {@link CollectionViewBinding} and
4955
5103
  * {@link useReferenceDialog}
4956
5104
  *
4957
5105
  * Please note that you only need to use this component if you are building
4958
5106
  * a custom view. If you just need to create a default view you can do it
4959
5107
  * exclusively with config options.
4960
5108
  *
4961
- * If you want to bind a {@link EntityCollection} to a table with the default
5109
+ * If you want to bind a {@link CollectionConfig} to a table with the default
4962
5110
  * options you see in collections in the top level navigation, you can
4963
- * check {@link EntityCollectionView}.
5111
+ * check {@link CollectionViewBinding}.
4964
5112
  *
4965
5113
  * The data displayed in the table is managed by a {@link EntityTableController}.
4966
5114
  * You can build the default, bound to a path in the driver, by using the hook
4967
5115
  * {@link useDataTableController}
4968
5116
  *
4969
- * @see EntityCollectionTableProps
4970
- * @see EntityCollectionView
5117
+ * @see CollectionTableBindingProps
5118
+ * @see CollectionViewBinding
4971
5119
  * @see VirtualTable
4972
5120
  * @group Components
4973
5121
  */
@@ -4998,7 +5146,7 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
4998
5146
  if (cell) selectionStore.select({
4999
5147
  ...cell,
5000
5148
  columnKey: cell.propertyKey,
5001
- rowId: cell.entityId
5149
+ id: cell.entityId
5002
5150
  });
5003
5151
  else selectionStore.select(void 0);
5004
5152
  }, [selectionStore]);
@@ -5037,6 +5185,19 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
5037
5185
  size,
5038
5186
  selectionStore
5039
5187
  ]);
5188
+ const createFilterField = useCallback(({ id, filterValue, setFilterValue, column, hidden, setHidden }) => {
5189
+ if (!column.custom) return null;
5190
+ const { resolvedProperty } = column.custom;
5191
+ if (!resolvedProperty) return null;
5192
+ return /* @__PURE__ */ jsx(FilterFieldBinding, {
5193
+ propertyKey: id,
5194
+ property: resolvedProperty,
5195
+ value: filterValue,
5196
+ setValue: setFilterValue,
5197
+ hidden,
5198
+ setHidden
5199
+ });
5200
+ }, []);
5040
5201
  return /* @__PURE__ */ jsx(SelectableTableContext.Provider, {
5041
5202
  value: contextValue,
5042
5203
  children: /* @__PURE__ */ jsx("div", {
@@ -5075,93 +5236,33 @@ var SelectableTable = function SelectableTable({ onValueChange, cellRenderer, on
5075
5236
  })
5076
5237
  });
5077
5238
  };
5078
- function createFilterField({ id, filterValue, setFilterValue, column, hidden, setHidden }) {
5079
- if (!column.custom) return null;
5080
- const { resolvedProperty } = column.custom;
5081
- const isArray = resolvedProperty?.type === "array";
5082
- const ofVal = isArray && resolvedProperty ? resolvedProperty.of : void 0;
5083
- const baseProperty = isArray ? Array.isArray(ofVal) ? ofVal[0] : ofVal : resolvedProperty;
5084
- if (!baseProperty) return null;
5085
- if (baseProperty.type === "reference") return /* @__PURE__ */ jsx(ReferenceFilterField, {
5086
- value: filterValue,
5087
- setValue: setFilterValue,
5088
- name: id,
5089
- isArray,
5090
- path: baseProperty.path,
5091
- title: resolvedProperty?.name,
5092
- includeId: baseProperty.includeId,
5093
- previewProperties: baseProperty?.ui?.previewProperties,
5094
- hidden,
5095
- setHidden
5096
- });
5097
- else if (baseProperty.type === "relation" && baseProperty.relation) return /* @__PURE__ */ jsx(RelationFilterField, {
5098
- value: filterValue,
5099
- setValue: setFilterValue,
5100
- name: id,
5101
- relation: baseProperty.relation,
5102
- hidden,
5103
- setHidden
5104
- });
5105
- else if (baseProperty.type === "number" || baseProperty.type === "string") {
5106
- const name = baseProperty.name;
5107
- const enumValues = baseProperty.enum ? enumToObjectEntries(baseProperty.enum) : void 0;
5108
- return /* @__PURE__ */ jsx(StringNumberFilterField, {
5109
- value: filterValue,
5110
- setValue: setFilterValue,
5111
- name: id,
5112
- type: baseProperty.type,
5113
- isArray,
5114
- enumValues,
5115
- title: name
5116
- });
5117
- } else if (baseProperty.type === "boolean") {
5118
- const name = baseProperty.name;
5119
- return /* @__PURE__ */ jsx(BooleanFilterField, {
5120
- value: filterValue,
5121
- setValue: setFilterValue,
5122
- name: id,
5123
- title: name
5124
- });
5125
- } else if (baseProperty.type === "date") {
5126
- const title = baseProperty.name;
5127
- return /* @__PURE__ */ jsx(DateTimeFilterField, {
5128
- value: filterValue,
5129
- setValue: setFilterValue,
5130
- name: id,
5131
- mode: baseProperty.mode,
5132
- isArray,
5133
- title
5134
- });
5135
- }
5136
- return /* @__PURE__ */ jsx("div", { children: `Currently the filter field ${resolvedProperty?.type} is not supported` });
5137
- }
5138
5239
  //#endregion
5139
- //#region src/components/EntityCollectionTable/EntityCollectionTable.tsx
5240
+ //#region src/components/CollectionTableBinding/CollectionTableBinding.tsx
5140
5241
  /**
5141
5242
  * This component is in charge of rendering a collection table with a high
5142
5243
  * degree of customization.
5143
5244
  *
5144
- * This component is used internally by {@link EntityCollectionView} and
5245
+ * This component is used internally by {@link CollectionViewBinding} and
5145
5246
  * {@link useReferenceDialog}
5146
5247
  *
5147
5248
  * Please note that you only need to use this component if you are building
5148
5249
  * a custom view. If you just need to create a default view you can do it
5149
5250
  * exclusively with config options.
5150
5251
  *
5151
- * If you want to bind a {@link EntityCollection} to a table with the default
5252
+ * If you want to bind a {@link CollectionConfig} to a table with the default
5152
5253
  * options you see in collections in the top level navigation, you can
5153
- * check {@link EntityCollectionView}.
5254
+ * check {@link CollectionViewBinding}.
5154
5255
  *
5155
5256
  * The data displayed in the table is managed by a {@link EntityTableController}.
5156
5257
  * You can build the default, bound to a path in the driver, by using the hook
5157
5258
  * {@link useDataTableController}
5158
5259
  *
5159
- * @see EntityCollectionTableProps
5160
- * @see EntityCollectionView
5260
+ * @see CollectionTableBindingProps
5261
+ * @see CollectionViewBinding
5161
5262
  * @see VirtualTable
5162
5263
  * @group Components
5163
5264
  */
5164
- var EntityCollectionTable = function EntityCollectionTable({ className, style, fixedFilter, actionsStart, actions, viewModeToggle, title, tableRowActionsBuilder, uniqueFieldValidator, getPropertyFor, onValueChange, selectionController, highlightedEntities, onEntityClick, onColumnResize, initialScroll, onScroll, onSizeChanged, hoverRow = true, inlineEditing = false, additionalFields, displayedColumnIds, defaultSize, properties, tableController, filterable = true, sortable = true, endAdornment, AddColumnComponent, AdditionalHeaderWidget, additionalIDHeaderWidget, emptyComponent, getIdColumnWidth, enablePopupIcon, openEntityMode = "side_panel", onColumnsOrderChange, hideToolbar = false }) {
5265
+ var CollectionTableBinding = function CollectionTableBinding({ className, style, fixedFilter, actionsStart, actions, viewModeToggle, title, tableRowActionsBuilder, uniqueFieldValidator, getPropertyFor, onValueChange, selectionController, highlightedEntities, onEntityClick, onColumnResize, initialScroll, onScroll, onSizeChanged, hoverRow = true, inlineEditing = false, additionalFields, displayedColumnIds, defaultSize, properties, tableController, filterable = true, sortable = true, endAdornment, AddColumnComponent, AdditionalHeaderWidget, additionalIDHeaderWidget, emptyComponent, getIdColumnWidth, enablePopupIcon, openEntityMode = "side_panel", onColumnsOrderChange, hideToolbar = false }) {
5165
5266
  const ref = useRef(null);
5166
5267
  const largeLayout = useLargeLayout();
5167
5268
  const selectedEntities = useMemo(() => {
@@ -5314,7 +5415,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
5314
5415
  width: column.width,
5315
5416
  frozen: column.frozen
5316
5417
  });
5317
- else return /* @__PURE__ */ jsx(EntityCollectionRowActions, {
5418
+ else return /* @__PURE__ */ jsx(CollectionRowActions, {
5318
5419
  entity: props.rowData,
5319
5420
  width: column.width,
5320
5421
  frozen: column.frozen,
@@ -5389,7 +5490,7 @@ var EntityCollectionTable = function EntityCollectionTable({ className, style, f
5389
5490
  });
5390
5491
  };
5391
5492
  //#endregion
5392
- //#region src/components/EntityCollectionView/useSelectionController.tsx
5493
+ //#region src/components/CollectionViewBinding/useSelectionController.tsx
5393
5494
  function useSelectionController(onSelectionChange) {
5394
5495
  const [selectedEntities, setSelectedEntities] = useState([]);
5395
5496
  const onSelectionChangeRef = useRef(onSelectionChange);
@@ -5448,11 +5549,11 @@ function mergeEntityActions(currentActions, newActions) {
5448
5549
  return updatedActions;
5449
5550
  }
5450
5551
  //#endregion
5451
- //#region src/components/EntityEditViewFormActions.tsx
5452
- function EntityEditViewFormActions({ collection, path, entity, layout, savingError, formex, disabled, status, pluginActions, openEntityMode, showDefaultActions = true, navigateBack, formContext }) {
5552
+ //#region src/components/EditFormActions.tsx
5553
+ function EditFormActions({ collection, path, entity, layout, savingError, formex, disabled, status, pluginActions, openEntityMode, showDefaultActions = true, navigateBack, formContext }) {
5453
5554
  const { canCreate, canDelete } = usePermissions();
5454
5555
  const context = useCMSContext();
5455
- const sideEntityController = context.sideEntityController;
5556
+ const sidePanelController = context.sidePanelController;
5456
5557
  const sideDialogContext = useSideDialogContext();
5457
5558
  const customizationController = useCustomizationController();
5458
5559
  const { t } = useTranslation();
@@ -5482,7 +5583,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
5482
5583
  formActions,
5483
5584
  collection,
5484
5585
  context,
5485
- sideEntityController,
5586
+ sidePanelController,
5486
5587
  disabled,
5487
5588
  status,
5488
5589
  sideDialogContext,
@@ -5500,7 +5601,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
5500
5601
  formActions,
5501
5602
  collection,
5502
5603
  context,
5503
- sideEntityController,
5604
+ sidePanelController,
5504
5605
  sideDialogContext,
5505
5606
  disabled,
5506
5607
  status,
@@ -5515,7 +5616,7 @@ function EntityEditViewFormActions({ collection, path, entity, layout, savingErr
5515
5616
  if (layout === "responsive") return /* @__PURE__ */ jsxs(Fragment, { children: [bottomActions, sideActions] });
5516
5617
  return layout === "bottom" ? bottomActions : sideActions;
5517
5618
  }
5518
- function buildBottomActions({ savingError, entity, formActions, collection, context, sideEntityController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
5619
+ function buildBottomActions({ savingError, entity, formActions, collection, context, sidePanelController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
5519
5620
  const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
5520
5621
  const canClose = openEntityMode === "side_panel" || openEntityMode === "dialog";
5521
5622
  return /* @__PURE__ */ jsxs(DialogActions, {
@@ -5538,7 +5639,7 @@ function buildBottomActions({ savingError, entity, formActions, collection, cont
5538
5639
  path: getCollectionDataPath(collection),
5539
5640
  collection,
5540
5641
  context,
5541
- sideEntityController,
5642
+ sidePanelController,
5542
5643
  openEntityMode,
5543
5644
  navigateBack,
5544
5645
  formContext
@@ -5607,7 +5708,7 @@ function buildBottomActions({ savingError, entity, formActions, collection, cont
5607
5708
  ]
5608
5709
  });
5609
5710
  }
5610
- function buildSideActions({ savingError, entity, formActions, collection, context, sideEntityController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
5711
+ function buildSideActions({ savingError, entity, formActions, collection, context, sidePanelController, disabled, status, sideDialogContext, pluginActions, openEntityMode, navigateBack, formContext, formex, t, className }) {
5611
5712
  const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
5612
5713
  return /* @__PURE__ */ jsxs("div", {
5613
5714
  className: cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin, className),
@@ -5656,7 +5757,7 @@ function buildSideActions({ savingError, entity, formActions, collection, contex
5656
5757
  path: getCollectionDataPath(collection),
5657
5758
  collection,
5658
5759
  context,
5659
- sideEntityController,
5760
+ sidePanelController,
5660
5761
  openEntityMode,
5661
5762
  navigateBack,
5662
5763
  formContext
@@ -5719,14 +5820,14 @@ function EntityActionButton({ action, enabled, props }) {
5719
5820
  });
5720
5821
  }
5721
5822
  //#endregion
5722
- //#region src/components/EntityEditView.tsx
5723
- var EntityHistoryView = lazy(() => import("./history-B3cqBzEV.js").then((m) => ({ default: m.EntityHistoryView })));
5823
+ //#region src/components/EditViewBinding.tsx
5824
+ var EntityHistoryView = lazy(() => import("./history-GSa4BgDt.js").then((m) => ({ default: m.EntityHistoryView })));
5724
5825
  /**
5725
5826
  * This is the default view that is used as the content of a side panel when
5726
- * an entity is opened.
5827
+ * a record is opened.
5727
5828
  */
5728
- function EntityEditView({ entityId, ...props }) {
5729
- const { entity, dataLoading, dataLoadingError } = useEntityFetch({
5829
+ function EditViewBinding({ entityId, ...props }) {
5830
+ const { entity, dataLoading, dataLoadingError } = useFetch({
5730
5831
  path: props.path,
5731
5832
  entityId,
5732
5833
  collection: props.collection,
@@ -5754,7 +5855,7 @@ function EntityEditView({ entityId, ...props }) {
5754
5855
  children: "Entity not found"
5755
5856
  }) });
5756
5857
  }
5757
- const content = /* @__PURE__ */ jsx(EntityEditViewInner, {
5858
+ const content = /* @__PURE__ */ jsx(EditViewBindingInner, {
5758
5859
  ...props,
5759
5860
  entityId,
5760
5861
  entity,
@@ -5764,16 +5865,15 @@ function EntityEditView({ entityId, ...props }) {
5764
5865
  setStatus,
5765
5866
  canEdit
5766
5867
  });
5767
- if (props.collection.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
5768
- overrides: props.collection.components,
5868
+ return /* @__PURE__ */ jsx(CollectionScopeProvider, {
5869
+ collection: props.collection,
5769
5870
  children: content
5770
5871
  });
5771
- return content;
5772
5872
  }
5773
- function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved, onTabChange, navigateBack, entity, initialDirtyValues, dataLoading, layout = "side_panel", barActions, status, setStatus, formProps, canEdit }) {
5774
- const ResolvedFormActions = useComponentOverride("Entity.FormActions", EntityEditViewFormActions);
5873
+ function EditViewBindingInner({ path, entityId, selectedTab: selectedTabProp, collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved, onTabChange, navigateBack, entity, initialDirtyValues, dataLoading, layout = "side_panel", barActions, status, setStatus, formProps, canEdit }) {
5874
+ const ResolvedFormActions = useComponentOverride("EditView.FormActions", EditFormActions);
5775
5875
  const ResolvedEntityForm = useComponentOverride("Entity.Form", EntityFormBinding);
5776
- const ResolvedCollectionView = useComponentOverride("Collection.View", EntityCollectionView);
5876
+ const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
5777
5877
  const context = useRebaseContext();
5778
5878
  const urlController = useUrlController();
5779
5879
  const navigate = useNavigate();
@@ -5921,7 +6021,7 @@ function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, col
5921
6021
  const jsonView = activeTab === "__json" || jsonTabMounted ? /* @__PURE__ */ jsx("div", {
5922
6022
  className: cls("relative flex-1 h-full overflow-auto w-full", { "hidden": activeTab !== JSON_TAB_VALUE }),
5923
6023
  role: "tabpanel",
5924
- children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) })
6024
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(JsonPreviewBinding, { values: formContext?.values ?? entity?.values ?? {} }) })
5925
6025
  }, "json_view") : null;
5926
6026
  const historyView = includeHistoryView && activeTab === "__rebase_history" ? /* @__PURE__ */ jsx("div", {
5927
6027
  className: "relative flex-1 h-full overflow-auto w-full",
@@ -5998,7 +6098,7 @@ function EntityEditViewInner({ path, entityId, selectedTab: selectedTabProp, col
5998
6098
  modifiedValues: usedEntity?.values,
5999
6099
  formContext: readOnlyFormContext
6000
6100
  })
6001
- }) }) : /* @__PURE__ */ jsx(EntityView, {
6101
+ }) }) : /* @__PURE__ */ jsx(EntityViewBinding, {
6002
6102
  className: "px-8 h-full overflow-auto",
6003
6103
  entity,
6004
6104
  path,
@@ -6247,21 +6347,21 @@ function EntityFormSkeleton({ collection }) {
6247
6347
  });
6248
6348
  }
6249
6349
  //#endregion
6250
- //#region src/components/EntitySidePanel.tsx
6350
+ //#region src/components/SidePanelBinding.tsx
6251
6351
  /**
6252
6352
  * This is the component in charge of rendering the side dialog used
6253
- * for editing entities. Use the {@link useSideEntityController} to open
6353
+ * for editing entities. Use the {@link useSidePanel} to open
6254
6354
  * and control the dialogs.
6255
6355
  * This component needs a parent {@link Rebase}
6256
- * {@link useSideEntityController}
6356
+ * {@link useSidePanel}
6257
6357
  * @group Components
6258
6358
  */
6259
- function EntitySidePanel(props) {
6359
+ function SidePanelBinding(props) {
6260
6360
  const { allowFullScreen = true, path, entityId, selectedTab, formProps } = props;
6261
- const ResolvedDetailView = useComponentOverride("Entity.DetailView", EntityDetailView);
6361
+ const ResolvedDetailView = useComponentOverride("DetailView", DetailViewBinding);
6262
6362
  const { blocked, setBlocked, setBlockedNavigationMessage, close } = useSideDialogContext();
6263
6363
  const navigate = useNavigate();
6264
- const sideEntityController = useSideEntityController();
6364
+ const sidePanelController = useSidePanel();
6265
6365
  const collectionRegistryController = useCollectionRegistryController();
6266
6366
  const sideDialogsController = useSideDialogContext();
6267
6367
  const urlController = useUrlController();
@@ -6273,7 +6373,7 @@ function EntitySidePanel(props) {
6273
6373
  const onUpdate = (params) => {
6274
6374
  if (props.onUpdate) props.onUpdate(params);
6275
6375
  setShowEditInPanel(false);
6276
- if (params.status !== "existing") sideEntityController.replace({
6376
+ if (params.status !== "existing") sidePanelController.replace({
6277
6377
  path: params.path,
6278
6378
  entityId: params.entityId,
6279
6379
  selectedTab: params.selectedTab,
@@ -6311,7 +6411,7 @@ function EntitySidePanel(props) {
6311
6411
  });
6312
6412
  if (effectiveDefault && effectiveDefault !== "edit") {
6313
6413
  hasCorrectedDefaultView.current = true;
6314
- sideEntityController.replace({
6414
+ sidePanelController.replace({
6315
6415
  path,
6316
6416
  entityId,
6317
6417
  selectedTab: effectiveDefault,
@@ -6324,7 +6424,7 @@ function EntitySidePanel(props) {
6324
6424
  entityId,
6325
6425
  collection,
6326
6426
  path,
6327
- sideEntityController
6427
+ sidePanelController
6328
6428
  ]);
6329
6429
  const onValuesModified = useCallback((modified) => {
6330
6430
  setBlockedNavigationMessage(modified ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -6365,7 +6465,7 @@ function EntitySidePanel(props) {
6365
6465
  }),
6366
6466
  onTabChange: ({ entityId: tabEntityId, selectedTab, collection: paramCollection }) => {
6367
6467
  if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") return;
6368
- if (tabEntityId) sideEntityController.replace({
6468
+ if (tabEntityId) sidePanelController.replace({
6369
6469
  path,
6370
6470
  entityId: tabEntityId,
6371
6471
  selectedTab,
@@ -6373,7 +6473,7 @@ function EntitySidePanel(props) {
6373
6473
  collection: paramCollection ?? collection
6374
6474
  });
6375
6475
  }
6376
- }) : /* @__PURE__ */ jsx(EntityEditView, {
6476
+ }) : /* @__PURE__ */ jsx(EditViewBinding, {
6377
6477
  ...props,
6378
6478
  layout: collection?.openEntityMode === "dialog" ? "dialog" : "side_panel",
6379
6479
  collection,
@@ -6404,7 +6504,7 @@ function EntitySidePanel(props) {
6404
6504
  }),
6405
6505
  onTabChange: ({ entityId: tabEntityId, selectedTab, collection: paramCollection }) => {
6406
6506
  if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") return;
6407
- if (tabEntityId) sideEntityController.replace({
6507
+ if (tabEntityId) sidePanelController.replace({
6408
6508
  path,
6409
6509
  entityId: tabEntityId,
6410
6510
  selectedTab,
@@ -6416,22 +6516,22 @@ function EntitySidePanel(props) {
6416
6516
  }) }) });
6417
6517
  }
6418
6518
  //#endregion
6419
- //#region src/hooks/useBuildSideEntityController.tsx
6519
+ //#region src/hooks/useBuildSidePanel.tsx
6420
6520
  /**
6421
6521
  * Thin wrapper that resolves the Entity.SidePanel component override.
6422
6522
  * Because the JSX is created inside `propsToSidePanel` (a plain function,
6423
6523
  * not a React component), we need this wrapper so the hook is called at the
6424
6524
  * top level of a React component per the Rules of Hooks.
6425
6525
  */
6426
- function ResolvedEntitySidePanelInner(props) {
6427
- return /* @__PURE__ */ jsx(useComponentOverride("Entity.SidePanel", EntitySidePanel), { ...props });
6526
+ function ResolvedSidePanelBindingInner(props) {
6527
+ return /* @__PURE__ */ jsx(useComponentOverride("Entity.SidePanel", SidePanelBinding), { ...props });
6428
6528
  }
6429
- function ResolvedEntitySidePanel(props) {
6430
- if (props.collection?.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
6431
- overrides: props.collection.components,
6432
- children: /* @__PURE__ */ jsx(ResolvedEntitySidePanelInner, { ...props })
6529
+ function ResolvedSidePanelBinding(props) {
6530
+ if (props.collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
6531
+ collection: props.collection,
6532
+ children: /* @__PURE__ */ jsx(ResolvedSidePanelBindingInner, { ...props })
6433
6533
  });
6434
- return /* @__PURE__ */ jsx(ResolvedEntitySidePanelInner, { ...props });
6534
+ return /* @__PURE__ */ jsx(ResolvedSidePanelBindingInner, { ...props });
6435
6535
  }
6436
6536
  var NEW_URL_HASH = "new_side";
6437
6537
  var SIDE_URL_HASH = "side";
@@ -6469,7 +6569,7 @@ function getNestedPropertiesDepth(property, accumulator = 0) {
6469
6569
  else return getNestedPropertiesDepth(property.of, accumulator + 1);
6470
6570
  else return accumulator + 1;
6471
6571
  }
6472
- var useBuildSideEntityController = (collectionRegistryController, urlController, navigationStateController, sideDialogsController, authController) => {
6572
+ var useBuildSidePanel = (collectionRegistryController, urlController, navigationStateController, sideDialogsController, authController) => {
6473
6573
  const location = useLocation();
6474
6574
  const initialised = useRef(false);
6475
6575
  const currentPanelKeysRef = useRef([]);
@@ -6522,7 +6622,7 @@ var useBuildSideEntityController = (collectionRegistryController, urlController,
6522
6622
  sideDialogsController.close();
6523
6623
  }, [sideDialogsController]);
6524
6624
  const open = useCallback((props) => {
6525
- if (props.copy && !props.entityId) throw Error("If you want to copy an entity you need to provide an entityId");
6625
+ if (props.copy && !props.entityId) throw Error("If you want to copy a entity you need to provide a entityId");
6526
6626
  const defaultSelectedView = resolveDefaultSelectedView(props.collection ? props.collection.defaultSelectedView : void 0, {
6527
6627
  status: props.copy ? "copy" : props.entityId ? "existing" : "new",
6528
6628
  entityId: props.entityId
@@ -6540,7 +6640,7 @@ var useBuildSideEntityController = (collectionRegistryController, urlController,
6540
6640
  location.search
6541
6641
  ]);
6542
6642
  const replace = useCallback((props) => {
6543
- if (props.copy && !props.entityId) throw Error("If you want to copy an entity you need to provide an entityId");
6643
+ if (props.copy && !props.entityId) throw Error("If you want to copy a entity you need to provide a entityId");
6544
6644
  sideDialogsController.replace(propsToSidePanel(props, urlController.buildUrlCollectionPath, urlController.resolveDatabasePathsFrom, smallLayout, customizationController, authController, location.search));
6545
6645
  }, [
6546
6646
  urlController.buildUrlCollectionPath,
@@ -6616,7 +6716,7 @@ var propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayo
6616
6716
  const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
6617
6717
  return {
6618
6718
  key: `${props.path}/${props.entityId}`,
6619
- component: /* @__PURE__ */ jsx(ResolvedEntitySidePanel, { ...resolvedPanelProps }),
6719
+ component: /* @__PURE__ */ jsx(ResolvedSidePanelBinding, { ...resolvedPanelProps }),
6620
6720
  urlPath,
6621
6721
  parentUrlPath,
6622
6722
  width: entityViewWidth,
@@ -6689,21 +6789,21 @@ function useUrlController() {
6689
6789
  */
6690
6790
  function useCMSContext() {
6691
6791
  const baseContext = useRebaseContext();
6692
- const sideEntityController = useSideEntityController();
6792
+ const sidePanelController = useSidePanel();
6693
6793
  const sideDialogsController = useSideDialogsController();
6694
6794
  const urlController = useUrlController();
6695
6795
  const navigationStateController = useNavigationStateController();
6696
6796
  const collectionRegistryController = useCollectionRegistryController();
6697
6797
  return useMemo(() => ({
6698
6798
  ...baseContext,
6699
- sideEntityController,
6799
+ sidePanelController,
6700
6800
  sideDialogsController,
6701
6801
  urlController,
6702
6802
  navigationStateController,
6703
6803
  collectionRegistryController
6704
6804
  }), [
6705
6805
  baseContext,
6706
- sideEntityController,
6806
+ sidePanelController,
6707
6807
  sideDialogsController,
6708
6808
  urlController,
6709
6809
  navigationStateController,
@@ -6734,8 +6834,13 @@ function resolveNavigationFrom({ path, context }) {
6734
6834
  if (entry.type === "collection") return Promise.resolve(entry);
6735
6835
  else if (entry.type === "entity") {
6736
6836
  if (!collectionRegistryController.getCollection(entry.slug)) throw Error(`No collection defined in the navigation for the entity with path ${entry.slug}`);
6737
- return data.collection(entry.slug).findById(entry.entityId).then((entity) => {
6738
- if (!entity) return void 0;
6837
+ return data.collection(entry.slug).findById(entry.entityId).then((row) => {
6838
+ if (!row) return void 0;
6839
+ const entity = {
6840
+ id: entry.entityId,
6841
+ path: entry.slug,
6842
+ values: row
6843
+ };
6739
6844
  return {
6740
6845
  ...entry,
6741
6846
  entity
@@ -6783,12 +6888,12 @@ function useResolvedNavigationFrom({ path }) {
6783
6888
  ]);
6784
6889
  }
6785
6890
  //#endregion
6786
- //#region src/hooks/useEntityHistory.ts
6891
+ //#region src/hooks/useHistory.ts
6787
6892
  /**
6788
6893
  * Hook to fetch entity history from the backend REST API.
6789
6894
  * Replaces the old subcollection-based approach with a proper API call.
6790
6895
  */
6791
- function useEntityHistory(params) {
6896
+ function useHistory(params) {
6792
6897
  const { slug, entityId, enabled = true, pageSize = 10 } = params;
6793
6898
  const apiConfig = useApiConfig();
6794
6899
  const [entries, setEntries] = useState([]);
@@ -7123,7 +7228,7 @@ function DeleteEntityDialog({ entityOrEntitiesToDelete, collection, onClose, ope
7123
7228
  if (entityOrEntities && multipleEntities) content = /* @__PURE__ */ jsx(Fragment, { children: t("multiple_entities") });
7124
7229
  else {
7125
7230
  const entity = entityOrEntities;
7126
- content = entity ? /* @__PURE__ */ jsx(EntityView, {
7231
+ content = entity ? /* @__PURE__ */ jsx(EntityViewBinding, {
7127
7232
  entity,
7128
7233
  collection,
7129
7234
  path
@@ -7171,7 +7276,7 @@ function DeleteEntityDialog({ entityOrEntitiesToDelete, collection, onClose, ope
7171
7276
  });
7172
7277
  }
7173
7278
  //#endregion
7174
- //#region src/components/EntityCollectionView/utils.ts
7279
+ //#region src/components/CollectionViewBinding/utils.ts
7175
7280
  function addRecentId(collectionId, id) {
7176
7281
  const newRecentIds = [id, ...getRecentIds(collectionId).filter((i) => i !== id)];
7177
7282
  if (newRecentIds.length > 5) newRecentIds.pop();
@@ -7189,11 +7294,11 @@ function getRecentIds(collectionId) {
7189
7294
  //#endregion
7190
7295
  //#region src/util/navigation_utils.ts
7191
7296
  /**
7192
- * Navigate to an entity using either a side panel or full-screen mode.
7297
+ * Navigate to a entity using either a side panel or full-screen mode.
7193
7298
  * This is an admin-specific UI concern and lives here (not in common).
7194
7299
  */
7195
- function navigateToEntity({ openEntityMode, collection, entityId, copy, path, selectedTab, defaultValues, sideEntityController, onClose, navigation, replace }) {
7196
- if (openEntityMode === "side_panel" || openEntityMode === "dialog") sideEntityController.open({
7300
+ function navigateToEntity({ openEntityMode, collection, entityId, copy, path, selectedTab, defaultValues, sidePanelController, onClose, navigation, replace }) {
7301
+ if (openEntityMode === "side_panel" || openEntityMode === "dialog") sidePanelController.open({
7197
7302
  entityId,
7198
7303
  path,
7199
7304
  copy,
@@ -7288,7 +7393,7 @@ function CreationResultDialog({ result, onClose }) {
7288
7393
  color: "warning",
7289
7394
  children: /* @__PURE__ */ jsx(Typography, {
7290
7395
  variant: "body2",
7291
- children: t("temporary_password_description") ?? "Email is not configured. Share this temporary password with the user securely. It will not be shown again."
7396
+ children: result.emailDeliveryFailed ? t("temporary_password_email_failed_description") ?? "The email could not be delivered. Share this temporary password with the user securely. It will not be shown again." : t("temporary_password_description") ?? "Email is not configured. Share this temporary password with the user securely. It will not be shown again."
7292
7397
  })
7293
7398
  }),
7294
7399
  /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
@@ -7335,9 +7440,9 @@ var editEntityAction = {
7335
7440
  name: "Edit",
7336
7441
  collapsed: false,
7337
7442
  isEnabled: ({ entity }) => Boolean(entity),
7338
- onClick({ entity, collection, path, context, sideEntityController, highlightEntity, unhighlightEntity, openEntityMode }) {
7443
+ onClick({ entity, collection, path, context, sidePanelController, highlightEntity, unhighlightEntity, openEntityMode }) {
7339
7444
  if (!entity) throw new Error("INTERNAL: editEntityAction: Entity is undefined");
7340
- if (!sideEntityController) throw new Error("INTERNAL: editEntityAction: sideEntityController is undefined");
7445
+ if (!sidePanelController) throw new Error("INTERNAL: editEntityAction: sidePanelController is undefined");
7341
7446
  highlightEntity?.(entity);
7342
7447
  context?.analyticsController?.onAnalyticsEvent?.("entity_click", {
7343
7448
  path: entity.path,
@@ -7355,7 +7460,7 @@ var editEntityAction = {
7355
7460
  collection,
7356
7461
  entityId: entity.id,
7357
7462
  path: newFullIdPath,
7358
- sideEntityController,
7463
+ sidePanelController,
7359
7464
  onClose: () => unhighlightEntity?.(entity),
7360
7465
  navigation: context.urlController,
7361
7466
  selectedTab: defaultSelectedView
@@ -7368,9 +7473,9 @@ var copyEntityAction = {
7368
7473
  name: "Copy",
7369
7474
  key: "copy",
7370
7475
  isEnabled: ({ entity }) => Boolean(entity),
7371
- onClick({ entity, collection, context, path, sideEntityController, highlightEntity, unhighlightEntity, openEntityMode }) {
7476
+ onClick({ entity, collection, context, path, sidePanelController, highlightEntity, unhighlightEntity, openEntityMode }) {
7372
7477
  if (!entity) throw new Error("INTERNAL: copyEntityAction: Entity is undefined");
7373
- if (!sideEntityController) throw new Error("INTERNAL: copyEntityAction: sideEntityController is undefined");
7478
+ if (!sidePanelController) throw new Error("INTERNAL: copyEntityAction: sidePanelController is undefined");
7374
7479
  highlightEntity?.(entity);
7375
7480
  context?.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
7376
7481
  path: entity.path,
@@ -7384,7 +7489,7 @@ var copyEntityAction = {
7384
7489
  entityId: entity.id,
7385
7490
  path: usedPath,
7386
7491
  copy: true,
7387
- sideEntityController,
7492
+ sidePanelController,
7388
7493
  onClose: () => unhighlightEntity?.(entity),
7389
7494
  navigation: context.urlController
7390
7495
  });
@@ -7432,8 +7537,19 @@ function ResetPasswordActionDialog({ user, open, onClose }) {
7432
7537
  const { t } = useTranslation();
7433
7538
  const [loading, setLoading] = useState(false);
7434
7539
  const [creationResult, setCreationResult] = useState(null);
7540
+ const [mode, setMode] = useState("email");
7541
+ const [password, setPassword] = useState("");
7542
+ const [confirmPassword, setConfirmPassword] = useState("");
7543
+ const [error, setError] = useState(null);
7544
+ const passwordsMatch = password === confirmPassword;
7545
+ const canSubmit = mode === "email" || password.length > 0 && passwordsMatch;
7435
7546
  const handleConfirm = async () => {
7547
+ if (mode === "manual" && !passwordsMatch) {
7548
+ setError(t("passwords_dont_match") || "Passwords don't match");
7549
+ return;
7550
+ }
7436
7551
  setLoading(true);
7552
+ setError(null);
7437
7553
  try {
7438
7554
  const baseUrl = client?.baseUrl || "";
7439
7555
  const token = await getAuthToken?.();
@@ -7442,28 +7558,27 @@ function ResetPasswordActionDialog({ user, open, onClose }) {
7442
7558
  headers: {
7443
7559
  "Content-Type": "application/json",
7444
7560
  ...token ? { "Authorization": `Bearer ${token}` } : {}
7445
- }
7561
+ },
7562
+ body: JSON.stringify(mode === "manual" ? { password } : {})
7446
7563
  });
7447
7564
  if (!response.ok) {
7448
- const error = await response.json().catch(() => ({}));
7449
- throw new Error(error.message || "Failed to reset password");
7565
+ const errorBody = await response.json().catch(() => ({}));
7566
+ throw new Error(errorBody.error?.message || errorBody.message || "Failed to reset password");
7450
7567
  }
7451
7568
  const data = await response.json();
7452
- setCreationResult({
7453
- user,
7454
- invitationSent: data.invitationSent ?? false,
7455
- temporaryPassword: data.temporaryPassword
7456
- });
7457
7569
  snackbarController.open({
7458
7570
  type: "success",
7459
7571
  message: t("reset_password_success") || "Password reset successfully"
7460
7572
  });
7461
- } catch (error) {
7462
- snackbarController.open({
7463
- type: "error",
7464
- message: error instanceof Error ? error.message : t("error_resetting_password") || "Error resetting password"
7573
+ if (data.invitationSent || data.temporaryPassword) setCreationResult({
7574
+ user,
7575
+ invitationSent: data.invitationSent ?? false,
7576
+ temporaryPassword: data.temporaryPassword,
7577
+ emailDeliveryFailed: data.emailDeliveryFailed ?? false
7465
7578
  });
7466
- onClose();
7579
+ else onClose();
7580
+ } catch (e) {
7581
+ setError(e instanceof Error ? e.message : t("error_resetting_password") || "Error resetting password");
7467
7582
  } finally {
7468
7583
  setLoading(false);
7469
7584
  }
@@ -7475,13 +7590,101 @@ function ResetPasswordActionDialog({ user, open, onClose }) {
7475
7590
  onClose();
7476
7591
  }
7477
7592
  });
7478
- return /* @__PURE__ */ jsx(ConfirmationDialog, {
7593
+ return /* @__PURE__ */ jsxs(Dialog, {
7479
7594
  open,
7480
- loading,
7481
- onAccept: handleConfirm,
7482
- onCancel: onClose,
7483
- title: /* @__PURE__ */ jsx(Fragment, { children: t("reset_password") || "Reset Password" }),
7484
- body: /* @__PURE__ */ jsx(Fragment, { children: t("reset_password_confirmation") || "Are you sure you want to reset this user's password?" })
7595
+ onOpenChange: (o) => !o ? onClose() : void 0,
7596
+ maxWidth: "xl",
7597
+ children: [
7598
+ /* @__PURE__ */ jsx(DialogTitle, {
7599
+ variant: "h5",
7600
+ gutterBottom: false,
7601
+ children: t("reset_password") || "Reset Password"
7602
+ }),
7603
+ /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsxs("div", {
7604
+ className: "flex flex-col gap-4 py-2",
7605
+ children: [
7606
+ /* @__PURE__ */ jsx(Typography, {
7607
+ variant: "body2",
7608
+ color: "secondary",
7609
+ children: user.email
7610
+ }),
7611
+ /* @__PURE__ */ jsxs(RadioGroup, {
7612
+ value: mode,
7613
+ onValueChange: (v) => {
7614
+ setMode(v);
7615
+ setError(null);
7616
+ },
7617
+ children: [/* @__PURE__ */ jsxs("div", {
7618
+ className: "flex items-center gap-2",
7619
+ children: [/* @__PURE__ */ jsx(RadioGroupItem, {
7620
+ value: "email",
7621
+ id: "reset-password-mode-email"
7622
+ }), /* @__PURE__ */ jsx(Label, {
7623
+ htmlFor: "reset-password-mode-email",
7624
+ children: t("reset_password_send_email") || "Send a password reset email"
7625
+ })]
7626
+ }), /* @__PURE__ */ jsxs("div", {
7627
+ className: "flex items-center gap-2",
7628
+ children: [/* @__PURE__ */ jsx(RadioGroupItem, {
7629
+ value: "manual",
7630
+ id: "reset-password-mode-manual"
7631
+ }), /* @__PURE__ */ jsx(Label, {
7632
+ htmlFor: "reset-password-mode-manual",
7633
+ children: t("reset_password_set_manually") || "Set a password manually"
7634
+ })]
7635
+ })]
7636
+ }),
7637
+ mode === "manual" && /* @__PURE__ */ jsxs(Fragment, { children: [
7638
+ /* @__PURE__ */ jsx(TextField, {
7639
+ type: "password",
7640
+ value: password,
7641
+ autoFocus: true,
7642
+ autoComplete: "new-password",
7643
+ label: t("new_password") || "New password",
7644
+ onChange: (e) => {
7645
+ setPassword(e.target.value);
7646
+ setError(null);
7647
+ }
7648
+ }),
7649
+ /* @__PURE__ */ jsx(TextField, {
7650
+ type: "password",
7651
+ value: confirmPassword,
7652
+ autoComplete: "new-password",
7653
+ error: confirmPassword.length > 0 && !passwordsMatch,
7654
+ label: t("confirm_password") || "Confirm password",
7655
+ onChange: (e) => {
7656
+ setConfirmPassword(e.target.value);
7657
+ setError(null);
7658
+ }
7659
+ }),
7660
+ /* @__PURE__ */ jsx(Typography, {
7661
+ variant: "caption",
7662
+ color: "secondary",
7663
+ children: t("reset_password_set_manually_description") || "The password is updated immediately and no email is sent. Share it with the user securely."
7664
+ })
7665
+ ] }),
7666
+ error && /* @__PURE__ */ jsx(Alert, {
7667
+ color: "error",
7668
+ children: /* @__PURE__ */ jsx(Typography, {
7669
+ variant: "body2",
7670
+ children: error
7671
+ })
7672
+ })
7673
+ ]
7674
+ }) }),
7675
+ /* @__PURE__ */ jsxs(DialogActions, { children: [/* @__PURE__ */ jsx(Button, {
7676
+ variant: "text",
7677
+ onClick: onClose,
7678
+ disabled: loading,
7679
+ children: t("cancel")
7680
+ }), /* @__PURE__ */ jsx(LoadingButton, {
7681
+ variant: "filled",
7682
+ onClick: handleConfirm,
7683
+ loading,
7684
+ disabled: !canSubmit,
7685
+ children: t("reset_password") || "Reset Password"
7686
+ })] })
7687
+ ]
7485
7688
  });
7486
7689
  }
7487
7690
  var resetPasswordAction = {
@@ -7547,13 +7750,17 @@ function applyPluginModifyCollection(resolvedCollections, modifyCollection) {
7547
7750
  * with `auth: true` or `auth: { enabled: true }`.
7548
7751
  *
7549
7752
  * Injections:
7550
- * 1. **resetPasswordAction** — adds the entity action unless explicitly disabled
7753
+ * 1. **resetPasswordAction** — adds the entity action unless explicitly disabled,
7754
+ * or unless the auth adapter reports no `adminPasswordReset` support. Custom
7755
+ * adapters mount their own admin routes and may not implement
7756
+ * `POST /admin/users/:userId/reset-password`; injecting the action anyway
7757
+ * would show a button that can only ever 404.
7551
7758
  * 2. **afterSave callback** — shows the `CreationResultDialog` when a new user
7552
7759
  * is created with `invitationSent` or `temporaryPassword` in the response
7553
7760
  *
7554
7761
  * Skips injection if the collection already has the action/callback present.
7555
7762
  */
7556
- function injectAuthCollectionConfig(collections) {
7763
+ function injectAuthCollectionConfig(collections, adminPasswordResetSupported) {
7557
7764
  return collections.map((collection) => {
7558
7765
  const authProp = collection.auth;
7559
7766
  if (!authProp) return collection;
@@ -7564,6 +7771,7 @@ function injectAuthCollectionConfig(collections) {
7564
7771
  let actionToInject;
7565
7772
  if (resetPref === false) actionToInject = void 0;
7566
7773
  else if (typeof resetPref === "object") actionToInject = resetPref;
7774
+ else if (!adminPasswordResetSupported) actionToInject = void 0;
7567
7775
  else actionToInject = resetPasswordAction;
7568
7776
  if (actionToInject) {
7569
7777
  const injectedAction = actionToInject;
@@ -7586,7 +7794,7 @@ function injectAuthCollectionConfig(collections) {
7586
7794
  const { dialogsController } = context;
7587
7795
  const creationResult = {
7588
7796
  user: {
7589
- uid: String(props.entityId),
7797
+ uid: String(props.id),
7590
7798
  email: typeof values.email === "string" ? values.email : "",
7591
7799
  displayName: typeof values.displayName === "string" ? values.displayName : "",
7592
7800
  roles: Array.isArray(values.roles) ? values.roles : [],
@@ -7595,7 +7803,8 @@ function injectAuthCollectionConfig(collections) {
7595
7803
  isAnonymous: false
7596
7804
  },
7597
7805
  invitationSent: !!values.invitationSent,
7598
- temporaryPassword: typeof values.temporaryPassword === "string" ? values.temporaryPassword : void 0
7806
+ temporaryPassword: typeof values.temporaryPassword === "string" ? values.temporaryPassword : void 0,
7807
+ emailDeliveryFailed: !!values.emailDeliveryFailed
7599
7808
  };
7600
7809
  const { closeDialog } = dialogsController.open({
7601
7810
  key: "user_creation_result",
@@ -7622,7 +7831,7 @@ async function resolveCollections(collections, authController, data, plugins) {
7622
7831
  if (plugin.hooks?.modifyCollection) resolvedCollections = applyPluginModifyCollection(resolvedCollections, plugin.hooks.modifyCollection);
7623
7832
  if (plugin.hooks?.injectCollections) resolvedCollections = plugin.hooks.injectCollections(resolvedCollections);
7624
7833
  }
7625
- resolvedCollections = injectAuthCollectionConfig(resolvedCollections);
7834
+ resolvedCollections = injectAuthCollectionConfig(resolvedCollections, authController.capabilities?.adminPasswordReset ?? true);
7626
7835
  resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
7627
7836
  return resolvedCollections;
7628
7837
  }
@@ -7831,7 +8040,7 @@ function useAsyncResolver({ resolver, initialValue, isEqual, deps, disabled }) {
7831
8040
  //#region src/hooks/navigation/useResolvedCollections.ts
7832
8041
  /**
7833
8042
  * Hook that resolves collection props (which may be async builders or arrays)
7834
- * into concrete EntityCollection[], and registers them with the CollectionRegistry.
8043
+ * into concrete CollectionConfig[], and registers them with the CollectionRegistry.
7835
8044
  *
7836
8045
  * When userManagement is provided, the default users collection is always
7837
8046
  * prepended. Developer collections override via generic slug-based dedup
@@ -8314,7 +8523,7 @@ var SideDialogContext = React.createContext({
8314
8523
  var useSideDialogContext = () => useContext(SideDialogContext);
8315
8524
  /**
8316
8525
  * This is the component in charge of rendering the side dialogs used
8317
- * for editing entities. Use the {@link useSideEntityController} to open
8526
+ * for editing entities. Use the {@link useSidePanel} to open
8318
8527
  * and control the dialogs.
8319
8528
  * This component needs a parent {@link Rebase}
8320
8529
  * {@link useSideDialogsController}
@@ -8432,22 +8641,22 @@ function SideDialogView({ offsetPosition, panel, panelIndex, isTopPanel }) {
8432
8641
  });
8433
8642
  }
8434
8643
  //#endregion
8435
- //#region src/components/ReferenceTable/EntitySelectionTable.tsx
8644
+ //#region src/components/ReferenceTable/SelectionTableBinding.tsx
8436
8645
  /**
8437
8646
  * This component allows to select entities from a given collection.
8438
- * You probably want to open this dialog as a side view using {@link useEntitySelectionTable}
8647
+ * You probably want to open this dialog as a side view using {@link useSelectionTableBinding}
8439
8648
  * @group Components
8440
8649
  */
8441
- function EntitySelectionTable(props) {
8650
+ function SelectionTableBinding(props) {
8442
8651
  if (!props.collection) return /* @__PURE__ */ jsx(ErrorView, { error: "Could not find collection" });
8443
- return /* @__PURE__ */ jsx(EntitySelectionTableInternal, {
8652
+ return /* @__PURE__ */ jsx(SelectionTableBindingInternal, {
8444
8653
  ...props,
8445
8654
  collection: props.collection
8446
8655
  });
8447
8656
  }
8448
- function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntitiesSelected, multiselect, collection, path: pathInput, selectedEntityIds: selectedEntityIdsProp, description, fixedFilter, maxSelection }) {
8657
+ function SelectionTableBindingInternal({ onSingleEntitySelected, onMultipleEntitiesSelected, multiselect, collection, path: pathInput, selectedEntityIds: selectedEntityIdsProp, description, fixedFilter, maxSelection }) {
8449
8658
  const sideDialogContext = useSideDialogContext();
8450
- const sideEntityController = useSideEntityController();
8659
+ const sidePanelController = useSidePanel();
8451
8660
  const urlController = useUrlController();
8452
8661
  const analyticsController = useAnalyticsController();
8453
8662
  const path = urlController.resolveDatabasePathsFrom(pathInput);
@@ -8524,7 +8733,7 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
8524
8733
  ]);
8525
8734
  const onNewClick = () => {
8526
8735
  analyticsController.onAnalyticsEvent?.("reference_selection_new_entity", { path });
8527
- sideEntityController.open({
8736
+ sidePanelController.open({
8528
8737
  path,
8529
8738
  collection,
8530
8739
  updateUrl: true,
@@ -8537,7 +8746,7 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
8537
8746
  };
8538
8747
  const tableRowActionsBuilder = ({ entity, size, width, frozen }) => {
8539
8748
  const selectedEntities = selectionController.selectedEntities;
8540
- return /* @__PURE__ */ jsx(EntityCollectionRowActions, {
8749
+ return /* @__PURE__ */ jsx(CollectionRowActions, {
8541
8750
  width,
8542
8751
  frozen,
8543
8752
  entity,
@@ -8562,51 +8771,54 @@ function EntitySelectionTableInternal({ onSingleEntitySelected, onMultipleEntiti
8562
8771
  fixedFilter,
8563
8772
  updateUrl: false
8564
8773
  });
8565
- return /* @__PURE__ */ jsxs("div", {
8566
- className: "flex flex-col h-full",
8567
- children: [/* @__PURE__ */ jsx("div", {
8568
- className: "grow",
8569
- children: entitiesDisplayedFirst && /* @__PURE__ */ jsx(EntityCollectionTable, {
8570
- additionalFields: collection.additionalFields,
8571
- displayedColumnIds,
8572
- onEntityClick,
8573
- tableController,
8574
- enablePopupIcon: false,
8575
- tableRowActionsBuilder,
8576
- openEntityMode: "side_panel",
8577
- title: /* @__PURE__ */ jsxs(Typography, {
8578
- variant: "subtitle2",
8579
- className: "flex flex-row gap-2",
8580
- children: [/* @__PURE__ */ jsx(IconForView, {
8581
- size: "small",
8582
- collectionOrView: collection,
8583
- className: "text-surface-300 dark:text-surface-600"
8584
- }), collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`]
8585
- }),
8586
- defaultSize: collection.defaultSize,
8587
- properties: collection.properties,
8588
- fixedFilter,
8589
- inlineEditing: false,
8590
- selectionController,
8591
- actions: /* @__PURE__ */ jsx(EntitySelectionDialogActions, {
8592
- collection,
8593
- path,
8594
- onNewClick,
8595
- onClear
8774
+ return /* @__PURE__ */ jsx(CollectionScopeProvider, {
8775
+ collection,
8776
+ children: /* @__PURE__ */ jsxs("div", {
8777
+ className: "flex flex-col h-full",
8778
+ children: [/* @__PURE__ */ jsx("div", {
8779
+ className: "grow",
8780
+ children: entitiesDisplayedFirst && /* @__PURE__ */ jsx(CollectionTableBinding, {
8781
+ additionalFields: collection.additionalFields,
8782
+ displayedColumnIds,
8783
+ onEntityClick,
8784
+ tableController,
8785
+ enablePopupIcon: false,
8786
+ tableRowActionsBuilder,
8787
+ openEntityMode: "side_panel",
8788
+ title: /* @__PURE__ */ jsxs(Typography, {
8789
+ variant: "subtitle2",
8790
+ className: "flex flex-row gap-2",
8791
+ children: [/* @__PURE__ */ jsx(IconForView, {
8792
+ size: "small",
8793
+ collectionOrView: collection,
8794
+ className: "text-surface-300 dark:text-surface-600"
8795
+ }), collection.singularName ? `Select ${collection.singularName}` : `Select from ${collection.name}`]
8796
+ }),
8797
+ defaultSize: collection.defaultSize,
8798
+ properties: collection.properties,
8799
+ fixedFilter,
8800
+ inlineEditing: false,
8801
+ selectionController,
8802
+ actions: /* @__PURE__ */ jsx(EntitySelectionDialogActions, {
8803
+ collection,
8804
+ path,
8805
+ onNewClick,
8806
+ onClear
8807
+ })
8596
8808
  })
8597
- })
8598
- }), /* @__PURE__ */ jsxs(DialogActions, {
8599
- translucent: false,
8600
- children: [description && /* @__PURE__ */ jsx(Typography, {
8601
- variant: "body2",
8602
- className: "grow text-left",
8603
- children: description
8604
- }), /* @__PURE__ */ jsx(Button, {
8605
- onClick: onDone,
8606
- variant: "filled",
8607
- children: "Done"
8809
+ }), /* @__PURE__ */ jsxs(DialogActions, {
8810
+ translucent: false,
8811
+ children: [description && /* @__PURE__ */ jsx(Typography, {
8812
+ variant: "body2",
8813
+ className: "grow text-left",
8814
+ children: description
8815
+ }), /* @__PURE__ */ jsx(Button, {
8816
+ onClick: onDone,
8817
+ variant: "filled",
8818
+ children: "Done"
8819
+ })]
8608
8820
  })]
8609
- })]
8821
+ })
8610
8822
  });
8611
8823
  }
8612
8824
  function EntitySelectionDialogActions({ collection, path, onClear, onNewClick }) {
@@ -8631,7 +8843,7 @@ function EntitySelectionDialogActions({ collection, path, onClear, onNewClick })
8631
8843
  }), addButton] });
8632
8844
  }
8633
8845
  //#endregion
8634
- //#region src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts
8846
+ //#region src/components/CollectionViewBinding/hooks/useCollectionInlineEditor.ts
8635
8847
  function useCollectionInlineEditor({ path, collection, dataClient, context }) {
8636
8848
  const uniqueFieldValidator = useCallback(async ({ name, value, property, entityId }) => {
8637
8849
  const conflictingEntities = (await dataClient.collection(path).find({ where: { [name]: ["==", value] } })).data;
@@ -8922,7 +9134,7 @@ function ReadOnlyFieldBinding({ propertyKey, value, error, showError, minimalist
8922
9134
  *
8923
9135
  * Please note that if you build a custom field in a component, the
8924
9136
  * **validation** passed in the property will have no effect. You need to set
8925
- * the validation in the `EntityCollection` definition.
9137
+ * the validation in the `CollectionConfig` definition.
8926
9138
  *
8927
9139
  * @param propertyKey You can use nested names such as `address.street` or `friends[2]`
8928
9140
  * @param property
@@ -9505,7 +9717,7 @@ function ArrayOfReferencesFieldBinding({ propertyKey, value, error, showError, d
9505
9717
  const onMultipleEntitiesSelected = useCallback((entities) => {
9506
9718
  setValue(entities.map((e) => getReferenceFrom(e)));
9507
9719
  }, [setValue]);
9508
- const referenceDialogController = useEntitySelectionDialog({
9720
+ const referenceDialogController = useSelectionDialog({
9509
9721
  multiselect: true,
9510
9722
  path: ofProperty.path,
9511
9723
  collection,
@@ -9854,13 +10066,13 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
9854
10066
  });
9855
10067
  setInternalState(newRowIds);
9856
10068
  }, [value]);
9857
- const updatetype = (rowId, type) => {
9858
- if (!rowId) {
10069
+ const updatetype = (id, type) => {
10070
+ if (!id) {
9859
10071
  console.warn("No key selected for data type update");
9860
10072
  return;
9861
10073
  }
9862
10074
  setInternalState(internalState.map((row) => {
9863
- if (row[0] === rowId) return [row[0], {
10075
+ if (row[0] === id) return [row[0], {
9864
10076
  key: row[1].key,
9865
10077
  type
9866
10078
  }];
@@ -9868,20 +10080,20 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
9868
10080
  }));
9869
10081
  setValue({
9870
10082
  ...value ?? {},
9871
- [internalState.find((row) => row[0] === rowId)?.[1].key ?? ""]: getDefaultValueFortype(type)
10083
+ [internalState.find((row) => row[0] === id)?.[1].key ?? ""]: getDefaultValueFortype(type)
9872
10084
  });
9873
10085
  };
9874
10086
  return /* @__PURE__ */ jsxs("div", {
9875
10087
  className: "py-1 flex flex-col gap-1",
9876
- children: [internalState.map(([rowId, { key: fieldKey, type }], index) => {
10088
+ children: [internalState.map(([id, { key: fieldKey, type }], index) => {
9877
10089
  const entryValue = fieldKey ? value?.[fieldKey] : "";
9878
10090
  const onFieldKeyChange = (newKey) => {
9879
- setInternalState(internalState.map((currentRowId) => {
9880
- if (currentRowId[0] === rowId) return [rowId, {
10091
+ setInternalState(internalState.map((currentId) => {
10092
+ if (currentId[0] === id) return [id, {
9881
10093
  key: newKey ?? "",
9882
- type: currentRowId[1].type
10094
+ type: currentId[1].type
9883
10095
  }];
9884
- return currentRowId;
10096
+ return currentId;
9885
10097
  }));
9886
10098
  if (typeof value === "object" && newKey in value) return;
9887
10099
  const newValue = { ...value ?? {} };
@@ -9893,14 +10105,14 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
9893
10105
  });
9894
10106
  };
9895
10107
  return /* @__PURE__ */ jsx(MapKeyValueRow, {
9896
- rowId,
10108
+ id,
9897
10109
  fieldKey,
9898
10110
  value: value ?? {},
9899
10111
  onDeleteClick: () => {
9900
10112
  const newValue = { ...value ?? {} };
9901
10113
  if (initialValue && fieldKey in initialValue) newValue[fieldKey] = void 0;
9902
10114
  else delete newValue[fieldKey];
9903
- setInternalState(internalState.filter((currentRowId) => currentRowId[0] !== rowId));
10115
+ setInternalState(internalState.filter((currentId) => currentId[0] !== id));
9904
10116
  setValue({ ...newValue });
9905
10117
  },
9906
10118
  onFieldKeyChange,
@@ -9909,7 +10121,7 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
9909
10121
  type,
9910
10122
  disabled,
9911
10123
  updatetype
9912
- }, rowId);
10124
+ }, id);
9913
10125
  }), /* @__PURE__ */ jsx(Button, {
9914
10126
  variant: "text",
9915
10127
  size: "small",
@@ -9931,7 +10143,7 @@ function MapEditView({ value, initialValue, setValue, fieldName, disabled }) {
9931
10143
  })]
9932
10144
  });
9933
10145
  }
9934
- function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClick, setValue, entryValue, type, updatetype, disabled }) {
10146
+ function MapKeyValueRow({ id, fieldKey, value, onFieldKeyChange, onDeleteClick, setValue, entryValue, type, updatetype, disabled }) {
9935
10147
  const { locale } = useCustomizationController();
9936
10148
  const { t } = useTranslation();
9937
10149
  function buildInput(entryValue, fieldKey, type) {
@@ -9993,7 +10205,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
9993
10205
  children: /* @__PURE__ */ jsx(ArrayContainer, {
9994
10206
  value: arrayValue,
9995
10207
  newDefaultEntry: "",
9996
- droppableId: rowId.toString(),
10208
+ droppableId: id.toString(),
9997
10209
  addLabel: fieldKey ? t("add_to_field", { fieldName: fieldKey }) : t("add"),
9998
10210
  size: "small",
9999
10211
  disabled: disabled || !fieldKey,
@@ -10041,7 +10253,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
10041
10253
  });
10042
10254
  }
10043
10255
  function doUpdatetype(type) {
10044
- updatetype(rowId, type);
10256
+ updatetype(id, type);
10045
10257
  }
10046
10258
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Typography, {
10047
10259
  component: "div",
@@ -10110,7 +10322,7 @@ function MapKeyValueRow({ rowId, fieldKey, value, onFieldKeyChange, onDeleteClic
10110
10322
  })]
10111
10323
  })
10112
10324
  ]
10113
- }, rowId.toString()), (type === "map" || type === "array") && buildInput(entryValue, fieldKey, type)] });
10325
+ }, id.toString()), (type === "map" || type === "array") && buildInput(entryValue, fieldKey, type)] });
10114
10326
  }
10115
10327
  function ArrayKeyValueRow({ id, index, value, setValue }) {
10116
10328
  const { locale } = useCustomizationController();
@@ -10582,7 +10794,7 @@ function ReferenceFieldBindingInternal({ propertyKey, value, setValue, error, sh
10582
10794
  const onSingleEntitySelected = useCallback((e) => {
10583
10795
  setValue(e ? getReferenceFrom(e) : null);
10584
10796
  }, [setValue, propertyKey]);
10585
- const referenceDialogController = useEntitySelectionDialog({
10797
+ const referenceDialogController = useSelectionDialog({
10586
10798
  multiselect: false,
10587
10799
  path: property.path,
10588
10800
  collection,
@@ -11402,7 +11614,7 @@ function MultipleRelationFieldBinding({ propertyKey, value: valueProp, error, sh
11402
11614
  const onMultipleEntitiesSelected = useCallback((entities) => {
11403
11615
  setValue(entities.map((e) => getRelationFrom(e)));
11404
11616
  }, [setValue]);
11405
- const referenceDialogController = useEntitySelectionDialog({
11617
+ const referenceDialogController = useSelectionDialog({
11406
11618
  multiselect: true,
11407
11619
  path: getCollectionDataPath(collection),
11408
11620
  collection,
@@ -11548,7 +11760,7 @@ function SingleRelationFieldBinding({ propertyKey, value, size, error, showError
11548
11760
  const onSingleEntitySelected = useCallback((e) => {
11549
11761
  setValue(e ? getRelationFrom(e) : null);
11550
11762
  }, [setValue]);
11551
- const referenceDialogController = useEntitySelectionDialog({
11763
+ const referenceDialogController = useSelectionDialog({
11552
11764
  multiselect: false,
11553
11765
  path: getCollectionDataPath(collection),
11554
11766
  collection,
@@ -11749,7 +11961,7 @@ var DEFAULT_FIELD_CONFIGS = {
11749
11961
  },
11750
11962
  user_select: {
11751
11963
  key: "user_select",
11752
- name: "UserIcon select",
11964
+ name: "User select",
11753
11965
  description: "Select a user from the user management system. Store the user ID.",
11754
11966
  Icon: UserIcon,
11755
11967
  property: {
@@ -12877,10 +13089,10 @@ function EditorCollectionAction({ path, parentCollectionSlugs, parentEntityIds,
12877
13089
  }) });
12878
13090
  }
12879
13091
  //#endregion
12880
- //#region src/components/EntityCollectionView/EntityCollectionViewActions.tsx
13092
+ //#region src/components/CollectionViewBinding/CollectionViewActions.tsx
12881
13093
  var ImportCollectionAction$1 = lazy(() => Promise.resolve().then(() => import_exports).then((m) => ({ default: m.ImportCollectionAction })));
12882
13094
  var ExportCollectionAction$1 = lazy(() => Promise.resolve().then(() => export_exports).then((m) => ({ default: m.ExportCollectionAction })));
12883
- function EntityCollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
13095
+ function CollectionViewActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, onNewClick, onMultipleDeleteClick, selectionEnabled, path, selectionController, tableController, collectionEntitiesCount, compact, children, openNewDocument }) {
12884
13096
  const context = useCMSContext();
12885
13097
  const { canCreate, canDelete } = usePermissions();
12886
13098
  const largeLayout = useLargeLayout();
@@ -12985,7 +13197,7 @@ function EntityCollectionViewActions({ collection, relativePath, parentCollectio
12985
13197
  });
12986
13198
  }
12987
13199
  //#endregion
12988
- //#region src/components/EntityCollectionView/useEntityPreviewSlots.ts
13200
+ //#region src/components/CollectionViewBinding/usePreviewSlots.ts
12989
13201
  /**
12990
13202
  * Resolve which property key fills each slot for a given collection.
12991
13203
  * Pure function — call inside `useMemo`.
@@ -13280,12 +13492,12 @@ function resolveRelationDisplayName(relation, prop) {
13280
13492
  return id !== void 0 ? String(id) : void 0;
13281
13493
  }
13282
13494
  //#endregion
13283
- //#region src/components/EntityCollectionView/EntityCard.tsx
13495
+ //#region src/components/CollectionViewBinding/EntityCardBinding.tsx
13284
13496
  /**
13285
- * Card component for displaying an entity in a grid view.
13497
+ * Card component for displaying a entity in a grid view.
13286
13498
  * Shows thumbnail, title, and preview properties via the shared slot system.
13287
13499
  */
13288
- function EntityCard({ entity, collection, onClick, selected, highlighted, onSelectionChange, selectionEnabled, size = "m" }) {
13500
+ function EntityCardBinding({ entity, collection, onClick, selected, highlighted, onSelectionChange, selectionEnabled, size = "m" }) {
13289
13501
  const authController = useAuthController();
13290
13502
  const analyticsController = useAnalyticsController();
13291
13503
  const slotKeys = useCollectionSlotKeys(collection, authController, useCustomizationController().propertyConfigs);
@@ -13404,13 +13616,13 @@ function EntityCard({ entity, collection, onClick, selected, highlighted, onSele
13404
13616
  });
13405
13617
  }
13406
13618
  //#endregion
13407
- //#region src/components/EntityCollectionView/EntityCollectionCardView.tsx
13619
+ //#region src/components/CollectionViewBinding/CollectionCardViewBinding.tsx
13408
13620
  /**
13409
13621
  * Card grid view for displaying entities with infinite scroll.
13410
- * Alternative to the EntityCollectionTable for visual browsing.
13622
+ * Alternative to the CollectionTableBinding for visual browsing.
13411
13623
  */
13412
- function EntityCollectionCardView({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, onScroll, initialScroll, size = "m" }) {
13413
- const ResolvedEntityCard = useComponentOverride("Collection.Card", EntityCard);
13624
+ function CollectionCardViewBinding({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, onScroll, initialScroll, size = "m" }) {
13625
+ const ResolvedEntityCard = useComponentOverride("Collection.Card", EntityCardBinding);
13414
13626
  const { data, dataLoading, noMoreToLoad, dataLoadingError, itemCount, setItemCount, pageSize = 50, paginationEnabled } = tableController;
13415
13627
  const handleEntityClick = useCallback((entity) => {
13416
13628
  onEntityClick?.(entity);
@@ -13460,7 +13672,7 @@ function EntityCollectionCardView({ collection, tableController, onEntityClick,
13460
13672
  });
13461
13673
  }
13462
13674
  //#endregion
13463
- //#region src/components/EntityCollectionView/EntityCollectionListView.tsx
13675
+ //#region src/components/CollectionViewBinding/CollectionListViewBinding.tsx
13464
13676
  /**
13465
13677
  * Get row padding/spacing classes based on size
13466
13678
  */
@@ -13581,7 +13793,7 @@ function formatDateValue(value) {
13581
13793
  * - Column-sortable headers
13582
13794
  * - Infinite scroll
13583
13795
  */
13584
- function EntityCollectionListView({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, size = "m", selectedEntityId, getActionsForEntity, path, openEntityMode }) {
13796
+ function CollectionListViewBinding({ collection, tableController, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, size = "m", selectedEntityId, getActionsForEntity, path, openEntityMode }) {
13585
13797
  const authController = useAuthController();
13586
13798
  const customizationController = useCustomizationController();
13587
13799
  const analyticsController = useAnalyticsController();
@@ -14024,7 +14236,7 @@ var ListRow = React.memo(function ListRow({ entity, collection, onClick, selecte
14024
14236
  path,
14025
14237
  collection,
14026
14238
  context,
14027
- sideEntityController: context?.sideEntityController,
14239
+ sidePanelController: context?.sidePanelController,
14028
14240
  selectionController,
14029
14241
  openEntityMode: openEntityMode ?? collection?.openEntityMode ?? "full_screen"
14030
14242
  });
@@ -14037,7 +14249,7 @@ var ListRow = React.memo(function ListRow({ entity, collection, onClick, selecte
14037
14249
  });
14038
14250
  });
14039
14251
  //#endregion
14040
- //#region src/components/EntityCollectionView/SplitListView.tsx
14252
+ //#region src/components/CollectionViewBinding/SplitListView.tsx
14041
14253
  var PANEL_SIZE_KEY = "rebase_split_list_panel_size";
14042
14254
  function getSavedPanelSize(path) {
14043
14255
  try {
@@ -14066,7 +14278,7 @@ function savePanelSize(path, size) {
14066
14278
  * State management:
14067
14279
  * - The selected entity is driven by the URL path (e.g. /c/authors/14).
14068
14280
  * `selectedEntityId` comes from props via RebaseRoute, NOT from internal state.
14069
- * - Clicking an entity navigates to /c/authors/{id} via the standard onEntityClick handler.
14281
+ * - Clicking a entity navigates to /c/authors/{id} via the standard onEntityClick handler.
14070
14282
  * - Closing the detail navigates back to /c/authors.
14071
14283
  */
14072
14284
  function SplitListView({ collection, tableController, onEntityClick: externalOnEntityClick, onNewClick: externalOnNewClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, onScroll, initialScroll, size = "m", path, parentCollectionSlugs, parentEntityIds, selectedEntityId, selectedTab, toolbar, children }) {
@@ -14196,7 +14408,7 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
14196
14408
  const detailPanel = renderedEntityId !== void 0 ? /* @__PURE__ */ jsx("div", {
14197
14409
  className: cls("flex-1 flex flex-col min-w-0 h-full transition-all ease-out w-full", animationPhase === "entered" ? "opacity-100 translate-x-0" : largeLayout ? "opacity-0 translate-x-8" : "opacity-0 translate-x-1/3"),
14198
14410
  style: { transitionDuration: `${TRANSITION_DURATION}ms` },
14199
- children: /* @__PURE__ */ jsx(ErrorBoundary, { children: collection.defaultEntityAction === "view" && !isEditMode ? /* @__PURE__ */ jsx(EntityDetailView, {
14411
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: collection.defaultEntityAction === "view" && !isEditMode ? /* @__PURE__ */ jsx(DetailViewBinding, {
14200
14412
  path,
14201
14413
  collection,
14202
14414
  entityId: renderedEntityId,
@@ -14217,7 +14429,7 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
14217
14429
  if (currentViewParam) entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
14218
14430
  navigate(entityUrl);
14219
14431
  }
14220
- }, String(renderedEntityId)) : /* @__PURE__ */ jsx(EntityEditView, {
14432
+ }, String(renderedEntityId)) : /* @__PURE__ */ jsx(EditViewBinding, {
14221
14433
  path,
14222
14434
  collection,
14223
14435
  entityId: renderedEntityId,
@@ -14257,16 +14469,16 @@ function SplitListView({ collection, tableController, onEntityClick: externalOnE
14257
14469
  });
14258
14470
  }
14259
14471
  //#endregion
14260
- //#region src/components/EntityCollectionView/EntityBoardCard.tsx
14472
+ //#region src/components/CollectionViewBinding/BoardCardBinding.tsx
14261
14473
  /**
14262
- * Compact card component for displaying an entity in a Kanban board.
14474
+ * Compact card component for displaying a entity in a Kanban board.
14263
14475
  * Uses the shared slot system for consistent preview rendering.
14264
14476
  *
14265
14477
  * Selection UX: The checkbox overlays on top of the image/icon thumbnail area,
14266
14478
  * revealed on card hover or when the card is selected. This keeps the card
14267
14479
  * layout clean while providing intuitive selection affordance.
14268
14480
  */
14269
- function EntityBoardCardInner({ item, isDragging, isGroupedOver, style, collection, onClick, selected, onSelectionChange, selectionEnabled = false }) {
14481
+ function BoardCardBindingInner({ item, isDragging, isGroupedOver, style, collection, onClick, selected, onSelectionChange, selectionEnabled = false }) {
14270
14482
  const entity = item.data;
14271
14483
  const slotKeys = useCollectionSlotKeys(collection, useAuthController(), useCustomizationController().propertyConfigs);
14272
14484
  const slots = useMemo(() => resolveEntitySlots(entity, collection, slotKeys), [
@@ -14403,9 +14615,9 @@ function EntityBoardCardInner({ item, isDragging, isGroupedOver, style, collecti
14403
14615
  })
14404
14616
  });
14405
14617
  }
14406
- var EntityBoardCard = memo(EntityBoardCardInner);
14618
+ var BoardCardBinding = memo(BoardCardBindingInner);
14407
14619
  //#endregion
14408
- //#region src/components/EntityCollectionView/useBoardDataController.tsx
14620
+ //#region src/components/CollectionViewBinding/useBoardDataController.tsx
14409
14621
  var DEFAULT_PAGE_SIZE$1 = 20;
14410
14622
  /**
14411
14623
  * Shallow equality for entity value records.
@@ -14533,7 +14745,7 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
14533
14745
  ...currentFilterValues ?? {},
14534
14746
  [currentColumnProperty]: ["==", column]
14535
14747
  };
14536
- const orderByParam = currentOrderProperty ? `${currentOrderProperty}:asc` : void 0;
14748
+ const orderByParam = currentOrderProperty ? [currentOrderProperty, "asc"] : void 0;
14537
14749
  setColumnData((prev) => ({
14538
14750
  ...prev,
14539
14751
  [column]: {
@@ -14584,12 +14796,21 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
14584
14796
  return valA < valB ? -1 : valA > valB ? 1 : 0;
14585
14797
  });
14586
14798
  if (currentCollection.callbacks?.afterRead) try {
14587
- processed = await Promise.all(processed.map((entity) => currentCollection.callbacks.afterRead({
14588
- collection: currentCollection,
14589
- path: currentResolvedPath,
14590
- entity,
14591
- context: currentContext
14592
- })));
14799
+ processed = await Promise.all(processed.map(async (entity) => {
14800
+ const processedRow = await currentCollection.callbacks.afterRead({
14801
+ collection: currentCollection,
14802
+ path: currentResolvedPath,
14803
+ row: {
14804
+ id: entity.id,
14805
+ ...entity.values
14806
+ },
14807
+ context: currentContext
14808
+ });
14809
+ return {
14810
+ ...entity,
14811
+ values: processedRow
14812
+ };
14813
+ }));
14593
14814
  } catch (e) {
14594
14815
  console.error("Error in afterRead callback:", e);
14595
14816
  }
@@ -14639,17 +14860,20 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
14639
14860
  }));
14640
14861
  };
14641
14862
  const accessor = currentDataClient.collection(currentResolvedPath);
14863
+ const includeParams = getRelationIncludeParams(currentCollection);
14642
14864
  if (accessor.listen) {
14643
14865
  const unsubscribe = accessor.listen({
14644
14866
  where: whereFilter,
14645
14867
  limit: itemCount,
14646
- orderBy: orderByParam
14868
+ orderBy: orderByParam,
14869
+ include: includeParams
14647
14870
  }, (res) => onUpdate(res.data), onError);
14648
14871
  unsubscribersRef.current[column] = unsubscribe;
14649
14872
  } else accessor.find({
14650
14873
  where: whereFilter,
14651
14874
  limit: itemCount,
14652
- orderBy: orderByParam
14875
+ orderBy: orderByParam,
14876
+ include: includeParams
14653
14877
  }).then((res) => onUpdate(res.data)).catch(onError);
14654
14878
  }, []);
14655
14879
  useEffect(() => {
@@ -14863,7 +15087,7 @@ function useBoardDataController({ fullPath, collection, columnProperty, columns,
14863
15087
  ]);
14864
15088
  }
14865
15089
  //#endregion
14866
- //#region src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts
15090
+ //#region src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts
14867
15091
  function useKanbanDragAndDrop({ collection, fullPath, columnProperty, orderProperty, dataClient, context, boardDataController, analyticsController }) {
14868
15092
  const handleItemsReorder = useCallback(async (items, moveInfo) => {
14869
15093
  const entity = items.find((item) => item.id === moveInfo?.itemId)?.data;
@@ -14936,15 +15160,15 @@ function useKanbanDragAndDrop({ collection, fullPath, columnProperty, orderPrope
14936
15160
  return useMemo(() => ({ handleItemsReorder }), [handleItemsReorder]);
14937
15161
  }
14938
15162
  //#endregion
14939
- //#region src/components/EntityCollectionView/EntityCollectionBoardView.tsx
15163
+ //#region src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx
14940
15164
  /**
14941
15165
  * Kanban board view for displaying entities grouped by a string enum property.
14942
15166
  */
14943
- function EntityCollectionBoardView({ collection, tableController, fullPath, parentCollectionSlugs = [], parentEntityIds = [], columnProperty, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, deletedEntities }) {
15167
+ function CollectionBoardViewBinding({ collection, tableController, fullPath, parentCollectionSlugs = [], parentEntityIds = [], columnProperty, onEntityClick, selectionController, selectionEnabled = true, highlightedEntities, emptyComponent, deletedEntities }) {
14944
15168
  const customizationController = useCustomizationController();
14945
15169
  const context = useRebaseContext();
14946
15170
  const dataClient = useData();
14947
- const sideEntityController = useSideEntityController();
15171
+ const sidePanelController = useSidePanel();
14948
15172
  const analyticsController = useAnalyticsController();
14949
15173
  const { t } = useTranslation();
14950
15174
  const plugins = customizationController.plugins ?? [];
@@ -15229,7 +15453,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
15229
15453
  handleSelectionChangeRef.current(entity, sel);
15230
15454
  }, []);
15231
15455
  const ItemComponent = useMemo(() => {
15232
- const Comp = (props) => /* @__PURE__ */ jsx(EntityBoardCard, {
15456
+ const Comp = (props) => /* @__PURE__ */ jsx(BoardCardBinding, {
15233
15457
  ...props,
15234
15458
  collection: collectionRef.current,
15235
15459
  onClick: stableOnClick,
@@ -15352,7 +15576,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
15352
15576
  path: fullPath,
15353
15577
  column
15354
15578
  });
15355
- sideEntityController.open({
15579
+ sidePanelController.open({
15356
15580
  path: fullPath,
15357
15581
  collection,
15358
15582
  entityId: void 0,
@@ -15395,7 +15619,7 @@ function EntityCollectionBoardView({ collection, tableController, fullPath, pare
15395
15619
  });
15396
15620
  }
15397
15621
  //#endregion
15398
- //#region src/components/EntityCollectionView/ViewModeToggle.tsx
15622
+ //#region src/components/CollectionViewBinding/ViewModeToggle.tsx
15399
15623
  var ALL_VIEW_MODES = [
15400
15624
  "list",
15401
15625
  "table",
@@ -15520,7 +15744,7 @@ function ViewModeToggle({ viewMode = "table", onViewModeChange, enabledViews = A
15520
15744
  });
15521
15745
  }
15522
15746
  //#endregion
15523
- //#region src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx
15747
+ //#region src/components/CollectionTableBinding/internal/popup_field/useDraggable.tsx
15524
15748
  /** Tracks events originating inside the inner (non-draggable) area. */
15525
15749
  var innerClicked = /* @__PURE__ */ new WeakSet();
15526
15750
  function useDraggable({ containerRef, innerRef, x, y, onMove }) {
@@ -15584,7 +15808,7 @@ function useDraggable({ containerRef, innerRef, x, y, onMove }) {
15584
15808
  ]);
15585
15809
  }
15586
15810
  //#endregion
15587
- //#region src/components/EntityCollectionTable/internal/popup_field/useWindowSize.tsx
15811
+ //#region src/components/CollectionTableBinding/internal/popup_field/useWindowSize.tsx
15588
15812
  function useWindowSize() {
15589
15813
  const [size, setSize] = useState({
15590
15814
  width: 0,
@@ -15604,7 +15828,7 @@ function useWindowSize() {
15604
15828
  return size;
15605
15829
  }
15606
15830
  //#endregion
15607
- //#region src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx
15831
+ //#region src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx
15608
15832
  function PopupFormField(props) {
15609
15833
  if (!props.open) return null;
15610
15834
  return /* @__PURE__ */ jsx(PopupFormFieldLoading, { ...props });
@@ -15884,13 +16108,14 @@ function ClearFilterSortButton({ tableController, enabled }) {
15884
16108
  return null;
15885
16109
  }
15886
16110
  //#endregion
15887
- //#region src/components/EntityCollectionView/FiltersDialog.tsx
16111
+ //#region src/components/CollectionViewBinding/FiltersDialog.tsx
15888
16112
  /**
15889
16113
  * Dialog that displays all filterable properties from a collection
15890
16114
  * and allows setting filter values for each.
15891
16115
  */
15892
16116
  function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilterValues, fixedFilter }) {
15893
16117
  const { t } = useTranslation();
16118
+ const engine = useCollectionScope()?.engine;
15894
16119
  const [localFilters, setLocalFilters] = useState(filterValues ?? {});
15895
16120
  const [hiddenFields, setHiddenFields] = useState({});
15896
16121
  React.useEffect(() => {
@@ -15900,17 +16125,22 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
15900
16125
  return Object.entries(properties).filter(([key, property]) => {
15901
16126
  if (!property) return false;
15902
16127
  if (fixedFilter && key in fixedFilter) return false;
15903
- const baseProperty = property.type === "array" ? property.of : property;
15904
- if (!baseProperty || Array.isArray(baseProperty)) return false;
15905
- return [
15906
- "string",
15907
- "number",
15908
- "boolean",
15909
- "date",
15910
- "reference"
15911
- ].includes(baseProperty.type);
16128
+ const isArray = property.type === "array";
16129
+ const ofProp = isArray && "of" in property ? property.of : void 0;
16130
+ const baseProperty = isArray ? Array.isArray(ofProp) ? ofProp[0] : ofProp : property;
16131
+ if (!baseProperty) return false;
16132
+ if (baseProperty.ui?.Filter) return true;
16133
+ return resolveFilterOperators({
16134
+ property: baseProperty,
16135
+ isArray,
16136
+ engine
16137
+ }).length > 0;
15912
16138
  });
15913
- }, [properties, fixedFilter]);
16139
+ }, [
16140
+ properties,
16141
+ fixedFilter,
16142
+ engine
16143
+ ]);
15914
16144
  const handleFilterChange = useCallback((propertyKey, value) => {
15915
16145
  setLocalFilters((prev) => {
15916
16146
  const newFilters = { ...prev };
@@ -15943,55 +16173,23 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
15943
16173
  const isAnyFieldHidden = Object.values(hiddenFields).some((hidden) => hidden);
15944
16174
  const activeFilterCount = Object.keys(localFilters).length;
15945
16175
  const renderFilterField = useCallback((propertyKey, property) => {
15946
- const isArray = property.type === "array";
15947
- const ofProp = isArray && "of" in property ? property.of : void 0;
15948
- const baseProperty = isArray ? Array.isArray(ofProp) ? ofProp[0] : ofProp : property;
15949
- if (!baseProperty) return null;
15950
16176
  const filterValue = localFilters[propertyKey];
15951
16177
  const setValue = (value) => handleFilterChange(propertyKey, value);
15952
- if (baseProperty.type === "reference") return /* @__PURE__ */ jsx(ReferenceFilterField, {
16178
+ return /* @__PURE__ */ jsx(FilterFieldBinding, {
16179
+ propertyKey,
16180
+ property,
16181
+ engine,
15953
16182
  value: filterValue,
15954
16183
  setValue,
15955
- name: propertyKey,
15956
- isArray,
15957
- path: baseProperty.path,
15958
- title: property.name,
15959
- includeId: baseProperty.includeId,
15960
- previewProperties: baseProperty.ui?.previewProperties,
15961
16184
  hidden: hiddenFields[propertyKey] ?? false,
15962
16185
  setHidden: (hidden) => setHiddenForField(propertyKey, hidden)
15963
16186
  });
15964
- else if (baseProperty.type === "number" || baseProperty.type === "string") {
15965
- const enumValues = baseProperty.enum ? enumToObjectEntries(baseProperty.enum) : void 0;
15966
- return /* @__PURE__ */ jsx(StringNumberFilterField, {
15967
- value: filterValue,
15968
- setValue,
15969
- name: propertyKey,
15970
- type: baseProperty.type,
15971
- isArray,
15972
- enumValues,
15973
- title: property.name
15974
- });
15975
- } else if (baseProperty.type === "boolean") return /* @__PURE__ */ jsx(BooleanFilterField, {
15976
- value: filterValue,
15977
- setValue,
15978
- name: propertyKey,
15979
- title: property.name
15980
- });
15981
- else if (baseProperty.type === "date") return /* @__PURE__ */ jsx(DateTimeFilterField, {
15982
- value: filterValue,
15983
- setValue,
15984
- name: propertyKey,
15985
- mode: baseProperty.mode,
15986
- isArray,
15987
- title: property.name
15988
- });
15989
- return null;
15990
16187
  }, [
15991
16188
  localFilters,
15992
16189
  handleFilterChange,
15993
16190
  hiddenFields,
15994
- setHiddenForField
16191
+ setHiddenForField,
16192
+ engine
15995
16193
  ]);
15996
16194
  return /* @__PURE__ */ jsxs(Dialog, {
15997
16195
  open,
@@ -16055,7 +16253,7 @@ function FiltersDialog({ open, onOpenChange, properties, filterValues, setFilter
16055
16253
  });
16056
16254
  }
16057
16255
  //#endregion
16058
- //#region src/components/EntityCollectionView/FilterPresetsButton.tsx
16256
+ //#region src/components/CollectionViewBinding/FilterPresetsButton.tsx
16059
16257
  /**
16060
16258
  * Maximum number of presets shown as inline toggle chips before the
16061
16259
  * rest are collapsed into an overflow menu.
@@ -16248,8 +16446,8 @@ function FilterPresetsButton({ filterPresets, tableController, compact }) {
16248
16446
  });
16249
16447
  }
16250
16448
  //#endregion
16251
- //#region src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx
16252
- function EntityCollectionViewStartActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, path, selectionController, tableController, collectionEntitiesCount, resolvedProperties, compact, openNewDocument }) {
16449
+ //#region src/components/CollectionViewBinding/CollectionViewStartActions.tsx
16450
+ function CollectionViewStartActions({ collection, relativePath, parentCollectionSlugs, parentEntityIds, path, selectionController, tableController, collectionEntitiesCount, resolvedProperties, compact, openNewDocument }) {
16253
16451
  const context = useCMSContext();
16254
16452
  const largeLayout = useLargeLayout();
16255
16453
  const { t } = useTranslation();
@@ -16338,7 +16536,7 @@ function EntityCollectionViewStartActions({ collection, relativePath, parentColl
16338
16536
  ] });
16339
16537
  }
16340
16538
  //#endregion
16341
- //#region src/components/EntityCollectionView/EntityCollectionView.tsx
16539
+ //#region src/components/CollectionViewBinding/CollectionViewBinding.tsx
16342
16540
  var EMPTY_ARRAY = [];
16343
16541
  var DEFAULT_ENTITY_OPEN_MODE = "split";
16344
16542
  function getOpenEntityMode(viewMode, configuredMode) {
@@ -16348,20 +16546,20 @@ function getOpenEntityMode(viewMode, configuredMode) {
16348
16546
  return "split";
16349
16547
  }
16350
16548
  /**
16351
- * This component is in charge of binding a driver path with an {@link EntityCollection}
16549
+ * This component is in charge of binding a driver path with an {@link CollectionConfig}
16352
16550
  * where it's configuration is defined. It includes an infinite scrolling table
16353
16551
  * and a 'Add' new entities button,
16354
16552
  *
16355
16553
  * This component is the default one used for displaying entity collections
16356
16554
  * and is in charge of generating all the specific actions and customization
16357
- * of the lower level {@link EntityCollectionTable}
16555
+ * of the lower level {@link CollectionTableBinding}
16358
16556
  *
16359
16557
  * Please **note** that you only need to use this component if you are building
16360
16558
  * a custom view. If you just need to create a default view you can do it
16361
16559
  * exclusively with config options.
16362
16560
  *
16363
16561
  * If you need a lower level implementation with more granular options, you
16364
- * can use {@link EntityCollectionTable}.
16562
+ * can use {@link CollectionTableBinding}.
16365
16563
  *
16366
16564
  * If you need a generic table that is not bound to the driver or entities and
16367
16565
  * properties at all, you can check {@link VirtualTable}
@@ -16371,7 +16569,7 @@ function getOpenEntityMode(viewMode, configuredMode) {
16371
16569
 
16372
16570
  * @group Components
16373
16571
  */
16374
- var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({ path: pathProp, parentCollectionSlugs, parentEntityIds, isSubCollection, className, updateUrl, selectedEntityId: selectedEntityIdProp, selectedTab: selectedTabProp, ...collectionProp }) {
16572
+ var CollectionViewBindingInner = React.memo(function CollectionViewBindingInner({ path: pathProp, parentCollectionSlugs, parentEntityIds, isSubCollection, className, updateUrl, selectedEntityId: selectedEntityIdProp, selectedTab: selectedTabProp, ...collectionProp }) {
16375
16573
  const { t } = useTranslation();
16376
16574
  const context = useCMSContext();
16377
16575
  const collectionRegistry = useCollectionRegistryController();
@@ -16379,7 +16577,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16379
16577
  const breadcrumbs = useBreadcrumbsController();
16380
16578
  const path = pathProp ?? getCollectionDataPath(collectionProp);
16381
16579
  const dataClient = useData();
16382
- const sideEntityController = useSideEntityController();
16580
+ const sidePanelController = useSidePanel();
16383
16581
  useAuthController();
16384
16582
  const userConfigPersistence = useUserConfigurationPersistence();
16385
16583
  const analyticsController = useAnalyticsController();
@@ -16500,14 +16698,14 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16500
16698
  navigateToEntity({
16501
16699
  navigation: urlController,
16502
16700
  path: path ?? clickedEntity.path,
16503
- sideEntityController,
16701
+ sidePanelController,
16504
16702
  openEntityMode,
16505
16703
  collection,
16506
16704
  entityId: clickedEntity.id,
16507
16705
  replace: openEntityMode === "split" && selectedEntityIdProp !== void 0
16508
16706
  });
16509
16707
  }, [
16510
- sideEntityController,
16708
+ sidePanelController,
16511
16709
  openEntityMode,
16512
16710
  selectedEntityIdProp,
16513
16711
  path,
@@ -16522,11 +16720,11 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16522
16720
  collection,
16523
16721
  entityId: void 0,
16524
16722
  path,
16525
- sideEntityController,
16723
+ sidePanelController,
16526
16724
  navigation: urlController,
16527
16725
  onClose: unselectNavigatedEntity
16528
16726
  });
16529
- }, [path, sideEntityController]);
16727
+ }, [path, sidePanelController]);
16530
16728
  const openNewDocument = useCallback((defaultValues) => {
16531
16729
  const collection = collectionRef.current;
16532
16730
  analyticsController.onAnalyticsEvent?.("new_entity_click", { path });
@@ -16536,13 +16734,13 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16536
16734
  entityId: void 0,
16537
16735
  defaultValues,
16538
16736
  path,
16539
- sideEntityController,
16737
+ sidePanelController,
16540
16738
  navigation: urlController,
16541
16739
  onClose: unselectNavigatedEntity
16542
16740
  });
16543
16741
  }, [
16544
16742
  path,
16545
- sideEntityController,
16743
+ sidePanelController,
16546
16744
  openEntityMode,
16547
16745
  urlController,
16548
16746
  unselectNavigatedEntity
@@ -16741,7 +16939,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16741
16939
  selectedTab: subcollection.slug,
16742
16940
  path,
16743
16941
  navigation: urlController,
16744
- sideEntityController
16942
+ sidePanelController
16745
16943
  });
16746
16944
  },
16747
16945
  children: subcollection.name
@@ -16752,7 +16950,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16752
16950
  }, [
16753
16951
  collection,
16754
16952
  path,
16755
- sideEntityController
16953
+ sidePanelController
16756
16954
  ]);
16757
16955
  const updateLastDeleteTimestamp = useCallback(() => {
16758
16956
  setLastDeleteTimestamp(Date.now());
@@ -16783,7 +16981,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16783
16981
  return (largeLayout ? 80 + actionsWidth : 70 + actionsWidth) + (collapsedActions.length > 0 ? largeLayout ? 40 : 30 : 0);
16784
16982
  }, [getActionsForEntity, largeLayout]);
16785
16983
  const tableRowActionsBuilder = useCallback(({ entity, size, width, frozen }) => {
16786
- return /* @__PURE__ */ jsx(EntityCollectionRowActions, {
16984
+ return /* @__PURE__ */ jsx(CollectionRowActions, {
16787
16985
  entity,
16788
16986
  width,
16789
16987
  frozen,
@@ -16896,8 +17094,8 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16896
17094
  const isSearching = !!tableController.searchString;
16897
17095
  const isFilteredOrSorted = tableController.filterValues !== void 0 || tableController.sortBy !== void 0 || isSearching;
16898
17096
  const ResolvedEmptyState = useComponentOverride("Collection.EmptyState", DefaultCollectionEmptyState);
16899
- const ResolvedCollectionActions = useComponentOverride("Collection.Actions", EntityCollectionViewActions);
16900
- const ResolvedCollectionTable = useComponentOverride("Collection.Table", EntityCollectionTable);
17097
+ const ResolvedCollectionActions = useComponentOverride("Collection.Actions", CollectionViewActions);
17098
+ const ResolvedCollectionTable = useComponentOverride("Collection.Table", CollectionTableBinding);
16901
17099
  const emptyComponent = pluginEmptyStates.length > 0 ? /* @__PURE__ */ jsx(Fragment, { children: pluginEmptyStates }) : /* @__PURE__ */ jsx(ResolvedEmptyState, {
16902
17100
  canCreate: canCreateEntities && !isFilteredOrSorted,
16903
17101
  onNewClick,
@@ -16910,7 +17108,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16910
17108
  onTextSearch: tableController.setSearchString,
16911
17109
  initialSearchText: tableController.searchString,
16912
17110
  viewModeToggle: viewModeToggleElement,
16913
- actionsStart: /* @__PURE__ */ jsx(EntityCollectionViewStartActions, {
17111
+ actionsStart: /* @__PURE__ */ jsx(CollectionViewStartActions, {
16914
17112
  parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY,
16915
17113
  parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
16916
17114
  collection,
@@ -16940,7 +17138,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16940
17138
  children: pluginToolbarWidgets
16941
17139
  })
16942
17140
  });
16943
- const innerView = viewMode === "kanban" ? /* @__PURE__ */ jsx(EntityCollectionBoardView, {
17141
+ const innerView = viewMode === "kanban" ? /* @__PURE__ */ jsx(CollectionBoardViewBinding, {
16944
17142
  collection,
16945
17143
  tableController,
16946
17144
  fullPath: path,
@@ -16953,7 +17151,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16953
17151
  highlightedEntities: highlightedEntity ? [highlightedEntity] : [],
16954
17152
  deletedEntities,
16955
17153
  emptyComponent
16956
- }, `kanban-view-${path}-${selectedKanbanProperty}`) : viewMode === "cards" ? /* @__PURE__ */ jsx(EntityCollectionCardView, {
17154
+ }, `kanban-view-${path}-${selectedKanbanProperty}`) : viewMode === "cards" ? /* @__PURE__ */ jsx(CollectionCardViewBinding, {
16957
17155
  collection,
16958
17156
  tableController,
16959
17157
  onEntityClick,
@@ -16964,7 +17162,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
16964
17162
  initialScroll: tableController.initialScroll,
16965
17163
  size: cardSize,
16966
17164
  emptyComponent
16967
- }, `cards-view-${path}`) : viewMode === "list" ? /* @__PURE__ */ jsx(EntityCollectionListView, {
17165
+ }, `cards-view-${path}`) : viewMode === "list" ? /* @__PURE__ */ jsx(CollectionListViewBinding, {
16968
17166
  collection,
16969
17167
  tableController,
16970
17168
  onEntityClick,
@@ -17067,7 +17265,7 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
17067
17265
  children: pluginInsights
17068
17266
  })
17069
17267
  }),
17070
- /* @__PURE__ */ jsx(EntityCollectionListView, {
17268
+ /* @__PURE__ */ jsx(CollectionListViewBinding, {
17071
17269
  collection,
17072
17270
  tableController,
17073
17271
  onEntityClick,
@@ -17140,13 +17338,13 @@ var EntityCollectionViewInner = React.memo(function EntityCollectionViewInner({
17140
17338
  }, (a, b) => {
17141
17339
  return deepEqual(a.path, b.path) && deepEqual(a.parentCollectionSlugs, b.parentCollectionSlugs) && deepEqual(a.parentEntityIds, b.parentEntityIds) && deepEqual(a.isSubCollection, b.isSubCollection) && deepEqual(a.className, b.className) && deepEqual(a.properties, b.properties) && deepEqual(a.propertiesOrder, b.propertiesOrder) && deepEqual(a.hideIdFromCollection, b.hideIdFromCollection) && deepEqual(a.inlineEditing, b.inlineEditing) && deepEqual(a.selectionEnabled, b.selectionEnabled) && deepEqual(a.selectionController, b.selectionController) && deepEqual(a.Actions, b.Actions) && deepEqual(a.defaultSize, b.defaultSize) && deepEqual(a.includeJsonView, b.includeJsonView) && deepEqual(a.additionalFields, b.additionalFields) && deepEqual(a.sideDialogWidth, b.sideDialogWidth) && deepEqual(a.openEntityMode, b.openEntityMode) && deepEqual(a.exportable, b.exportable) && deepEqual(a.history, b.history) && deepEqual(a.fixedFilter, b.fixedFilter) && deepEqual(a.selectedEntityId, b.selectedEntityId) && deepEqual(a.selectedTab, b.selectedTab);
17142
17340
  });
17143
- var EntityCollectionView = React.memo(function EntityCollectionView(props) {
17341
+ var CollectionViewBinding = React.memo(function CollectionViewBinding(props) {
17144
17342
  const collectionRegistry = useCollectionRegistryController();
17145
17343
  const path = props.path ?? props.slug;
17146
17344
  const collection = collectionRegistry.getCollection(path) ?? props;
17147
- const content = /* @__PURE__ */ jsx(EntityCollectionViewInner, { ...props });
17148
- if (collection?.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
17149
- overrides: collection.components,
17345
+ const content = /* @__PURE__ */ jsx(CollectionViewBindingInner, { ...props });
17346
+ if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
17347
+ collection,
17150
17348
  children: content
17151
17349
  });
17152
17350
  return content;
@@ -17198,7 +17396,7 @@ function EntitiesCount({ path, collection, filter, sortBy, onCountChange }) {
17198
17396
  }
17199
17397
  let cancelled = false;
17200
17398
  const whereParams = filter && Object.keys(filter).length > 0 ? filter : void 0;
17201
- const orderByParams = sortByProperty ? `${String(sortByProperty)}:${currentSort}` : void 0;
17399
+ const orderByParams = sortByProperty && currentSort ? [String(sortByProperty), currentSort] : void 0;
17202
17400
  const cacheKey = `${path}|${filterKey}|${sortByProperty ?? ""}|${currentSort ?? ""}`;
17203
17401
  let countPromise = inflightCountRequests.get(cacheKey);
17204
17402
  if (!countPromise) {
@@ -17239,7 +17437,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
17239
17437
  const [openPopup, setOpenPopup] = React.useState(false);
17240
17438
  const [searchString, setSearchString] = React.useState("");
17241
17439
  const [recentIds, setRecentIds] = React.useState(getRecentIds(collection.slug).map(String));
17242
- const sideEntityController = useSideEntityController();
17440
+ const sidePanelController = useSidePanel();
17243
17441
  const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
17244
17442
  return /* @__PURE__ */ jsx(Tooltip, {
17245
17443
  title: !openPopup ? t("find_by_id") : void 0,
@@ -17269,7 +17467,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
17269
17467
  collection,
17270
17468
  entityId,
17271
17469
  path,
17272
- sideEntityController,
17470
+ sidePanelController,
17273
17471
  navigation: urlController
17274
17472
  });
17275
17473
  },
@@ -17308,7 +17506,7 @@ function EntityIdHeaderWidget({ collection, path, idPath }) {
17308
17506
  collection,
17309
17507
  entityId: id,
17310
17508
  path,
17311
- sideEntityController,
17509
+ sidePanelController,
17312
17510
  navigation: urlController
17313
17511
  });
17314
17512
  },
@@ -17347,7 +17545,7 @@ function ReferenceWidget({ name, multiselect = false, path, disabled, value, onR
17347
17545
  entities
17348
17546
  });
17349
17547
  }, [disabled, onReferenceSelected]);
17350
- const referenceDialogController = useEntitySelectionDialog({
17548
+ const referenceDialogController = useSelectionDialog({
17351
17549
  multiselect,
17352
17550
  path,
17353
17551
  collection,
@@ -17491,15 +17689,15 @@ function useBuildSideDialogsController() {
17491
17689
  ]);
17492
17690
  }
17493
17691
  //#endregion
17494
- //#region src/components/SideEntityProvider.tsx
17692
+ //#region src/components/SidePanelProvider.tsx
17495
17693
  /**
17496
- * Provider that builds the SideEntityController and makes it available
17497
- * via the SideEntityControllerContext from @rebasepro/core.
17694
+ * Provider that builds the SidePanelController and makes it available
17695
+ * via the SidePanelControllerContext from @rebasepro/app.
17498
17696
  *
17499
- * After the CMS extraction refactor, `useBuildSideEntityController` lives
17697
+ * After the CMS extraction refactor, `useBuildSidePanel` lives
17500
17698
  * in the CMS package while the context it feeds into lives in core.
17501
17699
  * This provider bridges the two: place it inside the `<Rebase>` tree and
17502
- * above any component that calls `useSideEntityController()`.
17700
+ * above any component that calls `useSidePanel()`.
17503
17701
  *
17504
17702
  * Also auto-registers the side entity controller and breadcrumbs into the
17505
17703
  * self-assembling Studio bridge (when a StudioBridgeRegistryProvider is
@@ -17509,28 +17707,28 @@ function useBuildSideDialogsController() {
17509
17707
  * ```tsx
17510
17708
  * <Rebase ...>
17511
17709
  * {({ loading }) => (
17512
- * <SideEntityProvider>
17710
+ * <SidePanelProvider>
17513
17711
  * <RebaseRoutes>
17514
17712
  * ...
17515
17713
  * </RebaseRoutes>
17516
- * </SideEntityProvider>
17714
+ * </SidePanelProvider>
17517
17715
  * )}
17518
17716
  * </Rebase>
17519
17717
  * ```
17520
17718
  *
17521
17719
  * @group Components
17522
17720
  */
17523
- function SideEntityProvider({ children }) {
17721
+ function SidePanelProvider({ children }) {
17524
17722
  const collectionRegistryController = useCollectionRegistryController();
17525
17723
  const urlController = useUrlController();
17526
17724
  const navigationStateController = useNavigationStateController();
17527
17725
  const sideDialogsController = useBuildSideDialogsController();
17528
- const sideEntityController = useBuildSideEntityController(collectionRegistryController, urlController, navigationStateController, sideDialogsController, useAuthController());
17726
+ const sidePanelController = useBuildSidePanel(collectionRegistryController, urlController, navigationStateController, sideDialogsController, useAuthController());
17529
17727
  return /* @__PURE__ */ jsx(BreadcrumbsProvider, { children: /* @__PURE__ */ jsx(SideDialogsControllerContext.Provider, {
17530
17728
  value: sideDialogsController,
17531
- children: /* @__PURE__ */ jsxs(SideEntityControllerContext.Provider, {
17532
- value: sideEntityController,
17533
- children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar$1, { sideEntityController }), children]
17729
+ children: /* @__PURE__ */ jsxs(SidePanelControllerContext.Provider, {
17730
+ value: sidePanelController,
17731
+ children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar$1, { sidePanelController }), children]
17534
17732
  })
17535
17733
  }) });
17536
17734
  }
@@ -17538,9 +17736,9 @@ function SideEntityProvider({ children }) {
17538
17736
  * Internal component that auto-registers side entity and breadcrumbs
17539
17737
  * into the Studio bridge. Must be a child of BreadcrumbsProvider.
17540
17738
  */
17541
- function BridgeAutoRegistrar$1({ sideEntityController }) {
17739
+ function BridgeAutoRegistrar$1({ sidePanelController }) {
17542
17740
  const breadcrumbs = useBreadcrumbsController();
17543
- useBridgeRegistration("sideEntityController", sideEntityController);
17741
+ useBridgeRegistration("sidePanelController", sidePanelController);
17544
17742
  useBridgeRegistration("breadcrumbs", breadcrumbs);
17545
17743
  return null;
17546
17744
  }
@@ -18291,8 +18489,9 @@ var Scaffold = React.memo(function Scaffold(props) {
18291
18489
  className: "flex flex-col grow overflow-auto",
18292
18490
  children: [hasAppBar && /* @__PURE__ */ jsx(DrawerHeader, {}), /* @__PURE__ */ jsx("div", {
18293
18491
  className: cls(defaultBorderMixin, "bg-surface-50 dark:bg-surface-800", "grow overflow-auto m-0", {
18294
- "lg:mt-4": !hasAppBar,
18295
18492
  "mt-1 lg:m-0 lg:mx-2 lg:mb-2 lg:rounded-lg lg:border-t lg:border-x lg:border-solid": padding,
18493
+ "lg:mt-2": !hasAppBar && padding,
18494
+ "lg:mt-4": !hasAppBar && !padding,
18296
18495
  "border-t": hasAppBar && !padding
18297
18496
  }),
18298
18497
  children: /* @__PURE__ */ jsx(ErrorBoundary, { children: otherChildren })
@@ -18355,7 +18554,7 @@ function DrawerWrapper(props) {
18355
18554
  });
18356
18555
  }
18357
18556
  //#endregion
18358
- //#region src/components/RebaseCMS.tsx
18557
+ //#region src/components/RebaseAdmin.tsx
18359
18558
  /**
18360
18559
  * Declarative component to configure the CMS in Rebase.
18361
18560
  * Renders nothing — purely registers config into the RebaseRegistry.
@@ -18364,7 +18563,7 @@ function DrawerWrapper(props) {
18364
18563
  * is auto-wired as a native feature (slots, provider, Studio view) without
18365
18564
  * needing any external plugin.
18366
18565
  */
18367
- function RebaseCMS({ collections, views, homePage, entityViews, entityActions, collectionEditor, navigationGroupMappings }) {
18566
+ function RebaseAdmin({ collections, views, homePage, entityViews, entityActions, collectionEditor, navigationGroupMappings, basePath }) {
18368
18567
  const dispatch = useRebaseRegistryDispatch();
18369
18568
  useLayoutEffect(() => {
18370
18569
  dispatch.registerCMS({
@@ -18374,7 +18573,8 @@ function RebaseCMS({ collections, views, homePage, entityViews, entityActions, c
18374
18573
  entityViews,
18375
18574
  entityActions,
18376
18575
  collectionEditor,
18377
- navigationGroupMappings
18576
+ navigationGroupMappings,
18577
+ basePath
18378
18578
  });
18379
18579
  return () => dispatch.unregisterCMS();
18380
18580
  }, [
@@ -18385,7 +18585,8 @@ function RebaseCMS({ collections, views, homePage, entityViews, entityActions, c
18385
18585
  entityViews,
18386
18586
  entityActions,
18387
18587
  collectionEditor,
18388
- navigationGroupMappings
18588
+ navigationGroupMappings,
18589
+ basePath
18389
18590
  ]);
18390
18591
  return null;
18391
18592
  }
@@ -18519,7 +18720,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
18519
18720
  //#region src/components/RebaseNavigation.tsx
18520
18721
  var EMPTY_PLUGINS = [];
18521
18722
  var EMPTY_COLLECTIONS = [];
18522
- var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-BQTIExjA.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
18723
+ var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-C6XQ7Il5.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
18523
18724
  /**
18524
18725
  * Navigation layer — builds and provides all CMS navigation controllers:
18525
18726
  * collection registry, URL controller, navigation state, side entity,
@@ -18534,7 +18735,7 @@ var CollectionsStudioView = lazy(() => import("./RouterCollectionsStudioView-BQT
18534
18735
  * ```tsx
18535
18736
  * <RebaseNavigation>
18536
18737
  * <MyCustomLayout>
18537
- * <EntityCollectionView ... />
18738
+ * <CollectionViewBinding ... />
18538
18739
  * </MyCustomLayout>
18539
18740
  * </RebaseNavigation>
18540
18741
  * ```
@@ -18560,13 +18761,19 @@ function RebaseNavigation({ children }) {
18560
18761
  const defaultData = useData();
18561
18762
  const getCollectionRef = useRef(collectionRegistryController.getCollection);
18562
18763
  getCollectionRef.current = collectionRegistryController.getCollection;
18764
+ useContext(CollectionResolverRegistrationContext)(useCallback((slug) => getCollectionRef.current(slug), []));
18563
18765
  const routedData = useMemo(() => buildRoutedRebaseData({
18564
18766
  defaultData,
18565
18767
  sources: dataSources.sources,
18566
18768
  resolveKey: (slugOrPath) => resolveDataSource(getCollectionRef.current(slugOrPath), dataSources.registry).key
18567
18769
  }), [defaultData, dataSources]);
18568
18770
  const urlController = useBuildUrlController({
18569
- basePath: "/",
18771
+ basePath: useMemo(() => {
18772
+ const raw = registry.cmsConfig?.basePath;
18773
+ if (!raw || raw === "/") return "/";
18774
+ const trimmed = raw.replace(/^\/+/, "").replace(/\/+$/, "");
18775
+ return trimmed ? `/${trimmed}` : "/";
18776
+ }, [registry.cmsConfig?.basePath]),
18570
18777
  baseCollectionPath: "/c",
18571
18778
  collectionRegistryController
18572
18779
  });
@@ -18659,7 +18866,7 @@ function RebaseNavigation({ children }) {
18659
18866
  value: urlController,
18660
18867
  children: /* @__PURE__ */ jsx(NavigationStateContext.Provider, {
18661
18868
  value: navigationStateController,
18662
- children: /* @__PURE__ */ jsxs(SideEntityProvider, { children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar, {
18869
+ children: /* @__PURE__ */ jsxs(SidePanelProvider, { children: [/* @__PURE__ */ jsx(BridgeAutoRegistrar, {
18663
18870
  collectionRegistryController,
18664
18871
  urlController,
18665
18872
  navigationStateController
@@ -18690,17 +18897,18 @@ function BridgeAutoRegistrar({ collectionRegistryController, urlController, navi
18690
18897
  //#endregion
18691
18898
  //#region src/components/RebaseLayout.tsx
18692
18899
  /**
18693
- * Layout layer — provides the Scaffold, AppBar, Drawer, and SideDialogs.
18900
+ * Layout layer — provides the Scaffold, Drawer, and SideDialogs.
18694
18901
  *
18695
18902
  * Wraps the route outlet with the standard Rebase admin layout.
18696
- * Override individual pieces (appBar, drawer) via props.
18903
+ * Override the drawer via props; pass `appBar` to add a top bar (there is
18904
+ * none by default — the drawer owns navigation and user actions).
18697
18905
  *
18698
18906
  * **Independently usable**: Use this when you want the Rebase layout
18699
18907
  * without its default route definitions.
18700
18908
  *
18701
18909
  * @example
18702
18910
  * ```tsx
18703
- * <RebaseLayout title="My Admin">
18911
+ * <RebaseLayout title="My Admin" appBar={<AppBar/>}>
18704
18912
  * <Route path="/" element={<MyHomePage />} />
18705
18913
  * <Route path="/custom" element={<CustomView />} />
18706
18914
  * </RebaseLayout>
@@ -18709,13 +18917,7 @@ function BridgeAutoRegistrar({ collectionRegistryController, urlController, navi
18709
18917
  function RebaseLayout(props) {
18710
18918
  const { title = "Rebase", appBar, drawer, autoOpenDrawer = false, devViews = [] } = props;
18711
18919
  const adminModeController = useAdminModeController();
18712
- const ResolvedAppBar = useComponentOverride("Shell.AppBar", AppBar);
18713
18920
  const ResolvedDrawer = useComponentOverride("Shell.Drawer", Drawer);
18714
- const ActiveAppBar = appBar ?? /* @__PURE__ */ jsx(ResolvedAppBar, {
18715
- includeLanguageToggle: false,
18716
- includeModeToggle: false,
18717
- includeUserMenu: false
18718
- });
18719
18921
  const ActiveDrawer = drawer ?? /* @__PURE__ */ jsx(ResolvedDrawer, {
18720
18922
  title,
18721
18923
  logoDestination: adminModeController.mode === "studio" ? "/s" : "/"
@@ -18724,7 +18926,7 @@ function RebaseLayout(props) {
18724
18926
  autoOpenDrawer,
18725
18927
  children: [
18726
18928
  /* @__PURE__ */ jsx(AdminModeSyncer, { devViews }),
18727
- ActiveAppBar,
18929
+ appBar,
18728
18930
  ActiveDrawer,
18729
18931
  /* @__PURE__ */ jsx(Outlet, {}),
18730
18932
  /* @__PURE__ */ jsx(SideDialogs, {})
@@ -19742,7 +19944,7 @@ function RebaseRoute() {
19742
19944
  const urlController = useUrlController();
19743
19945
  const breadcrumbs = useBreadcrumbsController();
19744
19946
  const userConfigPersistence = useUserConfigurationPersistence();
19745
- const ResolvedCollectionView = useComponentOverride("Collection.View", EntityCollectionView);
19947
+ const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
19746
19948
  const hash = location.hash;
19747
19949
  const isSidePanel = hash.includes("#side");
19748
19950
  const isNew = hash.includes("#new") || hash.includes("#new_side");
@@ -19937,7 +20139,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
19937
20139
  const fullIdPath = isNew ? lastCollectionEntry.slug : lastEntityEntry.slug;
19938
20140
  const collectionPath = urlController.resolveDatabasePathsFrom(fullIdPath);
19939
20141
  const isEditRoute = pathname.endsWith("/edit") || pathname.split("/").pop() === "edit";
19940
- if (collection.defaultEntityAction === "view" && !isNew && !isCopy && entityId && !isEditRoute) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(EntityDetailView, {
20142
+ if (collection.defaultEntityAction === "view" && !isNew && !isCopy && entityId && !isEditRoute) return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(DetailViewBinding, {
19941
20143
  entityId,
19942
20144
  collection,
19943
20145
  layout: "full_screen",
@@ -19955,7 +20157,7 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
19955
20157
  parentCollectionSlugs,
19956
20158
  parentEntityIds
19957
20159
  }, collection.slug + "_view_" + entityId) });
19958
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(EntityEditView, {
20160
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(EditViewBinding, {
19959
20161
  entityId: isNew ? void 0 : entityId,
19960
20162
  collection,
19961
20163
  layout: "full_screen",
@@ -20011,8 +20213,8 @@ function CustomViewRoute({ view }) {
20011
20213
  }
20012
20214
  //#endregion
20013
20215
  //#region src/components/CollectionEditorDialogs.tsx
20014
- var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-BO_aQ-Z4.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
20015
- var PropertyFormDialog = lazy(() => import("./PropertyEditView-DKzOpMjR.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
20216
+ var CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-DbPpDDwb.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
20217
+ var PropertyFormDialog = lazy(() => import("./PropertyEditView-DfJbZ67t.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
20016
20218
  /**
20017
20219
  * Renders the CollectionEditorDialog and PropertyFormDialog inside
20018
20220
  * the RebaseShell tree where CMS-internal contexts
@@ -20206,7 +20408,7 @@ function RebaseShell(props) {
20206
20408
  * @group Components
20207
20409
  */
20208
20410
  function CollectionPanelInner({ mergedCollection, path, title, updateUrl, className }) {
20209
- const ResolvedCollectionView = useComponentOverride("Collection.View", EntityCollectionView);
20411
+ const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
20210
20412
  return /* @__PURE__ */ jsxs("div", {
20211
20413
  className,
20212
20414
  children: [title !== false && /* @__PURE__ */ jsx(Typography, {
@@ -20255,15 +20457,13 @@ function CollectionPanel(props) {
20255
20457
  ]
20256
20458
  })
20257
20459
  });
20258
- const content = /* @__PURE__ */ jsx(CollectionPanelInner, {
20259
- ...props,
20260
- mergedCollection
20261
- });
20262
- if (mergedCollection.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
20263
- overrides: mergedCollection.components,
20264
- children: content
20460
+ return /* @__PURE__ */ jsx(CollectionScopeProvider, {
20461
+ collection: mergedCollection,
20462
+ children: /* @__PURE__ */ jsx(CollectionPanelInner, {
20463
+ ...props,
20464
+ mergedCollection
20465
+ })
20265
20466
  });
20266
- return content;
20267
20467
  }
20268
20468
  //#endregion
20269
20469
  //#region src/preview/components/RelationPreview.tsx
@@ -20358,17 +20558,17 @@ function RelationPreviewInternal(props) {
20358
20558
  ...props,
20359
20559
  collection
20360
20560
  });
20361
- if (collection?.components) return /* @__PURE__ */ jsx(CollectionComponentOverrideProvider, {
20362
- overrides: collection.components,
20561
+ if (collection) return /* @__PURE__ */ jsx(CollectionScopeProvider, {
20562
+ collection,
20363
20563
  children: content
20364
20564
  });
20365
20565
  return content;
20366
20566
  }
20367
20567
  function RelationPreviewExisting({ relation, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover, textOnly }) {
20368
20568
  const passedEntity = relation.data;
20369
- const ResolvedEntityPreview = useComponentOverride("Entity.Preview", EntityPreview);
20569
+ const ResolvedEntityPreview = useComponentOverride("EntityPreview", EntityPreviewBinding);
20370
20570
  const customizationController = useCustomizationController();
20371
- const { entity, dataLoading, dataLoadingError } = useEntityFetch({
20571
+ const { entity, dataLoading, dataLoadingError } = useFetch({
20372
20572
  path: relation.path,
20373
20573
  entityId: passedEntity ? void 0 : relation.id,
20374
20574
  collection,
@@ -21418,7 +21618,7 @@ function zodToFormErrors(zodError) {
21418
21618
  /**
21419
21619
  * Headless entity form component.
21420
21620
  *
21421
- * Renders a form for an entity collection without any CMS or backend dependencies.
21621
+ * Renders a form for a entity collection without any CMS or backend dependencies.
21422
21622
  * All backend concerns (save, caching, analytics, plugin slots) are provided via
21423
21623
  * callback props. For CMS-connected usage, use {@link EntityFormBinding} instead.
21424
21624
  *
@@ -21870,7 +22070,7 @@ function useOnAutoSave(autoSave, formex, lastSavedValues, save) {
21870
22070
  */
21871
22071
  function EntityFormBinding({ path, entityId: entityIdProp, collection, entity, initialStatus, onSaved, onValuesModified, onEntityChange, onStatusChange, openEntityMode = "full_screen", navigateBack: navigateBackProp, initialDirtyValues, ...restProps }) {
21872
22072
  const { t } = useTranslation();
21873
- const sideEntityController = useSideEntityController();
22073
+ const sidePanelController = useSidePanel();
21874
22074
  const collectionRegistryController = useCollectionRegistryController();
21875
22075
  const authController = useAuthController();
21876
22076
  const dataClient = useData();
@@ -21924,12 +22124,12 @@ function EntityFormBinding({ path, entityId: entityIdProp, collection, entity, i
21924
22124
  navigateBackProp();
21925
22125
  return;
21926
22126
  }
21927
- if (openEntityMode === "side_panel" || openEntityMode === "dialog") sideEntityController.close();
22127
+ if (openEntityMode === "side_panel" || openEntityMode === "dialog") sidePanelController.close();
21928
22128
  else window.history.back();
21929
22129
  }, [
21930
22130
  navigateBackProp,
21931
22131
  openEntityMode,
21932
- sideEntityController
22132
+ sidePanelController
21933
22133
  ]);
21934
22134
  const clearDirtyCache = useCallback(() => {
21935
22135
  if (status === "new" || status === "copy") {
@@ -22180,22 +22380,16 @@ function normalizeEnumValueConfig(config) {
22180
22380
  * entity-aware data layer to the headless collection view.
22181
22381
  */
22182
22382
  /**
22183
- * Flatten Entity<M> objects to plain row objects.
22184
- * The headless view works with flat `Record<string, unknown>` rows,
22185
- * while the entity system uses `{ id, path, values: M }`.
22186
- *
22187
- * The flattened row includes `id` and `path` at the top level,
22188
- * plus all values spread.
22383
+ * Unwrap `Entity<M>` objects to flat rows for the headless view.
22384
+ * The entity system uses `{ id, path, values: M }`; `values` is already the
22385
+ * flat row `M` carrying its real primary key, so unwrapping is just `.values` —
22386
+ * no `id`/`path` merge (those are view-model metadata, not row columns).
22189
22387
  */
22190
22388
  function flattenEntities(entities) {
22191
- return entities.map((entity) => ({
22192
- id: entity.id,
22193
- path: entity.path,
22194
- ...entity.values
22195
- }));
22389
+ return entities.map((entity) => entity.values);
22196
22390
  }
22197
22391
  /**
22198
- * React hook that adapts an EntityTableController to a CollectionDataController.
22392
+ * React hook that adapts a EntityTableController to a CollectionDataController.
22199
22393
  *
22200
22394
  * Usage:
22201
22395
  * ```tsx
@@ -22503,7 +22697,7 @@ function ImportDataPreview({ importConfig, properties, propertiesOrder }) {
22503
22697
  importConfig.setEntities(mappedData);
22504
22698
  }, []);
22505
22699
  const selectionController = useSelectionController();
22506
- return /* @__PURE__ */ jsx(EntityCollectionTable, {
22700
+ return /* @__PURE__ */ jsx(CollectionTableBinding, {
22507
22701
  title: /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Typography, {
22508
22702
  variant: "subtitle2",
22509
22703
  children: "Imported data preview"
@@ -23112,7 +23306,7 @@ function serializeMatches(matches) {
23112
23306
  }
23113
23307
  /**
23114
23308
  * Resolve a relation target to a string slug.
23115
- * Functions are called to extract the target; EntityCollection objects
23309
+ * Functions are called to extract the target; CollectionConfig objects
23116
23310
  * use their slug.
23117
23311
  */
23118
23312
  function resolveRelationTarget(target) {
@@ -23327,14 +23521,14 @@ function toSerializableProperties(properties) {
23327
23521
  return result;
23328
23522
  }
23329
23523
  /**
23330
- * Convert an `EntityCollection` to its JSON-serializable form.
23524
+ * Convert an `CollectionConfig` to its JSON-serializable form.
23331
23525
  *
23332
23526
  * Strips all non-serializable fields (functions, React nodes, class instances)
23333
23527
  * while preserving the structural schema that the collection editor works with.
23334
23528
  *
23335
23529
  * The result is safe for `JSON.stringify()` and database storage.
23336
23530
  */
23337
- function toSerializableCollection(collection) {
23531
+ function toSerializableCollectionConfig(collection) {
23338
23532
  const result = {
23339
23533
  slug: collection.slug,
23340
23534
  name: collection.name,
@@ -23439,13 +23633,13 @@ function fromSerializableProperties(serialized) {
23439
23633
  return result;
23440
23634
  }
23441
23635
  /**
23442
- * Convert a `SerializableCollection` back to an `EntityCollection`.
23636
+ * Convert a `SerializableCollectionConfig` back to an `CollectionConfig`.
23443
23637
  *
23444
23638
  * The result will NOT contain any of the non-serializable fields
23445
23639
  * (callbacks, entityActions, etc.) — those must be re-attached by the
23446
23640
  * consumer if needed.
23447
23641
  */
23448
- function fromSerializableCollection(serialized) {
23642
+ function fromSerializableCollectionConfig(serialized) {
23449
23643
  const { properties, ...rest } = serialized;
23450
23644
  return {
23451
23645
  ...rest,
@@ -23486,7 +23680,7 @@ function useJsonCollectionsConfigController({ store, readOnly = false, autoLoad
23486
23680
  try {
23487
23681
  const [serialized, navEntries] = await Promise.all([storeRef.current.load(), storeRef.current.loadNavigationEntries?.() ?? Promise.resolve([])]);
23488
23682
  if (cancelled) return;
23489
- setCollections(serialized.map(fromSerializableCollection));
23683
+ setCollections(serialized.map(fromSerializableCollectionConfig));
23490
23684
  setNavigationEntries(navEntries);
23491
23685
  } catch (e) {
23492
23686
  console.error("useJsonCollectionsConfigController: failed to load collections", e);
@@ -23502,7 +23696,7 @@ function useJsonCollectionsConfigController({ store, readOnly = false, autoLoad
23502
23696
  * Update local state and persist a collection to the store.
23503
23697
  */
23504
23698
  const persistCollection = useCallback(async (collection) => {
23505
- const serializable = toSerializableCollection(collection);
23699
+ const serializable = toSerializableCollectionConfig(collection);
23506
23700
  await storeRef.current.save(collection.slug, serializable);
23507
23701
  }, []);
23508
23702
  /**
@@ -23938,15 +24132,15 @@ var DEFAULT_COLLECTION_GENERATION_ENDPOINT = "https://api.rebase.pro/collections
23938
24132
  *
23939
24133
  * @example
23940
24134
  * ```tsx
23941
- * import { RebaseCMS } from "@rebasepro/admin";
24135
+ * import { RebaseAdmin } from "@rebasepro/admin";
23942
24136
  * import { buildCollectionGenerationCallback } from "@rebasepro/admin/collection_editor";
23943
- * import { useFirebaseAuthController } from "@rebasepro/client-firebase";
24137
+ * import { useFirebaseAuthController } from "@rebasepro/firebase";
23944
24138
  *
23945
24139
  * const authController = useFirebaseAuthController({ firebaseApp });
23946
24140
  *
23947
24141
  * export function App() {
23948
24142
  * return (
23949
- * <RebaseCMS
24143
+ * <RebaseAdmin
23950
24144
  * collectionEditor={{
23951
24145
  * generateCollection: buildCollectionGenerationCallback({
23952
24146
  * getAuthToken: authController.getAuthToken
@@ -24027,6 +24221,6 @@ function getFullIdPath(propertyKey, propertyNamespace) {
24027
24221
  return idToPropertiesPath(propertyNamespace ? `${propertyNamespace}.${propertyKey}` : propertyKey);
24028
24222
  }
24029
24223
  //#endregion
24030
- export { RelationPreview as $, SelectableTable as $n, BlockFieldBinding as $t, useCollectionDataController as A, removeInitialAndTrailingSlashes$1 as An, renderSkeletonIcon as Ar, useImportConfig as At, ArrayOfMapsPreview as B, useUrlController as Bn, getFieldId as Bt, downloadEntitiesExport as C, editEntityAction as Cn, ArrayPropertyPreview as Cr, useCollectionEditorController as Ct, ImportDataPreview as D, getCollectionBySlugWithin as Dn, StorageThumbnailInternal as Dr, flattenEntry as Dt, ImportCollectionAction as E, addInitialSlash as En, StorageThumbnail as Er, convertDataToEntity as Et, extractTouchedValues as F, useEntityHistory as Fn, ImagePreview as Fr, PropertyConfigBadge as Ft, DatePreview as G, useSideDialogsController as Gn, SelectFieldBinding as Gt, UserPreview as H, useNavigationStateController as Hn, TextFieldBinding as Ht, getChanges as I, resolveNavigationFrom as In, EmptyValue as Ir, DEFAULT_FIELD_CONFIGS as It, ArrayOneOfPreview as J, useBuildSideEntityController as Jn, MultiSelectFieldBinding as Jt, KeyValuePreview as K, buildSidePanelsFromUrl as Kn, RepeatFieldBinding as Kt, getInitialEntityValues as L, useResolvedNavigationFrom as Ln, getDefaultFieldConfig as Lt, mapPropertyToConfig as M, removeTrailingSlash as Mn, renderSkeletonText as Mr, ImportFileUpload as Mt, EntityFormBinding as N, resolveCollectionPathIds$1 as Nn, UrlComponentPreview as Nr, convertFileToJson as Nt, PropertySelectEntry as O, getCollectionPathsCombinations as On, SkeletonPropertyComponent as Or, processValueMapping as Ot, EntityForm as P, useBuildCollectionRegistryController as Pn, sanitizeUrl as Pr, unflattenObject as Pt, ArrayOfStorageComponentsPreview as Q, EntityCollectionTable as Qn, DateTimeFieldBinding as Qt, removeEmptyContainers as R, useCMSContext as Rn, getDefaultFieldId as Rt, downloadDataAsCsv as S, deleteEntityAction as Sn, isRelationProperty as Sr, EntityCollectionViewActions as St, getEntityJsonExportableData as T, CreationResultDialog as Tn, EnumValuesChip as Tr, DataNewPropertiesMapping as Tt, NumberPropertyPreview as U, CollectionRegistryContext as Un, SwitchFieldBinding as Ut, PropertyPreview as V, NavigationStateContext as Vn, VectorFieldBinding as Vt, BooleanPreview as W, useCollectionRegistryController as Wn, StorageUploadFieldBinding as Wt, ArrayPropertyEnumPreview as X, useSelectionController as Xn, MapFieldBinding as Xt, ArrayOfStringsPreview as Y, mergeEntityActions as Yn, MarkdownEditorFieldBinding as Yt, ArrayEnumPreview as Z, VirtualTableInput$1 as Zn, KeyValueFieldBinding as Zt, toSerializableProperty as _, useBuildNavigationStateController as _n, getIconForWidget as _r, SideEntityProvider as _t, namespaceToPropertiesPath as a, FormLayout as an, useEntitySelectionDialog as ar, RebaseLayout as at, BasicExportAction as b, useResolvedCollections as bn, getResolvedPropertyInPath as br, EntityCollectionCardView as bt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as c, PropertyIdCopyTooltip as cn, EntityView as cr, RebaseAuthGate as ct, useJsonCollectionsConfigController as d, SearchIconsView as dn, EntityPreview as dr, Drawer as dt, ArrayOfReferencesFieldBinding as en, EntityCollectionRowActions as er, CollectionPanel as et, fromSerializableCollection as f, FieldCaption as fn, getEntityPreviewKeys as fr, DefaultDrawer as ft, toSerializableProperties as g, useBuildUrlController as gn, getIconForProperty as gr, AdminModeSyncer as gt, toSerializableCollection as h, useBreadcrumbsController as hn, getDefaultPropertiesOrder as hr, useApp as ht, namespaceToPropertiesOrderPath as i, ReadOnlyFieldBinding as in, useSideEntityController as ir, RebaseRoute as it, mapPropertiesToConfigs as j, removeInitialSlash as jn, renderSkeletonImageThumbnail as jr, ImportSaveInProgress as jt, createStaticDataController as k, getLastSegment$1 as kn, renderSkeletonCaptionText as kr, getInferenceType as kt, buildCollectionGenerationCallback as l, LabelWithIcon as ln, ArrayOfReferencesPreview as lr, RebaseCMS as lt, fromSerializableProperty as m, SideDialogs as mn, getBracketNotation as mr, AppBar as mt, getFullIdPath as n, ArrayCustomShapedFieldBinding as nn, SelectableTableContext as nr, RebaseRouteDefs as nt, MissingReferenceWidget as o, FormEntry as on, resolveEntityAction as or, RebaseNavigation as ot, fromSerializableProperties as p, EntitySelectionTable as pn, getEntityTitlePropertyKey as pr, DrawerFooterActions as pt, MapPropertyPreview as q, getEntityViewWidth as qn, ReferenceFieldBinding as qt, idToPropertiesPath as r, PropertyFieldBinding as rn, SideEntityControllerContext as rr, CustomViewRoute as rt, CollectionGenerationApiError as s, LabelWithIconAndTooltip as sn, resolveEntityView as sr, useLocalCollectionsConfigController as st, getFullId as t, ArrayContainer as tn, useClearRestoreValue as tr, RebaseShell as tt, validateCollectionJson as u, FieldHelperText as un, ReferencePreview as ur, Scaffold as ut, useCollectionsConfigController as v, useTopLevelNavigation as vn, getPropertiesWithPropertiesOrder as vr, ReferenceWidget as vt, getEntityCSVExportableData as w, resetPasswordAction as wn, StringPropertyPreview as wr, ImportNewPropertyFieldPreview as wt, downloadBlob as x, copyEntityAction as xn, isReferenceProperty as xr, EntityCard as xt, ExportCollectionAction as y, useResolvedViews as yn, getPropertyInPath as yr, EntityCollectionView as yt, zodToFormErrors as z, UrlContext as zn, getFieldConfig as zt };
24224
+ export { RelationPreview as $, SelectableTable as $n, BlockFieldBinding as $t, useCollectionDataController as A, removeInitialAndTrailingSlashes$1 as An, renderSkeletonIcon as Ar, useImportConfig as At, ArrayOfMapsPreview as B, useUrlController as Bn, getFieldId as Bt, downloadEntitiesExport as C, editEntityAction as Cn, ArrayPropertyPreview as Cr, useCollectionEditorController as Ct, ImportDataPreview as D, getCollectionBySlugWithin as Dn, StorageThumbnailInternal as Dr, flattenEntry as Dt, ImportCollectionAction as E, addInitialSlash as En, StorageThumbnail as Er, convertDataToEntity as Et, extractTouchedValues as F, useHistory as Fn, ImagePreview as Fr, PropertyConfigBadge as Ft, DatePreview as G, useSideDialogsController as Gn, SelectFieldBinding as Gt, UserPreview as H, useNavigationStateController as Hn, TextFieldBinding as Ht, getChanges as I, resolveNavigationFrom as In, EmptyValue as Ir, DEFAULT_FIELD_CONFIGS as It, ArrayOneOfPreview as J, useBuildSidePanel as Jn, MultiSelectFieldBinding as Jt, KeyValuePreview as K, buildSidePanelsFromUrl as Kn, RepeatFieldBinding as Kt, getInitialEntityValues as L, useResolvedNavigationFrom as Ln, getDefaultFieldConfig as Lt, mapPropertyToConfig as M, removeTrailingSlash as Mn, renderSkeletonText as Mr, ImportFileUpload as Mt, EntityFormBinding as N, resolveCollectionPathIds$1 as Nn, UrlComponentPreview as Nr, convertFileToJson as Nt, PropertySelectEntry as O, getCollectionPathsCombinations as On, SkeletonPropertyComponent as Or, processValueMapping as Ot, EntityForm as P, useBuildCollectionRegistryController as Pn, sanitizeUrl as Pr, unflattenObject as Pt, ArrayOfStorageComponentsPreview as Q, CollectionTableBinding as Qn, DateTimeFieldBinding as Qt, removeEmptyContainers as R, useCMSContext as Rn, getDefaultFieldId as Rt, downloadDataAsCsv as S, deleteEntityAction as Sn, isRelationProperty as Sr, CollectionViewActions as St, getEntityJsonExportableData as T, CreationResultDialog as Tn, EnumValuesChip as Tr, DataNewPropertiesMapping as Tt, NumberPropertyPreview as U, CollectionRegistryContext as Un, SwitchFieldBinding as Ut, PropertyPreview as V, NavigationStateContext as Vn, VectorFieldBinding as Vt, BooleanPreview as W, useCollectionRegistryController as Wn, StorageUploadFieldBinding as Wt, ArrayPropertyEnumPreview as X, useSelectionController as Xn, MapFieldBinding as Xt, ArrayOfStringsPreview as Y, mergeEntityActions as Yn, MarkdownEditorFieldBinding as Yt, ArrayEnumPreview as Z, VirtualTableInput$1 as Zn, KeyValueFieldBinding as Zt, toSerializableProperty as _, useBuildNavigationStateController as _n, getIconForWidget as _r, SidePanelProvider as _t, namespaceToPropertiesPath as a, FormLayout as an, useSelectionDialog as ar, RebaseLayout as at, BasicExportAction as b, useResolvedCollections as bn, getResolvedPropertyInPath as br, CollectionCardViewBinding as bt, DEFAULT_COLLECTION_GENERATION_ENDPOINT as c, PropertyIdCopyTooltip as cn, EntityViewBinding as cr, RebaseAuthGate as ct, useJsonCollectionsConfigController as d, SearchIconsView as dn, EntityPreviewBinding as dr, Drawer as dt, ArrayOfReferencesFieldBinding as en, CollectionRowActions as er, CollectionPanel as et, fromSerializableCollectionConfig as f, FieldCaption as fn, getEntityPreviewKeys as fr, DefaultDrawer as ft, toSerializableProperties as g, useBuildUrlController as gn, getIconForProperty as gr, AdminModeSyncer as gt, toSerializableCollectionConfig as h, useBreadcrumbsController as hn, getDefaultPropertiesOrder as hr, useApp as ht, namespaceToPropertiesOrderPath as i, ReadOnlyFieldBinding as in, useSidePanel as ir, RebaseRoute as it, mapPropertiesToConfigs as j, removeInitialSlash as jn, renderSkeletonImageThumbnail as jr, ImportSaveInProgress as jt, createStaticDataController as k, getLastSegment$1 as kn, renderSkeletonCaptionText as kr, getInferenceType as kt, buildCollectionGenerationCallback as l, LabelWithIcon as ln, ArrayOfReferencesPreview as lr, RebaseAdmin as lt, fromSerializableProperty as m, SideDialogs as mn, getBracketNotation as mr, AppBar as mt, getFullIdPath as n, ArrayCustomShapedFieldBinding as nn, SelectableTableContext as nr, RebaseRouteDefs as nt, MissingReferenceWidget as o, FormEntry as on, resolveEntityAction as or, RebaseNavigation as ot, fromSerializableProperties as p, SelectionTableBinding as pn, getEntityTitlePropertyKey as pr, DrawerFooterActions as pt, MapPropertyPreview as q, getEntityViewWidth as qn, ReferenceFieldBinding as qt, idToPropertiesPath as r, PropertyFieldBinding as rn, SidePanelControllerContext as rr, CustomViewRoute as rt, CollectionGenerationApiError as s, LabelWithIconAndTooltip as sn, resolveEntityView as sr, useLocalCollectionsConfigController as st, getFullId as t, ArrayContainer as tn, useClearRestoreValue as tr, RebaseShell as tt, validateCollectionJson as u, FieldHelperText as un, ReferencePreview as ur, Scaffold as ut, useCollectionsConfigController as v, useTopLevelNavigation as vn, getPropertiesWithPropertiesOrder as vr, ReferenceWidget as vt, getEntityCSVExportableData as w, resetPasswordAction as wn, StringPropertyPreview as wr, ImportNewPropertyFieldPreview as wt, downloadBlob as x, copyEntityAction as xn, isReferenceProperty as xr, EntityCardBinding as xt, ExportCollectionAction as y, useResolvedViews as yn, getPropertyInPath as yr, CollectionViewBinding as yt, zodToFormErrors as z, UrlContext as zn, getFieldConfig as zt };
24031
24225
 
24032
- //# sourceMappingURL=src-cxV1ODRG.js.map
24226
+ //# sourceMappingURL=src-B8WuGSPZ.js.map