@rebasepro/admin 0.0.1-canary.eae7889 → 0.1.0
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/{CollectionEditorDialog-B2M9lCyL.js → CollectionEditorDialog-MbvXGzEq.js} +42 -31
- package/dist/CollectionEditorDialog-MbvXGzEq.js.map +1 -0
- package/dist/{CollectionsStudioView-WG6soyfs.js → CollectionsStudioView-D9X6aiAr.js} +12 -12
- package/dist/CollectionsStudioView-D9X6aiAr.js.map +1 -0
- package/dist/{ContentHomePage-CDF_a6Lp.js → ContentHomePage-CfVB1eUo.js} +26 -26
- package/dist/ContentHomePage-CfVB1eUo.js.map +1 -0
- package/dist/{ExportCollectionAction-Dc0VOWMN.js → ExportCollectionAction-CUwJg4F9.js} +2 -2
- package/dist/{ExportCollectionAction-Dc0VOWMN.js.map → ExportCollectionAction-CUwJg4F9.js.map} +1 -1
- package/dist/{ImportCollectionAction-DpCagAOy.js → ImportCollectionAction-DGa_SF_8.js} +2 -2
- package/dist/{ImportCollectionAction-DpCagAOy.js.map → ImportCollectionAction-DGa_SF_8.js.map} +1 -1
- package/dist/{PropertyEditView-DS67DxoT.js → PropertyEditView-C4nlYmAc.js} +82 -104
- package/dist/PropertyEditView-C4nlYmAc.js.map +1 -0
- package/dist/{RolesView-CIuYBimF.js → RolesView-CNWxnR8e.js} +7 -5
- package/dist/RolesView-CNWxnR8e.js.map +1 -0
- package/dist/{UsersView-B5zelXnH.js → UsersView-YiTIcXkA.js} +14 -35
- package/dist/UsersView-YiTIcXkA.js.map +1 -0
- package/dist/collection_editor/ConfigControllerProvider.d.ts +0 -4
- package/dist/collection_editor/types/collection_editor_controller.d.ts +6 -3
- package/dist/collection_editor/types/config_controller.d.ts +14 -7
- package/dist/collection_editor/ui/AddKanbanColumnAction.d.ts +3 -2
- package/dist/collection_editor/ui/CollectionViewHeaderAction.d.ts +3 -2
- package/dist/collection_editor/ui/EditorCollectionAction.d.ts +1 -1
- package/dist/collection_editor/ui/EditorCollectionActionStart.d.ts +1 -1
- package/dist/collection_editor/ui/EditorEntityAction.d.ts +1 -1
- package/dist/collection_editor/ui/KanbanSetupAction.d.ts +3 -2
- package/dist/collection_editor/ui/PropertyAddColumnComponent.d.ts +3 -2
- package/dist/collection_editor/ui/collection_editor/CollectionDetailsForm.d.ts +3 -4
- package/dist/collection_editor/ui/collection_editor/CollectionEditorDialog.d.ts +2 -3
- package/dist/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -2
- package/dist/collection_editor/ui/collection_editor/SubcollectionsEditTab.d.ts +3 -2
- package/dist/collection_editor_ui.js +3 -3
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +1 -1
- package/dist/components/EntityCollectionTable/column_utils.d.ts +2 -2
- package/dist/components/EntityCollectionTable/fields/TableMultipleRelationField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableRelationField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/fields/TableRelationSelectorField.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +5 -1
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -2
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +2 -1
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +4 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +4 -2
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -2
- package/dist/components/EntityCollectionView/SplitListView.d.ts +3 -2
- package/dist/components/EntityEditView.d.ts +9 -2
- package/dist/components/RebaseCMS.d.ts +1 -1
- package/dist/components/ReferenceTable/EntitySelectionTable.d.ts +2 -2
- package/dist/components/ReferenceWidget.d.ts +2 -2
- package/dist/components/RelationSelector.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +2 -2
- package/dist/editor.js +2 -2
- package/dist/editor.js.map +1 -1
- package/dist/hooks/navigation/useNavigationRegistry.d.ts +2 -1
- package/dist/hooks/useEntityHistory.d.ts +1 -1
- package/dist/{index-CHxgwt6E.js → index-CtzpHzMQ.js} +11 -4
- package/dist/index-CtzpHzMQ.js.map +1 -0
- package/dist/{index-Dey5WJpO.js → index-DKlrVD1m.js} +3 -3
- package/dist/index-DKlrVD1m.js.map +1 -0
- package/dist/{index-CBhrgpR7.js → index-kHJXfLNI.js} +3 -3
- package/dist/index-kHJXfLNI.js.map +1 -0
- package/dist/index.js +79 -63
- package/dist/index.js.map +1 -1
- package/dist/{useEntityHistory-Dcj4zhGj.js → useEntityHistory-UVsSclfZ.js} +3 -1
- package/dist/useEntityHistory-UVsSclfZ.js.map +1 -0
- package/dist/util/navigation_utils.d.ts +10 -1
- package/dist/{util-BQ82ySL3.js → util-CwLmSpGp.js} +1653 -1257
- package/dist/util-CwLmSpGp.js.map +1 -0
- package/package.json +9 -17
- package/src/collection_editor/ConfigControllerProvider.tsx +19 -28
- package/src/collection_editor/types/collection_editor_controller.tsx +3 -3
- package/src/collection_editor/types/config_controller.tsx +7 -7
- package/src/collection_editor/ui/AddKanbanColumnAction.tsx +4 -4
- package/src/collection_editor/ui/CollectionViewHeaderAction.tsx +3 -3
- package/src/collection_editor/ui/EditorCollectionAction.tsx +3 -3
- package/src/collection_editor/ui/EditorCollectionActionStart.tsx +7 -7
- package/src/collection_editor/ui/EditorEntityAction.tsx +3 -3
- package/src/collection_editor/ui/HomePageEditorCollectionAction.tsx +4 -2
- package/src/collection_editor/ui/KanbanSetupAction.tsx +4 -3
- package/src/collection_editor/ui/MissingReferenceWidget.tsx +3 -2
- package/src/collection_editor/ui/NewCollectionButton.tsx +2 -1
- package/src/collection_editor/ui/NewCollectionCard.tsx +2 -1
- package/src/collection_editor/ui/PropertyAddColumnComponent.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionDetailsForm.tsx +5 -50
- package/src/collection_editor/ui/collection_editor/CollectionEditorDialog.tsx +12 -20
- package/src/collection_editor/ui/collection_editor/CollectionPropertiesEditorForm.tsx +1 -3
- package/src/collection_editor/ui/collection_editor/CollectionRLSTab.tsx +17 -2
- package/src/collection_editor/ui/collection_editor/CollectionRelationsTab.tsx +3 -3
- package/src/collection_editor/ui/collection_editor/CollectionStudioView.tsx +2 -1
- package/src/collection_editor/ui/collection_editor/CollectionsStudioView.tsx +18 -12
- package/src/collection_editor/ui/collection_editor/DisplaySettingsForm.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/GetCodeDialog.tsx +1 -2
- package/src/collection_editor/ui/collection_editor/PropertyFieldPreview.tsx +6 -6
- package/src/collection_editor/ui/collection_editor/SubcollectionsEditTab.tsx +4 -4
- package/src/collection_editor/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
- package/src/collection_editor/ui/collection_editor/properties/ReferencePropertyField.tsx +15 -49
- package/src/collection_editor/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +4 -5
- package/src/collection_editor/ui/collection_editor/templates/pages_template.ts +1 -1
- package/src/collection_editor/ui/collection_editor/templates/products_template.ts +2 -2
- package/src/components/DefaultAppBar.tsx +2 -2
- package/src/components/DefaultDrawer.tsx +25 -17
- package/src/components/DrawerNavigationGroup.tsx +4 -4
- package/src/components/DrawerNavigationItem.tsx +6 -6
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +1 -1
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -4
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableMultipleRelationField.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableRelationField.tsx +4 -4
- package/src/components/EntityCollectionTable/fields/TableRelationSelectorField.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +8 -2
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/common.tsx +5 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +1 -1
- package/src/components/EntityCollectionTable/table_bindings.tsx +45 -35
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +18 -19
- package/src/components/EntityCollectionView/EntityCard.tsx +2 -2
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +42 -14
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionListView.tsx +157 -54
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +169 -75
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +23 -13
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +21 -12
- package/src/components/EntityCollectionView/FiltersDialog.tsx +7 -7
- package/src/components/EntityCollectionView/SplitListView.tsx +24 -8
- package/src/components/EntityCollectionView/useEntityPreviewSlots.ts +33 -5
- package/src/components/EntityEditView.tsx +85 -85
- package/src/components/EntitySidePanel.tsx +18 -10
- package/src/components/HomePage/ContentHomePage.tsx +24 -15
- package/src/components/HomePage/NavigationCard.tsx +4 -4
- package/src/components/HomePage/NavigationGroup.tsx +2 -2
- package/src/components/RebaseAuthGate.tsx +2 -0
- package/src/components/RebaseCMS.tsx +4 -3
- package/src/components/RebaseNavigation.tsx +8 -5
- package/src/components/ReferenceTable/EntitySelectionTable.tsx +4 -4
- package/src/components/ReferenceWidget.tsx +3 -3
- package/src/components/RelationSelector.tsx +33 -5
- package/src/components/SelectableTable/SelectableTable.tsx +6 -6
- package/src/components/UserSelector.tsx +1 -1
- package/src/components/admin/RolesView.tsx +10 -3
- package/src/components/admin/UsersView.tsx +13 -25
- package/src/components/app/Scaffold.tsx +4 -4
- package/src/components/field_configs.tsx +29 -32
- package/src/components/history/EntityHistoryView.tsx +12 -1
- package/src/editor/editor.tsx +2 -2
- package/src/form/EntityForm.tsx +5 -4
- package/src/form/PropertyFieldBinding.tsx +14 -10
- package/src/form/components/FieldHelperText.tsx +1 -1
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -5
- package/src/form/field_bindings/BlockFieldBinding.tsx +4 -4
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +7 -7
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MultipleRelationFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +7 -7
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +2 -2
- package/src/form/field_bindings/RelationFieldBinding.tsx +4 -4
- package/src/form/field_bindings/RepeatFieldBinding.tsx +5 -5
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -1
- package/src/form/field_bindings/TextFieldBinding.tsx +7 -7
- package/src/form/field_bindings/UserSelectFieldBinding.tsx +1 -1
- package/src/form/useClearRestoreValue.tsx +1 -1
- package/src/form/validation.ts +1 -1
- package/src/hooks/navigation/contexts/CollectionRegistryContext.tsx +2 -1
- package/src/hooks/navigation/useBuildCollectionRegistryController.tsx +15 -3
- package/src/hooks/navigation/useNavigationRegistry.ts +14 -3
- package/src/hooks/navigation/useResolvedViews.tsx +1 -3
- package/src/hooks/navigation/useTopLevelNavigation.ts +1 -1
- package/src/hooks/navigation/utils.ts +1 -1
- package/src/hooks/useEntityHistory.ts +7 -2
- package/src/preview/PropertyPreview.tsx +27 -23
- package/src/preview/components/StorageThumbnail.tsx +4 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfRelationsPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +3 -3
- package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
- package/src/routes/RebaseRoute.tsx +57 -11
- package/src/util/navigation_utils.ts +21 -2
- package/src/util/previews.ts +15 -6
- package/src/util/property_utils.tsx +3 -3
- package/dist/CollectionEditorDialog-B2M9lCyL.js.map +0 -1
- package/dist/CollectionsStudioView-WG6soyfs.js.map +0 -1
- package/dist/ContentHomePage-CDF_a6Lp.js.map +0 -1
- package/dist/PropertyEditView-DS67DxoT.js.map +0 -1
- package/dist/RolesView-CIuYBimF.js.map +0 -1
- package/dist/UsersView-B5zelXnH.js.map +0 -1
- package/dist/index-CBhrgpR7.js.map +0 -1
- package/dist/index-CHxgwt6E.js.map +0 -1
- package/dist/index-Dey5WJpO.js.map +0 -1
- package/dist/useEntityHistory-Dcj4zhGj.js.map +0 -1
- package/dist/util-BQ82ySL3.js.map +0 -1
|
@@ -6,6 +6,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
|
6
6
|
import { deepEqual as equal } from "fast-equals"
|
|
7
7
|
|
|
8
8
|
const EMPTY_ARRAY: any[] = [];
|
|
9
|
+
const DEFAULT_ENTITY_OPEN_MODE = "split";
|
|
9
10
|
|
|
10
11
|
import { CollectionSize, Entity, EntityReference, EntityTableController, FilterValues, PartialEntityCollection, SaveEntityProps, ViewMode } from "@rebasepro/types";
|
|
11
12
|
import {
|
|
@@ -29,7 +30,8 @@ import {
|
|
|
29
30
|
useLargeLayout,
|
|
30
31
|
usePermissions,
|
|
31
32
|
useTranslation,
|
|
32
|
-
useSlot
|
|
33
|
+
useSlot,
|
|
34
|
+
IconForView
|
|
33
35
|
} from "@rebasepro/core";
|
|
34
36
|
import { useUserConfigurationPersistence } from "@rebasepro/core";
|
|
35
37
|
import { EntityCollectionViewActions } from "./EntityCollectionViewActions";
|
|
@@ -62,15 +64,15 @@ import { mergeDeep } from "@rebasepro/utils";
|
|
|
62
64
|
import { useCollectionRegistryController, useUrlController, useSideEntityController, useCMSContext } from "../../index";
|
|
63
65
|
import { useBreadcrumbsController } from "../../index";
|
|
64
66
|
|
|
65
|
-
const DEFAULT_ENTITY_OPEN_MODE: "side_panel" | "full_screen" | "split" = "split";
|
|
66
|
-
|
|
67
67
|
function getOpenEntityMode(
|
|
68
68
|
viewMode: ViewMode,
|
|
69
69
|
configuredMode?: "side_panel" | "full_screen" | "split"
|
|
70
70
|
): "side_panel" | "full_screen" | "split" {
|
|
71
71
|
if (configuredMode) return configuredMode;
|
|
72
72
|
if (viewMode === "kanban") return "side_panel";
|
|
73
|
-
return
|
|
73
|
+
if (viewMode === "table" || viewMode === "cards") return "full_screen";
|
|
74
|
+
// "list" view defaults to split
|
|
75
|
+
return "split";
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
/**
|
|
@@ -89,7 +91,7 @@ export type EntityCollectionViewProps<M extends Record<string, unknown>> = {
|
|
|
89
91
|
/**
|
|
90
92
|
* If this is a subcollection, specify the parent collection ids.
|
|
91
93
|
*/
|
|
92
|
-
|
|
94
|
+
parentCollectionSlugs?: string[], parentEntityIds?: string[];
|
|
93
95
|
/**
|
|
94
96
|
* Whether this is a subcollection or not.
|
|
95
97
|
*/
|
|
@@ -144,7 +146,7 @@ export const EntityCollectionView = React.memo(
|
|
|
144
146
|
function EntityCollectionView<M extends Record<string, unknown>>({
|
|
145
147
|
path: pathProp,
|
|
146
148
|
|
|
147
|
-
|
|
149
|
+
parentCollectionSlugs, parentEntityIds,
|
|
148
150
|
isSubCollection,
|
|
149
151
|
className,
|
|
150
152
|
updateUrl,
|
|
@@ -173,9 +175,10 @@ export const EntityCollectionView = React.memo(
|
|
|
173
175
|
const scrollRestoration = useScrollRestoration();
|
|
174
176
|
|
|
175
177
|
const collection = useMemo(() => {
|
|
178
|
+
const registryCollection = collectionRegistry.getCollection(path) || collectionProp;
|
|
176
179
|
const userOverride = userConfigPersistence?.getCollectionConfig<M>(path);
|
|
177
|
-
return (userOverride ? mergeDeep(
|
|
178
|
-
}, [collectionProp, path, userConfigPersistence
|
|
180
|
+
return (userOverride ? mergeDeep(registryCollection, userOverride) : registryCollection) as EntityCollection<M>;
|
|
181
|
+
}, [collectionProp, path, userConfigPersistence, collectionRegistry]);
|
|
179
182
|
|
|
180
183
|
const collectionRef = React.useRef(collection);
|
|
181
184
|
useEffect(() => {
|
|
@@ -371,6 +374,23 @@ export const EntityCollectionView = React.memo(
|
|
|
371
374
|
})
|
|
372
375
|
}, [path, sideEntityController]);
|
|
373
376
|
|
|
377
|
+
const openNewDocument = useCallback((defaultValues?: Record<string, unknown>) => {
|
|
378
|
+
const collection = collectionRef.current;
|
|
379
|
+
analyticsController.onAnalyticsEvent?.("new_entity_click", {
|
|
380
|
+
path: path
|
|
381
|
+
});
|
|
382
|
+
navigateToEntity({
|
|
383
|
+
openEntityMode,
|
|
384
|
+
collection,
|
|
385
|
+
entityId: undefined,
|
|
386
|
+
defaultValues,
|
|
387
|
+
path: path,
|
|
388
|
+
sideEntityController,
|
|
389
|
+
navigation: urlController,
|
|
390
|
+
onClose: unselectNavigatedEntity
|
|
391
|
+
});
|
|
392
|
+
}, [path, sideEntityController, openEntityMode, urlController, unselectNavigatedEntity]);
|
|
393
|
+
|
|
374
394
|
const onMultipleDeleteClick = () => {
|
|
375
395
|
analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
|
|
376
396
|
path: path
|
|
@@ -399,14 +419,14 @@ export const EntityCollectionView = React.memo(
|
|
|
399
419
|
|
|
400
420
|
const pluginAddColumnComponents = useSlot("collection.add-column", {
|
|
401
421
|
path,
|
|
402
|
-
|
|
422
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
403
423
|
collection,
|
|
404
424
|
tableController
|
|
405
425
|
});
|
|
406
426
|
|
|
407
427
|
const pluginToolbarWidgets = useSlot("collection.toolbar", {
|
|
408
428
|
path,
|
|
409
|
-
|
|
429
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
410
430
|
collection: collection,
|
|
411
431
|
tableController: tableController,
|
|
412
432
|
selectionController: usedSelectionController
|
|
@@ -414,7 +434,7 @@ export const EntityCollectionView = React.memo(
|
|
|
414
434
|
|
|
415
435
|
const pluginEmptyStates = useSlot("collection.empty-state", {
|
|
416
436
|
path,
|
|
417
|
-
|
|
437
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
418
438
|
collection,
|
|
419
439
|
canCreate: canCreateEntities,
|
|
420
440
|
onNewClick
|
|
@@ -422,7 +442,7 @@ export const EntityCollectionView = React.memo(
|
|
|
422
442
|
|
|
423
443
|
const pluginInsights = useSlot("collection.insights", {
|
|
424
444
|
path,
|
|
425
|
-
|
|
445
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
426
446
|
collection
|
|
427
447
|
});
|
|
428
448
|
|
|
@@ -714,9 +734,11 @@ export const EntityCollectionView = React.memo(
|
|
|
714
734
|
}, [updateLastDeleteTimestamp, usedSelectionController]);
|
|
715
735
|
|
|
716
736
|
// Update breadcrumb count when count changes
|
|
737
|
+
const updateCountRef = React.useRef(breadcrumbs.updateCount);
|
|
738
|
+
updateCountRef.current = breadcrumbs.updateCount;
|
|
717
739
|
useEffect(() => {
|
|
718
|
-
|
|
719
|
-
}, [docsCount, path
|
|
740
|
+
updateCountRef.current(path, docsCount);
|
|
741
|
+
}, [docsCount, path]);
|
|
720
742
|
|
|
721
743
|
// EntitiesCount fetches count and updates breadcrumb - no visual rendering needed here
|
|
722
744
|
const countFetcher = <EntitiesCount
|
|
@@ -751,14 +773,14 @@ export const EntityCollectionView = React.memo(
|
|
|
751
773
|
path,
|
|
752
774
|
collection: collection as unknown as EntityCollection,
|
|
753
775
|
tableController: tableController as unknown as EntityTableController,
|
|
754
|
-
|
|
776
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY
|
|
755
777
|
};
|
|
756
778
|
return <>{headerActionContributions.map((s, i) => (
|
|
757
779
|
<ErrorBoundary key={`header_action_${propertyKey}_${i}`}>
|
|
758
780
|
<s.Component {...headerSlotProps} {...(s.props ?? {})}/>
|
|
759
781
|
</ErrorBoundary>
|
|
760
782
|
))}</>;
|
|
761
|
-
}, [headerActionContributions, path,
|
|
783
|
+
}, [headerActionContributions, path, parentCollectionSlugs]);
|
|
762
784
|
|
|
763
785
|
const addColumnComponentInternal = pluginAddColumnComponents.length > 0
|
|
764
786
|
? function () {
|
|
@@ -794,13 +816,13 @@ export const EntityCollectionView = React.memo(
|
|
|
794
816
|
.forEach(plugin => {
|
|
795
817
|
plugin.hooks!.onColumnsReorder!({
|
|
796
818
|
fullPath: path,
|
|
797
|
-
|
|
819
|
+
parentCollectionSlugs: parentCollectionSlugs ?? EMPTY_ARRAY, parentEntityIds: parentEntityIds ?? EMPTY_ARRAY,
|
|
798
820
|
collection,
|
|
799
821
|
newPropertiesOrder
|
|
800
822
|
});
|
|
801
823
|
});
|
|
802
824
|
}
|
|
803
|
-
}, [collection, setLocalPropertiesOrder, customizationController, path,
|
|
825
|
+
}, [collection, setLocalPropertiesOrder, customizationController, path, parentCollectionSlugs]);
|
|
804
826
|
|
|
805
827
|
// Popover open state managed at parent level to prevent closing when view changes
|
|
806
828
|
const [viewModePopoverOpen, setViewModePopoverOpen] = useState(false);
|
|
@@ -825,7 +847,7 @@ export const EntityCollectionView = React.memo(
|
|
|
825
847
|
const pluginErrorViews = useSlot("collection.error", {
|
|
826
848
|
path,
|
|
827
849
|
collection,
|
|
828
|
-
|
|
850
|
+
parentCollectionSlugs, parentEntityIds,
|
|
829
851
|
error: tableController.dataLoadingError as Error
|
|
830
852
|
});
|
|
831
853
|
const pluginErrorView = tableController.dataLoadingError && pluginErrorViews.length > 0
|
|
@@ -833,7 +855,8 @@ export const EntityCollectionView = React.memo(
|
|
|
833
855
|
: null;
|
|
834
856
|
|
|
835
857
|
// Shared empty state — plugin slot takes priority, then default
|
|
836
|
-
const
|
|
858
|
+
const isSearching = !!tableController.searchString;
|
|
859
|
+
const isFilteredOrSorted = tableController.filterValues !== undefined || tableController.sortBy !== undefined || isSearching;
|
|
837
860
|
const emptyComponent = pluginEmptyStates.length > 0
|
|
838
861
|
? <>{pluginEmptyStates}</>
|
|
839
862
|
: canCreateEntities && !isFilteredOrSorted
|
|
@@ -847,16 +870,21 @@ export const EntityCollectionView = React.memo(
|
|
|
847
870
|
{t("create_your_first_entry")}
|
|
848
871
|
</Button>
|
|
849
872
|
</div>
|
|
850
|
-
: <Typography variant={"label"}>
|
|
873
|
+
: <Typography variant={"label"}>
|
|
874
|
+
{isSearching
|
|
875
|
+
? t("no_results_search", { search: tableController.searchString ?? "" })
|
|
876
|
+
: t("no_results_filter_sort")}
|
|
877
|
+
</Typography>;
|
|
851
878
|
|
|
852
879
|
const toolbarNode = (
|
|
853
880
|
<CollectionTableToolbar
|
|
854
881
|
compact={isCompact}
|
|
855
882
|
loading={tableController.dataLoading}
|
|
856
883
|
onTextSearch={tableController.setSearchString}
|
|
884
|
+
initialSearchText={tableController.searchString}
|
|
857
885
|
viewModeToggle={viewModeToggleElement}
|
|
858
886
|
actionsStart={<EntityCollectionViewStartActions
|
|
859
|
-
|
|
887
|
+
parentCollectionSlugs={parentCollectionSlugs ?? EMPTY_ARRAY} parentEntityIds={parentEntityIds ?? EMPTY_ARRAY}
|
|
860
888
|
collection={collection}
|
|
861
889
|
tableController={tableController}
|
|
862
890
|
path={path}
|
|
@@ -864,14 +892,16 @@ export const EntityCollectionView = React.memo(
|
|
|
864
892
|
selectionController={usedSelectionController}
|
|
865
893
|
collectionEntitiesCount={docsCount ?? undefined}
|
|
866
894
|
resolvedProperties={resolvedCollection.properties}
|
|
895
|
+
openNewDocument={openNewDocument}
|
|
867
896
|
compact={isCompact}/>}
|
|
868
897
|
actions={
|
|
869
898
|
<EntityCollectionViewActions
|
|
870
|
-
|
|
899
|
+
parentCollectionSlugs={parentCollectionSlugs ?? EMPTY_ARRAY} parentEntityIds={parentEntityIds ?? EMPTY_ARRAY}
|
|
871
900
|
collection={collection}
|
|
872
901
|
tableController={tableController}
|
|
873
902
|
onMultipleDeleteClick={onMultipleDeleteClick}
|
|
874
903
|
onNewClick={onNewClick}
|
|
904
|
+
openNewDocument={openNewDocument}
|
|
875
905
|
path={path}
|
|
876
906
|
relativePath={collection.slug}
|
|
877
907
|
selectionController={usedSelectionController}
|
|
@@ -889,7 +919,7 @@ export const EntityCollectionView = React.memo(
|
|
|
889
919
|
collection={collection}
|
|
890
920
|
tableController={tableController}
|
|
891
921
|
fullPath={path}
|
|
892
|
-
|
|
922
|
+
parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
|
|
893
923
|
columnProperty={selectedKanbanProperty}
|
|
894
924
|
onEntityClick={onEntityClick}
|
|
895
925
|
selectionController={usedSelectionController}
|
|
@@ -987,7 +1017,7 @@ export const EntityCollectionView = React.memo(
|
|
|
987
1017
|
size={listSize}
|
|
988
1018
|
emptyComponent={emptyComponent}
|
|
989
1019
|
path={path}
|
|
990
|
-
|
|
1020
|
+
parentCollectionSlugs={parentCollectionSlugs} parentEntityIds={parentEntityIds}
|
|
991
1021
|
selectedEntityId={selectedEntityIdProp}
|
|
992
1022
|
selectedTab={selectedTabProp}
|
|
993
1023
|
toolbar={toolbarNode}
|
|
@@ -1000,7 +1030,7 @@ export const EntityCollectionView = React.memo(
|
|
|
1000
1030
|
className={cls(
|
|
1001
1031
|
"flex flex-col w-full",
|
|
1002
1032
|
selectedEntityIdProp === undefined
|
|
1003
|
-
? "max-w-6xl mx-auto px-3 md:px-4 lg
|
|
1033
|
+
? "max-w-6xl mx-auto px-3 md:px-4 lg:px-6 py-4"
|
|
1004
1034
|
: ""
|
|
1005
1035
|
)}
|
|
1006
1036
|
>
|
|
@@ -1020,8 +1050,17 @@ export const EntityCollectionView = React.memo(
|
|
|
1020
1050
|
</div>
|
|
1021
1051
|
</div>
|
|
1022
1052
|
{pluginInsights.length > 0 && (
|
|
1023
|
-
<div
|
|
1024
|
-
{
|
|
1053
|
+
<div
|
|
1054
|
+
className={cls(
|
|
1055
|
+
"grid transition-[grid-template-rows] duration-150 ease-out",
|
|
1056
|
+
selectedEntityIdProp === undefined
|
|
1057
|
+
? "grid-rows-[1fr]"
|
|
1058
|
+
: "grid-rows-[0fr]"
|
|
1059
|
+
)}
|
|
1060
|
+
>
|
|
1061
|
+
<div className="overflow-hidden flex-shrink-0">
|
|
1062
|
+
{pluginInsights}
|
|
1063
|
+
</div>
|
|
1025
1064
|
</div>
|
|
1026
1065
|
)}
|
|
1027
1066
|
<EntityCollectionListView
|
|
@@ -1042,15 +1081,44 @@ export const EntityCollectionView = React.memo(
|
|
|
1042
1081
|
)}
|
|
1043
1082
|
</SplitListView>
|
|
1044
1083
|
) : (
|
|
1045
|
-
|
|
1084
|
+
<div className="flex flex-col w-full h-full">
|
|
1046
1085
|
{toolbarNode}
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1086
|
+
<div className="flex-1 flex flex-col overflow-y-auto">
|
|
1087
|
+
{viewMode === "list" ? (
|
|
1088
|
+
<div
|
|
1089
|
+
className={cls(
|
|
1090
|
+
"flex flex-col w-full",
|
|
1091
|
+
selectedEntityIdProp === undefined
|
|
1092
|
+
? "max-w-6xl mx-auto px-3 md:px-4 lg:px-6 py-4"
|
|
1093
|
+
: ""
|
|
1094
|
+
)}
|
|
1095
|
+
>
|
|
1096
|
+
<div
|
|
1097
|
+
className={cls(
|
|
1098
|
+
"grid transition-[grid-template-rows,transform,margin] duration-150 ease-out",
|
|
1099
|
+
selectedEntityIdProp === undefined
|
|
1100
|
+
? "grid-rows-[1fr] translate-y-0 mt-12 mb-6"
|
|
1101
|
+
: "grid-rows-[0fr] -translate-y-2 mt-0 mb-0"
|
|
1102
|
+
)}
|
|
1103
|
+
>
|
|
1104
|
+
<div className="overflow-hidden flex items-center gap-4">
|
|
1105
|
+
<Typography gutterBottom variant="h4" className="grow mb-0" component="h4">
|
|
1106
|
+
{collection.name}
|
|
1107
|
+
</Typography>
|
|
1108
|
+
</div>
|
|
1109
|
+
</div>
|
|
1110
|
+
{pluginInsights.length > 0 && (
|
|
1111
|
+
<div className="flex-shrink-0">
|
|
1112
|
+
{pluginInsights}
|
|
1113
|
+
</div>
|
|
1114
|
+
)}
|
|
1115
|
+
{innerView}
|
|
1116
|
+
</div>
|
|
1117
|
+
) : (
|
|
1118
|
+
innerView
|
|
1119
|
+
)}
|
|
1120
|
+
</div>
|
|
1121
|
+
</div>
|
|
1054
1122
|
)}
|
|
1055
1123
|
|
|
1056
1124
|
{popupCell && <PopupFormField
|
|
@@ -1082,7 +1150,7 @@ export const EntityCollectionView = React.memo(
|
|
|
1082
1150
|
);
|
|
1083
1151
|
}, (a, b) => {
|
|
1084
1152
|
return equal(a.path, b.path) &&
|
|
1085
|
-
equal(a.
|
|
1153
|
+
equal(a.parentCollectionSlugs, b.parentCollectionSlugs) && equal(a.parentEntityIds, b.parentEntityIds) &&
|
|
1086
1154
|
equal(a.isSubCollection, b.isSubCollection) &&
|
|
1087
1155
|
equal(a.className, b.className) &&
|
|
1088
1156
|
equal(a.properties, b.properties) &&
|
|
@@ -1099,11 +1167,18 @@ export const EntityCollectionView = React.memo(
|
|
|
1099
1167
|
equal(a.openEntityMode, b.openEntityMode) &&
|
|
1100
1168
|
equal(a.exportable, b.exportable) &&
|
|
1101
1169
|
equal(a.history, b.history) &&
|
|
1102
|
-
equal(a.
|
|
1170
|
+
equal(a.fixedFilter, b.fixedFilter) &&
|
|
1103
1171
|
equal(a.selectedEntityId, b.selectedEntityId) &&
|
|
1104
1172
|
equal(a.selectedTab, b.selectedTab);
|
|
1105
1173
|
}) as React.FunctionComponent<EntityCollectionViewProps<any>>
|
|
1106
1174
|
|
|
1175
|
+
/**
|
|
1176
|
+
* Inflight count request deduplication map.
|
|
1177
|
+
* Keyed by `path|filterKey|sortByProperty|sortDir` so that concurrent
|
|
1178
|
+
* callers (e.g. React StrictMode double-mount) share the same promise.
|
|
1179
|
+
*/
|
|
1180
|
+
const inflightCountRequests = new Map<string, Promise<number>>();
|
|
1181
|
+
|
|
1107
1182
|
function EntitiesCount({
|
|
1108
1183
|
path,
|
|
1109
1184
|
collection,
|
|
@@ -1119,52 +1194,71 @@ function EntitiesCount({
|
|
|
1119
1194
|
}) {
|
|
1120
1195
|
|
|
1121
1196
|
const dataClient = useData();
|
|
1122
|
-
const navigation = useCollectionRegistryController();
|
|
1123
1197
|
|
|
1124
1198
|
const sortByProperty = sortBy ? sortBy[0] : undefined;
|
|
1125
1199
|
const currentSort = sortBy ? sortBy[1] : undefined;
|
|
1126
|
-
|
|
1127
|
-
|
|
1200
|
+
|
|
1201
|
+
// Use refs for values that should NOT trigger re-fetches
|
|
1202
|
+
const dataClientRef = React.useRef(dataClient);
|
|
1203
|
+
dataClientRef.current = dataClient;
|
|
1204
|
+
const onCountChangeRef = React.useRef(onCountChange);
|
|
1205
|
+
onCountChangeRef.current = onCountChange;
|
|
1206
|
+
|
|
1207
|
+
// Serialize filter to a stable string to avoid re-fetches on object identity changes
|
|
1208
|
+
const filterKey = React.useMemo(() => filter ? JSON.stringify(filter) : "", [filter]);
|
|
1128
1209
|
|
|
1129
1210
|
useEffect(() => {
|
|
1130
|
-
const accessor =
|
|
1131
|
-
if (accessor.count) {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
const whereMap: Record<string, string> = {};
|
|
1136
|
-
if (filter) {
|
|
1137
|
-
Object.entries(filter).forEach(([key, value]) => {
|
|
1138
|
-
if (value && Array.isArray(value)) {
|
|
1139
|
-
const [op, val] = value;
|
|
1140
|
-
const postgrestOp = op === "==" ? "eq" : op === "!=" ? "neq" : op === ">" ? "gt" : op === ">=" ? "gte" : op === "<" ? "lt" : op === "<=" ? "lte" : op === "in" ? "in" : op === "not-in" ? "nin" : op === "array-contains" ? "cs" : op === "array-contains-any" ? "csa" : "eq";
|
|
1141
|
-
|
|
1142
|
-
let stringVal: string;
|
|
1143
|
-
if (Array.isArray(val)) {
|
|
1144
|
-
stringVal = `(${val.join(",")})`;
|
|
1145
|
-
} else {
|
|
1146
|
-
stringVal = String(val);
|
|
1147
|
-
}
|
|
1148
|
-
whereMap[key] = `${postgrestOp}.${stringVal}`;
|
|
1149
|
-
}
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
const whereParams = Object.keys(whereMap).length > 0 ? whereMap : undefined;
|
|
1153
|
-
const orderByParams = sortByProperty ? `${String(sortByProperty)}:${currentSort}` : undefined;
|
|
1211
|
+
const accessor = dataClientRef.current.collection(path);
|
|
1212
|
+
if (!accessor.count) {
|
|
1213
|
+
onCountChangeRef.current?.(undefined);
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1154
1216
|
|
|
1155
|
-
|
|
1217
|
+
let cancelled = false;
|
|
1218
|
+
|
|
1219
|
+
// Convert filterValues to PostgREST where clause
|
|
1220
|
+
const whereMap: Record<string, string> = {};
|
|
1221
|
+
if (filter) {
|
|
1222
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
1223
|
+
if (value && Array.isArray(value)) {
|
|
1224
|
+
const [op, val] = value;
|
|
1225
|
+
const postgrestOp = op === "==" ? "eq" : op === "!=" ? "neq" : op === ">" ? "gt" : op === ">=" ? "gte" : op === "<" ? "lt" : op === "<=" ? "lte" : op === "in" ? "in" : op === "not-in" ? "nin" : op === "array-contains" ? "cs" : op === "array-contains-any" ? "csa" : "eq";
|
|
1226
|
+
|
|
1227
|
+
let stringVal: string;
|
|
1228
|
+
if (Array.isArray(val)) {
|
|
1229
|
+
stringVal = `(${val.join(",")})`;
|
|
1230
|
+
} else {
|
|
1231
|
+
stringVal = String(val);
|
|
1232
|
+
}
|
|
1233
|
+
whereMap[key] = `${postgrestOp}.${stringVal}`;
|
|
1234
|
+
}
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
const whereParams = Object.keys(whereMap).length > 0 ? whereMap : undefined;
|
|
1238
|
+
const orderByParams = sortByProperty ? `${String(sortByProperty)}:${currentSort}` : undefined;
|
|
1239
|
+
|
|
1240
|
+
// Deduplicate inflight count requests (e.g. React StrictMode double-mount)
|
|
1241
|
+
const cacheKey = `${path}|${filterKey}|${sortByProperty ?? ""}|${currentSort ?? ""}`;
|
|
1242
|
+
let countPromise = inflightCountRequests.get(cacheKey);
|
|
1243
|
+
if (!countPromise) {
|
|
1244
|
+
countPromise = accessor.count({
|
|
1156
1245
|
where: whereParams,
|
|
1157
1246
|
orderBy: orderByParams
|
|
1158
|
-
}).then((c) => {
|
|
1159
|
-
if (onCountChange) onCountChange(c);
|
|
1160
|
-
}).catch((e) => {
|
|
1161
|
-
console.warn("Error fetching count", e);
|
|
1162
|
-
if (onCountChange) onCountChange(undefined);
|
|
1163
1247
|
});
|
|
1164
|
-
|
|
1165
|
-
|
|
1248
|
+
inflightCountRequests.set(cacheKey, countPromise);
|
|
1249
|
+
// Clean up the inflight entry once resolved/rejected
|
|
1250
|
+
countPromise.finally(() => inflightCountRequests.delete(cacheKey));
|
|
1166
1251
|
}
|
|
1167
|
-
|
|
1252
|
+
|
|
1253
|
+
countPromise.then((c) => {
|
|
1254
|
+
if (!cancelled) onCountChangeRef.current?.(c);
|
|
1255
|
+
}).catch((e) => {
|
|
1256
|
+
console.warn("Error fetching count", e);
|
|
1257
|
+
if (!cancelled) onCountChangeRef.current?.(undefined);
|
|
1258
|
+
});
|
|
1259
|
+
|
|
1260
|
+
return () => { cancelled = true; };
|
|
1261
|
+
}, [path, filterKey, sortByProperty, currentSort]);
|
|
1168
1262
|
|
|
1169
1263
|
// Count is now displayed in the breadcrumb bar, this component only fetches and reports
|
|
1170
1264
|
return null;
|
|
@@ -1175,7 +1269,7 @@ function buildPropertyWidthOverwrite(key: string, width: number): PartialEntityC
|
|
|
1175
1269
|
const [parentKey, ...childKey] = key.split(".");
|
|
1176
1270
|
return { properties: { [parentKey]: buildPropertyWidthOverwrite(childKey.join("."), width) } } as PartialEntityCollection;
|
|
1177
1271
|
}
|
|
1178
|
-
return { properties: { [key]: { columnWidth: width } } } as PartialEntityCollection;
|
|
1272
|
+
return { properties: { [key]: { ui: { columnWidth: width } } } } as PartialEntityCollection;
|
|
1179
1273
|
}
|
|
1180
1274
|
|
|
1181
1275
|
function EntityIdHeaderWidget({
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { EntityCollection } from "@rebasepro/types";
|
|
3
3
|
import React, { lazy, Suspense } from "react";
|
|
4
4
|
|
|
5
|
-
import { useLargeLayout, useTranslation, useSlot } from "@rebasepro/core";
|
|
5
|
+
import { useLargeLayout, useTranslation, useSlot, resolveComponentRef } from "@rebasepro/core";
|
|
6
6
|
import { CollectionActionsProps, EntityTableController, SelectionController } from "@rebasepro/types";
|
|
7
7
|
import { Button, IconButton, Tooltip, Popover, iconSize } from "@rebasepro/ui";
|
|
8
8
|
import { PlusIcon, Trash2Icon, MoreVerticalIcon } from "lucide-react";
|
|
@@ -20,7 +20,7 @@ export type EntityCollectionViewActionsProps<M extends Record<string, unknown>>
|
|
|
20
20
|
collection: EntityCollection<M>;
|
|
21
21
|
path: string;
|
|
22
22
|
relativePath: string;
|
|
23
|
-
|
|
23
|
+
parentCollectionSlugs: string[], parentEntityIds: string[];
|
|
24
24
|
selectionEnabled: boolean;
|
|
25
25
|
onNewClick: () => void;
|
|
26
26
|
onMultipleDeleteClick: () => void;
|
|
@@ -29,12 +29,13 @@ export type EntityCollectionViewActionsProps<M extends Record<string, unknown>>
|
|
|
29
29
|
collectionEntitiesCount?: number;
|
|
30
30
|
compact?: boolean;
|
|
31
31
|
children?: React.ReactNode;
|
|
32
|
+
openNewDocument: (defaultValues?: Record<string, unknown>) => void;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
35
36
|
collection,
|
|
36
37
|
relativePath,
|
|
37
|
-
|
|
38
|
+
parentCollectionSlugs, parentEntityIds,
|
|
38
39
|
onNewClick,
|
|
39
40
|
onMultipleDeleteClick,
|
|
40
41
|
selectionEnabled,
|
|
@@ -43,7 +44,8 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
43
44
|
tableController,
|
|
44
45
|
collectionEntitiesCount,
|
|
45
46
|
compact,
|
|
46
|
-
children
|
|
47
|
+
children,
|
|
48
|
+
openNewDocument
|
|
47
49
|
}: EntityCollectionViewActionsProps<M>) {
|
|
48
50
|
const context = useCMSContext();
|
|
49
51
|
|
|
@@ -64,6 +66,7 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
64
66
|
id={`add_entity_${path}`}
|
|
65
67
|
onClick={onNewClick}
|
|
66
68
|
startIcon={<PlusIcon size={iconSize.small}/>}
|
|
69
|
+
size="small"
|
|
67
70
|
variant="filled"
|
|
68
71
|
color="primary">
|
|
69
72
|
Add {collection.singularName ?? collection.name}
|
|
@@ -71,9 +74,9 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
71
74
|
: <Button
|
|
72
75
|
id={`add_entity_${path}`}
|
|
73
76
|
onClick={onNewClick}
|
|
74
|
-
variant=
|
|
77
|
+
variant="filled"
|
|
75
78
|
color={compact ? "neutral" : "primary"}
|
|
76
|
-
size=
|
|
79
|
+
size="small"
|
|
77
80
|
>
|
|
78
81
|
<PlusIcon size={iconSize.small}/>
|
|
79
82
|
</Button>);
|
|
@@ -110,20 +113,27 @@ export function EntityCollectionViewActions<M extends Record<string, unknown>>({
|
|
|
110
113
|
const actionProps: CollectionActionsProps<M> = {
|
|
111
114
|
path,
|
|
112
115
|
relativePath,
|
|
113
|
-
|
|
116
|
+
parentCollectionSlugs, parentEntityIds,
|
|
114
117
|
collection,
|
|
115
118
|
selectionController,
|
|
116
119
|
context,
|
|
117
120
|
tableController,
|
|
118
|
-
collectionEntitiesCount
|
|
121
|
+
collectionEntitiesCount,
|
|
122
|
+
openNewDocument
|
|
119
123
|
};
|
|
120
124
|
|
|
121
125
|
const actions = toArray(collection.Actions)
|
|
122
|
-
.map((
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
.map((actionRef, i) => {
|
|
127
|
+
const Action = resolveComponentRef(actionRef);
|
|
128
|
+
if (!Action) return null;
|
|
129
|
+
return (
|
|
130
|
+
<ErrorBoundary key={`actions_${i}`}>
|
|
131
|
+
<Suspense fallback={null}>
|
|
132
|
+
<Action {...actionProps}/>
|
|
133
|
+
</Suspense>
|
|
134
|
+
</ErrorBoundary>
|
|
135
|
+
);
|
|
136
|
+
});
|
|
127
137
|
|
|
128
138
|
const pluginActions = useSlot("collection.actions", actionProps as any);
|
|
129
139
|
|