@firecms/core 3.3.0 → 3.4.0-canary.1faa2a9
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 +4 -0
- package/dist/app/useApp.d.ts +1 -0
- package/dist/components/EntityCollectionTable/column_utils.d.ts +4 -3
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +6 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +3 -1
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +3 -1
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +3 -1
- package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +3 -1
- package/dist/components/EntityPreview.d.ts +3 -1
- package/dist/components/ErrorBoundary.d.ts +1 -3
- package/dist/components/LicenseBanner.d.ts +23 -0
- package/dist/components/ReferenceTable/ReferenceSelectionTable.d.ts +10 -1
- package/dist/components/SelectableTable/filters/filter_text_input.d.ts +30 -0
- package/dist/components/SelectableTable/filters/filter_text_input.test.d.ts +1 -0
- package/dist/components/common/table_url_params.d.ts +24 -0
- package/dist/components/common/useDataSourceTableController.d.ts +9 -1
- package/dist/components/common/useTableSearchHelper.d.ts +9 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/contexts/LicenseStatusContext.d.ts +16 -0
- package/dist/core/DefaultDrawer.d.ts +10 -3
- package/dist/core/EntityEditView.d.ts +9 -1
- package/dist/core/EntityEditViewFormActions.d.ts +1 -1
- package/dist/core/field_configs.d.ts +1 -1
- package/dist/core/index.d.ts +1 -0
- package/dist/core/plugin_translations.d.ts +38 -0
- package/dist/core/pro_plugins.d.ts +40 -0
- package/dist/de-KtBROUvS.js +700 -0
- package/dist/de-KtBROUvS.js.map +1 -0
- package/dist/editor/extensions/Image.d.ts +11 -0
- package/dist/editor/index.d.ts +2 -1
- package/dist/editor/lazy_editor.d.ts +6 -0
- package/dist/editor-BSo_aS1I.js +4563 -0
- package/dist/editor-BSo_aS1I.js.map +1 -0
- package/dist/form/EntityForm.d.ts +8 -1
- package/dist/form/EntityFormActions.d.ts +2 -0
- package/dist/form/field_bindings/GeopointFieldBinding.d.ts +5 -0
- package/dist/form/index.d.ts +1 -0
- package/dist/fr-BRFSBaVh.js +700 -0
- package/dist/fr-BRFSBaVh.js.map +1 -0
- package/dist/hi-DwCkga5X.js +700 -0
- package/dist/hi-DwCkga5X.js.map +1 -0
- package/dist/hooks/data/delete.d.ts +1 -1
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/hooks/data/useCollectionFetch.d.ts +7 -1
- package/dist/hooks/data/useEntityFetch.d.ts +9 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useLicenseStatus.d.ts +16 -0
- package/dist/hooks/useProjectLog.d.ts +11 -6
- package/dist/hooks/useTranslation.d.ts +1 -1
- package/dist/i18n/__tests__/FireCMSi18nProvider.test.d.ts +1 -0
- package/dist/i18n/__tests__/nested_provider_lifecycle.test.d.ts +1 -0
- package/dist/index.es.js +4509 -10665
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +9378 -6771
- package/dist/index.umd.js.map +1 -1
- package/dist/it-B2YGgDsx.js +700 -0
- package/dist/it-B2YGgDsx.js.map +1 -0
- package/dist/locales/pl.d.ts +2 -0
- package/dist/pl-BxHkywK8.js +702 -0
- package/dist/pl-BxHkywK8.js.map +1 -0
- package/dist/preview/index.d.ts +1 -0
- package/dist/preview/property_previews/GeopointPropertyPreview.d.ts +4 -0
- package/dist/pt-q6UV4diT.js +702 -0
- package/dist/pt-q6UV4diT.js.map +1 -0
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/collections.d.ts +31 -0
- package/dist/types/datasource.d.ts +67 -4
- package/dist/types/entities.d.ts +21 -1
- package/dist/types/entity_actions.d.ts +6 -0
- package/dist/types/entity_callbacks.d.ts +21 -0
- package/dist/types/firecms.d.ts +18 -1
- package/dist/types/firecms_context.d.ts +8 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/license.d.ts +54 -0
- package/dist/types/navigation.d.ts +34 -5
- package/dist/types/plugins.d.ts +22 -1
- package/dist/types/properties.d.ts +17 -1
- package/dist/types/side_entity_controller.d.ts +7 -0
- package/dist/types/translations.d.ts +37 -2
- package/dist/util/__tests__/collections.test.d.ts +1 -0
- package/dist/util/__tests__/urls.test.d.ts +1 -0
- package/dist/util/collections.d.ts +1 -1
- package/dist/util/date_fns_locales.d.ts +18 -0
- package/dist/util/entities.d.ts +1 -0
- package/dist/util/entity_cache.d.ts +11 -0
- package/dist/util/geopoint.d.ts +22 -0
- package/dist/util/index.d.ts +3 -0
- package/dist/util/lazy_eager.d.ts +3 -3
- package/dist/util/navigation_blocking.d.ts +22 -0
- package/dist/util/navigation_from_path.d.ts +17 -0
- package/dist/util/navigation_utils.d.ts +107 -3
- package/dist/util/parent_references_from_path.d.ts +16 -0
- package/dist/util/paths.d.ts +28 -0
- package/dist/util/permissions.d.ts +10 -4
- package/dist/util/urls.d.ts +22 -0
- package/package.json +17 -10
- package/src/app/Scaffold.tsx +41 -44
- package/src/app/useApp.tsx +1 -0
- package/src/components/DeleteEntityDialog.tsx +2 -0
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +3 -1
- package/src/components/EntityCollectionTable/column_utils.tsx +11 -19
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +7 -0
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -1
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +12 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +66 -15
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -2
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +8 -1
- package/src/components/EntityCollectionView/FiltersDialog.tsx +39 -28
- package/src/components/EntityCollectionView/useBoardDataController.tsx +17 -1
- package/src/components/EntityPreview.tsx +45 -41
- package/src/components/ErrorBoundary.tsx +12 -18
- package/src/components/LicenseBanner.tsx +209 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +19 -2
- package/src/components/ReferenceWidget.tsx +1 -1
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +33 -7
- package/src/components/SelectableTable/filters/filter_text_input.test.ts +184 -0
- package/src/components/SelectableTable/filters/filter_text_input.ts +71 -0
- package/src/components/VirtualTable/VirtualTable.tsx +19 -8
- package/src/components/common/default_entity_actions.tsx +22 -2
- package/src/components/common/table_url_params.ts +172 -0
- package/src/components/common/useDataSourceTableController.tsx +126 -163
- package/src/components/common/useTableSearchHelper.ts +26 -2
- package/src/components/index.tsx +1 -0
- package/src/contexts/LicenseStatusContext.tsx +50 -0
- package/src/contexts/SnackbarProvider.tsx +14 -1
- package/src/core/DefaultAppBar.tsx +28 -16
- package/src/core/DefaultDrawer.tsx +150 -64
- package/src/core/DrawerNavigationGroup.tsx +27 -29
- package/src/core/DrawerNavigationItem.tsx +10 -12
- package/src/core/EntityEditView.tsx +77 -35
- package/src/core/EntityEditViewFormActions.tsx +3 -2
- package/src/core/EntitySidePanel.tsx +8 -4
- package/src/core/FireCMS.tsx +73 -47
- package/src/core/SideDialogs.tsx +44 -1
- package/src/core/field_configs.tsx +15 -0
- package/src/core/index.tsx +1 -0
- package/src/core/plugin_translations.ts +87 -0
- package/src/core/pro_plugins.ts +79 -0
- package/src/editor/components/SlashCommandMenu.tsx +4 -1
- package/src/editor/extensions/Image.ts +17 -1
- package/src/editor/hooks/useProseMirror.ts +5 -0
- package/src/editor/index.ts +11 -1
- package/src/editor/lazy_editor.tsx +33 -0
- package/src/form/EntityForm.tsx +31 -10
- package/src/form/EntityFormActions.tsx +2 -0
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
- package/src/form/field_bindings/GeopointFieldBinding.tsx +139 -0
- package/src/form/index.tsx +1 -0
- package/src/hooks/data/delete.ts +8 -0
- package/src/hooks/data/save.ts +6 -1
- package/src/hooks/data/useCollectionFetch.tsx +21 -1
- package/src/hooks/data/useEntityFetch.tsx +35 -4
- package/src/hooks/index.tsx +2 -0
- package/src/hooks/useBuildNavigationController.tsx +70 -15
- package/src/hooks/useFireCMSContext.tsx +7 -3
- package/src/hooks/useLicenseStatus.tsx +32 -0
- package/src/hooks/useProjectLog.tsx +27 -9
- package/src/hooks/useResolvedNavigationFrom.tsx +3 -1
- package/src/hooks/useTranslation.ts +3 -1
- package/src/hooks/useValidateAuthenticator.tsx +4 -0
- package/src/i18n/FireCMSi18nProvider.tsx +199 -23
- package/src/i18n/__tests__/FireCMSi18nProvider.test.tsx +91 -0
- package/src/i18n/__tests__/nested_provider_lifecycle.test.tsx +67 -0
- package/src/internal/useBuildDataSource.ts +37 -15
- package/src/internal/useBuildSideEntityController.tsx +20 -5
- package/src/locales/de.ts +23 -4
- package/src/locales/en.ts +25 -4
- package/src/locales/es.ts +23 -4
- package/src/locales/fr.ts +23 -4
- package/src/locales/hi.ts +23 -4
- package/src/locales/it.ts +23 -4
- package/src/locales/pl.ts +749 -0
- package/src/locales/pt.ts +23 -4
- package/src/preview/PropertyPreview.tsx +12 -0
- package/src/preview/components/DatePreview.tsx +2 -4
- package/src/preview/components/ReferencePreview.tsx +7 -3
- package/src/preview/components/StorageThumbnail.tsx +24 -2
- package/src/preview/index.ts +1 -0
- package/src/preview/property_previews/GeopointPropertyPreview.tsx +23 -0
- package/src/routes/FireCMSRoute.tsx +54 -27
- package/src/types/analytics.ts +3 -0
- package/src/types/collections.ts +34 -0
- package/src/types/datasource.ts +67 -4
- package/src/types/entities.ts +24 -1
- package/src/types/entity_actions.tsx +6 -0
- package/src/types/entity_callbacks.ts +24 -0
- package/src/types/firecms.tsx +19 -1
- package/src/types/firecms_context.tsx +9 -0
- package/src/types/index.ts +1 -0
- package/src/types/license.ts +62 -0
- package/src/types/navigation.ts +35 -5
- package/src/types/plugins.tsx +23 -1
- package/src/types/properties.ts +17 -0
- package/src/types/side_entity_controller.tsx +7 -0
- package/src/types/translations.ts +37 -2
- package/src/util/__tests__/collections.test.ts +32 -0
- package/src/util/__tests__/urls.test.ts +131 -0
- package/src/util/collections.ts +1 -1
- package/src/util/date_fns_locales.ts +168 -0
- package/src/util/entities.ts +16 -1
- package/src/util/entity_cache.ts +18 -0
- package/src/util/geopoint.ts +81 -0
- package/src/util/index.ts +3 -0
- package/src/util/lazy_eager.tsx +30 -8
- package/src/util/navigation_blocking.ts +45 -0
- package/src/util/navigation_from_path.ts +47 -7
- package/src/util/navigation_utils.ts +244 -4
- package/src/util/parent_references_from_path.ts +45 -4
- package/src/util/paths.ts +40 -3
- package/src/util/permissions.ts +22 -10
- package/src/util/previews.ts +8 -1
- package/src/util/resolutions.ts +8 -0
- package/src/util/urls.ts +52 -0
- package/src/util/useStorageUploadController.tsx +6 -1
|
@@ -90,6 +90,7 @@ import { useSelectionController } from "./useSelectionController";
|
|
|
90
90
|
import { EntityCollectionViewStartActions } from "./EntityCollectionViewStartActions";
|
|
91
91
|
import { addRecentId, getRecentIds } from "./utils";
|
|
92
92
|
import { useScrollRestoration } from "../common/useScrollRestoration";
|
|
93
|
+
import { entityCacheKey } from "../../util/entity_cache";
|
|
93
94
|
|
|
94
95
|
const DEFAULT_ENTITY_OPEN_MODE: "side_panel" | "full_screen" = "side_panel";
|
|
95
96
|
|
|
@@ -106,6 +107,14 @@ export type EntityCollectionViewProps<M extends Record<string, any>> = {
|
|
|
106
107
|
* Full path using navigation ids.
|
|
107
108
|
*/
|
|
108
109
|
fullIdPath?: string;
|
|
110
|
+
/**
|
|
111
|
+
* `fullPath` split at its real segment boundaries, e.g. `["nodes", "node/42", "edges"]`.
|
|
112
|
+
* Forwarded to the datasource so a parent entity id containing "/" stays unambiguous.
|
|
113
|
+
*
|
|
114
|
+
* Optional, and never derived by splitting `fullPath` — a guess would be wrong in
|
|
115
|
+
* exactly the case the field exists for. Absent means "not known here", not "no slashes".
|
|
116
|
+
*/
|
|
117
|
+
pathSegments?: string[];
|
|
109
118
|
/**
|
|
110
119
|
* If this is a subcollection, specify the parent collection ids.
|
|
111
120
|
*/
|
|
@@ -152,6 +161,7 @@ export const EntityCollectionView = React.memo(
|
|
|
152
161
|
function EntityCollectionView<M extends Record<string, any>>({
|
|
153
162
|
fullPath: fullPathProp,
|
|
154
163
|
fullIdPath,
|
|
164
|
+
pathSegments,
|
|
155
165
|
parentCollectionIds,
|
|
156
166
|
isSubCollection,
|
|
157
167
|
className,
|
|
@@ -190,7 +200,7 @@ export const EntityCollectionView = React.memo(
|
|
|
190
200
|
collectionRef.current = collection;
|
|
191
201
|
}, [collection]);
|
|
192
202
|
|
|
193
|
-
const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
|
|
203
|
+
const canCreateEntities = canCreateEntity(collection, authController, fullPath, null, pathSegments);
|
|
194
204
|
const [highlightedEntity, setHighlightedEntity] = useState<Entity<M> | undefined>(undefined);
|
|
195
205
|
const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
|
|
196
206
|
|
|
@@ -220,7 +230,7 @@ export const EntityCollectionView = React.memo(
|
|
|
220
230
|
|
|
221
231
|
const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
|
|
222
232
|
const collection = collectionRef.current;
|
|
223
|
-
if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
|
|
233
|
+
if (!canEditEntity(collection, authController, fullPath, entity ?? null, pathSegments)) {
|
|
224
234
|
return false;
|
|
225
235
|
}
|
|
226
236
|
return collection.inlineEditing === undefined || collection.inlineEditing;
|
|
@@ -317,6 +327,7 @@ export const EntityCollectionView = React.memo(
|
|
|
317
327
|
|
|
318
328
|
const tableController = useDataSourceTableController<M>({
|
|
319
329
|
fullPath,
|
|
330
|
+
pathSegments,
|
|
320
331
|
collection,
|
|
321
332
|
lastDeleteTimestamp,
|
|
322
333
|
scrollRestoration,
|
|
@@ -342,10 +353,16 @@ export const EntityCollectionView = React.memo(
|
|
|
342
353
|
addRecentId(collection.id, clickedEntity.id);
|
|
343
354
|
}
|
|
344
355
|
|
|
345
|
-
|
|
356
|
+
// In a collection group the row's own path is the real one, so the row's segments
|
|
357
|
+
// are the matching ones; otherwise both come from this view. `path` and
|
|
358
|
+
// `pathSegments` are picked from the same source so they cannot describe
|
|
359
|
+
// different chains.
|
|
360
|
+
const isCollectionGroup = Boolean(collection?.collectionGroup);
|
|
361
|
+
const path = isCollectionGroup ? clickedEntity.path : (fullPath ?? clickedEntity.path);
|
|
346
362
|
navigateToEntity({
|
|
347
363
|
navigation,
|
|
348
364
|
path,
|
|
365
|
+
pathSegments: isCollectionGroup ? clickedEntity.pathSegments : (pathSegments ?? clickedEntity.pathSegments),
|
|
349
366
|
fullIdPath,
|
|
350
367
|
sideEntityController,
|
|
351
368
|
openEntityMode,
|
|
@@ -365,6 +382,7 @@ export const EntityCollectionView = React.memo(
|
|
|
365
382
|
collection,
|
|
366
383
|
entityId: undefined,
|
|
367
384
|
path: fullPath,
|
|
385
|
+
pathSegments,
|
|
368
386
|
fullIdPath,
|
|
369
387
|
sideEntityController,
|
|
370
388
|
navigation,
|
|
@@ -440,6 +458,7 @@ export const EntityCollectionView = React.memo(
|
|
|
440
458
|
const onViewModeChange = useCallback((mode: ViewMode) => {
|
|
441
459
|
analyticsController.onAnalyticsEvent?.("view_mode_changed", {
|
|
442
460
|
path: fullPath,
|
|
461
|
+
pathSegments,
|
|
443
462
|
from: viewMode,
|
|
444
463
|
to: mode
|
|
445
464
|
});
|
|
@@ -450,7 +469,7 @@ export const EntityCollectionView = React.memo(
|
|
|
450
469
|
}
|
|
451
470
|
}, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
|
|
452
471
|
|
|
453
|
-
const createEnabled = canCreateEntity(collection, authController, fullPath, null);
|
|
472
|
+
const createEnabled = canCreateEntity(collection, authController, fullPath, null, pathSegments);
|
|
454
473
|
|
|
455
474
|
const uniqueFieldValidator: UniqueFieldValidator = useCallback(
|
|
456
475
|
({
|
|
@@ -458,8 +477,8 @@ export const EntityCollectionView = React.memo(
|
|
|
458
477
|
value,
|
|
459
478
|
property,
|
|
460
479
|
entityId
|
|
461
|
-
}) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection),
|
|
462
|
-
[fullPath]);
|
|
480
|
+
}) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection, pathSegments),
|
|
481
|
+
[fullPath, pathSegments]);
|
|
463
482
|
|
|
464
483
|
const onValueChange: OnCellValueChange<any, any> = ({
|
|
465
484
|
value,
|
|
@@ -473,6 +492,8 @@ export const EntityCollectionView = React.memo(
|
|
|
473
492
|
|
|
474
493
|
const saveProps: SaveEntityProps = {
|
|
475
494
|
path: entity.path ?? fullPath,
|
|
495
|
+
// Paired with the `path` above: the row's segments describe the row's path.
|
|
496
|
+
pathSegments: entity.path ? entity.pathSegments : pathSegments,
|
|
476
497
|
entityId: entity.id,
|
|
477
498
|
values: updatedValues,
|
|
478
499
|
previousValues: entity.values,
|
|
@@ -503,7 +524,7 @@ export const EntityCollectionView = React.memo(
|
|
|
503
524
|
|
|
504
525
|
};
|
|
505
526
|
|
|
506
|
-
const resolvedFullPath = navigation.resolveIdsFrom(fullPath);
|
|
527
|
+
const resolvedFullPath = navigation.resolveIdsFrom(fullPath, pathSegments);
|
|
507
528
|
const resolvedCollection = useMemo(() => resolveCollection<M>({
|
|
508
529
|
collection,
|
|
509
530
|
path: fullPath,
|
|
@@ -581,6 +602,7 @@ export const EntityCollectionView = React.memo(
|
|
|
581
602
|
const onKanbanPropertyChange = useCallback((property: string) => {
|
|
582
603
|
analyticsController.onAnalyticsEvent?.("kanban_property_changed", {
|
|
583
604
|
path: fullPath,
|
|
605
|
+
pathSegments,
|
|
584
606
|
property
|
|
585
607
|
});
|
|
586
608
|
setSelectedKanbanProperty(property);
|
|
@@ -645,6 +667,7 @@ export const EntityCollectionView = React.memo(
|
|
|
645
667
|
entityId: entity.id,
|
|
646
668
|
selectedTab: subcollection.id ?? subcollection.path,
|
|
647
669
|
path: fullPath,
|
|
670
|
+
pathSegments,
|
|
648
671
|
fullIdPath,
|
|
649
672
|
navigation,
|
|
650
673
|
sideEntityController
|
|
@@ -663,13 +686,15 @@ export const EntityCollectionView = React.memo(
|
|
|
663
686
|
width: 260,
|
|
664
687
|
dependencies: [],
|
|
665
688
|
Builder: ({ entity }) => {
|
|
666
|
-
|
|
689
|
+
// `entity.path` is a RAW datasource path, so its segments are passed:
|
|
690
|
+
// splitting it would mis-read any parent id containing "/".
|
|
691
|
+
const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path, entity.pathSegments);
|
|
667
692
|
return (
|
|
668
693
|
<div className={"flex flex-col gap-2 w-full"}>
|
|
669
694
|
{collectionsWithPath.map((reference) => {
|
|
670
695
|
return (
|
|
671
696
|
<ReferencePreview
|
|
672
|
-
key={reference.path
|
|
697
|
+
key={entityCacheKey(reference.path, reference.id)}
|
|
673
698
|
reference={reference}
|
|
674
699
|
size={"small"} />
|
|
675
700
|
);
|
|
@@ -700,7 +725,7 @@ export const EntityCollectionView = React.memo(
|
|
|
700
725
|
entity?: Entity<M>,
|
|
701
726
|
customEntityActions?: EntityAction[]
|
|
702
727
|
}): EntityAction[] => {
|
|
703
|
-
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
|
|
728
|
+
const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity, entity.pathSegments ?? pathSegments) : true;
|
|
704
729
|
const actions: EntityAction[] = [
|
|
705
730
|
{ ...editEntityAction, name: t("edit") }
|
|
706
731
|
];
|
|
@@ -776,6 +801,7 @@ export const EntityCollectionView = React.memo(
|
|
|
776
801
|
// EntitiesCount fetches count and updates breadcrumb - no visual rendering needed here
|
|
777
802
|
const countFetcher = <EntitiesCount
|
|
778
803
|
fullPath={fullPath}
|
|
804
|
+
pathSegments={pathSegments}
|
|
779
805
|
collection={collection}
|
|
780
806
|
filter={tableController.filterValues}
|
|
781
807
|
sortBy={tableController.sortBy}
|
|
@@ -829,9 +855,14 @@ export const EntityCollectionView = React.memo(
|
|
|
829
855
|
onTextSearchClick,
|
|
830
856
|
textSearchEnabled
|
|
831
857
|
} = useTableSearchHelper({
|
|
858
|
+
pathSegments,
|
|
832
859
|
collection,
|
|
833
860
|
fullPath: resolvedFullPath,
|
|
834
|
-
parentCollectionIds
|
|
861
|
+
parentCollectionIds,
|
|
862
|
+
// When the search term comes from the URL instead of the search bar, text search
|
|
863
|
+
// has never been initialised for this collection. Initialise it so the search bar
|
|
864
|
+
// is usable (editable and clearable) right away.
|
|
865
|
+
initialSearchString: tableController.searchString
|
|
835
866
|
});
|
|
836
867
|
|
|
837
868
|
// Popover open state managed at parent level to prevent closing when view changes
|
|
@@ -881,6 +912,7 @@ export const EntityCollectionView = React.memo(
|
|
|
881
912
|
loading={tableController.dataLoading}
|
|
882
913
|
onTextSearch={textSearchEnabled && textSearchInitialised ? tableController.setSearchString : undefined}
|
|
883
914
|
onTextSearchClick={textSearchEnabled && !textSearchInitialised ? onTextSearchClick : undefined}
|
|
915
|
+
initialSearchString={tableController.searchString}
|
|
884
916
|
textSearchLoading={textSearchLoading}
|
|
885
917
|
viewModeToggle={viewModeToggleElement}
|
|
886
918
|
actionsStart={<EntityCollectionViewStartActions
|
|
@@ -888,6 +920,7 @@ export const EntityCollectionView = React.memo(
|
|
|
888
920
|
collection={collection}
|
|
889
921
|
tableController={tableController}
|
|
890
922
|
path={fullPath}
|
|
923
|
+
pathSegments={pathSegments}
|
|
891
924
|
relativePath={collection.path}
|
|
892
925
|
selectionController={usedSelectionController}
|
|
893
926
|
collectionEntitiesCount={docsCount}
|
|
@@ -899,6 +932,7 @@ export const EntityCollectionView = React.memo(
|
|
|
899
932
|
onMultipleDeleteClick={onMultipleDeleteClick}
|
|
900
933
|
onNewClick={onNewClick}
|
|
901
934
|
path={fullPath}
|
|
935
|
+
pathSegments={pathSegments}
|
|
902
936
|
relativePath={collection.path}
|
|
903
937
|
selectionController={usedSelectionController}
|
|
904
938
|
selectionEnabled={selectionEnabled}
|
|
@@ -915,6 +949,7 @@ export const EntityCollectionView = React.memo(
|
|
|
915
949
|
collection={collection}
|
|
916
950
|
tableController={tableController}
|
|
917
951
|
fullPath={fullPath}
|
|
952
|
+
pathSegments={pathSegments}
|
|
918
953
|
parentCollectionIds={parentCollectionIds}
|
|
919
954
|
columnProperty={selectedKanbanProperty}
|
|
920
955
|
onEntityClick={onEntityClick}
|
|
@@ -1006,6 +1041,7 @@ export const EntityCollectionView = React.memo(
|
|
|
1006
1041
|
getIdColumnWidth={getIdColumnWidth}
|
|
1007
1042
|
additionalIDHeaderWidget={<EntityIdHeaderWidget
|
|
1008
1043
|
path={fullPath}
|
|
1044
|
+
pathSegments={pathSegments}
|
|
1009
1045
|
fullIdPath={fullIdPath ?? fullPath}
|
|
1010
1046
|
collection={collection} />}
|
|
1011
1047
|
openEntityMode={openEntityMode}
|
|
@@ -1045,6 +1081,7 @@ export const EntityCollectionView = React.memo(
|
|
|
1045
1081
|
|
|
1046
1082
|
{popupCell && <PopupFormField
|
|
1047
1083
|
key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`}
|
|
1084
|
+
pathSegments={pathSegments}
|
|
1048
1085
|
open={Boolean(popupCell)}
|
|
1049
1086
|
onClose={onPopupClose}
|
|
1050
1087
|
cellRect={popupCell?.cellRect}
|
|
@@ -1100,13 +1137,16 @@ function EntitiesCount({
|
|
|
1100
1137
|
collection,
|
|
1101
1138
|
filter,
|
|
1102
1139
|
sortBy,
|
|
1103
|
-
onCountChange
|
|
1140
|
+
onCountChange,
|
|
1141
|
+
pathSegments
|
|
1104
1142
|
}: {
|
|
1105
1143
|
fullPath: string,
|
|
1106
1144
|
collection: EntityCollection,
|
|
1107
1145
|
filter?: FilterValues<any>,
|
|
1108
1146
|
sortBy?: [string, "asc" | "desc"],
|
|
1109
1147
|
onCountChange?: (count: number) => void,
|
|
1148
|
+
/** `fullPath` split at its real segment boundaries; forwarded to countEntities. */
|
|
1149
|
+
pathSegments?: string[],
|
|
1110
1150
|
}) {
|
|
1111
1151
|
|
|
1112
1152
|
const dataSource = useDataSource(collection);
|
|
@@ -1116,18 +1156,24 @@ function EntitiesCount({
|
|
|
1116
1156
|
|
|
1117
1157
|
const sortByProperty = sortBy ? sortBy[0] : undefined;
|
|
1118
1158
|
const currentSort = sortBy ? sortBy[1] : undefined;
|
|
1119
|
-
|
|
1159
|
+
// Resolved together so the two representations always describe the same chain.
|
|
1160
|
+
// Segments are resolved, never derived (see useEntityFetch).
|
|
1161
|
+
const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
|
|
1162
|
+
const resolvedPathSegments = useMemo(() => pathSegments
|
|
1163
|
+
? (navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments)
|
|
1164
|
+
: undefined, [pathSegments, navigation.resolveSegmentsFrom]);
|
|
1120
1165
|
|
|
1121
1166
|
useEffect(() => {
|
|
1122
1167
|
if (dataSource.countEntities)
|
|
1123
1168
|
dataSource.countEntities({
|
|
1124
1169
|
path: resolvedPath,
|
|
1170
|
+
pathSegments: resolvedPathSegments,
|
|
1125
1171
|
collection,
|
|
1126
1172
|
filter,
|
|
1127
1173
|
orderBy: sortByProperty,
|
|
1128
1174
|
order: currentSort
|
|
1129
1175
|
}).then(setCount).catch(setError);
|
|
1130
|
-
}, [fullPath, dataSource.countEntities, resolvedPath, collection, filter, sortByProperty, currentSort]);
|
|
1176
|
+
}, [fullPath, dataSource.countEntities, resolvedPath, resolvedPathSegments, collection, filter, sortByProperty, currentSort]);
|
|
1131
1177
|
|
|
1132
1178
|
useEffect(() => {
|
|
1133
1179
|
if (onCountChange && count !== undefined) {
|
|
@@ -1156,10 +1202,13 @@ function buildPropertyWidthOverwrite(key: string, width: number): PartialEntityC
|
|
|
1156
1202
|
function EntityIdHeaderWidget({
|
|
1157
1203
|
collection,
|
|
1158
1204
|
path,
|
|
1205
|
+
pathSegments,
|
|
1159
1206
|
fullIdPath
|
|
1160
1207
|
}: {
|
|
1161
1208
|
collection: EntityCollection,
|
|
1162
1209
|
path: string,
|
|
1210
|
+
/** `path` split at its real segment boundaries, when the caller knows them. */
|
|
1211
|
+
pathSegments?: string[],
|
|
1163
1212
|
fullIdPath: string
|
|
1164
1213
|
}) {
|
|
1165
1214
|
|
|
@@ -1199,6 +1248,7 @@ function EntityIdHeaderWidget({
|
|
|
1199
1248
|
collection,
|
|
1200
1249
|
entityId,
|
|
1201
1250
|
path,
|
|
1251
|
+
pathSegments,
|
|
1202
1252
|
fullIdPath,
|
|
1203
1253
|
sideEntityController,
|
|
1204
1254
|
navigation
|
|
@@ -1224,7 +1274,7 @@ function EntityIdHeaderWidget({
|
|
|
1224
1274
|
</form>
|
|
1225
1275
|
{recentIds && recentIds.length > 0 && <div className="flex flex-col gap-2 p-2">
|
|
1226
1276
|
{recentIds.map(id => (
|
|
1227
|
-
<ReferencePreview reference={new EntityReference(id, path)}
|
|
1277
|
+
<ReferencePreview reference={new EntityReference(id, path, undefined, pathSegments)}
|
|
1228
1278
|
key={id}
|
|
1229
1279
|
hover={true}
|
|
1230
1280
|
onClick={() => {
|
|
@@ -1234,6 +1284,7 @@ function EntityIdHeaderWidget({
|
|
|
1234
1284
|
collection,
|
|
1235
1285
|
entityId: id,
|
|
1236
1286
|
path,
|
|
1287
|
+
pathSegments,
|
|
1237
1288
|
fullIdPath,
|
|
1238
1289
|
sideEntityController,
|
|
1239
1290
|
navigation
|
|
@@ -22,6 +22,8 @@ import { useTranslation } from "../../hooks/useTranslation";
|
|
|
22
22
|
export type EntityCollectionViewActionsProps<M extends Record<string, any>> = {
|
|
23
23
|
collection: EntityCollection<M>;
|
|
24
24
|
path: string;
|
|
25
|
+
/** `path` split at its real segment boundaries, when known. Never derived from `path`. */
|
|
26
|
+
pathSegments?: string[];
|
|
25
27
|
relativePath: string;
|
|
26
28
|
parentCollectionIds: string[];
|
|
27
29
|
selectionEnabled: boolean;
|
|
@@ -40,6 +42,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
40
42
|
onMultipleDeleteClick,
|
|
41
43
|
selectionEnabled,
|
|
42
44
|
path,
|
|
45
|
+
pathSegments,
|
|
43
46
|
selectionController,
|
|
44
47
|
tableController,
|
|
45
48
|
collectionEntitiesCount,
|
|
@@ -56,7 +59,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
56
59
|
|
|
57
60
|
const selectedEntities = selectionController.selectedEntities;
|
|
58
61
|
|
|
59
|
-
const addButton = canCreateEntity(collection, authController, path, null) &&
|
|
62
|
+
const addButton = canCreateEntity(collection, authController, path, null, pathSegments) &&
|
|
60
63
|
onNewClick && (largeLayout
|
|
61
64
|
? <Button
|
|
62
65
|
id={`add_entity_${path}`}
|
|
@@ -75,7 +78,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
75
78
|
<AddIcon size={"small"} />
|
|
76
79
|
</Button>);
|
|
77
80
|
|
|
78
|
-
const multipleDeleteEnabled = canDeleteEntity(collection, authController, path, null);
|
|
81
|
+
const multipleDeleteEnabled = canDeleteEntity(collection, authController, path, null, pathSegments);
|
|
79
82
|
|
|
80
83
|
let multipleDeleteButton: React.ReactNode | undefined;
|
|
81
84
|
if (selectionEnabled) {
|
|
@@ -107,6 +110,7 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
107
110
|
|
|
108
111
|
const actionProps: CollectionActionsProps = {
|
|
109
112
|
path,
|
|
113
|
+
pathSegments,
|
|
110
114
|
relativePath,
|
|
111
115
|
parentCollectionIds,
|
|
112
116
|
collection,
|
|
@@ -17,6 +17,8 @@ import { useTranslation } from "../../hooks/useTranslation";
|
|
|
17
17
|
export type EntityCollectionViewStartActionsProps<M extends Record<string, any>> = {
|
|
18
18
|
collection: EntityCollection<M>;
|
|
19
19
|
path: string;
|
|
20
|
+
/** `path` split at its real segment boundaries, when known. Never derived from `path`. */
|
|
21
|
+
pathSegments?: string[];
|
|
20
22
|
relativePath: string;
|
|
21
23
|
parentCollectionIds: string[];
|
|
22
24
|
selectionController: SelectionController<M>;
|
|
@@ -33,6 +35,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
33
35
|
relativePath,
|
|
34
36
|
parentCollectionIds,
|
|
35
37
|
path,
|
|
38
|
+
pathSegments,
|
|
36
39
|
selectionController,
|
|
37
40
|
tableController,
|
|
38
41
|
collectionEntitiesCount,
|
|
@@ -57,6 +60,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
57
60
|
|
|
58
61
|
const actionProps: CollectionActionsProps = {
|
|
59
62
|
path,
|
|
63
|
+
pathSegments,
|
|
60
64
|
relativePath,
|
|
61
65
|
parentCollectionIds,
|
|
62
66
|
collection,
|
|
@@ -66,8 +70,10 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
66
70
|
collectionEntitiesCount
|
|
67
71
|
};
|
|
68
72
|
|
|
73
|
+
const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
|
|
74
|
+
|
|
69
75
|
// Filters button
|
|
70
|
-
const filtersButton = resolvedProperties && tableController.setFilterValues && (
|
|
76
|
+
const filtersButton = resolvedProperties && tableController.setFilterValues && hasAnyAllowedFilters && (
|
|
71
77
|
<Tooltip title={t("filters")}
|
|
72
78
|
key={"filters_tooltip"}>
|
|
73
79
|
<Badge
|
|
@@ -131,6 +137,7 @@ export function EntityCollectionViewStartActions<M extends Record<string, any>>(
|
|
|
131
137
|
filterValues={tableController.filterValues}
|
|
132
138
|
setFilterValues={(filterValues) => tableController.setFilterValues?.(filterValues ?? {})}
|
|
133
139
|
forceFilter={collection.forceFilter}
|
|
140
|
+
allowedFilters={tableController.allowedFilters?.map(key => key.toString())}
|
|
134
141
|
/>
|
|
135
142
|
)}
|
|
136
143
|
</>
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
DialogActions,
|
|
13
13
|
DialogContent,
|
|
14
14
|
DialogTitle,
|
|
15
|
-
FilterListIcon,
|
|
16
15
|
Typography
|
|
17
16
|
} from "@firecms/ui";
|
|
18
17
|
import { useTranslation } from "../../hooks/useTranslation";
|
|
@@ -30,6 +29,7 @@ export interface FiltersDialogProps {
|
|
|
30
29
|
filterValues: FilterValues<any> | undefined;
|
|
31
30
|
setFilterValues: (filterValues?: FilterValues<any>) => void;
|
|
32
31
|
forceFilter?: FilterValues<any>;
|
|
32
|
+
allowedFilters?: string[];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
@@ -42,7 +42,8 @@ export function FiltersDialog({
|
|
|
42
42
|
properties,
|
|
43
43
|
filterValues,
|
|
44
44
|
setFilterValues,
|
|
45
|
-
forceFilter
|
|
45
|
+
forceFilter,
|
|
46
|
+
allowedFilters
|
|
46
47
|
}: FiltersDialogProps) {
|
|
47
48
|
const { t } = useTranslation();
|
|
48
49
|
|
|
@@ -59,18 +60,18 @@ export function FiltersDialog({
|
|
|
59
60
|
}
|
|
60
61
|
}, [open, filterValues]);
|
|
61
62
|
|
|
62
|
-
// Get list of
|
|
63
|
-
const
|
|
64
|
-
return Object.entries(properties).filter(([key
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (!baseProperty) return false;
|
|
71
|
-
return ["string", "number", "boolean", "date", "reference"].includes(baseProperty.dataType);
|
|
63
|
+
// Get list of editable filter properties
|
|
64
|
+
const editableFilterProperties = useMemo(() => {
|
|
65
|
+
return Object.entries(properties).filter(([key]) => {
|
|
66
|
+
const isFilterAllowed = !allowedFilters || allowedFilters.includes(key);
|
|
67
|
+
|
|
68
|
+
const isFilterForced = Boolean(forceFilter && Object.keys(forceFilter).includes(key));
|
|
69
|
+
|
|
70
|
+
return isFilterAllowed && !isFilterForced;
|
|
72
71
|
});
|
|
73
|
-
}, [properties, forceFilter]);
|
|
72
|
+
}, [properties, allowedFilters, forceFilter]);
|
|
73
|
+
|
|
74
|
+
const hasEditableFilterProperties = editableFilterProperties.length > 0;
|
|
74
75
|
|
|
75
76
|
const handleFilterChange = useCallback((propertyKey: string, value?: [VirtualTableWhereFilterOp, any]) => {
|
|
76
77
|
setLocalFilters(prev => {
|
|
@@ -103,7 +104,13 @@ export function FiltersDialog({
|
|
|
103
104
|
|
|
104
105
|
// Check if any reference field's dialog is currently open (should hide this dialog)
|
|
105
106
|
const isAnyFieldHidden = Object.values(hiddenFields).some(hidden => hidden);
|
|
106
|
-
|
|
107
|
+
|
|
108
|
+
const getActiveFilterCount = () => {
|
|
109
|
+
const editableLocalFilters = Object.keys(localFilters).filter((key) => !forceFilter || !(key in forceFilter));
|
|
110
|
+
return editableLocalFilters.length;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const activeFilterCount = getActiveFilterCount();
|
|
107
114
|
|
|
108
115
|
const renderFilterField = useCallback((propertyKey: string, property: ResolvedProperty) => {
|
|
109
116
|
const isArray = property.dataType === "array";
|
|
@@ -185,14 +192,14 @@ export function FiltersDialog({
|
|
|
185
192
|
</DialogTitle>
|
|
186
193
|
|
|
187
194
|
<DialogContent >
|
|
188
|
-
{
|
|
195
|
+
{!hasEditableFilterProperties ? (
|
|
189
196
|
<Typography color="secondary" className="py-8 text-center">
|
|
190
197
|
{t("no_filterable_properties")}
|
|
191
198
|
</Typography>
|
|
192
199
|
) : (
|
|
193
200
|
<table className="w-full border-collapse">
|
|
194
201
|
<tbody>
|
|
195
|
-
{
|
|
202
|
+
{editableFilterProperties.map(([propertyKey, property], index) => {
|
|
196
203
|
const hasFilter = propertyKey in localFilters;
|
|
197
204
|
|
|
198
205
|
return (
|
|
@@ -234,18 +241,22 @@ export function FiltersDialog({
|
|
|
234
241
|
{t("clear")}
|
|
235
242
|
</Button>
|
|
236
243
|
<div className="flex-grow" />
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
244
|
+
{hasEditableFilterProperties && (
|
|
245
|
+
<>
|
|
246
|
+
<Button
|
|
247
|
+
variant="text"
|
|
248
|
+
onClick={() => onOpenChange(false)}
|
|
249
|
+
>
|
|
250
|
+
{t("cancel")}
|
|
251
|
+
</Button>
|
|
252
|
+
<Button
|
|
253
|
+
variant="filled"
|
|
254
|
+
onClick={handleApply}
|
|
255
|
+
>
|
|
256
|
+
{t("apply_filters")}
|
|
257
|
+
</Button>
|
|
258
|
+
</>
|
|
259
|
+
)}
|
|
249
260
|
</DialogActions>
|
|
250
261
|
</Dialog>
|
|
251
262
|
);
|
|
@@ -45,6 +45,8 @@ export interface BoardDataController<M extends Record<string, any> = any, COLUMN
|
|
|
45
45
|
export interface UseBoardDataControllerProps<M extends Record<string, any> = any> {
|
|
46
46
|
/** Full path to the collection */
|
|
47
47
|
fullPath: string;
|
|
48
|
+
/** `fullPath` split at its real segment boundaries; forwarded to the datasource. */
|
|
49
|
+
pathSegments?: string[];
|
|
48
50
|
/** The entity collection configuration */
|
|
49
51
|
collection: EntityCollection<M>;
|
|
50
52
|
/** Property key used for column assignment */
|
|
@@ -67,6 +69,7 @@ export interface UseBoardDataControllerProps<M extends Record<string, any> = any
|
|
|
67
69
|
*/
|
|
68
70
|
export function useBoardDataController<M extends Record<string, any> = any, COLUMN extends string = string>({
|
|
69
71
|
fullPath,
|
|
72
|
+
pathSegments,
|
|
70
73
|
collection,
|
|
71
74
|
columnProperty,
|
|
72
75
|
columns,
|
|
@@ -79,7 +82,12 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
79
82
|
const context = useFireCMSContext();
|
|
80
83
|
const dataSource = useDataSource(collection);
|
|
81
84
|
const navigation = useNavigationController();
|
|
82
|
-
|
|
85
|
+
// Resolved together so the two representations always describe the same chain.
|
|
86
|
+
// Segments are resolved, never derived (see useEntityFetch).
|
|
87
|
+
const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
|
|
88
|
+
const resolvedPathSegments = useMemo(() => pathSegments
|
|
89
|
+
? (navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments)
|
|
90
|
+
: undefined, [pathSegments, navigation.resolveSegmentsFrom]);
|
|
83
91
|
|
|
84
92
|
// Stable refs for objects that shouldn't trigger re-subscriptions
|
|
85
93
|
const dataSourceRef = useRef(dataSource);
|
|
@@ -95,11 +103,13 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
95
103
|
const orderPropertyRef = useRef(orderProperty);
|
|
96
104
|
const searchStringRef = useRef(searchString);
|
|
97
105
|
const resolvedPathRef = useRef(resolvedPath);
|
|
106
|
+
const resolvedPathSegmentsRef = useRef(resolvedPathSegments);
|
|
98
107
|
filterValuesRef.current = filterValues;
|
|
99
108
|
columnPropertyRef.current = columnProperty;
|
|
100
109
|
orderPropertyRef.current = orderProperty;
|
|
101
110
|
searchStringRef.current = searchString;
|
|
102
111
|
resolvedPathRef.current = resolvedPath;
|
|
112
|
+
resolvedPathSegmentsRef.current = resolvedPathSegments;
|
|
103
113
|
|
|
104
114
|
// Track item count per column for pagination
|
|
105
115
|
const [columnItemCounts, setColumnItemCounts] = useState<Record<string, number>>(() => {
|
|
@@ -168,6 +178,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
168
178
|
const currentOrderProperty = orderPropertyRef.current;
|
|
169
179
|
const currentSearchString = searchStringRef.current;
|
|
170
180
|
const currentResolvedPath = resolvedPathRef.current;
|
|
181
|
+
const currentPathSegments = resolvedPathSegmentsRef.current;
|
|
171
182
|
|
|
172
183
|
// Build filter for this column
|
|
173
184
|
const columnFilter: FilterValues<string> = {
|
|
@@ -205,6 +216,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
205
216
|
currentCollection.callbacks!.onFetch!({
|
|
206
217
|
collection: currentCollection,
|
|
207
218
|
path: currentResolvedPath,
|
|
219
|
+
pathSegments: currentPathSegments,
|
|
208
220
|
entity,
|
|
209
221
|
context: currentContext
|
|
210
222
|
})
|
|
@@ -248,6 +260,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
248
260
|
if (currentDataSource.listenCollection) {
|
|
249
261
|
const unsubscribe = currentDataSource.listenCollection<M>({
|
|
250
262
|
path: currentResolvedPath,
|
|
263
|
+
pathSegments: currentPathSegments,
|
|
251
264
|
collection: currentCollection,
|
|
252
265
|
onUpdate,
|
|
253
266
|
onError,
|
|
@@ -262,6 +275,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
262
275
|
} else {
|
|
263
276
|
currentDataSource.fetchCollection<M>({
|
|
264
277
|
path: currentResolvedPath,
|
|
278
|
+
pathSegments: currentPathSegments,
|
|
265
279
|
collection: currentCollection,
|
|
266
280
|
searchString: currentSearchString,
|
|
267
281
|
filter: columnFilter,
|
|
@@ -297,6 +311,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
297
311
|
const currentColumnProperty = columnPropertyRef.current;
|
|
298
312
|
const currentSearchString = searchStringRef.current;
|
|
299
313
|
const currentResolvedPath = resolvedPathRef.current;
|
|
314
|
+
const currentPathSegments = resolvedPathSegmentsRef.current;
|
|
300
315
|
const currentColumns = columns;
|
|
301
316
|
const currentColumnItemCounts = columnItemCounts;
|
|
302
317
|
|
|
@@ -316,6 +331,7 @@ export function useBoardDataController<M extends Record<string, any> = any, COLU
|
|
|
316
331
|
};
|
|
317
332
|
currentDataSource.countEntities({
|
|
318
333
|
path: currentResolvedPath,
|
|
334
|
+
pathSegments: currentPathSegments,
|
|
319
335
|
collection: currentCollection,
|
|
320
336
|
filter: columnFilter,
|
|
321
337
|
searchString: currentSearchString
|