@firecms/core 3.0.0-beta.6 → 3.0.0-beta.8
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/app/AppBar.d.ts +12 -0
- package/dist/app/Drawer.d.ts +17 -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/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
- 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 +2 -0
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityPreview.d.ts +3 -2
- package/dist/components/ReferenceWidget.d.ts +3 -1
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +5 -6
- package/dist/components/VirtualTable/types.d.ts +3 -3
- package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/common/table_height.d.ts +5 -0
- package/dist/components/common/types.d.ts +3 -5
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +5 -8
- package/dist/core/DefaultDrawer.d.ts +19 -0
- package/dist/core/DrawerNavigationItem.d.ts +9 -0
- package/dist/core/EntityEditView.d.ts +17 -3
- package/dist/core/NavigationRoutes.d.ts +2 -2
- package/dist/core/index.d.ts +3 -4
- package/dist/form/PropertiesForm.d.ts +8 -0
- package/dist/form/components/FieldHelperText.d.ts +3 -3
- package/dist/form/components/StorageItemPreview.d.ts +4 -4
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +2 -4
- package/dist/form/index.d.ts +0 -2
- package/dist/hooks/data/save.d.ts +1 -2
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +10199 -10140
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +5 -0
- package/dist/preview/components/ReferencePreview.d.ts +2 -1
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/collections.d.ts +22 -1
- package/dist/types/datasource.d.ts +18 -8
- package/dist/types/entity_actions.d.ts +14 -0
- package/dist/types/fields.d.ts +31 -30
- package/dist/types/navigation.d.ts +2 -2
- package/dist/types/plugins.d.ts +11 -3
- package/dist/types/properties.d.ts +15 -2
- package/dist/util/icon_synonyms.d.ts +1 -97
- package/dist/util/icons.d.ts +2 -2
- package/dist/util/objects.d.ts +1 -1
- package/dist/util/resolutions.d.ts +8 -8
- package/dist/util/storage.d.ts +23 -2
- package/dist/util/useStorageUploadController.d.ts +1 -1
- package/package.json +130 -122
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +25 -0
- package/src/app/Scaffold.tsx +249 -0
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +32 -0
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +8 -10
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +9 -7
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +22 -15
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -1
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -6
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -5
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +26 -24
- package/src/components/EntityPreview.tsx +9 -7
- package/src/components/EntityView.tsx +4 -4
- package/src/components/HomePage/NavigationCard.tsx +2 -2
- package/src/components/HomePage/SmallNavigationCard.tsx +5 -5
- package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +1 -0
- package/src/components/ReferenceWidget.tsx +21 -11
- package/src/components/SearchIconsView.tsx +5 -5
- package/src/components/SelectableTable/SelectableTable.tsx +4 -2
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +4 -1
- package/src/components/VirtualTable/VirtualTable.tsx +13 -12
- package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
- package/src/components/VirtualTable/VirtualTableProps.tsx +6 -6
- package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
- package/src/components/VirtualTable/types.tsx +2 -3
- package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +2 -2
- package/src/components/common/index.ts +1 -0
- package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
- package/src/components/common/types.tsx +3 -5
- package/src/components/common/useColumnsIds.tsx +10 -2
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +11 -0
- package/src/components/common/useTableSearchHelper.ts +52 -12
- package/src/components/index.tsx +2 -1
- package/src/contexts/DialogsProvider.tsx +2 -2
- package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +51 -36
- package/src/core/DefaultDrawer.tsx +177 -0
- package/src/core/DrawerNavigationItem.tsx +62 -0
- package/src/core/EntityEditView.tsx +673 -134
- package/src/core/EntitySidePanel.tsx +1 -2
- package/src/core/FireCMS.tsx +36 -40
- package/src/core/NavigationRoutes.tsx +6 -7
- package/src/core/field_configs.tsx +1 -1
- package/src/core/index.tsx +3 -4
- package/src/form/PropertiesForm.tsx +81 -0
- package/src/form/PropertyFieldBinding.tsx +29 -7
- package/src/form/components/FieldHelperText.tsx +3 -3
- package/src/form/components/StorageItemPreview.tsx +20 -11
- package/src/form/components/StorageUploadProgress.tsx +3 -3
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -5
- package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +44 -39
- package/src/form/field_bindings/MapFieldBinding.tsx +11 -3
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +2 -2
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -9
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +15 -13
- package/src/form/field_bindings/RepeatFieldBinding.tsx +10 -7
- package/src/form/field_bindings/SelectFieldBinding.tsx +3 -3
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +10 -39
- package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -1
- package/src/form/index.tsx +4 -4
- package/src/form/validation.ts +1 -17
- package/src/hooks/data/save.ts +2 -1
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +2 -3
- package/src/hooks/useBuildNavigationController.tsx +1 -2
- package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
- package/src/hooks/useValidateAuthenticator.tsx +15 -15
- package/src/index.ts +1 -0
- package/src/internal/useBuildDataSource.ts +12 -0
- package/src/internal/useBuildSideEntityController.tsx +72 -11
- package/src/preview/PropertyPreview.tsx +7 -4
- package/src/preview/PropertyPreviewProps.tsx +6 -0
- package/src/preview/components/BooleanPreview.tsx +2 -2
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +21 -33
- package/src/preview/components/ReferencePreview.tsx +22 -22
- package/src/preview/components/StorageThumbnail.tsx +5 -1
- package/src/preview/components/UrlComponentPreview.tsx +44 -11
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
- package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/types/auth.tsx +1 -1
- package/src/types/collections.ts +28 -2
- package/src/types/customization_controller.tsx +0 -1
- package/src/types/datasource.ts +20 -16
- package/src/types/entity_actions.tsx +16 -3
- package/src/types/fields.tsx +33 -33
- package/src/types/navigation.ts +1 -2
- package/src/types/plugins.tsx +12 -3
- package/src/types/properties.ts +17 -2
- package/src/types/storage.ts +1 -1
- package/src/util/entities.ts +4 -3
- package/src/util/enums.ts +1 -1
- package/src/util/icon_list.ts +2 -2
- package/src/util/icon_synonyms.ts +3 -99
- package/src/util/objects.ts +25 -28
- package/src/util/permissions.ts +1 -0
- package/src/util/resolutions.ts +32 -31
- package/src/util/storage.ts +75 -21
- package/src/util/useStorageUploadController.tsx +21 -3
- package/dist/components/VirtualTable/common.d.ts +0 -2
- package/dist/core/Drawer.d.ts +0 -23
- package/dist/core/Scaffold.d.ts +0 -55
- package/dist/core/SideEntityView.d.ts +0 -7
- package/dist/form/EntityForm.d.ts +0 -77
- package/dist/internal/useBuildCustomizationController.d.ts +0 -2
- package/src/core/Drawer.tsx +0 -191
- package/src/core/Scaffold.tsx +0 -281
- package/src/core/SideEntityView.tsx +0 -38
- package/src/form/EntityForm.tsx +0 -728
- package/src/internal/useBuildCustomizationController.tsx +0 -5
package/src/hooks/data/save.ts
CHANGED
|
@@ -17,7 +17,6 @@ import { resolveCollection } from "../../util";
|
|
|
17
17
|
export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
|
|
18
18
|
SaveEntityProps<M> &
|
|
19
19
|
{
|
|
20
|
-
callbacks?: EntityCallbacks<M>;
|
|
21
20
|
onSaveSuccess?: (updatedEntity: Entity<M>) => void,
|
|
22
21
|
onSaveFailure?: (e: Error) => void,
|
|
23
22
|
onPreSaveHookError?: (e: Error) => void,
|
|
@@ -109,6 +108,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
|
|
|
109
108
|
updatedValues = values;
|
|
110
109
|
}
|
|
111
110
|
|
|
111
|
+
console.log("Saving entity", entityId, updatedValues);
|
|
112
112
|
return dataSource.saveEntity({
|
|
113
113
|
collection,
|
|
114
114
|
path: resolvedPath,
|
|
@@ -117,6 +117,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
|
|
|
117
117
|
previousValues,
|
|
118
118
|
status
|
|
119
119
|
}).then((entity) => {
|
|
120
|
+
console.log("Entity saved");
|
|
120
121
|
try {
|
|
121
122
|
if (callbacks?.onSaveSuccess) {
|
|
122
123
|
const resolvedCollection = resolveCollection<M>({
|
package/src/hooks/index.tsx
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./useResolvedNavigationFrom";
|
|
|
10
10
|
|
|
11
11
|
export * from "./useStorageSource";
|
|
12
12
|
export * from "./useAuthController";
|
|
13
|
+
export * from "./useDialogsController";
|
|
13
14
|
export * from "./useSideDialogsController";
|
|
14
15
|
export * from "./useSideEntityController";
|
|
15
16
|
export * from "./useFireCMSContext";
|
|
@@ -22,10 +22,9 @@ export function useBuildLocalConfigurationPersistence(): UserConfigurationPersis
|
|
|
22
22
|
const onCollectionModified = useCallback(<M extends Record<string, any>>(path: string, data: PartialEntityCollection<M>) => {
|
|
23
23
|
const storageKey = `collection_config::${stripCollectionPath(path)}`;
|
|
24
24
|
localStorage.setItem(storageKey, JSON.stringify(data));
|
|
25
|
-
const
|
|
26
|
-
const cachedConfig = currentCache[storageKey];
|
|
25
|
+
const cachedConfig = configCache.current[storageKey];
|
|
27
26
|
const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);
|
|
28
|
-
configCache.current = mergeDeep(
|
|
27
|
+
configCache.current[storageKey] = mergeDeep(configCache.current[storageKey], newConfig);
|
|
29
28
|
}, [getCollectionFromStorage]);
|
|
30
29
|
|
|
31
30
|
const [recentlyVisitedPaths, _setRecentlyVisitedPaths] = useState<string[]>([]);
|
|
@@ -241,7 +241,6 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
241
241
|
|
|
242
242
|
const getCollection = useCallback((
|
|
243
243
|
idOrPath: string,
|
|
244
|
-
entityId?: string,
|
|
245
244
|
includeUserOverride = false
|
|
246
245
|
): EC | undefined => {
|
|
247
246
|
const collections = collectionsRef.current;
|
|
@@ -251,7 +250,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
251
250
|
const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);
|
|
252
251
|
|
|
253
252
|
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
|
|
254
|
-
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
|
|
253
|
+
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : undefined;
|
|
255
254
|
|
|
256
255
|
let result: Partial<EntityCollection> | undefined = overriddenCollection;
|
|
257
256
|
|
|
@@ -80,7 +80,7 @@ export function resolveNavigationFrom<M extends Record<string, any>, UserType ex
|
|
|
80
80
|
if (entry.type === "collection") {
|
|
81
81
|
return Promise.resolve(entry);
|
|
82
82
|
} else if (entry.type === "entity") {
|
|
83
|
-
const collection = navigation.getCollection(entry.path
|
|
83
|
+
const collection = navigation.getCollection(entry.path);
|
|
84
84
|
if (!collection) {
|
|
85
85
|
throw Error(`No collection defined in the navigation for the entity with path ${entry.path}`);
|
|
86
86
|
}
|
|
@@ -11,20 +11,21 @@ import { AuthController, Authenticator, DataSourceDelegate, StorageSource, User
|
|
|
11
11
|
* @param storageSource
|
|
12
12
|
* @param dataSourceDelegate
|
|
13
13
|
*/
|
|
14
|
-
export function useValidateAuthenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
export function useValidateAuthenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>>
|
|
15
|
+
({
|
|
16
|
+
disabled,
|
|
17
|
+
authController,
|
|
18
|
+
authenticator,
|
|
19
|
+
storageSource,
|
|
20
|
+
dataSourceDelegate
|
|
21
|
+
}:
|
|
22
|
+
{
|
|
23
|
+
disabled?: boolean,
|
|
24
|
+
authController: Controller,
|
|
25
|
+
authenticator?: boolean | Authenticator<UserType, Controller>,
|
|
26
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
27
|
+
storageSource: StorageSource;
|
|
28
|
+
}): {
|
|
28
29
|
canAccessMainView: boolean,
|
|
29
30
|
authLoading: boolean,
|
|
30
31
|
notAllowedError: any,
|
|
@@ -70,7 +71,6 @@ export function useValidateAuthenticator<UserType extends User = User, Controlle
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
const delegateUser = authController.user;
|
|
73
|
-
console.debug("Checking authentication for user", delegateUser);
|
|
74
74
|
|
|
75
75
|
if (authenticator instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {
|
|
76
76
|
setAuthLoading(true);
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
FetchCollectionProps,
|
|
10
10
|
FetchEntityProps,
|
|
11
11
|
FilterValues,
|
|
12
|
+
FireCMSContext,
|
|
12
13
|
ListenCollectionProps,
|
|
13
14
|
ListenEntityProps,
|
|
14
15
|
NavigationController,
|
|
@@ -313,6 +314,17 @@ export function useBuildDataSource({
|
|
|
313
314
|
)
|
|
314
315
|
}, [delegate.isFilterCombinationValid]),
|
|
315
316
|
|
|
317
|
+
initTextSearch: useCallback(async (props: {
|
|
318
|
+
context: FireCMSContext,
|
|
319
|
+
path: string,
|
|
320
|
+
collection: EntityCollection,
|
|
321
|
+
parentCollectionIds?: string[]
|
|
322
|
+
}): Promise<boolean> => {
|
|
323
|
+
if (!delegate.initTextSearch)
|
|
324
|
+
return false;
|
|
325
|
+
return delegate.initTextSearch(props)
|
|
326
|
+
}, [delegate.initTextSearch]),
|
|
327
|
+
|
|
316
328
|
};
|
|
317
329
|
|
|
318
330
|
}
|
|
@@ -2,14 +2,15 @@ import { useCallback, useEffect, useRef } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
EntityCollection,
|
|
4
4
|
EntitySidePanelProps,
|
|
5
|
-
NavigationController,
|
|
5
|
+
NavigationController, PropertyConfig,
|
|
6
|
+
ResolvedProperty,
|
|
6
7
|
SideDialogPanelProps,
|
|
7
8
|
SideDialogsController,
|
|
8
9
|
SideEntityController
|
|
9
10
|
} from "../types";
|
|
10
11
|
import { getNavigationEntriesFromPathInternal, 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";
|
|
@@ -19,8 +20,67 @@ const NEW_URL_HASH = "new";
|
|
|
19
20
|
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {
|
|
20
21
|
if (small) return CONTAINER_FULL_WIDTH;
|
|
21
22
|
const mainViewSelected = !props.selectedSubPath;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
let resolvedWidth: string | undefined;
|
|
24
|
+
if (props.width) {
|
|
25
|
+
resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
|
|
26
|
+
} else if (props.collection?.sideDialogWidth) {
|
|
27
|
+
resolvedWidth = typeof props.collection.sideDialogWidth === "number" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!mainViewSelected) {
|
|
31
|
+
return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`
|
|
32
|
+
} else {
|
|
33
|
+
if (resolvedWidth) {
|
|
34
|
+
return resolvedWidth
|
|
35
|
+
} else if (!props.collection) {
|
|
36
|
+
return FORM_CONTAINER_WIDTH;
|
|
37
|
+
} else {
|
|
38
|
+
return calculateCollectionDesiredWidth(props.collection);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const collectionViewWidthCache: { [key: string]: string } = {};
|
|
44
|
+
|
|
45
|
+
function calculateCollectionDesiredWidth(collection: EntityCollection<any>): string {
|
|
46
|
+
if (collectionViewWidthCache[collection.id]) {
|
|
47
|
+
return collectionViewWidthCache[collection.id];
|
|
48
|
+
}
|
|
49
|
+
const resolvedCollection = resolveCollection({
|
|
50
|
+
collection,
|
|
51
|
+
path: "__ignored",
|
|
52
|
+
ignoreMissingFields: true
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
let result = FORM_CONTAINER_WIDTH
|
|
56
|
+
if (resolvedCollection?.properties) {
|
|
57
|
+
const values = Object.values(resolvedCollection.properties).map((p: ResolvedProperty) => getNestedPropertiesDepth(p));
|
|
58
|
+
const maxDepth = Math.max(...values);
|
|
59
|
+
if (maxDepth < 3) {
|
|
60
|
+
result = FORM_CONTAINER_WIDTH;
|
|
61
|
+
} else {
|
|
62
|
+
result = 768 + 32 * (maxDepth - 2) + "px";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
collectionViewWidthCache[collection.id] = result;
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getNestedPropertiesDepth(property: ResolvedProperty, accumulator: number = 0): number {
|
|
70
|
+
if (property.dataType === "map" && property.properties) {
|
|
71
|
+
const values = Object.values(property.properties).flatMap((property) => getNestedPropertiesDepth(property, accumulator + 1));
|
|
72
|
+
return Math.max(...values);
|
|
73
|
+
} else if (property.dataType === "array" && property.oneOf) {
|
|
74
|
+
return accumulator + 3;
|
|
75
|
+
} else if (property.dataType === "array" && property.of) {
|
|
76
|
+
if (Array.isArray(property.of)) {
|
|
77
|
+
return Math.max(...property.of.map((p) => getNestedPropertiesDepth(p, accumulator + 1)));
|
|
78
|
+
} else {
|
|
79
|
+
return getNestedPropertiesDepth(property.of, accumulator + 1);
|
|
80
|
+
}
|
|
81
|
+
} else {
|
|
82
|
+
return accumulator + 1;
|
|
83
|
+
}
|
|
24
84
|
}
|
|
25
85
|
|
|
26
86
|
export const useBuildSideEntityController = (navigation: NavigationController,
|
|
@@ -40,12 +100,12 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
40
100
|
const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
|
|
41
101
|
const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);
|
|
42
102
|
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
43
|
-
const
|
|
103
|
+
const props = panelsFromUrl[i];
|
|
44
104
|
setTimeout(() => {
|
|
45
105
|
if (i === 0)
|
|
46
|
-
sideDialogsController.replace(propsToSidePanel(
|
|
106
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
47
107
|
else
|
|
48
|
-
sideDialogsController.open(propsToSidePanel(
|
|
108
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))
|
|
49
109
|
}, 1);
|
|
50
110
|
}
|
|
51
111
|
} else {
|
|
@@ -119,7 +179,8 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
119
179
|
sidePanels.push({
|
|
120
180
|
path: navigationEntry.path,
|
|
121
181
|
entityId: navigationEntry.entityId,
|
|
122
|
-
copy: false
|
|
182
|
+
copy: false,
|
|
183
|
+
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
123
184
|
}
|
|
124
185
|
);
|
|
125
186
|
} else if (navigationEntry.type === "custom_view") {
|
|
@@ -163,16 +224,16 @@ const propsToSidePanel = (props: EntitySidePanelProps<any>,
|
|
|
163
224
|
|
|
164
225
|
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
165
226
|
...props,
|
|
166
|
-
path: resolvedPath
|
|
227
|
+
path: resolvedPath,
|
|
167
228
|
};
|
|
168
229
|
|
|
169
|
-
return
|
|
230
|
+
return {
|
|
170
231
|
key: `${props.path}/${props.entityId}`,
|
|
171
232
|
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
172
233
|
urlPath: newPath,
|
|
173
234
|
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
174
235
|
width: getEntityViewWidth(props, smallLayout),
|
|
175
236
|
onClose: props.onClose
|
|
176
|
-
}
|
|
237
|
+
};
|
|
177
238
|
}
|
|
178
239
|
;
|
|
@@ -47,13 +47,12 @@ 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
|
-
propertyValue: value,
|
|
57
56
|
fields: customizationController.propertyConfigs
|
|
58
57
|
});
|
|
59
58
|
|
|
@@ -85,12 +84,15 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
85
84
|
content =
|
|
86
85
|
<UrlComponentPreview size={props.size}
|
|
87
86
|
url={value}
|
|
87
|
+
interactive={interactive}
|
|
88
88
|
previewType={stringProperty.url}/>;
|
|
89
89
|
} else if (stringProperty.storage) {
|
|
90
|
+
const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
|
|
90
91
|
content = <StorageThumbnail
|
|
92
|
+
interactive={interactive}
|
|
91
93
|
storeUrl={property.storage?.storeUrl ?? false}
|
|
92
94
|
size={props.size}
|
|
93
|
-
storagePathOrDownloadUrl={
|
|
95
|
+
storagePathOrDownloadUrl={filePath}/>;
|
|
94
96
|
} else if (stringProperty.markdown) {
|
|
95
97
|
content = <Markdown source={value} size={"small"}/>;
|
|
96
98
|
} else {
|
|
@@ -172,8 +174,9 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
172
174
|
content = <ReferencePreview
|
|
173
175
|
disabled={!property.path}
|
|
174
176
|
previewProperties={property.previewProperties}
|
|
177
|
+
includeId={property.includeId}
|
|
178
|
+
includeEntityLink={property.includeEntityLink}
|
|
175
179
|
size={props.size}
|
|
176
|
-
// onClick={props.onClick}
|
|
177
180
|
reference={value as EntityReference}
|
|
178
181
|
/>;
|
|
179
182
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Checkbox,
|
|
2
|
+
import { Checkbox, cls } from "@firecms/ui";
|
|
3
3
|
import { PreviewSize } from "../PropertyPreviewProps";
|
|
4
4
|
import { Property } from "../../types";
|
|
5
5
|
|
|
@@ -21,6 +21,6 @@ export function BooleanPreview({
|
|
|
21
21
|
size={size}
|
|
22
22
|
color={"secondary"}/>
|
|
23
23
|
{property.name && <span
|
|
24
|
-
className={
|
|
24
|
+
className={cls("text-text-secondary dark:text-text-secondary-dark", size === "tiny" ? "text-sm" : "")}>{property.name}</span>}
|
|
25
25
|
</div>;
|
|
26
26
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { Chip } from "@firecms/ui";
|
|
2
3
|
import { EnumValues } from "../../types";
|
|
3
4
|
import { buildEnumLabel, enumToObjectEntries, getColorScheme, getLabelOrConfigFrom } from "../../util/enums";
|
|
4
|
-
import { Chip } from "@firecms/ui";
|
|
5
5
|
|
|
6
6
|
export interface EnumValuesChipProps {
|
|
7
7
|
enumValues?: EnumValues;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { CSSProperties, useMemo
|
|
1
|
+
import React, { CSSProperties, useMemo } from "react";
|
|
2
2
|
|
|
3
3
|
import { getThumbnailMeasure } from "../util";
|
|
4
4
|
import { PreviewSize } from "../PropertyPreviewProps";
|
|
@@ -20,8 +20,6 @@ export function ImagePreview({
|
|
|
20
20
|
url
|
|
21
21
|
}: ImagePreviewProps) {
|
|
22
22
|
|
|
23
|
-
const [onHover, setOnHover] = useState(false);
|
|
24
|
-
|
|
25
23
|
const imageSize = useMemo(() => getThumbnailMeasure(size), [size]);
|
|
26
24
|
|
|
27
25
|
if (size === "tiny") {
|
|
@@ -47,60 +45,50 @@ export function ImagePreview({
|
|
|
47
45
|
|
|
48
46
|
return (
|
|
49
47
|
<div
|
|
50
|
-
className="relative flex items-center justify-center max-w-full max-h-full"
|
|
48
|
+
className="relative flex items-center justify-center max-w-full max-h-full group"
|
|
51
49
|
style={{
|
|
52
50
|
width: imageSize,
|
|
53
51
|
height: imageSize
|
|
54
52
|
}}
|
|
55
|
-
key={"image_preview_" + url}
|
|
56
|
-
onMouseEnter={() => setOnHover(true)}
|
|
57
|
-
onMouseMove={() => setOnHover(true)}
|
|
58
|
-
onMouseLeave={() => setOnHover(false)}>
|
|
53
|
+
key={"image_preview_" + url}>
|
|
59
54
|
|
|
60
55
|
<img src={url}
|
|
61
56
|
className={"rounded-md"}
|
|
62
57
|
style={imageStyle}/>
|
|
63
58
|
|
|
64
|
-
{onHover && <>
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
</IconButton>
|
|
80
|
-
</div>
|
|
60
|
+
<div className={"flex flex-row gap-2 absolute bottom-[-4px] right-[-4px] invisible group-hover:visible"}>
|
|
61
|
+
{navigator && <Tooltip title="Copy url to clipboard" side={"bottom"}>
|
|
62
|
+
<IconButton
|
|
63
|
+
variant={"filled"}
|
|
64
|
+
size={"small"}
|
|
65
|
+
onClick={(e) => {
|
|
66
|
+
e.stopPropagation();
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
return navigator.clipboard.writeText(url);
|
|
69
|
+
}}>
|
|
70
|
+
<ContentCopyIcon className={"text-gray-700 dark:text-gray-300"}
|
|
71
|
+
size={"small"}/>
|
|
72
|
+
</IconButton>
|
|
81
73
|
</Tooltip>}
|
|
82
74
|
|
|
83
|
-
<Tooltip title="Open image in new tab">
|
|
75
|
+
<Tooltip title="Open image in new tab" side={"bottom"}>
|
|
84
76
|
<IconButton
|
|
77
|
+
className="invisible group-hover:visible"
|
|
85
78
|
variant={"filled"}
|
|
86
79
|
component={"a" as React.ElementType}
|
|
87
|
-
style={{
|
|
88
|
-
position: "absolute",
|
|
89
|
-
bottom: -4,
|
|
90
|
-
right: -4
|
|
91
|
-
}}
|
|
92
80
|
href={url}
|
|
93
81
|
rel="noopener noreferrer"
|
|
94
82
|
target="_blank"
|
|
95
83
|
size={"small"}
|
|
96
84
|
onClick={(e: any) => e.stopPropagation()}
|
|
97
85
|
>
|
|
98
|
-
<OpenInNewIcon className={"text-gray-
|
|
86
|
+
<OpenInNewIcon className={"text-gray-700 dark:text-gray-300"}
|
|
99
87
|
size={"small"}/>
|
|
100
88
|
</IconButton>
|
|
101
89
|
</Tooltip>
|
|
102
|
-
|
|
103
|
-
|
|
90
|
+
</div>
|
|
91
|
+
|
|
104
92
|
</div>
|
|
105
93
|
);
|
|
106
94
|
}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
3
|
import { Entity, EntityCollection, EntityReference } from "../../types";
|
|
4
|
-
import {
|
|
5
|
-
useCustomizationController,
|
|
6
|
-
useEntityFetch,
|
|
7
|
-
useNavigationController,
|
|
8
|
-
useSideEntityController
|
|
9
|
-
} from "../../hooks";
|
|
4
|
+
import { useCustomizationController, useEntityFetch, useNavigationController } from "../../hooks";
|
|
10
5
|
import { PreviewSize } from "../PropertyPreviewProps";
|
|
11
|
-
import {
|
|
6
|
+
import { Skeleton } from "@firecms/ui";
|
|
12
7
|
import { ErrorView } from "../../components";
|
|
13
|
-
import { useAnalyticsController } from "../../hooks/useAnalyticsController";
|
|
14
8
|
import { EntityPreview, EntityPreviewContainer } from "../../components/EntityPreview";
|
|
15
9
|
|
|
16
10
|
export type ReferencePreviewProps = {
|
|
@@ -20,7 +14,8 @@ export type ReferencePreviewProps = {
|
|
|
20
14
|
previewProperties?: string[];
|
|
21
15
|
onClick?: (e: React.SyntheticEvent) => void;
|
|
22
16
|
hover?: boolean;
|
|
23
|
-
|
|
17
|
+
includeEntityLink?: boolean;
|
|
18
|
+
includeId?: boolean;
|
|
24
19
|
};
|
|
25
20
|
|
|
26
21
|
/**
|
|
@@ -46,19 +41,21 @@ function areEqual(prevProps: ReferencePreviewProps, nextProps: ReferencePreviewP
|
|
|
46
41
|
prevProps.hover === nextProps.hover &&
|
|
47
42
|
prevProps.reference?.id === nextProps.reference?.id &&
|
|
48
43
|
prevProps.reference?.path === nextProps.reference?.path &&
|
|
49
|
-
prevProps.
|
|
44
|
+
prevProps.includeEntityLink === nextProps.includeEntityLink &&
|
|
45
|
+
prevProps.onClick === nextProps.onClick
|
|
50
46
|
;
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
function ReferencePreviewInternal
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
function ReferencePreviewInternal({
|
|
50
|
+
disabled,
|
|
51
|
+
reference,
|
|
52
|
+
previewProperties,
|
|
53
|
+
size,
|
|
54
|
+
hover,
|
|
55
|
+
onClick,
|
|
56
|
+
includeEntityLink = true,
|
|
57
|
+
includeId = true
|
|
58
|
+
}: ReferencePreviewProps) {
|
|
62
59
|
|
|
63
60
|
const customizationController = useCustomizationController();
|
|
64
61
|
|
|
@@ -79,7 +76,8 @@ function ReferencePreviewInternal<M extends Record<string, any>>({
|
|
|
79
76
|
previewProperties={previewProperties}
|
|
80
77
|
size={size}
|
|
81
78
|
disabled={disabled}
|
|
82
|
-
|
|
79
|
+
includeEntityLink={includeEntityLink}
|
|
80
|
+
includeId={includeId}
|
|
83
81
|
onClick={onClick}
|
|
84
82
|
hover={hover}/>
|
|
85
83
|
}
|
|
@@ -90,7 +88,8 @@ function ReferencePreviewExisting<M extends Record<string, any> = any>({
|
|
|
90
88
|
previewProperties,
|
|
91
89
|
size,
|
|
92
90
|
disabled,
|
|
93
|
-
|
|
91
|
+
includeEntityLink,
|
|
92
|
+
includeId,
|
|
94
93
|
onClick,
|
|
95
94
|
hover
|
|
96
95
|
}: ReferencePreviewProps & {
|
|
@@ -158,7 +157,8 @@ function ReferencePreviewExisting<M extends Record<string, any> = any>({
|
|
|
158
157
|
entity={usedEntity}
|
|
159
158
|
collection={collection}
|
|
160
159
|
onClick={onClick}
|
|
161
|
-
|
|
160
|
+
includeEntityLink={includeEntityLink}
|
|
161
|
+
includeId={includeId}
|
|
162
162
|
hover={hover}/>;
|
|
163
163
|
|
|
164
164
|
}
|
|
@@ -11,6 +11,7 @@ type StorageThumbnailProps = {
|
|
|
11
11
|
storagePathOrDownloadUrl: string;
|
|
12
12
|
storeUrl: boolean;
|
|
13
13
|
size: PreviewSize;
|
|
14
|
+
interactive?: boolean;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
/**
|
|
@@ -21,13 +22,15 @@ export const StorageThumbnail = React.memo<StorageThumbnailProps>(StorageThumbna
|
|
|
21
22
|
function areEqual(prevProps: StorageThumbnailProps, nextProps: StorageThumbnailProps) {
|
|
22
23
|
return prevProps.size === nextProps.size &&
|
|
23
24
|
prevProps.storagePathOrDownloadUrl === nextProps.storagePathOrDownloadUrl &&
|
|
24
|
-
prevProps.storeUrl === nextProps.storeUrl
|
|
25
|
+
prevProps.storeUrl === nextProps.storeUrl&&
|
|
26
|
+
prevProps.interactive === nextProps.interactive;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
const URL_CACHE: Record<string, DownloadConfig> = {};
|
|
28
30
|
|
|
29
31
|
export function StorageThumbnailInternal({
|
|
30
32
|
storeUrl,
|
|
33
|
+
interactive,
|
|
31
34
|
storagePathOrDownloadUrl,
|
|
32
35
|
size
|
|
33
36
|
}: StorageThumbnailProps) {
|
|
@@ -68,6 +71,7 @@ export function StorageThumbnailInternal({
|
|
|
68
71
|
return downloadConfig?.url
|
|
69
72
|
? <UrlComponentPreview previewType={previewType}
|
|
70
73
|
url={downloadConfig.url}
|
|
74
|
+
interactive={interactive}
|
|
71
75
|
size={size}
|
|
72
76
|
hint={storagePathOrDownloadUrl}/>
|
|
73
77
|
: renderSkeletonImageThumbnail(size);
|