@firecms/core 3.0.0-beta.13 → 3.0.0-beta.14
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 +7 -12
- package/dist/components/EntityPreview.d.ts +4 -2
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +0 -4
- package/dist/components/index.d.ts +1 -0
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -9
- package/dist/hooks/useBuildNavigationController.d.ts +2 -9
- package/dist/index.es.js +1183 -705
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1191 -716
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +20 -2
- package/dist/types/firecms.d.ts +2 -1
- package/dist/types/navigation.d.ts +5 -0
- package/dist/types/plugins.d.ts +12 -0
- package/dist/types/side_entity_controller.d.ts +4 -0
- package/dist/util/callbacks.d.ts +2 -0
- package/dist/util/index.d.ts +1 -0
- package/package.json +8 -6
- package/src/components/ArrayContainer.tsx +409 -294
- package/src/components/ClearFilterSortButton.tsx +1 -1
- package/src/components/ConfirmationDialog.tsx +9 -9
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +13 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +53 -27
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -0
- package/src/components/EntityPreview.tsx +18 -14
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +2 -1
- package/src/components/HomePage/NavigationCardBinding.tsx +3 -1
- package/src/components/SelectableTable/SelectableTable.tsx +140 -143
- package/src/components/VirtualTable/VirtualTable.tsx +8 -30
- package/src/components/VirtualTable/VirtualTableProps.tsx +0 -5
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -1
- package/src/components/index.tsx +2 -0
- package/src/core/EntityEditView.tsx +26 -14
- package/src/core/EntitySidePanel.tsx +15 -20
- package/src/core/FireCMS.tsx +7 -1
- package/src/form/EntityForm.tsx +1 -1
- package/src/form/PropertyFieldBinding.tsx +0 -1
- package/src/form/components/CustomIdField.tsx +3 -1
- package/src/form/components/LabelWithIcon.tsx +1 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +3 -2
- package/src/form/field_bindings/MapFieldBinding.tsx +5 -4
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/RepeatFieldBinding.tsx +1 -0
- package/src/form/field_bindings/SelectFieldBinding.tsx +2 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +222 -154
- package/src/hooks/data/save.ts +0 -6
- package/src/hooks/useBuildNavigationController.tsx +30 -16
- package/src/internal/useBuildSideEntityController.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +2 -2
- package/src/preview/components/ReferencePreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +1 -1
- package/src/preview/property_previews/StringPropertyPreview.tsx +1 -1
- package/src/types/collections.ts +24 -2
- package/src/types/firecms.tsx +2 -2
- package/src/types/navigation.ts +6 -0
- package/src/types/plugins.tsx +16 -0
- package/src/types/side_entity_controller.tsx +5 -5
- package/src/util/callbacks.ts +119 -0
- package/src/util/index.ts +1 -0
- package/src/util/navigation_utils.ts +70 -55
- package/src/util/objects.ts +53 -20
- package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
- package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
|
@@ -18,7 +18,7 @@ export function ClearFilterSortButton({
|
|
|
18
18
|
if ((filterIsSet || sortIsSet) && (tableController.clearFilter || tableController.setSortBy)) {
|
|
19
19
|
let label;
|
|
20
20
|
if (filterIsSet && sortIsSet) {
|
|
21
|
-
label = "Clear filter
|
|
21
|
+
label = "Clear filter/sort";
|
|
22
22
|
} else if (filterIsSet) {
|
|
23
23
|
label = "Clear filter";
|
|
24
24
|
} else {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton
|
|
3
|
+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton } from "@firecms/ui";
|
|
4
4
|
|
|
5
5
|
export function ConfirmationDialog({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
open,
|
|
7
|
+
onAccept,
|
|
8
|
+
onCancel,
|
|
9
|
+
title,
|
|
10
|
+
loading,
|
|
11
|
+
body
|
|
12
|
+
}: {
|
|
13
13
|
open: boolean,
|
|
14
14
|
onAccept: () => void,
|
|
15
15
|
onCancel: () => void,
|
|
@@ -38,7 +38,7 @@ export function ConfirmationDialog({
|
|
|
38
38
|
type="submit"
|
|
39
39
|
loading={loading}
|
|
40
40
|
onClick={onAccept}
|
|
41
|
-
|
|
41
|
+
autoFocus>
|
|
42
42
|
Ok
|
|
43
43
|
</LoadingButton>
|
|
44
44
|
</DialogActions>
|
|
@@ -394,7 +394,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
394
394
|
size={size}
|
|
395
395
|
multiselect={true}
|
|
396
396
|
path={arrayProperty.of.path}
|
|
397
|
-
previewProperties={arrayProperty.of.
|
|
397
|
+
previewProperties={arrayProperty.of.previewKeys}
|
|
398
398
|
title={arrayProperty.name}
|
|
399
399
|
forceFilter={arrayProperty.of.forceFilter}
|
|
400
400
|
includeId={arrayProperty.of.includeId}
|
|
@@ -55,7 +55,7 @@ export function CollectionTableToolbar({
|
|
|
55
55
|
<Tooltip title={"Table row size"} side={"right"} sideOffset={4}>
|
|
56
56
|
<Select
|
|
57
57
|
value={size as string}
|
|
58
|
-
className="w-16
|
|
58
|
+
className="w-16 ml-2"
|
|
59
59
|
size={"small"}
|
|
60
60
|
onValueChange={(v) => onSizeChanged(v as CollectionSize)}
|
|
61
61
|
renderValue={(v) => <div className={"font-medium"}>{v.toUpperCase()}</div>}
|
|
@@ -5,6 +5,7 @@ import useMeasure from "react-use-measure";
|
|
|
5
5
|
import { cls, DoNotDisturbOnIcon, Tooltip } from "@firecms/ui";
|
|
6
6
|
import { ErrorBoundary } from "../../../components";
|
|
7
7
|
import { getRowHeight, TableSize } from "../../common/table_height";
|
|
8
|
+
import { ErrorTooltip } from "../../ErrorTooltip";
|
|
8
9
|
|
|
9
10
|
interface EntityTableCellProps {
|
|
10
11
|
children: React.ReactNode;
|
|
@@ -183,7 +184,7 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
|
|
|
183
184
|
? "border-primary"
|
|
184
185
|
: "border-transparent";
|
|
185
186
|
|
|
186
|
-
|
|
187
|
+
const result = <>
|
|
187
188
|
<div
|
|
188
189
|
className={cls(
|
|
189
190
|
"transition-colors duration-100 ease-in-out",
|
|
@@ -241,7 +242,17 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
|
|
|
241
242
|
</div>}
|
|
242
243
|
|
|
243
244
|
</div>
|
|
244
|
-
|
|
245
|
+
</>;
|
|
246
|
+
if (showError) {
|
|
247
|
+
return (
|
|
248
|
+
<ErrorTooltip
|
|
249
|
+
align={"start"}
|
|
250
|
+
title={error?.message ?? "Error"}>
|
|
251
|
+
{result}
|
|
252
|
+
</ErrorTooltip>
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
245
256
|
}, (a, b) => {
|
|
246
257
|
return a.error === b.error &&
|
|
247
258
|
a.value === b.value &&
|
|
@@ -17,7 +17,6 @@ import { Formex, useCreateFormex } from "@firecms/formex";
|
|
|
17
17
|
import { useDraggable } from "./useDraggable";
|
|
18
18
|
import { CustomFieldValidator, getYupEntitySchema } from "../../../../form/validation";
|
|
19
19
|
import { useWindowSize } from "./useWindowSize";
|
|
20
|
-
import { ElementResizeListener } from "./ElementResizeListener";
|
|
21
20
|
import { getPropertyInPath, isReadOnly, resolveCollection } from "../../../../util";
|
|
22
21
|
import { Button, CloseIcon, DialogActions, IconButton, Typography } from "@firecms/ui";
|
|
23
22
|
import { PropertyFieldBinding, yupToFormErrors } from "../../../../form";
|
|
@@ -71,7 +70,7 @@ export function PopupFormFieldLoading<M extends Record<string, any>>({
|
|
|
71
70
|
collection: inputCollection
|
|
72
71
|
}).then(setEntity);
|
|
73
72
|
}
|
|
74
|
-
}, [entityId, inputCollection]);
|
|
73
|
+
}, [entityId, inputCollection, dataSource, path]);
|
|
75
74
|
|
|
76
75
|
if (!entity) return null;
|
|
77
76
|
return <PopupFormFieldInternal {...{
|
|
@@ -147,33 +146,35 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
147
146
|
};
|
|
148
147
|
}, [cellRect, windowSize.height, windowSize.width]);
|
|
149
148
|
|
|
150
|
-
const normalizePosition = useCallback((
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
149
|
+
const normalizePosition = useCallback((
|
|
150
|
+
pos: { x: number, y: number },
|
|
151
|
+
draggableBoundingRect: DOMRect,
|
|
152
|
+
currentWindowSize: { width: number, height: number }
|
|
153
|
+
) => {
|
|
154
|
+
if (!draggableBoundingRect || draggableBoundingRect.width === 0 || draggableBoundingRect.height === 0) {
|
|
155
|
+
return pos;
|
|
156
|
+
}
|
|
159
157
|
return {
|
|
160
|
-
x: Math.max(0, Math.min(x,
|
|
161
|
-
y: Math.max(0, Math.min(y,
|
|
158
|
+
x: Math.max(0, Math.min(pos.x, currentWindowSize.width - draggableBoundingRect.width)),
|
|
159
|
+
y: Math.max(0, Math.min(pos.y, currentWindowSize.height - draggableBoundingRect.height))
|
|
162
160
|
};
|
|
163
|
-
}, [
|
|
161
|
+
}, []);
|
|
164
162
|
|
|
165
|
-
const updatePopupLocation = useCallback((
|
|
163
|
+
const updatePopupLocation = useCallback((newPositionCandidate?: {
|
|
166
164
|
x: number,
|
|
167
165
|
y: number
|
|
168
166
|
}) => {
|
|
169
|
-
|
|
170
167
|
const draggableBoundingRect = draggableRef.current?.getBoundingClientRect();
|
|
171
|
-
if (!cellRect || !draggableBoundingRect)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
168
|
+
if (!cellRect || !draggableBoundingRect || draggableBoundingRect.width === 0 || draggableBoundingRect.height === 0) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const basePosition = newPositionCandidate ?? getInitialLocation();
|
|
172
|
+
const newNormalizedPosition = normalizePosition(basePosition, draggableBoundingRect, windowSize);
|
|
173
|
+
|
|
174
|
+
if (!popupLocation || newNormalizedPosition.x !== popupLocation.x || newNormalizedPosition.y !== popupLocation.y) {
|
|
175
|
+
setPopupLocation(newNormalizedPosition);
|
|
176
|
+
}
|
|
177
|
+
}, [cellRect, getInitialLocation, normalizePosition, popupLocation, windowSize]);
|
|
177
178
|
|
|
178
179
|
useDraggable({
|
|
179
180
|
containerRef: draggableRef,
|
|
@@ -192,19 +193,25 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
192
193
|
|
|
193
194
|
useLayoutEffect(
|
|
194
195
|
() => {
|
|
196
|
+
if (!cellRect || initialPositionSet.current) return;
|
|
197
|
+
// Ensure draggableRef is available and has dimensions before initial positioning
|
|
195
198
|
const draggableBoundingRect = draggableRef.current?.getBoundingClientRect();
|
|
196
|
-
if (!
|
|
199
|
+
if (!draggableBoundingRect || draggableBoundingRect.width === 0 || draggableBoundingRect.height === 0) {
|
|
200
|
+
// If not ready, perhaps wait or log. For now, just return.
|
|
201
|
+
// This might need a retry mechanism or ensure content is rendered first.
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
197
204
|
updatePopupLocation();
|
|
198
205
|
initialPositionSet.current = true;
|
|
199
206
|
},
|
|
200
|
-
[cellRect, updatePopupLocation
|
|
207
|
+
[cellRect, updatePopupLocation] // Removed initialPositionSet.current from deps as it's a ref
|
|
201
208
|
);
|
|
202
209
|
|
|
203
210
|
useLayoutEffect(
|
|
204
211
|
() => {
|
|
205
212
|
updatePopupLocation(popupLocation);
|
|
206
213
|
},
|
|
207
|
-
[windowSize, cellRect]
|
|
214
|
+
[windowSize, cellRect, updatePopupLocation, popupLocation]
|
|
208
215
|
);
|
|
209
216
|
|
|
210
217
|
const validationSchema = useMemo(() => {
|
|
@@ -218,9 +225,28 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
218
225
|
}, [collection, entityId, propertyKey, customFieldValidator]);
|
|
219
226
|
|
|
220
227
|
const adaptResize = useCallback(() => {
|
|
228
|
+
// When the popup resizes, we want to re-evaluate its position
|
|
229
|
+
// based on its current location and new dimensions.
|
|
221
230
|
return updatePopupLocation(popupLocation);
|
|
222
231
|
}, [popupLocation, updatePopupLocation]);
|
|
223
232
|
|
|
233
|
+
// Setup ResizeObserver
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
const element = draggableRef.current;
|
|
236
|
+
if (!element) return;
|
|
237
|
+
|
|
238
|
+
const observer = new ResizeObserver(() => {
|
|
239
|
+
adaptResize();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
observer.observe(element);
|
|
243
|
+
|
|
244
|
+
return () => {
|
|
245
|
+
observer.unobserve(element);
|
|
246
|
+
observer.disconnect();
|
|
247
|
+
};
|
|
248
|
+
}, [adaptResize, draggableRef]);
|
|
249
|
+
|
|
224
250
|
const saveValue = async (values: M) => {
|
|
225
251
|
setSavingError(null);
|
|
226
252
|
if (inputCollection && entity && onCellValueChange && propertyKey) {
|
|
@@ -288,7 +314,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
288
314
|
underlyingValueHasChanged: false,
|
|
289
315
|
context: formContext,
|
|
290
316
|
partOfArray: false,
|
|
291
|
-
minimalistView:
|
|
317
|
+
minimalistView: true,
|
|
292
318
|
autoFocus: open
|
|
293
319
|
}
|
|
294
320
|
: undefined;
|
|
@@ -372,7 +398,7 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
372
398
|
} cursor-grab overflow-visible`}
|
|
373
399
|
ref={draggableRef}>
|
|
374
400
|
|
|
375
|
-
|
|
401
|
+
{/* ElementResizeListener removed from here */}
|
|
376
402
|
|
|
377
403
|
<div
|
|
378
404
|
className="overflow-hidden">
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React, { useEffect } from "react";
|
|
1
|
+
import React, { useCallback, useEffect } from "react";
|
|
2
2
|
|
|
3
3
|
interface DraggableProps {
|
|
4
4
|
containerRef: React.RefObject<HTMLDivElement>,
|
|
5
5
|
innerRef: React.RefObject<HTMLDivElement>,
|
|
6
|
-
// ref: React.RefObject<HTMLDivElement>,
|
|
7
6
|
x?: number;
|
|
8
7
|
y?: number;
|
|
9
8
|
onMove: (params: { x: number, y: number }) => void,
|
|
@@ -22,7 +21,7 @@ export function useDraggable({
|
|
|
22
21
|
|
|
23
22
|
const listeningRef = React.useRef(false);
|
|
24
23
|
|
|
25
|
-
const onMouseDown = (event: any) => {
|
|
24
|
+
const onMouseDown = useCallback((event: any) => {
|
|
26
25
|
if (event.button !== 0 || !containerRef.current || event.defaultPrevented || event.innerClicked) {
|
|
27
26
|
return;
|
|
28
27
|
}
|
|
@@ -39,16 +38,17 @@ export function useDraggable({
|
|
|
39
38
|
document.addEventListener("selectstart", onSelect);
|
|
40
39
|
listeningRef.current = true;
|
|
41
40
|
// event.stopPropagation();
|
|
42
|
-
};
|
|
43
|
-
|
|
41
|
+
}, [containerRef, onMove]);
|
|
42
|
+
|
|
43
|
+
const onMouseDownInner = useCallback((event: any) => {
|
|
44
44
|
// @ts-ignore
|
|
45
45
|
event.innerClicked = true;
|
|
46
|
-
}
|
|
46
|
+
}, [])
|
|
47
47
|
|
|
48
|
-
const onSelect = (event: any) => {
|
|
48
|
+
const onSelect = useCallback((event: any) => {
|
|
49
49
|
event.preventDefault()
|
|
50
50
|
event.stopPropagation();
|
|
51
|
-
}
|
|
51
|
+
}, [])
|
|
52
52
|
|
|
53
53
|
const onMouseUp = (event: any) => {
|
|
54
54
|
document.removeEventListener("mousemove", onMouseMove);
|
|
@@ -92,6 +92,6 @@ export function useDraggable({
|
|
|
92
92
|
if (innerCurrent)
|
|
93
93
|
innerCurrent.removeEventListener("mousedown", onMouseDownInner);
|
|
94
94
|
};
|
|
95
|
-
});
|
|
95
|
+
}, [containerRef, innerRef, onMouseDownInner, onMouseDown]);
|
|
96
96
|
|
|
97
97
|
}
|
|
@@ -425,6 +425,7 @@ export const EntityCollectionView = React.memo(
|
|
|
425
425
|
Builder: ({ entity }) => (
|
|
426
426
|
<Button color={"primary"}
|
|
427
427
|
variant={"outlined"}
|
|
428
|
+
className={"max-w-full truncate justify-start"}
|
|
428
429
|
startIcon={<KeyboardTabIcon size={"small"}/>}
|
|
429
430
|
onClick={(event: any) => {
|
|
430
431
|
event.stopPropagation();
|
|
@@ -749,10 +750,13 @@ export const EntityCollectionView = React.memo(
|
|
|
749
750
|
equal(a.defaultSize, b.defaultSize) &&
|
|
750
751
|
equal(a.initialFilter, b.initialFilter) &&
|
|
751
752
|
equal(a.initialSort, b.initialSort) &&
|
|
753
|
+
equal(a.includeJsonView, b.includeJsonView) &&
|
|
752
754
|
equal(a.textSearchEnabled, b.textSearchEnabled) &&
|
|
753
755
|
equal(a.additionalFields, b.additionalFields) &&
|
|
754
756
|
equal(a.sideDialogWidth, b.sideDialogWidth) &&
|
|
755
757
|
equal(a.openEntityMode, b.openEntityMode) &&
|
|
758
|
+
equal(a.exportable, b.exportable) &&
|
|
759
|
+
equal(a.history, b.history) &&
|
|
756
760
|
equal(a.forceFilter, b.forceFilter);
|
|
757
761
|
}) as React.FunctionComponent<EntityCollectionViewProps<any>>
|
|
758
762
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getEntityImagePreviewPropertyKey,
|
|
8
8
|
getEntityPreviewKeys,
|
|
9
9
|
getEntityTitlePropertyKey,
|
|
10
|
+
getPropertyInPath,
|
|
10
11
|
getValueInPath,
|
|
11
12
|
IconForView,
|
|
12
13
|
resolveCollection
|
|
@@ -26,11 +27,13 @@ export type EntityPreviewProps = {
|
|
|
26
27
|
actions?: React.ReactNode,
|
|
27
28
|
collection?: EntityCollection,
|
|
28
29
|
hover?: boolean;
|
|
29
|
-
|
|
30
|
+
previewKeys?: string[],
|
|
30
31
|
disabled?: boolean,
|
|
31
32
|
entity: Entity<any>,
|
|
32
33
|
includeId?: boolean,
|
|
34
|
+
includeTitle?: boolean,
|
|
33
35
|
includeEntityLink?: boolean,
|
|
36
|
+
includeImage?: boolean,
|
|
34
37
|
onClick?: (e: React.SyntheticEvent) => void;
|
|
35
38
|
};
|
|
36
39
|
|
|
@@ -43,12 +46,14 @@ export function EntityPreview({
|
|
|
43
46
|
disabled,
|
|
44
47
|
hover,
|
|
45
48
|
collection: collectionProp,
|
|
46
|
-
|
|
49
|
+
previewKeys,
|
|
47
50
|
onClick,
|
|
48
51
|
size,
|
|
49
52
|
includeId = true,
|
|
53
|
+
includeTitle = true,
|
|
50
54
|
includeEntityLink = true,
|
|
51
|
-
|
|
55
|
+
includeImage = true,
|
|
56
|
+
entity,
|
|
52
57
|
}: EntityPreviewProps) {
|
|
53
58
|
|
|
54
59
|
const authController = useAuthController();
|
|
@@ -72,11 +77,11 @@ export function EntityPreview({
|
|
|
72
77
|
authController
|
|
73
78
|
}), [collection]);
|
|
74
79
|
|
|
75
|
-
const listProperties = useMemo(() => getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs,
|
|
76
|
-
[
|
|
80
|
+
const listProperties = useMemo(() => previewKeys ?? getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs, previewKeys, size === "medium" || size === "large" ? 3 : 1),
|
|
81
|
+
[previewKeys, resolvedCollection, size]);
|
|
77
82
|
|
|
78
|
-
const titleProperty = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
|
|
79
|
-
const imagePropertyKey = getEntityImagePreviewPropertyKey(resolvedCollection);
|
|
83
|
+
const titleProperty = includeTitle ? getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs) : undefined;
|
|
84
|
+
const imagePropertyKey = includeImage ? getEntityImagePreviewPropertyKey(resolvedCollection) : undefined;
|
|
80
85
|
const imageProperty = imagePropertyKey ? resolvedCollection.properties[imagePropertyKey] : undefined;
|
|
81
86
|
const usedImageProperty = imageProperty && "of" in imageProperty ? imageProperty.of : imageProperty;
|
|
82
87
|
const restProperties = listProperties.filter(p => p !== titleProperty && p !== imagePropertyKey);
|
|
@@ -103,9 +108,7 @@ export function EntityPreview({
|
|
|
103
108
|
</div>
|
|
104
109
|
|
|
105
110
|
|
|
106
|
-
<div className={"flex flex-col grow
|
|
107
|
-
"maxWidth": "calc(100% - 96px)"
|
|
108
|
-
}}>
|
|
111
|
+
<div className={"flex flex-col grow w-full m-1 shrink min-w-0"}>
|
|
109
112
|
|
|
110
113
|
{size !== "small" && includeId && (
|
|
111
114
|
entity
|
|
@@ -135,9 +138,10 @@ export function EntityPreview({
|
|
|
135
138
|
)}
|
|
136
139
|
|
|
137
140
|
{restProperties && restProperties.map((key) => {
|
|
138
|
-
const childProperty = resolvedCollection.properties
|
|
141
|
+
const childProperty = getPropertyInPath(resolvedCollection.properties, key);
|
|
139
142
|
if (!childProperty) return null;
|
|
140
143
|
|
|
144
|
+
const valueInPath = getValueInPath(entity.values, key);
|
|
141
145
|
return (
|
|
142
146
|
<div key={"ref_prev_" + key}
|
|
143
147
|
className={cls("truncate", restProperties.length > 1 ? "my-0.5" : "my-0")}>
|
|
@@ -145,7 +149,7 @@ export function EntityPreview({
|
|
|
145
149
|
entity
|
|
146
150
|
? <PropertyPreview
|
|
147
151
|
propertyKey={key as string}
|
|
148
|
-
value={
|
|
152
|
+
value={valueInPath}
|
|
149
153
|
property={childProperty as ResolvedProperty}
|
|
150
154
|
size={"small"}/>
|
|
151
155
|
: <SkeletonPropertyComponent
|
|
@@ -162,7 +166,7 @@ export function EntityPreview({
|
|
|
162
166
|
<Tooltip title={`See details for ${entity.id}`} className={"shrink-0"}>
|
|
163
167
|
<IconButton
|
|
164
168
|
color={"inherit"}
|
|
165
|
-
size={"
|
|
169
|
+
size={"small"}
|
|
166
170
|
className={size !== "small" ? "self-start" : ""}
|
|
167
171
|
onClick={(e) => {
|
|
168
172
|
e.stopPropagation();
|
|
@@ -177,7 +181,7 @@ export function EntityPreview({
|
|
|
177
181
|
updateUrl: true
|
|
178
182
|
});
|
|
179
183
|
}}>
|
|
180
|
-
<KeyboardTabIcon size={"
|
|
184
|
+
<KeyboardTabIcon size={"small"}/>
|
|
181
185
|
</IconButton>
|
|
182
186
|
</Tooltip>}
|
|
183
187
|
|
|
@@ -114,6 +114,7 @@ export function DefaultHomePage({
|
|
|
114
114
|
);
|
|
115
115
|
})}
|
|
116
116
|
</>;
|
|
117
|
+
|
|
117
118
|
additionalPluginChildrenStart = <div className={"flex flex-col gap-2"}>
|
|
118
119
|
{customizationController.plugins.filter(plugin => plugin.homePage?.additionalChildrenStart)
|
|
119
120
|
.map((plugin, i) => {
|
|
@@ -179,7 +180,7 @@ export function DefaultHomePage({
|
|
|
179
180
|
|
|
180
181
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
181
182
|
{thisGroupCollections.map((entry) => (
|
|
182
|
-
<div key={`nav_${entry.group}_${entry.name}`} className="col-span-1">
|
|
183
|
+
<div key={`nav_${entry.group}_${entry.path}_${entry.name}`} className="col-span-1">
|
|
183
184
|
<NavigationCardBinding
|
|
184
185
|
{...entry}
|
|
185
186
|
onClick={() => {
|
|
@@ -7,6 +7,7 @@ import { useUserConfigurationPersistence } from "../../hooks/useUserConfiguratio
|
|
|
7
7
|
import { IconButton, StarIcon } from "@firecms/ui";
|
|
8
8
|
import { NavigationCard } from "./NavigationCard";
|
|
9
9
|
import { SmallNavigationCard } from "./SmallNavigationCard";
|
|
10
|
+
import React from "react";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* This is the component used in the home page to render a card for each
|
|
@@ -47,6 +48,7 @@ export function NavigationCardBinding({
|
|
|
47
48
|
? [
|
|
48
49
|
<IconButton
|
|
49
50
|
key={"favourite"}
|
|
51
|
+
size={"small"}
|
|
50
52
|
onClick={(e) => {
|
|
51
53
|
e.preventDefault();
|
|
52
54
|
e.stopPropagation();
|
|
@@ -61,7 +63,7 @@ export function NavigationCardBinding({
|
|
|
61
63
|
}
|
|
62
64
|
}}>
|
|
63
65
|
<StarIcon
|
|
64
|
-
size={
|
|
66
|
+
size={"small"}
|
|
65
67
|
className={favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500"}/>
|
|
66
68
|
</IconButton>
|
|
67
69
|
]
|