@rebasepro/admin 0.12.0 → 0.12.1-canary.g009ed95

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 (172) hide show
  1. package/README.md +1 -1
  2. package/dist/{CollectionEditorDialog-Dpc75wIZ.js → CollectionEditorDialog-B-iVE9y3.js} +75 -62
  3. package/dist/{CollectionEditorDialog-Dpc75wIZ.js.map → CollectionEditorDialog-B-iVE9y3.js.map} +1 -1
  4. package/dist/{PropertyEditView-DH3XZC2x.js → PropertyEditView-DoLEH_bQ.js} +36 -16
  5. package/dist/{PropertyEditView-DH3XZC2x.js.map → PropertyEditView-DoLEH_bQ.js.map} +1 -1
  6. package/dist/{RouterCollectionsStudioView-BZLq4MGp.js → RouterCollectionsStudioView-C3669Ezm.js} +5 -5
  7. package/dist/{RouterCollectionsStudioView-BZLq4MGp.js.map → RouterCollectionsStudioView-C3669Ezm.js.map} +1 -1
  8. package/dist/collection_editor/serializable_types.d.ts +4 -1
  9. package/dist/collection_editor/ui/collection_editor/CollectionRelationsTab.d.ts +1 -0
  10. package/dist/collection_editor/useLocalCollectionsConfigController.d.ts +8 -0
  11. package/dist/collection_editor_ui.js +5 -5
  12. package/dist/collection_editor_ui.js.map +1 -1
  13. package/dist/components/CollectionViewBinding/SplitListCloseButton.d.ts +10 -0
  14. package/dist/components/CollectionViewBinding/SplitViewContext.d.ts +23 -0
  15. package/dist/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.d.ts +26 -0
  16. package/dist/components/DetailViewBinding.d.ts +5 -0
  17. package/dist/components/EditFormActions.d.ts +12 -1
  18. package/dist/components/EditViewBinding.d.ts +6 -1
  19. package/dist/components/EntityIdentityBar.d.ts +53 -0
  20. package/dist/components/EntityInspector.d.ts +29 -0
  21. package/dist/components/EntityPreviewNesting.d.ts +25 -0
  22. package/dist/components/EntityViewBinding.d.ts +9 -0
  23. package/dist/components/InlineEntityPreview.d.ts +47 -0
  24. package/dist/components/index.d.ts +2 -0
  25. package/dist/editor.js +18 -10
  26. package/dist/editor.js.map +1 -1
  27. package/dist/{export-BzIpUdSK.js → export-B8DIn-u8.js} +2 -2
  28. package/dist/{export-BzIpUdSK.js.map → export-B8DIn-u8.js.map} +1 -1
  29. package/dist/form/EntityForm.d.ts +1 -1
  30. package/dist/form/EntityFormActions.d.ts +11 -1
  31. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  32. package/dist/form/components/FieldBlock.d.ts +30 -0
  33. package/dist/form/components/FormRail.d.ts +18 -0
  34. package/dist/form/components/FormSections.d.ts +16 -0
  35. package/dist/form/components/index.d.ts +3 -2
  36. package/dist/form/components/useRailVisible.d.ts +24 -0
  37. package/dist/form/field_bindings/BinaryFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/DateTimeFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/GeopointFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  41. package/dist/form/field_bindings/MultiSelectFieldBinding.d.ts +1 -1
  42. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  43. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  44. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
  45. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -1
  46. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  47. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +1 -1
  48. package/dist/form/field_bindings/VectorFieldBinding.d.ts +1 -1
  49. package/dist/{history-g9688IaK.js → history-ClwDEtqN.js} +32 -31
  50. package/dist/history-ClwDEtqN.js.map +1 -0
  51. package/dist/hooks/navigation/utils.d.ts +16 -0
  52. package/dist/hooks/useBuildSidePanel.d.ts +14 -0
  53. package/dist/hooks/useEntityDisplayTitle.d.ts +18 -0
  54. package/dist/hooks/useRecordActions.d.ts +17 -0
  55. package/dist/{import-BjUG-cIY.js → import-Cwzf4RW5.js} +2 -2
  56. package/dist/{import-BjUG-cIY.js.map → import-Cwzf4RW5.js.map} +1 -1
  57. package/dist/index.js +106 -35
  58. package/dist/index.js.map +1 -1
  59. package/dist/markdown-CklalUUk.js.map +1 -1
  60. package/dist/preview/components/InlineEntityListPreview.d.ts +15 -0
  61. package/dist/preview/index.d.ts +1 -0
  62. package/dist/preview/property_previews/ArrayOfReferencesPreview.d.ts +1 -1
  63. package/dist/preview/property_previews/ArrayOfRelationsPreview.d.ts +1 -1
  64. package/dist/types/components/EntityFormActionsProps.d.ts +0 -1
  65. package/dist/types/components/EntityFormProps.d.ts +0 -5
  66. package/dist/types/fields.d.ts +24 -0
  67. package/dist/{util-B5fJm1FA.js → util-DSh3HRzK.js} +1974 -1130
  68. package/dist/util-DSh3HRzK.js.map +1 -0
  69. package/package.json +32 -34
  70. package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
  71. package/src/collection_editor/serializable_types.ts +4 -3
  72. package/src/collection_editor/serializable_utils.ts +51 -17
  73. package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +65 -22
  74. package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +38 -30
  75. package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -1
  76. package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +1 -1
  77. package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +1 -1
  78. package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +16 -0
  79. package/src/collection_editor/useLocalCollectionsConfigController.tsx +127 -15
  80. package/src/collection_editor/validateCollectionJson.ts +3 -3
  81. package/src/components/AdminModeSyncer.tsx +1 -1
  82. package/src/components/CollectionTableBinding/PropertyTableCell.tsx +10 -2
  83. package/src/components/CollectionTableBinding/column_utils.tsx +26 -2
  84. package/src/components/CollectionTableBinding/table_bindings.tsx +2 -1
  85. package/src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx +23 -16
  86. package/src/components/CollectionViewBinding/CollectionViewActions.tsx +7 -1
  87. package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +8 -2
  88. package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +22 -11
  89. package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +33 -0
  90. package/src/components/CollectionViewBinding/SplitListView.tsx +18 -3
  91. package/src/components/CollectionViewBinding/SplitViewContext.tsx +34 -0
  92. package/src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts +48 -9
  93. package/src/components/CollectionViewBinding/useBoardDataController.tsx +80 -25
  94. package/src/components/CollectionViewBinding/usePreviewSlots.ts +18 -6
  95. package/src/components/DefaultAppBar.tsx +1 -1
  96. package/src/components/DefaultDrawer.tsx +1 -1
  97. package/src/components/DetailViewBinding.tsx +100 -143
  98. package/src/components/DrawerNavigationItem.tsx +1 -1
  99. package/src/components/EditFormActions.tsx +54 -129
  100. package/src/components/EditViewBinding.tsx +182 -93
  101. package/src/components/EntityIdentityBar.tsx +288 -0
  102. package/src/components/EntityInspector.tsx +132 -0
  103. package/src/components/EntityPreviewBinding.tsx +6 -2
  104. package/src/components/EntityPreviewNesting.tsx +50 -0
  105. package/src/components/EntityViewBinding.tsx +35 -32
  106. package/src/components/HomePage/FavouritesView.tsx +1 -1
  107. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  108. package/src/components/HomePage/SmallNavigationCard.tsx +1 -1
  109. package/src/components/InlineEntityPreview.tsx +149 -0
  110. package/src/components/RebaseLayout.tsx +1 -1
  111. package/src/components/RebaseNavigation.tsx +45 -5
  112. package/src/components/RebaseRouteDefs.tsx +1 -1
  113. package/src/components/SelectableTable/SelectableTable.tsx +2 -2
  114. package/src/components/SidePanelBinding.tsx +19 -13
  115. package/src/components/UserSelector.tsx +12 -6
  116. package/src/components/common/default_entity_actions.tsx +4 -3
  117. package/src/components/history/EntityHistoryEntry.tsx +28 -7
  118. package/src/components/history/EntityHistoryView.tsx +20 -20
  119. package/src/components/history/LastEditedByIndicator.tsx +4 -3
  120. package/src/components/index.ts +2 -0
  121. package/src/data_import/utils/get_import_inference_type.ts +6 -0
  122. package/src/form/EntityForm.tsx +267 -179
  123. package/src/form/EntityFormActions.tsx +50 -99
  124. package/src/form/EntityFormBinding.tsx +4 -2
  125. package/src/form/PropertyFieldBinding.tsx +4 -0
  126. package/src/form/components/FieldBlock.tsx +119 -0
  127. package/src/form/components/FormRail.tsx +125 -0
  128. package/src/form/components/FormSections.tsx +118 -0
  129. package/src/form/components/index.tsx +3 -2
  130. package/src/form/components/useRailVisible.tsx +46 -0
  131. package/src/form/field_bindings/BinaryFieldBinding.tsx +3 -2
  132. package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -2
  133. package/src/form/field_bindings/GeopointFieldBinding.tsx +3 -2
  134. package/src/form/field_bindings/MapFieldBinding.tsx +1 -2
  135. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +3 -2
  136. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -1
  137. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -1
  138. package/src/form/field_bindings/ReferenceFieldBinding.tsx +2 -1
  139. package/src/form/field_bindings/RelationFieldBinding.tsx +6 -4
  140. package/src/form/field_bindings/RepeatFieldBinding.tsx +4 -1
  141. package/src/form/field_bindings/SelectFieldBinding.tsx +3 -2
  142. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +31 -8
  143. package/src/form/field_bindings/SwitchFieldBinding.tsx +7 -3
  144. package/src/form/field_bindings/TextFieldBinding.tsx +18 -16
  145. package/src/form/field_bindings/UserSelectFieldBinding.tsx +3 -2
  146. package/src/form/field_bindings/VectorFieldBinding.tsx +2 -1
  147. package/src/hooks/navigation/useBuildUrlController.tsx +1 -1
  148. package/src/hooks/navigation/useTopLevelNavigation.ts +18 -7
  149. package/src/hooks/navigation/utils.ts +20 -0
  150. package/src/hooks/useBuildSideDialogsController.tsx +2 -2
  151. package/src/hooks/useBuildSidePanel.tsx +22 -61
  152. package/src/hooks/useEntityDisplayTitle.tsx +60 -0
  153. package/src/hooks/useHistory.ts +6 -5
  154. package/src/hooks/useRecordActions.tsx +69 -0
  155. package/src/hooks/useResolvedUsers.ts +10 -5
  156. package/src/preview/PropertyPreview.tsx +48 -22
  157. package/src/preview/components/InlineEntityListPreview.tsx +42 -0
  158. package/src/preview/components/ReferencePreview.tsx +34 -14
  159. package/src/preview/components/RelationPreview.tsx +34 -14
  160. package/src/preview/index.ts +1 -0
  161. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +24 -1
  162. package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +25 -1
  163. package/src/routes/RebaseRoute.tsx +2 -2
  164. package/src/types/components/EntityFormActionsProps.tsx +0 -1
  165. package/src/types/components/EntityFormProps.tsx +0 -6
  166. package/src/types/fields.tsx +27 -0
  167. package/dist/form/components/FormEntry.d.ts +0 -6
  168. package/dist/form/components/FormLayout.d.ts +0 -5
  169. package/dist/history-g9688IaK.js.map +0 -1
  170. package/dist/util-B5fJm1FA.js.map +0 -1
  171. package/src/form/components/FormEntry.tsx +0 -22
  172. package/src/form/components/FormLayout.tsx +0 -16
package/README.md CHANGED
@@ -8,7 +8,7 @@ CMS frontend — content management views, forms, routing, visual schema editor,
8
8
  pnpm add @rebasepro/admin
9
9
  ```
10
10
 
11
- **Peer dependencies:** `react >= 19`, `react-dom >= 19`, `react-router ^7`, `react-router-dom ^7`
11
+ **Peer dependencies:** `react >= 19.2.7`, `react-dom >= 19.2.7`, `react-router ^8`
12
12
 
13
13
  ## What This Package Does
14
14
 
@@ -1,14 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { $t as CollectionTableBinding, A as getFieldId, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType, Ft as FieldCaption, In as useCollectionRegistryController, Nt as PropertyConfigBadge, Ot as ImportSaveInProgress, Pt as SearchIconsView, St as DataNewPropertiesMapping, Zt as useSelectionController, _ as useCollectionsConfigController, i as namespaceToPropertiesOrderPath, in as useUrlController, k as getFieldConfig, kt as ImportFileUpload, l as validateCollectionJson, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, on as useNavigationStateController, r as idToPropertiesPath, t as getFullId, vt as useCollectionEditorController, xt as ImportNewPropertyFieldPreview } from "./util-B5fJm1FA.js";
3
- import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, l as useSafeSnackbarController, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-DH3XZC2x.js";
2
+ import { $t as CollectionTableBinding, A as getFieldId, Ct as convertDataToEntity, Dt as useImportConfig, Et as getInferenceType, Ft as FieldCaption, Ln as useCollectionRegistryController, Nt as PropertyConfigBadge, Ot as ImportSaveInProgress, Pt as SearchIconsView, St as DataNewPropertiesMapping, Zt as useSelectionController, _ as useCollectionsConfigController, i as namespaceToPropertiesOrderPath, in as useUrlController, k as getFieldConfig, kt as ImportFileUpload, l as validateCollectionJson, m as toSerializableCollectionConfig, n as getFullIdPath, o as CollectionGenerationApiError, on as useNavigationStateController, r as idToPropertiesPath, t as getFullId, vt as useCollectionEditorController, xt as ImportNewPropertyFieldPreview } from "./util-DSh3HRzK.js";
3
+ import { a as updatePropertyFromWidget, c as useAIModifiedPaths, i as supportedFields, l as useSafeSnackbarController, n as PropertyForm, o as PropertyTree, r as PropertyFormDialog, s as AIModifiedPathsProvider } from "./PropertyEditView-DoLEH_bQ.js";
4
4
  import * as React$1 from "react";
5
5
  import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
6
6
  import { Alert, AppWindow, ArrowLeftIcon, BooleanSwitchWithLabel, Button, Card, CheckIcon, Chip, CircularProgress, CircularProgressCenter, CodeIcon, ColumnsIcon, Container, CopyIcon, DebouncedTextField, Dialog, DialogActions, DialogContent, DialogTitle, ErrorBoundary, FileIcon, FileSearchIcon, FileTextIcon, IconButton, KanbanIcon, KeyIcon, LayoutGridIcon, ListIcon, LoadingButton, Menu, MultiSelect, MultiSelectItem, PanelLeftIcon, Paper, PlusIcon, Select, SelectItem, ShoppingCartIcon, SquareIcon, Tab, TableIcon, Tabs, TextField, ToggleButtonGroup, Tooltip, Trash2Icon, Typography, UserIcon, XIcon, cls, coolIconKeys, defaultBorderMixin, iconSize } from "@rebasepro/ui";
7
- import { buildCollectionFromTableMetadata, getEffectiveSecurityRules, getSubcollections, getTableName, isPropertyBuilder } from "@rebasepro/common";
7
+ import { buildCollectionFromTableMetadata, getGeneratedPolicyNames, getSubcollections, getTableName, isPropertyBuilder } from "@rebasepro/common";
8
8
  import { AIIcon, ConfirmationDialog, ErrorView, IconForView, UnsavedChangesDialog, removeInitialAndTrailingSlashes, useAuthController, useCustomizationController, useLargeLayout, useRebaseContext, useUnsavedChangesDialog } from "@rebasepro/app";
9
9
  import { Field, Formex, clone, getIn, useCreateFormex, useFormex } from "@rebasepro/forms";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
- import { camelCase, getPolicyNamesForRule, getPolicyNamesForRules, isEmptyObject, mergeDeep, prettifyIdentifier, randomString, removeUndefined, singular, slugify, toSnakeCase, unslugify } from "@rebasepro/utils";
11
+ import { camelCase, getPolicyNamesForRule, isEmptyObject, mergeDeep, prettifyIdentifier, randomString, removeUndefined, singular, slugify, toSnakeCase, unslugify } from "@rebasepro/utils";
12
12
  import { getDataSourceCapabilities } from "@rebasepro/types";
13
13
  import { z } from "zod";
14
14
  import { buildEntityPropertiesFromData, buildPropertyFromData } from "@rebasepro/inference";
@@ -875,7 +875,8 @@ function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyE
875
875
  return currentPropertiesOrderRef.current[namespace] ?? getIn(values, namespaceToPropertiesOrderPath(namespace));
876
876
  };
877
877
  const updatePropertiesOrder = (newPropertiesOrder, namespace) => {
878
- setFieldValue(namespaceToPropertiesOrderPath(namespace), newPropertiesOrder, false);
878
+ const propertiesOrderPath = namespaceToPropertiesOrderPath(namespace);
879
+ setFieldValue(propertiesOrderPath, newPropertiesOrder, false);
879
880
  currentPropertiesOrderRef.current[namespace ?? ""] = newPropertiesOrder;
880
881
  };
881
882
  const deleteProperty = (propertyKey, namespace) => {
@@ -884,7 +885,10 @@ function CollectionPropertiesEditorForm({ showErrors, isNewCollection, propertyE
884
885
  if (!fullId) throw Error("collection editor miss config");
885
886
  setFieldValue(idToPropertiesPath(fullId), void 0, false);
886
887
  const currentPropertiesOrder = getCurrentPropertiesOrder(namespace);
887
- if (currentPropertiesOrder) updatePropertiesOrder(currentPropertiesOrder.filter((p) => p !== propertyKey), namespace);
888
+ if (currentPropertiesOrder) {
889
+ const newPropertiesOrder = currentPropertiesOrder.filter((p) => p !== propertyKey);
890
+ updatePropertiesOrder(newPropertiesOrder, namespace);
891
+ }
888
892
  setNewPropertyDialogOpen(false);
889
893
  setSelectedPropertyIndex(void 0);
890
894
  setSelectedPropertyKey(void 0);
@@ -1177,7 +1181,8 @@ function CollectionJsonImportDialog({ open, onClose, onImport }) {
1177
1181
  setErrors([]);
1178
1182
  return;
1179
1183
  }
1180
- setErrors(validateCollectionJson(value).errors);
1184
+ const result = validateCollectionJson(value);
1185
+ setErrors(result.errors);
1181
1186
  }, []);
1182
1187
  const handleImport = useCallback(() => {
1183
1188
  const result = validateCollectionJson(jsonValue);
@@ -2077,7 +2082,8 @@ function CollectionEditorImportMapping({ importConfig, propertyConfigs }) {
2077
2082
  return currentPropertiesOrderRef.current[namespace] ?? getIn(values, namespaceToPropertiesOrderPath(namespace));
2078
2083
  };
2079
2084
  const updatePropertiesOrder = (newPropertiesOrder, namespace) => {
2080
- setFieldValue(namespaceToPropertiesOrderPath(namespace), newPropertiesOrder, false);
2085
+ const propertiesOrderPath = namespaceToPropertiesOrderPath(namespace);
2086
+ setFieldValue(propertiesOrderPath, newPropertiesOrder, false);
2081
2087
  currentPropertiesOrderRef.current[namespace ?? ""] = newPropertiesOrder;
2082
2088
  };
2083
2089
  if (previousId && previousId !== id) {
@@ -2379,6 +2385,8 @@ function toSecurityRule(policy) {
2379
2385
  function CollectionRLSTab() {
2380
2386
  const { values, setFieldValue } = useFormex();
2381
2387
  const [editingPolicy, setEditingPolicy] = useState(null);
2388
+ const { readOnly, readOnlyReason } = useCollectionsConfigController();
2389
+ const readOnlyTitle = readOnlyReason || "This backend does not accept collection edits.";
2382
2390
  const rules = values.securityRules || [];
2383
2391
  const { databaseAdmin } = useRebaseContext();
2384
2392
  const [dbPolicies, setDbPolicies] = useState([]);
@@ -2400,7 +2408,7 @@ function CollectionRLSTab() {
2400
2408
  if (Array.isArray(res)) return res;
2401
2409
  return [];
2402
2410
  };
2403
- setDbPolicies(extractRows(result).map((p) => {
2411
+ const policies = extractRows(result).map((p) => {
2404
2412
  let parsedRoles = [];
2405
2413
  const r = p.roles || p.ROLES;
2406
2414
  if (Array.isArray(r)) parsedRoles = r;
@@ -2414,7 +2422,8 @@ function CollectionRLSTab() {
2414
2422
  qual: p.qual || p.QUAL || null,
2415
2423
  with_check: p.with_check || p.WITH_CHECK || null
2416
2424
  };
2417
- }));
2425
+ });
2426
+ setDbPolicies(policies);
2418
2427
  } catch (e) {
2419
2428
  console.error("Failed to fetch DB policies", e);
2420
2429
  } finally {
@@ -2461,27 +2470,10 @@ function CollectionRLSTab() {
2461
2470
  };
2462
2471
  }, [databaseAdmin]);
2463
2472
  const tableName = values.id || values.table || values.alias;
2464
- /**
2465
- * Every policy name `rebase db push` would write for this collection.
2466
- *
2467
- * Two things make this more than `rules.map(r => r.name)`:
2468
- * - a rule without an explicit `name` becomes `<table>_<op>_<hash>`, so
2469
- * comparing `rule.name` to `policyname` never matches for it;
2470
- * - the generator also injects the safe-by-default baseline
2471
- * (`<table>_default_admin_*`), which is in no collection's `securityRules`.
2472
- *
2473
- * Missing either made Rebase's own policies look hand-written, and offered to
2474
- * import them back into the codebase that produced them.
2475
- */
2476
2473
  const generatedPolicyNames = useMemo(() => {
2477
2474
  if (!tableName) return /* @__PURE__ */ new Set();
2478
- const effectiveRules = getEffectiveSecurityRules(values);
2479
- return getPolicyNamesForRules([...rules, ...effectiveRules], tableName);
2480
- }, [
2481
- rules,
2482
- tableName,
2483
- values
2484
- ]);
2475
+ return getGeneratedPolicyNames(values);
2476
+ }, [tableName, values]);
2485
2477
  const unmappedPolicies = dbPolicies.filter((dp) => !generatedPolicyNames.has(dp.policyname));
2486
2478
  const handleSave = async (newPolicy) => {
2487
2479
  const rule = toSecurityRule(newPolicy);
@@ -2504,11 +2496,15 @@ function CollectionRLSTab() {
2504
2496
  children: [/* @__PURE__ */ jsx(Typography, {
2505
2497
  variant: "h5",
2506
2498
  children: "Row Level Security"
2507
- }), /* @__PURE__ */ jsx(Button, {
2508
- variant: "filled",
2509
- color: "neutral",
2510
- onClick: () => setEditingPolicy("new"),
2511
- children: "CREATE POLICY"
2499
+ }), /* @__PURE__ */ jsx(Tooltip, {
2500
+ title: readOnly ? readOnlyTitle : void 0,
2501
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
2502
+ variant: "filled",
2503
+ color: "neutral",
2504
+ disabled: readOnly,
2505
+ onClick: () => setEditingPolicy("new"),
2506
+ children: "CREATE POLICY"
2507
+ }) })
2512
2508
  })]
2513
2509
  }),
2514
2510
  rules.length === 0 ? /* @__PURE__ */ jsx("div", {
@@ -2550,6 +2546,7 @@ function CollectionRLSTab() {
2550
2546
  children: [/* @__PURE__ */ jsx(Button, {
2551
2547
  size: "small",
2552
2548
  variant: "text",
2549
+ disabled: readOnly,
2553
2550
  onClick: () => setEditingPolicy({
2554
2551
  policyname: rule.name ?? "",
2555
2552
  tablename: values.id || values.table || values.alias || "your_table",
@@ -2562,6 +2559,7 @@ function CollectionRLSTab() {
2562
2559
  children: "EDIT"
2563
2560
  }), /* @__PURE__ */ jsx(IconButton, {
2564
2561
  size: "small",
2562
+ disabled: readOnly,
2565
2563
  onClick: () => {
2566
2564
  setFieldValue("securityRules", rules.filter((r) => r.name !== rule.name));
2567
2565
  },
@@ -2630,15 +2628,19 @@ function CollectionRLSTab() {
2630
2628
  })]
2631
2629
  }), /* @__PURE__ */ jsx("div", {
2632
2630
  className: "flex items-center gap-1 sm:gap-2 shrink-0",
2633
- children: /* @__PURE__ */ jsx(Button, {
2634
- size: "small",
2635
- variant: "outlined",
2636
- color: "primary",
2637
- onClick: () => {
2638
- const rule = toSecurityRule(dp);
2639
- setFieldValue("securityRules", [...rules, rule]);
2640
- },
2641
- children: "Import to codebase"
2631
+ children: /* @__PURE__ */ jsx(Tooltip, {
2632
+ title: readOnly ? readOnlyTitle : void 0,
2633
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, {
2634
+ size: "small",
2635
+ variant: "outlined",
2636
+ color: "primary",
2637
+ disabled: readOnly,
2638
+ onClick: () => {
2639
+ const rule = toSecurityRule(dp);
2640
+ setFieldValue("securityRules", [...rules, rule]);
2641
+ },
2642
+ children: "Import to codebase"
2643
+ }) })
2642
2644
  })
2643
2645
  })]
2644
2646
  }, dp.policyname))
@@ -2684,7 +2686,7 @@ function InlinePolicyEditor({ policy, table, availableRoles, rolesUnavailable, o
2684
2686
  * from what users hold, so a role that is referenced here but assigned to
2685
2687
  * nobody would otherwise vanish from its own policy on the next save.
2686
2688
  */
2687
- const roleOptions = useMemo(() => Array.from(new Set([...availableRoles, ...roles])).sort(), [availableRoles, roles]);
2689
+ const roleOptions = useMemo(() => Array.from(/* @__PURE__ */ new Set([...availableRoles, ...roles])).sort(), [availableRoles, roles]);
2688
2690
  const addCustomRole = () => {
2689
2691
  const trimmed = customRole.trim();
2690
2692
  if (!trimmed || roles.includes(trimmed)) {
@@ -2964,10 +2966,12 @@ function CollectionEditor(props) {
2964
2966
  }, [collection, fallbackSlug]);
2965
2967
  const initialValues = React$1.useMemo(() => {
2966
2968
  return initialCollection ? applyPropertyConfigs(initialCollection, propertyConfigs) : copyFromProp ? (() => {
2967
- const { subcollections: _sub, ...rest } = copyFromProp;
2969
+ const { subcollections: _sub, schema: _schema, auth: _auth, ...rest } = copyFromProp;
2968
2970
  return {
2969
2971
  ...rest,
2970
2972
  name: "",
2973
+ slug: fallbackSlug,
2974
+ table: "",
2971
2975
  ownerId: authController.user?.uid ?? ""
2972
2976
  };
2973
2977
  })() : {
@@ -3002,6 +3006,8 @@ function CollectionEditor(props) {
3002
3006
  });
3003
3007
  }
3004
3008
  function CollectionEditorInternal({ isNewCollection, configController, editedCollectionId, parentCollectionSlugs, parentEntityIds, path, collectionInference, handleClose, extraView, handleCancel, setFormDirty, getUser, parentCollection, getData, existingPaths, existingIds, includeTemplates, collection, setCollection, initialValues, propertyConfigs, existingEntities, initialView: initialViewProp, expandKanban, generateCollection, onAnalyticsEvent, fullScreen, unmappedTables, onFetchTableMetadata, propertyTypePresets, hiddenPropertyTypes, renderExtraPropertyFields, renderExtraCollectionFields, visibleTabs, standalone }) {
3009
+ /** Why the submit buttons below are dead, straight from the backend. */
3010
+ const readOnlyTitle = configController?.readOnlyReason || "This backend does not accept collection edits.";
3005
3011
  const importConfigRaw = useImportConfig();
3006
3012
  const urlControllerRaw = useUrlController();
3007
3013
  const collectionRegistryRaw = useCollectionRegistryController();
@@ -3285,14 +3291,17 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3285
3291
  onAnalyticsEvent
3286
3292
  }), fullScreen && !isNewCollection && /* @__PURE__ */ jsx("div", {
3287
3293
  className: "flex items-center gap-2",
3288
- children: /* @__PURE__ */ jsx(LoadingButton, {
3289
- variant: "filled",
3290
- color: "primary",
3291
- type: "submit",
3292
- onClick: () => formController.handleSubmit(),
3293
- disabled: !dirty || isSubmitting || configController?.readOnly,
3294
- loading: isSubmitting,
3295
- children: configController?.readOnly ? "Update (Read-only)" : "Update"
3294
+ children: /* @__PURE__ */ jsx(Tooltip, {
3295
+ title: configController?.readOnly ? readOnlyTitle : void 0,
3296
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(LoadingButton, {
3297
+ variant: "filled",
3298
+ color: "primary",
3299
+ type: "submit",
3300
+ onClick: () => formController.handleSubmit(),
3301
+ disabled: !dirty || isSubmitting || configController?.readOnly,
3302
+ loading: isSubmitting,
3303
+ children: configController?.readOnly ? "Update (Read-only)" : "Update"
3304
+ }) })
3296
3305
  })
3297
3306
  })]
3298
3307
  })]
@@ -3371,10 +3380,11 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3371
3380
  showErrors: submitCount > 0,
3372
3381
  isNewCollection,
3373
3382
  onPropertyError: (propertyKey, namespace, error) => {
3374
- propertyErrorsRef.current = removeUndefined({
3383
+ const current = removeUndefined({
3375
3384
  ...propertyErrorsRef.current,
3376
3385
  [getFullIdPath(propertyKey, namespace)]: removeUndefined(error, true)
3377
3386
  }, true);
3387
+ propertyErrorsRef.current = current;
3378
3388
  formController.validate();
3379
3389
  },
3380
3390
  getUser,
@@ -3462,13 +3472,16 @@ function CollectionEditorInternal({ isNewCollection, configController, editedCol
3462
3472
  startIcon: currentView === "properties" ? /* @__PURE__ */ jsx(CheckIcon, {}) : void 0,
3463
3473
  children: [currentView === "general" && "Next", currentView === "properties" && "Create collection"]
3464
3474
  }),
3465
- !isNewCollection && !fullScreen && /* @__PURE__ */ jsx(LoadingButton, {
3466
- variant: "filled",
3467
- color: "primary",
3468
- type: "submit",
3469
- disabled: isSubmitting || configController?.readOnly,
3470
- loading: isSubmitting,
3471
- children: configController?.readOnly ? "Update collection (Read-only)" : "Update collection"
3475
+ !isNewCollection && !fullScreen && /* @__PURE__ */ jsx(Tooltip, {
3476
+ title: configController?.readOnly ? readOnlyTitle : void 0,
3477
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(LoadingButton, {
3478
+ variant: "filled",
3479
+ color: "primary",
3480
+ type: "submit",
3481
+ disabled: isSubmitting || configController?.readOnly,
3482
+ loading: isSubmitting,
3483
+ children: configController?.readOnly ? "Update collection (Read-only)" : "Update collection"
3484
+ }) })
3472
3485
  })
3473
3486
  ]
3474
3487
  })]
@@ -3537,4 +3550,4 @@ var validateId = (value, isNewCollection, existingPaths, existingIds) => {
3537
3550
  //#endregion
3538
3551
  export { CollectionEditorDialog as n, CollectionEditorDialog_exports as r, CollectionEditor as t };
3539
3552
 
3540
- //# sourceMappingURL=CollectionEditorDialog-Dpc75wIZ.js.map
3553
+ //# sourceMappingURL=CollectionEditorDialog-B-iVE9y3.js.map