@rebasepro/cms 0.22.0 → 0.24.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 (90) hide show
  1. package/dist/{CollectionEditorDialog-CUtfS_49.js → CollectionEditorDialog-p5-I-Apu.js} +181 -97
  2. package/dist/CollectionEditorDialog-p5-I-Apu.js.map +1 -0
  3. package/dist/{PropertyEditView-BpEbC0Q2.js → PropertyEditView-DDB_X-00.js} +55 -23
  4. package/dist/PropertyEditView-DDB_X-00.js.map +1 -0
  5. package/dist/{RouterCollectionsStudioView-EK8Knq5I.js → RouterCollectionsStudioView-SGBV4CMg.js} +34 -10
  6. package/dist/RouterCollectionsStudioView-SGBV4CMg.js.map +1 -0
  7. package/dist/{SchemaChangeDialog-BeP0A4MJ.js → SchemaChangeDialog-CcFSXvkK.js} +33 -12
  8. package/dist/SchemaChangeDialog-CcFSXvkK.js.map +1 -0
  9. package/dist/collection_editor/_cms_internals.d.ts +3 -1
  10. package/dist/collection_editor/liveSchemaClient.d.ts +38 -18
  11. package/dist/collection_editor/relation_kinds.d.ts +11 -0
  12. package/dist/collection_editor/serializable_types.d.ts +2 -0
  13. package/dist/collection_editor/types/config_controller.d.ts +11 -0
  14. package/dist/collection_editor/ui/collection_editor/CollectionStudioView.d.ts +8 -1
  15. package/dist/collection_editor/useLiveSchemaEditing.d.ts +5 -5
  16. package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +7 -0
  17. package/dist/collection_editor_ui.js +5 -5
  18. package/dist/components/ClearFilterSortButton.d.ts +7 -1
  19. package/dist/components/CollectionTableBinding/fields/CompactEntityCellField.d.ts +12 -13
  20. package/dist/components/CollectionTableBinding/fields/TableMultipleRelationField.d.ts +6 -3
  21. package/dist/components/CollectionTableBinding/fields/TableReferenceField.d.ts +8 -1
  22. package/dist/components/CollectionTableBinding/fields/TableRelationField.d.ts +8 -1
  23. package/dist/components/CollectionTableBinding/fields/TableRelationSelectorField.d.ts +13 -3
  24. package/dist/components/CollectionTableBinding/fields/VirtualTableSelect.d.ts +10 -0
  25. package/dist/components/CollectionTableBinding/fields/VirtualTableUserSelect.d.ts +10 -0
  26. package/dist/components/CollectionTableBinding/internal/EntityTableCell.d.ts +21 -0
  27. package/dist/components/CollectionTableBinding/internal/TableCellOpener.d.ts +45 -0
  28. package/dist/components/CollectionTableBinding/table_bindings.d.ts +24 -0
  29. package/dist/components/CollectionViewBinding/CollectionViewActions.d.ts +6 -1
  30. package/dist/components/CollectionViewBinding/CollectionViewBinding.d.ts +12 -3
  31. package/dist/components/CollectionViewBinding/FiltersDialog.d.ts +5 -0
  32. package/dist/components/EditViewBinding.d.ts +7 -1
  33. package/dist/components/EntityIdentityBar.d.ts +29 -4
  34. package/dist/components/EntityPreviewBinding.d.ts +8 -1
  35. package/dist/components/EntityPreviewNesting.d.ts +15 -0
  36. package/dist/components/NavigationLoadingErrorView.d.ts +16 -0
  37. package/dist/components/PickerTrigger.d.ts +17 -0
  38. package/dist/components/ReferenceTable/SelectionTableBinding.d.ts +12 -0
  39. package/dist/components/RelationSelector.d.ts +24 -7
  40. package/dist/components/UserSelector.d.ts +8 -1
  41. package/dist/components/common/ActionMenuLabel.d.ts +15 -0
  42. package/dist/components/common/default_entity_actions.d.ts +37 -0
  43. package/dist/data_export/export/additional_fields.d.ts +13 -0
  44. package/dist/data_export/export/export.d.ts +6 -0
  45. package/dist/data_import/components/ImportConversionProblems.d.ts +11 -0
  46. package/dist/data_import/components/index.d.ts +1 -0
  47. package/dist/data_import/utils/csv.d.ts +3 -2
  48. package/dist/data_import/utils/data.d.ts +81 -4
  49. package/dist/data_import/utils/id_column.d.ts +16 -0
  50. package/dist/data_import/utils/import_columns.d.ts +48 -0
  51. package/dist/editor/editor.d.ts +7 -1
  52. package/dist/editor/extensions/Image.d.ts +22 -1
  53. package/dist/editor/hooks/useProseMirror.d.ts +4 -1
  54. package/dist/editor.js +69 -7
  55. package/dist/editor.js.map +1 -1
  56. package/dist/{export-LvIpE7sE.js → export-DCHuPD1a.js} +65 -211
  57. package/dist/export-DCHuPD1a.js.map +1 -0
  58. package/dist/form/form_utils.d.ts +37 -0
  59. package/dist/form/resolve_form_properties.d.ts +26 -0
  60. package/dist/form/validation.d.ts +13 -0
  61. package/dist/{history-DG6Ln7CV.js → history-CBd6SBRs.js} +3 -2
  62. package/dist/{history-DG6Ln7CV.js.map → history-CBd6SBRs.js.map} +1 -1
  63. package/dist/hooks/useEntityDisplay.d.ts +4 -5
  64. package/dist/hooks/useRecordActions.d.ts +28 -6
  65. package/dist/hooks/useReferencePaths.d.ts +21 -0
  66. package/dist/hooks/useStorageReferenceResolver.d.ts +23 -0
  67. package/dist/{import-Cxnmpyjl.js → import-DjQoRrIU.js} +35 -54
  68. package/dist/import-DjQoRrIU.js.map +1 -0
  69. package/dist/index.js +191 -117
  70. package/dist/index.js.map +1 -1
  71. package/dist/preview/components/StorageMarkdown.d.ts +10 -0
  72. package/dist/preview/util.d.ts +29 -0
  73. package/dist/util/caller_scopes.d.ts +15 -0
  74. package/dist/util/entity_actions.d.ts +37 -1
  75. package/dist/util/fit_inline_actions.d.ts +20 -0
  76. package/dist/util/navigation_utils.d.ts +14 -2
  77. package/dist/util/view_mode.d.ts +12 -18
  78. package/dist/{util-CyIcgnv2.js → util-BRvKFMLa.js} +5775 -3665
  79. package/dist/util-BRvKFMLa.js.map +1 -0
  80. package/dist/{util-DB31IoJE.js → util-D7ebttKT.js} +39 -2
  81. package/dist/util-D7ebttKT.js.map +1 -0
  82. package/package.json +9 -9
  83. package/dist/CollectionEditorDialog-CUtfS_49.js.map +0 -1
  84. package/dist/PropertyEditView-BpEbC0Q2.js.map +0 -1
  85. package/dist/RouterCollectionsStudioView-EK8Knq5I.js.map +0 -1
  86. package/dist/SchemaChangeDialog-BeP0A4MJ.js.map +0 -1
  87. package/dist/export-LvIpE7sE.js.map +0 -1
  88. package/dist/import-Cxnmpyjl.js.map +0 -1
  89. package/dist/util-CyIcgnv2.js.map +0 -1
  90. package/dist/util-DB31IoJE.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
- import { $n as CollectionRegistryContext, $t as getCollectionBySlugWithin, A as getFieldId, An as ReadOnlyFieldBinding, Ar as getIconForWidget, At as convertDataToEntity, B as MapFieldBinding, Bn as MapPropertyPreview, Bt as detectCsvDelimiter, C as EntityFormBinding, Cn as NavigationStateContext, Cr as LABEL_ICON_SIZE, Ct as EntityCardBinding, D as getDefaultFieldConfig, Dn as SelectableTableContext, Dr as getBracketNotation, Dt as useCollectionEditorDialogsState, E as DEFAULT_FIELD_CONFIGS, En as SideDialogsControllerContext, Er as PropertyKeyHint, Et as ConfigControllerProvider, F as SelectFieldBinding, Fn as UserPreview, Fr as isRelationProperty, Ft as ImportSaveInProgress, G as useSelectionDialog, Gn as ArrayOfStorageComponentsPreview, Gt as SearchIconsView, H as DateTimeFieldBinding, Hn as ArrayOfStringsPreview, Ht as parseCsvToObjects, I as RepeatFieldBinding, In as NumberPropertyPreview, It as IMPORT_BATCH_SIZE, J as useBuildUrlController, Jn as InlineEntityListPreview, Jt as BreadcrumbsProvider, K as SelectionTableBinding, Kn as RelationPreview, Kt as FieldCaption, L as ReferenceFieldBinding, Ln as BooleanPreview, Lt as saveImportedEntities, M as TextFieldBinding, Mn as FieldHelperText, Mr as getPropertyInPath, Mt as processValueMapping, N as SwitchFieldBinding, Nn as ArrayOfMapsPreview, Nr as getResolvedPropertyInPath, Nt as getInferenceType, O as getDefaultFieldId, On as ArrayCustomShapedFieldBinding, Or as getDefaultPropertiesOrder, Ot as ImportNewPropertyFieldPreview, P as StorageUploadFieldBinding, Pn as PropertyPreview, Pr as isReferenceProperty, Pt as useImportConfig, Q as useResolvedCollections, Qn as useSidePanel, Qt as addInitialSlash, R as MultiSelectFieldBinding, Rn as DatePreview, Rt as ImportFileUpload, S as isSchemaChangeCancelled, Sn as useUrlController, Sr as FieldBlock, St as CollectionCardViewBinding, T as PropertyFieldBinding, Tn as useSideDialogsController, Tr as spanClass, Tt as useCollectionEditorController, U as BlockFieldBinding, Un as ArrayPropertyEnumPreview, Ut as ArrayContainer, V as KeyValueFieldBinding, Vn as ArrayOneOfPreview, Vt as parseCsvRows, W as ArrayOfReferencesFieldBinding, Wn as ArrayEnumPreview, Wt as PropertyConfigBadge, X as useTopLevelNavigation, Xn as EntityPreviewBinding, Xt as resolveEntityView, Y as useBuildNavigationStateController, Yn as ReferencePreview, Yt as resolveEntityAction, Z as useResolvedViews, Zn as SidePanelControllerContext, Zt as mergeEntityActions, _ as useCollectionsConfigController, _n as CollectionTableBinding, _r as ImagePreview, _t as editEntityAction, a as namespaceToPropertiesPath, an as resolveCollectionPathIds, ar as getEntityTitlePropertyKeyForEntity, at as getEntityViewWidth, b as asUnavailable, bn as useAdminContext, br as FormRail, bt as DetailViewBinding, c as buildCollectionGenerationCallback, cn as SelectionMenu, cr as EnumValuesChip, d as fromSerializableCollectionConfigs, dn as resolveSelection, dr as SkeletonPropertyComponent, dt as getInitialEntityValues, en as getCollectionPathsCombinations, er as useCollectionRegistryController, et as useBuildCollectionRegistryController, f as fromSerializableProperties, fn as selectionQueryToFindParams, fr as renderSkeletonCaptionText, ft as removeEmptyContainers, g as toSerializableProperty, gn as VirtualTableInput, gr as UrlComponentPreview, gt as deleteEntityAction, h as toSerializableProperties, hn as useSelectionController, hr as renderSkeletonText, ht as copyEntityAction, i as namespaceToPropertiesOrderPath, in as removeTrailingSlash, ir as getEntityTitlePropertyKey, it as buildSidePanelsFromUrl, j as VectorFieldBinding, jn as LabelWithIcon, jr as getPropertiesWithPropertiesOrder, jt as flattenEntry, k as getFieldConfig, kn as useClearRestoreValue, kr as getIconForProperty, kt as DataNewPropertiesMapping, l as validateCollectionJson, ln as MAX_SELECTION_ROWS, lr as StorageThumbnail, lt as extractTouchedValues, m as toSerializableCollectionConfig, mr as renderSkeletonImageThumbnail, mt as CollectionViewBinding, n as getFullIdPath, nn as removeInitialAndTrailingSlashes, nr as useResolvedUser, nt as resolveNavigationFrom, o as CollectionGenerationApiError, on as resolveOpenEntityMode, or as ArrayPropertyPreview, ot as useBuildSidePanel, p as fromSerializableProperty, pn as serializeSelectionQuery, pr as renderSkeletonIcon, pt as zodToFormErrors, q as SideDialogs, qn as ArrayOfReferencesPreview, qt as useBreadcrumbsController, r as idToPropertiesPath, rn as removeInitialSlash, rr as getEntityPreviewKeys, rt as useResolvedNavigationFrom, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as resolveViewMode, sr as StringPropertyPreview, st as EditViewBinding, t as getFullId, tn as getLastSegment, tr as getUserLabel, tt as useHistory, u as fromSerializableCollectionConfig, un as SELECTION_PAGE_SIZE, ur as StorageThumbnailInternal, ut as getChanges, v as LiveSchemaError, vn as SelectableTable, vr as EmptyValue, vt as resetPasswordAction, w as EntityForm, wn as useNavigationStateController, wr as isSelfLabellingProperty, wt as CollectionViewActions, x as createLiveSchemaClient, xn as UrlContext, xr as RecordMeta, xt as EntityViewBinding, y as SchemaChangeCancelled, yn as CollectionRowActions, yr as FormSections, yt as CreationResultDialog, z as MarkdownEditorFieldBinding, zn as KeyValuePreview, zt as convertFileToJson } from "./util-CyIcgnv2.js";
2
- import { r as sanitizeUrl } from "./util-DB31IoJE.js";
3
- import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-Cxnmpyjl.js";
4
- import { a as MAX_EXPORT_ROWS, c as downloadDataAsCsv, d as escapeCsvFormula, f as getEntityCSVExportableData, i as EXPORT_PAGE_SIZE, l as downloadEntitiesExport, n as ExportCollectionAction, o as fetchAllEntitiesForExport, p as getEntityJsonExportableData, r as BasicExportAction, s as downloadBlob, u as entryToCSVRow } from "./export-LvIpE7sE.js";
1
+ import { $n as UserPreview, $r as isReferenceProperty, $t as downloadDataAsCsv, A as getFieldId, An as serializeSelectionQuery, Ar as SkeletonPropertyComponent, At as ImportNewPropertyFieldPreview, B as MapFieldBinding, Bn as useUrlController, Br as RecordMeta, C as EntityFormBinding, Cn as resolveOpenEntityMode, Cr as getEntityTitlePropertyKey, Ct as EntityViewBinding, D as getDefaultFieldConfig, Dn as SELECTION_PAGE_SIZE, Dr as EnumValuesChip, Dt as useCollectionEditorController, E as DEFAULT_FIELD_CONFIGS, En as MAX_SELECTION_ROWS, Er as StringPropertyPreview, Et as CollectionViewActions, F as SelectFieldBinding, Fn as SelectableTable, Fr as UrlComponentPreview, Ft as convertImportData, G as useSelectionDialog, Gn as SelectableTableContext, Gr as PropertyKeyHint, Gt as IMPORT_BATCH_SIZE, H as DateTimeFieldBinding, Hn as useNavigationStateController, Hr as LABEL_ICON_SIZE, Ht as getInferenceType, I as RepeatFieldBinding, In as CollectionRowActions, Ir as ImagePreview, It as flattenEntry, J as useBuildUrlController, Jn as ReadOnlyFieldBinding, Jr as getIconForProperty, Jt as convertFileToJson, K as SelectionTableBinding, Kn as ArrayCustomShapedFieldBinding, Kr as getBracketNotation, Kt as saveImportedEntities, L as ReferenceFieldBinding, Ln as mergeEntityActions, Lr as EmptyValue, Lt as mappedColumnTarget, M as TextFieldBinding, Mn as useSelectionController, Mr as renderSkeletonIcon, N as SwitchFieldBinding, Nn as VirtualTableInput, Nr as renderSkeletonImageThumbnail, Nt as ImportConversionProblems, O as getDefaultFieldId, On as resolveSelection, Or as StorageThumbnail, Ot as ConfigControllerProvider, P as StorageUploadFieldBinding, Pn as CollectionTableBinding, Pr as renderSkeletonText, Pt as convertDataToEntity, Q as useResolvedCollections, Qn as PropertyPreview, Qr as getResolvedPropertyInPath, Qt as downloadBlob, R as MultiSelectFieldBinding, Rn as useAdminContext, Rr as FormSections, Rt as processValueMapping, S as isSchemaChangeCancelled, Sn as resolveCollectionPathIds, Sr as getEntityPreviewKeys, St as reportsScopes, T as PropertyFieldBinding, Tn as SelectionMenu, Tr as ArrayPropertyPreview, Tt as EntityCardBinding, U as BlockFieldBinding, Un as useSideDialogsController, Ur as isSelfLabellingProperty, Ut as useImportConfig, V as KeyValueFieldBinding, Vn as NavigationStateContext, Vr as FieldBlock, W as ArrayOfReferencesFieldBinding, Wn as SideDialogsControllerContext, Wr as spanClass, Wt as ImportSaveInProgress, X as useTopLevelNavigation, Xn as FieldHelperText, Xr as getPropertiesWithPropertiesOrder, Xt as parseCsvRows, Y as useBuildNavigationStateController, Yn as LabelWithIcon, Yr as getIconForWidget, Yt as detectCsvDelimiter, Z as useResolvedViews, Zn as ArrayOfMapsPreview, Zr as getPropertyInPath, Zt as parseCsvToObjects, _ as useCollectionsConfigController, _n as getLastSegment, _r as useSidePanel, _t as deleteEntityAction, a as namespaceToPropertiesPath, an as unescapeCsvFormula, ar as ArrayOneOfPreview, at as getEntityViewWidth, b as asUnavailable, bn as removeInitialSlash, br as getUserLabel, bt as CreationResultDialog, c as buildCollectionGenerationCallback, cn as SearchIconsView, cr as ArrayEnumPreview, d as fromSerializableCollectionConfigs, dn as BreadcrumbsProvider, dr as ArrayOfReferencesPreview, dt as getInitialEntityValues, ei as isRelationProperty, en as downloadEntitiesExport, er as NumberPropertyPreview, et as useBuildCollectionRegistryController, f as fromSerializableProperties, fn as resolveEntityAction, fr as InlineEntityListPreview, ft as removeEmptyContainers, g as toSerializableProperty, gn as getCollectionPathsCombinations, gr as SidePanelControllerContext, gt as copyEntityAction, h as toSerializableProperties, hn as getCollectionBySlugWithin, hr as EntityPreviewBinding, ht as DetailViewBinding, i as namespaceToPropertiesOrderPath, in as getEntityJsonExportableData, ir as MapPropertyPreview, it as buildSidePanelsFromUrl, j as VectorFieldBinding, jr as renderSkeletonCaptionText, jt as DataNewPropertiesMapping, k as getFieldConfig, kn as selectionQueryToFindParams, kr as StorageThumbnailInternal, kt as useCollectionEditorDialogsState, l as validateCollectionJson, ln as FieldCaption, lr as ArrayOfStorageComponentsPreview, lt as extractTouchedValues, m as toSerializableCollectionConfig, mn as addInitialSlash, mr as useReferencePaths, mt as CollectionViewBinding, n as getFullIdPath, nn as escapeCsvFormula, nr as DatePreview, nt as resolveNavigationFrom, o as CollectionGenerationApiError, on as ArrayContainer, or as ArrayOfStringsPreview, ot as useBuildSidePanel, p as fromSerializableProperty, pn as resolveEntityView, pr as ReferencePreview, pt as zodToFormErrors, q as SideDialogs, qn as useClearRestoreValue, qr as getDefaultPropertiesOrder, qt as ImportFileUpload, r as idToPropertiesPath, rn as getEntityCSVExportableData, rr as KeyValuePreview, rt as useResolvedNavigationFrom, s as DEFAULT_COLLECTION_GENERATION_ENDPOINT, sn as PropertyConfigBadge, sr as ArrayPropertyEnumPreview, st as EditViewBinding, t as getFullId, tn as entryToCSVRow, tr as BooleanPreview, tt as useHistory, u as fromSerializableCollectionConfig, un as useBreadcrumbsController, ur as RelationPreview, ut as getChanges, v as LiveSchemaError, vn as isPathWithinRecord, vr as CollectionRegistryContext, vt as editEntityAction, w as EntityForm, wn as resolveViewMode, wr as getEntityTitlePropertyKeyForEntity, wt as CollectionCardViewBinding, x as createLiveSchemaClient, xn as removeTrailingSlash, xr as useResolvedUser, xt as callerHoldsScope, y as SchemaChangeCancelled, yn as removeInitialAndTrailingSlashes, yr as useCollectionRegistryController, yt as resetPasswordAction, z as MarkdownEditorFieldBinding, zn as UrlContext, zr as FormRail, zt as slashDateOrdersByColumn } from "./util-BRvKFMLa.js";
2
+ import { o as sanitizeUrl } from "./util-D7ebttKT.js";
3
+ import { i as PropertySelectEntry, n as ImportCollectionAction, r as ImportDataPreview } from "./import-DjQoRrIU.js";
4
+ import { a as MAX_EXPORT_ROWS, i as EXPORT_PAGE_SIZE, n as ExportCollectionAction, o as fetchAllEntitiesForExport, r as BasicExportAction } from "./export-DCHuPD1a.js";
5
5
  import React, { Suspense, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
6
6
  import { deepEqual } from "fast-equals";
7
7
  import { Avatar, Button, Card, CenteredView, ChevronDownIcon, ChevronsLeftIcon, ChevronsRightIcon, Chip, CircularProgressCenter, Collapse, Container, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, ExpandablePanel, IconButton, LogOutIcon, Markdown, Menu, MenuIcon, MenuItem, MoonIcon, PencilIcon, SearchBar, SettingsIcon, Sheet, Skeleton, StarIcon, SunIcon, SunMoonIcon, TextField, Tooltip, Typography, cls, defaultBorderMixin, iconSize, lazyChunk } from "@rebasepro/ui";
8
- import { buildRoutedRebaseData, getReferenceFrom, resolveDataSource } from "@rebasepro/common";
9
- import { CollectionResolverRegistrationContext, CollectionScopeProvider, CustomizationControllerContext, DEFAULT_API_PATH, ErrorView, IconForView, LanguageToggle, LoginView, NavigationBlockerProvider, NotFoundPage, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StudioBridgeRegistryProvider, UnsavedChangesDialog, UserSettingsView, buildCollapsedDefaults, getIcon, getLastSegment as getLastSegment$1, getNavigationEntriesFromPath, useAdminModeController, useAnalyticsController, useAuthController, useBridgeRegistration, useCollapsedGroups, useComponentOverride, useCustomizationController, useData, useDataSources, useLargeLayout, useModeController, useNavigationBlocker, useNavigationGroupLabel, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRestoreScroll, useSlot, useTranslation, useUserConfigurationPersistence } from "@rebasepro/app";
8
+ import { buildRoutedRebaseData, resolveDataSource } from "@rebasepro/common";
9
+ import { CollectionResolverRegistrationContext, CollectionScopeProvider, ConnectionLostBanner, CustomizationControllerContext, DEFAULT_API_PATH, ErrorView, IconForView, LanguageToggle, LoginView, NavigationBlockerProvider, NotFoundPage, RebaseDataContext, RebaseLogo, RebaseRoutes, SchemaDriftBanner, StudioBridgeRegistryProvider, UnsavedChangesDialog, UserSettingsView, buildCollapsedDefaults, getIcon, getLastSegment as getLastSegment$1, getNavigationEntriesFromPath, readEmailLinkAction, useAdminModeController, useAnalyticsController, useAuthController, useBridgeRegistration, useCollapsedGroups, useComponentOverride, useCustomizationController, useData, useDataSources, useLargeLayout, useModeController, useNavigationBlocker, useNavigationGroupLabel, useRebaseClient, useRebaseContext, useRebaseRegistry, useRebaseRegistryDispatch, useRestoreScroll, useSlot, useTranslation, useUserConfigurationPersistence } from "@rebasepro/app";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ import { diffCollections } from "@rebasepro/types";
11
12
  import { prettifyIdentifier, toArray } from "@rebasepro/utils";
12
13
  import { Link, NavLink, Outlet, Route, useLocation, useNavigate } from "react-router";
13
14
  import { DndContext, DragOverlay, KeyboardSensor, MeasuringStrategy, MouseSensor, TouchSensor, closestCenter, closestCorners, getFirstCollision, pointerWithin, rectIntersection, useDndMonitor, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
@@ -34,6 +35,27 @@ function CustomViewRoute({ view }) {
34
35
  return /* @__PURE__ */ jsx(Fragment, { children: view.view });
35
36
  }
36
37
  //#endregion
38
+ //#region src/components/NavigationLoadingErrorView.tsx
39
+ /**
40
+ * The collections or views could not be resolved: a `collections` or `views`
41
+ * builder threw, or a plugin's `modifyCollections` did, or something either of
42
+ * them awaited failed.
43
+ *
44
+ * That failure used to be caught, logged and stored as
45
+ * `navigationLoadingError`, and then read by nothing: the home page rendered
46
+ * an empty search bar and a deep link to a collection spun for ever, or said
47
+ * the collection was not registered — the wrong cause. This says what failed
48
+ * and offers the retry the navigation controller already had.
49
+ */
50
+ function NavigationLoadingErrorView({ error, onRetry }) {
51
+ const { t } = useTranslation();
52
+ return /* @__PURE__ */ jsx(ErrorView, {
53
+ title: t("error_loading_navigation"),
54
+ error,
55
+ onRetry
56
+ });
57
+ }
58
+ //#endregion
37
59
  //#region src/routes/RebaseRoute.tsx
38
60
  function RebaseRoute() {
39
61
  const location = useLocation();
@@ -42,6 +64,7 @@ function RebaseRoute() {
42
64
  const breadcrumbs = useBreadcrumbsController();
43
65
  const userConfigPersistence = useUserConfigurationPersistence();
44
66
  const ResolvedCollectionView = useComponentOverride("Collection.View", CollectionViewBinding);
67
+ const navigationState = useNavigationStateController();
45
68
  const hash = location.hash;
46
69
  const isSidePanel = hash.includes("#side");
47
70
  const isNew = hash.includes("#new") || hash.includes("#new_side");
@@ -70,6 +93,10 @@ function RebaseRoute() {
70
93
  else throw new Error("Unexpected navigation entry type");
71
94
  }) });
72
95
  }, [navigationEntries.map((entry) => entry.path).join(",")]);
96
+ if (navigationState.navigationLoadingError && !navigationEntries.some((entry) => entry.type === "collection")) return /* @__PURE__ */ jsx(CenteredView, { children: /* @__PURE__ */ jsx(NavigationLoadingErrorView, {
97
+ error: navigationState.navigationLoadingError,
98
+ onRetry: navigationState.refreshNavigation
99
+ }) });
73
100
  if (isNew) return /* @__PURE__ */ jsx(EntityFullScreenRoute, {
74
101
  pathname,
75
102
  navigationEntries,
@@ -201,11 +228,11 @@ function EntityFullScreenRoute({ pathname, navigationEntries, isNew, isCopy }) {
201
228
  const basePath = !entityId || isNew ? pathname : pathname.substring(0, pathname.lastIndexOf(`/${entityId}`));
202
229
  const entityPath = basePath + `/${entityId}`;
203
230
  const blocker = useNavigationBlocker(useCallback(({ currentLocation, nextLocation }) => {
204
- if (nextLocation.pathname.startsWith(entityPath)) return false;
231
+ if (isPathWithinRecord(nextLocation.pathname, entityPath)) return false;
205
232
  const nextHash = nextLocation.hash;
206
233
  if (nextHash === "#side" || nextHash === "#new_side") return false;
207
234
  const currentHash = currentLocation.hash;
208
- if ((currentHash === "#side" || currentHash === "#new_side") && (nextLocation.pathname === basePath || nextLocation.pathname.startsWith(entityPath))) return false;
235
+ if ((currentHash === "#side" || currentHash === "#new_side") && (nextLocation.pathname === basePath || isPathWithinRecord(nextLocation.pathname, entityPath))) return false;
209
236
  return blocked.current;
210
237
  }, [entityPath, basePath]));
211
238
  const lastCollectionEntry = [...navigationEntries].reverse().find((entry) => entry.type === "collection");
@@ -322,29 +349,39 @@ function UnresolvedCollectionView({ path }) {
322
349
  */
323
350
  function ReferenceWidget({ name, multiselect = false, path, disabled, value, onReferenceSelected, onMultipleReferenceSelected, previewProperties, fixedFilter, size, className, includeId, includeEntityLink }) {
324
351
  const collectionRegistryController = useCollectionRegistryController();
352
+ const { toCollectionPath, referenceTo } = useReferencePaths();
353
+ const collectionPath = toCollectionPath(path);
325
354
  const collection = useMemo(() => {
326
- return collectionRegistryController.getCollection(path);
327
- }, [path, collectionRegistryController.getCollection]);
355
+ return collectionRegistryController.getCollection(collectionPath);
356
+ }, [collectionPath, collectionRegistryController.getCollection]);
328
357
  const onSingleEntitySelected = useCallback((entity) => {
329
358
  if (disabled) return;
330
359
  if (onReferenceSelected) {
331
- const reference = entity ? getReferenceFrom(entity) : null;
360
+ const reference = entity ? referenceTo(entity) : null;
332
361
  onReferenceSelected?.({
333
362
  reference,
334
363
  entity
335
364
  });
336
365
  }
337
- }, [disabled, onReferenceSelected]);
366
+ }, [
367
+ disabled,
368
+ onReferenceSelected,
369
+ referenceTo
370
+ ]);
338
371
  const onMultipleEntitiesSelected = useCallback((entities) => {
339
372
  if (disabled) return;
340
373
  if (onMultipleReferenceSelected) onMultipleReferenceSelected({
341
- references: entities ? entities.map((e) => getReferenceFrom(e)) : null,
374
+ references: entities ? entities.map((e) => referenceTo(e)) : null,
342
375
  entities
343
376
  });
344
- }, [disabled, onReferenceSelected]);
377
+ }, [
378
+ disabled,
379
+ onReferenceSelected,
380
+ referenceTo
381
+ ]);
345
382
  const referenceDialogController = useSelectionDialog({
346
383
  multiselect,
347
- path,
384
+ path: collectionPath,
348
385
  collection,
349
386
  onSingleEntitySelected,
350
387
  onMultipleEntitiesSelected,
@@ -695,7 +732,6 @@ var DefaultAppBar = function DefaultAppBar({ title, endAdornment, startAdornment
695
732
  includeLanguageToggle && /* @__PURE__ */ jsx(LanguageToggle, {}),
696
733
  includeModeToggle && /* @__PURE__ */ jsxs(Menu, {
697
734
  trigger: /* @__PURE__ */ jsx(IconButton, {
698
- color: "inherit",
699
735
  "aria-label": "Toggle theme",
700
736
  children: mode === "dark" ? /* @__PURE__ */ jsx(MoonIcon, { size: iconSize.small }) : /* @__PURE__ */ jsx(SunIcon, { size: iconSize.small })
701
737
  }),
@@ -1160,7 +1196,6 @@ function DrawerFooterActions({ drawerOpen, drawerHovered, dropDownActions, user:
1160
1196
  className: "flex items-center gap-0",
1161
1197
  children: [/* @__PURE__ */ jsx(LanguageToggle, {}), /* @__PURE__ */ jsxs(Menu, {
1162
1198
  trigger: /* @__PURE__ */ jsx(IconButton, {
1163
- color: "inherit",
1164
1199
  "aria-label": t("toggle_theme", { defaultValue: "Toggle theme" }),
1165
1200
  className: "text-surface-500 dark:text-surface-400",
1166
1201
  children: mode === "dark" ? /* @__PURE__ */ jsx(MoonIcon, { size: iconSize.small }) : mode === "light" ? /* @__PURE__ */ jsx(SunIcon, { size: iconSize.small }) : /* @__PURE__ */ jsx(SunMoonIcon, { size: iconSize.small })
@@ -1368,14 +1403,21 @@ var Scaffold = React.memo(function Scaffold(props) {
1368
1403
  }),
1369
1404
  /* @__PURE__ */ jsxs("main", {
1370
1405
  className: "flex flex-col grow overflow-auto",
1371
- children: [hasAppBar && /* @__PURE__ */ jsx(DrawerHeader, {}), /* @__PURE__ */ jsx("div", {
1372
- className: cls("bg-surface-sheet", "grow overflow-auto m-0", "lg:border lg:border-hairline", {
1373
- "mt-1 lg:m-0 lg:mx-2 lg:mb-2 lg:rounded-xl": padding,
1374
- "lg:mt-2": !hasAppBar && padding,
1375
- "lg:mt-4": !hasAppBar && !padding
1376
- }),
1377
- children: /* @__PURE__ */ jsx(ErrorBoundary, { children: otherChildren })
1378
- })]
1406
+ children: [
1407
+ hasAppBar && /* @__PURE__ */ jsx(DrawerHeader, {}),
1408
+ /* @__PURE__ */ jsx(ConnectionLostBanner, { className: cls("px-2 pt-1", {
1409
+ "lg:pt-0 lg:pb-2": padding,
1410
+ "lg:pt-2": !hasAppBar && padding
1411
+ }) }),
1412
+ /* @__PURE__ */ jsx("div", {
1413
+ className: cls("bg-surface-sheet", "grow overflow-auto m-0", "lg:border lg:border-hairline", {
1414
+ "mt-1 lg:m-0 lg:mx-2 lg:mb-2 lg:rounded-xl": padding,
1415
+ "lg:mt-2": !hasAppBar && padding,
1416
+ "lg:mt-4": !hasAppBar && !padding
1417
+ }),
1418
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: otherChildren })
1419
+ })
1420
+ ]
1379
1421
  })
1380
1422
  ]
1381
1423
  })
@@ -1403,7 +1445,6 @@ function DrawerWrapper(props) {
1403
1445
  if (!useLargeLayout()) {
1404
1446
  if (!props.displayed) return null;
1405
1447
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
1406
- color: "inherit",
1407
1448
  "aria-label": t("open_menu"),
1408
1449
  onClick: () => props.setDrawerOpen(true),
1409
1450
  className: "absolute sm:top-2 sm:left-4 top-1 left-2",
@@ -1493,7 +1534,9 @@ function RebaseAuthGate({ children }) {
1493
1534
  const registry = useRebaseRegistry();
1494
1535
  const authController = useAuthController();
1495
1536
  if (authController?.initialLoading) return /* @__PURE__ */ jsx(CircularProgressCenter, { size: "large" });
1496
- if (!authController?.user) return /* @__PURE__ */ jsx(Fragment, { children: registry.authConfig?.loginView ?? /* @__PURE__ */ jsx(LoginView, { authController }) });
1537
+ const openedLink = typeof window !== "undefined" ? readEmailLinkAction(window.location)?.kind : void 0;
1538
+ const linkOpensOverSession = openedLink === "verify-email" || openedLink === "confirm-email-change" || openedLink === "magic-link";
1539
+ if (!authController?.user || linkOpensOverSession) return /* @__PURE__ */ jsx(Fragment, { children: registry.authConfig?.loginView ?? /* @__PURE__ */ jsx(LoginView, { authController }) });
1497
1540
  return /* @__PURE__ */ jsx(Fragment, { children });
1498
1541
  }
1499
1542
  //#endregion
@@ -1523,9 +1566,16 @@ function RebaseAuthGate({ children }) {
1523
1566
  * a browser downloads before the login screen paints. It cost 14 kB there, for
1524
1567
  * a dialog most sessions never open. The bundle budget caught it.
1525
1568
  */
1526
- var SchemaChangeDialog = lazyChunk(() => import("./SchemaChangeDialog-BeP0A4MJ.js").then((n) => n.n).then((m) => ({ default: m.SchemaChangeDialog })));
1569
+ var SchemaChangeDialog = lazyChunk(() => import("./SchemaChangeDialog-CcFSXvkK.js").then((n) => n.n).then((m) => ({ default: m.SchemaChangeDialog })));
1570
+ /** The answer when nobody asked. */
1571
+ var NOT_ASKED = {
1572
+ enabled: false,
1573
+ canPlan: false,
1574
+ canApply: false
1575
+ };
1527
1576
  function useLiveSchemaEditing(options) {
1528
- const { baseUrl, authKey, writeSourceOnly } = options;
1577
+ const { baseUrl, authKey } = options;
1578
+ const asking = options.enabled !== false;
1529
1579
  const optionsRef = useRef(options);
1530
1580
  optionsRef.current = options;
1531
1581
  const client = useMemo(() => options.client ?? createLiveSchemaClient({
@@ -1543,6 +1593,7 @@ function useLiveSchemaEditing(options) {
1543
1593
  /** Which review a plan response belongs to. See `reviewChange`. */
1544
1594
  const reviewToken = useRef(0);
1545
1595
  const ready = useCallback(() => {
1596
+ if (!asking) return Promise.resolve(NOT_ASKED);
1546
1597
  const key = [client, authKey];
1547
1598
  const current = probe.current;
1548
1599
  if (!current || current.key[0] !== key[0] || current.key[1] !== key[1]) probe.current = {
@@ -1550,7 +1601,11 @@ function useLiveSchemaEditing(options) {
1550
1601
  promise: client.status()
1551
1602
  };
1552
1603
  return probe.current.promise;
1553
- }, [client, authKey]);
1604
+ }, [
1605
+ client,
1606
+ authKey,
1607
+ asking
1608
+ ]);
1554
1609
  useEffect(() => {
1555
1610
  let cancelled = false;
1556
1611
  ready().then((answer) => {
@@ -1625,23 +1680,33 @@ function useLiveSchemaEditing(options) {
1625
1680
  setApplyError(err instanceof Error ? err.message : String(err));
1626
1681
  });
1627
1682
  }, [client, pending]);
1683
+ /**
1684
+ * "Edit source only": commit the collection, run nothing.
1685
+ *
1686
+ * Through the same door as an apply, so it is committed. It used to be a
1687
+ * write through the source-only editor that nobody committed, which every
1688
+ * later "Commit and apply" met as somebody else's work — 409, with the
1689
+ * dialog never saying why.
1690
+ */
1628
1691
  const onSourceOnly = useCallback(() => {
1629
- if (!pending || !writeSourceOnly) return;
1692
+ if (!pending) return;
1630
1693
  setApplying(true);
1631
1694
  setApplyError(void 0);
1632
1695
  const settle = pending;
1633
- writeSourceOnly(settle.change).then(() => {
1634
- clear();
1696
+ client.apply({
1697
+ ...settle.change,
1698
+ sourceOnly: true
1699
+ }).then((answer) => {
1700
+ setResult(answer);
1701
+ setApplying(false);
1635
1702
  settle.resolve();
1703
+ setPending(void 0);
1636
1704
  }, (err) => {
1637
1705
  setApplying(false);
1638
1706
  setApplyError(err instanceof Error ? err.message : String(err));
1639
1707
  });
1640
- }, [
1641
- pending,
1642
- writeSourceOnly,
1643
- clear
1644
- ]);
1708
+ }, [client, pending]);
1709
+ const sourceOnlyOffered = Boolean(plan && !plan.applicable && plan.changes.filter((change) => change.verdict !== "safe").every((change) => change.sourceOnly));
1645
1710
  const onClose = useCallback(() => {
1646
1711
  if (applying) return;
1647
1712
  const settle = pending;
@@ -1670,7 +1735,7 @@ function useLiveSchemaEditing(options) {
1670
1735
  applyError,
1671
1736
  onConfirm,
1672
1737
  onRetry: planError ? onRetry : void 0,
1673
- onSourceOnly: writeSourceOnly ? onSourceOnly : void 0,
1738
+ onSourceOnly: sourceOnlyOffered ? onSourceOnly : void 0,
1674
1739
  onClose,
1675
1740
  applyRefusedBecause: status && !status.canApply ? status.applyRefusedBecause : void 0,
1676
1741
  target: status && {
@@ -1735,7 +1800,8 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1735
1800
  throw e;
1736
1801
  }
1737
1802
  };
1738
- const forcedReadOnly = options?.readOnly;
1803
+ const noSchemaAccess = options?.mayReadSchema === false;
1804
+ const forcedReadOnly = noSchemaAccess ? true : options?.readOnly;
1739
1805
  const authKey = options?.authKey ?? null;
1740
1806
  const [availability, setAvailability] = useState({ state: "unknown" });
1741
1807
  useEffect(() => {
@@ -1778,12 +1844,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1778
1844
  baseUrl: `${String(clientBaseUrl).replace(/\/$/, "")}${clientApiPath}/admin/schema`,
1779
1845
  getAuthToken: resolveToken,
1780
1846
  authKey,
1781
- writeSourceOnly: async ({ collectionId, collection }) => {
1782
- await request("/collection/save", {
1783
- collectionId,
1784
- collectionData: collection
1785
- });
1786
- }
1847
+ enabled: forcedReadOnly !== true
1787
1848
  });
1788
1849
  /**
1789
1850
  * Perform a write, through the live editor when there is one.
@@ -1793,32 +1854,44 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1793
1854
  * deployment, a non-Postgres driver, a version too old to be asked — so
1794
1855
  * nothing about the editor depends on the feature being there.
1795
1856
  */
1796
- const write = async (collectionId, collection, sourceOnly) => {
1797
- if (!(await liveSchema.ready()).enabled) return sourceOnly();
1798
- await liveSchema.reviewChange({
1857
+ const write = async (collectionId, change) => {
1858
+ if ("patch" in change && change.patch.length === 0) return;
1859
+ const available = await liveSchema.ready();
1860
+ const proposed = {
1799
1861
  collectionId,
1800
- collection
1801
- });
1862
+ ...change
1863
+ };
1864
+ if (!available.enabled) {
1865
+ await request("/collection/save", "patch" in change ? {
1866
+ collectionId,
1867
+ patch: change.patch
1868
+ } : {
1869
+ collectionId,
1870
+ collectionData: change.collection
1871
+ });
1872
+ return;
1873
+ }
1874
+ await liveSchema.reviewChange(proposed);
1802
1875
  };
1803
1876
  const readOnly = forcedReadOnly ?? (availability.state === "known" ? !availability.enabled : buildModeGuess());
1804
- const readOnlyReason = availability.state === "known" && availability.reason ? availability.reason : "Collections can only be edited against a backend running the schema editor, which is off in production.";
1877
+ const readOnlyReason = noSchemaAccess ? void 0 : availability.state === "known" && availability.reason ? availability.reason : "Collections can only be edited against a backend running the schema editor, which is off in production.";
1805
1878
  const findCollection = (id) => parsedCollections.find((c) => c.id === id || c.slug === id);
1806
1879
  /**
1807
- * The whole collection as it should end up.
1880
+ * What to send for a collection that should end up as `saving`.
1808
1881
  *
1809
- * Live editing computes the proposed state by replacing one collection in
1810
- * the set, so it needs all of it: handed a patch, it would read every
1811
- * property the patch does not mention as a removal and refuse the change.
1812
- * A collection this does not recognise is a new one, and the patch is the
1813
- * whole of it.
1882
+ * For one that exists: the difference from `loaded` — what the person
1883
+ * changed — and nothing else. Both sides are the same view model, through
1884
+ * JSON, so whatever JSON cannot carry (a handler, a shared property, an
1885
+ * imported enum) is absent from both and never appears as a change; the
1886
+ * server writes only the keys the patch names. A collection this does not
1887
+ * recognise is a new one, and is sent whole.
1814
1888
  */
1815
- const wholeCollection = (id, patch) => {
1816
- const current = findCollection(id);
1817
- return current ? {
1818
- ...current,
1819
- ...patch
1820
- } : patch;
1889
+ const changeFor = (id, saving, loaded) => {
1890
+ const current = loaded ?? findCollection(id);
1891
+ return current ? { patch: diffCollections(current, saving) } : { collection: saving };
1821
1892
  };
1893
+ /** `findCollection`, as the record a patch is computed from. */
1894
+ const currentOf = (id) => findCollection(id) ?? {};
1822
1895
  return useMemo(() => ({
1823
1896
  loading: false,
1824
1897
  readOnly,
@@ -1830,61 +1903,53 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1830
1903
  if (found) return found;
1831
1904
  throw Error(`Collection ${id} not found in local mode`);
1832
1905
  },
1833
- saveCollection: async ({ id, collectionData }) => {
1834
- await write(id, collectionData, () => request("/collection/save", {
1835
- collectionId: id,
1836
- collectionData
1837
- }));
1906
+ saveCollection: async ({ id, collectionData, baseline }) => {
1907
+ await write(id, changeFor(id, collectionData, baseline));
1838
1908
  },
1839
1909
  updateCollection: async ({ id, collectionData }) => {
1840
- await write(id, wholeCollection(id, collectionData), () => request("/collection/save", {
1841
- collectionId: id,
1842
- collectionData
1843
- }));
1910
+ const current = findCollection(id);
1911
+ await write(id, current ? { patch: diffCollections(current, {
1912
+ ...current,
1913
+ ...collectionData
1914
+ }) } : { collection: collectionData });
1844
1915
  },
1845
1916
  deleteCollection: async ({ id }) => {
1846
- await request("/collection/delete", { collectionId: id });
1917
+ if (!(await liveSchema.ready()).enabled) {
1918
+ await request("/collection/delete", { collectionId: id });
1919
+ return;
1920
+ }
1921
+ await liveSchema.reviewChange({
1922
+ collectionId: id,
1923
+ remove: true
1924
+ });
1847
1925
  },
1848
1926
  saveProperty: async ({ path, propertyKey, property, newPropertiesOrder }) => {
1849
- const properties = {
1850
- ...findCollection(path)?.properties ?? {},
1851
- [propertyKey]: property
1852
- };
1853
- const proposed = wholeCollection(path, {
1854
- properties,
1927
+ const current = currentOf(path);
1928
+ await write(path, { patch: diffCollections(current, {
1929
+ ...current,
1930
+ properties: {
1931
+ ...current.properties ?? {},
1932
+ [propertyKey]: property
1933
+ },
1855
1934
  ...newPropertiesOrder ? { propertiesOrder: newPropertiesOrder } : {}
1856
- });
1857
- await write(path, proposed, async () => {
1858
- await request("/property/save", {
1859
- collectionId: path,
1860
- propertyKey,
1861
- propertyConfig: property
1862
- });
1863
- if (newPropertiesOrder) await request("/collection/save", {
1864
- collectionId: path,
1865
- collectionData: { propertiesOrder: newPropertiesOrder },
1866
- partial: true
1867
- });
1868
- });
1935
+ }) });
1869
1936
  },
1870
1937
  deleteProperty: async ({ path, propertyKey, newPropertiesOrder }) => {
1871
- await request("/property/delete", {
1872
- collectionId: path,
1873
- propertyKey
1874
- });
1875
- if (newPropertiesOrder) await request("/collection/save", {
1876
- collectionId: path,
1877
- collectionData: { propertiesOrder: newPropertiesOrder },
1878
- partial: true
1879
- });
1938
+ const current = currentOf(path);
1939
+ const { [propertyKey]: _removed, ...properties } = current.properties ?? {};
1940
+ await write(path, { patch: diffCollections(current, {
1941
+ ...current,
1942
+ properties,
1943
+ ...newPropertiesOrder ? { propertiesOrder: newPropertiesOrder } : {}
1944
+ }) });
1880
1945
  },
1881
1946
  updatePropertiesOrder: async ({ collection, fullPath, newPropertiesOrder }) => {
1882
- const collectionId = collection.id || fullPath.split("/").pop();
1883
- await request("/collection/save", {
1884
- collectionId,
1885
- collectionData: { propertiesOrder: newPropertiesOrder },
1886
- partial: true
1887
- });
1947
+ const collectionId = collection.id || fullPath.split("/").pop() || "";
1948
+ const current = currentOf(collectionId);
1949
+ await write(collectionId, { patch: diffCollections(current, {
1950
+ ...current,
1951
+ propertiesOrder: newPropertiesOrder
1952
+ }) });
1888
1953
  },
1889
1954
  updateKanbanColumnsOrder: async () => {},
1890
1955
  navigationEntries: [],
@@ -1903,7 +1968,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
1903
1968
  //#region src/components/RebaseNavigation.tsx
1904
1969
  var EMPTY_PLUGINS = [];
1905
1970
  var EMPTY_COLLECTIONS = [];
1906
- var CollectionsStudioView = lazyChunk(() => import("./RouterCollectionsStudioView-EK8Knq5I.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1971
+ var CollectionsStudioView = lazyChunk(() => import("./RouterCollectionsStudioView-SGBV4CMg.js").then((n) => n.n).then((m) => ({ default: m.RouterCollectionsStudioView })));
1907
1972
  /**
1908
1973
  * Navigation layer — builds and provides all admin navigation controllers:
1909
1974
  * collection registry, URL controller, navigation state, side entity,
@@ -1944,7 +2009,7 @@ function RebaseNavigation({ children }) {
1944
2009
  const defaultData = useData();
1945
2010
  const getCollectionRef = useRef(collectionRegistryController.getCollection);
1946
2011
  getCollectionRef.current = collectionRegistryController.getCollection;
1947
- useContext(CollectionResolverRegistrationContext)(useCallback((slug) => getCollectionRef.current(slug), []));
2012
+ useContext(CollectionResolverRegistrationContext)(useCallback((slug) => getCollectionRef.current(slug), []), collectionRegistryController.resolveDataPath);
1948
2013
  const routedData = useMemo(() => buildRoutedRebaseData({
1949
2014
  defaultData,
1950
2015
  sources: dataSources.sources,
@@ -1972,7 +2037,8 @@ function RebaseNavigation({ children }) {
1972
2037
  const internalConfigController = useLocalCollectionsConfigController(rebaseClient, resolvedCollections, collectionEditorEnabled ? {
1973
2038
  readOnly: collectionEditorOptions?.readOnly,
1974
2039
  getAuthToken: collectionEditorOptions?.getAuthToken ?? authController?.getAuthToken,
1975
- authKey: authController?.user?.uid ?? null
2040
+ authKey: authController?.user?.uid ?? null,
2041
+ mayReadSchema: reportsScopes(authController) ? callerHoldsScope(authController, "schema:read") : void 0
1976
2042
  } : { readOnly: true });
1977
2043
  const schemaView = useMemo(() => {
1978
2044
  if (!collectionEditorEnabled) return void 0;
@@ -2198,10 +2264,10 @@ function NavigationGroup({ children, group, minimised, isPreview, isPotentialCar
2198
2264
  const TitleContent = /* @__PURE__ */ jsxs("div", {
2199
2265
  className: cls("flex items-center", isPreview ? "px-1 py-0.5" : ""),
2200
2266
  children: [/* @__PURE__ */ jsx(Typography, {
2201
- variant: isPreview ? "body2" : "caption",
2267
+ variant: "micro",
2202
2268
  component: "h2",
2203
2269
  color: "secondary",
2204
- className: cls("px-4 py-1 rounded", "font-medium text-[10px] uppercase tracking-[0.08em] text-surface-400 dark:text-surface-400"),
2270
+ className: cls("py-1 rounded", isPreview && "px-4"),
2205
2271
  children: currentGroupLabel
2206
2272
  }), !isPreview && onEditGroup && !dndDisabled && /* @__PURE__ */ jsx(IconButton, {
2207
2273
  size: "smallest",
@@ -2229,7 +2295,7 @@ function NavigationGroup({ children, group, minimised, isPreview, isPotentialCar
2229
2295
  if (open !== !collapsed) onToggleCollapsed?.();
2230
2296
  },
2231
2297
  className: cls("mt-6"),
2232
- titleClassName: cls("min-h-0 p-0 border-none", "rounded flex items-center justify-between w-full", "hover:bg-transparent", "cursor-pointer select-none", collapsed && "bg-surface-field"),
2298
+ titleClassName: cls("min-h-0 p-0 px-3 -mx-3 w-auto border-none", "rounded flex items-center justify-between w-full", "hover:bg-transparent", "cursor-pointer select-none", collapsed && "bg-surface-field"),
2233
2299
  innerClassName: cls("mt-4", !minimised ? "pt-0" : ""),
2234
2300
  title: /* @__PURE__ */ jsx("div", {
2235
2301
  onMouseEnter: () => setIsHovered(true),
@@ -2339,6 +2405,7 @@ function NavigationCardBinding({ slug, collection, view, url, name, description,
2339
2405
  const favourite = (userConfigurationPersistence?.favouritePaths ?? []).includes(slug);
2340
2406
  const actionsArray = userConfigurationPersistence ? [/* @__PURE__ */ jsx(IconButton, {
2341
2407
  size: "small",
2408
+ className: favourite ? void 0 : "opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100 pointer-coarse:opacity-100",
2342
2409
  onClick: (e) => {
2343
2410
  e.preventDefault();
2344
2411
  e.stopPropagation();
@@ -3051,6 +3118,13 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
3051
3118
  additionalPluginActions
3052
3119
  ]
3053
3120
  }),
3121
+ navigationStateController.navigationLoadingError && /* @__PURE__ */ jsx("div", {
3122
+ className: "mb-4",
3123
+ children: /* @__PURE__ */ jsx(NavigationLoadingErrorView, {
3124
+ error: navigationStateController.navigationLoadingError,
3125
+ onRetry: navigationStateController.refreshNavigation
3126
+ })
3127
+ }),
3054
3128
  /* @__PURE__ */ jsx(FavouritesView, { hidden: performingSearch }),
3055
3129
  additionalChildrenStart,
3056
3130
  additionalPluginChildrenStart,
@@ -3181,8 +3255,8 @@ function ContentHomePage({ additionalActions, additionalChildrenStart, additiona
3181
3255
  }
3182
3256
  //#endregion
3183
3257
  //#region src/components/CollectionEditorDialogs.tsx
3184
- var CollectionEditorDialog = lazyChunk(() => import("./CollectionEditorDialog-CUtfS_49.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
3185
- var PropertyFormDialog = lazyChunk(() => import("./PropertyEditView-BpEbC0Q2.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
3258
+ var CollectionEditorDialog = lazyChunk(() => import("./CollectionEditorDialog-p5-I-Apu.js").then((n) => n.r).then((m) => ({ default: m.CollectionEditorDialog })));
3259
+ var PropertyFormDialog = lazyChunk(() => import("./PropertyEditView-DDB_X-00.js").then((n) => n.t).then((m) => ({ default: m.PropertyFormDialog })));
3186
3260
  /**
3187
3261
  * Renders the CollectionEditorDialog and PropertyFormDialog inside
3188
3262
  * the RebaseShell tree where admin-internal contexts
@@ -3788,6 +3862,6 @@ function MissingReferenceWidget({ path: pathProp }) {
3788
3862
  });
3789
3863
  }
3790
3864
  //#endregion
3791
- export { AdminModeSyncer, AppBar, ArrayContainer, ArrayCustomShapedFieldBinding, ArrayEnumPreview, ArrayOfMapsPreview, ArrayOfReferencesFieldBinding, ArrayOfReferencesPreview, ArrayOfStorageComponentsPreview, ArrayOfStringsPreview, ArrayOneOfPreview, ArrayPropertyEnumPreview, ArrayPropertyPreview, BasicExportAction, BlockFieldBinding, BooleanPreview, CollectionCardViewBinding, CollectionGenerationApiError, CollectionPanel, CollectionRegistryContext, CollectionRowActions, CollectionTableBinding, CollectionViewActions, CollectionViewBinding, CreationResultDialog, CustomViewRoute, DEFAULT_COLLECTION_GENERATION_ENDPOINT, DEFAULT_FIELD_CONFIGS, DataNewPropertiesMapping, DatePreview, DateTimeFieldBinding, DefaultDrawer, Drawer, DrawerFooterActions, DrawerNavigationGroup, DrawerNavigationItem, EXPORT_PAGE_SIZE, EmptyValue, EntityCardBinding, EntityForm, EntityFormBinding, EntityPreviewBinding, EntityViewBinding, EnumValuesChip, ExportCollectionAction, FieldBlock, FieldCaption, FieldHelperText, FormRail, FormSections, IMPORT_BATCH_SIZE, ImagePreview, ImportCollectionAction, ImportDataPreview, ImportFileUpload, ImportNewPropertyFieldPreview, ImportSaveInProgress, InlineEntityListPreview, KeyValueFieldBinding, KeyValuePreview, LABEL_ICON_SIZE, LabelWithIcon, LiveSchemaError, MAX_EXPORT_ROWS, MAX_SELECTION_ROWS, MapFieldBinding, MapPropertyPreview, MarkdownEditorFieldBinding, MissingReferenceWidget, MultiSelectFieldBinding, NavigationStateContext, NumberPropertyPreview, PropertyConfigBadge, PropertyFieldBinding, PropertyKeyHint, PropertyPreview, PropertySelectEntry, ReadOnlyFieldBinding, RebaseAuthGate, RebaseCMS, RebaseLayout, RebaseNavigation, RebaseRoute, RebaseRouteDefs, RebaseShell, RecordMeta, ReferenceFieldBinding, ReferencePreview, ReferenceWidget, RelationPreview, RepeatFieldBinding, SELECTION_PAGE_SIZE, Scaffold, SchemaChangeCancelled, SearchIconsView, SelectFieldBinding, SelectableTable, SelectableTableContext, SelectionMenu, SelectionTableBinding, SideDialogs, SidePanelControllerContext, SidePanelProvider, SkeletonPropertyComponent, StorageThumbnail, StorageThumbnailInternal, StorageUploadFieldBinding, StringPropertyPreview, SwitchFieldBinding, TextFieldBinding, UrlComponentPreview, UrlContext, UserPreview, VectorFieldBinding, VirtualTableInput, addInitialSlash, asUnavailable, buildCollectionGenerationCallback, buildSidePanelsFromUrl, convertDataToEntity, convertFileToJson, copyEntityAction, createLiveSchemaClient, createStaticDataController, deleteEntityAction, detectCsvDelimiter, downloadBlob, downloadDataAsCsv, downloadEntitiesExport, editEntityAction, entryToCSVRow, escapeCsvFormula, extractTouchedValues, fetchAllEntitiesForExport, flattenEntry, fromSerializableCollectionConfig, fromSerializableCollectionConfigs, fromSerializableProperties, fromSerializableProperty, getBracketNotation, getChanges, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultFieldConfig, getDefaultFieldId, getDefaultPropertiesOrder, getEntityCSVExportableData, getEntityJsonExportableData, getEntityPreviewKeys, getEntityTitlePropertyKey, getEntityTitlePropertyKeyForEntity, getEntityViewWidth, getFieldConfig, getFieldId, getFullId, getFullIdPath, getIconForProperty, getIconForWidget, getInferenceType, getInitialEntityValues, getLastSegment, getPropertiesWithPropertiesOrder, getPropertyInPath, getResolvedPropertyInPath, getUserLabel, idToPropertiesPath, isReferenceProperty, isRelationProperty, isSchemaChangeCancelled, isSelfLabellingProperty, mapPropertiesToConfigs, mapPropertyToConfig, mergeEntityActions, namespaceToPropertiesOrderPath, namespaceToPropertiesPath, parseCsvRows, parseCsvToObjects, processValueMapping, removeEmptyContainers, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, renderSkeletonCaptionText, renderSkeletonIcon, renderSkeletonImageThumbnail, renderSkeletonText, resetPasswordAction, resolveCollectionPathIds, resolveEntityAction, resolveEntityView, resolveNavigationFrom, resolveSelection, sanitizeUrl, saveImportedEntities, selectionQueryToFindParams, serializeSelectionQuery, spanClass, toSerializableCollectionConfig, toSerializableProperties, toSerializableProperty, useAdminContext, useApp, useBreadcrumbsController, useBuildCollectionRegistryController, useBuildNavigationStateController, useBuildSidePanel, useBuildUrlController, useClearRestoreValue, useCollectionDataController, useCollectionEditorController, useCollectionRegistryController, useCollectionsConfigController, useHistory, useImportConfig, useJsonCollectionsConfigController, useLiveSchemaEditing, useLocalCollectionsConfigController, useNavigationStateController, useResolvedCollections, useResolvedNavigationFrom, useResolvedUser, useResolvedViews, useSelectionController, useSelectionDialog, useSideDialogsController, useSidePanel, useTopLevelNavigation, useUrlController, validateCollectionJson, zodToFormErrors };
3865
+ export { AdminModeSyncer, AppBar, ArrayContainer, ArrayCustomShapedFieldBinding, ArrayEnumPreview, ArrayOfMapsPreview, ArrayOfReferencesFieldBinding, ArrayOfReferencesPreview, ArrayOfStorageComponentsPreview, ArrayOfStringsPreview, ArrayOneOfPreview, ArrayPropertyEnumPreview, ArrayPropertyPreview, BasicExportAction, BlockFieldBinding, BooleanPreview, CollectionCardViewBinding, CollectionGenerationApiError, CollectionPanel, CollectionRegistryContext, CollectionRowActions, CollectionTableBinding, CollectionViewActions, CollectionViewBinding, CreationResultDialog, CustomViewRoute, DEFAULT_COLLECTION_GENERATION_ENDPOINT, DEFAULT_FIELD_CONFIGS, DataNewPropertiesMapping, DatePreview, DateTimeFieldBinding, DefaultDrawer, Drawer, DrawerFooterActions, DrawerNavigationGroup, DrawerNavigationItem, EXPORT_PAGE_SIZE, EmptyValue, EntityCardBinding, EntityForm, EntityFormBinding, EntityPreviewBinding, EntityViewBinding, EnumValuesChip, ExportCollectionAction, FieldBlock, FieldCaption, FieldHelperText, FormRail, FormSections, IMPORT_BATCH_SIZE, ImagePreview, ImportCollectionAction, ImportConversionProblems, ImportDataPreview, ImportFileUpload, ImportNewPropertyFieldPreview, ImportSaveInProgress, InlineEntityListPreview, KeyValueFieldBinding, KeyValuePreview, LABEL_ICON_SIZE, LabelWithIcon, LiveSchemaError, MAX_EXPORT_ROWS, MAX_SELECTION_ROWS, MapFieldBinding, MapPropertyPreview, MarkdownEditorFieldBinding, MissingReferenceWidget, MultiSelectFieldBinding, NavigationStateContext, NumberPropertyPreview, PropertyConfigBadge, PropertyFieldBinding, PropertyKeyHint, PropertyPreview, PropertySelectEntry, ReadOnlyFieldBinding, RebaseAuthGate, RebaseCMS, RebaseLayout, RebaseNavigation, RebaseRoute, RebaseRouteDefs, RebaseShell, RecordMeta, ReferenceFieldBinding, ReferencePreview, ReferenceWidget, RelationPreview, RepeatFieldBinding, SELECTION_PAGE_SIZE, Scaffold, SchemaChangeCancelled, SearchIconsView, SelectFieldBinding, SelectableTable, SelectableTableContext, SelectionMenu, SelectionTableBinding, SideDialogs, SidePanelControllerContext, SidePanelProvider, SkeletonPropertyComponent, StorageThumbnail, StorageThumbnailInternal, StorageUploadFieldBinding, StringPropertyPreview, SwitchFieldBinding, TextFieldBinding, UrlComponentPreview, UrlContext, UserPreview, VectorFieldBinding, VirtualTableInput, addInitialSlash, asUnavailable, buildCollectionGenerationCallback, buildSidePanelsFromUrl, convertDataToEntity, convertFileToJson, convertImportData, copyEntityAction, createLiveSchemaClient, createStaticDataController, deleteEntityAction, detectCsvDelimiter, downloadBlob, downloadDataAsCsv, downloadEntitiesExport, editEntityAction, entryToCSVRow, escapeCsvFormula, extractTouchedValues, fetchAllEntitiesForExport, flattenEntry, fromSerializableCollectionConfig, fromSerializableCollectionConfigs, fromSerializableProperties, fromSerializableProperty, getBracketNotation, getChanges, getCollectionBySlugWithin, getCollectionPathsCombinations, getDefaultFieldConfig, getDefaultFieldId, getDefaultPropertiesOrder, getEntityCSVExportableData, getEntityJsonExportableData, getEntityPreviewKeys, getEntityTitlePropertyKey, getEntityTitlePropertyKeyForEntity, getEntityViewWidth, getFieldConfig, getFieldId, getFullId, getFullIdPath, getIconForProperty, getIconForWidget, getInferenceType, getInitialEntityValues, getLastSegment, getPropertiesWithPropertiesOrder, getPropertyInPath, getResolvedPropertyInPath, getUserLabel, idToPropertiesPath, isReferenceProperty, isRelationProperty, isSchemaChangeCancelled, isSelfLabellingProperty, mapPropertiesToConfigs, mapPropertyToConfig, mappedColumnTarget, mergeEntityActions, namespaceToPropertiesOrderPath, namespaceToPropertiesPath, parseCsvRows, parseCsvToObjects, processValueMapping, removeEmptyContainers, removeInitialAndTrailingSlashes, removeInitialSlash, removeTrailingSlash, renderSkeletonCaptionText, renderSkeletonIcon, renderSkeletonImageThumbnail, renderSkeletonText, resetPasswordAction, resolveCollectionPathIds, resolveEntityAction, resolveEntityView, resolveNavigationFrom, resolveSelection, sanitizeUrl, saveImportedEntities, selectionQueryToFindParams, serializeSelectionQuery, slashDateOrdersByColumn, spanClass, toSerializableCollectionConfig, toSerializableProperties, toSerializableProperty, unescapeCsvFormula, useAdminContext, useApp, useBreadcrumbsController, useBuildCollectionRegistryController, useBuildNavigationStateController, useBuildSidePanel, useBuildUrlController, useClearRestoreValue, useCollectionDataController, useCollectionEditorController, useCollectionRegistryController, useCollectionsConfigController, useHistory, useImportConfig, useJsonCollectionsConfigController, useLiveSchemaEditing, useLocalCollectionsConfigController, useNavigationStateController, useResolvedCollections, useResolvedNavigationFrom, useResolvedUser, useResolvedViews, useSelectionController, useSelectionDialog, useSideDialogsController, useSidePanel, useTopLevelNavigation, useUrlController, validateCollectionJson, zodToFormErrors };
3792
3866
 
3793
3867
  //# sourceMappingURL=index.js.map