@firecms/core 3.0.0-canary.19 → 3.0.0-canary.191
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 +31 -11
- package/dist/core/EntityEditViewFormActions.d.ts +2 -0
- 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/SideDialogs.d.ts +4 -2
- package/dist/core/index.d.ts +4 -4
- package/dist/form/EntityForm.d.ts +36 -68
- package/dist/form/EntityFormActions.d.ts +16 -0
- 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/FormEntry.d.ts +6 -0
- package/dist/form/components/FormLayout.d.ts +5 -0
- 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 +3 -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 +16 -18
- 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 +7 -5
- package/dist/hooks/useFireCMSContext.d.ts +1 -1
- package/dist/hooks/useModeController.d.ts +1 -2
- 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 +22037 -14330
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +24386 -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 +71 -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 +32 -14
- package/dist/types/permissions.d.ts +4 -4
- package/dist/types/plugins.d.ts +23 -12
- package/dist/types/properties.d.ts +52 -24
- 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 +81 -80
- 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/ModeController.tsx +1 -3
- package/src/contexts/SnackbarProvider.tsx +2 -0
- package/src/core/DefaultAppBar.tsx +207 -0
- package/src/core/DefaultDrawer.tsx +185 -0
- package/src/core/DrawerNavigationItem.tsx +66 -0
- package/src/core/EntityEditView.tsx +358 -480
- package/src/core/EntityEditViewFormActions.tsx +198 -0
- package/src/core/EntitySidePanel.tsx +87 -17
- package/src/core/FireCMS.tsx +56 -49
- package/src/core/FireCMSRouter.tsx +17 -0
- package/src/core/NavigationRoutes.tsx +28 -38
- package/src/core/SideDialogs.tsx +22 -12
- package/src/core/field_configs.tsx +11 -12
- package/src/core/index.tsx +6 -5
- package/src/form/EntityForm.tsx +568 -546
- package/src/form/EntityFormActions.tsx +168 -0
- 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/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- 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 +4 -5
- package/src/form/components/index.tsx +3 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +31 -19
- 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 +71 -54
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +153 -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 +42 -50
- package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
- package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
- package/src/form/index.tsx +16 -37
- package/src/form/useClearRestoreValue.tsx +2 -2
- package/src/form/validation.ts +13 -23
- 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 +22 -29
- package/src/hooks/useBuildNavigationController.tsx +159 -52
- package/src/hooks/useFireCMSContext.tsx +5 -5
- package/src/hooks/useLargeLayout.tsx +0 -35
- package/src/hooks/useModeController.tsx +1 -2
- 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 +178 -70
- package/src/internal/useUnsavedChangesDialog.tsx +127 -91
- package/src/preview/PropertyPreview.tsx +17 -24
- 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 +60 -28
- 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 +12 -11
- 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 +223 -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 +81 -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 +38 -18
- package/src/types/permissions.ts +5 -5
- package/src/types/plugins.tsx +25 -14
- package/src/types/properties.ts +60 -25
- 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 +204 -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 +71 -27
- 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/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/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
|
@@ -3,24 +3,85 @@ import {
|
|
|
3
3
|
EntityCollection,
|
|
4
4
|
EntitySidePanelProps,
|
|
5
5
|
NavigationController,
|
|
6
|
+
ResolvedProperty,
|
|
6
7
|
SideDialogPanelProps,
|
|
7
8
|
SideDialogsController,
|
|
8
9
|
SideEntityController
|
|
9
10
|
} from "../types";
|
|
10
|
-
import {
|
|
11
|
+
import { getNavigationEntriesFromPath, NavigationViewInternal } from "../util/navigation_from_path";
|
|
11
12
|
import { useLocation } from "react-router-dom";
|
|
12
|
-
import { removeInitialAndTrailingSlashes, resolveDefaultSelectedView } from "../util";
|
|
13
|
+
import { removeInitialAndTrailingSlashes, resolveCollection, resolveDefaultSelectedView } from "../util";
|
|
13
14
|
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
|
|
14
15
|
import { useLargeLayout } from "../hooks";
|
|
15
16
|
import { EntitySidePanel } from "../core/EntitySidePanel";
|
|
16
17
|
|
|
17
|
-
const NEW_URL_HASH = "
|
|
18
|
+
const NEW_URL_HASH = "new_side";
|
|
19
|
+
const SIDE_URL_HASH = "side";
|
|
18
20
|
|
|
19
21
|
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {
|
|
20
22
|
if (small) return CONTAINER_FULL_WIDTH;
|
|
21
|
-
const mainViewSelected = !props.
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
const mainViewSelected = !props.selectedTab;
|
|
24
|
+
let resolvedWidth: string | undefined;
|
|
25
|
+
if (props.width) {
|
|
26
|
+
resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
27
|
+
} else if (props.collection?.sideDialogWidth) {
|
|
28
|
+
resolvedWidth = typeof props.collection.sideDialogWidth === "number" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!mainViewSelected) {
|
|
32
|
+
return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`
|
|
33
|
+
} else {
|
|
34
|
+
if (resolvedWidth) {
|
|
35
|
+
return resolvedWidth
|
|
36
|
+
} else if (!props.collection) {
|
|
37
|
+
return FORM_CONTAINER_WIDTH;
|
|
38
|
+
} else {
|
|
39
|
+
return calculateCollectionDesiredWidth(props.collection);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const collectionViewWidthCache: { [key: string]: string } = {};
|
|
45
|
+
|
|
46
|
+
function calculateCollectionDesiredWidth(collection: EntityCollection<any>): string {
|
|
47
|
+
if (collectionViewWidthCache[collection.id]) {
|
|
48
|
+
return collectionViewWidthCache[collection.id];
|
|
49
|
+
}
|
|
50
|
+
const resolvedCollection = resolveCollection({
|
|
51
|
+
collection,
|
|
52
|
+
path: "__ignored",
|
|
53
|
+
ignoreMissingFields: true
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
let result = FORM_CONTAINER_WIDTH
|
|
57
|
+
if (resolvedCollection?.properties) {
|
|
58
|
+
const values = Object.values(resolvedCollection.properties).map((p: ResolvedProperty) => getNestedPropertiesDepth(p));
|
|
59
|
+
const maxDepth = Math.max(...values);
|
|
60
|
+
if (maxDepth < 3) {
|
|
61
|
+
result = FORM_CONTAINER_WIDTH;
|
|
62
|
+
} else {
|
|
63
|
+
result = 768 + 32 * (maxDepth - 2) + "px";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
collectionViewWidthCache[collection.id] = result;
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function getNestedPropertiesDepth(property: ResolvedProperty, accumulator: number = 0): number {
|
|
71
|
+
if (property.dataType === "map" && property.properties) {
|
|
72
|
+
const values = Object.values(property.properties).flatMap((property) => getNestedPropertiesDepth(property, accumulator + 1));
|
|
73
|
+
return Math.max(...values);
|
|
74
|
+
} else if (property.dataType === "array" && property.oneOf) {
|
|
75
|
+
return accumulator + 3;
|
|
76
|
+
} else if (property.dataType === "array" && property.of) {
|
|
77
|
+
if (Array.isArray(property.of)) {
|
|
78
|
+
return Math.max(...property.of.map((p) => getNestedPropertiesDepth(p, accumulator + 1)));
|
|
79
|
+
} else {
|
|
80
|
+
return getNestedPropertiesDepth(property.of, accumulator + 1);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
return accumulator + 1;
|
|
84
|
+
}
|
|
24
85
|
}
|
|
25
86
|
|
|
26
87
|
export const useBuildSideEntityController = (navigation: NavigationController,
|
|
@@ -33,24 +94,60 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
33
94
|
|
|
34
95
|
// only on initialisation, create panels from URL
|
|
35
96
|
useEffect(() => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
97
|
+
|
|
98
|
+
const newFlag = location.hash === `#${NEW_URL_HASH}`;
|
|
99
|
+
const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
|
|
100
|
+
|
|
101
|
+
if (!navigation.loading) {
|
|
102
|
+
if ((newFlag || sideFlag) && navigation.isUrlCollectionPath(location.pathname)) {
|
|
39
103
|
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
40
104
|
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);
|
|
41
105
|
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
42
|
-
const
|
|
43
|
-
setTimeout(() => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}, 1);
|
|
106
|
+
const props = panelsFromUrl[i];
|
|
107
|
+
// setTimeout(() => {
|
|
108
|
+
if (i === 0)
|
|
109
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
110
|
+
else
|
|
111
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout))
|
|
112
|
+
// }, 1);
|
|
49
113
|
}
|
|
50
114
|
}
|
|
51
115
|
initialised.current = true;
|
|
52
116
|
}
|
|
53
|
-
}, [
|
|
117
|
+
}, [navigation.loading]);
|
|
118
|
+
|
|
119
|
+
// sync panels if URL changes with #side
|
|
120
|
+
const currentPanelKeys = sideDialogsController.sidePanels.map(p => p.key);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
if (initialised.current) {
|
|
123
|
+
const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
|
|
124
|
+
if (sideFlag) {
|
|
125
|
+
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
126
|
+
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], false);
|
|
127
|
+
// if we have more panels than determined by the url, we ignore the url. We might have references open
|
|
128
|
+
if (panelsFromUrl.length <= currentPanelKeys.length) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
|
|
132
|
+
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
133
|
+
const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
|
|
134
|
+
if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
|
|
135
|
+
sideDialogsController.replace(panelProps);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}, [location.pathname, location.hash, currentPanelKeys]);
|
|
140
|
+
|
|
141
|
+
// update side panels to match browser size
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
|
|
144
|
+
if (sidePanelProps.additional) {
|
|
145
|
+
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
146
|
+
}
|
|
147
|
+
return sidePanelProps;
|
|
148
|
+
});
|
|
149
|
+
sideDialogsController.setSidePanels(updatedSidePanels);
|
|
150
|
+
}, [smallLayout]);
|
|
54
151
|
|
|
55
152
|
const close = useCallback(() => {
|
|
56
153
|
sideDialogsController.close();
|
|
@@ -70,12 +167,17 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
70
167
|
}
|
|
71
168
|
);
|
|
72
169
|
|
|
73
|
-
sideDialogsController.open(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
170
|
+
sideDialogsController.open(
|
|
171
|
+
propsToSidePanel({
|
|
172
|
+
selectedTab: defaultSelectedView,
|
|
173
|
+
...props
|
|
174
|
+
},
|
|
175
|
+
navigation.buildUrlCollectionPath,
|
|
176
|
+
navigation.resolveIdsFrom,
|
|
177
|
+
smallLayout
|
|
178
|
+
));
|
|
77
179
|
|
|
78
|
-
}, [sideDialogsController, navigation, smallLayout]);
|
|
180
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
|
|
79
181
|
|
|
80
182
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
81
183
|
|
|
@@ -83,9 +185,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
83
185
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
84
186
|
}
|
|
85
187
|
|
|
86
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation, smallLayout));
|
|
188
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
87
189
|
|
|
88
|
-
}, [navigation, sideDialogsController, smallLayout]);
|
|
190
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
|
|
89
191
|
|
|
90
192
|
return {
|
|
91
193
|
close,
|
|
@@ -96,12 +198,12 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
96
198
|
|
|
97
199
|
export function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {
|
|
98
200
|
|
|
99
|
-
const navigationViewsForPath: NavigationViewInternal<any>[] =
|
|
201
|
+
const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPath({
|
|
100
202
|
path,
|
|
101
203
|
collections
|
|
102
204
|
});
|
|
103
205
|
|
|
104
|
-
|
|
206
|
+
let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
|
|
105
207
|
let lastCollectionPath = "";
|
|
106
208
|
for (let i = 0; i < navigationViewsForPath.length; i++) {
|
|
107
209
|
const navigationEntry = navigationViewsForPath[i];
|
|
@@ -110,63 +212,69 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
110
212
|
lastCollectionPath = navigationEntry.path;
|
|
111
213
|
}
|
|
112
214
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];
|
|
131
|
-
if (lastSidePanel)
|
|
132
|
-
lastSidePanel.selectedSubPath = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
133
|
-
}
|
|
215
|
+
const previousEntry = navigationViewsForPath[i - 1];
|
|
216
|
+
if (navigationEntry.type === "entity") {
|
|
217
|
+
sidePanel = {
|
|
218
|
+
path: navigationEntry.path,
|
|
219
|
+
entityId: navigationEntry.entityId,
|
|
220
|
+
copy: false,
|
|
221
|
+
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
222
|
+
};
|
|
223
|
+
} else if (navigationEntry.type === "custom_view") {
|
|
224
|
+
if (previousEntry?.type === "entity") {
|
|
225
|
+
if (sidePanel)
|
|
226
|
+
sidePanel.selectedTab = navigationEntry.view.key;
|
|
227
|
+
}
|
|
228
|
+
} else if (navigationEntry.type === "collection") {
|
|
229
|
+
if (previousEntry?.type === "entity") {
|
|
230
|
+
if (sidePanel)
|
|
231
|
+
sidePanel.selectedTab = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
134
232
|
}
|
|
135
233
|
}
|
|
136
234
|
|
|
137
235
|
}
|
|
138
236
|
|
|
139
237
|
if (newFlag) {
|
|
140
|
-
|
|
238
|
+
sidePanel = {
|
|
141
239
|
path: lastCollectionPath,
|
|
142
240
|
copy: false
|
|
143
|
-
}
|
|
241
|
+
}
|
|
144
242
|
}
|
|
145
243
|
|
|
146
|
-
return
|
|
244
|
+
return sidePanel ? [sidePanel] : [];
|
|
147
245
|
}
|
|
148
246
|
|
|
149
|
-
const propsToSidePanel = (props: EntitySidePanelProps<any>, navigation: NavigationController, smallLayout: boolean): SideDialogPanelProps => {
|
|
150
247
|
|
|
151
|
-
|
|
248
|
+
const propsToSidePanel = (props: EntitySidePanelProps,
|
|
249
|
+
buildUrlCollectionPath: (path: string) => string,
|
|
250
|
+
resolveIdsFrom: (pathWithAliases: string) => string,
|
|
251
|
+
smallLayout: boolean): SideDialogPanelProps => {
|
|
152
252
|
|
|
153
|
-
|
|
154
|
-
? navigation.buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || ""}`)
|
|
155
|
-
: navigation.buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
156
|
-
const resolvedPath = navigation.resolveAliasesFrom(props.path);
|
|
253
|
+
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
157
254
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
255
|
+
const newPath = props.entityId
|
|
256
|
+
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
|
|
257
|
+
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
258
|
+
const resolvedPath = resolveIdsFrom(props.path);
|
|
162
259
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
260
|
+
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
261
|
+
...props,
|
|
262
|
+
path: resolvedPath,
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const entityViewWidth = getEntityViewWidth(props, smallLayout);
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
key: `${props.path}/${props.entityId}`,
|
|
269
|
+
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
270
|
+
urlPath: newPath,
|
|
271
|
+
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
272
|
+
width: entityViewWidth,
|
|
273
|
+
onClose: props.onClose,
|
|
274
|
+
additional: props
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function isSideUrl(url: string): boolean {
|
|
279
|
+
return url.endsWith("#" + SIDE_URL_HASH) || url.endsWith("#" + NEW_URL_HASH);
|
|
280
|
+
}
|
|
@@ -1,106 +1,142 @@
|
|
|
1
|
-
import React, { useCallback } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { UNSAFE_NavigationContext, useNavigate } from "react-router-dom";
|
|
4
|
-
import { Button, Dialog, DialogActions, DialogContent, Typography } from "@firecms/ui";
|
|
1
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Type representing a pending navigation action.
|
|
6
|
+
*/
|
|
7
|
+
type PendingNavigation =
|
|
8
|
+
| {
|
|
9
|
+
type: "popstate";
|
|
10
|
+
delta: number;
|
|
11
|
+
}
|
|
12
|
+
| {
|
|
13
|
+
type: "link";
|
|
14
|
+
href: string;
|
|
15
|
+
}
|
|
16
|
+
| null;
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Custom hook to handle navigation blocking when there are unsaved changes.
|
|
20
|
+
*
|
|
21
|
+
* @param when - Indicates whether to block navigation.
|
|
22
|
+
* @param onSuccess - Callback invoked when navigation is confirmed.
|
|
23
|
+
* @returns An object containing the state of navigation blocking and handlers.
|
|
24
|
+
*/
|
|
25
|
+
export function useNavigationUnsavedChangesDialog(
|
|
26
|
+
when: boolean,
|
|
27
|
+
onSuccess: () => void
|
|
28
|
+
): {
|
|
29
|
+
navigationWasBlocked: boolean;
|
|
30
|
+
handleCancel: () => void;
|
|
31
|
+
handleOk: () => void;
|
|
32
|
+
} {
|
|
33
|
+
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
|
|
34
|
+
const [pendingNavigation, setPendingNavigation] = useState<PendingNavigation>(null);
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Handler to cancel the navigation attempt.
|
|
38
|
+
*/
|
|
39
|
+
const handleCancel = useCallback(() => {
|
|
40
|
+
setIsDialogOpen(false);
|
|
41
|
+
setPendingNavigation(null);
|
|
42
|
+
}, []);
|
|
21
43
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Handler to confirm and proceed with the navigation.
|
|
46
|
+
*/
|
|
47
|
+
const handleOk = useCallback(() => {
|
|
48
|
+
setIsDialogOpen(false);
|
|
49
|
+
if (pendingNavigation) {
|
|
50
|
+
onSuccess();
|
|
51
|
+
if (pendingNavigation.type === "popstate") {
|
|
52
|
+
window.history.go(pendingNavigation.delta);
|
|
53
|
+
} else if (pendingNavigation.type === "link") {
|
|
54
|
+
window.location.href = pendingNavigation.href;
|
|
55
|
+
}
|
|
56
|
+
setPendingNavigation(null);
|
|
57
|
+
}
|
|
58
|
+
}, [onSuccess, pendingNavigation]);
|
|
27
59
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return;
|
|
60
|
+
/**
|
|
61
|
+
* Event handler for beforeunload to handle page refresh or tab close.
|
|
62
|
+
*/
|
|
63
|
+
const handleBeforeUnload = useCallback(
|
|
64
|
+
(e: BeforeUnloadEvent) => {
|
|
65
|
+
if (when) {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
e.returnValue = "";
|
|
37
68
|
}
|
|
38
|
-
|
|
39
|
-
|
|
69
|
+
},
|
|
70
|
+
[when]
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Event handler for popstate to handle back and forward browser buttons.
|
|
75
|
+
*/
|
|
76
|
+
const handlePopState = useCallback(
|
|
77
|
+
(e: PopStateEvent) => {
|
|
78
|
+
if (when) {
|
|
79
|
+
e.preventDefault();
|
|
80
|
+
// Assuming backward navigation; adjust delta as needed
|
|
81
|
+
setPendingNavigation({
|
|
82
|
+
type: "popstate",
|
|
83
|
+
delta: -1
|
|
84
|
+
});
|
|
85
|
+
setIsDialogOpen(true);
|
|
40
86
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
87
|
+
},
|
|
88
|
+
[when]
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Event handler to intercept link clicks within the application.
|
|
93
|
+
*/
|
|
94
|
+
const handleLinkClick = useCallback(
|
|
95
|
+
(e: MouseEvent) => {
|
|
96
|
+
if (!when) return;
|
|
43
97
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
98
|
+
const target = e.target as HTMLElement;
|
|
99
|
+
const anchor = target.closest("a[href]") as HTMLAnchorElement | null;
|
|
100
|
+
if (anchor && anchor.host === window.location.host) {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
const href = anchor.getAttribute("href");
|
|
103
|
+
if (href) {
|
|
104
|
+
setPendingNavigation({
|
|
105
|
+
type: "link",
|
|
106
|
+
href
|
|
107
|
+
});
|
|
108
|
+
setIsDialogOpen(true);
|
|
54
109
|
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
[when]
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Effect hook to add and clean up event listeners based on the `when` condition.
|
|
117
|
+
*/
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (when) {
|
|
120
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
121
|
+
window.addEventListener("popstate", handlePopState);
|
|
122
|
+
document.addEventListener("click", handleLinkClick);
|
|
123
|
+
} else {
|
|
124
|
+
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
125
|
+
window.removeEventListener("popstate", handlePopState);
|
|
126
|
+
document.removeEventListener("click", handleLinkClick);
|
|
127
|
+
}
|
|
58
128
|
|
|
59
|
-
|
|
60
|
-
|
|
129
|
+
// Cleanup on unmount or when `when` changes
|
|
130
|
+
return () => {
|
|
131
|
+
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
132
|
+
window.removeEventListener("popstate", handlePopState);
|
|
133
|
+
document.removeEventListener("click", handleLinkClick);
|
|
134
|
+
};
|
|
135
|
+
}, [when, handleBeforeUnload, handlePopState, handleLinkClick]);
|
|
61
136
|
|
|
62
137
|
return {
|
|
63
|
-
navigationWasBlocked:
|
|
138
|
+
navigationWasBlocked: isDialogOpen,
|
|
64
139
|
handleCancel,
|
|
65
|
-
handleOk
|
|
140
|
+
handleOk,
|
|
66
141
|
};
|
|
67
142
|
}
|
|
68
|
-
|
|
69
|
-
export interface UnsavedChangesDialogProps {
|
|
70
|
-
open: boolean;
|
|
71
|
-
body?: React.ReactNode;
|
|
72
|
-
title?: string;
|
|
73
|
-
handleOk: () => void;
|
|
74
|
-
handleCancel: () => void;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function UnsavedChangesDialog({
|
|
78
|
-
open,
|
|
79
|
-
handleOk,
|
|
80
|
-
handleCancel,
|
|
81
|
-
body,
|
|
82
|
-
title
|
|
83
|
-
}: UnsavedChangesDialogProps) {
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<Dialog
|
|
87
|
-
open={open}
|
|
88
|
-
onOpenChange={(open) => open ? handleCancel() : handleOk()}
|
|
89
|
-
>
|
|
90
|
-
<DialogContent>
|
|
91
|
-
<Typography variant={"h6"}>{title}</Typography>
|
|
92
|
-
|
|
93
|
-
{body}
|
|
94
|
-
|
|
95
|
-
<Typography>
|
|
96
|
-
Are you sure you want to leave this page?
|
|
97
|
-
</Typography>
|
|
98
|
-
|
|
99
|
-
</DialogContent>
|
|
100
|
-
<DialogActions>
|
|
101
|
-
<Button variant="text" onClick={handleCancel} autoFocus> Cancel </Button>
|
|
102
|
-
<Button onClick={handleOk}> Ok </Button>
|
|
103
|
-
</DialogActions>
|
|
104
|
-
</Dialog>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
@@ -47,17 +47,16 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
47
47
|
size,
|
|
48
48
|
height,
|
|
49
49
|
width,
|
|
50
|
-
|
|
50
|
+
interactive
|
|
51
51
|
} = props;
|
|
52
52
|
|
|
53
53
|
const property = resolveProperty({
|
|
54
54
|
propertyKey,
|
|
55
55
|
propertyOrBuilder: inputProperty,
|
|
56
|
-
|
|
57
|
-
fields: customizationController.propertyConfigs
|
|
56
|
+
propertyConfigs: customizationController.propertyConfigs
|
|
58
57
|
});
|
|
59
58
|
|
|
60
|
-
if (
|
|
59
|
+
if (property === null) {
|
|
61
60
|
content = <EmptyValue/>;
|
|
62
61
|
} else if (property.Preview) {
|
|
63
62
|
content = createElement(property.Preview as React.ComponentType<PropertyPreviewProps>,
|
|
@@ -71,12 +70,19 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
71
70
|
// entity,
|
|
72
71
|
customProps: property.customProps
|
|
73
72
|
});
|
|
74
|
-
} else if (value === null) {
|
|
73
|
+
} else if (value === undefined || value === null) {
|
|
75
74
|
content = <EmptyValue/>;
|
|
76
75
|
} else if (property.dataType === "string") {
|
|
77
76
|
const stringProperty = property as ResolvedStringProperty;
|
|
78
77
|
if (typeof value === "string") {
|
|
79
|
-
if (stringProperty.
|
|
78
|
+
if (stringProperty.storage) {
|
|
79
|
+
const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
|
|
80
|
+
content = <StorageThumbnail
|
|
81
|
+
interactive={interactive}
|
|
82
|
+
storeUrl={property.storage?.storeUrl ?? false}
|
|
83
|
+
size={props.size}
|
|
84
|
+
storagePathOrDownloadUrl={filePath}/>;
|
|
85
|
+
} else if (stringProperty.url) {
|
|
80
86
|
if (typeof stringProperty.url === "boolean")
|
|
81
87
|
content =
|
|
82
88
|
<UrlComponentPreview size={props.size}
|
|
@@ -85,14 +91,10 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
85
91
|
content =
|
|
86
92
|
<UrlComponentPreview size={props.size}
|
|
87
93
|
url={value}
|
|
94
|
+
interactive={interactive}
|
|
88
95
|
previewType={stringProperty.url}/>;
|
|
89
|
-
} else if (stringProperty.storage) {
|
|
90
|
-
content = <StorageThumbnail
|
|
91
|
-
storeUrl={property.storage?.storeUrl ?? false}
|
|
92
|
-
size={props.size}
|
|
93
|
-
storagePathOrDownloadUrl={value}/>;
|
|
94
96
|
} else if (stringProperty.markdown) {
|
|
95
|
-
content = <Markdown source={value}/>;
|
|
97
|
+
content = <Markdown source={value} size={"small"}/>;
|
|
96
98
|
} else {
|
|
97
99
|
content = <StringPropertyPreview {...props}
|
|
98
100
|
property={stringProperty}
|
|
@@ -113,17 +115,7 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
113
115
|
content = <ArrayPropertyPreview {...props}
|
|
114
116
|
value={value}
|
|
115
117
|
property={property as ResolvedArrayProperty}/>;
|
|
116
|
-
}
|
|
117
|
-
// else if (arrayProperty.of.dataType === "map") {
|
|
118
|
-
// content =
|
|
119
|
-
// <ArrayOfMapsPreview propertyKey={propertyKey}
|
|
120
|
-
// property={property as ResolvedArrayProperty}
|
|
121
|
-
// value={value as Record<string, any>[]} // This might be wrong
|
|
122
|
-
// entity={entity}
|
|
123
|
-
// size={size}
|
|
124
|
-
// />;
|
|
125
|
-
// }
|
|
126
|
-
else if (arrayProperty.of.dataType === "reference") {
|
|
118
|
+
} else if (arrayProperty.of.dataType === "reference") {
|
|
127
119
|
content = <ArrayOfReferencesPreview {...props}
|
|
128
120
|
value={value}
|
|
129
121
|
property={property as ResolvedArrayProperty}/>;
|
|
@@ -182,8 +174,9 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
182
174
|
content = <ReferencePreview
|
|
183
175
|
disabled={!property.path}
|
|
184
176
|
previewProperties={property.previewProperties}
|
|
177
|
+
includeId={property.includeId}
|
|
178
|
+
includeEntityLink={property.includeEntityLink}
|
|
185
179
|
size={props.size}
|
|
186
|
-
// onClick={props.onClick}
|
|
187
180
|
reference={value as EntityReference}
|
|
188
181
|
/>;
|
|
189
182
|
} else {
|
|
@@ -3,7 +3,7 @@ import { CMSType, Property, ResolvedProperty } from "../types";
|
|
|
3
3
|
/**
|
|
4
4
|
* @group Preview components
|
|
5
5
|
*/
|
|
6
|
-
export type PreviewSize = "
|
|
6
|
+
export type PreviewSize = "small" | "medium" | "large";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @group Preview components
|
|
@@ -46,4 +46,10 @@ export interface PropertyPreviewProps<T extends CMSType = any, CustomProps = any
|
|
|
46
46
|
*/
|
|
47
47
|
customProps?: CustomProps;
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* If the preview should be interactive or not.
|
|
51
|
+
* This applies only to videos.
|
|
52
|
+
*/
|
|
53
|
+
interactive?: boolean;
|
|
54
|
+
|
|
49
55
|
}
|