@rebasepro/admin 0.3.0 → 0.4.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 (86) hide show
  1. package/dist/{CollectionEditorDialog-D0VqpLPO.js → CollectionEditorDialog-Bo86h-d-.js} +22 -5
  2. package/dist/CollectionEditorDialog-Bo86h-d-.js.map +1 -0
  3. package/dist/{CollectionsStudioView-Bc3Rxxc2.js → CollectionsStudioView-bsg4AT_Z.js} +4 -4
  4. package/dist/{CollectionsStudioView-Bc3Rxxc2.js.map → CollectionsStudioView-bsg4AT_Z.js.map} +1 -1
  5. package/dist/{ExportCollectionAction-Ckc-09BQ.js → ExportCollectionAction-Cf-Id5uO.js} +35 -27
  6. package/dist/ExportCollectionAction-Cf-Id5uO.js.map +1 -0
  7. package/dist/{ImportCollectionAction-BqjIrC3Z.js → ImportCollectionAction-LN5sreK9.js} +2 -2
  8. package/dist/{ImportCollectionAction-BqjIrC3Z.js.map → ImportCollectionAction-LN5sreK9.js.map} +1 -1
  9. package/dist/{PropertyEditView-CvRSV-A2.js → PropertyEditView-jCWCxmCz.js} +2 -2
  10. package/dist/{PropertyEditView-CvRSV-A2.js.map → PropertyEditView-jCWCxmCz.js.map} +1 -1
  11. package/dist/collection_editor_ui.js +3 -3
  12. package/dist/components/CollectionPanel.d.ts +83 -0
  13. package/dist/components/EntityDetailView.d.ts +0 -3
  14. package/dist/components/EntityEditView.d.ts +2 -3
  15. package/dist/components/RebaseRouteDefs.d.ts +1 -1
  16. package/dist/components/SelectableTable/SelectableTable.d.ts +2 -2
  17. package/dist/components/SelectableTable/SelectableTableContext.d.ts +1 -1
  18. package/dist/components/SelectableTable/SelectionStore.d.ts +3 -3
  19. package/dist/components/admin/index.d.ts +1 -3
  20. package/dist/components/index.d.ts +1 -0
  21. package/dist/editor.js +15 -5
  22. package/dist/editor.js.map +1 -1
  23. package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +1 -1
  24. package/dist/hooks/navigation/useResolvedViews.d.ts +2 -5
  25. package/dist/{index-UQOMHwt1.js → index-BrqSvMG0.js} +3 -3
  26. package/dist/index-BrqSvMG0.js.map +1 -0
  27. package/dist/{index-DY2k5TtG.js → index-Cb0bPnzZ.js} +3 -3
  28. package/dist/index-Cb0bPnzZ.js.map +1 -0
  29. package/dist/{index-BCcLwgfe.js → index-z3H8iqsj.js} +2 -2
  30. package/dist/{index-BCcLwgfe.js.map → index-z3H8iqsj.js.map} +1 -1
  31. package/dist/index.d.ts +2 -4
  32. package/dist/index.js +228 -295
  33. package/dist/index.js.map +1 -1
  34. package/dist/util/entity_view_constants.d.ts +6 -0
  35. package/dist/util/resolutions.d.ts +1 -2
  36. package/dist/{util-ZM9gQuCv.js → util-CvNp6A-r.js} +422 -798
  37. package/dist/util-CvNp6A-r.js.map +1 -0
  38. package/package.json +8 -8
  39. package/src/collection_editor/pgColumnToProperty.ts +19 -2
  40. package/src/collection_editor/validateCollectionJson.ts +12 -12
  41. package/src/components/CollectionPanel.tsx +155 -0
  42. package/src/components/DefaultDrawer.tsx +2 -2
  43. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +64 -34
  44. package/src/components/EntityCollectionView/EntityCollectionListView.tsx +8 -1
  45. package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -1
  46. package/src/components/EntityCollectionView/hooks/useCollectionInlineEditor.ts +1 -0
  47. package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +69 -18
  48. package/src/components/EntityDetailView.tsx +36 -37
  49. package/src/components/EntityEditView.tsx +108 -51
  50. package/src/components/EntityEditViewFormActions.tsx +4 -4
  51. package/src/components/EntitySidePanel.tsx +47 -14
  52. package/src/components/PropertyCollectionView.tsx +1 -0
  53. package/src/components/RebaseRouteDefs.tsx +4 -6
  54. package/src/components/SelectableTable/SelectableTable.tsx +24 -22
  55. package/src/components/SelectableTable/SelectableTableContext.tsx +2 -1
  56. package/src/components/SelectableTable/SelectionStore.ts +4 -4
  57. package/src/components/admin/index.ts +1 -3
  58. package/src/components/index.ts +3 -3
  59. package/src/data_export/export/BasicExportAction.tsx +11 -9
  60. package/src/data_export/export/ExportCollectionAction.tsx +15 -13
  61. package/src/editor/editor.tsx +20 -4
  62. package/src/form/EntityForm.tsx +3 -3
  63. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -1
  64. package/src/hooks/navigation/useBuildNavigationStateController.tsx +2 -3
  65. package/src/hooks/navigation/useResolvedCollections.ts +2 -10
  66. package/src/hooks/navigation/useResolvedViews.tsx +6 -48
  67. package/src/hooks/useBuildSideEntityController.tsx +20 -3
  68. package/src/index.ts +6 -5
  69. package/src/util/entity_view_constants.ts +6 -0
  70. package/src/util/previews.ts +9 -1
  71. package/src/util/resolutions.ts +2 -6
  72. package/dist/CollectionEditorDialog-D0VqpLPO.js.map +0 -1
  73. package/dist/ExportCollectionAction-Ckc-09BQ.js.map +0 -1
  74. package/dist/components/admin/RoleChip.d.ts +0 -4
  75. package/dist/components/admin/RolesFilterSelect.d.ts +0 -2
  76. package/dist/components/admin/RolesView.d.ts +0 -4
  77. package/dist/components/admin/UserRolesSelectField.d.ts +0 -2
  78. package/dist/components/admin/UsersView.d.ts +0 -4
  79. package/dist/index-DY2k5TtG.js.map +0 -1
  80. package/dist/index-UQOMHwt1.js.map +0 -1
  81. package/dist/util-ZM9gQuCv.js.map +0 -1
  82. package/src/components/admin/RoleChip.tsx +0 -23
  83. package/src/components/admin/RolesFilterSelect.tsx +0 -45
  84. package/src/components/admin/RolesView.tsx +0 -470
  85. package/src/components/admin/UserRolesSelectField.tsx +0 -50
  86. package/src/components/admin/UsersView.tsx +0 -693
@@ -1,12 +1,12 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
- import { DialogActions, Typography, IconButton, Button, AlertCircleIcon, LoadingButton, cls, defaultBorderMixin, Tooltip, CopyIcon, ImageOffIcon, ExternalLinkIcon, FileTextIcon, Skeleton, Table, TableBody, TableRow, TableCell, Chip, getColorSchemeForSeed, ErrorBoundary, FunctionSquareIcon, iconSize, CircleIcon, HashIcon, LinkIcon, Rows3Icon, UploadIcon, RepeatIcon, VoteIcon, CalendarIcon, FlagIcon, GlobeIcon, MailIcon, AlignLeftIcon, TextIcon, ArrowRightToLineIcon, HistoryIcon, CircularProgressCenter, Tab, Maximize2Icon, PencilIcon, Alert, Tabs, CodeIcon, CenteredView, useDebouncedCallback, TextareaAutosize, focusedDisabled, MultiSelect, MultiSelectItem, Select, SelectItem, TextField, BooleanSwitch, DateTimeField, useInjectStyles, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, XIcon, PopoverPrimitive, SearchIcon, CircularProgress, ChevronDownIcon, Separator, paperMixin, CheckIcon, Menu, MenuItem, MoreVerticalIcon, Checkbox, Badge, SearchBar, Label, BooleanSwitchWithLabel, useOutsideAlerter, VirtualTable, getColorSchemeForKey, Container, PlusIcon, TableHeader, Trash2Icon, Dialog, DialogTitle, DialogContent, Sheet, debounce, coolIconKeys, lucideIcons, ExpandablePanel, HandleIcon, MinusIcon, ChevronUpIcon, Collapse, EyeOffIcon, EyeIcon, FolderUpIcon, ListOrderedIcon, UserIcon, ListIcon, QuoteIcon, FileUpload, ChevronRightIcon, SettingsIcon, Popover, CHIP_COLORS, Card, ResizablePanels, Markdown, RefreshCwIcon, TableIcon, LayoutGridIcon, KanbanIcon, ToggleButtonGroup, ColumnsIcon, CheckCircleIcon, KeyRoundIcon, Portal, FilterXIcon, FilterChip, ChevronsUpDownIcon, ArrowLeftIcon, FilterIcon, MoonIcon, SunIcon, SunMoonIcon, LogOutIcon, Avatar, ChevronsLeftIcon, ChevronsRightIcon, MenuIcon, ArrowRightIcon, AlertTriangleIcon, XCircleIcon } from "@rebasepro/ui";
3
+ import { DialogActions, Typography, IconButton, Button, AlertCircleIcon, LoadingButton, cls, defaultBorderMixin, Tooltip, CopyIcon, ImageOffIcon, ExternalLinkIcon, FileTextIcon, Skeleton, Table, TableBody, TableRow, TableCell, Chip, getColorSchemeForSeed, ErrorBoundary, FunctionSquareIcon, iconSize, CircleIcon, HashIcon, LinkIcon, Rows3Icon, UploadIcon, RepeatIcon, VoteIcon, CalendarIcon, FlagIcon, GlobeIcon, MailIcon, AlignLeftIcon, TextIcon, ArrowRightToLineIcon, HistoryIcon, CircularProgressCenter, Tab, Maximize2Icon, PencilIcon, Alert, Tabs, CodeIcon, CenteredView, useDebouncedCallback, TextareaAutosize, focusedDisabled, MultiSelect, MultiSelectItem, Select, SelectItem, TextField, BooleanSwitch, DateTimeField, useInjectStyles, fieldBackgroundInvisibleMixin, fieldBackgroundMixin, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, XIcon, PopoverPrimitive, SearchIcon, CircularProgress, ChevronDownIcon, Separator, paperMixin, CheckIcon, Menu, MenuItem, MoreVerticalIcon, Checkbox, Badge, SearchBar, Label, BooleanSwitchWithLabel, useOutsideAlerter, VirtualTable, Dialog, Sheet, PlusIcon, debounce, coolIconKeys, lucideIcons, ExpandablePanel, HandleIcon, MinusIcon, ChevronUpIcon, Collapse, EyeOffIcon, EyeIcon, Trash2Icon, FolderUpIcon, ListOrderedIcon, UserIcon, ListIcon, QuoteIcon, FileUpload, ChevronRightIcon, TableHeader, SettingsIcon, Popover, CHIP_COLORS, Card, ResizablePanels, getColorSchemeForKey, Markdown, RefreshCwIcon, DialogContent, TableIcon, LayoutGridIcon, KanbanIcon, ToggleButtonGroup, ColumnsIcon, DialogTitle, CheckCircleIcon, KeyRoundIcon, Portal, FilterXIcon, FilterChip, ChevronsUpDownIcon, ArrowLeftIcon, FilterIcon, MoonIcon, SunIcon, SunMoonIcon, LogOutIcon, Avatar, ChevronsLeftIcon, ChevronsRightIcon, MenuIcon, ArrowRightIcon, AlertTriangleIcon, XCircleIcon } from "@rebasepro/ui";
4
4
  import * as React from "react";
5
5
  import React__default, { useRef, useEffect, useState, useMemo, lazy, Suspense, useCallback, useSyncExternalStore, useContext, createContext, forwardRef, memo, useLayoutEffect, createElement } from "react";
6
- import { useTranslation, useStorageSource, ErrorView, buildEnumLabel, getColorScheme, useAuthController, useCustomizationController, useAnalyticsController, IconForView, useEntityFetch, useModeController, useRebaseContext, usePermissions, createFormexStub, useSlot, resolveComponentRef, getIcon, PluginProviderStack, useUserSelector, UserDisplay, useSnackbarController, ErrorTooltip, useStorageUploadController, useData, useRelationSelector, getRowHeight, getEntityFromCache, useLargeLayout, getColumnKeysForProperty, DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE$1, getEntityFromMemoryCache, saveEntityToMemoryCache, CONTAINER_FULL_WIDTH, ADDITIONAL_TAB_WIDTH, FORM_CONTAINER_WIDTH, useInternalUserManagementController, ConfirmationDialog, useUnsavedChangesDialog, UnsavedChangesDialog, useColumnIds, useDataTableController, saveEntityWithCallbacks, iconsSearch, deleteEntityWithCallbacks, useUserConfigurationPersistence, useScrollRestoration, useBridgeRegistration, useAdminModeController, RebaseLogo, LanguageToggle, useRebaseRegistry, buildCollapsedDefaults, useCollapsedGroups, useBuildLocalConfigurationPersistence, useRebaseClient, CustomizationControllerContext, StudioBridgeRegistryProvider, flattenKeys, removeEntityFromCache, saveEntityToCache, removeEntityFromMemoryCache, getFormFieldKeys } from "@rebasepro/core";
6
+ import { useTranslation, useStorageSource, ErrorView, buildEnumLabel, getColorScheme, useAuthController, useCustomizationController, useAnalyticsController, IconForView, useEntityFetch, useModeController, useRebaseContext, usePermissions, createFormexStub, useSlot, resolveComponentRef, getIcon, PluginProviderStack, useUserSelector, UserDisplay, useSnackbarController, ErrorTooltip, useStorageUploadController, useData, useRelationSelector, getRowHeight, getEntityFromCache, useLargeLayout, getColumnKeysForProperty, DEFAULT_PAGE_SIZE as DEFAULT_PAGE_SIZE$1, getEntityFromMemoryCache, saveEntityToMemoryCache, CONTAINER_FULL_WIDTH, ADDITIONAL_TAB_WIDTH, FORM_CONTAINER_WIDTH, useUnsavedChangesDialog, UnsavedChangesDialog, useColumnIds, useDataTableController, saveEntityWithCallbacks, iconsSearch, deleteEntityWithCallbacks, useInternalUserManagementController, ConfirmationDialog, useUserConfigurationPersistence, useScrollRestoration, useBridgeRegistration, useAdminModeController, RebaseLogo, LanguageToggle, useRebaseRegistry, buildCollapsedDefaults, useCollapsedGroups, useBuildLocalConfigurationPersistence, useRebaseClient, CustomizationControllerContext, StudioBridgeRegistryProvider, flattenKeys, removeEntityFromCache, saveEntityToCache, removeEntityFromMemoryCache, getFormFieldKeys } from "@rebasepro/core";
7
7
  import ExcelJS from "exceljs";
8
- import { isPropertyBuilder, enumToObjectEntries, getLabelOrConfigFrom, resolveArrayProperties, getEntityImagePreviewPropertyKey, resolveDefaultSelectedView, getSubcollections, removeInitialAndTrailingSlashes, resolveEnumValues, getReferenceFrom, normalizeToEntityRelation, getRelationFrom, isReadOnly, getLocalChangesBackup, getNavigationEntriesFromPath, CollectionRegistry, getParentReferencesFromPath, canReadCollection, defaultUsersCollection, resolveCollectionPathIds, resolveProperty, isHidden, getArrayResolvedProperties, DEFAULT_ONE_OF_VALUE, getDefaultValueFor, DEFAULT_ONE_OF_TYPE, getDefaultValueFortype, resolveStorageFilenameString, resolveStoragePathString, resolveRelationProperty, getTableName, getDefaultValuesFor } from "@rebasepro/common";
9
- import { EntityRelation, EntityReference, getDataSourceCapabilities, GeoPoint, Vector } from "@rebasepro/types";
8
+ import { isPropertyBuilder, enumToObjectEntries, getLabelOrConfigFrom, resolveArrayProperties, getEntityImagePreviewPropertyKey, resolveDefaultSelectedView, getSubcollections, removeInitialAndTrailingSlashes, resolveEnumValues, getReferenceFrom, normalizeToEntityRelation, getRelationFrom, isReadOnly, getLocalChangesBackup, getNavigationEntriesFromPath, CollectionRegistry, getParentReferencesFromPath, canReadCollection, resolveCollectionPathIds, resolveProperty, isHidden, getArrayResolvedProperties, DEFAULT_ONE_OF_VALUE, getDefaultValueFor, DEFAULT_ONE_OF_TYPE, getDefaultValueFortype, resolveStorageFilenameString, resolveStoragePathString, resolveRelationProperty, getTableName, getDefaultValuesFor } from "@rebasepro/common";
9
+ import { EntityRelation, EntityReference, GeoPoint, getDataSourceCapabilities, Vector } from "@rebasepro/types";
10
10
  import { useFormex, setIn, Field, getIn, useCreateFormex, Formex } from "@rebasepro/formex";
11
11
  import { inferTypeFromValue } from "@rebasepro/schema-inference";
12
12
  import { hydrateRegExp, getValueInPath, mergeDeep, getHashValue, pick, randomString, toArray, defaultDateFormat, isObject } from "@rebasepro/utils";
@@ -1951,6 +1951,10 @@ function getDefaultPropertiesOrder(collection) {
1951
1951
  if (collection.propertiesOrder) return collection.propertiesOrder;
1952
1952
  return [...Object.keys(collection.properties), ...(collection.additionalFields ?? []).map((field) => field.key)];
1953
1953
  }
1954
+ function isHiddenProperty(property) {
1955
+ if (!property) return false;
1956
+ return Boolean(property.ui?.hideFromCollection);
1957
+ }
1954
1958
  function getEntityPreviewKeys(authController, targetCollection, fields, previewProperties, limit = 3) {
1955
1959
  const allProperties = Object.keys(targetCollection.properties);
1956
1960
  let listProperties = previewProperties?.filter((p) => allProperties.includes(p));
@@ -1967,7 +1971,7 @@ function getEntityPreviewKeys(authController, targetCollection, fields, previewP
1967
1971
  return !isIdProp;
1968
1972
  }).filter((key) => {
1969
1973
  const property = targetCollection.properties[key];
1970
- return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isRelationProperty(property);
1974
+ return property && !isPropertyBuilder(property) && !isReferenceProperty(property) && !isRelationProperty(property) && !isHiddenProperty(property);
1971
1975
  }).slice(0, limit);
1972
1976
  }
1973
1977
  }
@@ -1981,6 +1985,9 @@ function getEntityTitlePropertyKey(collection, propertyConfigs) {
1981
1985
  const property = collection.properties[key];
1982
1986
  if (property && !isPropertyBuilder(property)) {
1983
1987
  const prop = property;
1988
+ if (isHiddenProperty(prop)) {
1989
+ continue;
1990
+ }
1984
1991
  if (prop.type === "string" && !prop.ui?.multiline && !prop.ui?.markdown && !prop.storage && !prop.isId) {
1985
1992
  if (!firstStringCandidate) {
1986
1993
  firstStringCandidate = key;
@@ -2612,9 +2619,6 @@ function EntityView(t0) {
2612
2619
  }
2613
2620
  return t8;
2614
2621
  }
2615
- const EntityHistoryView$2 = lazy(() => import("./index-BCcLwgfe.js").then((m) => ({
2616
- default: m.EntityHistoryView
2617
- })));
2618
2622
  const BUILTIN_ENTITY_VIEWS = {
2619
2623
  "__rebase_history": {
2620
2624
  key: "__rebase_history",
@@ -2622,7 +2626,6 @@ const BUILTIN_ENTITY_VIEWS = {
2622
2626
  tabComponent: React__default.createElement(HistoryIcon, {
2623
2627
  size: 20
2624
2628
  }),
2625
- Builder: EntityHistoryView$2,
2626
2629
  position: "end"
2627
2630
  }
2628
2631
  };
@@ -2702,12 +2705,12 @@ function EntityJsonPreview(t0) {
2702
2705
  }
2703
2706
  return t4;
2704
2707
  }
2705
- const EntityHistoryView$1 = lazy(() => import("./index-BCcLwgfe.js").then((m) => ({
2708
+ const MAIN_TAB_VALUE = "__main_##Q$SC^#S6";
2709
+ const JSON_TAB_VALUE = "__json";
2710
+ const HISTORY_TAB_VALUE = "__rebase_history";
2711
+ const EntityHistoryView$1 = lazy(() => import("./index-z3H8iqsj.js").then((m) => ({
2706
2712
  default: m.EntityHistoryView
2707
2713
  })));
2708
- const MAIN_TAB_VALUE$1 = "__main_##Q$SC^#S6";
2709
- const JSON_TAB_VALUE$1 = "__json";
2710
- const HISTORY_TAB_VALUE$1 = "__rebase_history";
2711
2714
  function EntityDetailView(t0) {
2712
2715
  const $ = c(15);
2713
2716
  let entityId;
@@ -2815,13 +2818,22 @@ function EntityDetailViewInner({
2815
2818
  status: "existing",
2816
2819
  entityId
2817
2820
  }), [collection, entityId]);
2818
- const [selectedTab, setSelectedTab] = useState(selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE$1);
2821
+ const hasAppliedDefault = useRef(false);
2822
+ const [selectedTab, setSelectedTab] = useState(() => {
2823
+ const val = selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
2824
+ hasAppliedDefault.current = true;
2825
+ return val === "edit" ? MAIN_TAB_VALUE : val;
2826
+ });
2819
2827
  useEffect(() => {
2820
- const target = selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE$1;
2828
+ const val_0 = hasAppliedDefault.current ? selectedTabProp ?? MAIN_TAB_VALUE : selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
2829
+ const target = val_0 === "edit" ? MAIN_TAB_VALUE : val_0;
2830
+ if (!hasAppliedDefault.current) {
2831
+ hasAppliedDefault.current = true;
2832
+ }
2821
2833
  if (target !== selectedTab) {
2822
2834
  setSelectedTab(target);
2823
2835
  }
2824
- }, [selectedTabProp, defaultSelectedView]);
2836
+ }, [selectedTabProp]);
2825
2837
  const subcollections = getSubcollections(collection).filter((c2) => !c2.hideFromNavigation);
2826
2838
  const subcollectionsCount = subcollections?.length ?? 0;
2827
2839
  const customViews = collection.entityViews ?? [];
@@ -2832,7 +2844,7 @@ function EntityDetailViewInner({
2832
2844
  const {
2833
2845
  resolvedEntityViews
2834
2846
  } = resolvedSelectedEntityView(customViews, customizationController, selectedTab);
2835
- const mainViewVisible = selectedTab === MAIN_TAB_VALUE$1;
2847
+ const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
2836
2848
  const mountedTabsRef = useRef(/* @__PURE__ */ new Set());
2837
2849
  if (selectedTab) {
2838
2850
  mountedTabsRef.current.add(selectedTab);
@@ -2873,7 +2885,8 @@ function EntityDetailViewInner({
2873
2885
  disabled: true
2874
2886
  }), [entityId, parentCollectionSlugs, parentEntityIds, path, collection, context, readOnlyFormContext, layout]);
2875
2887
  const pluginActionsTop = useSlot("form.actions.top", formActionTopProps);
2876
- const detailViewConfig = collection.detailView;
2888
+ const formViewConfig = collection.formView;
2889
+ const FormViewBuilder = formViewConfig?.Builder ? resolveComponentRef(formViewConfig.Builder) : null;
2877
2890
  const titlePropertyKey = getEntityTitlePropertyKey(collection, customizationController.propertyConfigs);
2878
2891
  const title = (usedEntity?.values && titlePropertyKey ? getValueInPath(usedEntity.values, titlePropertyKey) : void 0) ?? collection.singularName ?? collection.name;
2879
2892
  const nonActionCustomViews = useMemo(() => resolvedEntityViews.filter((e) => !e.includeActions), [resolvedEntityViews]);
@@ -2890,11 +2903,11 @@ function EntityDetailViewInner({
2890
2903
  }), role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: readOnlyFormContext && /* @__PURE__ */ jsx(Builder, { collection, parentCollectionSlugs, parentEntityIds, entity: usedEntity, modifiedValues: usedEntity?.values, formContext: readOnlyFormContext }) }) }) }, `custom_view_${customView.key}`);
2891
2904
  }).filter(Boolean);
2892
2905
  const globalLoading = dataLoading && !usedEntity;
2893
- const jsonTabMounted = mountedTabsRef.current.has(JSON_TAB_VALUE$1);
2894
- const jsonView = selectedTab === JSON_TAB_VALUE$1 || jsonTabMounted ? /* @__PURE__ */ jsx("div", { className: cls("relative flex-1 h-full overflow-auto w-full", {
2895
- "hidden": selectedTab !== JSON_TAB_VALUE$1
2906
+ const jsonTabMounted = mountedTabsRef.current.has(JSON_TAB_VALUE);
2907
+ const jsonView = selectedTab === JSON_TAB_VALUE || jsonTabMounted ? /* @__PURE__ */ jsx("div", { className: cls("relative flex-1 h-full overflow-auto w-full", {
2908
+ "hidden": selectedTab !== JSON_TAB_VALUE
2896
2909
  }), role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityJsonPreview, { values: usedEntity?.values ?? {} }) }) }, "json_view") : null;
2897
- const historyView = includeHistoryView && selectedTab === HISTORY_TAB_VALUE$1 ? /* @__PURE__ */ jsx("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: /* @__PURE__ */ jsx(EntityHistoryView$1, { collection, entity: usedEntity, formContext: readOnlyFormContext, modifiedValues: usedEntity?.values }) }) }) }, "history_view") : null;
2910
+ const historyView = includeHistoryView && selectedTab === HISTORY_TAB_VALUE ? /* @__PURE__ */ jsx("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: /* @__PURE__ */ jsx(EntityHistoryView$1, { collection, entity: usedEntity, formContext: readOnlyFormContext, modifiedValues: usedEntity?.values }) }) }) }, "history_view") : null;
2898
2911
  const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
2899
2912
  const subcollectionId = subcollection.slug;
2900
2913
  const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.slug)}` : void 0;
@@ -2909,27 +2922,15 @@ function EntityDetailViewInner({
2909
2922
  onTabChange?.({
2910
2923
  path,
2911
2924
  entityId,
2912
- selectedTab: value === MAIN_TAB_VALUE$1 ? void 0 : value,
2925
+ selectedTab: value === MAIN_TAB_VALUE ? void 0 : value,
2913
2926
  collection
2914
2927
  });
2915
2928
  }, [onTabChange, path, entityId, collection]);
2916
2929
  const propertyDetailView = () => {
2917
- if (detailViewConfig?.Builder) {
2918
- const CustomBuilder = resolveComponentRef(detailViewConfig.Builder);
2919
- if (CustomBuilder && usedEntity) {
2920
- return /* @__PURE__ */ jsx(CustomBuilder, { collection, entity: usedEntity, path, onEditClick: onEditClick ?? (() => {
2921
- }) });
2922
- }
2930
+ if (FormViewBuilder && usedEntity) {
2931
+ return /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: /* @__PURE__ */ jsx(FormViewBuilder, { collection, parentCollectionSlugs, parentEntityIds, entity: usedEntity, modifiedValues: usedEntity?.values, formContext: readOnlyFormContext }) }) });
2923
2932
  }
2924
- const HeaderComponent = detailViewConfig?.Header ? resolveComponentRef(detailViewConfig.Header) : null;
2925
- const FooterComponent = detailViewConfig?.Footer ? resolveComponentRef(detailViewConfig.Footer) : null;
2926
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2927
- HeaderComponent && usedEntity && /* @__PURE__ */ jsx(HeaderComponent, { collection, entity: usedEntity, path, onEditClick: onEditClick ?? (() => {
2928
- }) }),
2929
- usedEntity && /* @__PURE__ */ jsx(EntityView, { entity: usedEntity, collection, path }),
2930
- FooterComponent && usedEntity && /* @__PURE__ */ jsx(FooterComponent, { collection, entity: usedEntity, path, onEditClick: onEditClick ?? (() => {
2931
- }) })
2932
- ] });
2933
+ return /* @__PURE__ */ jsx(Fragment, { children: usedEntity && /* @__PURE__ */ jsx(EntityView, { entity: usedEntity, collection, path }) });
2933
2934
  };
2934
2935
  const subcollectionTabs = subcollections && subcollections.map((subcollection_0) => {
2935
2936
  const icon = getIcon(subcollection_0.icon, void 0, void 0, "small");
@@ -2989,9 +2990,9 @@ function EntityDetailViewInner({
2989
2990
  hasAdditionalViews && /* @__PURE__ */ jsx("div", { className: "flex-1 flex justify-end min-w-0 shrink-0", children: /* @__PURE__ */ jsxs(Tabs, { className: "!w-fit max-w-full", value: selectedTab, onValueChange: (value_0) => {
2990
2991
  onSideTabClick(value_0);
2991
2992
  }, children: [
2992
- includeJsonView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: JSON_TAB_VALUE$1, className: "text-sm", children: /* @__PURE__ */ jsx(CodeIcon, { size: iconSize.small }) }),
2993
- includeHistoryView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: HISTORY_TAB_VALUE$1, className: "text-sm", children: /* @__PURE__ */ jsx(HistoryIcon, { size: iconSize.small }) }),
2994
- /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: MAIN_TAB_VALUE$1, className: "text-sm min-w-[90px]", children: collection.singularName ?? collection.name }),
2993
+ includeJsonView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: JSON_TAB_VALUE, className: "text-sm", children: /* @__PURE__ */ jsx(CodeIcon, { size: iconSize.small }) }),
2994
+ includeHistoryView && /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: HISTORY_TAB_VALUE, className: "text-sm", children: /* @__PURE__ */ jsx(HistoryIcon, { size: iconSize.small }) }),
2995
+ /* @__PURE__ */ jsx(Tab, { disabled: !hasAdditionalViews, value: MAIN_TAB_VALUE, className: "text-sm min-w-[90px]", children: collection.singularName ?? collection.name }),
2995
2996
  customViewTabsStart,
2996
2997
  customViewTabsEnd,
2997
2998
  subcollectionTabs
@@ -7903,17 +7904,19 @@ const SelectableTable = function SelectableTable2({
7903
7904
  };
7904
7905
  }, [unselect]);
7905
7906
  const onFilterUpdate = useCallback((updatedFilterValues) => {
7906
- setFilterValues?.({
7907
- ...updatedFilterValues,
7908
- ...fixedFilter
7909
- });
7910
- }, [fixedFilter]);
7907
+ if (setFilterValues) {
7908
+ setFilterValues({
7909
+ ...updatedFilterValues,
7910
+ ...fixedFilter
7911
+ });
7912
+ }
7913
+ }, [fixedFilter, setFilterValues]);
7911
7914
  const contextValue = useMemo(() => ({
7912
- setPopupCell,
7913
7915
  select,
7914
7916
  onValueChange,
7915
7917
  size: size ?? "m",
7916
- selectionStore
7918
+ selectionStore,
7919
+ setPopupCell
7917
7920
  }), [setPopupCell, select, onValueChange, size, selectionStore]);
7918
7921
  return /* @__PURE__ */ jsx(SelectableTableContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("div", { className: "h-full w-full flex flex-col bg-white dark:bg-surface-900", ref, children: /* @__PURE__ */ jsx(
7919
7922
  VirtualTable,
@@ -8322,7 +8325,7 @@ function buildBottomActions({
8322
8325
  const canClose = openEntityMode === "side_panel" || openEntityMode === "dialog";
8323
8326
  return /* @__PURE__ */ jsxs(DialogActions, { className, position: "absolute", children: [
8324
8327
  savingError && /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Typography, { color: "error", children: savingError.message }) }),
8325
- formActions.length > 0 && /* @__PURE__ */ jsx("div", { className: "grow flex overflow-auto no-scrollbar", children: formActions.map((action) => {
8328
+ formActions.length > 0 && /* @__PURE__ */ jsx("div", { className: "grow flex overflow-auto no-scrollbar", children: formActions.map((action, index) => {
8326
8329
  const props = {
8327
8330
  view: "form",
8328
8331
  entity,
@@ -8335,7 +8338,7 @@ function buildBottomActions({
8335
8338
  formContext
8336
8339
  };
8337
8340
  const isEnabled = !action.isEnabled || action.isEnabled(props);
8338
- return /* @__PURE__ */ jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
8341
+ return /* @__PURE__ */ jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key ?? action.name ?? index);
8339
8342
  }) }),
8340
8343
  pluginActions,
8341
8344
  hasErrors ? /* @__PURE__ */ jsx(ErrorTooltip, { title: "This form has errors", children: /* @__PURE__ */ jsx(AlertCircleIcon, { className: "ml-4 text-red-500", size: iconSize.smallest }) }) : null,
@@ -8387,7 +8390,7 @@ function buildSideActions({
8387
8390
  /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "text", disabled: disabled || formex.isSubmitting, type: "reset", children: status === "existing" ? t("discard") : t("clear") }),
8388
8391
  collection.defaultEntityAction === "view" && status === "existing" && /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "text", disabled, onClick: navigateBack, children: t("back_to_detail") ?? "Back to details" }),
8389
8392
  pluginActions,
8390
- formActions.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-row flex-wrap mt-2", children: formActions.map((action) => {
8393
+ formActions.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-row flex-wrap mt-2", children: formActions.map((action, index) => {
8391
8394
  const props = {
8392
8395
  view: "form",
8393
8396
  entity,
@@ -8400,7 +8403,7 @@ function buildSideActions({
8400
8403
  formContext
8401
8404
  };
8402
8405
  const isEnabled = !action.isEnabled || action.isEnabled(props);
8403
- return /* @__PURE__ */ jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
8406
+ return /* @__PURE__ */ jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key ?? action.name ?? index);
8404
8407
  }) }),
8405
8408
  savingError && /* @__PURE__ */ jsx("div", { className: "text-right", children: /* @__PURE__ */ jsx(Typography, { color: "error", children: savingError.message }) })
8406
8409
  ] });
@@ -8485,12 +8488,9 @@ function EntityActionButton(t0) {
8485
8488
  }
8486
8489
  return t5;
8487
8490
  }
8488
- const EntityHistoryView = lazy(() => import("./index-BCcLwgfe.js").then((m) => ({
8491
+ const EntityHistoryView = lazy(() => import("./index-z3H8iqsj.js").then((m) => ({
8489
8492
  default: m.EntityHistoryView
8490
8493
  })));
8491
- const MAIN_TAB_VALUE = "__main_##Q$SC^#S6";
8492
- const JSON_TAB_VALUE = "__json";
8493
- const HISTORY_TAB_VALUE = "__rebase_history";
8494
8494
  function EntityEditView(t0) {
8495
8495
  const $ = c(28);
8496
8496
  let entityId;
@@ -8651,13 +8651,22 @@ function EntityEditViewInner({
8651
8651
  status,
8652
8652
  entityId
8653
8653
  }), [collection, status, entityId]);
8654
- const [selectedTab, setSelectedTab] = useState(selectedTabProp === "edit" ? MAIN_TAB_VALUE : selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE);
8654
+ const hasAppliedDefault = useRef(false);
8655
+ const [selectedTab, setSelectedTab] = useState(() => {
8656
+ const val = selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
8657
+ hasAppliedDefault.current = true;
8658
+ return val === "edit" ? MAIN_TAB_VALUE : val;
8659
+ });
8655
8660
  useEffect(() => {
8656
- const target = selectedTabProp === "edit" ? MAIN_TAB_VALUE : selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
8661
+ const val_0 = hasAppliedDefault.current ? selectedTabProp ?? MAIN_TAB_VALUE : selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE;
8662
+ const target = val_0 === "edit" ? MAIN_TAB_VALUE : val_0;
8663
+ if (!hasAppliedDefault.current) {
8664
+ hasAppliedDefault.current = true;
8665
+ }
8657
8666
  if (target !== selectedTab) {
8658
8667
  setSelectedTab(target);
8659
8668
  }
8660
- }, [selectedTabProp, defaultSelectedView]);
8669
+ }, [selectedTabProp]);
8661
8670
  const subcollections = getSubcollections(collection).filter((c2) => !c2.hideFromNavigation);
8662
8671
  const subcollectionsCount = subcollections?.length ?? 0;
8663
8672
  const customViews = collection.entityViews ?? [];
@@ -8683,6 +8692,7 @@ function EntityEditViewInner({
8683
8692
  return {
8684
8693
  entityId,
8685
8694
  disabled: false,
8695
+ readOnly: true,
8686
8696
  openEntityMode: layout,
8687
8697
  status,
8688
8698
  values: usedEntity?.values ?? {},
@@ -8746,12 +8756,18 @@ function EntityEditViewInner({
8746
8756
  });
8747
8757
  }
8748
8758
  }, [status, onTabChange, path, entityId, collection]);
8759
+ const formViewConfig = collection.formView;
8760
+ const FormViewBuilder = formViewConfig?.Builder ? resolveComponentRef(formViewConfig.Builder) : null;
8761
+ formViewConfig?.includeActions !== false;
8749
8762
  const entityReadOnlyView = !canEdit && entity ? /* @__PURE__ */ jsx("div", { className: cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", canEdit || !mainViewVisible || selectedSecondaryForm ? "hidden" : ""), children: /* @__PURE__ */ jsxs("div", { className: cls("relative flex flex-col max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit"), children: [
8750
8763
  /* @__PURE__ */ jsx(Typography, { className: "mt-16 mb-8 mx-8", variant: "h4", children: collection.singularName ?? collection.name }),
8751
- /* @__PURE__ */ jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
8764
+ FormViewBuilder && readOnlyFormContext ? /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: /* @__PURE__ */ jsx(FormViewBuilder, { collection, parentCollectionSlugs, parentEntityIds, entity: usedEntity, modifiedValues: usedEntity?.values, formContext: readOnlyFormContext }) }) }) : /* @__PURE__ */ jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
8752
8765
  /* @__PURE__ */ jsx("div", { className: "h-16" })
8753
8766
  ] }) }) : null;
8754
- const entityView = /* @__PURE__ */ jsx(EntityForm, { collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, navigateBack, ...formProps, onEntityChange: (entity_0) => {
8767
+ const entityView = FormViewBuilder ? (
8768
+ // formView.Builder replaces the default form
8769
+ /* @__PURE__ */ jsx("div", { className: cls("relative flex-1 w-full h-full overflow-auto", (!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : ""), children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(CircularProgressCenter, {}), children: (formContext ?? readOnlyFormContext) && /* @__PURE__ */ jsx(FormViewBuilder, { collection, parentCollectionSlugs, parentEntityIds, entity: usedEntity, modifiedValues: (formContext ?? readOnlyFormContext)?.formex?.values ?? usedEntity?.values, formContext: formContext ?? readOnlyFormContext }) }) }) })
8770
+ ) : /* @__PURE__ */ jsx(EntityForm, { collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, navigateBack, ...formProps, onEntityChange: (entity_0) => {
8755
8771
  setUsedEntity(entity_0);
8756
8772
  formProps?.onEntityChange?.(entity_0);
8757
8773
  }, onStatusChange: (status_0) => {
@@ -8945,7 +8961,6 @@ function EntitySidePanel(props) {
8945
8961
  close
8946
8962
  } = useSideDialogContext();
8947
8963
  const navigate = useNavigate();
8948
- const location = useLocation();
8949
8964
  const sideEntityController = useSideEntityController();
8950
8965
  const collectionRegistryController = useCollectionRegistryController();
8951
8966
  const sideDialogsController = useSideDialogContext();
@@ -8988,6 +9003,26 @@ function EntitySidePanel(props) {
8988
9003
  useEffect(() => {
8989
9004
  setShowEditInPanel(selectedTab === "edit");
8990
9005
  }, [entityId, selectedTab]);
9006
+ const hasCorrectedDefaultView = useRef(false);
9007
+ useEffect(() => {
9008
+ if (hasCorrectedDefaultView.current) return;
9009
+ if (selectedTab) return;
9010
+ if (!entityId || !collection?.defaultSelectedView) return;
9011
+ const effectiveDefault = resolveDefaultSelectedView(collection.defaultSelectedView, {
9012
+ status: "existing",
9013
+ entityId
9014
+ });
9015
+ if (effectiveDefault && effectiveDefault !== "edit") {
9016
+ hasCorrectedDefaultView.current = true;
9017
+ sideEntityController.replace({
9018
+ path,
9019
+ entityId,
9020
+ selectedTab: effectiveDefault,
9021
+ updateUrl: collection.openEntityMode !== "dialog",
9022
+ collection
9023
+ });
9024
+ }
9025
+ }, [selectedTab, entityId, collection, path, sideEntityController]);
8991
9026
  const onValuesModified = useCallback((modified) => {
8992
9027
  setBlockedNavigationMessage(modified ? /* @__PURE__ */ jsxs(Fragment, { children: [
8993
9028
  " You have unsaved changes in this ",
@@ -9021,12 +9056,12 @@ function EntitySidePanel(props) {
9021
9056
  return;
9022
9057
  }
9023
9058
  if (tabEntityId) {
9024
- const collectionPath = removeInitialAndTrailingSlashes(path);
9025
- const tabSuffix = selectedTab_0 ? "/" + selectedTab_0 : "";
9026
- const fullUrl = urlController.buildUrlCollectionPath(`${collectionPath}/${tabEntityId}${tabSuffix}#side`);
9027
- navigate(fullUrl, {
9028
- replace: true,
9029
- state: location.state
9059
+ sideEntityController.replace({
9060
+ path,
9061
+ entityId: tabEntityId,
9062
+ selectedTab: selectedTab_0,
9063
+ updateUrl: true,
9064
+ collection: paramCollection ?? collection
9030
9065
  });
9031
9066
  }
9032
9067
  } }) : /* @__PURE__ */ jsx(EntityEditView, { ...props, layout: collection?.openEntityMode === "dialog" ? "dialog" : "side_panel", collection, parentCollectionSlugs, parentEntityIds, onValuesModified, onSaved: onUpdate, navigateBack: () => setShowEditInPanel(false), barActions: ({
@@ -9052,20 +9087,20 @@ function EntitySidePanel(props) {
9052
9087
  }
9053
9088
  }, children: /* @__PURE__ */ jsx(Maximize2Icon, {}) })
9054
9089
  ] }), onTabChange: ({
9055
- entityId: entityId_0,
9090
+ entityId: tabEntityId_0,
9056
9091
  selectedTab: selectedTab_1,
9057
9092
  collection: paramCollection_0
9058
9093
  }) => {
9059
9094
  if (collection?.openEntityMode === "dialog" || paramCollection_0?.openEntityMode === "dialog") {
9060
9095
  return;
9061
9096
  }
9062
- if (entityId_0) {
9063
- const collectionPath_0 = removeInitialAndTrailingSlashes(path);
9064
- const tabSuffix_0 = selectedTab_1 ? "/" + selectedTab_1 : "";
9065
- const fullUrl_0 = urlController.buildUrlCollectionPath(`${collectionPath_0}/${entityId_0}${tabSuffix_0}#side`);
9066
- navigate(fullUrl_0, {
9067
- replace: true,
9068
- state: location.state
9097
+ if (tabEntityId_0) {
9098
+ sideEntityController.replace({
9099
+ path,
9100
+ entityId: tabEntityId_0,
9101
+ selectedTab: selectedTab_1,
9102
+ updateUrl: true,
9103
+ collection: paramCollection_0 ?? collection
9069
9104
  });
9070
9105
  }
9071
9106
  }, formProps }) }) });
@@ -9077,7 +9112,7 @@ function getEntityViewWidth(props, small, customizationController) {
9077
9112
  const {
9078
9113
  selectedSecondaryForm
9079
9114
  } = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
9080
- const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || props.selectedTab === HISTORY_TAB_VALUE || Boolean(selectedSecondaryForm);
9115
+ const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === "edit" || props.selectedTab === JSON_TAB_VALUE || props.selectedTab === HISTORY_TAB_VALUE || Boolean(selectedSecondaryForm);
9081
9116
  let resolvedWidth;
9082
9117
  if (props.width) {
9083
9118
  resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
@@ -9200,8 +9235,8 @@ const useBuildSideEntityController = (collectionRegistryController, urlControlle
9200
9235
  entityId: props_0.entityId
9201
9236
  });
9202
9237
  sideDialogsController.open(propsToSidePanel({
9203
- selectedTab: defaultSelectedView,
9204
- ...props_0
9238
+ ...props_0,
9239
+ selectedTab: props_0.selectedTab ?? defaultSelectedView
9205
9240
  }, urlController.buildUrlCollectionPath, urlController.resolveDatabasePathsFrom, smallLayout, customizationController, authController, location.search));
9206
9241
  }, [sideDialogsController, urlController.buildUrlCollectionPath, urlController.resolveDatabasePathsFrom, smallLayout, authController.user, location.search]);
9207
9242
  const replace = useCallback((props_1) => {
@@ -9235,6 +9270,7 @@ function buildSidePanelsFromUrl(path, collections, newFlag) {
9235
9270
  path: navigationEntry.slug,
9236
9271
  entityId: navigationEntry.entityId,
9237
9272
  copy: false,
9273
+ collection: navigationEntry.parentCollection,
9238
9274
  width: navigationEntry.parentCollection?.sideDialogWidth
9239
9275
  };
9240
9276
  } else if (navigationEntry.type === "custom_view") {
@@ -9247,6 +9283,15 @@ function buildSidePanelsFromUrl(path, collections, newFlag) {
9247
9283
  }
9248
9284
  }
9249
9285
  }
9286
+ if (sidePanel && !sidePanel.selectedTab && sidePanel.collection) {
9287
+ const defaultView = resolveDefaultSelectedView(sidePanel.collection.defaultSelectedView, {
9288
+ status: sidePanel.copy ? "copy" : sidePanel.entityId ? "existing" : "new",
9289
+ entityId: sidePanel.entityId
9290
+ });
9291
+ if (defaultView) {
9292
+ sidePanel.selectedTab = defaultView;
9293
+ }
9294
+ }
9250
9295
  if (newFlag) {
9251
9296
  sidePanel = {
9252
9297
  path: lastCollectionPath,
@@ -9719,11 +9764,7 @@ function useResolvedCollections(props) {
9719
9764
  try {
9720
9765
  const resolved = await resolveCollections(collectionsProp, authControllerRef.current, dataRef.current, pluginsRef.current);
9721
9766
  if (cancelled) return;
9722
- const defaults = [];
9723
- if (userManagementRef.current) {
9724
- defaults.push(defaultUsersCollection);
9725
- }
9726
- const deduped = Array.from(new Map([...defaults, ...resolved].map((c2) => [c2.slug, c2])).values());
9767
+ const deduped = [...resolved];
9727
9768
  const changed = collectionRegistryController.collectionRegistryRef.current.registerMultiple(deduped);
9728
9769
  if (changed) {
9729
9770
  console.debug("Collections have changed", deduped);
@@ -9755,481 +9796,6 @@ function useResolvedCollections(props) {
9755
9796
  refresh
9756
9797
  }), [resolvedCollections, loading, error, refresh]);
9757
9798
  }
9758
- function RoleChip(t0) {
9759
- const $ = c(9);
9760
- const {
9761
- role
9762
- } = t0;
9763
- let colorScheme;
9764
- if (role.isAdmin) {
9765
- let t12;
9766
- if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
9767
- t12 = getColorSchemeForKey("blue");
9768
- $[0] = t12;
9769
- } else {
9770
- t12 = $[0];
9771
- }
9772
- colorScheme = t12;
9773
- } else {
9774
- if (role.id === "editor") {
9775
- let t12;
9776
- if ($[1] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
9777
- t12 = getColorSchemeForKey("yellow");
9778
- $[1] = t12;
9779
- } else {
9780
- t12 = $[1];
9781
- }
9782
- colorScheme = t12;
9783
- } else {
9784
- if (role.id === "viewer") {
9785
- let t12;
9786
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
9787
- t12 = getColorSchemeForKey("gray");
9788
- $[2] = t12;
9789
- } else {
9790
- t12 = $[2];
9791
- }
9792
- colorScheme = t12;
9793
- } else {
9794
- let t12;
9795
- if ($[3] !== role.id) {
9796
- t12 = getColorSchemeForSeed(role.id);
9797
- $[3] = role.id;
9798
- $[4] = t12;
9799
- } else {
9800
- t12 = $[4];
9801
- }
9802
- colorScheme = t12;
9803
- }
9804
- }
9805
- }
9806
- let t1;
9807
- if ($[5] !== colorScheme || $[6] !== role.id || $[7] !== role.name) {
9808
- t1 = /* @__PURE__ */ jsx(Chip, { colorScheme, children: role.name }, role.id);
9809
- $[5] = colorScheme;
9810
- $[6] = role.id;
9811
- $[7] = role.name;
9812
- $[8] = t1;
9813
- } else {
9814
- t1 = $[8];
9815
- }
9816
- return t1;
9817
- }
9818
- function RolesView({
9819
- userManagement: userManagementProp
9820
- }) {
9821
- const userManagementContext = useInternalUserManagementController();
9822
- const userManagement = userManagementProp ?? userManagementContext;
9823
- if (!userManagement) {
9824
- return null;
9825
- }
9826
- const {
9827
- roles,
9828
- saveRole,
9829
- deleteRole,
9830
- loading,
9831
- allowDefaultRolesCreation,
9832
- rolesError
9833
- } = userManagement;
9834
- const snackbarController = useSnackbarController();
9835
- const {
9836
- t
9837
- } = useTranslation();
9838
- const breadcrumbs = useBreadcrumbsController();
9839
- React__default.useEffect(() => {
9840
- breadcrumbs.set({
9841
- breadcrumbs: [{
9842
- title: t("roles"),
9843
- url: "/roles"
9844
- }]
9845
- });
9846
- }, []);
9847
- const [dialogOpen, setDialogOpen] = useState(false);
9848
- const [selectedRole, setSelectedRole] = useState();
9849
- const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
9850
- const [roleToDelete, setRoleToDelete] = useState();
9851
- const [deleteInProgress, setDeleteInProgress] = useState(false);
9852
- const handleAddRole = () => {
9853
- setSelectedRole(void 0);
9854
- setDialogOpen(true);
9855
- };
9856
- const handleEditRole = (role) => {
9857
- setSelectedRole(role);
9858
- setDialogOpen(true);
9859
- };
9860
- const handleClose = () => {
9861
- setDialogOpen(false);
9862
- setSelectedRole(void 0);
9863
- };
9864
- const handleDelete = async () => {
9865
- if (!roleToDelete || !deleteRole) return;
9866
- setDeleteInProgress(true);
9867
- try {
9868
- await deleteRole(roleToDelete);
9869
- snackbarController.open({
9870
- type: "success",
9871
- message: t("role_deleted_successfully")
9872
- });
9873
- setDeleteConfirmOpen(false);
9874
- setRoleToDelete(void 0);
9875
- } catch (error) {
9876
- snackbarController.open({
9877
- type: "error",
9878
- message: error instanceof Error ? error.message : t("error_deleting_role")
9879
- });
9880
- } finally {
9881
- setDeleteInProgress(false);
9882
- }
9883
- };
9884
- const createDefaultRoles = async () => {
9885
- if (!saveRole) return;
9886
- const defaultRoles = [{
9887
- id: "admin",
9888
- name: "Admin",
9889
- isAdmin: true
9890
- }, {
9891
- id: "editor",
9892
- name: "Editor",
9893
- isAdmin: false
9894
- }, {
9895
- id: "viewer",
9896
- name: "Viewer",
9897
- isAdmin: false
9898
- }];
9899
- try {
9900
- for (const role_0 of defaultRoles) {
9901
- await saveRole(role_0);
9902
- }
9903
- snackbarController.open({
9904
- type: "success",
9905
- message: t("saved_correctly")
9906
- });
9907
- } catch (error_0) {
9908
- snackbarController.open({
9909
- type: "error",
9910
- message: error_0 instanceof Error ? error_0.message : t("error_saving_role")
9911
- });
9912
- }
9913
- };
9914
- if (loading) {
9915
- return /* @__PURE__ */ jsx(CenteredView, { children: /* @__PURE__ */ jsx(CircularProgress, {}) });
9916
- }
9917
- return /* @__PURE__ */ jsxs(Container, { className: "w-full flex flex-col py-4 gap-4", maxWidth: "6xl", children: [
9918
- /* @__PURE__ */ jsxs("div", { className: "flex items-center mt-12 mb-4 gap-4", children: [
9919
- /* @__PURE__ */ jsx(Typography, { gutterBottom: true, variant: "h4", className: "grow mb-0", component: "h4", children: t("roles") }),
9920
- /* @__PURE__ */ jsx(Button, { startIcon: /* @__PURE__ */ jsx(PlusIcon, {}), onClick: handleAddRole, disabled: !saveRole, children: t("add_role") })
9921
- ] }),
9922
- /* @__PURE__ */ jsx("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ jsxs(Table, { className: "w-full", children: [
9923
- /* @__PURE__ */ jsxs(TableHeader, { children: [
9924
- /* @__PURE__ */ jsx(TableCell, { header: true, children: t("role") }),
9925
- /* @__PURE__ */ jsx(TableCell, { header: true, className: "items-center", children: t("is_admin") }),
9926
- /* @__PURE__ */ jsx(TableCell, { header: true, className: "w-24 text-right", children: t("actions") })
9927
- ] }),
9928
- /* @__PURE__ */ jsxs(TableBody, { children: [
9929
- roles && roles.map((role_1) => {
9930
- return /* @__PURE__ */ jsxs(TableRow, { onClick: () => saveRole && handleEditRole(role_1), children: [
9931
- /* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsx(RoleChip, { role: role_1 }) }),
9932
- /* @__PURE__ */ jsx(TableCell, { className: "items-center", children: /* @__PURE__ */ jsx(Checkbox, { checked: role_1.isAdmin ?? false, disabled: true }) }),
9933
- /* @__PURE__ */ jsx(TableCell, { className: "text-right whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "flex justify-end items-center gap-1", children: !role_1.isAdmin && deleteRole && /* @__PURE__ */ jsx(Tooltip, { asChild: true, title: t("delete_this_role"), children: /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: (e) => {
9934
- e.stopPropagation();
9935
- setRoleToDelete(role_1);
9936
- setDeleteConfirmOpen(true);
9937
- }, children: /* @__PURE__ */ jsx(Trash2Icon, { size: iconSize.small }) }) }) }) })
9938
- ] }, role_1.id);
9939
- }),
9940
- (!roles || roles.length === 0) && /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colspan: 3, children: /* @__PURE__ */ jsxs(CenteredView, { className: "flex flex-col gap-4 my-8 items-center", children: [
9941
- /* @__PURE__ */ jsx(Typography, { variant: "label", children: rolesError ? t("no_permission_to_view_roles") : t("no_roles_yet") }),
9942
- rolesError && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: t("no_permission_description") }),
9943
- !rolesError && allowDefaultRolesCreation && saveRole && /* @__PURE__ */ jsx(Button, { onClick: createDefaultRoles, children: t("create_default_roles") })
9944
- ] }) }) })
9945
- ] })
9946
- ] }) }),
9947
- saveRole && /* @__PURE__ */ jsx(RoleDetailsForm, { open: dialogOpen, role: selectedRole, saveRole, handleClose }, selectedRole?.id ?? "new"),
9948
- /* @__PURE__ */ jsx(ConfirmationDialog, { open: deleteConfirmOpen, loading: deleteInProgress, onAccept: handleDelete, onCancel: () => {
9949
- setDeleteConfirmOpen(false);
9950
- setRoleToDelete(void 0);
9951
- }, title: /* @__PURE__ */ jsx(Fragment, { children: t("delete_confirmation_title") }), body: /* @__PURE__ */ jsx(Fragment, { children: t("delete_role_confirmation") }) })
9952
- ] });
9953
- }
9954
- function RoleDetailsForm({
9955
- open,
9956
- role: roleProp,
9957
- saveRole,
9958
- handleClose
9959
- }) {
9960
- const snackbarController = useSnackbarController();
9961
- const {
9962
- t
9963
- } = useTranslation();
9964
- const isNewRole = !roleProp;
9965
- const [roleId, setRoleId] = useState(roleProp?.id || "");
9966
- const [roleName, setRoleName] = useState(roleProp?.name || "");
9967
- const [isAdmin, setIsAdmin] = useState(roleProp?.isAdmin ?? false);
9968
- const [isSubmitting, setIsSubmitting] = useState(false);
9969
- const [errors, setErrors] = useState({});
9970
- const [submitCount, setSubmitCount] = useState(0);
9971
- const validate = () => {
9972
- const newErrors = {};
9973
- if (!roleId) newErrors.id = "Required";
9974
- if (!roleName) newErrors.name = "Required";
9975
- setErrors(newErrors);
9976
- return Object.keys(newErrors).length === 0;
9977
- };
9978
- const handleSubmit = async (e) => {
9979
- e.preventDefault();
9980
- setSubmitCount((c2) => c2 + 1);
9981
- if (!validate()) return;
9982
- setIsSubmitting(true);
9983
- try {
9984
- await saveRole({
9985
- id: roleId,
9986
- name: roleName,
9987
- isAdmin
9988
- });
9989
- handleClose();
9990
- } catch (error) {
9991
- snackbarController.open({
9992
- type: "error",
9993
- message: error instanceof Error ? error.message : "Failed to save role"
9994
- });
9995
- } finally {
9996
- setIsSubmitting(false);
9997
- }
9998
- };
9999
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (open_0) => !open_0 ? handleClose() : void 0, maxWidth: "4xl", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, autoComplete: "off", noValidate: true, style: {
10000
- display: "flex",
10001
- flexDirection: "column",
10002
- position: "relative",
10003
- height: "100%"
10004
- }, children: [
10005
- /* @__PURE__ */ jsx(DialogTitle, { variant: "h4", gutterBottom: false, children: t("role") }),
10006
- /* @__PURE__ */ jsx(DialogContent, { className: "h-full grow overflow-y-auto", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-4", children: [
10007
- /* @__PURE__ */ jsxs("div", { className: "col-span-12 sm:col-span-4", children: [
10008
- /* @__PURE__ */ jsx(TextField, { name: "id", required: true, error: submitCount > 0 && Boolean(errors.id), value: roleId, onChange: (e_0) => setRoleId(e_0.target.value), label: t("role_id"), disabled: !isNewRole }),
10009
- submitCount > 0 && errors.id && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "error", children: errors.id })
10010
- ] }),
10011
- /* @__PURE__ */ jsxs("div", { className: "col-span-12 sm:col-span-4", children: [
10012
- /* @__PURE__ */ jsx(TextField, { name: "name", required: true, error: submitCount > 0 && Boolean(errors.name), value: roleName, onChange: (e_1) => setRoleName(e_1.target.value), label: t("role_name") }),
10013
- submitCount > 0 && errors.name && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "error", children: errors.name })
10014
- ] }),
10015
- /* @__PURE__ */ jsx("div", { className: "col-span-12 sm:col-span-4 flex items-start pt-2", children: /* @__PURE__ */ jsxs(Label, { className: "flex items-center gap-2 cursor-pointer mt-3", children: [
10016
- /* @__PURE__ */ jsx(Checkbox, { checked: isAdmin, onCheckedChange: (checked) => setIsAdmin(Boolean(checked)) }),
10017
- /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "font-medium", children: t("is_admin") })
10018
- ] }) }),
10019
- /* @__PURE__ */ jsx("div", { className: "col-span-12", children: /* @__PURE__ */ jsx(CollectionPermissionsMatrix, { roleId, isAdmin }) })
10020
- ] }) }),
10021
- /* @__PURE__ */ jsxs(DialogActions, { children: [
10022
- /* @__PURE__ */ jsx(Button, { variant: "text", onClick: handleClose, children: t("cancel") }),
10023
- /* @__PURE__ */ jsx(LoadingButton, { variant: "filled", type: "submit", disabled: isSubmitting, loading: isSubmitting, children: isNewRole ? t("create_role") : t("update") })
10024
- ] })
10025
- ] }) });
10026
- }
10027
- const CRUD_OPS = [{
10028
- op: "select",
10029
- label: "read"
10030
- }, {
10031
- op: "insert",
10032
- label: "create"
10033
- }, {
10034
- op: "update",
10035
- label: "edit"
10036
- }, {
10037
- op: "delete",
10038
- label: "delete"
10039
- }];
10040
- function hasRoleAccess(rules, roleId, op) {
10041
- if (!rules || rules.length === 0) return true;
10042
- const applicable = rules.filter((r) => r.operation === op || r.operation === "all" || r.operations?.includes(op) || r.operations?.includes("all"));
10043
- if (applicable.length === 0) return false;
10044
- const forRole = applicable.filter((r) => !r.roles || r.roles.length === 0 || r.roles.includes(roleId) || r.roles.includes("public"));
10045
- if (forRole.length === 0) return false;
10046
- for (const r of forRole) {
10047
- if ((r.mode ?? "permissive") === "restrictive") return false;
10048
- }
10049
- return forRole.some((r) => (r.mode ?? "permissive") === "permissive");
10050
- }
10051
- function PermCell(t0) {
10052
- const $ = c(3);
10053
- const {
10054
- granted
10055
- } = t0;
10056
- const t1 = granted ? "text-green-500 dark:text-green-400 font-bold" : "text-surface-300 dark:text-surface-600";
10057
- const t2 = granted ? "✓" : "✗";
10058
- let t3;
10059
- if ($[0] !== t1 || $[1] !== t2) {
10060
- t3 = /* @__PURE__ */ jsx("span", { className: t1, children: t2 });
10061
- $[0] = t1;
10062
- $[1] = t2;
10063
- $[2] = t3;
10064
- } else {
10065
- t3 = $[2];
10066
- }
10067
- return t3;
10068
- }
10069
- function CollectionPermissionsMatrix(t0) {
10070
- const $ = c(34);
10071
- const {
10072
- roleId,
10073
- isAdmin
10074
- } = t0;
10075
- const {
10076
- collections
10077
- } = useCollectionRegistryController();
10078
- const {
10079
- t
10080
- } = useTranslation();
10081
- if (!collections || collections.length === 0) {
10082
- let t12;
10083
- if ($[0] !== t) {
10084
- t12 = t("no_collections_configured");
10085
- $[0] = t;
10086
- $[1] = t12;
10087
- } else {
10088
- t12 = $[1];
10089
- }
10090
- let t22;
10091
- if ($[2] !== t12) {
10092
- t22 = /* @__PURE__ */ jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsx(Typography, { variant: "label", className: "text-surface-400", children: t12 }) });
10093
- $[2] = t12;
10094
- $[3] = t22;
10095
- } else {
10096
- t22 = $[3];
10097
- }
10098
- return t22;
10099
- }
10100
- const topLevel = collections;
10101
- let t1;
10102
- if ($[4] !== t) {
10103
- t1 = t("collection_permissions");
10104
- $[4] = t;
10105
- $[5] = t1;
10106
- } else {
10107
- t1 = $[5];
10108
- }
10109
- let t2;
10110
- if ($[6] !== t1) {
10111
- t2 = /* @__PURE__ */ jsx(Typography, { variant: "label", className: "mb-2 block text-surface-500 dark:text-surface-400 uppercase tracking-wide text-xs", children: t1 });
10112
- $[6] = t1;
10113
- $[7] = t2;
10114
- } else {
10115
- t2 = $[7];
10116
- }
10117
- let t3;
10118
- if ($[8] !== t) {
10119
- t3 = t("collection");
10120
- $[8] = t;
10121
- $[9] = t3;
10122
- } else {
10123
- t3 = $[9];
10124
- }
10125
- let t4;
10126
- if ($[10] !== t3) {
10127
- t4 = /* @__PURE__ */ jsx(TableCell, { header: true, children: t3 });
10128
- $[10] = t3;
10129
- $[11] = t4;
10130
- } else {
10131
- t4 = $[11];
10132
- }
10133
- let t5;
10134
- if ($[12] !== t) {
10135
- t5 = CRUD_OPS.map((t62) => {
10136
- const {
10137
- op,
10138
- label
10139
- } = t62;
10140
- return /* @__PURE__ */ jsx(TableCell, { header: true, align: "center", className: "w-20", children: t(label) }, op);
10141
- });
10142
- $[12] = t;
10143
- $[13] = t5;
10144
- } else {
10145
- t5 = $[13];
10146
- }
10147
- let t6;
10148
- if ($[14] !== t4 || $[15] !== t5) {
10149
- t6 = /* @__PURE__ */ jsxs(TableHeader, { children: [
10150
- t4,
10151
- t5
10152
- ] });
10153
- $[14] = t4;
10154
- $[15] = t5;
10155
- $[16] = t6;
10156
- } else {
10157
- t6 = $[16];
10158
- }
10159
- let t7;
10160
- if ($[17] !== isAdmin || $[18] !== roleId || $[19] !== t || $[20] !== topLevel) {
10161
- let t82;
10162
- if ($[22] !== isAdmin || $[23] !== roleId || $[24] !== t) {
10163
- t82 = (collection) => {
10164
- const capabilities = getDataSourceCapabilities(collection.driver);
10165
- const rules = capabilities.supportsRLS && "securityRules" in collection ? collection.securityRules : void 0;
10166
- const noRules = !rules || rules.length === 0;
10167
- return /* @__PURE__ */ jsxs(TableRow, { children: [
10168
- /* @__PURE__ */ jsxs(TableCell, { children: [
10169
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
10170
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: collection.name }),
10171
- noRules && !isAdmin && /* @__PURE__ */ jsx(Tooltip, { title: t("no_security_rules_defined"), children: /* @__PURE__ */ jsx(Chip, { size: "smallest", colorScheme: "gray", children: t("no_rules") }) })
10172
- ] }),
10173
- /* @__PURE__ */ jsx("span", { className: "text-xs text-surface-400 font-mono", children: collection.slug })
10174
- ] }),
10175
- CRUD_OPS.map((t92) => {
10176
- const {
10177
- op: op_0
10178
- } = t92;
10179
- return /* @__PURE__ */ jsx(TableCell, { align: "center", className: "w-20", children: /* @__PURE__ */ jsx(PermCell, { granted: isAdmin || hasRoleAccess(rules, roleId, op_0) }) }, op_0);
10180
- })
10181
- ] }, collection.slug);
10182
- };
10183
- $[22] = isAdmin;
10184
- $[23] = roleId;
10185
- $[24] = t;
10186
- $[25] = t82;
10187
- } else {
10188
- t82 = $[25];
10189
- }
10190
- t7 = topLevel.map(t82);
10191
- $[17] = isAdmin;
10192
- $[18] = roleId;
10193
- $[19] = t;
10194
- $[20] = topLevel;
10195
- $[21] = t7;
10196
- } else {
10197
- t7 = $[21];
10198
- }
10199
- let t8;
10200
- if ($[26] !== t7) {
10201
- t8 = /* @__PURE__ */ jsx(TableBody, { children: t7 });
10202
- $[26] = t7;
10203
- $[27] = t8;
10204
- } else {
10205
- t8 = $[27];
10206
- }
10207
- let t9;
10208
- if ($[28] !== t6 || $[29] !== t8) {
10209
- t9 = /* @__PURE__ */ jsx("div", { className: `rounded-lg overflow-hidden border w-full ${defaultBorderMixin}`, children: /* @__PURE__ */ jsxs(Table, { className: "w-full", children: [
10210
- t6,
10211
- t8
10212
- ] }) });
10213
- $[28] = t6;
10214
- $[29] = t8;
10215
- $[30] = t9;
10216
- } else {
10217
- t9 = $[30];
10218
- }
10219
- let t10;
10220
- if ($[31] !== t2 || $[32] !== t9) {
10221
- t10 = /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
10222
- t2,
10223
- t9
10224
- ] });
10225
- $[31] = t2;
10226
- $[32] = t9;
10227
- $[33] = t10;
10228
- } else {
10229
- t10 = $[33];
10230
- }
10231
- return t10;
10232
- }
10233
9799
  function viewSlugsEqual(a, b) {
10234
9800
  if (a === b) return true;
10235
9801
  if (!a || !b) return false;
@@ -10247,8 +9813,7 @@ function useResolvedViews(props) {
10247
9813
  data,
10248
9814
  plugins,
10249
9815
  adminMode = "content",
10250
- effectiveRoleController,
10251
- userManagement
9816
+ effectiveRoleController
10252
9817
  } = props;
10253
9818
  const [loading, setLoading] = useState(true);
10254
9819
  const [error, setError] = useState(void 0);
@@ -10280,24 +9845,6 @@ function useResolvedViews(props) {
10280
9845
  }, [adminMode, effectiveRoleController?.effectiveRole, authController]);
10281
9846
  const resolvedAuthControllerRef = useRef(resolvedAuthController);
10282
9847
  resolvedAuthControllerRef.current = resolvedAuthController;
10283
- const hasRoles = !!userManagement?.roles;
10284
- const rolesViewElement = useMemo(() => hasRoles ? /* @__PURE__ */ jsx(RolesView, {}) : null, [hasRoles]);
10285
- const injectedAdminViews = useMemo(() => {
10286
- const views = [];
10287
- const isUserAdmin = userManagement?.isAdmin !== false;
10288
- if (userManagement && isUserAdmin && userManagement.roles && rolesViewElement) {
10289
- views.push({
10290
- slug: "roles",
10291
- name: "Roles",
10292
- icon: "Shield",
10293
- view: rolesViewElement,
10294
- group: "Settings"
10295
- });
10296
- }
10297
- return views;
10298
- }, [userManagement, rolesViewElement]);
10299
- const injectedAdminViewsRef = useRef(injectedAdminViews);
10300
- injectedAdminViewsRef.current = injectedAdminViews;
10301
9848
  const initialLoading = resolvedAuthController.initialLoading;
10302
9849
  const user = resolvedAuthController.user;
10303
9850
  useEffect(() => {
@@ -10305,13 +9852,7 @@ function useResolvedViews(props) {
10305
9852
  let cancelled = false;
10306
9853
  (async () => {
10307
9854
  try {
10308
- const [newViews, newAdminViewsProp] = await Promise.all([resolveAppViews(viewsProp, resolvedAuthControllerRef.current, dataRef.current, pluginsRef.current), resolveAppViews(adminViewsProp, resolvedAuthControllerRef.current, dataRef.current)]);
10309
- const customSlugs = new Set(newAdminViewsProp.flatMap((v) => Array.isArray(v.slug) ? v.slug : [v.slug]));
10310
- const finalInjected = injectedAdminViewsRef.current.filter((v_0) => {
10311
- const slugs = Array.isArray(v_0.slug) ? v_0.slug : [v_0.slug];
10312
- return slugs.every((s) => !customSlugs.has(s));
10313
- });
10314
- const newAdminViews = [...newAdminViewsProp, ...finalInjected];
9855
+ const [newViews, newAdminViews] = await Promise.all([resolveAppViews(viewsProp, resolvedAuthControllerRef.current, dataRef.current, pluginsRef.current), resolveAppViews(adminViewsProp, resolvedAuthControllerRef.current, dataRef.current)]);
10315
9856
  if (!viewSlugsEqual(viewsRef.current, newViews)) {
10316
9857
  viewsRef.current = newViews;
10317
9858
  setResolvedViews(newViews);
@@ -10502,7 +10043,7 @@ function useTopLevelNavigation(props) {
10502
10043
  }), [topLevelNavigation]);
10503
10044
  }
10504
10045
  function useBuildNavigationStateController(props) {
10505
- const $ = c(38);
10046
+ const $ = c(37);
10506
10047
  const {
10507
10048
  authController,
10508
10049
  collections: collectionsProp,
@@ -10549,7 +10090,7 @@ function useBuildNavigationStateController(props) {
10549
10090
  refresh: refreshCollections
10550
10091
  } = useResolvedCollections(t1);
10551
10092
  let t2;
10552
- if ($[8] !== adminMode || $[9] !== adminViewsProp || $[10] !== authController || $[11] !== data || $[12] !== effectiveRoleController || $[13] !== plugins || $[14] !== userManagement || $[15] !== viewsProp) {
10093
+ if ($[8] !== adminMode || $[9] !== adminViewsProp || $[10] !== authController || $[11] !== data || $[12] !== effectiveRoleController || $[13] !== plugins || $[14] !== viewsProp) {
10553
10094
  t2 = {
10554
10095
  authController,
10555
10096
  views: viewsProp,
@@ -10557,8 +10098,7 @@ function useBuildNavigationStateController(props) {
10557
10098
  data,
10558
10099
  plugins,
10559
10100
  adminMode,
10560
- effectiveRoleController,
10561
- userManagement
10101
+ effectiveRoleController
10562
10102
  };
10563
10103
  $[8] = adminMode;
10564
10104
  $[9] = adminViewsProp;
@@ -10566,11 +10106,10 @@ function useBuildNavigationStateController(props) {
10566
10106
  $[11] = data;
10567
10107
  $[12] = effectiveRoleController;
10568
10108
  $[13] = plugins;
10569
- $[14] = userManagement;
10570
- $[15] = viewsProp;
10571
- $[16] = t2;
10109
+ $[14] = viewsProp;
10110
+ $[15] = t2;
10572
10111
  } else {
10573
- t2 = $[16];
10112
+ t2 = $[15];
10574
10113
  }
10575
10114
  const {
10576
10115
  views,
@@ -10580,7 +10119,7 @@ function useBuildNavigationStateController(props) {
10580
10119
  refresh: refreshViews
10581
10120
  } = useResolvedViews(t2);
10582
10121
  let t3;
10583
- if ($[17] !== adminMode || $[18] !== adminViews || $[19] !== collectionRegistryController || $[20] !== collections || $[21] !== navigationGroupMappings || $[22] !== plugins || $[23] !== urlController || $[24] !== views || $[25] !== viewsOrder) {
10122
+ if ($[16] !== adminMode || $[17] !== adminViews || $[18] !== collectionRegistryController || $[19] !== collections || $[20] !== navigationGroupMappings || $[21] !== plugins || $[22] !== urlController || $[23] !== views || $[24] !== viewsOrder) {
10584
10123
  t3 = {
10585
10124
  collections,
10586
10125
  views,
@@ -10592,40 +10131,40 @@ function useBuildNavigationStateController(props) {
10592
10131
  adminMode,
10593
10132
  collectionRegistryController
10594
10133
  };
10595
- $[17] = adminMode;
10596
- $[18] = adminViews;
10597
- $[19] = collectionRegistryController;
10598
- $[20] = collections;
10599
- $[21] = navigationGroupMappings;
10600
- $[22] = plugins;
10601
- $[23] = urlController;
10602
- $[24] = views;
10603
- $[25] = viewsOrder;
10604
- $[26] = t3;
10134
+ $[16] = adminMode;
10135
+ $[17] = adminViews;
10136
+ $[18] = collectionRegistryController;
10137
+ $[19] = collections;
10138
+ $[20] = navigationGroupMappings;
10139
+ $[21] = plugins;
10140
+ $[22] = urlController;
10141
+ $[23] = views;
10142
+ $[24] = viewsOrder;
10143
+ $[25] = t3;
10605
10144
  } else {
10606
- t3 = $[26];
10145
+ t3 = $[25];
10607
10146
  }
10608
10147
  const {
10609
10148
  topLevelNavigation
10610
10149
  } = useTopLevelNavigation(t3);
10611
10150
  let t4;
10612
- if ($[27] !== refreshCollections || $[28] !== refreshViews) {
10151
+ if ($[26] !== refreshCollections || $[27] !== refreshViews) {
10613
10152
  t4 = () => {
10614
10153
  refreshCollections();
10615
10154
  refreshViews();
10616
10155
  };
10617
- $[27] = refreshCollections;
10618
- $[28] = refreshViews;
10619
- $[29] = t4;
10156
+ $[26] = refreshCollections;
10157
+ $[27] = refreshViews;
10158
+ $[28] = t4;
10620
10159
  } else {
10621
- t4 = $[29];
10160
+ t4 = $[28];
10622
10161
  }
10623
10162
  const refreshNavigation = t4;
10624
10163
  let t5;
10625
10164
  const t6 = collectionsLoading || viewsLoading;
10626
10165
  const t7 = collectionsError ?? viewsError;
10627
10166
  let t8;
10628
- if ($[30] !== adminViews || $[31] !== plugins || $[32] !== refreshNavigation || $[33] !== t6 || $[34] !== t7 || $[35] !== topLevelNavigation || $[36] !== views) {
10167
+ if ($[29] !== adminViews || $[30] !== plugins || $[31] !== refreshNavigation || $[32] !== t6 || $[33] !== t7 || $[34] !== topLevelNavigation || $[35] !== views) {
10629
10168
  t8 = {
10630
10169
  views,
10631
10170
  adminViews,
@@ -10635,16 +10174,16 @@ function useBuildNavigationStateController(props) {
10635
10174
  refreshNavigation,
10636
10175
  plugins
10637
10176
  };
10638
- $[30] = adminViews;
10639
- $[31] = plugins;
10640
- $[32] = refreshNavigation;
10641
- $[33] = t6;
10642
- $[34] = t7;
10643
- $[35] = topLevelNavigation;
10644
- $[36] = views;
10645
- $[37] = t8;
10177
+ $[29] = adminViews;
10178
+ $[30] = plugins;
10179
+ $[31] = refreshNavigation;
10180
+ $[32] = t6;
10181
+ $[33] = t7;
10182
+ $[34] = topLevelNavigation;
10183
+ $[35] = views;
10184
+ $[36] = t8;
10646
10185
  } else {
10647
- t8 = $[37];
10186
+ t8 = $[36];
10648
10187
  }
10649
10188
  t5 = t8;
10650
10189
  return t5;
@@ -11443,6 +10982,9 @@ function useCollectionInlineEditor(t0) {
11443
10982
  setError,
11444
10983
  data: entity
11445
10984
  } = t32;
10985
+ if (!entity) {
10986
+ return;
10987
+ }
11446
10988
  const updatedValues = setIn({}, propertyKey, value_0);
11447
10989
  const saveProps = {
11448
10990
  path: entity.path ?? path,
@@ -12020,7 +11562,7 @@ function FormLayout(t0) {
12020
11562
  return t2;
12021
11563
  }
12022
11564
  function ReadOnlyFieldBinding(t0) {
12023
- const $ = c(18);
11565
+ const $ = c(23);
12024
11566
  const {
12025
11567
  propertyKey,
12026
11568
  value,
@@ -12030,6 +11572,7 @@ function ReadOnlyFieldBinding(t0) {
12030
11572
  property,
12031
11573
  includeDescription
12032
11574
  } = t0;
11575
+ const skipCardWrapper = property.type === "relation" || property.type === "reference";
12033
11576
  let t1;
12034
11577
  if ($[0] !== minimalistView || $[1] !== property || $[2] !== propertyKey) {
12035
11578
  t1 = !minimalistView && /* @__PURE__ */ jsx(LabelWithIconAndTooltip, { propertyKey, icon: getIconForProperty(property, "small"), required: property.validation?.required, title: property.name ?? propertyKey, className: "h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5" });
@@ -12040,49 +11583,62 @@ function ReadOnlyFieldBinding(t0) {
12040
11583
  } else {
12041
11584
  t1 = $[3];
12042
11585
  }
12043
- let t2;
12044
- if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
12045
- t2 = cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar");
11586
+ const t2 = !skipCardWrapper && paperMixin;
11587
+ const t3 = !skipCardWrapper && "p-4 md:p-6";
11588
+ let t4;
11589
+ if ($[4] !== t2 || $[5] !== t3) {
11590
+ t4 = cls(t2, "w-full min-h-14 overflow-x-scroll no-scrollbar", t3);
12046
11591
  $[4] = t2;
11592
+ $[5] = t3;
11593
+ $[6] = t4;
12047
11594
  } else {
12048
- t2 = $[4];
11595
+ t4 = $[6];
12049
11596
  }
12050
- let t3;
12051
- if ($[5] !== property || $[6] !== propertyKey || $[7] !== value) {
12052
- t3 = /* @__PURE__ */ jsx("div", { className: t2, children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(PropertyPreview, { propertyKey, value, property, size: "medium" }) }) });
12053
- $[5] = property;
12054
- $[6] = propertyKey;
12055
- $[7] = value;
12056
- $[8] = t3;
11597
+ let t5;
11598
+ if ($[7] !== property || $[8] !== propertyKey || $[9] !== value) {
11599
+ t5 = /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(PropertyPreview, { propertyKey, value, property, size: "medium" }) });
11600
+ $[7] = property;
11601
+ $[8] = propertyKey;
11602
+ $[9] = value;
11603
+ $[10] = t5;
12057
11604
  } else {
12058
- t3 = $[8];
11605
+ t5 = $[10];
12059
11606
  }
12060
- let t4;
12061
- if ($[9] !== error || $[10] !== includeDescription || $[11] !== property || $[12] !== showError) {
12062
- t4 = /* @__PURE__ */ jsx(FieldHelperText, { includeDescription, showError, error, property });
12063
- $[9] = error;
12064
- $[10] = includeDescription;
12065
- $[11] = property;
12066
- $[12] = showError;
12067
- $[13] = t4;
11607
+ let t6;
11608
+ if ($[11] !== t4 || $[12] !== t5) {
11609
+ t6 = /* @__PURE__ */ jsx("div", { className: t4, children: t5 });
11610
+ $[11] = t4;
11611
+ $[12] = t5;
11612
+ $[13] = t6;
12068
11613
  } else {
12069
- t4 = $[13];
11614
+ t6 = $[13];
12070
11615
  }
12071
- let t5;
12072
- if ($[14] !== t1 || $[15] !== t3 || $[16] !== t4) {
12073
- t5 = /* @__PURE__ */ jsxs(Fragment, { children: [
11616
+ let t7;
11617
+ if ($[14] !== error || $[15] !== includeDescription || $[16] !== property || $[17] !== showError) {
11618
+ t7 = /* @__PURE__ */ jsx(FieldHelperText, { includeDescription, showError, error, property });
11619
+ $[14] = error;
11620
+ $[15] = includeDescription;
11621
+ $[16] = property;
11622
+ $[17] = showError;
11623
+ $[18] = t7;
11624
+ } else {
11625
+ t7 = $[18];
11626
+ }
11627
+ let t8;
11628
+ if ($[19] !== t1 || $[20] !== t6 || $[21] !== t7) {
11629
+ t8 = /* @__PURE__ */ jsxs(Fragment, { children: [
12074
11630
  t1,
12075
- t3,
12076
- t4
11631
+ t6,
11632
+ t7
12077
11633
  ] });
12078
- $[14] = t1;
12079
- $[15] = t3;
12080
- $[16] = t4;
12081
- $[17] = t5;
11634
+ $[19] = t1;
11635
+ $[20] = t6;
11636
+ $[21] = t7;
11637
+ $[22] = t8;
12082
11638
  } else {
12083
- t5 = $[17];
11639
+ t8 = $[22];
12084
11640
  }
12085
- return t5;
11641
+ return t8;
12086
11642
  }
12087
11643
  const PropertyFieldBinding = React__default.memo(PropertyFieldBindingInternal, (a, b) => {
12088
11644
  if (a.propertyKey !== b.propertyKey) {
@@ -19050,10 +18606,10 @@ function EditorCollectionAction(t0) {
19050
18606
  }
19051
18607
  return t8;
19052
18608
  }
19053
- const ImportCollectionAction = lazy(() => import("./index-UQOMHwt1.js").then((m) => ({
18609
+ const ImportCollectionAction = lazy(() => import("./index-BrqSvMG0.js").then((m) => ({
19054
18610
  default: m.ImportCollectionAction
19055
18611
  })));
19056
- const ExportCollectionAction = lazy(() => import("./index-DY2k5TtG.js").then((m) => ({
18612
+ const ExportCollectionAction = lazy(() => import("./index-Cb0bPnzZ.js").then((m) => ({
19057
18613
  default: m.ExportCollectionAction
19058
18614
  })));
19059
18615
  function EntityCollectionViewActions(t0) {
@@ -19536,35 +19092,71 @@ function resolveEntitySlots(entity, collection, slotKeys) {
19536
19092
  }
19537
19093
  function resolveRelationDisplayName(relation, prop) {
19538
19094
  const data = "data" in relation ? relation.data : void 0;
19539
- if (!data || !data.values) {
19540
- const id2 = "id" in relation ? relation.id : void 0;
19541
- return id2 !== void 0 ? String(id2) : void 0;
19542
- }
19543
- const values = data.values;
19095
+ let targetCollection;
19544
19096
  try {
19545
- const targetCollection = prop.relation?.target?.();
19097
+ const resolved = prop.relation?.target?.() ?? (typeof prop.target === "function" ? prop.target() : void 0);
19098
+ if (resolved && typeof resolved === "object") {
19099
+ targetCollection = resolved;
19100
+ }
19101
+ } catch {
19102
+ }
19103
+ const extractDisplayName = (values) => {
19546
19104
  if (targetCollection) {
19547
19105
  const targetTitleKey = targetCollection.titleProperty;
19548
19106
  if (targetTitleKey && values[targetTitleKey] !== void 0) {
19549
19107
  return String(values[targetTitleKey]);
19550
19108
  }
19109
+ const isHiddenProp = (p) => {
19110
+ const ui = p.ui;
19111
+ if (ui?.hideFromCollection) return true;
19112
+ if (ui?.disabled?.hidden) return true;
19113
+ return false;
19114
+ };
19115
+ const isDisplayCandidate = (p) => {
19116
+ return p.type === "string" && !p.multiline && !p.markdown && !p.storage && !("isId" in p && p.isId) && !isHiddenProp(p);
19117
+ };
19118
+ const priorityKeys = ["name", "title", "label", "displayName"];
19119
+ for (const pk of priorityKeys) {
19120
+ const p = targetCollection.properties[pk];
19121
+ if (p && isDisplayCandidate(p) && values[pk] !== void 0 && values[pk] !== null) {
19122
+ return String(values[pk]);
19123
+ }
19124
+ }
19551
19125
  for (const [k, p] of Object.entries(targetCollection.properties)) {
19552
19126
  const tp = p;
19553
- if (tp.type === "string" && !tp.multiline && !tp.markdown && !tp.storage && !("isId" in tp && tp.isId)) {
19127
+ if (isDisplayCandidate(tp)) {
19554
19128
  if (values[k] !== void 0 && values[k] !== null) {
19555
19129
  return String(values[k]);
19556
19130
  }
19557
19131
  }
19558
19132
  }
19559
19133
  }
19560
- } catch {
19561
- }
19562
- for (const [, v] of Object.entries(values)) {
19563
- if (typeof v === "string" && v.length > 0 && v.length < 200) {
19564
- return v;
19134
+ for (const [, v] of Object.entries(values)) {
19135
+ if (typeof v === "string" && v.length > 0 && v.length < 200) {
19136
+ return v;
19137
+ }
19565
19138
  }
19139
+ return void 0;
19140
+ };
19141
+ if (data && data.values) {
19142
+ const result = extractDisplayName(data.values);
19143
+ if (result) return result;
19566
19144
  }
19567
19145
  const id = "id" in relation ? relation.id : void 0;
19146
+ if (id !== void 0 && targetCollection) {
19147
+ try {
19148
+ const slug = targetCollection.slug ?? targetCollection.table;
19149
+ if (slug) {
19150
+ const cacheKey = `${slug}/${id}`;
19151
+ const cached = getEntityFromCache(cacheKey);
19152
+ if (cached?.values) {
19153
+ const result = extractDisplayName(cached.values);
19154
+ if (result) return result;
19155
+ }
19156
+ }
19157
+ } catch {
19158
+ }
19159
+ }
19568
19160
  return id !== void 0 ? String(id) : void 0;
19569
19161
  }
19570
19162
  function EntityCard({
@@ -19639,6 +19231,18 @@ function getGridColumnsClass(size) {
19639
19231
  return "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6";
19640
19232
  }
19641
19233
  }
19234
+ function getScrollParent$1(element) {
19235
+ if (!element) return null;
19236
+ let parent = element.parentElement;
19237
+ while (parent) {
19238
+ const overflowY = window.getComputedStyle(parent).overflowY;
19239
+ if (overflowY === "auto" || overflowY === "scroll") {
19240
+ return parent;
19241
+ }
19242
+ parent = parent.parentElement;
19243
+ }
19244
+ return document.documentElement;
19245
+ }
19642
19246
  function EntityCollectionCardView({
19643
19247
  collection,
19644
19248
  tableController,
@@ -19652,7 +19256,6 @@ function EntityCollectionCardView({
19652
19256
  size = "m"
19653
19257
  }) {
19654
19258
  const containerRef = useRef(null);
19655
- const loadMoreRef = useRef(null);
19656
19259
  const hasRestoredScroll = useRef(false);
19657
19260
  const {
19658
19261
  data,
@@ -19685,37 +19288,48 @@ function EntityCollectionCardView({
19685
19288
  if (!dataLoading) isLoadingMore.current = false;
19686
19289
  }, [dataLoading]);
19687
19290
  useEffect(() => {
19688
- const observer = new IntersectionObserver((entries) => {
19291
+ const el = containerRef.current;
19292
+ if (!el) return;
19293
+ const scrollEl = getScrollParent$1(el);
19294
+ if (!scrollEl) return;
19295
+ let rafId = null;
19296
+ const update = () => {
19297
+ rafId = null;
19689
19298
  const {
19690
19299
  paginationEnabled: pe,
19691
19300
  noMoreToLoad: nm,
19692
- dataLoading: dl,
19693
19301
  itemCount: ic,
19694
19302
  pageSize: ps
19695
19303
  } = paginationStateRef.current;
19696
- if (entries[0].isIntersecting && pe && !dl && !nm && !isLoadingMore.current) {
19304
+ if (pe && !nm && !isLoadingMore.current && scrollEl.scrollHeight - scrollEl.scrollTop - scrollEl.clientHeight < 400) {
19697
19305
  isLoadingMore.current = true;
19698
19306
  setItemCount?.((ic ?? ps) + ps);
19699
19307
  }
19700
- }, {
19701
- root: containerRef.current,
19702
- rootMargin: "400px",
19703
- threshold: 0
19308
+ };
19309
+ const onScrollEvent = () => {
19310
+ if (rafId === null) rafId = requestAnimationFrame(update);
19311
+ };
19312
+ scrollEl.addEventListener("scroll", onScrollEvent, {
19313
+ passive: true
19704
19314
  });
19705
- if (loadMoreRef.current) {
19706
- observer.observe(loadMoreRef.current);
19707
- }
19708
- return () => observer.disconnect();
19315
+ const ro = new ResizeObserver(() => update());
19316
+ ro.observe(scrollEl);
19317
+ update();
19318
+ return () => {
19319
+ scrollEl.removeEventListener("scroll", onScrollEvent);
19320
+ ro.disconnect();
19321
+ if (rafId !== null) cancelAnimationFrame(rafId);
19322
+ };
19709
19323
  }, [setItemCount]);
19710
19324
  useEffect(() => {
19711
19325
  if (!containerRef.current || !initialScroll || hasRestoredScroll.current || data.length === 0) return;
19326
+ const scrollEl_0 = getScrollParent$1(containerRef.current);
19327
+ if (!scrollEl_0) return;
19712
19328
  let attempts = 0;
19713
19329
  const maxAttempts = 5;
19714
19330
  const tryRestore = () => {
19715
- const el = containerRef.current;
19716
- if (!el) return;
19717
- if (el.scrollHeight >= initialScroll || attempts >= maxAttempts) {
19718
- el.scrollTop = initialScroll;
19331
+ if (scrollEl_0.scrollHeight >= initialScroll || attempts >= maxAttempts) {
19332
+ scrollEl_0.scrollTop = initialScroll;
19719
19333
  hasRestoredScroll.current = true;
19720
19334
  } else {
19721
19335
  attempts++;
@@ -19726,10 +19340,12 @@ function EntityCollectionCardView({
19726
19340
  }, [initialScroll, data.length]);
19727
19341
  const lastScrollOffset = useRef(0);
19728
19342
  useEffect(() => {
19729
- const container = containerRef.current;
19730
- if (!container || !onScroll) return;
19343
+ const el_0 = containerRef.current;
19344
+ if (!el_0 || !onScroll) return;
19345
+ const scrollEl_1 = getScrollParent$1(el_0);
19346
+ if (!scrollEl_1) return;
19731
19347
  const handleScroll = () => {
19732
- const currentOffset = container.scrollTop;
19348
+ const currentOffset = scrollEl_1.scrollTop;
19733
19349
  const direction = currentOffset > lastScrollOffset.current ? "forward" : "backward";
19734
19350
  lastScrollOffset.current = currentOffset;
19735
19351
  onScroll({
@@ -19738,10 +19354,10 @@ function EntityCollectionCardView({
19738
19354
  scrollUpdateWasRequested: false
19739
19355
  });
19740
19356
  };
19741
- container.addEventListener("scroll", handleScroll, {
19357
+ scrollEl_1.addEventListener("scroll", handleScroll, {
19742
19358
  passive: true
19743
19359
  });
19744
- return () => container.removeEventListener("scroll", handleScroll);
19360
+ return () => scrollEl_1.removeEventListener("scroll", handleScroll);
19745
19361
  }, [onScroll]);
19746
19362
  const handleEntityClick = useCallback((entity) => {
19747
19363
  onEntityClick?.(entity);
@@ -19758,12 +19374,12 @@ function EntityCollectionCardView({
19758
19374
  const gridColumnsClass = getGridColumnsClass(size);
19759
19375
  const isInitialLoading = dataLoading && data.length === 0 && !dataLoadingError;
19760
19376
  const isEmpty = !dataLoading && data.length === 0 && !dataLoadingError;
19761
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "flex-1 overflow-auto p-4", children: dataLoadingError ? /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs(Typography, { className: "text-red-500", children: [
19377
+ return /* @__PURE__ */ jsx("div", { ref: containerRef, className: "w-full p-4", children: dataLoadingError ? /* @__PURE__ */ jsx("div", { className: "h-full flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs(Typography, { className: "text-red-500", children: [
19762
19378
  "Error loading data: ",
19763
19379
  dataLoadingError.message
19764
- ] }) }) : isInitialLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" }) }) : isEmpty ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, { variant: "label", color: "secondary", children: "No entries found" }) }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto", children: [
19380
+ ] }) }) : isInitialLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" }) }) : isEmpty ? /* @__PURE__ */ jsx("div", { className: "w-full flex items-center justify-center py-12 px-8", children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, { variant: "label", color: "secondary", children: "No entries found" }) }) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto", children: [
19765
19381
  /* @__PURE__ */ jsx("div", { className: cls("grid gap-4", gridColumnsClass), children: data.map((entity_3) => /* @__PURE__ */ jsx(EntityCard, { entity: entity_3, collection, onClick: handleEntityClick, selected: isEntitySelected(entity_3), highlighted: isEntityHighlighted(entity_3), onSelectionChange: handleSelectionChange, selectionEnabled, size }, `${entity_3.path}_${entity_3.id}`)) }),
19766
- /* @__PURE__ */ jsxs("div", { ref: loadMoreRef, className: "flex items-center justify-center py-8", children: [
19382
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center py-8", children: [
19767
19383
  dataLoading && /* @__PURE__ */ jsx(CircularProgress, { size: "small" }),
19768
19384
  !dataLoading && noMoreToLoad && data.length > 0 && /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "secondary", children: [
19769
19385
  "All ",
@@ -19820,6 +19436,13 @@ function getScrollParent(element) {
19820
19436
  return document.documentElement;
19821
19437
  }
19822
19438
  function isComplexPropertyType(property) {
19439
+ if (property.type === "array") {
19440
+ const ofProp = "of" in property ? property.of : void 0;
19441
+ const innerProp = ofProp ? Array.isArray(ofProp) ? ofProp[0] : ofProp : void 0;
19442
+ if (innerProp && typeof innerProp === "object" && "enum" in innerProp && innerProp.enum) {
19443
+ return false;
19444
+ }
19445
+ }
19823
19446
  return property.type === "array" || property.type === "map" || property.type === "reference" || property.type === "relation";
19824
19447
  }
19825
19448
  function compactValueSummary(value, property) {
@@ -20148,7 +19771,7 @@ function EntityCollectionListView({
20148
19771
  return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cls("w-full", selectedEntityId === void 0 && "rounded-lg overflow-hidden border " + defaultBorderMixin), children: dataLoadingError ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs(Typography, { className: "text-red-500", children: [
20149
19772
  "Error loading data: ",
20150
19773
  dataLoadingError.message
20151
- ] }) }) : isInitialLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" }) }) : isEmpty ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, { variant: "label", color: "secondary", children: "No entries found" }) }) : (
19774
+ ] }) }) : isInitialLoading ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12 px-8", children: /* @__PURE__ */ jsx(CircularProgress, { size: "small" }) }) : isEmpty ? /* @__PURE__ */ jsx("div", { className: "w-full flex items-center justify-center py-12 px-8", children: emptyComponent ?? /* @__PURE__ */ jsx(Typography, { variant: "label", color: "secondary", children: "No entries found" }) }) : (
20152
19775
  /* Spacer with total height — no internal scroll.
20153
19776
  The nearest scrollable ancestor provides the scrollbar. */
20154
19777
  /* @__PURE__ */ jsxs("div", { style: {
@@ -25237,7 +24860,7 @@ const EntityCollectionView = React__default.memo(function EntityCollectionView2(
25237
24860
  /* @__PURE__ */ jsx(EntityCollectionListView, { collection, tableController, onEntityClick, selectionController: usedSelectionController, selectionEnabled, highlightedEntities: highlightedEntity ? [highlightedEntity] : [], size: listSize, emptyComponent, selectedEntityId: selectedEntityIdProp, getActionsForEntity, path, openEntityMode }, `list-view-${path}`)
25238
24861
  ] }) : innerView }, `split-list-view-${path}`) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col w-full h-full", children: [
25239
24862
  toolbarNode,
25240
- /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col overflow-y-auto", children: viewMode === "list" ? /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col w-full", selectedEntityIdProp === void 0 ? "max-w-6xl mx-auto px-3 md:px-4 lg:px-6 py-4" : ""), children: [
24863
+ /* @__PURE__ */ jsx("div", { className: cls("flex-1 flex flex-col", (viewMode === "list" || viewMode === "cards") && "overflow-y-auto"), children: viewMode === "list" ? /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col w-full", selectedEntityIdProp === void 0 ? "max-w-6xl mx-auto px-3 md:px-4 lg:px-6 py-4" : ""), children: [
25241
24864
  /* @__PURE__ */ jsx("div", { className: cls("grid transition-[grid-template-rows,transform,margin] duration-150 ease-out", selectedEntityIdProp === void 0 ? "grid-rows-[1fr] translate-y-0 mt-12 mb-6" : "grid-rows-[0fr] -translate-y-2 mt-0 mb-0"), children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden flex items-center gap-4", children: /* @__PURE__ */ jsx(Typography, { gutterBottom: true, variant: "h4", className: "grow mb-0", component: "h4", children: collection.name }) }) }),
25242
24865
  pluginInsights.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: pluginInsights }),
25243
24866
  innerView
@@ -26643,7 +26266,7 @@ function DrawerToggle(t0) {
26643
26266
  }
26644
26267
  let t14;
26645
26268
  if ($[31] !== t1 || $[32] !== t13 || $[33] !== t2) {
26646
- t14 = /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-auto px-2 py-2", children: /* @__PURE__ */ jsx(Tooltip, { title: t1, side: "right", sideOffset: 12, asChild: true, open: t2, children: t13 }) });
26269
+ t14 = /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-auto px-4 pt-0.5 pb-2", children: /* @__PURE__ */ jsx(Tooltip, { title: t1, side: "right", sideOffset: 12, asChild: true, open: t2, children: t13 }) });
26647
26270
  $[31] = t1;
26648
26271
  $[32] = t13;
26649
26272
  $[33] = t2;
@@ -26797,7 +26420,7 @@ function DrawerFooterActions({
26797
26420
  } else {
26798
26421
  avatarComponent = null;
26799
26422
  }
26800
- return /* @__PURE__ */ jsx("div", { className: "shrink-0 pb-1", ref: portalRef, children: avatarComponent && /* @__PURE__ */ jsxs("div", { className: "flex items-center px-[16px] py-1", children: [
26423
+ return /* @__PURE__ */ jsx("div", { className: "shrink-0 pt-2 pb-0", ref: portalRef, children: avatarComponent && /* @__PURE__ */ jsxs("div", { className: "flex items-center px-[16px] py-1", children: [
26801
26424
  /* @__PURE__ */ jsxs(Menu, { trigger: /* @__PURE__ */ jsx("div", { className: cls("shrink-0 flex items-center justify-center w-[44px] cursor-pointer", "rounded-md py-1", "hover:bg-surface-accent-100 dark:hover:bg-surface-800", "transition-colors duration-150"), role: "button", tabIndex: 0, "aria-label": t("user_menu") || "User menu", children: avatarComponent }), side: "top", align: "start", children: [
26802
26425
  user && /* @__PURE__ */ jsxs("div", { className: "px-4 py-2 mb-1", children: [
26803
26426
  user.displayName && /* @__PURE__ */ jsx(Typography, { variant: "body1", color: "secondary", children: user.displayName }),
@@ -27415,7 +27038,7 @@ function useLocalCollectionsConfigController(clientOrUrl, baseCollections = [],
27415
27038
  }
27416
27039
  const EMPTY_PLUGINS = [];
27417
27040
  const EMPTY_COLLECTIONS = [];
27418
- const CollectionsStudioView = lazy(() => import("./CollectionsStudioView-Bc3Rxxc2.js").then((n) => n.b).then((m) => ({
27041
+ const CollectionsStudioView = lazy(() => import("./CollectionsStudioView-bsg4AT_Z.js").then((n) => n.b).then((m) => ({
27419
27042
  default: m.CollectionsStudioView
27420
27043
  })));
27421
27044
  function RebaseNavigation({
@@ -27653,10 +27276,10 @@ function _temp$3(event) {
27653
27276
  event.preventDefault();
27654
27277
  event.stopPropagation();
27655
27278
  }
27656
- const CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-D0VqpLPO.js").then((m) => ({
27279
+ const CollectionEditorDialog = lazy(() => import("./CollectionEditorDialog-Bo86h-d-.js").then((m) => ({
27657
27280
  default: m.CollectionEditorDialog
27658
27281
  })));
27659
- const PropertyFormDialog = lazy(() => import("./PropertyEditView-CvRSV-A2.js").then((n) => n.P).then((m) => ({
27282
+ const PropertyFormDialog = lazy(() => import("./PropertyEditView-jCWCxmCz.js").then((n) => n.P).then((m) => ({
27660
27283
  default: m.PropertyFormDialog
27661
27284
  })));
27662
27285
  function CollectionEditorDialogs() {
@@ -29248,6 +28871,9 @@ const PropertyCollectionView = (t0) => {
29248
28871
  if (value === null || value === void 0) {
29249
28872
  return null;
29250
28873
  }
28874
+ if (baseKey === "" && !properties[key]) {
28875
+ return null;
28876
+ }
29251
28877
  const currentKey_0 = baseKey ? `${baseKey}.${key}` : key;
29252
28878
  return /* @__PURE__ */ jsx(PropertyCollectionView, { data: value, properties, baseKey: currentKey_0, size }, currentKey_0);
29253
28879
  };
@@ -30351,15 +29977,15 @@ function validateProperty(property, path, errors) {
30351
29977
  });
30352
29978
  return;
30353
29979
  }
30354
- if (!property.dataType) {
29980
+ if (!property.type) {
30355
29981
  errors.push({
30356
- path: `${path}.dataType`,
29982
+ path: `${path}.type`,
30357
29983
  message: "Required field is missing"
30358
29984
  });
30359
- } else if (!VALID_DATA_TYPES.includes(property.dataType)) {
29985
+ } else if (!VALID_DATA_TYPES.includes(property.type)) {
30360
29986
  errors.push({
30361
- path: `${path}.dataType`,
30362
- message: `Invalid value "${property.dataType}", expected one of: ${VALID_DATA_TYPES.join(", ")}`
29987
+ path: `${path}.type`,
29988
+ message: `Invalid value "${property.type}", expected one of: ${VALID_DATA_TYPES.join(", ")}`
30363
29989
  });
30364
29990
  }
30365
29991
  if (property.name !== void 0 && typeof property.name !== "string") {
@@ -30368,7 +29994,7 @@ function validateProperty(property, path, errors) {
30368
29994
  message: "Must be a string"
30369
29995
  });
30370
29996
  }
30371
- if (property.dataType === "array") {
29997
+ if (property.type === "array") {
30372
29998
  if (property.of) {
30373
29999
  if (Array.isArray(property.of)) {
30374
30000
  property.of.forEach((ofProp, index) => {
@@ -30389,10 +30015,10 @@ function validateProperty(property, path, errors) {
30389
30015
  }
30390
30016
  }
30391
30017
  }
30392
- if (property.dataType === "map" && property.properties) {
30018
+ if (property.type === "map" && property.properties) {
30393
30019
  validateProperties(property.properties, `${path}.properties`, errors);
30394
30020
  }
30395
- if (property.dataType === "reference") {
30021
+ if (property.type === "reference") {
30396
30022
  if (property.path !== void 0 && typeof property.path !== "string") {
30397
30023
  errors.push({
30398
30024
  path: `${path}.path`,
@@ -30400,7 +30026,7 @@ function validateProperty(property, path, errors) {
30400
30026
  });
30401
30027
  }
30402
30028
  }
30403
- if (property.dataType === "relation") {
30029
+ if (property.type === "relation") {
30404
30030
  if (property.target !== void 0 && typeof property.target !== "string" && typeof property.target !== "function") {
30405
30031
  errors.push({
30406
30032
  path: `${path}.target`,
@@ -30472,7 +30098,7 @@ function validateProperty(property, path, errors) {
30472
30098
  });
30473
30099
  }
30474
30100
  }
30475
- if (property.dataType === "vector") {
30101
+ if (property.type === "vector") {
30476
30102
  if (property.dimensions !== void 0 && (typeof property.dimensions !== "number" || isNaN(property.dimensions) || property.dimensions <= 0)) {
30477
30103
  errors.push({
30478
30104
  path: `${path}.dimensions`,
@@ -30480,7 +30106,7 @@ function validateProperty(property, path, errors) {
30480
30106
  });
30481
30107
  }
30482
30108
  }
30483
- if (property.dataType === "string" && property.storage) {
30109
+ if (property.type === "string" && property.storage) {
30484
30110
  if (typeof property.storage !== "object") {
30485
30111
  errors.push({
30486
30112
  path: `${path}.storage`,
@@ -30750,7 +30376,7 @@ export {
30750
30376
  MapFieldBinding as Z,
30751
30377
  MapPropertyPreview as _,
30752
30378
  ArrayContainer as a,
30753
- isReferenceProperty as a$,
30379
+ mergeEntityActions as a$,
30754
30380
  MultiSelectFieldBinding as a0,
30755
30381
  NavigationCard as a1,
30756
30382
  NavigationStateContext as a2,
@@ -30761,98 +30387,96 @@ export {
30761
30387
  PropertyPreview as a7,
30762
30388
  ReadOnlyFieldBinding as a8,
30763
30389
  RebaseNavigation as a9,
30764
- VirtualTableInput as aA,
30765
- buildCollectionGenerationCallback as aB,
30766
- buildSidePanelsFromUrl as aC,
30767
- convertDataToEntity as aD,
30768
- convertFileToJson as aE,
30769
- copyEntityAction as aF,
30770
- deleteEntityAction as aG,
30771
- editEntityAction as aH,
30772
- flattenEntry as aI,
30773
- getBracketNotation as aJ,
30774
- getDefaultFieldConfig as aK,
30775
- getDefaultFieldId as aL,
30776
- getDefaultPropertiesOrder as aM,
30777
- getEntityPreviewKeys as aN,
30778
- getEntityTitlePropertyKey as aO,
30779
- getEntityViewWidth as aP,
30780
- getFieldConfig as aQ,
30781
- getFieldId as aR,
30782
- getFullId as aS,
30783
- getFullIdPath as aT,
30784
- getIconForProperty as aU,
30785
- getIconForWidget as aV,
30786
- getInferenceType as aW,
30787
- getPropertiesWithPropertiesOrder as aX,
30788
- getPropertyInPath as aY,
30789
- getResolvedPropertyInPath as aZ,
30790
- idToPropertiesPath as a_,
30390
+ buildSidePanelsFromUrl as aA,
30391
+ convertDataToEntity as aB,
30392
+ convertFileToJson as aC,
30393
+ copyEntityAction as aD,
30394
+ deleteEntityAction as aE,
30395
+ editEntityAction as aF,
30396
+ flattenEntry as aG,
30397
+ getBracketNotation as aH,
30398
+ getDefaultFieldConfig as aI,
30399
+ getDefaultFieldId as aJ,
30400
+ getDefaultPropertiesOrder as aK,
30401
+ getEntityPreviewKeys as aL,
30402
+ getEntityTitlePropertyKey as aM,
30403
+ getEntityViewWidth as aN,
30404
+ getFieldConfig as aO,
30405
+ getFieldId as aP,
30406
+ getFullId as aQ,
30407
+ getFullIdPath as aR,
30408
+ getIconForProperty as aS,
30409
+ getIconForWidget as aT,
30410
+ getInferenceType as aU,
30411
+ getPropertiesWithPropertiesOrder as aV,
30412
+ getPropertyInPath as aW,
30413
+ getResolvedPropertyInPath as aX,
30414
+ idToPropertiesPath as aY,
30415
+ isReferenceProperty as aZ,
30416
+ isRelationProperty as a_,
30791
30417
  ReferenceAsStringFieldBinding as aa,
30792
30418
  ReferenceFieldBinding as ab,
30793
30419
  ReferencePreview as ac,
30794
30420
  RelationPreview as ad,
30795
30421
  RepeatFieldBinding as ae,
30796
- RoleChip as af,
30797
- RolesView as ag,
30798
- Scaffold as ah,
30799
- SearchIconsView as ai,
30800
- SelectFieldBinding as aj,
30801
- SelectableTable as ak,
30802
- SelectableTableContext as al,
30803
- SideDialogs as am,
30804
- SideEntityControllerContext as an,
30805
- SideEntityProvider as ao,
30806
- SkeletonPropertyComponent as ap,
30807
- StorageThumbnail as aq,
30808
- StorageThumbnailInternal as ar,
30809
- StorageUploadFieldBinding as as,
30810
- StringPropertyPreview as at,
30811
- SwitchFieldBinding as au,
30812
- TextFieldBinding as av,
30813
- UrlComponentPreview as aw,
30814
- UrlContext as ax,
30815
- UserPreview as ay,
30816
- VectorFieldBinding as az,
30422
+ Scaffold as af,
30423
+ SearchIconsView as ag,
30424
+ SelectFieldBinding as ah,
30425
+ SelectableTable as ai,
30426
+ SelectableTableContext as aj,
30427
+ SideDialogs as ak,
30428
+ SideEntityControllerContext as al,
30429
+ SideEntityProvider as am,
30430
+ SkeletonPropertyComponent as an,
30431
+ StorageThumbnail as ao,
30432
+ StorageThumbnailInternal as ap,
30433
+ StorageUploadFieldBinding as aq,
30434
+ StringPropertyPreview as ar,
30435
+ SwitchFieldBinding as as,
30436
+ TextFieldBinding as at,
30437
+ UrlComponentPreview as au,
30438
+ UrlContext as av,
30439
+ UserPreview as aw,
30440
+ VectorFieldBinding as ax,
30441
+ VirtualTableInput as ay,
30442
+ buildCollectionGenerationCallback as az,
30817
30443
  ArrayCustomShapedFieldBinding as b,
30818
- isRelationProperty as b0,
30819
- mergeEntityActions as b1,
30820
- namespaceToPropertiesOrderPath as b2,
30821
- namespaceToPropertiesPath as b3,
30822
- processValueMapping as b4,
30823
- renderSkeletonCaptionText as b5,
30824
- renderSkeletonIcon as b6,
30825
- renderSkeletonImageThumbnail as b7,
30826
- renderSkeletonText as b8,
30827
- resetPasswordAction as b9,
30828
- validateCollectionJson as bA,
30829
- zodToFormErrors as bB,
30830
- resolveEntityAction as ba,
30831
- resolveEntityView as bb,
30832
- sanitizeUrl as bc,
30833
- unflattenObject as bd,
30834
- useApp as be,
30835
- useBreadcrumbsController as bf,
30836
- useBuildCollectionRegistryController as bg,
30837
- useBuildNavigationStateController as bh,
30838
- useBuildSideEntityController as bi,
30839
- useBuildUrlController as bj,
30840
- useCMSContext as bk,
30841
- useClearRestoreValue as bl,
30842
- useCollectionEditorController as bm,
30843
- useCollectionRegistryController as bn,
30844
- useCollectionsConfigController as bo,
30845
- useEntitySelectionDialog as bp,
30846
- useImportConfig as bq,
30847
- useLocalCollectionsConfigController as br,
30848
- useNavigationStateController as bs,
30849
- useResolvedCollections as bt,
30850
- useResolvedViews as bu,
30851
- useSelectionController as bv,
30852
- useSideDialogsController as bw,
30853
- useSideEntityController as bx,
30854
- useTopLevelNavigation as by,
30855
- useUrlController as bz,
30444
+ namespaceToPropertiesOrderPath as b0,
30445
+ namespaceToPropertiesPath as b1,
30446
+ processValueMapping as b2,
30447
+ renderSkeletonCaptionText as b3,
30448
+ renderSkeletonIcon as b4,
30449
+ renderSkeletonImageThumbnail as b5,
30450
+ renderSkeletonText as b6,
30451
+ resetPasswordAction as b7,
30452
+ resolveEntityAction as b8,
30453
+ resolveEntityView as b9,
30454
+ sanitizeUrl as ba,
30455
+ unflattenObject as bb,
30456
+ useApp as bc,
30457
+ useBreadcrumbsController as bd,
30458
+ useBuildCollectionRegistryController as be,
30459
+ useBuildNavigationStateController as bf,
30460
+ useBuildSideEntityController as bg,
30461
+ useBuildUrlController as bh,
30462
+ useCMSContext as bi,
30463
+ useClearRestoreValue as bj,
30464
+ useCollectionEditorController as bk,
30465
+ useCollectionRegistryController as bl,
30466
+ useCollectionsConfigController as bm,
30467
+ useEntitySelectionDialog as bn,
30468
+ useImportConfig as bo,
30469
+ useLocalCollectionsConfigController as bp,
30470
+ useNavigationStateController as bq,
30471
+ useResolvedCollections as br,
30472
+ useResolvedViews as bs,
30473
+ useSelectionController as bt,
30474
+ useSideDialogsController as bu,
30475
+ useSideEntityController as bv,
30476
+ useTopLevelNavigation as bw,
30477
+ useUrlController as bx,
30478
+ validateCollectionJson as by,
30479
+ zodToFormErrors as bz,
30856
30480
  ArrayEnumPreview as c,
30857
30481
  ArrayOfReferencesFieldBinding as d,
30858
30482
  ArrayOfReferencesPreview as e,
@@ -30878,4 +30502,4 @@ export {
30878
30502
  EntityCollectionTable as y,
30879
30503
  EntityCollectionView as z
30880
30504
  };
30881
- //# sourceMappingURL=util-ZM9gQuCv.js.map
30505
+ //# sourceMappingURL=util-CvNp6A-r.js.map