@firecms/core 3.0.0-beta.10 → 3.0.0-beta.12
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/dist/components/ArrayContainer.d.ts +22 -6
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
- package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
- package/dist/components/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
- package/dist/components/common/default_entity_actions.d.ts +0 -2
- package/dist/components/common/index.d.ts +1 -1
- package/dist/components/common/useColumnsIds.d.ts +1 -0
- package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
- package/dist/components/common/useDebouncedCallback.d.ts +1 -0
- package/dist/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/contexts/BreacrumbsContext.d.ts +8 -0
- package/dist/core/EntityEditView.d.ts +30 -22
- package/dist/core/EntityEditViewFormActions.d.ts +2 -0
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/core/FireCMSRouter.d.ts +4 -0
- package/dist/core/NavigationRoutes.d.ts +0 -1
- package/dist/core/SideDialogs.d.ts +4 -2
- package/dist/core/index.d.ts +2 -1
- package/dist/form/EntityForm.d.ts +45 -0
- package/dist/form/EntityFormActions.d.ts +17 -0
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FormEntry.d.ts +6 -0
- package/dist/form/components/FormLayout.d.ts +5 -0
- package/dist/form/components/index.d.ts +2 -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/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.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/SwitchFieldBinding.d.ts +1 -2
- package/dist/form/index.d.ts +16 -16
- package/dist/hooks/data/delete.d.ts +4 -4
- package/dist/hooks/data/save.d.ts +3 -3
- package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +4 -3
- package/dist/hooks/useAuthController.d.ts +1 -1
- package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
- package/dist/hooks/useBuildNavigationController.d.ts +7 -4
- package/dist/hooks/useFireCMSContext.d.ts +1 -1
- package/dist/hooks/useModeController.d.ts +1 -2
- package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
- package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
- package/dist/index.es.js +17032 -12909
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +17019 -12898
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildSideEntityController.d.ts +2 -2
- package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
- package/dist/preview/PropertyPreviewProps.d.ts +1 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -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 +7 -9
- package/dist/types/collections.d.ts +44 -23
- package/dist/types/datasource.d.ts +2 -6
- package/dist/types/dialogs_controller.d.ts +7 -3
- package/dist/types/entities.d.ts +1 -1
- package/dist/types/entity_actions.d.ts +14 -4
- package/dist/types/entity_callbacks.d.ts +16 -16
- package/dist/types/export_import.d.ts +4 -4
- package/dist/types/fields.d.ts +27 -4
- package/dist/types/firecms.d.ts +2 -2
- package/dist/types/firecms_context.d.ts +1 -1
- package/dist/types/navigation.d.ts +29 -12
- package/dist/types/permissions.d.ts +4 -4
- package/dist/types/plugins.d.ts +9 -8
- package/dist/types/properties.d.ts +18 -3
- package/dist/types/property_config.d.ts +0 -2
- package/dist/types/side_entity_controller.d.ts +6 -1
- package/dist/types/user.d.ts +1 -0
- package/dist/util/builders.d.ts +3 -3
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/entity_actions.d.ts +2 -0
- package/dist/util/entity_cache.d.ts +23 -0
- package/dist/util/icon_synonyms.d.ts +0 -1
- package/dist/util/icons.d.ts +3 -1
- package/dist/util/index.d.ts +1 -0
- package/dist/util/navigation_from_path.d.ts +6 -1
- package/dist/util/navigation_utils.d.ts +12 -1
- package/dist/util/objects.d.ts +1 -0
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/resolutions.d.ts +12 -7
- package/package.json +129 -125
- package/src/app/Scaffold.tsx +4 -4
- package/src/components/ArrayContainer.tsx +115 -34
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/ConfirmationDialog.tsx +2 -2
- package/src/components/DeleteEntityDialog.tsx +10 -19
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +44 -20
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +77 -73
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +90 -49
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
- package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
- package/src/components/EntityPreview.tsx +39 -30
- package/src/components/EntityView.tsx +5 -5
- package/src/components/ErrorView.tsx +3 -3
- package/src/components/HomePage/DefaultHomePage.tsx +1 -0
- package/src/components/HomePage/FavouritesView.tsx +6 -11
- package/src/components/HomePage/NavigationCard.tsx +1 -1
- package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
- package/src/components/HomePage/NavigationGroup.tsx +1 -1
- package/src/components/NotFoundPage.tsx +2 -2
- package/src/components/PropertyConfigBadge.tsx +1 -1
- package/src/components/PropertyIdCopyTooltip.tsx +3 -4
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +13 -8
- package/src/components/SelectableTable/SelectableTable.tsx +20 -5
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
- package/src/components/UnsavedChangesDialog.tsx +42 -0
- package/src/components/VirtualTable/VirtualTable.tsx +19 -2
- package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
- package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
- package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
- package/src/components/common/default_entity_actions.tsx +26 -37
- package/src/components/common/index.ts +1 -1
- package/src/components/common/useColumnsIds.tsx +1 -1
- 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/contexts/BreacrumbsContext.tsx +38 -0
- package/src/contexts/DialogsProvider.tsx +3 -2
- package/src/contexts/ModeController.tsx +1 -3
- package/src/contexts/SnackbarProvider.tsx +2 -0
- package/src/core/DefaultAppBar.tsx +56 -25
- package/src/core/DefaultDrawer.tsx +11 -9
- package/src/core/DrawerNavigationItem.tsx +4 -4
- package/src/core/EntityEditView.tsx +282 -1006
- package/src/core/EntityEditViewFormActions.tsx +199 -0
- package/src/core/EntitySidePanel.tsx +85 -15
- package/src/core/FireCMS.tsx +12 -9
- package/src/core/FireCMSRouter.tsx +17 -0
- package/src/core/NavigationRoutes.tsx +23 -32
- package/src/core/SideDialogs.tsx +21 -12
- package/src/core/field_configs.tsx +4 -4
- package/src/core/index.tsx +4 -2
- package/src/form/EntityForm.tsx +774 -0
- package/src/form/EntityFormActions.tsx +169 -0
- package/src/form/PropertyFieldBinding.tsx +39 -30
- package/src/form/components/CustomIdField.tsx +2 -0
- package/src/form/components/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- package/src/form/components/LabelWithIcon.tsx +6 -3
- package/src/form/components/StorageItemPreview.tsx +3 -3
- package/src/form/components/StorageUploadProgress.tsx +1 -1
- package/src/form/components/index.tsx +2 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +7 -6
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +20 -12
- package/src/form/field_bindings/BlockFieldBinding.tsx +45 -25
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
- package/src/form/field_bindings/MapFieldBinding.tsx +69 -52
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +9 -6
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -5
- package/src/form/field_bindings/RepeatFieldBinding.tsx +30 -22
- package/src/form/field_bindings/SelectFieldBinding.tsx +6 -5
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +7 -5
- package/src/form/field_bindings/SwitchFieldBinding.tsx +26 -25
- package/src/form/field_bindings/TextFieldBinding.tsx +4 -3
- package/src/form/index.tsx +16 -32
- package/src/form/validation.ts +12 -6
- package/src/hooks/data/delete.ts +4 -4
- package/src/hooks/data/save.ts +8 -9
- package/src/hooks/data/useCollectionFetch.tsx +3 -3
- package/src/hooks/data/useEntityFetch.tsx +10 -6
- package/src/hooks/useAuthController.tsx +1 -1
- package/src/hooks/useBreadcrumbsController.tsx +31 -0
- package/src/hooks/useBuildModeController.tsx +15 -28
- package/src/hooks/useBuildNavigationController.tsx +74 -29
- package/src/hooks/useFireCMSContext.tsx +5 -5
- package/src/hooks/useLargeLayout.tsx +0 -35
- package/src/hooks/useModeController.tsx +1 -2
- package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
- package/src/hooks/useValidateAuthenticator.tsx +3 -3
- package/src/internal/useBuildDataSource.ts +1 -1
- package/src/internal/useBuildSideDialogsController.tsx +3 -2
- package/src/internal/useBuildSideEntityController.tsx +124 -83
- package/src/internal/useUnsavedChangesDialog.tsx +127 -93
- package/src/preview/PropertyPreview.tsx +11 -11
- package/src/preview/PropertyPreviewProps.tsx +1 -1
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +5 -6
- package/src/preview/components/UrlComponentPreview.tsx +20 -21
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
- package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/preview/util.ts +10 -10
- package/src/routes/CustomCMSRoute.tsx +21 -0
- package/src/routes/FireCMSRoute.tsx +235 -0
- package/src/routes/HomePageRoute.tsx +17 -0
- package/src/types/auth.tsx +8 -12
- package/src/types/collections.ts +52 -26
- package/src/types/datasource.ts +2 -6
- package/src/types/dialogs_controller.tsx +7 -3
- package/src/types/entities.ts +1 -1
- package/src/types/entity_actions.tsx +16 -4
- package/src/types/entity_callbacks.ts +18 -18
- package/src/types/export_import.ts +4 -4
- package/src/types/fields.tsx +33 -4
- package/src/types/firecms.tsx +2 -2
- package/src/types/firecms_context.tsx +1 -1
- package/src/types/navigation.ts +36 -16
- package/src/types/permissions.ts +5 -5
- package/src/types/plugins.tsx +9 -8
- package/src/types/properties.ts +21 -3
- package/src/types/property_config.tsx +0 -2
- package/src/types/side_dialogs_controller.tsx +2 -0
- package/src/types/side_entity_controller.tsx +6 -1
- package/src/types/user.ts +2 -0
- package/src/util/builders.ts +10 -8
- package/src/util/entities.ts +3 -1
- package/src/util/entity_actions.ts +28 -0
- package/src/util/entity_cache.ts +204 -0
- package/src/util/icon_list.ts +1 -0
- package/src/util/icon_synonyms.ts +0 -1
- package/src/util/icons.tsx +12 -8
- package/src/util/index.ts +1 -0
- package/src/util/join_collections.ts +3 -0
- package/src/util/navigation_from_path.ts +13 -6
- package/src/util/navigation_utils.ts +53 -1
- package/src/util/objects.ts +24 -1
- package/src/util/parent_references_from_path.ts +3 -3
- package/src/util/permissions.ts +8 -8
- package/src/util/property_utils.tsx +10 -3
- package/src/util/references.ts +8 -2
- package/src/util/resolutions.ts +34 -13
- package/src/util/useStorageUploadController.tsx +40 -22
- package/dist/form/components/FormikArrayContainer.d.ts +0 -19
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
- package/src/form/components/FormikArrayContainer.tsx +0 -47
- /package/src/util/{common.tsx → common.ts} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import {
|
|
3
|
+
CustomizationController,
|
|
3
4
|
EntityCollection,
|
|
4
5
|
EntitySidePanelProps,
|
|
5
6
|
NavigationController,
|
|
@@ -8,18 +9,30 @@ import {
|
|
|
8
9
|
SideDialogsController,
|
|
9
10
|
SideEntityController
|
|
10
11
|
} from "../types";
|
|
11
|
-
import {
|
|
12
|
+
import { getNavigationEntriesFromPath, NavigationViewInternal } from "../util/navigation_from_path";
|
|
12
13
|
import { useLocation } from "react-router-dom";
|
|
13
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
removeInitialAndTrailingSlashes,
|
|
16
|
+
resolveCollection,
|
|
17
|
+
resolveDefaultSelectedView,
|
|
18
|
+
resolvedSelectedEntityView
|
|
19
|
+
} from "../util";
|
|
14
20
|
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
|
|
15
|
-
import { useLargeLayout } from "../hooks";
|
|
21
|
+
import { useCustomizationController, useLargeLayout } from "../hooks";
|
|
16
22
|
import { EntitySidePanel } from "../core/EntitySidePanel";
|
|
17
23
|
|
|
18
|
-
const NEW_URL_HASH = "
|
|
24
|
+
const NEW_URL_HASH = "new_side";
|
|
25
|
+
const SIDE_URL_HASH = "side";
|
|
19
26
|
|
|
20
|
-
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {
|
|
27
|
+
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string {
|
|
21
28
|
if (small) return CONTAINER_FULL_WIDTH;
|
|
22
|
-
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
selectedSecondaryForm
|
|
32
|
+
} = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
|
|
33
|
+
|
|
34
|
+
const shouldUseSmallLayout = !props.selectedTab || Boolean(selectedSecondaryForm);
|
|
35
|
+
|
|
23
36
|
let resolvedWidth: string | undefined;
|
|
24
37
|
if (props.width) {
|
|
25
38
|
resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
@@ -27,7 +40,7 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
|
|
|
27
40
|
resolvedWidth = typeof props.collection.sideDialogWidth === "number" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
if (!
|
|
43
|
+
if (!shouldUseSmallLayout) {
|
|
31
44
|
return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`
|
|
32
45
|
} else {
|
|
33
46
|
if (resolvedWidth) {
|
|
@@ -88,37 +101,59 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
88
101
|
|
|
89
102
|
const location = useLocation();
|
|
90
103
|
const initialised = useRef<boolean>(false);
|
|
104
|
+
const customizationController = useCustomizationController();
|
|
91
105
|
|
|
92
106
|
const smallLayout = !useLargeLayout();
|
|
93
107
|
|
|
94
108
|
// only on initialisation, create panels from URL
|
|
95
109
|
useEffect(() => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
|
|
111
|
+
const newFlag = location.hash === `#${NEW_URL_HASH}`;
|
|
112
|
+
const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
|
|
113
|
+
|
|
114
|
+
if (!navigation.loading) {
|
|
115
|
+
if ((newFlag || sideFlag) && navigation.isUrlCollectionPath(location.pathname)) {
|
|
100
116
|
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
101
117
|
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);
|
|
102
118
|
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
103
119
|
const props = panelsFromUrl[i];
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))
|
|
109
|
-
}, 1);
|
|
120
|
+
if (i === 0)
|
|
121
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
122
|
+
else
|
|
123
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController))
|
|
110
124
|
}
|
|
111
|
-
} else {
|
|
112
|
-
// console.warn("Location path is not a collection path");
|
|
113
125
|
}
|
|
114
126
|
initialised.current = true;
|
|
115
127
|
}
|
|
116
|
-
}, [
|
|
128
|
+
}, [navigation.loading]);
|
|
117
129
|
|
|
130
|
+
// sync panels if URL changes with #side
|
|
131
|
+
const currentPanelKeys = sideDialogsController.sidePanels.map(p => p.key);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
if (initialised.current) {
|
|
134
|
+
const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
|
|
135
|
+
if (sideFlag) {
|
|
136
|
+
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
137
|
+
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], false);
|
|
138
|
+
// if we have more panels than determined by the url, we ignore the url. We might have references open
|
|
139
|
+
if (panelsFromUrl.length <= currentPanelKeys.length) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
|
|
143
|
+
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
144
|
+
const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
|
|
145
|
+
if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
|
|
146
|
+
sideDialogsController.replace(panelProps);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}, [location.pathname, location.hash, currentPanelKeys]);
|
|
151
|
+
|
|
152
|
+
// update side panels to match browser size
|
|
118
153
|
useEffect(() => {
|
|
119
154
|
const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
|
|
120
155
|
if (sidePanelProps.additional) {
|
|
121
|
-
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.
|
|
156
|
+
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
122
157
|
}
|
|
123
158
|
return sidePanelProps;
|
|
124
159
|
});
|
|
@@ -143,12 +178,18 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
143
178
|
}
|
|
144
179
|
);
|
|
145
180
|
|
|
146
|
-
sideDialogsController.open(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
181
|
+
sideDialogsController.open(
|
|
182
|
+
propsToSidePanel({
|
|
183
|
+
selectedTab: defaultSelectedView,
|
|
184
|
+
...props
|
|
185
|
+
},
|
|
186
|
+
navigation.buildUrlCollectionPath,
|
|
187
|
+
navigation.resolveIdsFrom,
|
|
188
|
+
smallLayout,
|
|
189
|
+
customizationController
|
|
190
|
+
));
|
|
150
191
|
|
|
151
|
-
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.
|
|
192
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
|
|
152
193
|
|
|
153
194
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
154
195
|
|
|
@@ -156,9 +197,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
156
197
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
157
198
|
}
|
|
158
199
|
|
|
159
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.
|
|
200
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
160
201
|
|
|
161
|
-
}, [navigation.buildUrlCollectionPath, navigation.
|
|
202
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
|
|
162
203
|
|
|
163
204
|
return {
|
|
164
205
|
close,
|
|
@@ -169,12 +210,12 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
169
210
|
|
|
170
211
|
export function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {
|
|
171
212
|
|
|
172
|
-
const navigationViewsForPath: NavigationViewInternal<any>[] =
|
|
213
|
+
const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPath({
|
|
173
214
|
path,
|
|
174
215
|
collections
|
|
175
216
|
});
|
|
176
217
|
|
|
177
|
-
|
|
218
|
+
let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
|
|
178
219
|
let lastCollectionPath = "";
|
|
179
220
|
for (let i = 0; i < navigationViewsForPath.length; i++) {
|
|
180
221
|
const navigationEntry = navigationViewsForPath[i];
|
|
@@ -183,70 +224,70 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
183
224
|
lastCollectionPath = navigationEntry.path;
|
|
184
225
|
}
|
|
185
226
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (previousEntry.type === "entity") {
|
|
204
|
-
const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];
|
|
205
|
-
if (lastSidePanel)
|
|
206
|
-
lastSidePanel.selectedSubPath = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
207
|
-
}
|
|
227
|
+
const previousEntry = navigationViewsForPath[i - 1];
|
|
228
|
+
if (navigationEntry.type === "entity") {
|
|
229
|
+
sidePanel = {
|
|
230
|
+
path: navigationEntry.path,
|
|
231
|
+
entityId: navigationEntry.entityId,
|
|
232
|
+
copy: false,
|
|
233
|
+
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
234
|
+
};
|
|
235
|
+
} else if (navigationEntry.type === "custom_view") {
|
|
236
|
+
if (previousEntry?.type === "entity") {
|
|
237
|
+
if (sidePanel)
|
|
238
|
+
sidePanel.selectedTab = navigationEntry.view.key;
|
|
239
|
+
}
|
|
240
|
+
} else if (navigationEntry.type === "collection") {
|
|
241
|
+
if (previousEntry?.type === "entity") {
|
|
242
|
+
if (sidePanel)
|
|
243
|
+
sidePanel.selectedTab = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
208
244
|
}
|
|
209
245
|
}
|
|
210
246
|
|
|
211
247
|
}
|
|
212
248
|
|
|
213
249
|
if (newFlag) {
|
|
214
|
-
|
|
250
|
+
sidePanel = {
|
|
215
251
|
path: lastCollectionPath,
|
|
216
252
|
copy: false
|
|
217
|
-
}
|
|
253
|
+
}
|
|
218
254
|
}
|
|
219
255
|
|
|
220
|
-
return
|
|
256
|
+
return sidePanel ? [sidePanel] : [];
|
|
221
257
|
}
|
|
222
258
|
|
|
223
259
|
const propsToSidePanel = (props: EntitySidePanelProps,
|
|
224
260
|
buildUrlCollectionPath: (path: string) => string,
|
|
225
|
-
|
|
226
|
-
smallLayout: boolean
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
;
|
|
261
|
+
resolveIdsFrom: (pathWithAliases: string) => string,
|
|
262
|
+
smallLayout: boolean,
|
|
263
|
+
customizationController: CustomizationController): SideDialogPanelProps => {
|
|
264
|
+
|
|
265
|
+
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
266
|
+
|
|
267
|
+
const newPath = props.entityId
|
|
268
|
+
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
|
|
269
|
+
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
270
|
+
const resolvedPath = resolveIdsFrom(props.path);
|
|
271
|
+
|
|
272
|
+
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
273
|
+
...props,
|
|
274
|
+
path: resolvedPath,
|
|
275
|
+
formProps: props.formProps
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
key: `${props.path}/${props.entityId}`,
|
|
282
|
+
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
283
|
+
urlPath: newPath,
|
|
284
|
+
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
285
|
+
width: entityViewWidth,
|
|
286
|
+
onClose: props.onClose,
|
|
287
|
+
additional: props
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function isSideUrl(url: string): boolean {
|
|
292
|
+
return url.endsWith("#" + SIDE_URL_HASH) || url.endsWith("#" + NEW_URL_HASH);
|
|
293
|
+
}
|
|
@@ -1,108 +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
|
-
onEscapeKeyDown={() => {
|
|
88
|
-
handleCancel();
|
|
89
|
-
}}
|
|
90
|
-
open={open}
|
|
91
|
-
>
|
|
92
|
-
<DialogContent>
|
|
93
|
-
<Typography variant={"h6"}>{title}</Typography>
|
|
94
|
-
|
|
95
|
-
{body}
|
|
96
|
-
|
|
97
|
-
<Typography>
|
|
98
|
-
Are you sure you want to leave this page?
|
|
99
|
-
</Typography>
|
|
100
|
-
|
|
101
|
-
</DialogContent>
|
|
102
|
-
<DialogActions>
|
|
103
|
-
<Button variant="text" onClick={handleCancel} autoFocus> Cancel </Button>
|
|
104
|
-
<Button onClick={handleOk}> Ok </Button>
|
|
105
|
-
</DialogActions>
|
|
106
|
-
</Dialog>
|
|
107
|
-
);
|
|
108
|
-
}
|
|
@@ -53,10 +53,10 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
53
53
|
const property = resolveProperty({
|
|
54
54
|
propertyKey,
|
|
55
55
|
propertyOrBuilder: inputProperty,
|
|
56
|
-
|
|
56
|
+
propertyConfigs: customizationController.propertyConfigs
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
if (
|
|
59
|
+
if (property === null) {
|
|
60
60
|
content = <EmptyValue/>;
|
|
61
61
|
} else if (property.Preview) {
|
|
62
62
|
content = createElement(property.Preview as React.ComponentType<PropertyPreviewProps>,
|
|
@@ -70,12 +70,19 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
70
70
|
// entity,
|
|
71
71
|
customProps: property.customProps
|
|
72
72
|
});
|
|
73
|
-
} else if (value === null) {
|
|
73
|
+
} else if (value === undefined || value === null) {
|
|
74
74
|
content = <EmptyValue/>;
|
|
75
75
|
} else if (property.dataType === "string") {
|
|
76
76
|
const stringProperty = property as ResolvedStringProperty;
|
|
77
77
|
if (typeof value === "string") {
|
|
78
|
-
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) {
|
|
79
86
|
if (typeof stringProperty.url === "boolean")
|
|
80
87
|
content =
|
|
81
88
|
<UrlComponentPreview size={props.size}
|
|
@@ -88,13 +95,6 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
88
95
|
previewType={stringProperty.url}/>;
|
|
89
96
|
} else if (stringProperty.markdown) {
|
|
90
97
|
content = <Markdown source={value} size={"small"}/>;
|
|
91
|
-
} else if (stringProperty.storage) {
|
|
92
|
-
const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
|
|
93
|
-
content = <StorageThumbnail
|
|
94
|
-
interactive={interactive}
|
|
95
|
-
storeUrl={property.storage?.storeUrl ?? false}
|
|
96
|
-
size={props.size}
|
|
97
|
-
storagePathOrDownloadUrl={filePath}/>;
|
|
98
98
|
} else {
|
|
99
99
|
content = <StringPropertyPreview {...props}
|
|
100
100
|
property={stringProperty}
|
|
@@ -21,6 +21,6 @@ export function BooleanPreview({
|
|
|
21
21
|
size={size}
|
|
22
22
|
color={"secondary"}/>
|
|
23
23
|
{property.name && <span
|
|
24
|
-
className={cls("text-text-secondary dark:text-text-secondary-dark", size === "
|
|
24
|
+
className={cls("text-text-secondary dark:text-text-secondary-dark", size === "small" ? "text-sm" : "")}>{property.name}</span>}
|
|
25
25
|
</div>;
|
|
26
26
|
}
|
|
@@ -6,5 +6,5 @@ import React from "react";
|
|
|
6
6
|
export function EmptyValue() {
|
|
7
7
|
|
|
8
8
|
return <div
|
|
9
|
-
className="rounded-full bg-
|
|
9
|
+
className="rounded-full bg-surface-200 bg-opacity-30 dark:bg-opacity-20 w-5 h-2 inline-block"/>;
|
|
10
10
|
}
|
|
@@ -6,7 +6,7 @@ import { buildEnumLabel, enumToObjectEntries, getColorScheme, getLabelOrConfigFr
|
|
|
6
6
|
export interface EnumValuesChipProps {
|
|
7
7
|
enumValues?: EnumValues;
|
|
8
8
|
enumKey: string | number;
|
|
9
|
-
size: "
|
|
9
|
+
size: "small" | "medium" | "large";
|
|
10
10
|
className?: string;
|
|
11
11
|
children?: React.ReactNode;
|
|
12
12
|
}
|
|
@@ -22,7 +22,7 @@ export function ImagePreview({
|
|
|
22
22
|
|
|
23
23
|
const imageSize = useMemo(() => getThumbnailMeasure(size), [size]);
|
|
24
24
|
|
|
25
|
-
if (size === "
|
|
25
|
+
if (size === "small") {
|
|
26
26
|
return (
|
|
27
27
|
<img src={url}
|
|
28
28
|
className={"rounded-md"}
|
|
@@ -56,7 +56,6 @@ export function ImagePreview({
|
|
|
56
56
|
className={"rounded-md"}
|
|
57
57
|
style={imageStyle}/>
|
|
58
58
|
|
|
59
|
-
|
|
60
59
|
<div className={"flex flex-row gap-2 absolute bottom-[-4px] right-[-4px] invisible group-hover:visible"}>
|
|
61
60
|
{navigator && <Tooltip
|
|
62
61
|
asChild={true}
|
|
@@ -69,8 +68,8 @@ export function ImagePreview({
|
|
|
69
68
|
e.preventDefault();
|
|
70
69
|
return navigator.clipboard.writeText(url);
|
|
71
70
|
}}>
|
|
72
|
-
<ContentCopyIcon className={"text-
|
|
73
|
-
size={"
|
|
71
|
+
<ContentCopyIcon className={"text-surface-700 dark:text-surface-300"}
|
|
72
|
+
size={"smallest"}/>
|
|
74
73
|
</IconButton>
|
|
75
74
|
</Tooltip>}
|
|
76
75
|
|
|
@@ -85,8 +84,8 @@ export function ImagePreview({
|
|
|
85
84
|
size={"small"}
|
|
86
85
|
onClick={(e: any) => e.stopPropagation()}
|
|
87
86
|
>
|
|
88
|
-
<OpenInNewIcon className={"text-
|
|
89
|
-
size={"
|
|
87
|
+
<OpenInNewIcon className={"text-surface-700 dark:text-surface-300"}
|
|
88
|
+
size={"smallest"}/>
|
|
90
89
|
</IconButton>
|
|
91
90
|
</Tooltip>
|
|
92
91
|
</div>
|