@rebasepro/admin 0.0.1-canary.eae7889 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/dist/{CollectionEditorDialog-B2M9lCyL.js → CollectionEditorDialog-MbvXGzEq.js} +42 -31
  2. package/dist/CollectionEditorDialog-MbvXGzEq.js.map +1 -0
  3. package/dist/{CollectionsStudioView-WG6soyfs.js → CollectionsStudioView-D9X6aiAr.js} +12 -12
  4. package/dist/CollectionsStudioView-D9X6aiAr.js.map +1 -0
  5. package/dist/{ContentHomePage-CDF_a6Lp.js → ContentHomePage-CfVB1eUo.js} +26 -26
  6. package/dist/ContentHomePage-CfVB1eUo.js.map +1 -0
  7. package/dist/{ExportCollectionAction-Dc0VOWMN.js → ExportCollectionAction-CUwJg4F9.js} +2 -2
  8. package/dist/{ExportCollectionAction-Dc0VOWMN.js.map → ExportCollectionAction-CUwJg4F9.js.map} +1 -1
  9. package/dist/{ImportCollectionAction-DpCagAOy.js → ImportCollectionAction-DGa_SF_8.js} +2 -2
  10. package/dist/{ImportCollectionAction-DpCagAOy.js.map → ImportCollectionAction-DGa_SF_8.js.map} +1 -1
  11. package/dist/{PropertyEditView-DS67DxoT.js → PropertyEditView-C4nlYmAc.js} +82 -104
  12. package/dist/PropertyEditView-C4nlYmAc.js.map +1 -0
  13. package/dist/{RolesView-CIuYBimF.js → RolesView-CNWxnR8e.js} +7 -5
  14. package/dist/RolesView-CNWxnR8e.js.map +1 -0
  15. package/dist/{UsersView-B5zelXnH.js → UsersView-YiTIcXkA.js} +14 -35
  16. package/dist/UsersView-YiTIcXkA.js.map +1 -0
  17. package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -4
  18. package/dist/collection_editor/types/collection_editor_controller.d.ts +6 -3
  19. package/dist/collection_editor/types/config_controller.d.ts +14 -7
  20. package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +3 -2
  21. package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +3 -2
  22. package/dist/collection_editor/ui/EditorCollectionAction.d.ts +1 -1
  23. package/dist/collection_editor/ui/EditorCollectionActionStart.d.ts +1 -1
  24. package/dist/collection_editor/ui/EditorEntityAction.d.ts +1 -1
  25. package/dist/collection_editor/ui/KanbanSetupAction.d.ts +3 -2
  26. package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +3 -2
  27. package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +3 -4
  28. package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -3
  29. package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -2
  30. package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +3 -2
  31. package/dist/collection_editor_ui.js +3 -3
  32. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  33. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
  34. package/dist/components/EntityCollectionTable/column_utils.d.ts +2 -2
  35. package/dist/components/EntityCollectionTable/fields/TableMultipleRelationField.d.ts +1 -1
  36. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  37. package/dist/components/EntityCollectionTable/fields/TableRelationField.d.ts +1 -1
  38. package/dist/components/EntityCollectionTable/fields/TableRelationSelectorField.d.ts +2 -2
  39. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -1
  40. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -2
  41. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +2 -1
  42. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +4 -2
  43. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +4 -2
  44. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -2
  45. package/dist/components/EntityCollectionView/SplitListView.d.ts +3 -2
  46. package/dist/components/EntityEditView.d.ts +9 -2
  47. package/dist/components/RebaseCMS.d.ts +1 -1
  48. package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +2 -2
  49. package/dist/components/ReferenceWidget.d.ts +2 -2
  50. package/dist/components/RelationSelector.d.ts +1 -1
  51. package/dist/components/SelectableTable/SelectableTable.d.ts +2 -2
  52. package/dist/editor.js +2 -2
  53. package/dist/editor.js.map +1 -1
  54. package/dist/hooks/navigation/useNavigationRegistry.d.ts +2 -1
  55. package/dist/hooks/useEntityHistory.d.ts +1 -1
  56. package/dist/{index-CHxgwt6E.js → index-CtzpHzMQ.js} +11 -4
  57. package/dist/index-CtzpHzMQ.js.map +1 -0
  58. package/dist/{index-Dey5WJpO.js → index-DKlrVD1m.js} +3 -3
  59. package/dist/index-DKlrVD1m.js.map +1 -0
  60. package/dist/{index-CBhrgpR7.js → index-kHJXfLNI.js} +3 -3
  61. package/dist/index-kHJXfLNI.js.map +1 -0
  62. package/dist/index.js +79 -63
  63. package/dist/index.js.map +1 -1
  64. package/dist/{useEntityHistory-Dcj4zhGj.js → useEntityHistory-UVsSclfZ.js} +3 -1
  65. package/dist/useEntityHistory-UVsSclfZ.js.map +1 -0
  66. package/dist/util/navigation_utils.d.ts +10 -1
  67. package/dist/{util-BQ82ySL3.js → util-CwLmSpGp.js} +1653 -1257
  68. package/dist/util-CwLmSpGp.js.map +1 -0
  69. package/package.json +9 -17
  70. package/src/collection_editor/ConfigControllerProvider.tsx +19 -28
  71. package/src/collection_editor/types/collection_editor_controller.tsx +3 -3
  72. package/src/collection_editor/types/config_controller.tsx +7 -7
  73. package/src/collection_editor/ui/AddKanbanColumnAction.tsx +4 -4
  74. package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +3 -3
  75. package/src/collection_editor/ui/EditorCollectionAction.tsx +3 -3
  76. package/src/collection_editor/ui/EditorCollectionActionStart.tsx +7 -7
  77. package/src/collection_editor/ui/EditorEntityAction.tsx +3 -3
  78. package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +4 -2
  79. package/src/collection_editor/ui/KanbanSetupAction.tsx +4 -3
  80. package/src/collection_editor/ui/MissingReferenceWidget.tsx +3 -2
  81. package/src/collection_editor/ui/NewCollectionButton.tsx +2 -1
  82. package/src/collection_editor/ui/NewCollectionCard.tsx +2 -1
  83. package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -3
  84. package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +5 -50
  85. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +12 -20
  86. package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +1 -3
  87. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +17 -2
  88. package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -3
  89. package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +2 -1
  90. package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +18 -12
  91. package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +1 -2
  92. package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -2
  93. package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
  94. package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +4 -4
  95. package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
  96. package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +15 -49
  97. package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +4 -5
  98. package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +1 -1
  99. package/src/collection_editor/ui/collection_editor/templates/products_template.ts +2 -2
  100. package/src/components/DefaultAppBar.tsx +2 -2
  101. package/src/components/DefaultDrawer.tsx +25 -17
  102. package/src/components/DrawerNavigationGroup.tsx +4 -4
  103. package/src/components/DrawerNavigationItem.tsx +6 -6
  104. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +4 -4
  105. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
  106. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -4
  107. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  108. package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +3 -3
  109. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +3 -3
  110. package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +4 -4
  111. package/src/components/EntityCollectionTable/fields/TableRelationSelectorField.tsx +3 -3
  112. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +8 -2
  113. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -1
  114. package/src/components/EntityCollectionTable/internal/common.tsx +5 -5
  115. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
  116. package/src/components/EntityCollectionTable/table_bindings.tsx +45 -35
  117. package/src/components/EntityCollectionView/EntityBoardCard.tsx +18 -19
  118. package/src/components/EntityCollectionView/EntityCard.tsx +2 -2
  119. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +42 -14
  120. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +4 -3
  121. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +157 -54
  122. package/src/components/EntityCollectionView/EntityCollectionView.tsx +169 -75
  123. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +23 -13
  124. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +21 -12
  125. package/src/components/EntityCollectionView/FiltersDialog.tsx +7 -7
  126. package/src/components/EntityCollectionView/SplitListView.tsx +24 -8
  127. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +33 -5
  128. package/src/components/EntityEditView.tsx +85 -85
  129. package/src/components/EntitySidePanel.tsx +18 -10
  130. package/src/components/HomePage/ContentHomePage.tsx +24 -15
  131. package/src/components/HomePage/NavigationCard.tsx +4 -4
  132. package/src/components/HomePage/NavigationGroup.tsx +2 -2
  133. package/src/components/RebaseAuthGate.tsx +2 -0
  134. package/src/components/RebaseCMS.tsx +4 -3
  135. package/src/components/RebaseNavigation.tsx +8 -5
  136. package/src/components/ReferenceTable/EntitySelectionTable.tsx +4 -4
  137. package/src/components/ReferenceWidget.tsx +3 -3
  138. package/src/components/RelationSelector.tsx +33 -5
  139. package/src/components/SelectableTable/SelectableTable.tsx +6 -6
  140. package/src/components/UserSelector.tsx +1 -1
  141. package/src/components/admin/RolesView.tsx +10 -3
  142. package/src/components/admin/UsersView.tsx +13 -25
  143. package/src/components/app/Scaffold.tsx +4 -4
  144. package/src/components/field_configs.tsx +29 -32
  145. package/src/components/history/EntityHistoryView.tsx +12 -1
  146. package/src/editor/editor.tsx +2 -2
  147. package/src/form/EntityForm.tsx +5 -4
  148. package/src/form/PropertyFieldBinding.tsx +14 -10
  149. package/src/form/components/FieldHelperText.tsx +1 -1
  150. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -3
  151. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -5
  152. package/src/form/field_bindings/BlockFieldBinding.tsx +4 -4
  153. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  154. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  155. package/src/form/field_bindings/MapFieldBinding.tsx +7 -7
  156. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +1 -1
  157. package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +3 -3
  158. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +7 -7
  159. package/src/form/field_bindings/ReferenceFieldBinding.tsx +2 -2
  160. package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
  161. package/src/form/field_bindings/RepeatFieldBinding.tsx +5 -5
  162. package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
  163. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
  164. package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -1
  165. package/src/form/field_bindings/TextFieldBinding.tsx +7 -7
  166. package/src/form/field_bindings/UserSelectFieldBinding.tsx +1 -1
  167. package/src/form/useClearRestoreValue.tsx +1 -1
  168. package/src/form/validation.ts +1 -1
  169. package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -1
  170. package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -3
  171. package/src/hooks/navigation/useNavigationRegistry.ts +14 -3
  172. package/src/hooks/navigation/useResolvedViews.tsx +1 -3
  173. package/src/hooks/navigation/useTopLevelNavigation.ts +1 -1
  174. package/src/hooks/navigation/utils.ts +1 -1
  175. package/src/hooks/useEntityHistory.ts +7 -2
  176. package/src/preview/PropertyPreview.tsx +27 -23
  177. package/src/preview/components/StorageThumbnail.tsx +4 -1
  178. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  179. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
  180. package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +1 -1
  181. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +3 -3
  182. package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
  183. package/src/routes/RebaseRoute.tsx +57 -11
  184. package/src/util/navigation_utils.ts +21 -2
  185. package/src/util/previews.ts +15 -6
  186. package/src/util/property_utils.tsx +3 -3
  187. package/dist/CollectionEditorDialog-B2M9lCyL.js.map +0 -1
  188. package/dist/CollectionsStudioView-WG6soyfs.js.map +0 -1
  189. package/dist/ContentHomePage-CDF_a6Lp.js.map +0 -1
  190. package/dist/PropertyEditView-DS67DxoT.js.map +0 -1
  191. package/dist/RolesView-CIuYBimF.js.map +0 -1
  192. package/dist/UsersView-B5zelXnH.js.map +0 -1
  193. package/dist/index-CBhrgpR7.js.map +0 -1
  194. package/dist/index-CHxgwt6E.js.map +0 -1
  195. package/dist/index-Dey5WJpO.js.map +0 -1
  196. package/dist/useEntityHistory-Dcj4zhGj.js.map +0 -1
  197. package/dist/util-BQ82ySL3.js.map +0 -1
@@ -1,10 +1,10 @@
1
- import type { EntityCollection } from "@rebasepro/types";
1
+ import type { EntityCollection, ViewMode } from "@rebasepro/types";
2
2
  import { Blocker, useBlocker, useLocation } from "react-router";
3
3
  import { EntityEditView } from "../components/EntityEditView";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { useNavigate } from "react-router-dom";
6
6
  import { EntityCollectionView } from "../components";
7
- import { NotFoundPage } from "@rebasepro/core";
7
+ import { NotFoundPage, useUserConfigurationPersistence } from "@rebasepro/core";
8
8
  import { UnsavedChangesDialog } from "@rebasepro/core";
9
9
  import { CircularProgressCenter } from "@rebasepro/ui";
10
10
  import { getNavigationEntriesFromPath, NavigationViewCollectionInternal, NavigationViewEntityCustomInternal, NavigationViewInternal } from "@rebasepro/common";
@@ -18,6 +18,7 @@ export function RebaseRoute() {
18
18
  const collectionRegistry = useCollectionRegistryController();
19
19
  const urlController = useUrlController();
20
20
  const breadcrumbs = useBreadcrumbsController();
21
+ const userConfigPersistence = useUserConfigurationPersistence();
21
22
 
22
23
  const hash = location.hash;
23
24
  const isSidePanel = hash.includes("#side");
@@ -92,7 +93,7 @@ export function RebaseRoute() {
92
93
  return <EntityCollectionView
93
94
  key={`collection_view_${collection.slug}`}
94
95
  {...collection}
95
- parentCollectionIds={[]}
96
+ parentCollectionSlugs={[]} parentEntityIds={[]}
96
97
  path={collection.slug}
97
98
  updateUrl={true}
98
99
  Actions={toArray(collection.Actions)}/>
@@ -115,7 +116,7 @@ export function RebaseRoute() {
115
116
  return <EntityCollectionView
116
117
  key={`collection_view_${collection.slug}`}
117
118
  {...collection}
118
- parentCollectionIds={[]}
119
+ parentCollectionSlugs={[]} parentEntityIds={[]}
119
120
  path={collection.slug}
120
121
  updateUrl={true}
121
122
  Actions={toArray(collection.Actions)}/>;
@@ -141,7 +142,25 @@ export function RebaseRoute() {
141
142
  collection = collectionRegistry.getCollection(firstCollectionEntry.id);
142
143
  if (!collection)
143
144
  collection = collectionRegistry.getCollection(firstCollectionEntry.slug);
144
- if (collection && (collection.openEntityMode ?? "split") === "split") {
145
+
146
+ // Resolve the effective openEntityMode based on the current view mode.
147
+ // Priority: collection.openEntityMode (explicit) > view-mode-based default.
148
+ // View mode priority: URL __view param > saved user config > collection default.
149
+ let effectiveOpenMode: "side_panel" | "full_screen" | "split" | undefined = collection?.openEntityMode;
150
+ if (!effectiveOpenMode && collection) {
151
+ const urlViewParam = new URLSearchParams(location.search).get("__view");
152
+ let currentViewMode: ViewMode = collection.defaultViewMode ?? "list";
153
+ if (urlViewParam && ["list", "table", "kanban", "cards"].includes(urlViewParam)) {
154
+ currentViewMode = urlViewParam as ViewMode;
155
+ } else {
156
+ const savedView = userConfigPersistence?.getCollectionConfig(collection.slug)?.defaultViewMode;
157
+ if (savedView) currentViewMode = savedView as ViewMode;
158
+ }
159
+ if (currentViewMode === "kanban") effectiveOpenMode = "side_panel";
160
+ else if (currentViewMode === "table" || currentViewMode === "cards") effectiveOpenMode = "full_screen";
161
+ else effectiveOpenMode = "split";
162
+ }
163
+ if (collection && effectiveOpenMode === "split") {
145
164
  // Extract subcollection tab from the 3rd entry if present
146
165
  let selectedTab: string | undefined;
147
166
  if (navigationEntries.length === 3) {
@@ -168,7 +187,7 @@ export function RebaseRoute() {
168
187
  return <EntityCollectionView
169
188
  key={`collection_view_${collection.slug}`}
170
189
  {...collection}
171
- parentCollectionIds={[]}
190
+ parentCollectionSlugs={[]} parentEntityIds={[]}
172
191
  path={collection.slug}
173
192
  updateUrl={true}
174
193
  selectedEntityId={lastEntityEntry.entityId}
@@ -216,6 +235,10 @@ function EntityFullScreenRoute({
216
235
  const navigate = useNavigate();
217
236
  const location = useLocation();
218
237
 
238
+ // defaultValues may be carried via location.state when openNewDocument() is called
239
+ // for full-screen mode. We read it once on mount — after that, the form owns its state.
240
+ const defaultValues = (location.state as { defaultValues?: Record<string, unknown> } | null)?.defaultValues;
241
+
219
242
  // Preserve the current hash (e.g. #full) across tab/save navigations
220
243
  const hash = location.hash;
221
244
 
@@ -253,7 +276,8 @@ function EntityFullScreenRoute({
253
276
 
254
277
  const [selectedTab, setSelectedTab] = useState<string | undefined>(urlTab);
255
278
 
256
- const parentCollectionIds = collectionRegistry.getParentCollectionIds(navigationPath);
279
+ const parentCollectionSlugs = collectionRegistry.getParentCollectionSlugs(navigationPath);
280
+ const parentEntityIds = collectionRegistry.getParentEntityIds(navigationPath);
257
281
  useEffect(() => {
258
282
  if (urlTab !== selectedTab) {
259
283
  setSelectedTab(urlTab);
@@ -269,10 +293,27 @@ function EntityFullScreenRoute({
269
293
  let blocker: Blocker | undefined = undefined;
270
294
  try {
271
295
  blocker = useBlocker(({
296
+ currentLocation,
272
297
  nextLocation
273
298
  }) => {
274
299
  if (nextLocation.pathname.startsWith(entityPath))
275
300
  return false;
301
+
302
+ // Side panel overlay navigations preserve the underlying form via
303
+ // base_location in router state — no data is lost in either direction.
304
+
305
+ // Opening a side panel (e.g. clicking a relation arrow)
306
+ const nextHash = nextLocation.hash;
307
+ if (nextHash === "#side" || nextHash === "#new_side")
308
+ return false;
309
+
310
+ // Closing a side panel (navigate(-1) back to the form's own path)
311
+ const currentHash = currentLocation.hash;
312
+ if ((currentHash === "#side" || currentHash === "#new_side") &&
313
+ (nextLocation.pathname === basePath ||
314
+ nextLocation.pathname.startsWith(entityPath)))
315
+ return false;
316
+
276
317
  return blocked.current;
277
318
  });
278
319
  } catch (e) {
@@ -295,9 +336,10 @@ function EntityFullScreenRoute({
295
336
  return <NotFoundPage/>;
296
337
  }
297
338
 
298
- const collection = isNew
339
+ const rawCollection = isNew
299
340
  ? (lastCollectionEntry && "collection" in lastCollectionEntry ? lastCollectionEntry.collection : undefined)!
300
341
  : (lastEntityEntry && "parentCollection" in lastEntityEntry ? lastEntityEntry.parentCollection : undefined)!;
342
+ const collection = collectionRegistry.getCollection(rawCollection.slug) || rawCollection;
301
343
  const fullIdPath = isNew ? lastCollectionEntry!.slug : lastEntityEntry!.slug;
302
344
  const collectionPath = urlController.resolveDatabasePathsFrom(fullIdPath);
303
345
  return <>
@@ -309,14 +351,18 @@ function EntityFullScreenRoute({
309
351
  path={collectionPath}
310
352
  copy={isCopy}
311
353
  selectedTab={selectedTab ?? undefined}
354
+ defaultValues={isNew ? defaultValues : undefined}
312
355
  onValuesModified={(modified) => blocked.current = modified}
313
356
  onSaved={(params) => {
314
357
  const newSelectedTab = params.selectedTab;
315
358
  const newEntityId = params.entityId;
359
+ // Clear the hash after saving a new entity — preserving #new
360
+ // would cause the route to re-parse as "new" and show "not found".
361
+ const savedHash = isNew ? "" : hash;
316
362
  if (newSelectedTab) {
317
- navigate(`${basePath}/${newEntityId}/${newSelectedTab}${hash}`, { replace: true });
363
+ navigate(`${basePath}/${newEntityId}/${newSelectedTab}${savedHash}`, { replace: true });
318
364
  } else {
319
- navigate(`${basePath}/${newEntityId}${hash}`, { replace: true });
365
+ navigate(`${basePath}/${newEntityId}${savedHash}`, { replace: true });
320
366
  }
321
367
  }}
322
368
  onTabChange={(params) => {
@@ -331,7 +377,7 @@ function EntityFullScreenRoute({
331
377
  navigate(`${basePath}/${entityId}${hash}`, { replace: true });
332
378
  }
333
379
  }}
334
- parentCollectionIds={parentCollectionIds}
380
+ parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
335
381
  />
336
382
 
337
383
  <UnsavedChangesDialog
@@ -23,6 +23,7 @@ export function navigateToEntity({
23
23
  copy,
24
24
  path,
25
25
  selectedTab,
26
+ defaultValues,
26
27
  sideEntityController,
27
28
  onClose,
28
29
  navigation
@@ -34,6 +35,15 @@ export function navigateToEntity({
34
35
  entityId?: string | number;
35
36
  selectedTab?: string;
36
37
  copy?: boolean;
38
+ /**
39
+ * Pre-populate the new entity form with these values.
40
+ * Only applied when entityId is not set (i.e. "new" mode).
41
+ *
42
+ * Side panel: passed through EntitySidePanelProps → EntityEditView.
43
+ * Full screen: carried via React Router location.state so the route
44
+ * component can read it on mount without polluting the URL.
45
+ */
46
+ defaultValues?: Record<string, unknown>;
37
47
  path: string;
38
48
  sideEntityController: SideEntityController;
39
49
  onClose?: () => void;
@@ -49,7 +59,8 @@ export function navigateToEntity({
49
59
  selectedTab,
50
60
  collection,
51
61
  updateUrl: true,
52
- onClose
62
+ onClose,
63
+ defaultValues
53
64
  });
54
65
 
55
66
  } else {
@@ -57,13 +68,21 @@ export function navigateToEntity({
57
68
  if (entityId && selectedTab) {
58
69
  to += `/${selectedTab}`;
59
70
  }
71
+ // Preserve the __view query param so the target route knows the current view mode
72
+ const currentViewParam = new URLSearchParams(window.location.search).get("__view");
73
+ if (currentViewParam) {
74
+ to += `${to.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
75
+ }
60
76
  if (!entityId) {
61
77
  to += "#new";
62
78
  }
63
79
  if (copy) {
64
80
  to += "#copy";
65
81
  }
66
- navigation.navigate(to);
82
+ // Use React Router location.state to carry defaultValues — the correct SPA
83
+ // approach. No URL size limits, no encoding, nothing in the address bar.
84
+ // EntityFullScreenRoute reads location.state.defaultValues on mount.
85
+ navigation.navigate(to, defaultValues ? { state: { defaultValues } } : undefined);
67
86
  }
68
87
 
69
88
  }
@@ -35,16 +35,25 @@ export function getEntityTitlePropertyKey<M extends Record<string, unknown>>(col
35
35
  if (collection.titleProperty) {
36
36
  return collection.titleProperty as string;
37
37
  }
38
- // find first text field property
39
- for (const key in collection.properties) {
38
+
39
+ const orderToSearch = (collection.propertiesOrder as string[]) || Object.keys(collection.properties);
40
+ let firstStringCandidate: string | undefined;
41
+
42
+ for (const key of orderToSearch) {
40
43
  const property = collection.properties[key];
41
- if (!isPropertyBuilder(property)) {
44
+ if (property && !isPropertyBuilder(property)) {
42
45
  const prop = property as Property;
43
- if (prop.type === "string" && !prop.multiline && !prop.markdown && !prop.storage && !prop.isId) {
44
- return key;
46
+ if (prop.type === "string" && !prop.ui?.multiline && !prop.ui?.markdown && !prop.storage && !prop.isId) {
47
+ if (!firstStringCandidate) {
48
+ firstStringCandidate = key;
49
+ }
50
+ const lowerKey = key.toLowerCase();
51
+ if (["name", "title", "label", "displayname", "username"].includes(lowerKey)) {
52
+ return key; // Immediate return if it's a strong title candidate
53
+ }
45
54
  }
46
55
  }
47
56
  }
48
- return undefined;
57
+ return firstStringCandidate;
49
58
  }
50
59
 
@@ -58,10 +58,10 @@ function getDefaultIconForProperty(property: Property): LucideIcon {
58
58
  switch (property.type) {
59
59
  case "string": {
60
60
  if (property.storage) return UploadIcon;
61
- if (property.url) return GlobeIcon;
61
+ if (property.ui?.url) return GlobeIcon;
62
62
  if (property.email) return MailIcon;
63
- if (property.multiline || property.markdown) return AlignLeftIcon;
64
- if (property.reference) return LinkIcon;
63
+ if (property.ui?.multiline || property.ui?.markdown) return AlignLeftIcon;
64
+ if ((property as any).reference) return LinkIcon;
65
65
  return TextIcon;
66
66
  }
67
67
  case "number":