@rebasepro/admin 0.1.0 → 0.2.1

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 (242) hide show
  1. package/LICENSE +21 -6
  2. package/dist/{CollectionEditorDialog-MbvXGzEq.js → CollectionEditorDialog-BXIh2AXg.js} +40 -31
  3. package/dist/CollectionEditorDialog-BXIh2AXg.js.map +1 -0
  4. package/dist/{CollectionsStudioView-D9X6aiAr.js → CollectionsStudioView-jR8iz_ja.js} +6 -8
  5. package/dist/CollectionsStudioView-jR8iz_ja.js.map +1 -0
  6. package/dist/{ContentHomePage-CfVB1eUo.js → ContentHomePage-BQZWuOFb.js} +5 -7
  7. package/dist/ContentHomePage-BQZWuOFb.js.map +1 -0
  8. package/dist/{ExportCollectionAction-CUwJg4F9.js → ExportCollectionAction-CMdiiv1L.js} +36 -38
  9. package/dist/ExportCollectionAction-CMdiiv1L.js.map +1 -0
  10. package/dist/{ImportCollectionAction-DGa_SF_8.js → ImportCollectionAction-C05lE0IW.js} +5 -7
  11. package/dist/ImportCollectionAction-C05lE0IW.js.map +1 -0
  12. package/dist/{PropertyEditView-C4nlYmAc.js → PropertyEditView-BB5xjnhZ.js} +261 -165
  13. package/dist/PropertyEditView-BB5xjnhZ.js.map +1 -0
  14. package/dist/{RolesView-CNWxnR8e.js → RolesView-CULIHWZ9.js} +22 -11
  15. package/dist/RolesView-CULIHWZ9.js.map +1 -0
  16. package/dist/{UsersView-YiTIcXkA.js → UsersView-D7_AtJ44.js} +7 -71
  17. package/dist/UsersView-D7_AtJ44.js.map +1 -0
  18. package/dist/collection_editor/ui/collection_editor/LayoutModeSwitch.d.ts +2 -2
  19. package/dist/collection_editor/ui/collection_editor/properties/VectorPropertyField.d.ts +3 -0
  20. package/dist/collection_editor_ui.js +5 -5
  21. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +1 -1
  22. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
  23. package/dist/components/EntityCollectionView/EntityCollectionListView.d.ts +18 -2
  24. package/dist/components/EntityCollectionView/FilterPresetsButton.d.ts +21 -0
  25. package/dist/components/EntityDetailView.d.ts +31 -0
  26. package/dist/components/EntityEditView.d.ts +3 -2
  27. package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +1 -1
  28. package/dist/components/admin/CreationResultDialog.d.ts +5 -0
  29. package/dist/components/admin/RolesFilterSelect.d.ts +2 -0
  30. package/dist/components/admin/UserRolesSelectField.d.ts +2 -0
  31. package/dist/components/common/default_entity_actions.d.ts +7 -1
  32. package/dist/components/field_configs.d.ts +1 -1
  33. package/dist/components/index.d.ts +1 -0
  34. package/dist/data_import/utils/data.d.ts +1 -1
  35. package/dist/data_import/utils/file_headers.d.ts +6 -1
  36. package/dist/data_import/utils/file_to_json.d.ts +1 -11
  37. package/dist/data_import/utils/transforms.d.ts +11 -0
  38. package/dist/editor.js +2 -4
  39. package/dist/editor.js.map +1 -1
  40. package/dist/form/EntityForm.d.ts +1 -1
  41. package/dist/form/field_bindings/RelationFieldBinding.d.ts +1 -1
  42. package/dist/form/field_bindings/VectorFieldBinding.d.ts +11 -0
  43. package/dist/form/index.d.ts +1 -0
  44. package/dist/hooks/navigation/useResolvedViews.d.ts +2 -1
  45. package/dist/{index-CtzpHzMQ.js → index-BAM9KCmM.js} +4 -6
  46. package/dist/index-BAM9KCmM.js.map +1 -0
  47. package/dist/{index-DKlrVD1m.js → index-CoSNm3e3.js} +3 -3
  48. package/dist/index-CoSNm3e3.js.map +1 -0
  49. package/dist/{index-kHJXfLNI.js → index-D5OQhv-T.js} +3 -3
  50. package/dist/index-D5OQhv-T.js.map +1 -0
  51. package/dist/index.d.ts +4 -1
  52. package/dist/index.js +352 -148
  53. package/dist/index.js.map +1 -1
  54. package/dist/types/components/EntityFormActionsProps.d.ts +1 -1
  55. package/dist/types/components/EntityFormProps.d.ts +2 -1
  56. package/dist/types/fields.d.ts +3 -3
  57. package/dist/util/navigation_utils.d.ts +1 -1
  58. package/dist/{util-CwLmSpGp.js → util-DtbWD7LF.js} +5312 -2580
  59. package/dist/util-DtbWD7LF.js.map +1 -0
  60. package/package.json +45 -39
  61. package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
  62. package/src/collection_editor/ui/AddKanbanColumnAction.tsx +12 -2
  63. package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +1 -2
  64. package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -2
  65. package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -2
  66. package/src/collection_editor/ui/EditorEntityAction.tsx +1 -2
  67. package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +1 -2
  68. package/src/collection_editor/ui/NewCollectionButton.tsx +1 -2
  69. package/src/collection_editor/ui/NewCollectionCard.tsx +4 -6
  70. package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +1 -2
  71. package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +10 -2
  72. package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +18 -2
  73. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +22 -7
  74. package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +16 -2
  75. package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +19 -9
  76. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +13 -2
  77. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +24 -2
  78. package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +22 -3
  79. package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +1 -2
  80. package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +11 -2
  81. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +12 -2
  82. package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +16 -3
  83. package/src/collection_editor/ui/collection_editor/EnumForm.tsx +17 -2
  84. package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +18 -2
  85. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -2
  86. package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +1 -2
  87. package/src/collection_editor/ui/collection_editor/LayoutModeSwitch.tsx +17 -5
  88. package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +32 -6
  89. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +7 -7
  90. package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +14 -2
  91. package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +16 -2
  92. package/src/collection_editor/ui/collection_editor/ViewModeSwitch.tsx +9 -2
  93. package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +1 -2
  94. package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +1 -2
  95. package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +9 -2
  96. package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +11 -2
  97. package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +34 -0
  98. package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +15 -7
  99. package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +1 -2
  100. package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +15 -3
  101. package/src/collection_editor/ui/collection_editor/properties/conditions/property_paths.ts +1 -1
  102. package/src/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.tsx +1 -2
  103. package/src/collection_editor/useLocalCollectionsConfigController.tsx +0 -2
  104. package/src/collection_editor/validateCollectionJson.ts +9 -9
  105. package/src/components/AdminModeSyncer.tsx +1 -1
  106. package/src/components/ArrayContainer.tsx +19 -15
  107. package/src/components/ClearFilterSortButton.tsx +1 -2
  108. package/src/components/CollectionEditorDialogs.tsx +1 -1
  109. package/src/components/DefaultAppBar.tsx +15 -3
  110. package/src/components/DefaultDrawer.tsx +3 -3
  111. package/src/components/DrawerNavigationGroup.tsx +1 -2
  112. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +19 -9
  113. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
  114. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
  115. package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +1 -2
  116. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -2
  117. package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +1 -2
  118. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +1 -2
  119. package/src/components/EntityCollectionTable/fields/VirtualTableSelect.tsx +0 -1
  120. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +15 -27
  121. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +3 -4
  122. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -2
  123. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -5
  124. package/src/components/EntityCollectionTable/table_bindings.tsx +51 -45
  125. package/src/components/EntityCollectionView/Board.tsx +1 -2
  126. package/src/components/EntityCollectionView/BoardColumn.tsx +9 -2
  127. package/src/components/EntityCollectionView/BoardColumnTitle.tsx +5 -4
  128. package/src/components/EntityCollectionView/EntityCard.tsx +2 -2
  129. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +18 -16
  130. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +16 -17
  131. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +90 -21
  132. package/src/components/EntityCollectionView/EntityCollectionView.tsx +20 -11
  133. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -7
  134. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +14 -5
  135. package/src/components/EntityCollectionView/FilterPresetsButton.tsx +292 -0
  136. package/src/components/EntityCollectionView/FiltersDialog.tsx +1 -2
  137. package/src/components/EntityCollectionView/SplitListView.tsx +76 -25
  138. package/src/components/EntityCollectionView/ViewModeToggle.tsx +20 -7
  139. package/src/components/EntityCollectionView/hooks/useKanbanDragAndDrop.ts +1 -1
  140. package/src/components/EntityCollectionView/useBoardDataController.tsx +74 -6
  141. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +1 -1
  142. package/src/components/EntityDetailView.tsx +619 -0
  143. package/src/components/EntityEditView.tsx +29 -10
  144. package/src/components/EntityEditViewFormActions.tsx +20 -7
  145. package/src/components/EntityPreview.tsx +14 -5
  146. package/src/components/EntitySidePanel.tsx +116 -62
  147. package/src/components/EntityView.tsx +1 -2
  148. package/src/components/HomePage/ContentHomePage.tsx +1 -1
  149. package/src/components/HomePage/FavouritesView.tsx +1 -2
  150. package/src/components/HomePage/NavigationCard.tsx +1 -2
  151. package/src/components/HomePage/NavigationCardBinding.tsx +1 -2
  152. package/src/components/HomePage/NavigationGroup.tsx +1 -2
  153. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  154. package/src/components/PropertyIdCopyTooltip.tsx +1 -2
  155. package/src/components/RebaseAuthGate.tsx +2 -2
  156. package/src/components/RebaseNavigation.tsx +9 -7
  157. package/src/components/ReferenceTable/EntitySelectionTable.tsx +12 -8
  158. package/src/components/RelationSelector.tsx +34 -6
  159. package/src/components/SearchIconsView.tsx +10 -2
  160. package/src/components/SelectableTable/SelectableTable.tsx +4 -4
  161. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +1 -2
  162. package/src/components/SideDialogs.tsx +63 -38
  163. package/src/components/UserSelector.tsx +30 -6
  164. package/src/components/admin/CreationResultDialog.tsx +135 -0
  165. package/src/components/admin/RolesFilterSelect.tsx +45 -0
  166. package/src/components/admin/RolesView.tsx +53 -14
  167. package/src/components/admin/UserRolesSelectField.tsx +50 -0
  168. package/src/components/admin/UsersView.tsx +41 -124
  169. package/src/components/app/Scaffold.tsx +1 -2
  170. package/src/components/common/default_entity_actions.tsx +119 -12
  171. package/src/components/field_configs.tsx +39 -3
  172. package/src/components/history/EntityHistoryEntry.tsx +1 -2
  173. package/src/components/history/EntityHistoryView.tsx +1 -2
  174. package/src/components/index.ts +2 -0
  175. package/src/data_export/export/BasicExportAction.tsx +35 -38
  176. package/src/data_export/export/ExportCollectionAction.tsx +39 -40
  177. package/src/data_import/components/DataNewPropertiesMapping.tsx +15 -2
  178. package/src/data_import/components/ImportFileUpload.tsx +1 -2
  179. package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +1 -2
  180. package/src/data_import/import/ImportCollectionAction.tsx +21 -8
  181. package/src/data_import/utils/data.ts +23 -5
  182. package/src/data_import/utils/file_headers.ts +13 -89
  183. package/src/data_import/utils/file_to_json.ts +43 -68
  184. package/src/data_import/utils/transforms.ts +47 -0
  185. package/src/editor/components/SlashCommandMenu.tsx +17 -2
  186. package/src/editor/components/editor-bubble-item.tsx +1 -1
  187. package/src/editor/extensions/Image/index.ts +1 -1
  188. package/src/editor/extensions/Image.ts +1 -1
  189. package/src/editor/selectors/color-selector.tsx +1 -2
  190. package/src/editor/selectors/link-selector.tsx +1 -2
  191. package/src/editor/selectors/node-selector.tsx +16 -2
  192. package/src/editor/selectors/text-buttons.tsx +1 -2
  193. package/src/editor/utils/prosemirror-utils.ts +1 -1
  194. package/src/form/EntityForm.tsx +16 -6
  195. package/src/form/EntityFormActions.tsx +11 -3
  196. package/src/form/PropertyFieldBinding.tsx +5 -12
  197. package/src/form/components/FieldHelperText.tsx +1 -2
  198. package/src/form/components/LocalChangesMenu.tsx +17 -2
  199. package/src/form/components/StorageItemPreview.tsx +1 -2
  200. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -2
  201. package/src/form/field_bindings/KeyValueFieldBinding.tsx +17 -2
  202. package/src/form/field_bindings/MapFieldBinding.tsx +1 -1
  203. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +10 -3
  204. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -2
  205. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +1 -2
  206. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +7 -7
  207. package/src/form/field_bindings/RelationFieldBinding.tsx +150 -147
  208. package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -1
  209. package/src/form/field_bindings/SelectFieldBinding.tsx +1 -2
  210. package/src/form/field_bindings/TextFieldBinding.tsx +10 -2
  211. package/src/form/field_bindings/VectorFieldBinding.tsx +202 -0
  212. package/src/form/index.tsx +1 -0
  213. package/src/form/validation.ts +54 -2
  214. package/src/hooks/navigation/useBuildNavigationStateController.tsx +2 -1
  215. package/src/hooks/navigation/useResolvedViews.tsx +30 -15
  216. package/src/hooks/navigation/useTopLevelNavigation.ts +1 -1
  217. package/src/index.ts +6 -0
  218. package/src/preview/PropertyPreview.tsx +1 -1
  219. package/src/preview/components/ImagePreview.tsx +1 -1
  220. package/src/preview/components/UrlComponentPreview.tsx +1 -2
  221. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -2
  222. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +23 -24
  223. package/src/routes/RebaseRoute.tsx +64 -35
  224. package/src/types/components/EntityFormActionsProps.tsx +1 -1
  225. package/src/types/components/EntityFormProps.tsx +3 -1
  226. package/src/types/fields.tsx +4 -3
  227. package/src/util/navigation_utils.ts +4 -3
  228. package/src/util/previews.ts +1 -1
  229. package/src/util/property_utils.tsx +22 -6
  230. package/src/util/resolutions.ts +2 -2
  231. package/dist/CollectionEditorDialog-MbvXGzEq.js.map +0 -1
  232. package/dist/CollectionsStudioView-D9X6aiAr.js.map +0 -1
  233. package/dist/ContentHomePage-CfVB1eUo.js.map +0 -1
  234. package/dist/ExportCollectionAction-CUwJg4F9.js.map +0 -1
  235. package/dist/ImportCollectionAction-DGa_SF_8.js.map +0 -1
  236. package/dist/PropertyEditView-C4nlYmAc.js.map +0 -1
  237. package/dist/RolesView-CNWxnR8e.js.map +0 -1
  238. package/dist/UsersView-YiTIcXkA.js.map +0 -1
  239. package/dist/index-CtzpHzMQ.js.map +0 -1
  240. package/dist/index-DKlrVD1m.js.map +0 -1
  241. package/dist/index-kHJXfLNI.js.map +0 -1
  242. package/dist/util-CwLmSpGp.js.map +0 -1
@@ -7,7 +7,21 @@ import { PluginProviderStack, resolveComponentRef } from "@rebasepro/core";
7
7
 
8
8
  import { EntityCollectionView, EntityView } from "../components";
9
9
  import { CircularProgressCenter, iconSize } from "@rebasepro/ui";
10
- import { CodeIcon, HistoryIcon, Maximize2Icon } from "lucide-react";
10
+ import {
11
+ CenteredView,
12
+ CircularProgress,
13
+ cls,
14
+ CodeIcon,
15
+ defaultBorderMixin,
16
+ HistoryIcon,
17
+ IconButton,
18
+ Maximize2Icon,
19
+ Skeleton,
20
+ Tab,
21
+ Tabs,
22
+ Tooltip,
23
+ Typography
24
+ } from "@rebasepro/ui";
11
25
  import { ErrorBoundary } from "@rebasepro/ui";
12
26
  import { ErrorView } from "@rebasepro/core";
13
27
  import {
@@ -16,7 +30,6 @@ import {
16
30
  resolveDefaultSelectedView
17
31
  } from "@rebasepro/common";
18
32
  import { resolvedSelectedEntityView } from "../util/resolutions";
19
- import { CenteredView, CircularProgress, cls, defaultBorderMixin, IconButton, Tab, Tabs, Tooltip, Typography, Skeleton } from "@rebasepro/ui";
20
33
  import {
21
34
  useCustomizationController,
22
35
  useEntityFetch,
@@ -69,7 +82,8 @@ export interface EntityEditViewProps<M extends Record<string, unknown> = Record<
69
82
  onValuesModified?: (modified: boolean, values: M) => void;
70
83
  onSaved?: (params: OnUpdateParams) => void;
71
84
  onTabChange?: (props: OnTabChangeParams<M>) => void;
72
- layout?: "side_panel" | "full_screen" | "split";
85
+ navigateBack?: () => void;
86
+ layout?: "side_panel" | "full_screen" | "split" | "dialog";
73
87
  barActions?: (params: BarActionsParams) => any;
74
88
  formProps?: Partial<EntityFormProps<M>>,
75
89
  /**
@@ -152,6 +166,7 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
152
166
  onValuesModified,
153
167
  onSaved,
154
168
  onTabChange,
169
+ navigateBack,
155
170
  entity,
156
171
  initialDirtyValues,
157
172
  dataLoading,
@@ -209,9 +224,11 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
209
224
  }
210
225
  ), [collection, status, entityId]);
211
226
 
212
- const [selectedTab, setSelectedTab] = useState<string>(selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE);
227
+ const [selectedTab, setSelectedTab] = useState<string>(
228
+ selectedTabProp === "edit" ? MAIN_TAB_VALUE : (selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE)
229
+ );
213
230
  useEffect(() => {
214
- const target = selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
231
+ const target = selectedTabProp === "edit" ? MAIN_TAB_VALUE : (selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE);
215
232
  if (target !== selectedTab) {
216
233
  setSelectedTab(target);
217
234
  }
@@ -231,7 +248,7 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
231
248
  selectedSecondaryForm
232
249
  } = resolvedSelectedEntityView(customViews, customizationController, selectedTab, canEdit);
233
250
 
234
- const actionsAtTheBottom = layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
251
+ const actionsAtTheBottom = layout === "side_panel" || layout === "dialog" || selectedEntityView?.includeActions === "bottom";
235
252
 
236
253
  const mainViewVisible = selectedTab === MAIN_TAB_VALUE || Boolean(selectedSecondaryForm);
237
254
 
@@ -310,7 +327,7 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
310
327
  parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
311
328
  entity={usedEntity}
312
329
  modifiedValues={usedFormContext?.formex?.values ?? usedEntity?.values}
313
- formContext={usedFormContext as unknown as FormContext<Record<string, unknown>>}
330
+ formContext={usedFormContext as FormContext<Record<string, unknown>>}
314
331
  />}
315
332
  </Suspense>
316
333
  </ErrorBoundary>
@@ -424,6 +441,7 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
424
441
  className={cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className)}
425
442
  EntityFormActionsComponent={EntityEditViewFormActions}
426
443
  disabled={!canEdit}
444
+ navigateBack={navigateBack}
427
445
  {...formProps}
428
446
  onEntityChange={(entity) => {
429
447
  setUsedEntity(entity);
@@ -476,14 +494,15 @@ export function EntityEditViewInner<M extends Record<string, unknown>>({
476
494
  </Tab>
477
495
  );
478
496
 
479
- const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews || layout === "side_panel";
497
+ const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews || layout === "side_panel" || layout === "dialog";
480
498
 
481
- const fullScreenButton = !barActions && (layout === "side_panel" || layout === "split") && entityId ? (
499
+ const fullScreenButton = !barActions && (layout === "side_panel" || layout === "split" || layout === "dialog") && entityId ? (
482
500
  <Tooltip title={"Open full screen"}>
483
501
  <IconButton
484
502
  size="small"
485
503
  onClick={() => {
486
- const entityUrl = urlController.buildUrlCollectionPath(`${path}/${entityId}`);
504
+ const editSuffix = collection.defaultEntityAction === "view" ? "/edit" : "";
505
+ const entityUrl = urlController.buildUrlCollectionPath(`${path}/${entityId}${editSuffix}`);
487
506
  navigate(`${entityUrl}#full`);
488
507
  }}
489
508
  >
@@ -9,8 +9,7 @@ import { copyEntityAction, deleteEntityAction } from "../components";
9
9
  import { mergeEntityActions } from "../util/entity_actions";
10
10
  import { resolveEntityAction } from "../util/resolutions";
11
11
  import { Button, CircularProgress, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Tooltip, Typography } from "@rebasepro/ui";
12
- import { AlertCircleIcon } from "lucide-react";
13
- import { iconSize } from "@rebasepro/ui";
12
+ import { AlertCircleIcon, iconSize } from "@rebasepro/ui";
14
13
  import {
15
14
  useCustomizationController,
16
15
  useSnackbarController,
@@ -51,15 +50,16 @@ export function EntityEditViewFormActions({
51
50
  .filter(Boolean) as EntityAction[];
52
51
  const createEnabled = canCreate(collection, path);
53
52
  const deleteEnabled = entity ? canDelete(collection, path, entity) : false;
53
+ const disableActions = collection.disableDefaultActions ?? [];
54
54
  const actions: EntityAction[] = [];
55
- if (createEnabled)
55
+ if (createEnabled && !disableActions.includes("copy"))
56
56
  actions.push(copyEntityAction);
57
- if (deleteEnabled)
57
+ if (deleteEnabled && !disableActions.includes("delete"))
58
58
  actions.push(deleteEntityAction);
59
59
  if (customEntityActions)
60
60
  return mergeEntityActions(actions, customEntityActions);
61
61
  return actions;
62
- }, [canCreate, canDelete, collection, path, customizationController.entityActions?.length, entity]);
62
+ }, [canCreate, canDelete, collection, path, customizationController.entityActions?.length, entity, collection.disableDefaultActions]);
63
63
 
64
64
  const formActions = showDefaultActions ? entityActions.filter(a => a.includeInForm === undefined || a.includeInForm) : [];
65
65
 
@@ -123,7 +123,7 @@ type ActionsViewProps<M extends Record<string, unknown>> = {
123
123
  status: "new" | "existing" | "copy",
124
124
  sideDialogContext: SideDialogController,
125
125
  pluginActions?: any[],
126
- openEntityMode: "side_panel" | "full_screen" | "split";
126
+ openEntityMode: "side_panel" | "full_screen" | "split" | "dialog";
127
127
  navigateBack: () => void;
128
128
  formContext: FormContext,
129
129
  formex: FormexController<any>;
@@ -151,7 +151,7 @@ function buildBottomActions<M extends Record<string, unknown>>({
151
151
  }: ActionsViewProps<M>) {
152
152
 
153
153
  const hasErrors = Object.keys(formex.errors).length > 0 && formex.submitCount > 0;
154
- const canClose = openEntityMode === "side_panel";
154
+ const canClose = openEntityMode === "side_panel" || openEntityMode === "dialog";
155
155
  return <DialogActions
156
156
  className={className}
157
157
  position={"absolute"}>
@@ -200,6 +200,14 @@ function buildBottomActions<M extends Record<string, unknown>>({
200
200
  type="reset">
201
201
  {status === "existing" ? t("discard") : t("clear")}
202
202
  </Button>
203
+ {collection.defaultEntityAction === "view" && status === "existing" && (
204
+ <Button variant="text"
205
+ color="primary"
206
+ disabled={disabled}
207
+ onClick={navigateBack}>
208
+ {t("back_to_detail") ?? "Back to details"}
209
+ </Button>
210
+ )}
203
211
  <Button variant={canClose ? "text" : "filled"}
204
212
  color="primary"
205
213
  type="submit"
@@ -265,6 +273,11 @@ function buildSideActions<M extends Record<string, unknown>>({
265
273
  <Button fullWidth={true} variant="text" disabled={disabled || formex.isSubmitting} type="reset">
266
274
  {status === "existing" ? t("discard") : t("clear")}
267
275
  </Button>
276
+ {collection.defaultEntityAction === "view" && status === "existing" && (
277
+ <Button fullWidth={true} variant="text" disabled={disabled} onClick={navigateBack}>
278
+ {t("back_to_detail") ?? "Back to details"}
279
+ </Button>
280
+ )}
268
281
 
269
282
  {pluginActions}
270
283
 
@@ -6,8 +6,15 @@ import { useEffect, useMemo } from "react";
6
6
  import { Entity } from "@rebasepro/types";
7
7
  import type { PreviewSize } from "../types/components/PropertyPreviewProps";
8
8
  import { getEntityImagePreviewPropertyKey } from "@rebasepro/common";
9
- import { cls, defaultBorderMixin, IconButton, Skeleton, Tooltip, Typography } from "@rebasepro/ui";
10
- import { ArrowRightToLineIcon } from "lucide-react";
9
+ import {
10
+ ArrowRightToLineIcon,
11
+ cls,
12
+ defaultBorderMixin,
13
+ IconButton,
14
+ Skeleton,
15
+ Tooltip,
16
+ Typography
17
+ } from "@rebasepro/ui";
11
18
  import { PropertyPreview, SkeletonPropertyComponent } from "../preview";
12
19
  import {
13
20
  useAuthController,
@@ -77,6 +84,11 @@ export function EntityPreviewData({
77
84
 
78
85
  const collection = collectionProp ?? collectionRegistryController.getCollection(entity.path);
79
86
 
87
+ const listProperties = useMemo(() => {
88
+ if (!collection) return [];
89
+ return previewKeys ?? getEntityPreviewKeys(authController, collection, customizationController.propertyConfigs, previewKeys, size === "medium" || size === "large" ? 3 : 2);
90
+ }, [previewKeys, collection, size, authController, customizationController.propertyConfigs]);
91
+
80
92
  if (!collection) {
81
93
  return (
82
94
  <>
@@ -85,9 +97,6 @@ export function EntityPreviewData({
85
97
  );
86
98
  }
87
99
 
88
- const listProperties = useMemo(() => previewKeys ?? getEntityPreviewKeys(authController, collection, customizationController.propertyConfigs, previewKeys, size === "medium" || size === "large" ? 3 : 2),
89
- [previewKeys, collection, size]);
90
-
91
100
  const titleProperty = includeTitle ? getEntityTitlePropertyKey(collection, customizationController.propertyConfigs) : undefined;
92
101
  const imagePropertyKey = includeImage ? getEntityImagePreviewPropertyKey(collection) : undefined;
93
102
  const imageProperty = imagePropertyKey ? collection.properties[imagePropertyKey] : undefined;
@@ -1,13 +1,13 @@
1
1
  import type { EntityCollection } from "@rebasepro/types";
2
2
  import type { EntitySidePanelProps } from "@rebasepro/types";
3
- import React, { useCallback, useEffect, useMemo } from "react";
3
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
4
4
 
5
5
  import type { OnUpdateParams } from "../types/components/EntityFormProps";
6
6
  import { ErrorBoundary } from "@rebasepro/ui";
7
- import { Maximize2Icon, XIcon } from "lucide-react";
7
+ import { IconButton, Maximize2Icon, XIcon } from "@rebasepro/ui";
8
8
  import { EntityEditView } from "./EntityEditView";
9
+ import { EntityDetailView } from "./EntityDetailView";
9
10
  import { useSideDialogContext } from "./SideDialogs";
10
- import { IconButton } from "@rebasepro/ui";
11
11
  import { useLocation, useNavigate } from "react-router-dom";
12
12
  import { removeInitialAndTrailingSlashes } from "@rebasepro/common";
13
13
  import { saveEntityToMemoryCache } from "@rebasepro/core";
@@ -28,6 +28,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
28
28
  allowFullScreen = true,
29
29
  path,
30
30
  entityId,
31
+ selectedTab,
31
32
  formProps
32
33
  } = props;
33
34
 
@@ -59,12 +60,13 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
59
60
  if (props.onUpdate) {
60
61
  props.onUpdate(params);
61
62
  }
63
+ setShowEditInPanel(false);
62
64
  if (params.status !== "existing") {
63
65
  sideEntityController.replace({
64
66
  path: params.path,
65
67
  entityId: params.entityId,
66
68
  selectedTab: params.selectedTab,
67
- updateUrl: true,
69
+ updateUrl: collection?.openEntityMode !== "dialog",
68
70
  collection: params.collection
69
71
  });
70
72
  }
@@ -86,6 +88,14 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
86
88
 
87
89
  const collection = collectionRegistryController.getCollection(path) ?? props.collection;
88
90
 
91
+ const [showEditInPanel, setShowEditInPanel] = useState(selectedTab === "edit");
92
+ const isDetailMode = collection?.defaultEntityAction === "view" && !showEditInPanel && Boolean(entityId);
93
+
94
+ // Reset edit mode when switching entities
95
+ useEffect(() => {
96
+ setShowEditInPanel(selectedTab === "edit");
97
+ }, [entityId, selectedTab]);
98
+
89
99
  // Note: beforeunload is handled by useUnsavedChangesDialog in SideDialogView,
90
100
  // which listens to the same `blocked` state via SideDialogContext.
91
101
 
@@ -103,64 +113,108 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
103
113
  return (
104
114
  <>
105
115
  <ErrorBoundary>
106
- <EntityEditView
107
- {...props}
108
- layout={"side_panel"}
109
- collection={collection as EntityCollection}
110
- parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
111
- onValuesModified={onValuesModified}
112
- onSaved={onUpdate}
113
- barActions={({
114
- status,
115
- values
116
- }) => <div className="flex gap-1">
117
- <IconButton
118
- className="self-center"
119
- size={"small"}
120
- onClick={onClose}>
121
- <XIcon/>
122
- </IconButton>
123
- {allowFullScreen && <IconButton
124
- className="self-center"
125
- size={"small"}
126
- onClick={() => {
127
- const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
128
- saveEntityToMemoryCache(key, values);
129
- // Clear blocked so no unsaved-changes dialog fires
130
- setBlocked(false);
131
- setBlockedNavigationMessage(undefined);
132
- // IMPORTANT: useLocation() returns the frozen base_location from RebaseRoutes
133
- // (the collection URL), not the actual browser URL.
134
- // Build the full-screen URL directly from props using urlController.
135
- if (entityId) {
136
- const fullScreenUrl = urlController.buildUrlCollectionPath(`${path}/${entityId}`);
137
- navigate(fullScreenUrl, { state: null });
138
- } else {
139
- const fullScreenUrl = urlController.buildUrlCollectionPath(path);
140
- navigate(fullScreenUrl + "#new", { state: null });
141
- }
142
- }}>
143
- <Maximize2Icon/>
144
- </IconButton>}
145
- </div>}
146
- onTabChange={({
147
- entityId,
148
- selectedTab,
149
- collection
150
- }) => {
151
- // Only update the URL to reflect the new tab — don't call
152
- // sideEntityController.replace() which would recreate the
153
- // entire EntitySidePanel component, causing a full
154
- // unmount/remount and expensive re-render of the form.
155
- if (entityId) {
156
- const collectionPath = removeInitialAndTrailingSlashes(path);
157
- const tabSuffix = selectedTab ? "/" + selectedTab : "";
158
- const fullUrl = urlController.buildUrlCollectionPath(`${collectionPath}/${entityId}${tabSuffix}#side`);
159
- navigate(fullUrl, { replace: true, state: location.state });
160
- }
161
- }}
162
- formProps={formProps}
163
- />
116
+ {isDetailMode
117
+ ? <EntityDetailView
118
+ path={path}
119
+ layout={collection?.openEntityMode === "dialog" ? "dialog" : "side_panel"}
120
+ collection={collection as EntityCollection}
121
+ entityId={entityId!}
122
+ parentCollectionSlugs={parentCollectionSlugs}
123
+ parentEntityIds={parentEntityIds}
124
+ onEditClick={() => setShowEditInPanel(true)}
125
+ barActions={({
126
+ status,
127
+ values
128
+ }) => <div className="flex gap-1">
129
+ <IconButton
130
+ className="self-center"
131
+ size={"small"}
132
+ onClick={onClose}>
133
+ <XIcon/>
134
+ </IconButton>
135
+ {allowFullScreen && <IconButton
136
+ className="self-center"
137
+ size={"small"}
138
+ onClick={() => {
139
+ if (entityId) {
140
+ const fullScreenUrl = urlController.buildUrlCollectionPath(`${path}/${entityId}`);
141
+ navigate(fullScreenUrl, { state: null });
142
+ }
143
+ }}>
144
+ <Maximize2Icon/>
145
+ </IconButton>}
146
+ </div>}
147
+ onTabChange={({
148
+ entityId: tabEntityId,
149
+ selectedTab,
150
+ collection: paramCollection
151
+ }) => {
152
+ if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") {
153
+ return;
154
+ }
155
+ if (tabEntityId) {
156
+ const collectionPath = removeInitialAndTrailingSlashes(path);
157
+ const tabSuffix = selectedTab ? "/" + selectedTab : "";
158
+ const fullUrl = urlController.buildUrlCollectionPath(`${collectionPath}/${tabEntityId}${tabSuffix}#side`);
159
+ navigate(fullUrl, { replace: true, state: location.state });
160
+ }
161
+ }}
162
+ />
163
+ : <EntityEditView
164
+ {...props}
165
+ layout={collection?.openEntityMode === "dialog" ? "dialog" : "side_panel"}
166
+ collection={collection as EntityCollection}
167
+ parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
168
+ onValuesModified={onValuesModified}
169
+ onSaved={onUpdate}
170
+ navigateBack={() => setShowEditInPanel(false)}
171
+ barActions={({
172
+ status,
173
+ values
174
+ }) => <div className="flex gap-1">
175
+ <IconButton
176
+ className="self-center"
177
+ size={"small"}
178
+ onClick={onClose}>
179
+ <XIcon/>
180
+ </IconButton>
181
+ {allowFullScreen && <IconButton
182
+ className="self-center"
183
+ size={"small"}
184
+ onClick={() => {
185
+ const key = (status === "new" || status === "copy") ? path + "#new" : path + "/" + entityId;
186
+ saveEntityToMemoryCache(key, values);
187
+ setBlocked(false);
188
+ setBlockedNavigationMessage(undefined);
189
+ if (entityId) {
190
+ const fullScreenUrl = urlController.buildUrlCollectionPath(`${path}/${entityId}`);
191
+ navigate(fullScreenUrl, { state: null });
192
+ } else {
193
+ const fullScreenUrl = urlController.buildUrlCollectionPath(path);
194
+ navigate(fullScreenUrl + "#new", { state: null });
195
+ }
196
+ }}>
197
+ <Maximize2Icon/>
198
+ </IconButton>}
199
+ </div>}
200
+ onTabChange={({
201
+ entityId,
202
+ selectedTab,
203
+ collection: paramCollection
204
+ }) => {
205
+ if (collection?.openEntityMode === "dialog" || paramCollection?.openEntityMode === "dialog") {
206
+ return;
207
+ }
208
+ if (entityId) {
209
+ const collectionPath = removeInitialAndTrailingSlashes(path);
210
+ const tabSuffix = selectedTab ? "/" + selectedTab : "";
211
+ const fullUrl = urlController.buildUrlCollectionPath(`${collectionPath}/${entityId}${tabSuffix}#side`);
212
+ navigate(fullUrl, { replace: true, state: location.state });
213
+ }
214
+ }}
215
+ formProps={formProps}
216
+ />
217
+ }
164
218
  </ErrorBoundary>
165
219
 
166
220
  </>
@@ -3,8 +3,7 @@ import type { EntityCollection } from "@rebasepro/types";
3
3
  import type { CustomizationController } from "@rebasepro/types";
4
4
  import React from "react";
5
5
  import { Entity } from "@rebasepro/types";
6
- import { cls, defaultBorderMixin, IconButton, Typography } from "@rebasepro/ui";
7
- import { ExternalLinkIcon } from "lucide-react";
6
+ import { cls, defaultBorderMixin, ExternalLinkIcon, IconButton, Typography } from "@rebasepro/ui";
8
7
  ;
9
8
  import { useCustomizationController } from "@rebasepro/core";
10
9
  import { useAuthController } from "@rebasepro/core";
@@ -362,7 +362,7 @@ export function ContentHomePage({
362
362
  modifiers={dndModifiers}
363
363
  >
364
364
  <SortableContext
365
- key={JSON.stringify(containers)}
365
+ key={containers.join(",")}
366
366
  items={containers}
367
367
  strategy={verticalListSortingStrategy}
368
368
  >
@@ -1,8 +1,7 @@
1
1
  import type { NavigationEntry } from "@rebasepro/types";
2
2
  import { useNavigate } from "react-router-dom";
3
3
  ;
4
- import { Chip, Collapse } from "@rebasepro/ui";
5
- import { StarIcon } from "lucide-react";
4
+ import { Chip, Collapse, StarIcon } from "@rebasepro/ui";
6
5
  import { useUserConfigurationPersistence } from "@rebasepro/core";
7
6
  import { useNavigationStateController } from "../../index";
8
7
 
@@ -1,5 +1,4 @@
1
- import { Card, cls, Markdown, Typography } from "@rebasepro/ui";
2
- import { ArrowRightIcon } from "lucide-react";
1
+ import { ArrowRightIcon, Card, cls, Markdown, Typography } from "@rebasepro/ui";
3
2
  import React from "react";
4
3
 
5
4
  export type NavigationCardProps = {
@@ -1,8 +1,7 @@
1
1
  import type { NavigationEntry, EntityCollection } from "@rebasepro/types";
2
2
  import { useNavigate } from "react-router-dom";
3
3
  ;
4
- import { IconButton, Tooltip } from "@rebasepro/ui";
5
- import { StarIcon } from "lucide-react";
4
+ import { IconButton, StarIcon, Tooltip } from "@rebasepro/ui";
6
5
  import { NavigationCard } from "./NavigationCard";
7
6
  import { SmallNavigationCard } from "./SmallNavigationCard";
8
7
  import React from "react";
@@ -1,6 +1,5 @@
1
1
  import React, { PropsWithChildren, useState } from "react";
2
- import { cls, IconButton, Typography, ExpandablePanel , iconSize } from "@rebasepro/ui";
3
- import { PencilIcon } from "lucide-react";
2
+ import { cls, ExpandablePanel, IconButton, iconSize, PencilIcon, Typography } from "@rebasepro/ui";
4
3
  import { useTranslation } from "@rebasepro/core";
5
4
 
6
5
  export function NavigationGroup({
@@ -1,5 +1,4 @@
1
- import { cardClickableMixin, cardMixin, cls, Typography } from "@rebasepro/ui";
2
- import { ArrowRightIcon } from "lucide-react";
1
+ import { ArrowRightIcon, cardClickableMixin, cardMixin, cls, Typography } from "@rebasepro/ui";
3
2
 
4
3
  import { Link } from "react-router-dom";
5
4
 
@@ -1,5 +1,4 @@
1
- import { IconButton, Tooltip, Typography } from "@rebasepro/ui";
2
- import { CopyIcon } from "lucide-react";
1
+ import { CopyIcon, IconButton, Tooltip, Typography } from "@rebasepro/ui";
3
2
  import { useCallback, useState } from "react";
4
3
 
5
4
  export function PropertyIdCopyTooltip({
@@ -5,6 +5,7 @@ import {
5
5
  } from "@rebasepro/core";
6
6
  import { CircularProgressCenter } from "@rebasepro/ui";
7
7
  import { LoginView } from "@rebasepro/core";
8
+ import type { AuthControllerExtended } from "@rebasepro/types";
8
9
 
9
10
  /**
10
11
  * Auth gate component that handles the authentication flow.
@@ -27,7 +28,6 @@ export function RebaseAuthGate({ children }: { children: React.ReactNode }) {
27
28
  const registry = useRebaseRegistry();
28
29
  const authController = useAuthController();
29
30
 
30
- console.log("[AuthGate] initialLoading:", authController?.initialLoading, "user:", authController?.user?.email ?? null);
31
31
 
32
32
  if (authController?.initialLoading) {
33
33
  return <CircularProgressCenter size={"large"}/>;
@@ -35,7 +35,7 @@ export function RebaseAuthGate({ children }: { children: React.ReactNode }) {
35
35
 
36
36
  if (!authController?.user) {
37
37
  const ActiveLoginView = registry.authConfig?.loginView ?? (
38
- <LoginView authController={authController as any}/>
38
+ <LoginView authController={authController as AuthControllerExtended}/>
39
39
  );
40
40
  return <>{ActiveLoginView}</>;
41
41
  }
@@ -13,10 +13,12 @@ import {
13
13
  CustomizationControllerContext
14
14
  } from "@rebasepro/core";
15
15
  import { CircularProgressCenter } from "@rebasepro/ui";
16
- import type { AppView, CollectionEditorOptions, EntityCustomView, EntityAction } from "@rebasepro/types";
16
+ import type { AppView, CollectionEditorOptions, EntityCustomView, EntityAction, EntityCollection } from "@rebasepro/types";
17
+ import type { CollectionRegistryController } from "@rebasepro/types";
18
+ import type { UrlController, NavigationStateController } from "@rebasepro/types";
17
19
 
18
- const EMPTY_PLUGINS: any[] = [];
19
- const EMPTY_COLLECTIONS: any[] = [];
20
+ const EMPTY_PLUGINS: unknown[] = [];
21
+ const EMPTY_COLLECTIONS: EntityCollection[] = [];
20
22
 
21
23
  import { useBuildNavigationStateController } from "../hooks/navigation/useBuildNavigationStateController";
22
24
  import { useBuildUrlController } from "../hooks/navigation/useBuildUrlController";
@@ -146,7 +148,7 @@ export function RebaseNavigation({ children }: RebaseNavigationProps) {
146
148
  collectionRegistryController,
147
149
  urlController,
148
150
  adminMode: adminModeController?.mode,
149
- userManagement: userManagement as any
151
+ userManagement
150
152
  });
151
153
 
152
154
  // ── Merge CMS-registered entityViews/entityActions into the customization controller ──
@@ -222,9 +224,9 @@ function BridgeAutoRegistrar({
222
224
  urlController,
223
225
  navigationStateController
224
226
  }: {
225
- collectionRegistryController: any;
226
- urlController: any;
227
- navigationStateController: any;
227
+ collectionRegistryController: CollectionRegistryController;
228
+ urlController: UrlController;
229
+ navigationStateController: NavigationStateController;
228
230
  }) {
229
231
  useBridgeRegistration("collectionRegistry", collectionRegistryController);
230
232
  useBridgeRegistration("urlController", urlController);
@@ -15,8 +15,7 @@ import {
15
15
  usePermissions
16
16
  } from "@rebasepro/core";
17
17
  import { ErrorView } from "@rebasepro/core";
18
- import { Button, DialogActions, Typography } from "@rebasepro/ui";
19
- import { PlusIcon } from "lucide-react";
18
+ import { Button, DialogActions, PlusIcon, Typography } from "@rebasepro/ui";
20
19
  import { IconForView } from "@rebasepro/core";
21
20
  import { useSelectionController } from "../EntityCollectionView/useSelectionController";
22
21
 
@@ -92,6 +91,16 @@ export interface EntitySelectionProps<M extends Record<string, unknown>> {
92
91
  * @group Components
93
92
  */
94
93
  export function EntitySelectionTable<M extends Record<string, unknown>>(
94
+ props: EntitySelectionProps<M>
95
+ ) {
96
+ if (!props.collection) {
97
+ return <ErrorView
98
+ error={"Could not find collection"}/>
99
+ }
100
+ return <EntitySelectionTableInternal {...props} collection={props.collection} />;
101
+ }
102
+
103
+ function EntitySelectionTableInternal<M extends Record<string, unknown>>(
95
104
  {
96
105
  onSingleEntitySelected,
97
106
  onMultipleEntitiesSelected,
@@ -102,7 +111,7 @@ export function EntitySelectionTable<M extends Record<string, unknown>>(
102
111
  description,
103
112
  fixedFilter,
104
113
  maxSelection
105
- }: EntitySelectionProps<M>) {
114
+ }: EntitySelectionProps<M> & { collection: EntityCollection<M> }) {
106
115
 
107
116
  const sideDialogContext = useSideDialogContext();
108
117
  const sideEntityController = useSideEntityController();
@@ -248,11 +257,6 @@ export function EntitySelectionTable<M extends Record<string, unknown>>(
248
257
  sideDialogContext.close(false);
249
258
  }, [sideDialogContext]);
250
259
 
251
- if (!collection) {
252
- return <ErrorView
253
- error={"Could not find collection with id " + collection}/>
254
- }
255
-
256
260
  const displayedColumnIds = useColumnIds(collection, false);
257
261
 
258
262
  const tableController = useDataTableController<M>({