@rebasepro/cms 0.17.3 → 0.18.1
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 +4 -0
- package/dist/{CollectionEditorDialog-B-akreOU.js → CollectionEditorDialog-BeX4b92r.js} +13 -7
- package/dist/{CollectionEditorDialog-B-akreOU.js.map → CollectionEditorDialog-BeX4b92r.js.map} +1 -1
- package/dist/{PropertyEditView-CiY84wkR.js → PropertyEditView-C7thfj4L.js} +3 -3
- package/dist/{PropertyEditView-CiY84wkR.js.map → PropertyEditView-C7thfj4L.js.map} +1 -1
- package/dist/{RouterCollectionsStudioView-DkAWda4N.js → RouterCollectionsStudioView-BtjzvB6E.js} +4 -4
- package/dist/{RouterCollectionsStudioView-DkAWda4N.js.map → RouterCollectionsStudioView-BtjzvB6E.js.map} +1 -1
- package/dist/{SchemaChangeDialog-DceT8QFX.js → SchemaChangeDialog-CkqK6KOC.js} +4 -2
- package/dist/{SchemaChangeDialog-DceT8QFX.js.map → SchemaChangeDialog-CkqK6KOC.js.map} +1 -1
- package/dist/collection_editor/api/generateCollectionApi.d.ts +1 -2
- package/dist/collection_editor_ui.d.ts +2 -0
- package/dist/collection_editor_ui.js +6 -5
- package/dist/collection_editor_ui.js.map +1 -1
- package/dist/components/DeleteEntityDialog.d.ts +2 -3
- package/dist/components/RebaseLayout.d.ts +11 -4
- package/dist/components/field_configs.d.ts +1 -1
- package/dist/editor/sanitize-html.d.ts +15 -0
- package/dist/editor.js +195 -10
- package/dist/editor.js.map +1 -1
- package/dist/{export-Ben8E355.js → export--arni_VY.js} +2 -2
- package/dist/{export-Ben8E355.js.map → export--arni_VY.js.map} +1 -1
- package/dist/form/components/LabelWithIcon.d.ts +10 -0
- package/dist/{history-DIEVd26f.js → history-C2TpoQwi.js} +2 -2
- package/dist/{history-DIEVd26f.js.map → history-C2TpoQwi.js.map} +1 -1
- package/dist/hooks/navigation/useBuildNavigationStateController.d.ts +1 -1
- package/dist/hooks/navigation/useResolvedViews.d.ts +1 -1
- package/dist/hooks/navigation/useTopLevelNavigation.d.ts +1 -1
- package/dist/{import-D25x7ko-.js → import-DTkXNoBg.js} +2 -2
- package/dist/{import-D25x7ko-.js.map → import-DTkXNoBg.js.map} +1 -1
- package/dist/index.js +78 -33
- package/dist/index.js.map +1 -1
- package/dist/util/propertyConfigMapper.d.ts +1 -1
- package/dist/util-CfLFggP7.js +57 -0
- package/dist/util-CfLFggP7.js.map +1 -0
- package/dist/{util-DVqnqlLn.js → util-DE1WQW6h.js} +134 -112
- package/dist/util-DE1WQW6h.js.map +1 -0
- package/package.json +42 -34
- package/dist/util-DVqnqlLn.js.map +0 -1
- package/src/collection_editor/CollectionEditorDialogsContext.tsx +0 -25
- package/src/collection_editor/ConfigControllerProvider.tsx +0 -395
- package/src/collection_editor/_cms_internals.ts +0 -41
- package/src/collection_editor/api/generateCollectionApi.ts +0 -126
- package/src/collection_editor/api/index.ts +0 -1
- package/src/collection_editor/extensibility_types.ts +0 -168
- package/src/collection_editor/index.ts +0 -108
- package/src/collection_editor/liveSchemaClient.ts +0 -285
- package/src/collection_editor/relation_kinds.ts +0 -44
- package/src/collection_editor/serializable_types.ts +0 -535
- package/src/collection_editor/serializable_utils.ts +0 -729
- package/src/collection_editor/types/collection_editor_controller.tsx +0 -62
- package/src/collection_editor/types/collection_inference.ts +0 -18
- package/src/collection_editor/types/config_controller.tsx +0 -121
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +0 -199
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +0 -51
- package/src/collection_editor/ui/EditorCollectionAction.tsx +0 -54
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +0 -90
- package/src/collection_editor/ui/EditorEntityAction.tsx +0 -50
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +0 -114
- package/src/collection_editor/ui/KanbanSetupAction.tsx +0 -43
- package/src/collection_editor/ui/MissingReferenceWidget.tsx +0 -35
- package/src/collection_editor/ui/NewCollectionButton.tsx +0 -27
- package/src/collection_editor/ui/NewCollectionCard.tsx +0 -48
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +0 -49
- package/src/collection_editor/ui/collection_editor/AICollectionGeneratorPopover.tsx +0 -260
- package/src/collection_editor/ui/collection_editor/AIModifiedPathsContext.tsx +0 -90
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +0 -388
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +0 -1098
- package/src/collection_editor/ui/collection_editor/CollectionEditorWelcomeView.tsx +0 -301
- package/src/collection_editor/ui/collection_editor/CollectionJsonImportDialog.tsx +0 -172
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +0 -620
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +0 -530
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +0 -462
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +0 -104
- package/src/collection_editor/ui/collection_editor/CollectionYupValidation.tsx +0 -9
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +0 -199
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +0 -315
- package/src/collection_editor/ui/collection_editor/EntityActionsEditTab.tsx +0 -164
- package/src/collection_editor/ui/collection_editor/EntityActionsSelectDialog.tsx +0 -40
- package/src/collection_editor/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/EnumForm.tsx +0 -373
- package/src/collection_editor/ui/collection_editor/GeneralSettingsForm.tsx +0 -288
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +0 -141
- package/src/collection_editor/ui/collection_editor/KanbanConfigSection.tsx +0 -194
- package/src/collection_editor/ui/collection_editor/LayoutModeSwitch.tsx +0 -53
- package/src/collection_editor/ui/collection_editor/PropertyEditView.tsx +0 -980
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +0 -164
- package/src/collection_editor/ui/collection_editor/PropertyTree.tsx +0 -364
- package/src/collection_editor/ui/collection_editor/RouterCollectionStudioView.tsx +0 -44
- package/src/collection_editor/ui/collection_editor/RouterCollectionsStudioView.tsx +0 -41
- package/src/collection_editor/ui/collection_editor/SchemaChangeDialog.tsx +0 -470
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +0 -256
- package/src/collection_editor/ui/collection_editor/SwitchControl.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/ViewModeSwitch.tsx +0 -68
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +0 -67
- package/src/collection_editor/ui/collection_editor/import/CollectionEditorImportMapping.tsx +0 -296
- package/src/collection_editor/ui/collection_editor/import/clean_import_data.ts +0 -57
- package/src/collection_editor/ui/collection_editor/properties/BlockPropertyField.tsx +0 -147
- package/src/collection_editor/ui/collection_editor/properties/BooleanPropertyField.tsx +0 -41
- package/src/collection_editor/ui/collection_editor/properties/CommonPropertyFields.tsx +0 -113
- package/src/collection_editor/ui/collection_editor/properties/DateTimePropertyField.tsx +0 -250
- package/src/collection_editor/ui/collection_editor/properties/EnumPropertyField.tsx +0 -126
- package/src/collection_editor/ui/collection_editor/properties/KeyValuePropertyField.tsx +0 -20
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +0 -153
- package/src/collection_editor/ui/collection_editor/properties/MarkdownPropertyField.tsx +0 -217
- package/src/collection_editor/ui/collection_editor/properties/NumberPropertyField.tsx +0 -117
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +0 -129
- package/src/collection_editor/ui/collection_editor/properties/RelationPropertyField.tsx +0 -335
- package/src/collection_editor/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -107
- package/src/collection_editor/ui/collection_editor/properties/StoragePropertyField.tsx +0 -403
- package/src/collection_editor/ui/collection_editor/properties/StringPropertyField.tsx +0 -148
- package/src/collection_editor/ui/collection_editor/properties/UrlPropertyField.tsx +0 -91
- package/src/collection_editor/ui/collection_editor/properties/VectorPropertyField.tsx +0 -34
- package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +0 -49
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +0 -925
- package/src/collection_editor/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +0 -28
- package/src/collection_editor/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +0 -626
- package/src/collection_editor/ui/collection_editor/properties/conditions/index.ts +0 -6
- package/src/collection_editor/ui/collection_editor/properties/conditions/property_paths.ts +0 -93
- package/src/collection_editor/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +0 -52
- package/src/collection_editor/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +0 -63
- package/src/collection_editor/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +0 -114
- package/src/collection_editor/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +0 -154
- package/src/collection_editor/ui/collection_editor/properties/validation/ValidationPanel.tsx +0 -28
- package/src/collection_editor/ui/collection_editor/templates/blog_template.ts +0 -112
- package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +0 -183
- package/src/collection_editor/ui/collection_editor/templates/products_template.ts +0 -88
- package/src/collection_editor/ui/collection_editor/templates/users_template.ts +0 -42
- package/src/collection_editor/ui/collection_editor/util.ts +0 -28
- package/src/collection_editor/ui/collection_editor/utils/strings.ts +0 -1
- package/src/collection_editor/ui/collection_editor/utils/supported_fields.tsx +0 -39
- package/src/collection_editor/ui/collection_editor/utils/update_property_for_widget.ts +0 -276
- package/src/collection_editor/useCollectionEditorController.tsx +0 -9
- package/src/collection_editor/useCollectionsConfigController.tsx +0 -9
- package/src/collection_editor/useJsonCollectionsConfigController.tsx +0 -297
- package/src/collection_editor/useLiveSchemaEditing.tsx +0 -315
- package/src/collection_editor/useLocalCollectionsConfigController.tsx +0 -341
- package/src/collection_editor/useSafeSnackbarController.ts +0 -9
- package/src/collection_editor/validateCollectionJson.ts +0 -440
- package/src/collection_editor_ui.ts +0 -21
- package/src/components/AdditionalFieldValue.tsx +0 -68
- package/src/components/AdminModeSyncer.tsx +0 -56
- package/src/components/ArrayContainer.tsx +0 -542
- package/src/components/ClearFilterSortButton.tsx +0 -56
- package/src/components/CollectionEditorDialogs.tsx +0 -69
- package/src/components/CollectionPanel.tsx +0 -179
- package/src/components/CollectionTableBinding/CollectionRowActions.tsx +0 -244
- package/src/components/CollectionTableBinding/CollectionTableBinding.tsx +0 -394
- package/src/components/CollectionTableBinding/CollectionTableBindingProps.tsx +0 -172
- package/src/components/CollectionTableBinding/PropertyTableCell.tsx +0 -350
- package/src/components/CollectionTableBinding/column_utils.tsx +0 -155
- package/src/components/CollectionTableBinding/fields/TableMultipleRelationField.tsx +0 -131
- package/src/components/CollectionTableBinding/fields/TableReferenceField.tsx +0 -193
- package/src/components/CollectionTableBinding/fields/TableRelationField.tsx +0 -192
- package/src/components/CollectionTableBinding/fields/TableRelationSelectorField.tsx +0 -42
- package/src/components/CollectionTableBinding/fields/TableStorageUpload.tsx +0 -324
- package/src/components/CollectionTableBinding/fields/VirtualTableSelect.tsx +0 -132
- package/src/components/CollectionTableBinding/fields/VirtualTableUserSelect.tsx +0 -41
- package/src/components/CollectionTableBinding/index.tsx +0 -14
- package/src/components/CollectionTableBinding/internal/CollectionTableToolbar.tsx +0 -96
- package/src/components/CollectionTableBinding/internal/EntityTableCell.tsx +0 -309
- package/src/components/CollectionTableBinding/internal/EntityTableCellActions.tsx +0 -80
- package/src/components/CollectionTableBinding/internal/common.tsx +0 -74
- package/src/components/CollectionTableBinding/internal/popup_field/PopupFormField.tsx +0 -422
- package/src/components/CollectionTableBinding/internal/popup_field/useDraggable.tsx +0 -99
- package/src/components/CollectionTableBinding/internal/popup_field/useWindowSize.tsx +0 -22
- package/src/components/CollectionTableBinding/table_bindings.tsx +0 -350
- package/src/components/CollectionViewBinding/BoardCardBinding.tsx +0 -263
- package/src/components/CollectionViewBinding/CollectionBoardViewBinding.tsx +0 -662
- package/src/components/CollectionViewBinding/CollectionCardViewBinding.tsx +0 -159
- package/src/components/CollectionViewBinding/CollectionListViewBinding.tsx +0 -1430
- package/src/components/CollectionViewBinding/CollectionViewActions.tsx +0 -227
- package/src/components/CollectionViewBinding/CollectionViewBinding.tsx +0 -1603
- package/src/components/CollectionViewBinding/CollectionViewStartActions.tsx +0 -240
- package/src/components/CollectionViewBinding/EntityCardBinding.tsx +0 -239
- package/src/components/CollectionViewBinding/FilterPresetsButton.tsx +0 -298
- package/src/components/CollectionViewBinding/FiltersDialog.tsx +0 -218
- package/src/components/CollectionViewBinding/SearchExplanation.tsx +0 -106
- package/src/components/CollectionViewBinding/SearchHighlight.tsx +0 -311
- package/src/components/CollectionViewBinding/SlotValue.tsx +0 -156
- package/src/components/CollectionViewBinding/SortButton.tsx +0 -354
- package/src/components/CollectionViewBinding/SplitListCloseButton.tsx +0 -49
- package/src/components/CollectionViewBinding/SplitListShowButton.tsx +0 -28
- package/src/components/CollectionViewBinding/SplitListView.tsx +0 -488
- package/src/components/CollectionViewBinding/SplitViewContext.tsx +0 -34
- package/src/components/CollectionViewBinding/ViewModeToggle.tsx +0 -250
- package/src/components/CollectionViewBinding/hooks/useCollectionInlineEditor.ts +0 -81
- package/src/components/CollectionViewBinding/hooks/useKanbanDragAndDrop.ts +0 -181
- package/src/components/CollectionViewBinding/useBoardDataController.tsx +0 -802
- package/src/components/CollectionViewBinding/usePreviewSlots.ts +0 -703
- package/src/components/CollectionViewBinding/useSelectionController.tsx +0 -40
- package/src/components/CollectionViewBinding/utils.ts +0 -22
- package/src/components/DefaultAppBar.tsx +0 -264
- package/src/components/DefaultDrawer.tsx +0 -593
- package/src/components/DeleteEntityDialog.tsx +0 -205
- package/src/components/DetailViewBinding.tsx +0 -731
- package/src/components/DrawerNavigationGroup.tsx +0 -141
- package/src/components/DrawerNavigationItem.tsx +0 -115
- package/src/components/EditFormActions.tsx +0 -303
- package/src/components/EditViewBinding.tsx +0 -1069
- package/src/components/EntityDisplayHeader.tsx +0 -170
- package/src/components/EntityIdentityBar.tsx +0 -428
- package/src/components/EntityInspector.tsx +0 -156
- package/src/components/EntityPreviewBinding.tsx +0 -432
- package/src/components/EntityPreviewNesting.tsx +0 -50
- package/src/components/EntityViewBinding.tsx +0 -374
- package/src/components/FieldCaption.tsx +0 -14
- package/src/components/HomePage/ContentHomePage.tsx +0 -586
- package/src/components/HomePage/FavouritesView.tsx +0 -60
- package/src/components/HomePage/HomePageDnD.tsx +0 -704
- package/src/components/HomePage/NavigationCard.tsx +0 -81
- package/src/components/HomePage/NavigationCardBinding.tsx +0 -107
- package/src/components/HomePage/NavigationGroup.tsx +0 -156
- package/src/components/HomePage/RenameGroupDialog.tsx +0 -123
- package/src/components/HomePage/SmallNavigationCard.tsx +0 -41
- package/src/components/HomePage/index.tsx +0 -5
- package/src/components/InlineEntityPreview.tsx +0 -149
- package/src/components/JsonPreviewBinding.tsx +0 -66
- package/src/components/PropertyCollectionView.tsx +0 -336
- package/src/components/PropertyConfigBadge.tsx +0 -28
- package/src/components/PropertyIdCopyTooltip.tsx +0 -47
- package/src/components/RebaseAuthGate.tsx +0 -44
- package/src/components/RebaseCMS.tsx +0 -30
- package/src/components/RebaseLayout.tsx +0 -80
- package/src/components/RebaseNavigation.tsx +0 -369
- package/src/components/RebaseRouteDefs.tsx +0 -127
- package/src/components/RebaseShell.tsx +0 -83
- package/src/components/ReferenceTable/SelectionTableBinding.tsx +0 -389
- package/src/components/ReferenceWidget.tsx +0 -156
- package/src/components/RelationSelector.tsx +0 -926
- package/src/components/SearchIconsView.tsx +0 -78
- package/src/components/SelectableTable/SelectableTable.tsx +0 -309
- package/src/components/SelectableTable/SelectableTableContext.tsx +0 -7
- package/src/components/SelectableTable/SelectionStore.ts +0 -43
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +0 -59
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +0 -146
- package/src/components/SelectableTable/filters/FilterFieldBinding.tsx +0 -190
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +0 -250
- package/src/components/SelectableTable/filters/RelationFilterField.tsx +0 -238
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +0 -282
- package/src/components/SelectableTable/filters/null_filter.ts +0 -63
- package/src/components/SideDialogs.tsx +0 -238
- package/src/components/SidePanelBinding.tsx +0 -361
- package/src/components/SidePanelProvider.tsx +0 -80
- package/src/components/UserSelector.tsx +0 -513
- package/src/components/admin/CreationResultDialog.tsx +0 -138
- package/src/components/admin/index.ts +0 -1
- package/src/components/app/AppBar.tsx +0 -17
- package/src/components/app/Drawer.tsx +0 -38
- package/src/components/app/Scaffold.tsx +0 -366
- package/src/components/app/index.ts +0 -4
- package/src/components/app/useApp.tsx +0 -36
- package/src/components/common/default_entity_actions.tsx +0 -440
- package/src/components/common/index.ts +0 -1
- package/src/components/field_configs.tsx +0 -506
- package/src/components/history/EntityHistoryEntry.tsx +0 -203
- package/src/components/history/EntityHistoryView.tsx +0 -206
- package/src/components/history/LastEditedByFormAction.tsx +0 -24
- package/src/components/history/LastEditedByIndicator.tsx +0 -95
- package/src/components/history/UserChip.tsx +0 -15
- package/src/components/history/index.tsx +0 -5
- package/src/components/index.ts +0 -63
- package/src/contexts/BreacrumbsContext.tsx +0 -45
- package/src/contexts/SideDialogsControllerContext.tsx +0 -5
- package/src/contexts/SidePanelControllerContext.tsx +0 -5
- package/src/data_export/export/BasicExportAction.tsx +0 -142
- package/src/data_export/export/ExportCollectionAction.tsx +0 -321
- package/src/data_export/export/export.ts +0 -295
- package/src/data_export/export/fetch_export_data.ts +0 -90
- package/src/data_export/export/index.ts +0 -4
- package/src/data_export/index.ts +0 -1
- package/src/data_import/components/DataNewPropertiesMapping.tsx +0 -261
- package/src/data_import/components/ImportFileUpload.tsx +0 -42
- package/src/data_import/components/ImportNewPropertyFieldPreview.tsx +0 -58
- package/src/data_import/components/ImportSaveInProgress.tsx +0 -121
- package/src/data_import/components/index.ts +0 -4
- package/src/data_import/hooks/index.ts +0 -1
- package/src/data_import/hooks/useImportConfig.tsx +0 -34
- package/src/data_import/import/ImportCollectionAction.tsx +0 -461
- package/src/data_import/import/index.ts +0 -1
- package/src/data_import/index.ts +0 -5
- package/src/data_import/types/column_mapping.ts +0 -32
- package/src/data_import/types/index.ts +0 -1
- package/src/data_import/utils/csv.ts +0 -153
- package/src/data_import/utils/data.ts +0 -181
- package/src/data_import/utils/file_headers.ts +0 -14
- package/src/data_import/utils/file_to_json.ts +0 -149
- package/src/data_import/utils/get_import_inference_type.ts +0 -33
- package/src/data_import/utils/get_properties_mapping.ts +0 -67
- package/src/data_import/utils/index.ts +0 -5
- package/src/data_import/utils/save_entities.ts +0 -138
- package/src/data_import/utils/transforms.ts +0 -70
- package/src/editor/components/SlashCommandMenu.tsx +0 -532
- package/src/editor/components/editor-bubble-item.tsx +0 -32
- package/src/editor/components/editor-bubble.tsx +0 -143
- package/src/editor/components/image-bubble.tsx +0 -183
- package/src/editor/components/index.ts +0 -14
- package/src/editor/components/table-bubble.tsx +0 -233
- package/src/editor/editor.tsx +0 -529
- package/src/editor/extensions/HighlightDecorationExtension.ts +0 -115
- package/src/editor/extensions/Image.ts +0 -159
- package/src/editor/extensions/TextLoadingDecorationExtension.tsx +0 -107
- package/src/editor/extensions/clipboard.ts +0 -72
- package/src/editor/extensions/custom-keymap.ts +0 -25
- package/src/editor/extensions/drag-and-drop.tsx +0 -508
- package/src/editor/hooks/useProseMirror.ts +0 -126
- package/src/editor/hooks/useProseMirrorContext.ts +0 -15
- package/src/editor/index.ts +0 -2
- package/src/editor/markdown-it-plugins.d.ts +0 -24
- package/src/editor/markdown.ts +0 -204
- package/src/editor/nodeViews/ImageComponent.tsx +0 -20
- package/src/editor/nodeViews/ReactNodeView.tsx +0 -89
- package/src/editor/nodeViews/TaskItemComponent.tsx +0 -30
- package/src/editor/nodeViews/index.ts +0 -35
- package/src/editor/plugins/index.ts +0 -58
- package/src/editor/plugins/inputrules.ts +0 -82
- package/src/editor/plugins/placeholderPlugin.ts +0 -55
- package/src/editor/plugins/slashCommandPlugin.ts +0 -65
- package/src/editor/schema.ts +0 -339
- package/src/editor/selectors/ai-selector.tsx +0 -110
- package/src/editor/selectors/color-selector.tsx +0 -199
- package/src/editor/selectors/link-selector.tsx +0 -122
- package/src/editor/selectors/node-selector.tsx +0 -159
- package/src/editor/selectors/text-buttons.tsx +0 -79
- package/src/editor/types.ts +0 -6
- package/src/editor/useProseMirror.ts +0 -125
- package/src/editor/utils/prosemirror-utils.ts +0 -113
- package/src/editor/utils/remove_classes.ts +0 -18
- package/src/editor/utils/useDebouncedCallback.ts +0 -25
- package/src/form/EntityForm.tsx +0 -761
- package/src/form/EntityFormActions.tsx +0 -160
- package/src/form/EntityFormBinding.tsx +0 -342
- package/src/form/PropertyFieldBinding.tsx +0 -348
- package/src/form/components/ErrorFocus.tsx +0 -44
- package/src/form/components/FieldBlock.tsx +0 -189
- package/src/form/components/FieldHelperText.tsx +0 -84
- package/src/form/components/FormRail.tsx +0 -153
- package/src/form/components/FormSections.tsx +0 -145
- package/src/form/components/LabelWithIcon.tsx +0 -43
- package/src/form/components/LabelWithIconAndTooltip.tsx +0 -28
- package/src/form/components/LocalChangesMenu.tsx +0 -147
- package/src/form/components/StorageItemPreview.tsx +0 -81
- package/src/form/components/StorageUploadProgress.tsx +0 -118
- package/src/form/components/index.tsx +0 -6
- package/src/form/components/useRailVisible.tsx +0 -47
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +0 -109
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -172
- package/src/form/field_bindings/BinaryFieldBinding.tsx +0 -177
- package/src/form/field_bindings/BlockFieldBinding.tsx +0 -282
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +0 -78
- package/src/form/field_bindings/GeopointFieldBinding.tsx +0 -200
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -574
- package/src/form/field_bindings/MapFieldBinding.tsx +0 -120
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +0 -259
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +0 -130
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +0 -168
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +0 -94
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +0 -146
- package/src/form/field_bindings/RelationFieldBinding.tsx +0 -202
- package/src/form/field_bindings/RepeatFieldBinding.tsx +0 -143
- package/src/form/field_bindings/SelectFieldBinding.tsx +0 -111
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +0 -521
- package/src/form/field_bindings/SwitchFieldBinding.tsx +0 -70
- package/src/form/field_bindings/TextFieldBinding.tsx +0 -189
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +0 -71
- package/src/form/field_bindings/VectorFieldBinding.tsx +0 -209
- package/src/form/form_utils.ts +0 -243
- package/src/form/index.tsx +0 -36
- package/src/form/useClearRestoreValue.tsx +0 -36
- package/src/form/useUndoableDiscard.ts +0 -39
- package/src/form/validation.ts +0 -583
- package/src/hooks/index.ts +0 -16
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +0 -22
- package/src/hooks/navigation/contexts/NavigationStateContext.tsx +0 -16
- package/src/hooks/navigation/contexts/UrlContext.tsx +0 -24
- package/src/hooks/navigation/contexts/index.ts +0 -14
- package/src/hooks/navigation/useAsyncResolver.ts +0 -100
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +0 -218
- package/src/hooks/navigation/useBuildNavigationStateController.tsx +0 -134
- package/src/hooks/navigation/useBuildUrlController.tsx +0 -66
- package/src/hooks/navigation/useNavigationResolution.ts +0 -271
- package/src/hooks/navigation/useResolvedCollections.ts +0 -102
- package/src/hooks/navigation/useResolvedViews.tsx +0 -139
- package/src/hooks/navigation/useTopLevelNavigation.ts +0 -273
- package/src/hooks/navigation/utils.ts +0 -200
- package/src/hooks/useAdminContext.tsx +0 -83
- package/src/hooks/useBreadcrumbsController.tsx +0 -17
- package/src/hooks/useBuildSideDialogsController.tsx +0 -145
- package/src/hooks/useBuildSidePanel.tsx +0 -315
- package/src/hooks/useChildViewSource.ts +0 -46
- package/src/hooks/useEntityDisplay.tsx +0 -262
- package/src/hooks/useEntityDisplayTitle.tsx +0 -49
- package/src/hooks/useHistory.ts +0 -178
- package/src/hooks/useRecordActions.tsx +0 -69
- package/src/hooks/useResolvedNavigationFrom.tsx +0 -167
- package/src/hooks/useResolvedUsers.ts +0 -148
- package/src/hooks/useSelectionDialog.tsx +0 -58
- package/src/hooks/useSideDialogsController.tsx +0 -25
- package/src/hooks/useSidePanel.tsx +0 -13
- package/src/index.ts +0 -124
- package/src/preview/PropertyPreview.tsx +0 -331
- package/src/preview/compact_text.ts +0 -68
- package/src/preview/components/ArrayEnumPreview.tsx +0 -39
- package/src/preview/components/BooleanPreview.tsx +0 -28
- package/src/preview/components/DatePreview.tsx +0 -106
- package/src/preview/components/EmptyValue.tsx +0 -10
- package/src/preview/components/EnumValuesChip.tsx +0 -39
- package/src/preview/components/ImagePreview.tsx +0 -144
- package/src/preview/components/InlineEntityListPreview.tsx +0 -42
- package/src/preview/components/ReferencePreview.tsx +0 -235
- package/src/preview/components/RelationPreview.tsx +0 -271
- package/src/preview/components/StorageThumbnail.tsx +0 -147
- package/src/preview/components/UrlComponentPreview.tsx +0 -116
- package/src/preview/components/UserPreview.tsx +0 -30
- package/src/preview/components/date_fns_locales.ts +0 -125
- package/src/preview/index.ts +0 -26
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -73
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +0 -67
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +0 -77
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -49
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -70
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +0 -79
- package/src/preview/property_previews/ArrayPropertyEnumPreview.tsx +0 -35
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +0 -79
- package/src/preview/property_previews/MapPropertyPreview.tsx +0 -198
- package/src/preview/property_previews/NumberPropertyPreview.tsx +0 -39
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +0 -276
- package/src/preview/property_previews/StringPropertyPreview.tsx +0 -70
- package/src/preview/util.ts +0 -39
- package/src/routes/CustomViewRoute.tsx +0 -33
- package/src/routes/RebaseRoute.tsx +0 -467
- package/src/routes/index.ts +0 -2
- package/src/types/components/EntityFormActionsProps.tsx +0 -20
- package/src/types/components/EntityFormProps.tsx +0 -119
- package/src/types/components/PropertyPreviewProps.tsx +0 -85
- package/src/types/components/formex.tsx +0 -2
- package/src/types/components/index.ts +0 -3
- package/src/types/fields.tsx +0 -340
- package/src/types/index.ts +0 -4
- package/src/util/dataControllerAdapter.ts +0 -88
- package/src/util/entity_actions.ts +0 -28
- package/src/util/index.ts +0 -5
- package/src/util/navigation_utils.ts +0 -89
- package/src/util/number_format.ts +0 -46
- package/src/util/previews.ts +0 -131
- package/src/util/propertyConfigMapper.ts +0 -134
- package/src/util/property_utils.tsx +0 -236
- package/src/util/resolutions.ts +0 -96
- package/src/util/view_constants.ts +0 -33
- package/src/util/view_mode.ts +0 -176
|
@@ -1,488 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
-
import { Entity } from "@rebasepro/types";
|
|
4
|
-
import { CollectionSize, EntityTableController, SelectionController, AdminCollection } from "@rebasepro/cms-types";
|
|
5
|
-
import { EditViewBinding } from "../EditViewBinding";
|
|
6
|
-
import { DetailViewBinding } from "../DetailViewBinding";
|
|
7
|
-
import {
|
|
8
|
-
cls,
|
|
9
|
-
defaultBorderMixin,
|
|
10
|
-
ResizablePanels
|
|
11
|
-
} from "@rebasepro/ui";
|
|
12
|
-
import { useLargeLayout, UnsavedChangesDialog, useNavigationBlocker } from "@rebasepro/app";
|
|
13
|
-
import { useCollectionRegistryController } from "../../hooks/navigation/contexts/CollectionRegistryContext";
|
|
14
|
-
import { useNavigate, useLocation } from "react-router";
|
|
15
|
-
import { useUrlController } from "../../hooks/navigation/contexts/UrlContext";
|
|
16
|
-
import { ErrorBoundary } from "@rebasepro/ui";
|
|
17
|
-
import { withViewMode } from "../../util/view_mode";
|
|
18
|
-
import { SplitViewProvider } from "./SplitViewContext";
|
|
19
|
-
|
|
20
|
-
export type SplitListViewProps<M extends Record<string, unknown> = Record<string, unknown>> = {
|
|
21
|
-
collection: AdminCollection<M>;
|
|
22
|
-
tableController: EntityTableController<M>;
|
|
23
|
-
onEntityClick?: (entity: Entity<M>) => void;
|
|
24
|
-
onNewClick?: () => void;
|
|
25
|
-
selectionController?: SelectionController<M>;
|
|
26
|
-
selectionEnabled?: boolean;
|
|
27
|
-
highlightedEntities?: Entity<M>[];
|
|
28
|
-
emptyComponent?: React.ReactNode;
|
|
29
|
-
onScroll?: (props: {
|
|
30
|
-
scrollDirection: "forward" | "backward";
|
|
31
|
-
scrollOffset: number;
|
|
32
|
-
scrollUpdateWasRequested: boolean;
|
|
33
|
-
}) => void;
|
|
34
|
-
initialScroll?: number;
|
|
35
|
-
size?: CollectionSize;
|
|
36
|
-
path: string;
|
|
37
|
-
parentCollectionSlugs?: string[], parentEntityIds?: string[];
|
|
38
|
-
/**
|
|
39
|
-
* The entity ID to show in the detail panel.
|
|
40
|
-
* Comes from the URL path (e.g. /c/authors/14 → selectedEntityId = "14").
|
|
41
|
-
* When undefined, no detail panel is shown.
|
|
42
|
-
*/
|
|
43
|
-
selectedEntityId?: string | number;
|
|
44
|
-
/**
|
|
45
|
-
* When provided, the detail panel will open this tab (e.g. a subcollection slug).
|
|
46
|
-
* Used by the router to pass the subcollection tab from the URL.
|
|
47
|
-
*/
|
|
48
|
-
selectedTab?: string;
|
|
49
|
-
/**
|
|
50
|
-
* Toolbar to render above the content in the left panel.
|
|
51
|
-
*/
|
|
52
|
-
toolbar?: React.ReactNode;
|
|
53
|
-
/**
|
|
54
|
-
* The collection view to render on the left side.
|
|
55
|
-
*/
|
|
56
|
-
children: React.ReactNode;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const PANEL_SIZE_KEY = "rebase_split_list_panel_size";
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Whether the element accepts text, and therefore owns the keystroke.
|
|
63
|
-
* Covers native fields plus the ARIA roles custom editors expose.
|
|
64
|
-
*/
|
|
65
|
-
function isTextEntryTarget(target: HTMLElement | null): boolean {
|
|
66
|
-
if (!target) return false;
|
|
67
|
-
const tag = target.tagName;
|
|
68
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
69
|
-
if (target.isContentEditable) return true;
|
|
70
|
-
return Boolean(target.closest('[contenteditable="true"], [role="textbox"], [role="combobox"], [role="searchbox"]'));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Whether a bare letter shortcut may act on this target. Only the list side of
|
|
75
|
-
* the split owns them — inside the detail panel a keystroke belongs to the form.
|
|
76
|
-
*/
|
|
77
|
-
function isListShortcutTarget(target: HTMLElement | null, detailPanel: HTMLElement | null): boolean {
|
|
78
|
-
if (!target || target === document.body) return true;
|
|
79
|
-
return !detailPanel?.contains(target);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The list's share of the split, as a percentage, before anyone drags it.
|
|
84
|
-
*
|
|
85
|
-
* The list only has to identify a record — a title, a subtitle and a status
|
|
86
|
-
* chip — while the detail beside it carries the whole record and its rail. At
|
|
87
|
-
* 30% the list was taking width from the side that had four columns of fields
|
|
88
|
-
* to lay out; 26% still was, by about the width of one field.
|
|
89
|
-
*
|
|
90
|
-
* A default, not a constraint: {@link savePanelSize} remembers the drag per
|
|
91
|
-
* collection, so anyone who has already sized this list keeps their size. The
|
|
92
|
-
* drag floor is `minPanelSizePx`, and it holds below ~1100px of split — at that
|
|
93
|
-
* width this percentage is already the floor.
|
|
94
|
-
*/
|
|
95
|
-
const DEFAULT_PANEL_SIZE = 22;
|
|
96
|
-
|
|
97
|
-
function getSavedPanelSize(path: string): number {
|
|
98
|
-
try {
|
|
99
|
-
const saved = localStorage.getItem(`${PANEL_SIZE_KEY}_${path}`);
|
|
100
|
-
if (saved !== null) {
|
|
101
|
-
const val = parseFloat(saved);
|
|
102
|
-
if (!isNaN(val) && val > 0 && val < 100) return val;
|
|
103
|
-
}
|
|
104
|
-
} catch { /* ignore */ }
|
|
105
|
-
return DEFAULT_PANEL_SIZE;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function savePanelSize(path: string, size: number) {
|
|
109
|
-
try {
|
|
110
|
-
localStorage.setItem(`${PANEL_SIZE_KEY}_${path}`, size.toString());
|
|
111
|
-
} catch { /* ignore */ }
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Master-detail split view.
|
|
116
|
-
* Shows the list on the left and the entity edit view on the right.
|
|
117
|
-
*
|
|
118
|
-
* Animation approach:
|
|
119
|
-
* - The list always renders at full width.
|
|
120
|
-
* - When a detail opens, the list shrinks to `panelSize%` and the detail slides in.
|
|
121
|
-
* - On close, the reverse plays.
|
|
122
|
-
*
|
|
123
|
-
* State management:
|
|
124
|
-
* - The selected entity is driven by the URL path (e.g. /c/authors/14).
|
|
125
|
-
* `selectedEntityId` comes from props via RebaseRoute, NOT from internal state.
|
|
126
|
-
* - Clicking a entity navigates to /c/authors/{id} via the standard onEntityClick handler.
|
|
127
|
-
* - Closing the detail navigates back to /c/authors.
|
|
128
|
-
*/
|
|
129
|
-
export function SplitListView<M extends Record<string, unknown> = Record<string, unknown>>({
|
|
130
|
-
collection,
|
|
131
|
-
tableController,
|
|
132
|
-
onEntityClick: externalOnEntityClick,
|
|
133
|
-
onNewClick: externalOnNewClick,
|
|
134
|
-
selectionController,
|
|
135
|
-
selectionEnabled = true,
|
|
136
|
-
highlightedEntities,
|
|
137
|
-
emptyComponent,
|
|
138
|
-
onScroll,
|
|
139
|
-
initialScroll,
|
|
140
|
-
size = "m",
|
|
141
|
-
path,
|
|
142
|
-
parentCollectionSlugs, parentEntityIds,
|
|
143
|
-
selectedEntityId,
|
|
144
|
-
selectedTab,
|
|
145
|
-
toolbar,
|
|
146
|
-
children
|
|
147
|
-
}: SplitListViewProps<M>) {
|
|
148
|
-
const largeLayout = useLargeLayout();
|
|
149
|
-
const collectionRegistryController = useCollectionRegistryController();
|
|
150
|
-
const location = useLocation();
|
|
151
|
-
const isEditMode = location.pathname.endsWith("/edit") || location.pathname.split("/").pop() === "edit";
|
|
152
|
-
const navigate = useNavigate();
|
|
153
|
-
const urlController = useUrlController();
|
|
154
|
-
|
|
155
|
-
const showDetail = selectedEntityId !== undefined;
|
|
156
|
-
|
|
157
|
-
// ── Unsaved changes ──
|
|
158
|
-
// The detail form lives inside the split layout, so every way out of it
|
|
159
|
-
// (Escape, j/k, clicking another row, the browser back button) is a plain
|
|
160
|
-
// router navigation. A ref — not state — because the blocker predicate must
|
|
161
|
-
// observe the change synchronously, before the navigation it is guarding.
|
|
162
|
-
const dirty = useRef(false);
|
|
163
|
-
const detailPanelRef = useRef<HTMLDivElement>(null);
|
|
164
|
-
const setDirty = useCallback((modified: boolean) => {
|
|
165
|
-
dirty.current = modified;
|
|
166
|
-
}, []);
|
|
167
|
-
|
|
168
|
-
// The form remounts per entity, so its dirty state must not leak into the
|
|
169
|
-
// next one — and it has to be cleared here rather than left to the next
|
|
170
|
-
// form's own first report, because that form spends the load in a skeleton
|
|
171
|
-
// and a navigation during it would prompt about the record before it.
|
|
172
|
-
//
|
|
173
|
-
// On a *change* of record only, never on this view's own mount: a record
|
|
174
|
-
// arriving from full screen carries its edit back in and opens dirty, and
|
|
175
|
-
// the form says so from its first effect — which runs before this one, being
|
|
176
|
-
// a child's. Clearing unconditionally overwrote that report with `false`,
|
|
177
|
-
// and the way out of the split stopped asking about a live edit.
|
|
178
|
-
const previousEntityId = useRef(selectedEntityId);
|
|
179
|
-
useEffect(() => {
|
|
180
|
-
if (previousEntityId.current === selectedEntityId) return;
|
|
181
|
-
previousEntityId.current = selectedEntityId;
|
|
182
|
-
dirty.current = false;
|
|
183
|
-
}, [selectedEntityId]);
|
|
184
|
-
|
|
185
|
-
const blocker = useNavigationBlocker(useCallback(({
|
|
186
|
-
currentLocation,
|
|
187
|
-
nextLocation
|
|
188
|
-
}) => {
|
|
189
|
-
if (!dirty.current) return false;
|
|
190
|
-
if (currentLocation.pathname === nextLocation.pathname) return false;
|
|
191
|
-
// Side panel overlays (e.g. following a relation) render above the form
|
|
192
|
-
// and leave it mounted — nothing is lost in either direction.
|
|
193
|
-
const nextHash = nextLocation.hash;
|
|
194
|
-
if (nextHash === "#side" || nextHash === "#new_side") return false;
|
|
195
|
-
const currentHash = currentLocation.hash;
|
|
196
|
-
if (currentHash === "#side" || currentHash === "#new_side") return false;
|
|
197
|
-
return true;
|
|
198
|
-
}, []));
|
|
199
|
-
|
|
200
|
-
// Panel size state with persistence.
|
|
201
|
-
//
|
|
202
|
-
// Written on drag, not on mount. An effect that saved on mount stored
|
|
203
|
-
// {@link DEFAULT_PANEL_SIZE} under this collection's key the first time
|
|
204
|
-
// anyone opened the split — after which the default was frozen in every
|
|
205
|
-
// browser that had ever seen it, and changing it here reached nobody but a
|
|
206
|
-
// new visitor. Only a size someone chose is a size worth remembering.
|
|
207
|
-
const [panelSize, setPanelSize] = useState(() => getSavedPanelSize(path));
|
|
208
|
-
|
|
209
|
-
const handlePanelSizeChange = useCallback((size: number) => {
|
|
210
|
-
setPanelSize(size);
|
|
211
|
-
savePanelSize(path, size);
|
|
212
|
-
}, [path]);
|
|
213
|
-
|
|
214
|
-
// ── Animation state ──
|
|
215
|
-
// We track the "rendered" entity to keep the detail panel mounted during the exit animation.
|
|
216
|
-
const [renderedEntityId, setRenderedEntityId] = useState<string | number | undefined>(selectedEntityId);
|
|
217
|
-
const [animationPhase, setAnimationPhase] = useState<"idle" | "entering" | "entered" | "exiting">(
|
|
218
|
-
selectedEntityId !== undefined ? "entered" : "idle"
|
|
219
|
-
);
|
|
220
|
-
const animationTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
221
|
-
|
|
222
|
-
// Transition duration (ms) — keep in sync with CSS
|
|
223
|
-
const TRANSITION_DURATION = 150;
|
|
224
|
-
|
|
225
|
-
useEffect(() => {
|
|
226
|
-
if (animationTimer.current) {
|
|
227
|
-
clearTimeout(animationTimer.current);
|
|
228
|
-
animationTimer.current = null;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if (selectedEntityId !== undefined) {
|
|
232
|
-
// Opening or switching entity
|
|
233
|
-
setRenderedEntityId(selectedEntityId);
|
|
234
|
-
if (animationPhase === "idle" || animationPhase === "exiting") {
|
|
235
|
-
// Fresh open — trigger enter
|
|
236
|
-
setAnimationPhase("entering");
|
|
237
|
-
// Use requestAnimationFrame to ensure the "entering" class is painted
|
|
238
|
-
// before transitioning to "entered".
|
|
239
|
-
requestAnimationFrame(() => {
|
|
240
|
-
requestAnimationFrame(() => {
|
|
241
|
-
setAnimationPhase("entered");
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
// If already entered (switching entities), keep "entered"
|
|
246
|
-
} else {
|
|
247
|
-
// Closing
|
|
248
|
-
if (animationPhase === "entered" || animationPhase === "entering") {
|
|
249
|
-
setAnimationPhase("exiting");
|
|
250
|
-
animationTimer.current = setTimeout(() => {
|
|
251
|
-
setAnimationPhase("idle");
|
|
252
|
-
setRenderedEntityId(undefined);
|
|
253
|
-
}, TRANSITION_DURATION);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
return () => {
|
|
258
|
-
if (animationTimer.current) clearTimeout(animationTimer.current);
|
|
259
|
-
};
|
|
260
|
-
}, [selectedEntityId]); // Intentionally only depend on selectedEntityId
|
|
261
|
-
|
|
262
|
-
// Build a URL below this collection, preserving the active view mode.
|
|
263
|
-
const buildUrl = useCallback((subPath: string) => {
|
|
264
|
-
return withViewMode(urlController.buildUrlCollectionPath(subPath));
|
|
265
|
-
}, [urlController]);
|
|
266
|
-
|
|
267
|
-
// Close the detail panel: navigate back to the collection path
|
|
268
|
-
const handleCloseDetail = useCallback(() => {
|
|
269
|
-
navigate(buildUrl(path));
|
|
270
|
-
}, [navigate, buildUrl, path]);
|
|
271
|
-
|
|
272
|
-
// ── Keyboard navigation ──
|
|
273
|
-
const entityIds = useMemo(
|
|
274
|
-
() => tableController.data.map((e: Entity<M>) => e.id),
|
|
275
|
-
[tableController.data]
|
|
276
|
-
);
|
|
277
|
-
|
|
278
|
-
useEffect(() => {
|
|
279
|
-
const handleKeyDown = (e: KeyboardEvent) => {
|
|
280
|
-
const target = e.target as HTMLElement | null;
|
|
281
|
-
|
|
282
|
-
// Radix overlays own the keyboard while they are open — including Escape.
|
|
283
|
-
if (document.querySelector('[role="dialog"][data-state="open"]')) return;
|
|
284
|
-
|
|
285
|
-
if (e.key === "Escape") {
|
|
286
|
-
if (!selectedEntityId) return;
|
|
287
|
-
// First Escape leaves the field (which may also be dismissing its
|
|
288
|
-
// own dropdown), a second one closes the panel. Closing straight
|
|
289
|
-
// from a focused field would discard an in-progress edit.
|
|
290
|
-
if (isTextEntryTarget(target)) {
|
|
291
|
-
target?.blur();
|
|
292
|
-
e.preventDefault();
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
handleCloseDetail();
|
|
296
|
-
e.preventDefault();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Record navigation only belongs to the list side. Inside the detail
|
|
301
|
-
// panel these keys are the form's — arrows move between fields, and a
|
|
302
|
-
// bare letter is input for widgets that aren't native fields (rich
|
|
303
|
-
// text, code editors, comboboxes).
|
|
304
|
-
if (!isListShortcutTarget(target, detailPanelRef.current)) return;
|
|
305
|
-
if (isTextEntryTarget(target)) return;
|
|
306
|
-
|
|
307
|
-
// Arrow down / j → next entity
|
|
308
|
-
if ((e.key === "ArrowDown" || e.key === "j") && !e.metaKey && !e.ctrlKey) {
|
|
309
|
-
e.preventDefault();
|
|
310
|
-
if (entityIds.length === 0) return;
|
|
311
|
-
|
|
312
|
-
if (selectedEntityId === undefined) {
|
|
313
|
-
const firstEntity = tableController.data[0];
|
|
314
|
-
if (firstEntity) externalOnEntityClick?.(firstEntity);
|
|
315
|
-
} else {
|
|
316
|
-
const currentIndex = entityIds.indexOf(selectedEntityId);
|
|
317
|
-
if (currentIndex >= 0 && currentIndex < entityIds.length - 1) {
|
|
318
|
-
const nextEntity = tableController.data[currentIndex + 1];
|
|
319
|
-
if (nextEntity) externalOnEntityClick?.(nextEntity);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// Arrow up / k → previous entity
|
|
326
|
-
if ((e.key === "ArrowUp" || e.key === "k") && !e.metaKey && !e.ctrlKey) {
|
|
327
|
-
e.preventDefault();
|
|
328
|
-
if (entityIds.length === 0) return;
|
|
329
|
-
|
|
330
|
-
if (selectedEntityId === undefined) {
|
|
331
|
-
const lastEntity = tableController.data[tableController.data.length - 1];
|
|
332
|
-
if (lastEntity) externalOnEntityClick?.(lastEntity);
|
|
333
|
-
} else {
|
|
334
|
-
const currentIndex = entityIds.indexOf(selectedEntityId);
|
|
335
|
-
if (currentIndex > 0) {
|
|
336
|
-
const prevEntity = tableController.data[currentIndex - 1];
|
|
337
|
-
if (prevEntity) externalOnEntityClick?.(prevEntity);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// n → new entity
|
|
344
|
-
if (e.key === "n" && !e.metaKey && !e.ctrlKey && !e.altKey) {
|
|
345
|
-
externalOnNewClick?.();
|
|
346
|
-
e.preventDefault();
|
|
347
|
-
return;
|
|
348
|
-
}
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
352
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
353
|
-
}, [selectedEntityId, handleCloseDetail, externalOnEntityClick, externalOnNewClick, entityIds, tableController.data]);
|
|
354
|
-
|
|
355
|
-
const usedParentCollectionIds = parentCollectionSlugs ?? collectionRegistryController.getParentCollectionSlugs(path);
|
|
356
|
-
const usedParentEntityIds = parentEntityIds ?? collectionRegistryController.getParentEntityIds(path);
|
|
357
|
-
|
|
358
|
-
const isDetailVisible = animationPhase !== "idle";
|
|
359
|
-
|
|
360
|
-
// ── Unified Layout: animated split using ResizablePanels ──
|
|
361
|
-
|
|
362
|
-
const listPanel = (
|
|
363
|
-
<div
|
|
364
|
-
className={cls(
|
|
365
|
-
"flex flex-col h-full min-w-0 transition-all ease-out w-full",
|
|
366
|
-
(!largeLayout && isDetailVisible)
|
|
367
|
-
? "opacity-0 -translate-x-1/3 pointer-events-none"
|
|
368
|
-
: "opacity-100 translate-x-0"
|
|
369
|
-
)}
|
|
370
|
-
style={{ transitionDuration: `${TRANSITION_DURATION}ms` }}
|
|
371
|
-
>
|
|
372
|
-
{/* Toolbar stays fixed above the scrollable area */}
|
|
373
|
-
{toolbar}
|
|
374
|
-
{/* Scrollable content: title + insights + list rows */}
|
|
375
|
-
<div className="flex-1 overflow-y-auto overflow-x-hidden min-h-0">
|
|
376
|
-
{children}
|
|
377
|
-
</div>
|
|
378
|
-
</div>
|
|
379
|
-
);
|
|
380
|
-
|
|
381
|
-
const detailPanel = renderedEntityId !== undefined ? (
|
|
382
|
-
<div
|
|
383
|
-
ref={detailPanelRef}
|
|
384
|
-
className={cls(
|
|
385
|
-
"flex-1 flex flex-col min-w-0 h-full transition-all ease-out w-full",
|
|
386
|
-
animationPhase === "entered"
|
|
387
|
-
? "opacity-100 translate-x-0"
|
|
388
|
-
: (largeLayout ? "opacity-0 translate-x-8" : "opacity-0 translate-x-1/3")
|
|
389
|
-
)}
|
|
390
|
-
style={{ transitionDuration: `${TRANSITION_DURATION}ms` }}
|
|
391
|
-
>
|
|
392
|
-
<ErrorBoundary>
|
|
393
|
-
{collection.defaultEntityAction === "view" && !isEditMode
|
|
394
|
-
? <DetailViewBinding
|
|
395
|
-
key={String(renderedEntityId)}
|
|
396
|
-
path={path}
|
|
397
|
-
collection={collection as AdminCollection<Record<string, unknown>>}
|
|
398
|
-
entityId={renderedEntityId}
|
|
399
|
-
parentCollectionSlugs={usedParentCollectionIds}
|
|
400
|
-
parentEntityIds={usedParentEntityIds}
|
|
401
|
-
selectedTab={selectedTab}
|
|
402
|
-
layout="split"
|
|
403
|
-
onCloseRequest={handleCloseDetail}
|
|
404
|
-
onEditClick={() => {
|
|
405
|
-
navigate(buildUrl(`${path}/${renderedEntityId}/edit`));
|
|
406
|
-
}}
|
|
407
|
-
onTabChange={(params) => {
|
|
408
|
-
const newSelectedTab = params.selectedTab;
|
|
409
|
-
navigate(buildUrl(
|
|
410
|
-
newSelectedTab
|
|
411
|
-
? `${path}/${renderedEntityId}/${newSelectedTab}`
|
|
412
|
-
: `${path}/${renderedEntityId}`
|
|
413
|
-
));
|
|
414
|
-
}}
|
|
415
|
-
/>
|
|
416
|
-
: <EditViewBinding
|
|
417
|
-
key={String(renderedEntityId)}
|
|
418
|
-
path={path}
|
|
419
|
-
collection={collection as AdminCollection<Record<string, unknown>>}
|
|
420
|
-
entityId={renderedEntityId}
|
|
421
|
-
parentCollectionSlugs={usedParentCollectionIds}
|
|
422
|
-
parentEntityIds={usedParentEntityIds}
|
|
423
|
-
selectedTab={selectedTab}
|
|
424
|
-
layout="split"
|
|
425
|
-
// The ✕, and where "save and close" lands. A plain
|
|
426
|
-
// navigation: `useNavigationBlocker` above already
|
|
427
|
-
// stands between it and an unsaved edit, so the ✕ asks
|
|
428
|
-
// exactly what Escape and the browser's Back ask.
|
|
429
|
-
onCloseRequest={handleCloseDetail}
|
|
430
|
-
onValuesModified={setDirty}
|
|
431
|
-
onSaved={() => {
|
|
432
|
-
setDirty(false);
|
|
433
|
-
navigate(buildUrl(`${path}/${renderedEntityId}`), { replace: true });
|
|
434
|
-
}}
|
|
435
|
-
navigateBack={() => {
|
|
436
|
-
navigate(buildUrl(`${path}/${renderedEntityId}`));
|
|
437
|
-
}}
|
|
438
|
-
onTabChange={(params) => {
|
|
439
|
-
const newSelectedTab = params.selectedTab;
|
|
440
|
-
navigate(buildUrl(
|
|
441
|
-
newSelectedTab
|
|
442
|
-
? `${path}/${renderedEntityId}/${newSelectedTab}`
|
|
443
|
-
: `${path}/${renderedEntityId}`
|
|
444
|
-
));
|
|
445
|
-
}}
|
|
446
|
-
/>
|
|
447
|
-
}
|
|
448
|
-
</ErrorBoundary>
|
|
449
|
-
</div>
|
|
450
|
-
) : <></>;
|
|
451
|
-
|
|
452
|
-
// Closing the list is the full-screen entity route: the same `#full` the
|
|
453
|
-
// entity pane's expand button used, so there is one way to give the record
|
|
454
|
-
// the whole window and one way back out of it.
|
|
455
|
-
const openFullScreen = useCallback(() => {
|
|
456
|
-
if (selectedEntityId === undefined) return;
|
|
457
|
-
const suffix = isEditMode ? "/edit" : "";
|
|
458
|
-
navigate(`${buildUrl(`${path}/${selectedEntityId}${suffix}`)}#full`);
|
|
459
|
-
}, [navigate, buildUrl, path, selectedEntityId, isEditMode]);
|
|
460
|
-
|
|
461
|
-
const splitViewController = useMemo(() => ({
|
|
462
|
-
detailOpen: selectedEntityId !== undefined,
|
|
463
|
-
openFullScreen
|
|
464
|
-
}), [selectedEntityId, openFullScreen]);
|
|
465
|
-
|
|
466
|
-
return (
|
|
467
|
-
<SplitViewProvider value={splitViewController}>
|
|
468
|
-
<ResizablePanels
|
|
469
|
-
stacked={!largeLayout}
|
|
470
|
-
firstPanel={listPanel}
|
|
471
|
-
secondPanel={detailPanel}
|
|
472
|
-
showSecondPanel={isDetailVisible}
|
|
473
|
-
panelSizePercent={animationPhase === "entering" ? 100 : panelSize}
|
|
474
|
-
onPanelSizeChange={handlePanelSizeChange}
|
|
475
|
-
minPanelSizePx={240}
|
|
476
|
-
/>
|
|
477
|
-
|
|
478
|
-
<UnsavedChangesDialog
|
|
479
|
-
open={blocker?.state === "blocked"}
|
|
480
|
-
handleOk={() => {
|
|
481
|
-
dirty.current = false;
|
|
482
|
-
blocker?.proceed?.();
|
|
483
|
-
}}
|
|
484
|
-
handleCancel={() => blocker?.reset?.()}
|
|
485
|
-
body={<>You have unsaved changes in this <b>{collection.singularName ?? collection.name}</b>.</>}/>
|
|
486
|
-
</SplitViewProvider>
|
|
487
|
-
);
|
|
488
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import React, { useContext } from "react";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The enclosing master-detail split view, exposed to the list panel so it can
|
|
5
|
-
* carry the control that closes it.
|
|
6
|
-
*/
|
|
7
|
-
export type SplitViewController = {
|
|
8
|
-
/** Whether a record is open in the detail pane. */
|
|
9
|
-
detailOpen: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Close the list and leave the open record on its own, full screen. This is
|
|
12
|
-
* the existing full-screen entity route (`#full`), not a second mechanism.
|
|
13
|
-
*/
|
|
14
|
-
openFullScreen: () => void;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const SplitViewContext = React.createContext<SplitViewController | undefined>(undefined);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* The enclosing split view, or `undefined` when the component is not rendered
|
|
21
|
-
* inside one (a side panel, a dialog, a full-screen route).
|
|
22
|
-
*/
|
|
23
|
-
export function useSplitView(): SplitViewController | undefined {
|
|
24
|
-
return useContext(SplitViewContext);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function SplitViewProvider({
|
|
28
|
-
value,
|
|
29
|
-
children
|
|
30
|
-
}: { value: SplitViewController, children: React.ReactNode }) {
|
|
31
|
-
return <SplitViewContext.Provider value={value}>
|
|
32
|
-
{children}
|
|
33
|
-
</SplitViewContext.Provider>;
|
|
34
|
-
}
|