@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,297 +0,0 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
-
import type { EngineProperties, Property } from "@rebasepro/types";
|
|
3
|
-
import type { NavigationGroupMapping, AdminCollection } from "@rebasepro/cms-types";
|
|
4
|
-
import type {
|
|
5
|
-
CollectionsConfigController,
|
|
6
|
-
SaveCollectionParams,
|
|
7
|
-
UpdateCollectionParams,
|
|
8
|
-
DeleteCollectionParams,
|
|
9
|
-
SavePropertyParams,
|
|
10
|
-
DeletePropertyParams,
|
|
11
|
-
UpdatePropertiesOrderParams,
|
|
12
|
-
UpdateKanbanColumnsOrderParams,
|
|
13
|
-
} from "./types/config_controller";
|
|
14
|
-
import type { JsonCollectionStore, SerializableCollectionConfig } from "./serializable_types";
|
|
15
|
-
import { toSerializableCollectionConfig, toSerializableProperty, fromSerializableCollectionConfigs } from "./serializable_utils";
|
|
16
|
-
|
|
17
|
-
export interface UseJsonCollectionsConfigControllerOptions {
|
|
18
|
-
/**
|
|
19
|
-
* The store adapter for persisting/loading collections.
|
|
20
|
-
*/
|
|
21
|
-
store: JsonCollectionStore;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* If true, the configuration cannot be modified.
|
|
25
|
-
*/
|
|
26
|
-
readOnly?: boolean;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* If true, collections will be loaded from the store on mount.
|
|
30
|
-
* Defaults to true.
|
|
31
|
-
*/
|
|
32
|
-
autoLoad?: boolean;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* A `CollectionsConfigController` implementation that persists collection
|
|
37
|
-
* configurations as JSON via a pluggable `JsonCollectionStore` adapter.
|
|
38
|
-
*
|
|
39
|
-
* Use this when you want to store collection schemas in a database, API,
|
|
40
|
-
* localStorage, or any other JSON-compatible backend — as opposed to the
|
|
41
|
-
* default code-based persistence.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* ```tsx
|
|
45
|
-
* const store: JsonCollectionStore = {
|
|
46
|
-
* load: async () => { const res = await fetch('/api/schemas'); return res.json(); },
|
|
47
|
-
* save: async (slug, data) => { await fetch(`/api/schemas/${slug}`, { method: 'PUT', body: JSON.stringify(data) }); },
|
|
48
|
-
* delete: async (slug) => { await fetch(`/api/schemas/${slug}`, { method: 'DELETE' }); },
|
|
49
|
-
* };
|
|
50
|
-
*
|
|
51
|
-
* const configController = useJsonCollectionsConfigController({ store });
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export function useJsonCollectionsConfigController({
|
|
55
|
-
store,
|
|
56
|
-
readOnly = false,
|
|
57
|
-
autoLoad = true,
|
|
58
|
-
}: UseJsonCollectionsConfigControllerOptions): CollectionsConfigController {
|
|
59
|
-
const [collections, setCollections] = useState<AdminCollection[]>([]);
|
|
60
|
-
const [loading, setLoading] = useState(autoLoad);
|
|
61
|
-
const [navigationEntries, setNavigationEntries] = useState<NavigationGroupMapping[]>([]);
|
|
62
|
-
|
|
63
|
-
// Keep store ref stable to avoid stale closures in callbacks
|
|
64
|
-
const storeRef = useRef(store);
|
|
65
|
-
storeRef.current = store;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The current collections, readable outside a state updater.
|
|
69
|
-
*
|
|
70
|
-
* Three mutators used to compute their new value inside
|
|
71
|
-
* `setCollections(prev => …)` and persist from in there, which cost them
|
|
72
|
-
* both halves of a save: the promise they returned resolved before the
|
|
73
|
-
* store had answered, so a failed write reached the caller as a success,
|
|
74
|
-
* and a `setState` updater must be pure — under `StrictMode` React invokes
|
|
75
|
-
* it twice, so every one of those saves wrote to the store twice in
|
|
76
|
-
* development. Reading `prev` from a ref lets them do what
|
|
77
|
-
* `updatePropertiesOrder` already did: compute, set, then await.
|
|
78
|
-
*/
|
|
79
|
-
const collectionsRef = useRef<AdminCollection[]>([]);
|
|
80
|
-
const applyCollections = useCallback((next: AdminCollection[]) => {
|
|
81
|
-
collectionsRef.current = next;
|
|
82
|
-
setCollections(next);
|
|
83
|
-
}, []);
|
|
84
|
-
|
|
85
|
-
// ── Load on mount ─────────────────────────────────────────────────
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
if (!autoLoad) return;
|
|
88
|
-
let cancelled = false;
|
|
89
|
-
|
|
90
|
-
(async () => {
|
|
91
|
-
try {
|
|
92
|
-
const [serialized, navEntries] = await Promise.all([
|
|
93
|
-
storeRef.current.load(),
|
|
94
|
-
storeRef.current.loadNavigationEntries?.() ?? Promise.resolve([]),
|
|
95
|
-
]);
|
|
96
|
-
if (cancelled) return;
|
|
97
|
-
// Deserialized as a set: a relation's target is a slug, and a slug only
|
|
98
|
-
// resolves against the other collections it arrived with.
|
|
99
|
-
applyCollections(fromSerializableCollectionConfigs(serialized));
|
|
100
|
-
setNavigationEntries(navEntries);
|
|
101
|
-
} catch (e) {
|
|
102
|
-
console.error("useJsonCollectionsConfigController: failed to load collections", e);
|
|
103
|
-
} finally {
|
|
104
|
-
if (!cancelled) setLoading(false);
|
|
105
|
-
}
|
|
106
|
-
})();
|
|
107
|
-
|
|
108
|
-
return () => { cancelled = true; };
|
|
109
|
-
// `applyCollections` is `useCallback(…, [])`, so naming it here cannot
|
|
110
|
-
// re-run the mount effect — it is listed because a stable identity is a
|
|
111
|
-
// fact about today's code, not a reason to leave a dependency out.
|
|
112
|
-
}, [autoLoad, applyCollections]);
|
|
113
|
-
|
|
114
|
-
// ── Helpers ────────────────────────────────────────────────────────
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Update local state and persist a collection to the store.
|
|
118
|
-
*/
|
|
119
|
-
const persistCollection = useCallback(async (collection: AdminCollection) => {
|
|
120
|
-
const serializable = toSerializableCollectionConfig(collection);
|
|
121
|
-
await storeRef.current.save(collection.slug, serializable);
|
|
122
|
-
}, []);
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Find collection by id (slug).
|
|
126
|
-
*/
|
|
127
|
-
const getCollection = useCallback((id: string): AdminCollection => {
|
|
128
|
-
const found = collections.find(c => c.slug === id);
|
|
129
|
-
if (found) return found;
|
|
130
|
-
throw new Error(`Collection "${id}" not found`);
|
|
131
|
-
}, [collections]);
|
|
132
|
-
|
|
133
|
-
// ── CRUD operations ───────────────────────────────────────────────
|
|
134
|
-
|
|
135
|
-
const saveCollection = useCallback(async <M extends Record<string, unknown>>(
|
|
136
|
-
{ id, collectionData }: SaveCollectionParams<M>
|
|
137
|
-
) => {
|
|
138
|
-
const collection = collectionData as AdminCollection;
|
|
139
|
-
await persistCollection(collection);
|
|
140
|
-
const prev = collectionsRef.current;
|
|
141
|
-
const idx = prev.findIndex(c => c.slug === id);
|
|
142
|
-
if (idx >= 0) {
|
|
143
|
-
const next = [...prev];
|
|
144
|
-
next[idx] = collection;
|
|
145
|
-
applyCollections(next);
|
|
146
|
-
} else {
|
|
147
|
-
applyCollections([...prev, collection]);
|
|
148
|
-
}
|
|
149
|
-
}, [persistCollection, applyCollections]);
|
|
150
|
-
|
|
151
|
-
const updateCollection = useCallback(async <M extends Record<string, unknown>>(
|
|
152
|
-
{ id, collectionData, previousId }: UpdateCollectionParams<M>
|
|
153
|
-
) => {
|
|
154
|
-
const prev = collectionsRef.current;
|
|
155
|
-
const lookupId = previousId ?? id;
|
|
156
|
-
const idx = prev.findIndex(c => c.slug === lookupId);
|
|
157
|
-
if (idx < 0) return;
|
|
158
|
-
|
|
159
|
-
const merged = { ...prev[idx], ...collectionData } as AdminCollection;
|
|
160
|
-
const next = [...prev];
|
|
161
|
-
next[idx] = merged;
|
|
162
|
-
applyCollections(next);
|
|
163
|
-
|
|
164
|
-
await persistCollection(merged);
|
|
165
|
-
|
|
166
|
-
// If the slug changed, clean up the old entry in the store. After the
|
|
167
|
-
// save, not beside it: dropping the old key first and then failing to
|
|
168
|
-
// write the new one loses the collection outright.
|
|
169
|
-
if (previousId && previousId !== id) {
|
|
170
|
-
await storeRef.current.delete(previousId);
|
|
171
|
-
}
|
|
172
|
-
}, [persistCollection, applyCollections]);
|
|
173
|
-
|
|
174
|
-
const deleteCollection = useCallback(async ({ id }: DeleteCollectionParams) => {
|
|
175
|
-
await storeRef.current.delete(id);
|
|
176
|
-
applyCollections(collectionsRef.current.filter(c => c.slug !== id));
|
|
177
|
-
}, [applyCollections]);
|
|
178
|
-
|
|
179
|
-
const saveProperty = useCallback(async ({
|
|
180
|
-
path,
|
|
181
|
-
propertyKey,
|
|
182
|
-
property,
|
|
183
|
-
newPropertiesOrder,
|
|
184
|
-
}: SavePropertyParams) => {
|
|
185
|
-
const prev = collectionsRef.current;
|
|
186
|
-
const idx = prev.findIndex(c => c.slug === path);
|
|
187
|
-
if (idx < 0) return;
|
|
188
|
-
|
|
189
|
-
const collection = { ...prev[idx] };
|
|
190
|
-
collection.properties = {
|
|
191
|
-
...collection.properties,
|
|
192
|
-
[propertyKey]: property,
|
|
193
|
-
} as EngineProperties;
|
|
194
|
-
if (newPropertiesOrder) {
|
|
195
|
-
collection.propertiesOrder = newPropertiesOrder as typeof collection.propertiesOrder;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const next = [...prev];
|
|
199
|
-
next[idx] = collection as AdminCollection;
|
|
200
|
-
applyCollections(next);
|
|
201
|
-
|
|
202
|
-
await persistCollection(next[idx]);
|
|
203
|
-
}, [persistCollection, applyCollections]);
|
|
204
|
-
|
|
205
|
-
const deleteProperty = useCallback(async ({
|
|
206
|
-
path,
|
|
207
|
-
propertyKey,
|
|
208
|
-
newPropertiesOrder,
|
|
209
|
-
}: DeletePropertyParams) => {
|
|
210
|
-
const prev = collectionsRef.current;
|
|
211
|
-
const idx = prev.findIndex(c => c.slug === path);
|
|
212
|
-
if (idx < 0) return;
|
|
213
|
-
|
|
214
|
-
const collection = { ...prev[idx] };
|
|
215
|
-
const { [propertyKey]: _removed, ...remaining } = collection.properties;
|
|
216
|
-
collection.properties = remaining;
|
|
217
|
-
if (newPropertiesOrder) {
|
|
218
|
-
collection.propertiesOrder = newPropertiesOrder as typeof collection.propertiesOrder;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const next = [...prev];
|
|
222
|
-
next[idx] = collection as AdminCollection;
|
|
223
|
-
applyCollections(next);
|
|
224
|
-
|
|
225
|
-
await persistCollection(next[idx]);
|
|
226
|
-
}, [persistCollection, applyCollections]);
|
|
227
|
-
|
|
228
|
-
const updatePropertiesOrder = useCallback(async ({
|
|
229
|
-
collection,
|
|
230
|
-
newPropertiesOrder,
|
|
231
|
-
}: UpdatePropertiesOrderParams) => {
|
|
232
|
-
const updated = {
|
|
233
|
-
...collection,
|
|
234
|
-
propertiesOrder: newPropertiesOrder,
|
|
235
|
-
} as AdminCollection;
|
|
236
|
-
|
|
237
|
-
const prev = collectionsRef.current;
|
|
238
|
-
const idx = prev.findIndex(c => c.slug === collection.slug);
|
|
239
|
-
if (idx >= 0) {
|
|
240
|
-
const next = [...prev];
|
|
241
|
-
next[idx] = updated;
|
|
242
|
-
applyCollections(next);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
await persistCollection(updated);
|
|
246
|
-
}, [persistCollection, applyCollections]);
|
|
247
|
-
|
|
248
|
-
const updateKanbanColumnsOrder = useCallback(async ({
|
|
249
|
-
collection,
|
|
250
|
-
kanbanColumnProperty,
|
|
251
|
-
newColumnsOrder,
|
|
252
|
-
}: UpdateKanbanColumnsOrderParams) => {
|
|
253
|
-
// Kanban column order is stored in the enum order of the column property.
|
|
254
|
-
// For JSON persistence, we store it as-is — the view layer reads enum order.
|
|
255
|
-
// This is a no-op for now; the kanban order is determined by the enum
|
|
256
|
-
// definition on the property itself.
|
|
257
|
-
}, []);
|
|
258
|
-
|
|
259
|
-
const saveNavigationEntriesHandler = useCallback(async (entries: NavigationGroupMapping[]) => {
|
|
260
|
-
setNavigationEntries(entries);
|
|
261
|
-
if (storeRef.current.saveNavigationEntries) {
|
|
262
|
-
await storeRef.current.saveNavigationEntries(entries);
|
|
263
|
-
}
|
|
264
|
-
}, []);
|
|
265
|
-
|
|
266
|
-
// ── Return controller ─────────────────────────────────────────────
|
|
267
|
-
return useMemo<CollectionsConfigController>(() => ({
|
|
268
|
-
loading,
|
|
269
|
-
readOnly,
|
|
270
|
-
readOnlyReason: readOnly ? "Configuration is read-only." : undefined,
|
|
271
|
-
collections,
|
|
272
|
-
getCollection,
|
|
273
|
-
saveCollection,
|
|
274
|
-
updateCollection,
|
|
275
|
-
deleteCollection,
|
|
276
|
-
saveProperty,
|
|
277
|
-
deleteProperty,
|
|
278
|
-
updatePropertiesOrder,
|
|
279
|
-
updateKanbanColumnsOrder,
|
|
280
|
-
navigationEntries,
|
|
281
|
-
saveNavigationEntries: saveNavigationEntriesHandler,
|
|
282
|
-
}), [
|
|
283
|
-
loading,
|
|
284
|
-
readOnly,
|
|
285
|
-
collections,
|
|
286
|
-
getCollection,
|
|
287
|
-
saveCollection,
|
|
288
|
-
updateCollection,
|
|
289
|
-
deleteCollection,
|
|
290
|
-
saveProperty,
|
|
291
|
-
deleteProperty,
|
|
292
|
-
updatePropertiesOrder,
|
|
293
|
-
updateKanbanColumnsOrder,
|
|
294
|
-
navigationEntries,
|
|
295
|
-
saveNavigationEntriesHandler,
|
|
296
|
-
]);
|
|
297
|
-
}
|
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The plan-then-confirm flow, as a hook.
|
|
3
|
-
*
|
|
4
|
-
* Owns three things that belong together and nothing else: whether the backend
|
|
5
|
-
* can edit its schema, the plan for the change somebody is making, and the
|
|
6
|
-
* dialog they confirm it in. The config controller calls `reviewChange` and
|
|
7
|
-
* awaits it; everything about *how* the confirmation happens stays here.
|
|
8
|
-
*
|
|
9
|
-
* ## Why `reviewChange` returns a promise that can reject
|
|
10
|
-
*
|
|
11
|
-
* Because the editor needs to know. A save that was cancelled must not leave
|
|
12
|
-
* the form thinking it succeeded — the collection on screen would then differ
|
|
13
|
-
* from the one on disk, and the next save would be computed from the wrong
|
|
14
|
-
* `before`. Rejecting with {@link SchemaChangeCancelled} is how "the person
|
|
15
|
-
* said no" reaches the caller as an outcome rather than as silence.
|
|
16
|
-
*/
|
|
17
|
-
import React, { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
18
|
-
import { lazyChunk } from "@rebasepro/ui";
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
createLiveSchemaClient,
|
|
22
|
-
LiveSchemaError,
|
|
23
|
-
SchemaChangeCancelled,
|
|
24
|
-
type LiveSchemaClient,
|
|
25
|
-
type LiveSchemaPlan,
|
|
26
|
-
type LiveSchemaResult,
|
|
27
|
-
type LiveSchemaStatus,
|
|
28
|
-
type ProposedCollectionChange
|
|
29
|
-
} from "./liveSchemaClient";
|
|
30
|
-
|
|
31
|
-
// Re-exported so the hook stays the one import a caller needs.
|
|
32
|
-
export { SchemaChangeCancelled, isSchemaChangeCancelled } from "./liveSchemaClient";
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Loaded when a change is actually being reviewed, not before.
|
|
36
|
-
*
|
|
37
|
-
* This hook is reached from the collections config controller, which is
|
|
38
|
-
* constructed on every admin boot — so a static import would put the dialog and
|
|
39
|
-
* the `@rebasepro/ui` surface it draws on into the **eager** bundle: everything
|
|
40
|
-
* a browser downloads before the login screen paints. It cost 14 kB there, for
|
|
41
|
-
* a dialog most sessions never open. The bundle budget caught it.
|
|
42
|
-
*/
|
|
43
|
-
const SchemaChangeDialog = lazyChunk(() =>
|
|
44
|
-
import("./ui/collection_editor/SchemaChangeDialog")
|
|
45
|
-
.then(m => ({ default: m.SchemaChangeDialog }))
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
export interface UseLiveSchemaEditingOptions {
|
|
49
|
-
/** Base for the routes, e.g. `https://api.example.com/api/admin/schema`. */
|
|
50
|
-
baseUrl: string;
|
|
51
|
-
getAuthToken?: () => Promise<string | null> | string | null;
|
|
52
|
-
/**
|
|
53
|
-
* Identity of the signed-in user.
|
|
54
|
-
*
|
|
55
|
-
* Only used to re-ask: whether this backend will accept a schema change
|
|
56
|
-
* depends on who is asking, and the answer to an anonymous probe does not
|
|
57
|
-
* survive a sign-in.
|
|
58
|
-
*/
|
|
59
|
-
authKey?: string | null;
|
|
60
|
-
/**
|
|
61
|
-
* Write the collection source and leave the database alone — what the
|
|
62
|
-
* editor did before this existed. Offered in the dialog when a change is
|
|
63
|
-
* refused, so a dev can still delete a field from a collection they are
|
|
64
|
-
* designing. Omit it and the fallback is not offered.
|
|
65
|
-
*/
|
|
66
|
-
writeSourceOnly?: (change: ProposedCollectionChange) => Promise<void>;
|
|
67
|
-
/** Swappable for the tests, which have no server. */
|
|
68
|
-
client?: LiveSchemaClient;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface PendingChange {
|
|
72
|
-
change: ProposedCollectionChange;
|
|
73
|
-
resolve: () => void;
|
|
74
|
-
reject: (err: Error) => void;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface LiveSchemaEditing {
|
|
78
|
-
/** `undefined` until the backend has answered. For rendering. */
|
|
79
|
-
status?: LiveSchemaStatus;
|
|
80
|
-
/**
|
|
81
|
-
* The same answer, for deciding.
|
|
82
|
-
*
|
|
83
|
-
* `status` is undefined for one round trip after mount, and a caller that
|
|
84
|
-
* read it to choose a code path would take the "not available" branch for
|
|
85
|
-
* that window — so a save issued quickly after a page load would silently
|
|
86
|
-
* skip the confirmation and write source only, while the same save a second
|
|
87
|
-
* later would not. Timing-dependent behaviour with no visible difference is
|
|
88
|
-
* the worst shape this could have.
|
|
89
|
-
*
|
|
90
|
-
* Resolves once, cached; never rejects, because every way of failing to get
|
|
91
|
-
* an answer means the same thing to whoever is deciding.
|
|
92
|
-
*/
|
|
93
|
-
ready: () => Promise<LiveSchemaStatus>;
|
|
94
|
-
/**
|
|
95
|
-
* Plan the change, show it, and settle when the person has decided.
|
|
96
|
-
*
|
|
97
|
-
* Resolves once the change has been applied — or written source-only, if
|
|
98
|
-
* they chose that. Rejects with {@link SchemaChangeCancelled} if they
|
|
99
|
-
* closed the dialog, and with the underlying error if planning or applying
|
|
100
|
-
* failed in a way they did not choose.
|
|
101
|
-
*/
|
|
102
|
-
reviewChange: (change: ProposedCollectionChange) => Promise<void>;
|
|
103
|
-
/** Render this once, high enough that a dialog over the editor is not clipped. */
|
|
104
|
-
dialog: React.ReactNode;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function useLiveSchemaEditing(options: UseLiveSchemaEditingOptions): LiveSchemaEditing {
|
|
108
|
-
const { baseUrl, authKey, writeSourceOnly } = options;
|
|
109
|
-
|
|
110
|
-
const optionsRef = useRef(options);
|
|
111
|
-
optionsRef.current = options;
|
|
112
|
-
|
|
113
|
-
const client = useMemo(
|
|
114
|
-
() => options.client ?? createLiveSchemaClient({
|
|
115
|
-
baseUrl,
|
|
116
|
-
getAuthToken: () => optionsRef.current.getAuthToken?.() ?? null
|
|
117
|
-
}),
|
|
118
|
-
// `client` is either supplied once by a test or built from the URL. The
|
|
119
|
-
// token getter is read through the ref so a new closure on every render
|
|
120
|
-
// does not rebuild the client underneath an in-flight request.
|
|
121
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
122
|
-
[baseUrl, options.client]
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const [status, setStatus] = useState<LiveSchemaStatus | undefined>();
|
|
126
|
-
const [pending, setPending] = useState<PendingChange | undefined>();
|
|
127
|
-
const [plan, setPlan] = useState<LiveSchemaPlan | undefined>();
|
|
128
|
-
const [planError, setPlanError] = useState<string | undefined>();
|
|
129
|
-
const [result, setResult] = useState<LiveSchemaResult | undefined>();
|
|
130
|
-
const [applying, setApplying] = useState(false);
|
|
131
|
-
const [applyError, setApplyError] = useState<string | undefined>();
|
|
132
|
-
|
|
133
|
-
// The in-flight probe, so `ready()` can await the same one the effect
|
|
134
|
-
// started rather than issuing a second. Keyed by client+authKey the same way
|
|
135
|
-
// the effect is: a sign-in changes the answer, so it has to be re-asked.
|
|
136
|
-
// `undefined` passed explicitly: React 19's `useRef` takes no zero-argument
|
|
137
|
-
// overload, and omitting it is an error rather than a default.
|
|
138
|
-
const probe = useRef<{ key: unknown[]; promise: Promise<LiveSchemaStatus> } | undefined>(undefined);
|
|
139
|
-
|
|
140
|
-
/** Which review a plan response belongs to. See `reviewChange`. */
|
|
141
|
-
const reviewToken = useRef(0);
|
|
142
|
-
|
|
143
|
-
const ready = useCallback((): Promise<LiveSchemaStatus> => {
|
|
144
|
-
const key = [client, authKey];
|
|
145
|
-
const current = probe.current;
|
|
146
|
-
if (!current || current.key[0] !== key[0] || current.key[1] !== key[1]) {
|
|
147
|
-
probe.current = { key, promise: client.status() };
|
|
148
|
-
}
|
|
149
|
-
return probe.current!.promise;
|
|
150
|
-
}, [client, authKey]);
|
|
151
|
-
|
|
152
|
-
useEffect(() => {
|
|
153
|
-
let cancelled = false;
|
|
154
|
-
void ready().then(answer => {
|
|
155
|
-
if (!cancelled) setStatus(answer);
|
|
156
|
-
});
|
|
157
|
-
return () => { cancelled = true; };
|
|
158
|
-
}, [ready]);
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Ask what the change would do, and ignore an answer that arrives late.
|
|
162
|
-
*
|
|
163
|
-
* Separate from `reviewChange` so it can be issued *again* without starting
|
|
164
|
-
* a new review: a plan that failed on a dropped connection should cost a
|
|
165
|
-
* click, not the whole wizard — the person has already filled in the form,
|
|
166
|
-
* and making them do it twice for a transient failure is the kind of thing
|
|
167
|
-
* that teaches people to distrust the preview.
|
|
168
|
-
*/
|
|
169
|
-
const requestPlan = useCallback(async (change: ProposedCollectionChange) => {
|
|
170
|
-
// Identifies the review a response belongs to. A plan that arrives after
|
|
171
|
-
// its review was replaced must not be shown: the dialog would describe
|
|
172
|
-
// the *previous* change while the reader believes it describes this one.
|
|
173
|
-
const token = ++reviewToken.current;
|
|
174
|
-
try {
|
|
175
|
-
const answer = await client.plan(change);
|
|
176
|
-
if (token === reviewToken.current) setPlan(answer);
|
|
177
|
-
} catch (err: unknown) {
|
|
178
|
-
if (token !== reviewToken.current) return;
|
|
179
|
-
setPlanError(
|
|
180
|
-
err instanceof LiveSchemaError || err instanceof Error
|
|
181
|
-
? err.message
|
|
182
|
-
: String(err)
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
}, [client]);
|
|
186
|
-
|
|
187
|
-
const onRetry = useCallback(() => {
|
|
188
|
-
if (!pending) return;
|
|
189
|
-
setPlanError(undefined);
|
|
190
|
-
setPlan(undefined);
|
|
191
|
-
void requestPlan(pending.change);
|
|
192
|
-
}, [pending, requestPlan]);
|
|
193
|
-
|
|
194
|
-
const clear = useCallback(() => {
|
|
195
|
-
setPending(undefined);
|
|
196
|
-
setPlan(undefined);
|
|
197
|
-
setPlanError(undefined);
|
|
198
|
-
setResult(undefined);
|
|
199
|
-
setApplyError(undefined);
|
|
200
|
-
setApplying(false);
|
|
201
|
-
}, []);
|
|
202
|
-
|
|
203
|
-
const reviewChange = useCallback((change: ProposedCollectionChange) => {
|
|
204
|
-
return new Promise<void>((resolve, reject) => {
|
|
205
|
-
// A second review while one is open — a double-clicked save —
|
|
206
|
-
// replaces the pending one, and the one it replaces has to be
|
|
207
|
-
// settled. `setPending` used to overwrite `resolve`/`reject` with
|
|
208
|
-
// nobody left holding them, so the first caller's promise never
|
|
209
|
-
// settled at all and the editor's save simply never returned.
|
|
210
|
-
setPending(previous => {
|
|
211
|
-
previous?.reject(new SchemaChangeCancelled());
|
|
212
|
-
return { change, resolve, reject };
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
// Identifies the review a response belongs to. A plan that arrives
|
|
216
|
-
// after its review was replaced must not be shown: the dialog would
|
|
217
|
-
// describe the *previous* change while the reader believes it
|
|
218
|
-
// describes this one, and the SQL on screen would be for something
|
|
219
|
-
// they are not confirming.
|
|
220
|
-
setPlan(undefined);
|
|
221
|
-
setPlanError(undefined);
|
|
222
|
-
setResult(undefined);
|
|
223
|
-
setApplyError(undefined);
|
|
224
|
-
setApplying(false);
|
|
225
|
-
|
|
226
|
-
void requestPlan(change);
|
|
227
|
-
});
|
|
228
|
-
// `client` is not listed: this no longer touches it directly, and
|
|
229
|
-
// `requestPlan` already carries that dependency.
|
|
230
|
-
}, [requestPlan]);
|
|
231
|
-
|
|
232
|
-
const onConfirm = useCallback(() => {
|
|
233
|
-
if (!pending) return;
|
|
234
|
-
setApplying(true);
|
|
235
|
-
setApplyError(undefined);
|
|
236
|
-
void client.apply(pending.change).then(
|
|
237
|
-
answer => {
|
|
238
|
-
setResult(answer);
|
|
239
|
-
setApplying(false);
|
|
240
|
-
// Resolved here, not on close. The change has happened, and the
|
|
241
|
-
// dialog is now a receipt somebody may read for as long as they
|
|
242
|
-
// like — holding the caller open until they close it would
|
|
243
|
-
// leave the editor mid-save for no reason.
|
|
244
|
-
pending.resolve();
|
|
245
|
-
setPending(undefined);
|
|
246
|
-
},
|
|
247
|
-
(err: unknown) => {
|
|
248
|
-
setApplying(false);
|
|
249
|
-
setApplyError(err instanceof Error ? err.message : String(err));
|
|
250
|
-
}
|
|
251
|
-
);
|
|
252
|
-
}, [client, pending]);
|
|
253
|
-
|
|
254
|
-
const onSourceOnly = useCallback(() => {
|
|
255
|
-
if (!pending || !writeSourceOnly) return;
|
|
256
|
-
setApplying(true);
|
|
257
|
-
setApplyError(undefined);
|
|
258
|
-
const settle = pending;
|
|
259
|
-
void writeSourceOnly(settle.change).then(
|
|
260
|
-
() => { clear(); settle.resolve(); },
|
|
261
|
-
(err: unknown) => {
|
|
262
|
-
setApplying(false);
|
|
263
|
-
setApplyError(err instanceof Error ? err.message : String(err));
|
|
264
|
-
}
|
|
265
|
-
);
|
|
266
|
-
}, [pending, writeSourceOnly, clear]);
|
|
267
|
-
|
|
268
|
-
const onClose = useCallback(() => {
|
|
269
|
-
// Escape and the backdrop reach this too, and the Cancel *button* is the
|
|
270
|
-
// only one of the three that was disabled while applying. Closing
|
|
271
|
-
// mid-apply rejected the caller as cancelled while the commit and the
|
|
272
|
-
// DDL carried on — reporting that nothing happened while something did,
|
|
273
|
-
// which is the exact failure this whole feature exists to end.
|
|
274
|
-
if (applying) return;
|
|
275
|
-
|
|
276
|
-
const settle = pending;
|
|
277
|
-
clear();
|
|
278
|
-
// A dialog showing a result has already resolved; closing it is not a
|
|
279
|
-
// cancellation of anything.
|
|
280
|
-
if (settle && !result) settle.reject(new SchemaChangeCancelled());
|
|
281
|
-
}, [applying, pending, result, clear]);
|
|
282
|
-
|
|
283
|
-
// Not even a Suspense boundary until there is something to review — the
|
|
284
|
-
// chunk is fetched by the first `reviewChange`, and an admin session that
|
|
285
|
-
// never edits a collection never pays for it.
|
|
286
|
-
const open = Boolean(pending) || Boolean(result);
|
|
287
|
-
const dialog = open
|
|
288
|
-
? (
|
|
289
|
-
<Suspense fallback={null}>
|
|
290
|
-
<SchemaChangeDialog
|
|
291
|
-
open={open}
|
|
292
|
-
collectionId={pending?.change.collectionId ?? ""}
|
|
293
|
-
plan={plan}
|
|
294
|
-
planError={planError}
|
|
295
|
-
result={result}
|
|
296
|
-
applying={applying}
|
|
297
|
-
applyError={applyError}
|
|
298
|
-
onConfirm={onConfirm}
|
|
299
|
-
onRetry={planError ? onRetry : undefined}
|
|
300
|
-
onSourceOnly={writeSourceOnly ? onSourceOnly : undefined}
|
|
301
|
-
onClose={onClose}
|
|
302
|
-
applyRefusedBecause={
|
|
303
|
-
status && !status.canApply ? status.applyRefusedBecause : undefined
|
|
304
|
-
}
|
|
305
|
-
target={status && {
|
|
306
|
-
repository: status.repository,
|
|
307
|
-
branch: status.branch
|
|
308
|
-
}}
|
|
309
|
-
/>
|
|
310
|
-
</Suspense>
|
|
311
|
-
)
|
|
312
|
-
: null;
|
|
313
|
-
|
|
314
|
-
return { status, ready, reviewChange, dialog };
|
|
315
|
-
}
|