@rebasepro/admin 0.9.0 → 0.9.1-canary.0de22e0
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.
- package/README.md +7 -7
- package/dist/{CollectionEditorDialog-B-7uW3iJ.js → CollectionEditorDialog-D7odTn0N.js} +150 -36
- package/dist/CollectionEditorDialog-D7odTn0N.js.map +1 -0
- package/dist/{PropertyEditView-7KMTcrqi.js → PropertyEditView-i51tFOfM.js} +6 -6
- package/dist/PropertyEditView-i51tFOfM.js.map +1 -0
- package/dist/{RouterCollectionsStudioView-epqIbZrJ.js → RouterCollectionsStudioView-B9AjTCjT.js} +5 -5
- package/dist/RouterCollectionsStudioView-B9AjTCjT.js.map +1 -0
- package/dist/collection_editor/api/generateCollectionApi.d.ts +4 -4
- package/dist/collection_editor/ui/collection_editor/PropertyEditView.d.ts +1 -1
- package/dist/collection_editor/ui/collection_editor/SwitchControl.d.ts +1 -1
- package/dist/collection_editor/useSafeSnackbarController.d.ts +1 -1
- package/dist/collection_editor_ui.js +5 -5
- package/dist/collection_editor_ui.js.map +1 -1
- package/dist/components/CollectionTableBinding/CollectionTableBindingProps.d.ts +1 -1
- package/dist/components/CollectionTableBinding/internal/EntityTableCell.d.ts +1 -1
- package/dist/components/CollectionTableBinding/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/CollectionTableBinding/table_bindings.d.ts +1 -1
- package/dist/components/CollectionViewBinding/hooks/useCollectionInlineEditor.d.ts +1 -1
- package/dist/components/{RebaseCMS.d.ts → RebaseAdmin.d.ts} +2 -2
- package/dist/components/RebaseLayout.d.ts +5 -4
- package/dist/components/RebaseShell.d.ts +1 -0
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTableContext.d.ts +1 -1
- package/dist/components/SidePanelProvider.d.ts +1 -1
- package/dist/components/field_configs.d.ts +17 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/contexts/BreacrumbsContext.d.ts +1 -1
- package/dist/editor.js +1 -1
- package/dist/editor.js.map +1 -1
- package/dist/export-BM6HPujv.js +518 -0
- package/dist/export-BM6HPujv.js.map +1 -0
- package/dist/form/components/LocalChangesMenu.d.ts +1 -1
- package/dist/form/components/StorageUploadProgress.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/{history-7X5bON_n.js → history-CtIPJxvQ.js} +6 -6
- package/dist/history-CtIPJxvQ.js.map +1 -0
- package/dist/hooks/useSelectionDialog.d.ts +1 -1
- package/dist/import-DzQnT03v.js +328 -0
- package/dist/import-DzQnT03v.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3300 -2
- package/dist/index.js.map +1 -0
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/preview/util.d.ts +1 -0
- package/dist/types/components/formex.d.ts +1 -1
- package/dist/util/view_mode.d.ts +54 -0
- package/dist/{src-sUZfe29F.js → util-XFwQ9FEc.js} +17554 -21391
- package/dist/util-XFwQ9FEc.js.map +1 -0
- package/package.json +12 -17
- package/src/collection_editor/ConfigControllerProvider.tsx +1 -1
- package/src/collection_editor/api/generateCollectionApi.ts +4 -4
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +1 -1
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +1 -1
- package/src/collection_editor/ui/EditorCollectionAction.tsx +1 -1
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +1 -1
- package/src/collection_editor/ui/EditorEntityAction.tsx +1 -1
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +1 -1
- package/src/collection_editor/ui/KanbanSetupAction.tsx +1 -1
- package/src/collection_editor/ui/MissingReferenceWidget.tsx +1 -1
- package/src/collection_editor/ui/NewCollectionButton.tsx +1 -1
- package/src/collection_editor/ui/NewCollectionCard.tsx +1 -1
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +139 -13
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/EntityActionsSelectDialog.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/SwitchControl.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/BooleanPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +1 -1
- package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +2 -2
- package/src/collection_editor/useSafeSnackbarController.ts +1 -1
- package/src/components/AdminModeSyncer.tsx +1 -1
- package/src/components/ArrayContainer.tsx +1 -1
- package/src/components/ClearFilterSortButton.tsx +1 -1
- package/src/components/CollectionPanel.tsx +1 -1
- package/src/components/CollectionTableBinding/CollectionRowActions.tsx +3 -3
- package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +3 -3
- package/src/components/CollectionTableBinding/CollectionTableBindingProps.tsx +1 -1
- package/src/components/CollectionTableBinding/PropertyTableCell.tsx +1 -1
- package/src/components/CollectionTableBinding/column_utils.tsx +1 -1
- package/src/components/CollectionTableBinding/fields/TableMultipleRelationField.tsx +2 -2
- package/src/components/CollectionTableBinding/fields/TableReferenceField.tsx +2 -2
- package/src/components/CollectionTableBinding/fields/TableRelationField.tsx +2 -2
- package/src/components/CollectionTableBinding/fields/TableStorageUpload.tsx +1 -1
- package/src/components/CollectionTableBinding/internal/CollectionTableToolbar.tsx +1 -1
- package/src/components/CollectionTableBinding/internal/EntityTableCell.tsx +2 -2
- package/src/components/CollectionTableBinding/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx +4 -4
- package/src/components/CollectionTableBinding/table_bindings.tsx +1 -1
- package/src/components/CollectionViewBinding/BoardCardBinding.tsx +2 -2
- package/src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx +4 -4
- package/src/components/CollectionViewBinding/CollectionCardViewBinding.tsx +1 -1
- package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +3 -3
- package/src/components/CollectionViewBinding/CollectionViewActions.tsx +3 -3
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +77 -127
- package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +5 -9
- package/src/components/CollectionViewBinding/EntityCardBinding.tsx +3 -3
- package/src/components/CollectionViewBinding/FiltersDialog.tsx +19 -1
- package/src/components/CollectionViewBinding/SplitListView.tsx +114 -63
- package/src/components/CollectionViewBinding/ViewModeToggle.tsx +1 -1
- package/src/components/CollectionViewBinding/hooks/useCollectionInlineEditor.ts +2 -2
- package/src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts +2 -2
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +9 -3
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +1 -1
- package/src/components/DefaultAppBar.tsx +3 -3
- package/src/components/DefaultDrawer.tsx +3 -3
- package/src/components/DeleteEntityDialog.tsx +1 -1
- package/src/components/DetailViewBinding.tsx +7 -5
- package/src/components/DrawerNavigationGroup.tsx +2 -2
- package/src/components/EditFormActions.tsx +6 -6
- package/src/components/EditViewBinding.tsx +9 -8
- package/src/components/EntityPreviewBinding.tsx +5 -4
- package/src/components/EntityViewBinding.tsx +2 -2
- package/src/components/HomePage/ContentHomePage.tsx +6 -5
- package/src/components/HomePage/FavouritesView.tsx +2 -2
- package/src/components/HomePage/NavigationCardBinding.tsx +3 -3
- package/src/components/HomePage/NavigationGroup.tsx +1 -1
- package/src/components/HomePage/RenameGroupDialog.tsx +1 -1
- package/src/components/JsonPreviewBinding.tsx +1 -1
- package/src/components/{RebaseCMS.tsx → RebaseAdmin.tsx} +3 -3
- package/src/components/RebaseAuthGate.tsx +2 -2
- package/src/components/RebaseLayout.tsx +7 -13
- package/src/components/RebaseNavigation.tsx +18 -3
- package/src/components/RebaseRouteDefs.tsx +3 -3
- package/src/components/RebaseShell.tsx +2 -1
- package/src/components/ReferenceTable/SelectionTableBinding.tsx +7 -6
- package/src/components/ReferenceWidget.tsx +1 -1
- package/src/components/RelationSelector.tsx +1 -1
- package/src/components/SearchIconsView.tsx +2 -2
- package/src/components/SelectableTable/SelectableTable.tsx +2 -2
- package/src/components/SelectableTable/SelectableTableContext.tsx +1 -1
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +1 -1
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
- package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +1 -1
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +1 -1
- package/src/components/SideDialogs.tsx +1 -1
- package/src/components/SidePanelBinding.tsx +47 -9
- package/src/components/SidePanelProvider.tsx +15 -12
- package/src/components/UserSelector.tsx +1 -1
- package/src/components/admin/CreationResultDialog.tsx +6 -3
- package/src/components/app/Scaffold.tsx +6 -2
- package/src/components/common/default_entity_actions.tsx +123 -25
- package/src/components/field_configs.tsx +42 -25
- package/src/components/history/EntityHistoryEntry.tsx +1 -1
- package/src/components/history/EntityHistoryView.tsx +5 -5
- package/src/components/history/LastEditedByIndicator.tsx +2 -2
- package/src/components/index.ts +1 -1
- package/src/contexts/BreacrumbsContext.tsx +1 -1
- package/src/data_export/export/BasicExportAction.tsx +1 -1
- package/src/data_export/export/ExportCollectionAction.tsx +1 -1
- package/src/data_import/components/DataNewPropertiesMapping.tsx +1 -1
- package/src/data_import/components/ImportFileUpload.tsx +1 -1
- package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +3 -5
- package/src/data_import/components/ImportSaveInProgress.tsx +1 -1
- package/src/data_import/import/ImportCollectionAction.tsx +8 -8
- package/src/data_import/utils/data.ts +2 -2
- package/src/data_import/utils/get_properties_mapping.ts +1 -1
- package/src/editor/components/image-bubble.tsx +1 -1
- package/src/editor/components/table-bubble.tsx +1 -1
- package/src/editor/editor.tsx +1 -1
- package/src/editor/selectors/color-selector.tsx +1 -1
- package/src/editor/selectors/link-selector.tsx +1 -1
- package/src/editor/selectors/node-selector.tsx +2 -2
- package/src/editor/selectors/text-buttons.tsx +1 -1
- package/src/form/EntityForm.tsx +8 -5
- package/src/form/EntityFormActions.tsx +1 -1
- package/src/form/EntityFormBinding.tsx +7 -5
- package/src/form/PropertyFieldBinding.tsx +3 -3
- package/src/form/components/ErrorFocus.tsx +1 -1
- package/src/form/components/LocalChangesMenu.tsx +3 -3
- package/src/form/components/StorageItemPreview.tsx +1 -1
- package/src/form/components/StorageUploadProgress.tsx +3 -3
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -2
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -3
- package/src/form/field_bindings/BlockFieldBinding.tsx +4 -3
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +3 -2
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +4 -3
- package/src/form/field_bindings/MapFieldBinding.tsx +3 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +4 -3
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +2 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +3 -2
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -4
- package/src/form/field_bindings/RelationFieldBinding.tsx +3 -2
- package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -2
- package/src/form/field_bindings/SelectFieldBinding.tsx +2 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +5 -4
- package/src/form/field_bindings/SwitchFieldBinding.tsx +2 -1
- package/src/form/field_bindings/TextFieldBinding.tsx +2 -1
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +2 -1
- package/src/form/field_bindings/VectorFieldBinding.tsx +2 -1
- package/src/form/form_utils.ts +1 -1
- package/src/hooks/navigation/useNavigationResolution.ts +19 -4
- package/src/hooks/useBuildSidePanel.tsx +10 -2
- package/src/hooks/useCMSContext.tsx +1 -1
- package/src/hooks/useHistory.ts +1 -1
- package/src/hooks/useResolvedNavigationFrom.tsx +4 -2
- package/src/hooks/useSelectionDialog.tsx +3 -3
- package/src/index.ts +3 -3
- package/src/preview/PropertyPreview.tsx +2 -2
- package/src/preview/components/DatePreview.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +2 -2
- package/src/preview/components/ReferencePreview.tsx +3 -3
- package/src/preview/components/RelationPreview.tsx +3 -3
- package/src/preview/components/StorageThumbnail.tsx +1 -1
- package/src/preview/components/UrlComponentPreview.tsx +2 -9
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/NumberPropertyPreview.tsx +1 -1
- package/src/preview/util.ts +9 -0
- package/src/routes/CustomViewRoute.tsx +2 -1
- package/src/routes/RebaseRoute.tsx +21 -26
- package/src/types/components/formex.tsx +1 -1
- package/src/util/navigation_utils.ts +2 -5
- package/src/util/previews.ts +4 -2
- package/src/util/view_mode.ts +102 -0
- package/dist/CollectionEditorDialog-B-7uW3iJ.js.map +0 -1
- package/dist/PropertyEditView-7KMTcrqi.js.map +0 -1
- package/dist/RouterCollectionsStudioView-epqIbZrJ.js.map +0 -1
- package/dist/history-7X5bON_n.js.map +0 -1
- package/dist/src-sUZfe29F.js.map +0 -1
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
defaultBorderMixin,
|
|
9
9
|
ResizablePanels
|
|
10
10
|
} from "@rebasepro/ui";
|
|
11
|
-
import { useLargeLayout } from "@rebasepro/
|
|
12
|
-
import { useCollectionRegistryController } from "../../
|
|
11
|
+
import { useLargeLayout, UnsavedChangesDialog, useNavigationBlocker } from "@rebasepro/app";
|
|
12
|
+
import { useCollectionRegistryController } from "../../hooks/navigation/contexts/CollectionRegistryContext";
|
|
13
13
|
import { useNavigate, useLocation } from "react-router-dom";
|
|
14
|
-
import { useUrlController } from "../../
|
|
14
|
+
import { useUrlController } from "../../hooks/navigation/contexts/UrlContext";
|
|
15
15
|
import { ErrorBoundary } from "@rebasepro/ui";
|
|
16
|
+
import { withViewMode } from "../../util/view_mode";
|
|
16
17
|
|
|
17
18
|
export type SplitListViewProps<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
18
19
|
collection: CollectionConfig<M>;
|
|
@@ -55,6 +56,27 @@ export type SplitListViewProps<M extends Record<string, unknown> = Record<string
|
|
|
55
56
|
|
|
56
57
|
const PANEL_SIZE_KEY = "rebase_split_list_panel_size";
|
|
57
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Whether the element accepts text, and therefore owns the keystroke.
|
|
61
|
+
* Covers native fields plus the ARIA roles custom editors expose.
|
|
62
|
+
*/
|
|
63
|
+
function isTextEntryTarget(target: HTMLElement | null): boolean {
|
|
64
|
+
if (!target) return false;
|
|
65
|
+
const tag = target.tagName;
|
|
66
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
67
|
+
if (target.isContentEditable) return true;
|
|
68
|
+
return Boolean(target.closest('[contenteditable="true"], [role="textbox"], [role="combobox"], [role="searchbox"]'));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether a bare letter shortcut may act on this target. Only the list side of
|
|
73
|
+
* the split owns them — inside the detail panel a keystroke belongs to the form.
|
|
74
|
+
*/
|
|
75
|
+
function isListShortcutTarget(target: HTMLElement | null, detailPanel: HTMLElement | null): boolean {
|
|
76
|
+
if (!target || target === document.body) return true;
|
|
77
|
+
return !detailPanel?.contains(target);
|
|
78
|
+
}
|
|
79
|
+
|
|
58
80
|
function getSavedPanelSize(path: string): number {
|
|
59
81
|
try {
|
|
60
82
|
const saved = localStorage.getItem(`${PANEL_SIZE_KEY}_${path}`);
|
|
@@ -115,6 +137,37 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
115
137
|
|
|
116
138
|
const showDetail = selectedEntityId !== undefined;
|
|
117
139
|
|
|
140
|
+
// ── Unsaved changes ──
|
|
141
|
+
// The detail form lives inside the split layout, so every way out of it
|
|
142
|
+
// (Escape, j/k, clicking another row, the browser back button) is a plain
|
|
143
|
+
// router navigation. A ref — not state — because the blocker predicate must
|
|
144
|
+
// observe the change synchronously, before the navigation it is guarding.
|
|
145
|
+
const dirty = useRef(false);
|
|
146
|
+
const detailPanelRef = useRef<HTMLDivElement>(null);
|
|
147
|
+
const setDirty = useCallback((modified: boolean) => {
|
|
148
|
+
dirty.current = modified;
|
|
149
|
+
}, []);
|
|
150
|
+
|
|
151
|
+
// The form remounts per entity, so its dirty state must not leak into the next one.
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
dirty.current = false;
|
|
154
|
+
}, [selectedEntityId]);
|
|
155
|
+
|
|
156
|
+
const blocker = useNavigationBlocker(useCallback(({
|
|
157
|
+
currentLocation,
|
|
158
|
+
nextLocation
|
|
159
|
+
}) => {
|
|
160
|
+
if (!dirty.current) return false;
|
|
161
|
+
if (currentLocation.pathname === nextLocation.pathname) return false;
|
|
162
|
+
// Side panel overlays (e.g. following a relation) render above the form
|
|
163
|
+
// and leave it mounted — nothing is lost in either direction.
|
|
164
|
+
const nextHash = nextLocation.hash;
|
|
165
|
+
if (nextHash === "#side" || nextHash === "#new_side") return false;
|
|
166
|
+
const currentHash = currentLocation.hash;
|
|
167
|
+
if (currentHash === "#side" || currentHash === "#new_side") return false;
|
|
168
|
+
return true;
|
|
169
|
+
}, []));
|
|
170
|
+
|
|
118
171
|
// Panel size state with persistence
|
|
119
172
|
const [panelSize, setPanelSize] = useState(() => getSavedPanelSize(path));
|
|
120
173
|
|
|
@@ -170,16 +223,15 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
170
223
|
};
|
|
171
224
|
}, [selectedEntityId]); // Intentionally only depend on selectedEntityId
|
|
172
225
|
|
|
226
|
+
// Build a URL below this collection, preserving the active view mode.
|
|
227
|
+
const buildUrl = useCallback((subPath: string) => {
|
|
228
|
+
return withViewMode(urlController.buildUrlCollectionPath(subPath));
|
|
229
|
+
}, [urlController]);
|
|
230
|
+
|
|
173
231
|
// Close the detail panel: navigate back to the collection path
|
|
174
232
|
const handleCloseDetail = useCallback(() => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const currentViewParam = new URLSearchParams(window.location.search).get("__view");
|
|
178
|
-
if (currentViewParam) {
|
|
179
|
-
collectionUrl += `${collectionUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
180
|
-
}
|
|
181
|
-
navigate(collectionUrl);
|
|
182
|
-
}, [navigate, urlController, path]);
|
|
233
|
+
navigate(buildUrl(path));
|
|
234
|
+
}, [navigate, buildUrl, path]);
|
|
183
235
|
|
|
184
236
|
// ── Keyboard navigation ──
|
|
185
237
|
const entityIds = useMemo(
|
|
@@ -189,23 +241,33 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
189
241
|
|
|
190
242
|
useEffect(() => {
|
|
191
243
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
244
|
+
const target = e.target as HTMLElement | null;
|
|
245
|
+
|
|
246
|
+
// Radix overlays own the keyboard while they are open — including Escape.
|
|
247
|
+
if (document.querySelector('[role="dialog"][data-state="open"]')) return;
|
|
248
|
+
|
|
249
|
+
if (e.key === "Escape") {
|
|
250
|
+
if (!selectedEntityId) return;
|
|
251
|
+
// First Escape leaves the field (which may also be dismissing its
|
|
252
|
+
// own dropdown), a second one closes the panel. Closing straight
|
|
253
|
+
// from a focused field would discard an in-progress edit.
|
|
254
|
+
if (isTextEntryTarget(target)) {
|
|
255
|
+
target?.blur();
|
|
198
256
|
e.preventDefault();
|
|
257
|
+
return;
|
|
199
258
|
}
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (e.key === "Escape" && selectedEntityId) {
|
|
204
259
|
handleCloseDetail();
|
|
205
260
|
e.preventDefault();
|
|
206
261
|
return;
|
|
207
262
|
}
|
|
208
263
|
|
|
264
|
+
// Record navigation only belongs to the list side. Inside the detail
|
|
265
|
+
// panel these keys are the form's — arrows move between fields, and a
|
|
266
|
+
// bare letter is input for widgets that aren't native fields (rich
|
|
267
|
+
// text, code editors, comboboxes).
|
|
268
|
+
if (!isListShortcutTarget(target, detailPanelRef.current)) return;
|
|
269
|
+
if (isTextEntryTarget(target)) return;
|
|
270
|
+
|
|
209
271
|
// Arrow down / j → next entity
|
|
210
272
|
if ((e.key === "ArrowDown" || e.key === "j") && !e.metaKey && !e.ctrlKey) {
|
|
211
273
|
e.preventDefault();
|
|
@@ -282,6 +344,7 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
282
344
|
|
|
283
345
|
const detailPanel = renderedEntityId !== undefined ? (
|
|
284
346
|
<div
|
|
347
|
+
ref={detailPanelRef}
|
|
285
348
|
className={cls(
|
|
286
349
|
"flex-1 flex flex-col min-w-0 h-full transition-all ease-out w-full",
|
|
287
350
|
animationPhase === "entered"
|
|
@@ -302,25 +365,15 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
302
365
|
selectedTab={selectedTab}
|
|
303
366
|
layout="split"
|
|
304
367
|
onEditClick={() => {
|
|
305
|
-
|
|
306
|
-
const currentViewParam = new URLSearchParams(window.location.search).get("__view");
|
|
307
|
-
if (currentViewParam) {
|
|
308
|
-
entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
309
|
-
}
|
|
310
|
-
navigate(entityUrl);
|
|
368
|
+
navigate(buildUrl(`${path}/${renderedEntityId}/edit`));
|
|
311
369
|
}}
|
|
312
370
|
onTabChange={(params) => {
|
|
313
371
|
const newSelectedTab = params.selectedTab;
|
|
314
|
-
|
|
372
|
+
navigate(buildUrl(
|
|
315
373
|
newSelectedTab
|
|
316
374
|
? `${path}/${renderedEntityId}/${newSelectedTab}`
|
|
317
375
|
: `${path}/${renderedEntityId}`
|
|
318
|
-
);
|
|
319
|
-
const currentViewParam = new URLSearchParams(window.location.search).get("__view");
|
|
320
|
-
if (currentViewParam) {
|
|
321
|
-
entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
322
|
-
}
|
|
323
|
-
navigate(entityUrl);
|
|
376
|
+
));
|
|
324
377
|
}}
|
|
325
378
|
/>
|
|
326
379
|
: <EditViewBinding
|
|
@@ -332,34 +385,21 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
332
385
|
parentEntityIds={usedParentEntityIds}
|
|
333
386
|
selectedTab={selectedTab}
|
|
334
387
|
layout="split"
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
340
|
-
}
|
|
341
|
-
navigate(entityUrl, { replace: true });
|
|
388
|
+
onValuesModified={setDirty}
|
|
389
|
+
onSaved={() => {
|
|
390
|
+
setDirty(false);
|
|
391
|
+
navigate(buildUrl(`${path}/${renderedEntityId}`), { replace: true });
|
|
342
392
|
}}
|
|
343
393
|
navigateBack={() => {
|
|
344
|
-
|
|
345
|
-
const currentViewParam = new URLSearchParams(window.location.search).get("__view");
|
|
346
|
-
if (currentViewParam) {
|
|
347
|
-
entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
348
|
-
}
|
|
349
|
-
navigate(entityUrl);
|
|
394
|
+
navigate(buildUrl(`${path}/${renderedEntityId}`));
|
|
350
395
|
}}
|
|
351
396
|
onTabChange={(params) => {
|
|
352
397
|
const newSelectedTab = params.selectedTab;
|
|
353
|
-
|
|
398
|
+
navigate(buildUrl(
|
|
354
399
|
newSelectedTab
|
|
355
400
|
? `${path}/${renderedEntityId}/${newSelectedTab}`
|
|
356
401
|
: `${path}/${renderedEntityId}`
|
|
357
|
-
);
|
|
358
|
-
const currentViewParam = new URLSearchParams(window.location.search).get("__view");
|
|
359
|
-
if (currentViewParam) {
|
|
360
|
-
entityUrl += `${entityUrl.includes("?") ? "&" : "?"}__view=${currentViewParam}`;
|
|
361
|
-
}
|
|
362
|
-
navigate(entityUrl);
|
|
402
|
+
));
|
|
363
403
|
}}
|
|
364
404
|
/>
|
|
365
405
|
}
|
|
@@ -368,14 +408,25 @@ export function SplitListView<M extends Record<string, unknown> = Record<string,
|
|
|
368
408
|
) : <></>;
|
|
369
409
|
|
|
370
410
|
return (
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
411
|
+
<>
|
|
412
|
+
<ResizablePanels
|
|
413
|
+
stacked={!largeLayout}
|
|
414
|
+
firstPanel={listPanel}
|
|
415
|
+
secondPanel={detailPanel}
|
|
416
|
+
showSecondPanel={isDetailVisible}
|
|
417
|
+
panelSizePercent={animationPhase === "entering" ? 100 : panelSize}
|
|
418
|
+
onPanelSizeChange={setPanelSize}
|
|
419
|
+
minPanelSizePx={240}
|
|
420
|
+
/>
|
|
421
|
+
|
|
422
|
+
<UnsavedChangesDialog
|
|
423
|
+
open={blocker?.state === "blocked"}
|
|
424
|
+
handleOk={() => {
|
|
425
|
+
dirty.current = false;
|
|
426
|
+
blocker?.proceed?.();
|
|
427
|
+
}}
|
|
428
|
+
handleCancel={() => blocker?.reset?.()}
|
|
429
|
+
body={<>You have unsaved changes in this <b>{collection.singularName ?? collection.name}</b>.</>}/>
|
|
430
|
+
</>
|
|
380
431
|
);
|
|
381
432
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useMemo } from "react";
|
|
2
|
-
import { setIn } from "@rebasepro/
|
|
2
|
+
import { setIn } from "@rebasepro/forms";
|
|
3
3
|
import { CollectionConfig, RebaseData, RebaseContext } from "@rebasepro/types";
|
|
4
|
-
import { OnCellValueChange, saveEntityWithCallbacks, SaveEntityWithCallbacksProps, UniqueFieldValidator } from "@rebasepro/
|
|
4
|
+
import { OnCellValueChange, saveEntityWithCallbacks, SaveEntityWithCallbacksProps, UniqueFieldValidator } from "@rebasepro/app";
|
|
5
5
|
|
|
6
6
|
export interface UseCollectionInlineEditorParams<M extends Record<string, unknown>> {
|
|
7
7
|
path: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useMemo } from "react";
|
|
2
|
-
import { setIn } from "@rebasepro/
|
|
2
|
+
import { setIn } from "@rebasepro/forms";
|
|
3
3
|
import { CollectionConfig, RebaseData, RebaseContext, AnalyticsController, Entity } from "@rebasepro/types";
|
|
4
|
-
import { saveEntityWithCallbacks, SaveEntityWithCallbacksProps } from "@rebasepro/
|
|
4
|
+
import { saveEntityWithCallbacks, SaveEntityWithCallbacksProps } from "@rebasepro/app";
|
|
5
5
|
import { BoardItem } from "@rebasepro/ui";
|
|
6
6
|
import { BoardDataController } from "../useBoardDataController";
|
|
7
7
|
import { generateKeyBetween } from "fractional-indexing";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CollectionConfig } from "@rebasepro/types";
|
|
2
2
|
import { Entity, FilterValues } from "@rebasepro/types";
|
|
3
3
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { useData, useRebaseContext } from "@rebasepro/
|
|
4
|
+
import { getRelationIncludeParams, useData, useRebaseContext } from "@rebasepro/app";
|
|
5
5
|
|
|
6
6
|
const DEFAULT_PAGE_SIZE = 20;
|
|
7
7
|
|
|
@@ -410,18 +410,24 @@ values: { ...e.values,
|
|
|
410
410
|
|
|
411
411
|
// Set up listener or fetch
|
|
412
412
|
const accessor = currentDataClient.collection(currentResolvedPath);
|
|
413
|
+
|
|
414
|
+
// Eagerly include relations to avoid N+1 fetches.
|
|
415
|
+
const includeParams = getRelationIncludeParams(currentCollection);
|
|
416
|
+
|
|
413
417
|
if (accessor.listen) {
|
|
414
418
|
const unsubscribe = accessor.listen({
|
|
415
419
|
where: whereFilter,
|
|
416
420
|
limit: itemCount,
|
|
417
|
-
orderBy: orderByParam
|
|
421
|
+
orderBy: orderByParam,
|
|
422
|
+
include: includeParams
|
|
418
423
|
}, res => onUpdate(res.data as Entity<M>[]), onError);
|
|
419
424
|
unsubscribersRef.current[column] = unsubscribe;
|
|
420
425
|
} else {
|
|
421
426
|
accessor.find({
|
|
422
427
|
where: whereFilter,
|
|
423
428
|
limit: itemCount,
|
|
424
|
-
orderBy: orderByParam
|
|
429
|
+
orderBy: orderByParam,
|
|
430
|
+
include: includeParams
|
|
425
431
|
})
|
|
426
432
|
.then(res => onUpdate(res.data as Entity<M>[]))
|
|
427
433
|
.catch(onError);
|
|
@@ -2,7 +2,7 @@ import { useMemo } from "react";
|
|
|
2
2
|
import type { CollectionConfig, Property, RelationProperty } from "@rebasepro/types";
|
|
3
3
|
import type { Entity, PropertyConfig, EntityRelation } from "@rebasepro/types";
|
|
4
4
|
import { getEntityImagePreviewPropertyKey } from "@rebasepro/common";
|
|
5
|
-
import { getEntityFromCache } from "@rebasepro/
|
|
5
|
+
import { getEntityFromCache } from "@rebasepro/app";
|
|
6
6
|
import { getEntityTitlePropertyKey, getEntityPreviewKeys } from "../../util/previews";
|
|
7
7
|
import { getValueInPath } from "@rebasepro/utils";
|
|
8
8
|
import type { AuthController } from "@rebasepro/types";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
4
|
import { Link, useNavigate } from "react-router-dom";
|
|
5
|
-
import { RebaseLogo, LanguageToggle } from "@rebasepro/
|
|
5
|
+
import { RebaseLogo, LanguageToggle } from "@rebasepro/app";
|
|
6
6
|
import { ErrorBoundary, iconSize } from "@rebasepro/ui";
|
|
7
7
|
import {
|
|
8
8
|
Avatar,
|
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
SunMoonIcon,
|
|
19
19
|
Typography
|
|
20
20
|
} from "@rebasepro/ui";
|
|
21
|
-
import { useAuthController, useLargeLayout, useModeController, useAdminModeController, useTranslation } from "@rebasepro/
|
|
21
|
+
import { useAuthController, useLargeLayout, useModeController, useAdminModeController, useTranslation } from "@rebasepro/app";
|
|
22
22
|
import { useUrlController } from "../hooks/navigation/contexts/UrlContext";
|
|
23
23
|
import { User } from "@rebasepro/types";
|
|
24
24
|
import { useApp } from "./app/useApp";
|
|
25
25
|
import { useBreadcrumbsController } from "../hooks/useBreadcrumbsController";
|
|
26
|
-
import { UserSettingsView } from "@rebasepro/
|
|
26
|
+
import { UserSettingsView } from "@rebasepro/app";
|
|
27
27
|
|
|
28
28
|
export type DefaultAppBarProps<ADDITIONAL_PROPS = object> = {
|
|
29
29
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NavigationEntry, NavigationResult } from "@rebasepro/types";
|
|
2
2
|
import React, { useMemo } from "react";
|
|
3
3
|
|
|
4
|
-
import { useCollapsedGroups, buildCollapsedDefaults, useLargeLayout, useAdminModeController, useAuthController, useModeController, useTranslation, useSlot, useRebaseContext, useAnalyticsController, useRebaseRegistry, useComponentOverride } from "@rebasepro/
|
|
4
|
+
import { useCollapsedGroups, buildCollapsedDefaults, useLargeLayout, useAdminModeController, useAuthController, useModeController, useTranslation, useSlot, useRebaseContext, useAnalyticsController, useRebaseRegistry, useComponentOverride } from "@rebasepro/app";
|
|
5
5
|
import { useUrlController } from "../hooks/navigation/contexts/UrlContext";
|
|
6
6
|
import { useNavigationStateController } from "../hooks/navigation/contexts/NavigationStateContext";
|
|
7
7
|
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
Typography
|
|
30
30
|
} from "@rebasepro/ui";
|
|
31
31
|
import { DrawerNavigationGroup } from "./DrawerNavigationGroup";
|
|
32
|
-
import { LanguageToggle, RebaseLogo } from "@rebasepro/
|
|
32
|
+
import { LanguageToggle, RebaseLogo } from "@rebasepro/app";
|
|
33
33
|
import { useApp } from "./app/useApp";
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -166,7 +166,7 @@ function CMSNavigationContent() {
|
|
|
166
166
|
const allNavigationEntries = navigationState.topLevelNavigation?.navigationEntries ?? [];
|
|
167
167
|
|
|
168
168
|
// Build a set of Studio-only dev view slugs so we can distinguish them from
|
|
169
|
-
// CMS custom views added via <
|
|
169
|
+
// CMS custom views added via <RebaseAdmin views={...}> or plugins.
|
|
170
170
|
const studioViewSlugs = useMemo(() => {
|
|
171
171
|
const slugs = new Set<string>();
|
|
172
172
|
(registry.studioConfig?.devViews ?? []).forEach(v => slugs.add(v.slug));
|
|
@@ -3,9 +3,10 @@ import type { FormContext } from "../types/fields";
|
|
|
3
3
|
import type { PluginFormActionProps } from "@rebasepro/types";
|
|
4
4
|
import React, { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Entity, EntityStatus, getCollectionDataPath, Property } from "@rebasepro/types";
|
|
6
|
-
import { PluginProviderStack, resolveComponentRef, useComponentOverride, CollectionScopeProvider } from "@rebasepro/
|
|
6
|
+
import { PluginProviderStack, resolveComponentRef, useComponentOverride, CollectionScopeProvider } from "@rebasepro/app";
|
|
7
7
|
|
|
8
|
-
import { CollectionViewBinding
|
|
8
|
+
import { CollectionViewBinding } from "./CollectionViewBinding/CollectionViewBinding";
|
|
9
|
+
import { EntityViewBinding } from "./EntityViewBinding";
|
|
9
10
|
import { CircularProgressCenter, iconSize } from "@rebasepro/ui";
|
|
10
11
|
import {
|
|
11
12
|
Alert,
|
|
@@ -25,7 +26,7 @@ import {
|
|
|
25
26
|
Typography
|
|
26
27
|
} from "@rebasepro/ui";
|
|
27
28
|
import { ErrorBoundary } from "@rebasepro/ui";
|
|
28
|
-
import { ErrorView, createFormexStub, usePermissions, useTranslation, getIcon } from "@rebasepro/
|
|
29
|
+
import { ErrorView, createFormexStub, usePermissions, useTranslation, getIcon } from "@rebasepro/app";
|
|
29
30
|
import {
|
|
30
31
|
getSubcollections,
|
|
31
32
|
removeInitialAndTrailingSlashes,
|
|
@@ -38,8 +39,9 @@ import {
|
|
|
38
39
|
useRebaseContext,
|
|
39
40
|
useLargeLayout,
|
|
40
41
|
useSlot
|
|
41
|
-
} from "@rebasepro/
|
|
42
|
-
import { useUrlController
|
|
42
|
+
} from "@rebasepro/app";
|
|
43
|
+
import { useUrlController } from "../hooks/navigation/contexts/UrlContext";
|
|
44
|
+
import { useCollectionRegistryController } from "../hooks/navigation/contexts/CollectionRegistryContext";
|
|
43
45
|
import { useNavigate } from "react-router-dom";
|
|
44
46
|
import { getValueInPath } from "@rebasepro/utils";
|
|
45
47
|
import { getEntityTitlePropertyKey, resolveTitleToString } from "../util/previews";
|
|
@@ -2,9 +2,9 @@ import type { NavigationEntry } from "@rebasepro/types";
|
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { ChevronDownIcon, cls, iconSize, Typography } from "@rebasepro/ui";
|
|
4
4
|
|
|
5
|
-
import { IconForView } from "@rebasepro/
|
|
5
|
+
import { IconForView } from "@rebasepro/app";
|
|
6
6
|
import { DrawerNavigationItem } from "./DrawerNavigationItem";
|
|
7
|
-
import { useTranslation, useComponentOverride } from "@rebasepro/
|
|
7
|
+
import { useTranslation, useComponentOverride } from "@rebasepro/app";
|
|
8
8
|
|
|
9
9
|
export interface DrawerNavigationGroupProps {
|
|
10
10
|
/**
|
|
@@ -5,7 +5,7 @@ import type { EntityAction, EntityActionClickProps, SidePanelController } from "
|
|
|
5
5
|
import React, { useMemo } from "react";
|
|
6
6
|
import { Entity, getCollectionDataPath, RebaseContext } from "@rebasepro/types";
|
|
7
7
|
import type { EntityFormActionsProps } from "../types/components/EntityFormActionsProps";
|
|
8
|
-
import { copyEntityAction, deleteEntityAction } from "
|
|
8
|
+
import { copyEntityAction, deleteEntityAction } from "./common/default_entity_actions";
|
|
9
9
|
import { mergeEntityActions } from "../util/entity_actions";
|
|
10
10
|
import { resolveEntityAction } from "../util/resolutions";
|
|
11
11
|
import { Button, CircularProgress, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Tooltip, Typography } from "@rebasepro/ui";
|
|
@@ -14,12 +14,12 @@ import {
|
|
|
14
14
|
useCustomizationController,
|
|
15
15
|
useSnackbarController,
|
|
16
16
|
useTranslation
|
|
17
|
-
} from "@rebasepro/
|
|
17
|
+
} from "@rebasepro/app";
|
|
18
18
|
import { SideDialogController, useSideDialogContext } from "./SideDialogs";
|
|
19
|
-
import { FormexController } from "@rebasepro/
|
|
20
|
-
import { ErrorTooltip } from "@rebasepro/
|
|
21
|
-
import { usePermissions } from "@rebasepro/
|
|
22
|
-
import { useCMSContext } from "../
|
|
19
|
+
import { FormexController } from "@rebasepro/forms";
|
|
20
|
+
import { ErrorTooltip } from "@rebasepro/app";
|
|
21
|
+
import { usePermissions } from "@rebasepro/app";
|
|
22
|
+
import { useCMSContext } from "../hooks/useCMSContext";
|
|
23
23
|
|
|
24
24
|
export function EditFormActions({
|
|
25
25
|
collection,
|
|
@@ -3,9 +3,10 @@ import type { FormContext } from "../types/fields";
|
|
|
3
3
|
import type { PluginFormActionProps } from "@rebasepro/types";
|
|
4
4
|
import React, { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { Entity, EntityStatus, getCollectionDataPath } from "@rebasepro/types";
|
|
6
|
-
import { PluginProviderStack, resolveComponentRef, useComponentOverride, CollectionScopeProvider } from "@rebasepro/
|
|
6
|
+
import { PluginProviderStack, resolveComponentRef, useComponentOverride, CollectionScopeProvider } from "@rebasepro/app";
|
|
7
7
|
|
|
8
|
-
import { CollectionViewBinding
|
|
8
|
+
import { CollectionViewBinding } from "./CollectionViewBinding/CollectionViewBinding";
|
|
9
|
+
import { EntityViewBinding } from "./EntityViewBinding";
|
|
9
10
|
import { CircularProgressCenter, iconSize } from "@rebasepro/ui";
|
|
10
11
|
import {
|
|
11
12
|
CenteredView,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
Typography
|
|
24
25
|
} from "@rebasepro/ui";
|
|
25
26
|
import { ErrorBoundary } from "@rebasepro/ui";
|
|
26
|
-
import { ErrorView } from "@rebasepro/
|
|
27
|
+
import { ErrorView } from "@rebasepro/app";
|
|
27
28
|
import {
|
|
28
29
|
getSubcollections,
|
|
29
30
|
removeInitialAndTrailingSlashes,
|
|
@@ -37,8 +38,8 @@ import {
|
|
|
37
38
|
useLargeLayout,
|
|
38
39
|
useSlot,
|
|
39
40
|
getIcon
|
|
40
|
-
} from "@rebasepro/
|
|
41
|
-
import { getEntityFromMemoryCache } from "@rebasepro/
|
|
41
|
+
} from "@rebasepro/app";
|
|
42
|
+
import { getEntityFromMemoryCache } from "@rebasepro/app";
|
|
42
43
|
import { EntityFormBinding } from "../form";
|
|
43
44
|
import type { EntityFormBindingProps } from "../form";
|
|
44
45
|
import type { OnUpdateParams } from "../types/components/EntityFormProps";
|
|
@@ -46,9 +47,9 @@ import { EditFormActions } from "./EditFormActions";
|
|
|
46
47
|
import { JsonPreviewBinding } from "../components/JsonPreviewBinding";
|
|
47
48
|
// Lazy-load history view — only loaded when user clicks the HistoryIcon tab
|
|
48
49
|
const EntityHistoryView = lazy(() => import("../components/history").then(m => ({ default: m.EntityHistoryView })));
|
|
49
|
-
import { createFormexStub, getEntityFromCache } from "@rebasepro/
|
|
50
|
-
import { usePermissions } from "@rebasepro/
|
|
51
|
-
import { useUrlController } from "../
|
|
50
|
+
import { createFormexStub, getEntityFromCache } from "@rebasepro/app";
|
|
51
|
+
import { usePermissions } from "@rebasepro/app";
|
|
52
|
+
import { useUrlController } from "../hooks/navigation/contexts/UrlContext";
|
|
52
53
|
import { useNavigate } from "react-router-dom";
|
|
53
54
|
|
|
54
55
|
import { MAIN_TAB_VALUE, JSON_TAB_VALUE, HISTORY_TAB_VALUE } from "../util/view_constants";
|
|
@@ -21,13 +21,14 @@ import {
|
|
|
21
21
|
useCustomizationController,
|
|
22
22
|
useData,
|
|
23
23
|
ErrorView
|
|
24
|
-
} from "@rebasepro/
|
|
25
|
-
import { useAnalyticsController } from "@rebasepro/
|
|
26
|
-
import { IconForView } from "@rebasepro/
|
|
24
|
+
} from "@rebasepro/app";
|
|
25
|
+
import { useAnalyticsController } from "@rebasepro/app";
|
|
26
|
+
import { IconForView } from "@rebasepro/app";
|
|
27
27
|
import { getPropertyInPath } from "../util/property_utils";
|
|
28
28
|
import { getEntityPreviewKeys, getEntityTitlePropertyKey } from "../util/previews";
|
|
29
29
|
import { getValueInPath } from "@rebasepro/utils";
|
|
30
|
-
import { useCollectionRegistryController
|
|
30
|
+
import { useCollectionRegistryController } from "../hooks/navigation/contexts/CollectionRegistryContext";
|
|
31
|
+
import { useSidePanel } from "../hooks/useSidePanel";
|
|
31
32
|
|
|
32
33
|
export type EntityPreviewBindingProps = {
|
|
33
34
|
size?: PreviewSize,
|
|
@@ -5,8 +5,8 @@ import React from "react";
|
|
|
5
5
|
import { Entity } from "@rebasepro/types";
|
|
6
6
|
import { cls, defaultBorderMixin, ExternalLinkIcon, IconButton, Typography } from "@rebasepro/ui";
|
|
7
7
|
;
|
|
8
|
-
import { useCustomizationController } from "@rebasepro/
|
|
9
|
-
import { useAuthController } from "@rebasepro/
|
|
8
|
+
import { useCustomizationController } from "@rebasepro/app";
|
|
9
|
+
import { useAuthController } from "@rebasepro/app";
|
|
10
10
|
import { PropertyCollectionView } from "./PropertyCollectionView";
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -19,11 +19,12 @@ import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable"
|
|
|
19
19
|
import { restrictToVerticalAxis, restrictToWindowEdges } from "@dnd-kit/modifiers";
|
|
20
20
|
import { RenameGroupDialog } from "./RenameGroupDialog";
|
|
21
21
|
import { toArray } from "@rebasepro/utils";
|
|
22
|
-
import { useCollapsedGroups, buildCollapsedDefaults, useCustomizationController, useTranslation, useSlot, useAdminModeController, useRebaseRegistry } from "@rebasepro/
|
|
23
|
-
import { useRestoreScroll } from "@rebasepro/
|
|
22
|
+
import { useCollapsedGroups, buildCollapsedDefaults, useCustomizationController, useTranslation, useSlot, useAdminModeController, useRebaseRegistry } from "@rebasepro/app";
|
|
23
|
+
import { useRestoreScroll } from "@rebasepro/app";
|
|
24
24
|
|
|
25
|
-
import { SchemaDriftBanner } from "@rebasepro/
|
|
26
|
-
import { useBreadcrumbsController
|
|
25
|
+
import { SchemaDriftBanner } from "@rebasepro/app";
|
|
26
|
+
import { useBreadcrumbsController } from "../../hooks/useBreadcrumbsController";
|
|
27
|
+
import { useCMSContext } from "../../hooks/useCMSContext";
|
|
27
28
|
|
|
28
29
|
export const DEFAULT_GROUP_NAME = "Views";
|
|
29
30
|
export const ADMIN_GROUP_NAME = "Admin";
|
|
@@ -64,7 +65,7 @@ export function ContentHomePage({
|
|
|
64
65
|
} = navigationStateController.topLevelNavigation || {};
|
|
65
66
|
|
|
66
67
|
// Build a set of Studio-only dev view slugs so we can distinguish them from
|
|
67
|
-
// CMS custom views added via <
|
|
68
|
+
// CMS custom views added via <RebaseAdmin views={...}> or plugins.
|
|
68
69
|
const studioViewSlugs = useMemo(() => {
|
|
69
70
|
const slugs = new Set<string>();
|
|
70
71
|
(registry.studioConfig?.devViews ?? []).forEach(v => slugs.add(v.slug));
|
|
@@ -2,8 +2,8 @@ import type { NavigationEntry } from "@rebasepro/types";
|
|
|
2
2
|
import { useNavigate } from "react-router-dom";
|
|
3
3
|
;
|
|
4
4
|
import { Chip, Collapse, StarIcon } from "@rebasepro/ui";
|
|
5
|
-
import { useUserConfigurationPersistence } from "@rebasepro/
|
|
6
|
-
import { useNavigationStateController } from "../../
|
|
5
|
+
import { useUserConfigurationPersistence } from "@rebasepro/app";
|
|
6
|
+
import { useNavigationStateController } from "../../hooks/navigation/contexts/NavigationStateContext";
|
|
7
7
|
|
|
8
8
|
function NavigationChip({ entry }: { entry: NavigationEntry }) {
|
|
9
9
|
|
|
@@ -5,9 +5,9 @@ import { IconButton, StarIcon, Tooltip } from "@rebasepro/ui";
|
|
|
5
5
|
import { NavigationCard } from "./NavigationCard";
|
|
6
6
|
import { SmallNavigationCard } from "./SmallNavigationCard";
|
|
7
7
|
import React from "react";
|
|
8
|
-
import { useRebaseContext, useSlot } from "@rebasepro/
|
|
9
|
-
import { IconForView } from "@rebasepro/
|
|
10
|
-
import { useUserConfigurationPersistence } from "@rebasepro/
|
|
8
|
+
import { useRebaseContext, useSlot } from "@rebasepro/app";
|
|
9
|
+
import { IconForView } from "@rebasepro/app";
|
|
10
|
+
import { useUserConfigurationPersistence } from "@rebasepro/app";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* This is the component used in the home page to render a card for each
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { PropsWithChildren, useState } from "react";
|
|
2
2
|
import { cls, ExpandablePanel, IconButton, iconSize, PencilIcon, Typography } from "@rebasepro/ui";
|
|
3
|
-
import { useTranslation } from "@rebasepro/
|
|
3
|
+
import { useTranslation } from "@rebasepro/app";
|
|
4
4
|
|
|
5
5
|
export function NavigationGroup({
|
|
6
6
|
children,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField } from "@rebasepro/ui";
|
|
3
|
-
import { useTranslation } from "@rebasepro/
|
|
3
|
+
import { useTranslation } from "@rebasepro/app";
|
|
4
4
|
|
|
5
5
|
interface RenameGroupDialogProps {
|
|
6
6
|
open: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useRef } from "react";
|
|
2
2
|
import { Highlight, themes } from "prism-react-renderer";
|
|
3
|
-
import { useModeController } from "@rebasepro/
|
|
3
|
+
import { useModeController } from "@rebasepro/app";
|
|
4
4
|
|
|
5
5
|
export function JsonPreviewBinding({ values }: { values: object }) {
|
|
6
6
|
const code = JSON.stringify(values, null, "\t");
|