@firecms/core 3.0.1 → 3.1.0-canary.24c8270
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/components/AIIcon.d.ts +16 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +7 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +14 -0
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +6 -0
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
- package/dist/components/EntityCollectionView/Board.d.ts +2 -0
- package/dist/components/EntityCollectionView/BoardColumn.d.ts +42 -0
- package/dist/components/EntityCollectionView/BoardColumnTitle.d.ts +9 -0
- package/dist/components/EntityCollectionView/BoardSortableList.d.ts +14 -0
- package/dist/components/EntityCollectionView/EntityBoardCard.d.ts +26 -0
- package/dist/components/EntityCollectionView/EntityCard.d.ts +19 -0
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +20 -0
- package/dist/components/EntityCollectionView/EntityCollectionCardView.d.ts +31 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +7 -3
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +14 -0
- package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +44 -0
- package/dist/components/EntityCollectionView/board_types.d.ts +105 -0
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +60 -0
- package/dist/components/ErrorBoundary.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +5 -1
- package/dist/components/SelectableTable/filters/DateTimeFilterField.d.ts +2 -1
- package/dist/components/VirtualTable/VirtualTableCell.d.ts +6 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +3 -1
- package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -0
- package/dist/components/VirtualTable/fields/VirtualTableDateField.d.ts +1 -0
- package/dist/components/VirtualTable/types.d.ts +2 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/contexts/index.d.ts +10 -0
- package/dist/core/DrawerNavigationGroup.d.ts +45 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/validation.d.ts +3 -2
- package/dist/hooks/useBreadcrumbsController.d.ts +16 -0
- package/dist/hooks/useCollapsedGroups.d.ts +4 -1
- package/dist/index.es.js +5316 -1592
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5309 -1586
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +5 -0
- package/dist/preview/components/DatePreview.d.ts +13 -3
- package/dist/preview/components/ImagePreview.d.ts +5 -1
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/preview/property_previews/ArrayOfStorageComponentsPreview.d.ts +1 -1
- package/dist/preview/property_previews/ArrayOfStringsPreview.d.ts +1 -1
- package/dist/preview/property_previews/SkeletonPropertyComponent.d.ts +1 -1
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/collections.d.ts +50 -2
- package/dist/types/datasource.d.ts +0 -1
- package/dist/types/plugins.d.ts +62 -1
- package/dist/types/properties.d.ts +259 -4
- package/dist/util/__tests__/conditions.test.d.ts +1 -0
- package/dist/util/__tests__/objects.test.d.ts +1 -0
- package/dist/util/conditions.d.ts +26 -0
- package/dist/util/entities.d.ts +2 -3
- package/dist/util/index.d.ts +2 -1
- package/dist/util/property_utils.d.ts +2 -1
- package/dist/util/resolutions.d.ts +3 -3
- package/package.json +14 -11
- package/src/app/Scaffold.tsx +14 -15
- package/src/components/AIIcon.tsx +39 -0
- package/src/components/ArrayContainer.tsx +1 -4
- package/src/components/ClearFilterSortButton.tsx +19 -16
- package/src/components/ConfirmationDialog.tsx +0 -2
- package/src/components/DeleteEntityDialog.tsx +2 -4
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +74 -41
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +130 -79
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +121 -104
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +132 -103
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +20 -42
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +90 -49
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
- package/src/components/EntityCollectionView/Board.tsx +324 -0
- package/src/components/EntityCollectionView/BoardColumn.tsx +158 -0
- package/src/components/EntityCollectionView/BoardColumnTitle.tsx +45 -0
- package/src/components/EntityCollectionView/BoardSortableList.tsx +172 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +212 -0
- package/src/components/EntityCollectionView/EntityCard.tsx +235 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +733 -0
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +244 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +519 -203
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +31 -19
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +84 -15
- package/src/components/EntityCollectionView/FiltersDialog.tsx +249 -0
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +199 -0
- package/src/components/EntityCollectionView/board_types.ts +113 -0
- package/src/components/EntityCollectionView/useBoardDataController.tsx +490 -0
- package/src/components/ErrorTooltip.tsx +2 -1
- package/src/components/HomePage/DefaultHomePage.tsx +47 -10
- package/src/components/HomePage/HomePageDnD.tsx +56 -41
- package/src/components/HomePage/NavigationCard.tsx +20 -18
- package/src/components/HomePage/NavigationGroup.tsx +17 -16
- package/src/components/HomePage/RenameGroupDialog.tsx +0 -2
- package/src/components/HomePage/SmallNavigationCard.tsx +10 -9
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -10
- package/src/components/ReferenceWidget.tsx +2 -4
- package/src/components/SelectableTable/SelectableTable.tsx +75 -67
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +7 -6
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +39 -40
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -38
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +49 -58
- package/src/components/UnsavedChangesDialog.tsx +0 -2
- package/src/components/UserDisplay.tsx +4 -4
- package/src/components/VirtualTable/VirtualTable.tsx +272 -118
- package/src/components/VirtualTable/VirtualTableCell.tsx +18 -2
- package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -50
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +158 -42
- package/src/components/VirtualTable/VirtualTableProps.tsx +14 -1
- package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -0
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +19 -6
- package/src/components/VirtualTable/types.tsx +2 -0
- package/src/components/common/useColumnsIds.tsx +95 -3
- package/src/components/common/useDataSourceTableController.tsx +21 -4
- package/src/components/index.tsx +4 -0
- package/src/contexts/BreacrumbsContext.tsx +15 -8
- package/src/contexts/index.ts +10 -0
- package/src/core/DefaultAppBar.tsx +40 -27
- package/src/core/DefaultDrawer.tsx +42 -56
- package/src/core/DrawerNavigationGroup.tsx +118 -0
- package/src/core/DrawerNavigationItem.tsx +4 -3
- package/src/core/EntityEditView.tsx +41 -43
- package/src/core/EntitySidePanel.tsx +28 -26
- package/src/core/SideDialogs.tsx +4 -2
- package/src/core/field_configs.tsx +14 -9
- package/src/core/index.tsx +1 -0
- package/src/form/EntityForm.tsx +69 -60
- package/src/form/PropertyFieldBinding.tsx +61 -46
- package/src/form/components/ErrorFocus.tsx +3 -3
- package/src/form/components/StorageItemPreview.tsx +2 -1
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +0 -1
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -16
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +69 -67
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +22 -18
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +83 -83
- package/src/form/field_bindings/TextFieldBinding.tsx +71 -35
- package/src/form/validation.ts +245 -160
- package/src/hooks/useBreadcrumbsController.tsx +18 -0
- package/src/hooks/useBuildNavigationController.tsx +71 -28
- package/src/hooks/useCollapsedGroups.ts +12 -4
- package/src/hooks/useValidateAuthenticator.tsx +1 -1
- package/src/internal/useBuildDataSource.ts +68 -34
- package/src/internal/useBuildSideDialogsController.tsx +11 -8
- package/src/internal/useBuildSideEntityController.tsx +24 -24
- package/src/internal/useRestoreScroll.tsx +26 -14
- package/src/preview/PropertyPreview.tsx +41 -32
- package/src/preview/PropertyPreviewProps.tsx +6 -0
- package/src/preview/components/DatePreview.tsx +72 -4
- package/src/preview/components/EmptyValue.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +37 -21
- package/src/preview/components/StorageThumbnail.tsx +16 -12
- package/src/preview/components/UrlComponentPreview.tsx +28 -25
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +9 -7
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +11 -9
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +26 -24
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +61 -56
- package/src/routes/CustomCMSRoute.tsx +1 -0
- package/src/routes/FireCMSRoute.tsx +26 -13
- package/src/types/analytics.ts +10 -0
- package/src/types/collections.ts +57 -3
- package/src/types/datasource.ts +54 -56
- package/src/types/plugins.tsx +69 -1
- package/src/types/properties.ts +347 -27
- package/src/util/__tests__/conditions.test.ts +506 -0
- package/src/util/__tests__/objects.test.ts +196 -0
- package/src/util/callbacks.ts +6 -3
- package/src/util/collections.ts +51 -6
- package/src/util/conditions.ts +339 -0
- package/src/util/entities.ts +29 -30
- package/src/util/entity_cache.ts +2 -1
- package/src/util/index.ts +2 -1
- package/src/util/join_collections.ts +10 -8
- package/src/util/objects.ts +31 -13
- package/src/util/{references.ts → previews.ts} +16 -2
- package/src/util/property_utils.tsx +37 -11
- package/src/util/resolutions.ts +62 -58
- /package/dist/util/{references.d.ts → previews.d.ts} +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import { CollectionSize, Entity, EntityCollection, EntityTableController, SelectionController } from "../../types";
|
|
3
|
+
import { EntityCard } from "./EntityCard";
|
|
4
|
+
import { CircularProgress, cls, Typography } from "@firecms/ui";
|
|
5
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
6
|
+
|
|
7
|
+
export type EntityCollectionCardViewProps<M extends Record<string, any> = any> = {
|
|
8
|
+
collection: EntityCollection<M>;
|
|
9
|
+
tableController: EntityTableController<M>;
|
|
10
|
+
onEntityClick?: (entity: Entity<M>) => void;
|
|
11
|
+
selectionController?: SelectionController<M>;
|
|
12
|
+
selectionEnabled?: boolean;
|
|
13
|
+
highlightedEntities?: Entity<M>[];
|
|
14
|
+
emptyComponent?: React.ReactNode;
|
|
15
|
+
onScroll?: (props: {
|
|
16
|
+
scrollDirection: "forward" | "backward";
|
|
17
|
+
scrollOffset: number;
|
|
18
|
+
scrollUpdateWasRequested: boolean;
|
|
19
|
+
}) => void;
|
|
20
|
+
initialScroll?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Size of the cards in the grid view.
|
|
23
|
+
* - "xs": Extra small cards, most cards per row
|
|
24
|
+
* - "s": Small cards
|
|
25
|
+
* - "m": Medium cards (default)
|
|
26
|
+
* - "l": Large cards
|
|
27
|
+
* - "xl": Extra large cards, fewest cards per row
|
|
28
|
+
*/
|
|
29
|
+
size?: CollectionSize;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get grid column classes based on the size.
|
|
34
|
+
* Smaller size = more columns (smaller cards)
|
|
35
|
+
* Larger size = fewer columns (larger cards)
|
|
36
|
+
*/
|
|
37
|
+
function getGridColumnsClass(size: CollectionSize): string {
|
|
38
|
+
switch (size) {
|
|
39
|
+
case "xs":
|
|
40
|
+
// Compact: many small cards
|
|
41
|
+
return "grid-cols-4 sm:grid-cols-5 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10";
|
|
42
|
+
case "s":
|
|
43
|
+
// Small: more cards per row
|
|
44
|
+
return "grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-8";
|
|
45
|
+
case "m":
|
|
46
|
+
// Medium: balanced (default)
|
|
47
|
+
return "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6";
|
|
48
|
+
case "l":
|
|
49
|
+
// Large: fewer, bigger cards
|
|
50
|
+
return "grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4";
|
|
51
|
+
case "xl":
|
|
52
|
+
// Extra large: fewest, biggest cards
|
|
53
|
+
return "grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3";
|
|
54
|
+
default:
|
|
55
|
+
return "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Card grid view for displaying entities with infinite scroll.
|
|
61
|
+
* Alternative to the EntityCollectionTable for visual browsing.
|
|
62
|
+
*/
|
|
63
|
+
export function EntityCollectionCardView<M extends Record<string, any> = any>({
|
|
64
|
+
collection,
|
|
65
|
+
tableController,
|
|
66
|
+
onEntityClick,
|
|
67
|
+
selectionController,
|
|
68
|
+
selectionEnabled = true,
|
|
69
|
+
highlightedEntities,
|
|
70
|
+
emptyComponent,
|
|
71
|
+
onScroll,
|
|
72
|
+
initialScroll,
|
|
73
|
+
size = "m"
|
|
74
|
+
}: EntityCollectionCardViewProps<M>) {
|
|
75
|
+
const authController = useAuthController();
|
|
76
|
+
const customizationController = useCustomizationController();
|
|
77
|
+
|
|
78
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
79
|
+
const loadMoreRef = useRef<HTMLDivElement>(null);
|
|
80
|
+
const hasRestoredScroll = useRef(false);
|
|
81
|
+
|
|
82
|
+
const {
|
|
83
|
+
data,
|
|
84
|
+
dataLoading,
|
|
85
|
+
noMoreToLoad,
|
|
86
|
+
dataLoadingError,
|
|
87
|
+
itemCount,
|
|
88
|
+
setItemCount,
|
|
89
|
+
pageSize = 50,
|
|
90
|
+
paginationEnabled
|
|
91
|
+
} = tableController;
|
|
92
|
+
|
|
93
|
+
// Track if we're currently loading to prevent multiple simultaneous load requests
|
|
94
|
+
const isLoadingMore = useRef(false);
|
|
95
|
+
|
|
96
|
+
// Infinite scroll with Intersection Observer
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (!paginationEnabled || noMoreToLoad || dataLoading) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Reset loading flag when dataLoading becomes false
|
|
103
|
+
if (!dataLoading) {
|
|
104
|
+
isLoadingMore.current = false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const observer = new IntersectionObserver(
|
|
108
|
+
(entries) => {
|
|
109
|
+
if (entries[0].isIntersecting && !dataLoading && !noMoreToLoad && !isLoadingMore.current) {
|
|
110
|
+
// Prevent multiple load requests
|
|
111
|
+
isLoadingMore.current = true;
|
|
112
|
+
// Load more items
|
|
113
|
+
setItemCount?.((itemCount ?? pageSize) + pageSize);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
root: containerRef.current, // Use the scroll container, not viewport
|
|
118
|
+
rootMargin: "400px",
|
|
119
|
+
threshold: 0
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
if (loadMoreRef.current) {
|
|
124
|
+
observer.observe(loadMoreRef.current);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return () => observer.disconnect();
|
|
128
|
+
}, [paginationEnabled, noMoreToLoad, dataLoading, itemCount, pageSize, setItemCount]);
|
|
129
|
+
|
|
130
|
+
// Scroll restoration: restore initial scroll position
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (containerRef.current && initialScroll && !hasRestoredScroll.current && data.length > 0) {
|
|
133
|
+
containerRef.current.scrollTop = initialScroll;
|
|
134
|
+
hasRestoredScroll.current = true;
|
|
135
|
+
}
|
|
136
|
+
}, [initialScroll, data.length]);
|
|
137
|
+
|
|
138
|
+
// Scroll tracking: call onScroll when user scrolls
|
|
139
|
+
const lastScrollOffset = useRef(0);
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
const container = containerRef.current;
|
|
142
|
+
if (!container || !onScroll) return;
|
|
143
|
+
|
|
144
|
+
const handleScroll = () => {
|
|
145
|
+
const currentOffset = container.scrollTop;
|
|
146
|
+
const direction = currentOffset > lastScrollOffset.current ? "forward" : "backward";
|
|
147
|
+
lastScrollOffset.current = currentOffset;
|
|
148
|
+
onScroll({
|
|
149
|
+
scrollDirection: direction,
|
|
150
|
+
scrollOffset: currentOffset,
|
|
151
|
+
scrollUpdateWasRequested: false
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
156
|
+
return () => container.removeEventListener("scroll", handleScroll);
|
|
157
|
+
}, [onScroll]);
|
|
158
|
+
|
|
159
|
+
const handleEntityClick = useCallback((entity: Entity<M>) => {
|
|
160
|
+
onEntityClick?.(entity);
|
|
161
|
+
}, [onEntityClick]);
|
|
162
|
+
|
|
163
|
+
const handleSelectionChange = useCallback((entity: Entity<M>, selected: boolean) => {
|
|
164
|
+
selectionController?.toggleEntitySelection(entity, selected);
|
|
165
|
+
}, [selectionController]);
|
|
166
|
+
|
|
167
|
+
const isEntitySelected = useCallback((entity: Entity<M>) => {
|
|
168
|
+
return selectionController?.isEntitySelected(entity) ?? false;
|
|
169
|
+
}, [selectionController]);
|
|
170
|
+
|
|
171
|
+
const isEntityHighlighted = useCallback((entity: Entity<M>) => {
|
|
172
|
+
return highlightedEntities?.some(e => e.id === entity.id && e.path === entity.path) ?? false;
|
|
173
|
+
}, [highlightedEntities]);
|
|
174
|
+
|
|
175
|
+
// Show empty state
|
|
176
|
+
if (!dataLoading && data.length === 0 && !dataLoadingError) {
|
|
177
|
+
return (
|
|
178
|
+
<div className="flex-1 flex items-center justify-center p-8">
|
|
179
|
+
{emptyComponent ?? (
|
|
180
|
+
<Typography variant="label" color="secondary">
|
|
181
|
+
No entries found
|
|
182
|
+
</Typography>
|
|
183
|
+
)}
|
|
184
|
+
</div>
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Show error state
|
|
189
|
+
if (dataLoadingError) {
|
|
190
|
+
return (
|
|
191
|
+
<div className="flex-1 flex items-center justify-center p-8">
|
|
192
|
+
<Typography className="text-red-500">
|
|
193
|
+
Error loading data: {dataLoadingError.message}
|
|
194
|
+
</Typography>
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const gridColumnsClass = getGridColumnsClass(size);
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div
|
|
203
|
+
ref={containerRef}
|
|
204
|
+
className="flex-1 overflow-auto p-4"
|
|
205
|
+
>
|
|
206
|
+
{/* Card Grid with max-width container */}
|
|
207
|
+
<div className="max-w-7xl mx-auto">
|
|
208
|
+
<div className={cls(
|
|
209
|
+
"grid gap-4",
|
|
210
|
+
gridColumnsClass
|
|
211
|
+
)}>
|
|
212
|
+
{data.map((entity) => (
|
|
213
|
+
<EntityCard
|
|
214
|
+
key={`${entity.path}_${entity.id}`}
|
|
215
|
+
entity={entity}
|
|
216
|
+
collection={collection}
|
|
217
|
+
onClick={handleEntityClick}
|
|
218
|
+
selected={isEntitySelected(entity)}
|
|
219
|
+
highlighted={isEntityHighlighted(entity)}
|
|
220
|
+
onSelectionChange={handleSelectionChange}
|
|
221
|
+
selectionEnabled={selectionEnabled}
|
|
222
|
+
size={size}
|
|
223
|
+
/>
|
|
224
|
+
))}
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
{/* Load more trigger / Loading indicator */}
|
|
228
|
+
<div
|
|
229
|
+
ref={loadMoreRef}
|
|
230
|
+
className="flex items-center justify-center py-8"
|
|
231
|
+
>
|
|
232
|
+
{dataLoading && (
|
|
233
|
+
<CircularProgress size="small"/>
|
|
234
|
+
)}
|
|
235
|
+
{!dataLoading && noMoreToLoad && data.length > 0 && (
|
|
236
|
+
<Typography variant="caption" color="secondary">
|
|
237
|
+
All {data.length} entries loaded
|
|
238
|
+
</Typography>
|
|
239
|
+
)}
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
}
|