@firecms/core 3.0.0-canary.18 → 3.0.0-canary.180
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 +3 -3
- package/dist/app/AppBar.d.ts +12 -0
- package/dist/app/Drawer.d.ts +16 -0
- package/dist/app/Scaffold.d.ts +30 -0
- package/dist/app/index.d.ts +4 -0
- package/dist/app/useApp.d.ts +16 -0
- package/dist/components/ArrayContainer.d.ts +23 -6
- package/dist/components/CircularProgressCenter.d.ts +1 -1
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +13 -13
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +22 -6
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
- package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +3 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +7 -4
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +16 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityCollectionView/utils.d.ts +3 -0
- package/dist/components/EntityPreview.d.ts +5 -4
- package/dist/components/ErrorView.d.ts +1 -1
- package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
- package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
- package/dist/components/PropertyConfigBadge.d.ts +2 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
- package/dist/components/ReferenceWidget.d.ts +3 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +13 -3
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
- package/dist/components/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +28 -12
- package/dist/components/VirtualTable/types.d.ts +3 -3
- package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -3
- package/dist/components/common/index.d.ts +2 -1
- package/dist/components/common/table_height.d.ts +5 -0
- package/dist/components/common/types.d.ts +4 -6
- package/dist/components/common/useColumnsIds.d.ts +3 -1
- package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +13 -2
- package/dist/components/common/useDebouncedCallback.d.ts +1 -0
- package/dist/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/components/index.d.ts +4 -2
- package/dist/contexts/BreacrumbsContext.d.ts +8 -0
- package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
- package/dist/core/DefaultDrawer.d.ts +19 -0
- package/dist/core/DrawerNavigationItem.d.ts +10 -0
- package/dist/core/EntityEditView.d.ts +41 -9
- package/dist/core/FireCMS.d.ts +2 -2
- package/dist/core/FireCMSRouter.d.ts +4 -0
- package/dist/core/NavigationRoutes.d.ts +2 -3
- package/dist/core/index.d.ts +4 -4
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/components/FieldHelperText.d.ts +3 -3
- package/dist/form/components/LabelWithIcon.d.ts +1 -1
- package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
- package/dist/form/components/StorageItemPreview.d.ts +4 -4
- package/dist/form/components/index.d.ts +1 -1
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
- package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +3 -5
- package/dist/form/useClearRestoreValue.d.ts +2 -2
- package/dist/hooks/data/delete.d.ts +4 -4
- package/dist/hooks/data/save.d.ts +4 -5
- package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +4 -3
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useAuthController.d.ts +1 -1
- package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
- package/dist/hooks/useBuildNavigationController.d.ts +3 -5
- package/dist/hooks/useFireCMSContext.d.ts +1 -1
- package/dist/hooks/useProjectLog.d.ts +8 -2
- package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
- package/dist/hooks/useValidateAuthenticator.d.ts +4 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +21537 -14243
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +23973 -588
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +1 -16
- package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
- package/dist/preview/PropertyPreviewProps.d.ts +6 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +3 -2
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/preview/util.d.ts +3 -3
- package/dist/routes/CustomCMSRoute.d.ts +4 -0
- package/dist/routes/FireCMSRoute.d.ts +1 -0
- package/dist/routes/HomePageRoute.d.ts +3 -0
- package/dist/types/auth.d.ts +8 -10
- package/dist/types/collections.d.ts +71 -22
- package/dist/types/datasource.d.ts +52 -36
- package/dist/types/dialogs_controller.d.ts +7 -3
- package/dist/types/entities.d.ts +7 -2
- package/dist/types/entity_actions.d.ts +28 -4
- package/dist/types/entity_callbacks.d.ts +16 -16
- package/dist/types/entity_overrides.d.ts +2 -2
- package/dist/types/export_import.d.ts +4 -4
- package/dist/types/fields.d.ts +66 -42
- package/dist/types/firecms.d.ts +6 -2
- package/dist/types/firecms_context.d.ts +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/navigation.d.ts +31 -14
- package/dist/types/permissions.d.ts +4 -4
- package/dist/types/plugins.d.ts +23 -12
- package/dist/types/properties.d.ts +51 -23
- package/dist/types/property_config.d.ts +0 -2
- package/dist/types/side_dialogs_controller.d.ts +10 -0
- package/dist/types/side_entity_controller.d.ts +1 -1
- package/dist/types/storage.d.ts +86 -3
- package/dist/types/user.d.ts +1 -0
- package/dist/util/builders.d.ts +3 -3
- package/dist/util/entities.d.ts +3 -3
- package/dist/util/entity_actions.d.ts +2 -0
- package/dist/util/entity_cache.d.ts +23 -0
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icon_synonyms.d.ts +1 -98
- package/dist/util/icons.d.ts +6 -3
- package/dist/util/index.d.ts +2 -0
- package/dist/util/navigation_from_path.d.ts +5 -1
- package/dist/util/navigation_utils.d.ts +14 -3
- package/dist/util/objects.d.ts +2 -1
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/plurals.d.ts +0 -2
- package/dist/util/property_utils.d.ts +3 -3
- package/dist/util/resolutions.d.ts +30 -16
- package/dist/util/storage.d.ts +23 -2
- package/dist/util/useStorageUploadController.d.ts +3 -3
- package/package.json +61 -48
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +24 -0
- package/src/app/Scaffold.tsx +243 -0
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +32 -0
- package/src/components/ArrayContainer.tsx +126 -40
- package/src/components/CircularProgressCenter.tsx +2 -2
- package/src/components/ClearFilterSortButton.tsx +41 -0
- package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +3 -3
- package/src/components/DeleteEntityDialog.tsx +10 -19
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +54 -37
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +38 -31
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +30 -9
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +47 -39
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +30 -16
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +19 -17
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +31 -36
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +36 -34
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +84 -77
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +206 -112
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +20 -7
- package/src/components/EntityCollectionView/utils.ts +19 -0
- package/src/components/EntityPreview.tsx +62 -52
- package/src/components/EntityView.tsx +10 -10
- package/src/components/ErrorView.tsx +4 -4
- package/src/components/HomePage/DefaultHomePage.tsx +26 -19
- package/src/components/HomePage/FavouritesView.tsx +6 -11
- package/src/components/HomePage/NavigationCard.tsx +3 -3
- package/src/components/HomePage/NavigationCardBinding.tsx +5 -10
- package/src/components/HomePage/NavigationGroup.tsx +2 -2
- package/src/components/HomePage/SmallNavigationCard.tsx +5 -6
- package/src/components/NotFoundPage.tsx +2 -2
- package/src/components/PropertyConfigBadge.tsx +9 -3
- package/src/components/PropertyIdCopyTooltip.tsx +47 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +19 -13
- package/src/components/ReferenceWidget.tsx +21 -11
- package/src/components/SearchIconsView.tsx +10 -7
- package/src/components/SelectableTable/SelectableTable.tsx +27 -12
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +25 -8
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +36 -12
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +92 -23
- package/src/components/UnsavedChangesDialog.tsx +42 -0
- package/src/components/VirtualTable/VirtualTable.tsx +96 -48
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
- package/src/components/VirtualTable/VirtualTableHeader.tsx +10 -10
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
- package/src/components/VirtualTable/VirtualTableProps.tsx +33 -14
- package/src/components/VirtualTable/VirtualTableRow.tsx +5 -6
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +5 -5
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +3 -2
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
- package/src/components/VirtualTable/types.tsx +2 -3
- package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +33 -40
- package/src/components/common/index.ts +2 -1
- package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
- package/src/components/common/types.tsx +4 -6
- package/src/components/common/useColumnsIds.tsx +24 -3
- package/src/components/common/useDataSourceTableController.tsx +420 -0
- package/src/components/common/useDebouncedCallback.tsx +20 -0
- package/src/components/common/useScrollRestoration.tsx +68 -0
- package/src/components/common/useTableSearchHelper.ts +53 -12
- package/src/components/index.tsx +4 -2
- package/src/contexts/BreacrumbsContext.tsx +38 -0
- package/src/contexts/DialogsProvider.tsx +5 -4
- package/src/contexts/SnackbarProvider.tsx +2 -0
- package/src/core/DefaultAppBar.tsx +201 -0
- package/src/core/DefaultDrawer.tsx +185 -0
- package/src/core/DrawerNavigationItem.tsx +66 -0
- package/src/core/EntityEditView.tsx +1001 -213
- package/src/core/EntitySidePanel.tsx +80 -17
- package/src/core/FireCMS.tsx +56 -49
- package/src/core/FireCMSRouter.tsx +17 -0
- package/src/core/NavigationRoutes.tsx +20 -34
- package/src/core/SideDialogs.tsx +12 -6
- package/src/core/field_configs.tsx +11 -12
- package/src/core/index.tsx +6 -5
- package/src/form/PropertyFieldBinding.tsx +85 -44
- package/src/form/components/CustomIdField.tsx +6 -2
- package/src/form/components/FieldHelperText.tsx +4 -4
- package/src/form/components/LabelWithIcon.tsx +30 -19
- package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
- package/src/form/components/StorageItemPreview.tsx +22 -12
- package/src/form/components/StorageUploadProgress.tsx +3 -4
- package/src/form/components/index.tsx +1 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +31 -17
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +47 -35
- package/src/form/field_bindings/BlockFieldBinding.tsx +56 -34
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -14
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +60 -51
- package/src/form/field_bindings/MapFieldBinding.tsx +72 -53
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
- package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +11 -16
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +42 -31
- package/src/form/field_bindings/RepeatFieldBinding.tsx +56 -35
- package/src/form/field_bindings/SelectFieldBinding.tsx +22 -14
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +37 -47
- package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
- package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
- package/src/form/index.tsx +4 -9
- package/src/form/useClearRestoreValue.tsx +2 -2
- package/src/form/validation.ts +1 -17
- package/src/hooks/data/delete.ts +6 -5
- package/src/hooks/data/save.ts +13 -9
- package/src/hooks/data/useCollectionFetch.tsx +3 -3
- package/src/hooks/data/useDataSource.tsx +11 -3
- package/src/hooks/data/useEntityFetch.tsx +10 -6
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useAuthController.tsx +1 -1
- package/src/hooks/useBreadcrumbsController.tsx +31 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +150 -50
- package/src/hooks/useFireCMSContext.tsx +5 -5
- package/src/hooks/useLargeLayout.tsx +0 -35
- package/src/hooks/useProjectLog.tsx +32 -10
- package/src/hooks/useResolvedNavigationFrom.tsx +10 -12
- package/src/hooks/useValidateAuthenticator.tsx +17 -37
- package/src/index.ts +1 -0
- package/src/internal/useBuildDataSource.ts +72 -82
- package/src/internal/useBuildSideDialogsController.tsx +4 -2
- package/src/internal/useBuildSideEntityController.tsx +230 -70
- package/src/internal/useUnsavedChangesDialog.tsx +127 -91
- package/src/preview/PropertyPreview.tsx +13 -20
- package/src/preview/PropertyPreviewProps.tsx +7 -1
- package/src/preview/components/BooleanPreview.tsx +2 -2
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +2 -2
- package/src/preview/components/ImagePreview.tsx +25 -36
- package/src/preview/components/ReferencePreview.tsx +22 -33
- package/src/preview/components/StorageThumbnail.tsx +5 -1
- package/src/preview/components/UrlComponentPreview.tsx +44 -11
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -3
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -3
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -2
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -5
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -5
- package/src/preview/property_previews/MapPropertyPreview.tsx +9 -9
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
- package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
- package/src/preview/util.ts +10 -10
- package/src/routes/CustomCMSRoute.tsx +21 -0
- package/src/routes/FireCMSRoute.tsx +230 -0
- package/src/routes/HomePageRoute.tsx +17 -0
- package/src/types/auth.tsx +9 -13
- package/src/types/collections.ts +87 -27
- package/src/types/customization_controller.tsx +0 -1
- package/src/types/datasource.ts +61 -43
- package/src/types/dialogs_controller.tsx +7 -3
- package/src/types/entities.ts +12 -2
- package/src/types/entity_actions.tsx +32 -7
- package/src/types/entity_callbacks.ts +18 -18
- package/src/types/entity_overrides.tsx +2 -2
- package/src/types/export_import.ts +4 -4
- package/src/types/fields.tsx +72 -46
- package/src/types/firecms.tsx +7 -2
- package/src/types/firecms_context.tsx +1 -1
- package/src/types/index.ts +0 -1
- package/src/types/navigation.ts +37 -18
- package/src/types/permissions.ts +5 -5
- package/src/types/plugins.tsx +25 -14
- package/src/types/properties.ts +59 -24
- package/src/types/property_config.tsx +0 -2
- package/src/types/side_dialogs_controller.tsx +13 -0
- package/src/types/side_entity_controller.tsx +1 -1
- package/src/types/storage.ts +94 -3
- package/src/types/user.ts +2 -0
- package/src/util/builders.ts +10 -8
- package/src/util/entities.ts +9 -6
- package/src/util/entity_actions.ts +28 -0
- package/src/util/entity_cache.ts +196 -0
- package/src/util/enums.ts +1 -1
- package/src/util/icon_list.ts +16 -10
- package/src/util/icon_synonyms.ts +3 -100
- package/src/util/icons.tsx +17 -7
- package/src/util/index.ts +2 -0
- package/src/util/join_collections.ts +3 -0
- package/src/util/make_properties_editable.ts +13 -5
- package/src/util/navigation_from_path.ts +10 -2
- package/src/util/navigation_utils.ts +59 -7
- package/src/util/objects.ts +45 -28
- package/src/util/parent_references_from_path.ts +3 -3
- package/src/util/permissions.ts +9 -8
- package/src/util/plurals.ts +0 -2
- package/src/util/property_utils.tsx +11 -4
- package/src/util/references.ts +11 -2
- package/src/util/resolutions.ts +79 -46
- package/src/util/storage.ts +79 -21
- package/src/util/strings.ts +2 -2
- package/src/util/useStorageUploadController.tsx +34 -8
- package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
- package/dist/components/VirtualTable/common.d.ts +0 -2
- package/dist/core/Drawer.d.ts +0 -23
- package/dist/core/Scaffold.d.ts +0 -55
- package/dist/core/SideEntityView.d.ts +0 -7
- package/dist/form/EntityForm.d.ts +0 -77
- package/dist/form/components/FormikArrayContainer.d.ts +0 -18
- package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
- package/dist/internal/useBuildCustomizationController.d.ts +0 -2
- package/dist/internal/useLocaleConfig.d.ts +0 -1
- package/dist/types/appcheck.d.ts +0 -26
- package/src/components/FireCMSAppBar.tsx +0 -165
- package/src/components/PropertyIdCopyTooltipContent.tsx +0 -28
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -225
- package/src/core/Drawer.tsx +0 -191
- package/src/core/Scaffold.tsx +0 -281
- package/src/core/SideEntityView.tsx +0 -38
- package/src/form/EntityForm.tsx +0 -728
- package/src/form/components/FormikArrayContainer.tsx +0 -44
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
- package/src/internal/useBuildCustomizationController.tsx +0 -5
- package/src/internal/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
- /package/src/util/{common.tsx → common.ts} +0 -0
|
@@ -60,7 +60,7 @@ export interface CollectionFetchResult<M extends Record<string, any>> {
|
|
|
60
60
|
* @param searchString
|
|
61
61
|
* @group Hooks and utilities
|
|
62
62
|
*/
|
|
63
|
-
export function useCollectionFetch<M extends Record<string, any>,
|
|
63
|
+
export function useCollectionFetch<M extends Record<string, any>, USER extends User>(
|
|
64
64
|
{
|
|
65
65
|
path: inputPath,
|
|
66
66
|
collection,
|
|
@@ -73,12 +73,12 @@ export function useCollectionFetch<M extends Record<string, any>, UserType exten
|
|
|
73
73
|
const dataSource = useDataSource(collection);
|
|
74
74
|
const navigationController = useNavigationController();
|
|
75
75
|
|
|
76
|
-
const path = navigationController.
|
|
76
|
+
const path = navigationController.resolveIdsFrom(inputPath);
|
|
77
77
|
|
|
78
78
|
const sortByProperty = sortBy ? sortBy[0] : undefined;
|
|
79
79
|
const currentSort = sortBy ? sortBy[1] : undefined;
|
|
80
80
|
|
|
81
|
-
const context: FireCMSContext<
|
|
81
|
+
const context: FireCMSContext<USER> = useFireCMSContext();
|
|
82
82
|
|
|
83
83
|
const [data, setData] = useState<Entity<M>[]>([]);
|
|
84
84
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext
|
|
1
|
+
import { useContext } from "react";
|
|
2
2
|
import { DataSource, EntityCollection } from "../../types";
|
|
3
3
|
import { DataSourceContext } from "../../contexts/DataSourceContext";
|
|
4
4
|
|
|
@@ -7,8 +7,16 @@ import { DataSourceContext } from "../../contexts/DataSourceContext";
|
|
|
7
7
|
* @group Hooks and utilities
|
|
8
8
|
*/
|
|
9
9
|
export const useDataSource = (collection?: EntityCollection<any, any>): DataSource => {
|
|
10
|
+
// const customizationController = useCustomizationController();
|
|
11
|
+
// const navigationController = useNavigationController();
|
|
10
12
|
const defaultDataSource = useContext(DataSourceContext);
|
|
11
|
-
if (collection?.overrides?.
|
|
12
|
-
|
|
13
|
+
// if (collection?.overrides?.dataSourceDelegate) {
|
|
14
|
+
// console.trace("Using custom data source for collection " + collection.id);
|
|
15
|
+
// return useBuildDataSource({
|
|
16
|
+
// delegate: collection.overrides.dataSourceDelegate,
|
|
17
|
+
// propertyConfigs: customizationController?.propertyConfigs,
|
|
18
|
+
// navigationController: navigationController
|
|
19
|
+
// });
|
|
20
|
+
// }
|
|
13
21
|
return defaultDataSource;
|
|
14
22
|
};
|
|
@@ -7,10 +7,11 @@ import { useFireCMSContext } from "../useFireCMSContext";
|
|
|
7
7
|
/**
|
|
8
8
|
* @group Hooks and utilities
|
|
9
9
|
*/
|
|
10
|
-
export interface EntityFetchProps<M extends Record<string, any>,
|
|
10
|
+
export interface EntityFetchProps<M extends Record<string, any>, USER extends User = User> {
|
|
11
11
|
path: string;
|
|
12
12
|
entityId?: string;
|
|
13
|
-
|
|
13
|
+
databaseId?: string;
|
|
14
|
+
collection: EntityCollection<M, USER>;
|
|
14
15
|
useCache?: boolean;
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -35,20 +36,21 @@ const CACHE: Record<string, Entity<any> | undefined> = {};
|
|
|
35
36
|
* @group Hooks and utilities
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
|
-
export function useEntityFetch<M extends Record<string, any>,
|
|
39
|
+
export function useEntityFetch<M extends Record<string, any>, USER extends User>(
|
|
39
40
|
{
|
|
40
41
|
path: inputPath,
|
|
41
42
|
entityId,
|
|
42
43
|
collection,
|
|
44
|
+
databaseId,
|
|
43
45
|
useCache = false
|
|
44
|
-
}: EntityFetchProps<M,
|
|
46
|
+
}: EntityFetchProps<M, USER>): EntityFetchResult<M> {
|
|
45
47
|
|
|
46
48
|
const dataSource = useDataSource(collection);
|
|
47
49
|
const navigationController = useNavigationController();
|
|
48
50
|
|
|
49
|
-
const path = navigationController.
|
|
51
|
+
const path = navigationController.resolveIdsFrom(inputPath);
|
|
50
52
|
|
|
51
|
-
const context: FireCMSContext<
|
|
53
|
+
const context: FireCMSContext<USER> = useFireCMSContext();
|
|
52
54
|
|
|
53
55
|
const [entity, setEntity] = useState<Entity<M> | undefined>();
|
|
54
56
|
const [dataLoading, setDataLoading] = useState<boolean>(true);
|
|
@@ -96,6 +98,7 @@ export function useEntityFetch<M extends Record<string, any>, UserType extends U
|
|
|
96
98
|
return dataSource.listenEntity<M>({
|
|
97
99
|
path,
|
|
98
100
|
entityId,
|
|
101
|
+
databaseId,
|
|
99
102
|
collection,
|
|
100
103
|
onUpdate: onEntityUpdate,
|
|
101
104
|
onError
|
|
@@ -104,6 +107,7 @@ export function useEntityFetch<M extends Record<string, any>, UserType extends U
|
|
|
104
107
|
dataSource.fetchEntity<M>({
|
|
105
108
|
path,
|
|
106
109
|
entityId,
|
|
110
|
+
databaseId,
|
|
107
111
|
collection
|
|
108
112
|
})
|
|
109
113
|
.then(onEntityUpdate)
|
package/src/hooks/index.tsx
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./useResolvedNavigationFrom";
|
|
|
10
10
|
|
|
11
11
|
export * from "./useStorageSource";
|
|
12
12
|
export * from "./useAuthController";
|
|
13
|
+
export * from "./useDialogsController";
|
|
13
14
|
export * from "./useSideDialogsController";
|
|
14
15
|
export * from "./useSideEntityController";
|
|
15
16
|
export * from "./useFireCMSContext";
|
|
@@ -11,4 +11,4 @@ import { AuthControllerContext } from "../contexts/AuthControllerContext";
|
|
|
11
11
|
* @see AuthController
|
|
12
12
|
* @group Hooks and utilities
|
|
13
13
|
*/
|
|
14
|
-
export const useAuthController = <
|
|
14
|
+
export const useAuthController = <USER extends User = User, AuthControllerType extends AuthController<USER> = AuthController<USER>>(): AuthControllerType => useContext(AuthControllerContext) as AuthControllerType;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { BreadcrumbContext } from "../contexts/BreacrumbsContext";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @group Hooks and utilities
|
|
6
|
+
*/
|
|
7
|
+
export interface BreadcrumbsController {
|
|
8
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
9
|
+
set: (props: {
|
|
10
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
11
|
+
}) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @group Hooks and utilities
|
|
16
|
+
*/
|
|
17
|
+
export interface BreadcrumbEntry {
|
|
18
|
+
title: string;
|
|
19
|
+
url: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook to retrieve the BreadcrumbsController.
|
|
24
|
+
*
|
|
25
|
+
* Consider that in order to use this hook you need to have a parent
|
|
26
|
+
* `FireCMS`
|
|
27
|
+
*
|
|
28
|
+
* @see BreadcrumbsController
|
|
29
|
+
* @group Hooks and utilities
|
|
30
|
+
*/
|
|
31
|
+
export const useBreadcrumbsController = (): BreadcrumbsController => useContext(BreadcrumbContext);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { PartialEntityCollection, UserConfigurationPersistence } from "../types";
|
|
3
3
|
import { mergeDeep, stripCollectionPath } from "../util";
|
|
4
4
|
|
|
5
5
|
export function useBuildLocalConfigurationPersistence(): UserConfigurationPersistence {
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const configCache = useRef<Record<string, PartialEntityCollection>>({});
|
|
8
8
|
|
|
9
9
|
const getCollectionFromStorage = useCallback((storageKey: string) => {
|
|
10
10
|
const item = localStorage.getItem(storageKey);
|
|
@@ -13,20 +13,18 @@ export function useBuildLocalConfigurationPersistence(): UserConfigurationPersis
|
|
|
13
13
|
|
|
14
14
|
const getCollectionConfig = useCallback(<M extends Record<string, any>>(path: string): PartialEntityCollection<M> => {
|
|
15
15
|
const storageKey = `collection_config::${stripCollectionPath(path)}`;
|
|
16
|
-
if (configCache[storageKey]) {
|
|
17
|
-
return configCache[storageKey] as PartialEntityCollection<M>;
|
|
16
|
+
if (configCache.current[storageKey]) {
|
|
17
|
+
return configCache.current[storageKey] as PartialEntityCollection<M>;
|
|
18
18
|
}
|
|
19
19
|
return getCollectionFromStorage(storageKey);
|
|
20
|
-
}, [
|
|
20
|
+
}, [getCollectionFromStorage]);
|
|
21
21
|
|
|
22
22
|
const onCollectionModified = useCallback(<M extends Record<string, any>>(path: string, data: PartialEntityCollection<M>) => {
|
|
23
23
|
const storageKey = `collection_config::${stripCollectionPath(path)}`;
|
|
24
24
|
localStorage.setItem(storageKey, JSON.stringify(data));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return (mergeDeep(currentCache, newConfig));
|
|
29
|
-
});
|
|
25
|
+
const cachedConfig = configCache.current[storageKey];
|
|
26
|
+
const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);
|
|
27
|
+
configCache.current[storageKey] = mergeDeep(configCache.current[storageKey], newConfig);
|
|
30
28
|
}, [getCollectionFromStorage]);
|
|
31
29
|
|
|
32
30
|
const [recentlyVisitedPaths, _setRecentlyVisitedPaths] = useState<string[]>([]);
|
|
@@ -8,8 +8,13 @@ import { ModeController } from "./index";
|
|
|
8
8
|
*/
|
|
9
9
|
export function useBuildModeController(): ModeController {
|
|
10
10
|
|
|
11
|
-
const prefersDarkModeQuery =
|
|
12
|
-
|
|
11
|
+
const prefersDarkModeQuery = useCallback((): boolean => {
|
|
12
|
+
if (typeof window === "undefined")
|
|
13
|
+
return false;
|
|
14
|
+
const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
|
|
15
|
+
return mediaQueryList.matches;
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
13
18
|
const prefersDarkModeStorage: boolean | null = localStorage.getItem("prefers-dark-mode") != null ? localStorage.getItem("prefers-dark-mode") === "true" : null;
|
|
14
19
|
const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery;
|
|
15
20
|
const [mode, setMode] = useState<"light" | "dark">(prefersDarkMode ? "dark" : "light");
|
|
@@ -23,7 +28,7 @@ export function useBuildModeController(): ModeController {
|
|
|
23
28
|
const setDarkMode = useCallback(() => {
|
|
24
29
|
setMode("dark");
|
|
25
30
|
setDocumentMode("dark");
|
|
26
|
-
}, [
|
|
31
|
+
}, []);
|
|
27
32
|
|
|
28
33
|
const setLightMode = useCallback(() => {
|
|
29
34
|
setMode("light");
|
|
@@ -37,14 +42,15 @@ export function useBuildModeController(): ModeController {
|
|
|
37
42
|
|
|
38
43
|
const toggleMode = useCallback(() => {
|
|
39
44
|
|
|
45
|
+
const prefersDarkModeQueryResult = prefersDarkModeQuery();
|
|
40
46
|
if (mode === "light") {
|
|
41
|
-
if (!
|
|
47
|
+
if (!prefersDarkModeQueryResult)
|
|
42
48
|
localStorage.setItem("prefers-dark-mode", "true");
|
|
43
49
|
else
|
|
44
50
|
localStorage.removeItem("prefers-dark-mode");
|
|
45
51
|
setDarkMode();
|
|
46
52
|
} else {
|
|
47
|
-
if (
|
|
53
|
+
if (prefersDarkModeQueryResult)
|
|
48
54
|
localStorage.setItem("prefers-dark-mode", "false");
|
|
49
55
|
else
|
|
50
56
|
localStorage.removeItem("prefers-dark-mode");
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
EntityCollection,
|
|
10
10
|
EntityCollectionsBuilder,
|
|
11
11
|
EntityReference,
|
|
12
|
+
NavigationBlocker,
|
|
12
13
|
NavigationController,
|
|
13
14
|
PermissionsBuilder,
|
|
14
15
|
TopNavigationEntry,
|
|
@@ -20,19 +21,21 @@ import {
|
|
|
20
21
|
applyPermissionsFunctionIfEmpty,
|
|
21
22
|
getCollectionByPathOrId,
|
|
22
23
|
mergeDeep,
|
|
24
|
+
removeFunctions,
|
|
23
25
|
removeInitialAndTrailingSlashes,
|
|
24
26
|
resolveCollectionPathIds,
|
|
25
27
|
resolvePermissions
|
|
26
28
|
} from "../util";
|
|
27
29
|
import { getParentReferencesFromPath } from "../util/parent_references_from_path";
|
|
30
|
+
import { useBlocker, useNavigate } from "react-router-dom";
|
|
28
31
|
|
|
29
32
|
const DEFAULT_BASE_PATH = "/";
|
|
30
33
|
const DEFAULT_COLLECTION_PATH = "/c";
|
|
31
34
|
|
|
32
|
-
type BuildNavigationContextProps<EC extends EntityCollection,
|
|
35
|
+
export type BuildNavigationContextProps<EC extends EntityCollection, USER extends User> = {
|
|
33
36
|
basePath?: string,
|
|
34
37
|
baseCollectionPath?: string,
|
|
35
|
-
authController: AuthController<
|
|
38
|
+
authController: AuthController<USER>;
|
|
36
39
|
collections?: EC[] | EntityCollectionsBuilder<EC>;
|
|
37
40
|
collectionPermissions?: PermissionsBuilder;
|
|
38
41
|
views?: CMSView[] | CMSViewsBuilder;
|
|
@@ -50,7 +53,7 @@ type BuildNavigationContextProps<EC extends EntityCollection, UserType extends U
|
|
|
50
53
|
injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
|
|
51
54
|
};
|
|
52
55
|
|
|
53
|
-
export function useBuildNavigationController<EC extends EntityCollection,
|
|
56
|
+
export function useBuildNavigationController<EC extends EntityCollection, USER extends User>(props: BuildNavigationContextProps<EC, USER>): NavigationController {
|
|
54
57
|
const {
|
|
55
58
|
basePath = DEFAULT_BASE_PATH,
|
|
56
59
|
baseCollectionPath = DEFAULT_COLLECTION_PATH,
|
|
@@ -65,6 +68,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
65
68
|
injectCollections
|
|
66
69
|
} = props;
|
|
67
70
|
|
|
71
|
+
const navigate = useNavigate();
|
|
72
|
+
|
|
68
73
|
const collectionsRef = useRef<EntityCollection[] | undefined>();
|
|
69
74
|
const viewsRef = useRef<CMSView[] | undefined>();
|
|
70
75
|
const adminViewsRef = useRef<CMSView[] | undefined>();
|
|
@@ -130,6 +135,30 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
130
135
|
.filter(Boolean) as TopNavigationEntry[]
|
|
131
136
|
];
|
|
132
137
|
|
|
138
|
+
// Sort by group, entries with group "Admin" will go last, and second to last will be the group "Views"
|
|
139
|
+
navigationEntries = navigationEntries.sort((a, b) => {
|
|
140
|
+
if (a.group !== "Views" && a.group !== "Admin" && (b.group === "Views" || b.group === "Admin")) {
|
|
141
|
+
return -1;
|
|
142
|
+
}
|
|
143
|
+
if (b.group !== "Views" && b.group !== "Admin" && (a.group === "Views" || a.group === "Admin")) {
|
|
144
|
+
return 1;
|
|
145
|
+
}
|
|
146
|
+
if (a.group === "Admin" && b.group !== "Admin") {
|
|
147
|
+
return 1;
|
|
148
|
+
}
|
|
149
|
+
if (a.group !== "Admin" && b.group === "Admin") {
|
|
150
|
+
return -1;
|
|
151
|
+
}
|
|
152
|
+
if (a.group === "Views" && b.group !== "Views") {
|
|
153
|
+
return -1;
|
|
154
|
+
}
|
|
155
|
+
if (a.group !== "Views" && b.group === "Views") {
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
return 0;
|
|
159
|
+
|
|
160
|
+
});
|
|
161
|
+
|
|
133
162
|
if (viewsOrder) {
|
|
134
163
|
navigationEntries = navigationEntries.sort((a, b) => {
|
|
135
164
|
const aIndex = viewsOrder.indexOf(a.path);
|
|
@@ -163,8 +192,10 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
163
192
|
if (authController.initialLoading)
|
|
164
193
|
return;
|
|
165
194
|
|
|
195
|
+
console.debug("Refreshing navigation");
|
|
196
|
+
|
|
166
197
|
try {
|
|
167
|
-
|
|
198
|
+
|
|
168
199
|
const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
|
|
169
200
|
resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),
|
|
170
201
|
resolveCMSViews(viewsProp, authController, dataSourceDelegate),
|
|
@@ -172,24 +203,38 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
172
203
|
]
|
|
173
204
|
);
|
|
174
205
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
206
|
+
let shouldUpdateTopLevelNav = false;
|
|
207
|
+
if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
|
|
208
|
+
collectionsRef.current = resolvedCollections;
|
|
209
|
+
console.log("Collections have changed", resolvedCollections);
|
|
210
|
+
shouldUpdateTopLevelNav = true;
|
|
211
|
+
}
|
|
212
|
+
if (collectionsRef.current === undefined) {
|
|
181
213
|
collectionsRef.current = resolvedCollections;
|
|
214
|
+
shouldUpdateTopLevelNav = true;
|
|
215
|
+
}
|
|
216
|
+
if (!equal(viewsRef.current, resolvedViews)) {
|
|
182
217
|
viewsRef.current = resolvedViews;
|
|
218
|
+
shouldUpdateTopLevelNav = true;
|
|
219
|
+
}
|
|
220
|
+
if (!equal(adminViewsRef.current, resolvedAdminViews)) {
|
|
183
221
|
adminViewsRef.current = resolvedAdminViews;
|
|
184
|
-
|
|
222
|
+
shouldUpdateTopLevelNav = true;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
|
|
226
|
+
if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
|
|
227
|
+
setTopLevelNavigation(computedTopLevelNav);
|
|
185
228
|
}
|
|
186
229
|
} catch (e) {
|
|
187
230
|
console.error(e);
|
|
188
231
|
setNavigationLoadingError(e as any);
|
|
189
232
|
}
|
|
190
233
|
|
|
191
|
-
|
|
192
|
-
|
|
234
|
+
if (navigationLoading)
|
|
235
|
+
setNavigationLoading(false);
|
|
236
|
+
if (!initialised)
|
|
237
|
+
setInitialised(true);
|
|
193
238
|
|
|
194
239
|
}, [
|
|
195
240
|
collectionsProp,
|
|
@@ -208,7 +253,6 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
208
253
|
|
|
209
254
|
const getCollection = useCallback((
|
|
210
255
|
idOrPath: string,
|
|
211
|
-
entityId?: string,
|
|
212
256
|
includeUserOverride = false
|
|
213
257
|
): EC | undefined => {
|
|
214
258
|
const collections = collectionsRef.current;
|
|
@@ -218,8 +262,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
218
262
|
const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);
|
|
219
263
|
|
|
220
264
|
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
|
|
221
|
-
|
|
222
|
-
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
|
|
265
|
+
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : undefined;
|
|
223
266
|
|
|
224
267
|
let result: Partial<EntityCollection> | undefined = overriddenCollection;
|
|
225
268
|
|
|
@@ -244,9 +287,9 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
244
287
|
const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {
|
|
245
288
|
|
|
246
289
|
const collections = collectionsRef.current;
|
|
290
|
+
if (collections === undefined)
|
|
291
|
+
throw Error("getCollectionFromPaths: Collections have not been initialised yet");
|
|
247
292
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
248
|
-
if (!currentCollections)
|
|
249
|
-
throw Error("Collections have not been initialised yet");
|
|
250
293
|
|
|
251
294
|
for (let i = 0; i < pathSegments.length; i++) {
|
|
252
295
|
const pathSegment = pathSegments[i];
|
|
@@ -265,9 +308,9 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
265
308
|
const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {
|
|
266
309
|
|
|
267
310
|
const collections = collectionsRef.current;
|
|
311
|
+
if (collections === undefined)
|
|
312
|
+
throw Error("getCollectionFromIds: Collections have not been initialised yet");
|
|
268
313
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
269
|
-
if (!currentCollections)
|
|
270
|
-
throw Error("Collections have not been initialised yet");
|
|
271
314
|
|
|
272
315
|
for (let i = 0; i < ids.length; i++) {
|
|
273
316
|
const id = ids[i];
|
|
@@ -293,19 +336,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
293
336
|
throw Error("Expected path starting with " + fullCollectionPath);
|
|
294
337
|
}, [fullCollectionPath]);
|
|
295
338
|
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
}: {
|
|
299
|
-
path: string
|
|
300
|
-
}): string => {
|
|
301
|
-
return `s/edit/${encodePath(path)}`;
|
|
302
|
-
},
|
|
303
|
-
[]);
|
|
304
|
-
|
|
305
|
-
const resolveAliasesFrom = useCallback((path: string): string => {
|
|
306
|
-
const collections = collectionsRef.current;
|
|
307
|
-
if (!collections)
|
|
308
|
-
throw Error("Collections have not been initialised yet");
|
|
339
|
+
const resolveIdsFrom = useCallback((path: string): string => {
|
|
340
|
+
const collections = collectionsRef.current ?? [];
|
|
309
341
|
return resolveCollectionPathIds(path, collections);
|
|
310
342
|
}, []);
|
|
311
343
|
|
|
@@ -364,24 +396,16 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
364
396
|
isUrlCollectionPath,
|
|
365
397
|
urlPathToDataPath,
|
|
366
398
|
buildUrlCollectionPath,
|
|
367
|
-
|
|
368
|
-
buildCMSUrlPath,
|
|
369
|
-
resolveAliasesFrom,
|
|
399
|
+
resolveIdsFrom,
|
|
370
400
|
topLevelNavigation,
|
|
371
401
|
refreshNavigation,
|
|
372
402
|
getParentReferencesFromPath: getAllParentReferencesForPath,
|
|
373
403
|
getParentCollectionIds,
|
|
374
|
-
convertIdsToPaths
|
|
404
|
+
convertIdsToPaths,
|
|
405
|
+
navigate,
|
|
375
406
|
};
|
|
376
407
|
}
|
|
377
408
|
|
|
378
|
-
export function getSidePanelKey(path: string, entityId?: string) {
|
|
379
|
-
if (entityId)
|
|
380
|
-
return `${removeInitialAndTrailingSlashes(path)}/${removeInitialAndTrailingSlashes(entityId)}`;
|
|
381
|
-
else
|
|
382
|
-
return removeInitialAndTrailingSlashes(path);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
409
|
function encodePath(input: string) {
|
|
386
410
|
return encodeURIComponent(removeInitialAndTrailingSlashes(input))
|
|
387
411
|
.replaceAll("%2F", "/")
|
|
@@ -390,9 +414,10 @@ function encodePath(input: string) {
|
|
|
390
414
|
|
|
391
415
|
function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[], authController: AuthController<User>): EntityCollection[] {
|
|
392
416
|
return resolvedCollections
|
|
417
|
+
.filter((c) => Boolean(c.path))
|
|
393
418
|
.filter((c) => {
|
|
394
419
|
if (!c.permissions) return true;
|
|
395
|
-
const resolvedPermissions = resolvePermissions(c, authController, c.path, null)
|
|
420
|
+
const resolvedPermissions = resolvePermissions(c, authController, c.path, null);
|
|
396
421
|
return resolvedPermissions?.read !== false;
|
|
397
422
|
})
|
|
398
423
|
.map((c) => {
|
|
@@ -408,7 +433,7 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
408
433
|
collectionPermissions: PermissionsBuilder | undefined,
|
|
409
434
|
authController: AuthController,
|
|
410
435
|
dataSource: DataSourceDelegate,
|
|
411
|
-
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]) {
|
|
436
|
+
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {
|
|
412
437
|
let resolvedCollections: EntityCollection[] = [];
|
|
413
438
|
if (typeof collections === "function") {
|
|
414
439
|
resolvedCollections = await collections({
|
|
@@ -420,14 +445,12 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
420
445
|
resolvedCollections = collections;
|
|
421
446
|
}
|
|
422
447
|
|
|
423
|
-
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
424
|
-
|
|
425
|
-
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
426
|
-
|
|
427
448
|
if (injectCollections) {
|
|
428
449
|
resolvedCollections = injectCollections(resolvedCollections ?? []);
|
|
429
450
|
}
|
|
430
451
|
|
|
452
|
+
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
453
|
+
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
431
454
|
return resolvedCollections;
|
|
432
455
|
}
|
|
433
456
|
|
|
@@ -452,3 +475,80 @@ function getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {
|
|
|
452
475
|
}
|
|
453
476
|
return trimmed ?? "Views";
|
|
454
477
|
}
|
|
478
|
+
|
|
479
|
+
function areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {
|
|
480
|
+
if (a.length !== b.length) {
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
const aCopy = [...a];
|
|
484
|
+
const bCopy = [...b];
|
|
485
|
+
const aSorted = aCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
486
|
+
const bSorted = bCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
487
|
+
return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function areCollectionsEqual(a: EntityCollection, b: EntityCollection) {
|
|
491
|
+
const {
|
|
492
|
+
subcollections: subcollectionsA,
|
|
493
|
+
...restA
|
|
494
|
+
} = a;
|
|
495
|
+
const {
|
|
496
|
+
subcollections: subcollectionsB,
|
|
497
|
+
...restB
|
|
498
|
+
} = b;
|
|
499
|
+
if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
return equal(removeFunctions(restA), removeFunctions(restB));
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function useCustomBlocker(): NavigationBlocker {
|
|
506
|
+
const [blockListeners, setBlockListeners] = useState<Record<string, {
|
|
507
|
+
block: boolean,
|
|
508
|
+
basePath?: string
|
|
509
|
+
}>>({});
|
|
510
|
+
|
|
511
|
+
const shouldBlock = Object.values(blockListeners).some(b => b.block);
|
|
512
|
+
|
|
513
|
+
let blocker: any;
|
|
514
|
+
try {
|
|
515
|
+
blocker = useBlocker(({
|
|
516
|
+
nextLocation
|
|
517
|
+
}) => {
|
|
518
|
+
const allBasePaths = Object.values(blockListeners).map(b => b.basePath).filter(Boolean) as string[];
|
|
519
|
+
if (allBasePaths && allBasePaths.some(path => nextLocation.pathname.startsWith(path)))
|
|
520
|
+
return false;
|
|
521
|
+
return shouldBlock;
|
|
522
|
+
});
|
|
523
|
+
} catch (e) {
|
|
524
|
+
console.warn("Blocker not available, navigation will not be blocked");
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const updateBlockListener = (path: string, block: boolean, basePath?: string) => {
|
|
528
|
+
setBlockListeners(prev => ({
|
|
529
|
+
...prev,
|
|
530
|
+
[path]: {
|
|
531
|
+
block,
|
|
532
|
+
basePath
|
|
533
|
+
}
|
|
534
|
+
}));
|
|
535
|
+
return () => setBlockListeners(prev => {
|
|
536
|
+
const {
|
|
537
|
+
[path]: removed,
|
|
538
|
+
...rest
|
|
539
|
+
} = prev;
|
|
540
|
+
return rest;
|
|
541
|
+
})
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
const isBlocked = (path: string) => {
|
|
545
|
+
return (blockListeners[path]?.block ?? false) && blocker?.state === "blocked";
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return {
|
|
549
|
+
updateBlockListener,
|
|
550
|
+
isBlocked,
|
|
551
|
+
proceed: blocker?.proceed,
|
|
552
|
+
reset: blocker?.reset
|
|
553
|
+
}
|
|
554
|
+
}
|
|
@@ -21,9 +21,9 @@ import React, { useEffect } from "react";
|
|
|
21
21
|
* @see FireCMSContext
|
|
22
22
|
* @group Hooks and utilities
|
|
23
23
|
*/
|
|
24
|
-
export const useFireCMSContext = <
|
|
24
|
+
export const useFireCMSContext = <USER extends User = User, AuthControllerType extends AuthController<USER> = AuthController<USER>>(): FireCMSContext<USER, AuthControllerType> => {
|
|
25
25
|
|
|
26
|
-
const authController = useAuthController<
|
|
26
|
+
const authController = useAuthController<USER, AuthControllerType>();
|
|
27
27
|
const sideDialogsController = useSideDialogsController();
|
|
28
28
|
const sideEntityController = useSideEntityController();
|
|
29
29
|
const navigation = useNavigationController();
|
|
@@ -35,7 +35,7 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
|
|
|
35
35
|
const customizationController = useCustomizationController();
|
|
36
36
|
const analyticsController = useAnalyticsController();
|
|
37
37
|
|
|
38
|
-
const fireCMSContextRef = React.useRef<FireCMSContext<
|
|
38
|
+
const fireCMSContextRef = React.useRef<FireCMSContext<USER, AuthControllerType>>({
|
|
39
39
|
authController,
|
|
40
40
|
sideDialogsController,
|
|
41
41
|
sideEntityController,
|
|
@@ -68,9 +68,9 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
|
|
|
68
68
|
return fireCMSContextRef.current;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// export const useFireCMSContext = <
|
|
71
|
+
// export const useFireCMSContext = <USER extends User = User, AuthControllerType extends AuthController<USER> = AuthController<USER>>(): FireCMSContext<USER, AuthControllerType> => {
|
|
72
72
|
//
|
|
73
|
-
// const authController = useAuthController<
|
|
73
|
+
// const authController = useAuthController<USER, AuthControllerType>();
|
|
74
74
|
// const sideDialogsController = useSideDialogsController();
|
|
75
75
|
// const sideEntityController = useSideEntityController();
|
|
76
76
|
// const navigation = useNavigationController();
|
|
@@ -63,38 +63,3 @@ function checkLargeLayout(breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" |
|
|
|
63
63
|
return false;
|
|
64
64
|
return window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
// import { useEffect, useState } from "react";
|
|
68
|
-
//
|
|
69
|
-
// const breakpoints = {
|
|
70
|
-
// xs: 0,
|
|
71
|
-
// sm: 640,
|
|
72
|
-
// md: 768,
|
|
73
|
-
// lg: 1024,
|
|
74
|
-
// xl: 1280,
|
|
75
|
-
// "2xl": 1536,
|
|
76
|
-
// "3xl": 1920
|
|
77
|
-
// }
|
|
78
|
-
// export const useLargeLayout = (breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" = "lg"): boolean => {
|
|
79
|
-
// const [isLargeLayout, setIsLargeLayout] = useState<boolean>(false);
|
|
80
|
-
//
|
|
81
|
-
// useEffect(() => {
|
|
82
|
-
// const handleResize = () => {
|
|
83
|
-
// const matched = window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
|
|
84
|
-
// setIsLargeLayout(matched);
|
|
85
|
-
// };
|
|
86
|
-
//
|
|
87
|
-
// // Set initial state
|
|
88
|
-
// handleResize();
|
|
89
|
-
//
|
|
90
|
-
// // Set up event listener for resize events
|
|
91
|
-
// window.addEventListener("resize", handleResize);
|
|
92
|
-
//
|
|
93
|
-
// // Clean up event listener when component unmounts
|
|
94
|
-
// return () => {
|
|
95
|
-
// window.removeEventListener("resize", handleResize);
|
|
96
|
-
// };
|
|
97
|
-
// }, []);
|
|
98
|
-
//
|
|
99
|
-
// return isLargeLayout;
|
|
100
|
-
// };
|