@firecms/core 3.0.0-canary.20 → 3.0.0-canary.200
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 +33 -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 +45 -69
- package/dist/form/EntityFormActions.d.ts +17 -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 +22071 -14330
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +24420 -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 +6 -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 +6 -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 +207 -113
- 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 +374 -480
- package/src/core/EntityEditViewFormActions.tsx +199 -0
- package/src/core/EntitySidePanel.tsx +86 -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 +562 -524
- package/src/form/EntityFormActions.tsx +169 -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 +177 -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 +236 -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 +15 -0
- package/src/types/side_entity_controller.tsx +6 -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 +13 -6
- 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,58 @@ 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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
sideDialogsController.open(propsToSidePanel(panel, navigation, smallLayout))
|
|
48
|
-
}, 1);
|
|
106
|
+
const props = panelsFromUrl[i];
|
|
107
|
+
if (i === 0)
|
|
108
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
109
|
+
else
|
|
110
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout))
|
|
49
111
|
}
|
|
50
112
|
}
|
|
51
113
|
initialised.current = true;
|
|
52
114
|
}
|
|
53
|
-
}, [
|
|
115
|
+
}, [navigation.loading]);
|
|
116
|
+
|
|
117
|
+
// sync panels if URL changes with #side
|
|
118
|
+
const currentPanelKeys = sideDialogsController.sidePanels.map(p => p.key);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (initialised.current) {
|
|
121
|
+
const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
|
|
122
|
+
if (sideFlag) {
|
|
123
|
+
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
124
|
+
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], false);
|
|
125
|
+
// if we have more panels than determined by the url, we ignore the url. We might have references open
|
|
126
|
+
if (panelsFromUrl.length <= currentPanelKeys.length) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
|
|
130
|
+
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
131
|
+
const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
|
|
132
|
+
if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
|
|
133
|
+
sideDialogsController.replace(panelProps);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}, [location.pathname, location.hash, currentPanelKeys]);
|
|
138
|
+
|
|
139
|
+
// update side panels to match browser size
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
|
|
142
|
+
if (sidePanelProps.additional) {
|
|
143
|
+
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout);
|
|
144
|
+
}
|
|
145
|
+
return sidePanelProps;
|
|
146
|
+
});
|
|
147
|
+
sideDialogsController.setSidePanels(updatedSidePanels);
|
|
148
|
+
}, [smallLayout]);
|
|
54
149
|
|
|
55
150
|
const close = useCallback(() => {
|
|
56
151
|
sideDialogsController.close();
|
|
@@ -70,12 +165,17 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
70
165
|
}
|
|
71
166
|
);
|
|
72
167
|
|
|
73
|
-
sideDialogsController.open(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
168
|
+
sideDialogsController.open(
|
|
169
|
+
propsToSidePanel({
|
|
170
|
+
selectedTab: defaultSelectedView,
|
|
171
|
+
...props
|
|
172
|
+
},
|
|
173
|
+
navigation.buildUrlCollectionPath,
|
|
174
|
+
navigation.resolveIdsFrom,
|
|
175
|
+
smallLayout
|
|
176
|
+
));
|
|
77
177
|
|
|
78
|
-
}, [sideDialogsController, navigation, smallLayout]);
|
|
178
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
|
|
79
179
|
|
|
80
180
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
81
181
|
|
|
@@ -83,9 +183,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
83
183
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
84
184
|
}
|
|
85
185
|
|
|
86
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation, smallLayout));
|
|
186
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout));
|
|
87
187
|
|
|
88
|
-
}, [navigation, sideDialogsController, smallLayout]);
|
|
188
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
|
|
89
189
|
|
|
90
190
|
return {
|
|
91
191
|
close,
|
|
@@ -96,12 +196,12 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
96
196
|
|
|
97
197
|
export function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {
|
|
98
198
|
|
|
99
|
-
const navigationViewsForPath: NavigationViewInternal<any>[] =
|
|
199
|
+
const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPath({
|
|
100
200
|
path,
|
|
101
201
|
collections
|
|
102
202
|
});
|
|
103
203
|
|
|
104
|
-
|
|
204
|
+
let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
|
|
105
205
|
let lastCollectionPath = "";
|
|
106
206
|
for (let i = 0; i < navigationViewsForPath.length; i++) {
|
|
107
207
|
const navigationEntry = navigationViewsForPath[i];
|
|
@@ -110,63 +210,70 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
110
210
|
lastCollectionPath = navigationEntry.path;
|
|
111
211
|
}
|
|
112
212
|
|
|
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
|
-
}
|
|
213
|
+
const previousEntry = navigationViewsForPath[i - 1];
|
|
214
|
+
if (navigationEntry.type === "entity") {
|
|
215
|
+
sidePanel = {
|
|
216
|
+
path: navigationEntry.path,
|
|
217
|
+
entityId: navigationEntry.entityId,
|
|
218
|
+
copy: false,
|
|
219
|
+
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
220
|
+
};
|
|
221
|
+
} else if (navigationEntry.type === "custom_view") {
|
|
222
|
+
if (previousEntry?.type === "entity") {
|
|
223
|
+
if (sidePanel)
|
|
224
|
+
sidePanel.selectedTab = navigationEntry.view.key;
|
|
225
|
+
}
|
|
226
|
+
} else if (navigationEntry.type === "collection") {
|
|
227
|
+
if (previousEntry?.type === "entity") {
|
|
228
|
+
if (sidePanel)
|
|
229
|
+
sidePanel.selectedTab = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
134
230
|
}
|
|
135
231
|
}
|
|
136
232
|
|
|
137
233
|
}
|
|
138
234
|
|
|
139
235
|
if (newFlag) {
|
|
140
|
-
|
|
236
|
+
sidePanel = {
|
|
141
237
|
path: lastCollectionPath,
|
|
142
238
|
copy: false
|
|
143
|
-
}
|
|
239
|
+
}
|
|
144
240
|
}
|
|
145
241
|
|
|
146
|
-
return
|
|
242
|
+
return sidePanel ? [sidePanel] : [];
|
|
147
243
|
}
|
|
148
244
|
|
|
149
|
-
const propsToSidePanel = (props: EntitySidePanelProps<any>, navigation: NavigationController, smallLayout: boolean): SideDialogPanelProps => {
|
|
150
245
|
|
|
151
|
-
|
|
246
|
+
const propsToSidePanel = (props: EntitySidePanelProps,
|
|
247
|
+
buildUrlCollectionPath: (path: string) => string,
|
|
248
|
+
resolveIdsFrom: (pathWithAliases: string) => string,
|
|
249
|
+
smallLayout: boolean): SideDialogPanelProps => {
|
|
152
250
|
|
|
153
|
-
|
|
154
|
-
? navigation.buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || ""}`)
|
|
155
|
-
: navigation.buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
156
|
-
const resolvedPath = navigation.resolveAliasesFrom(props.path);
|
|
251
|
+
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
157
252
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
253
|
+
const newPath = props.entityId
|
|
254
|
+
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
|
|
255
|
+
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
256
|
+
const resolvedPath = resolveIdsFrom(props.path);
|
|
162
257
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
258
|
+
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
259
|
+
...props,
|
|
260
|
+
path: resolvedPath,
|
|
261
|
+
formProps: props.formProps
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const entityViewWidth = getEntityViewWidth(props, smallLayout);
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
key: `${props.path}/${props.entityId}`,
|
|
268
|
+
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
269
|
+
urlPath: newPath,
|
|
270
|
+
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
271
|
+
width: entityViewWidth,
|
|
272
|
+
onClose: props.onClose,
|
|
273
|
+
additional: props
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function isSideUrl(url: string): boolean {
|
|
278
|
+
return url.endsWith("#" + SIDE_URL_HASH) || url.endsWith("#" + NEW_URL_HASH);
|
|
279
|
+
}
|
|
@@ -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
|
}
|