@firecms/core 3.0.0-alpha.45 → 3.0.0-alpha.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +2 -2
- package/dist/hooks/index.d.ts +0 -2
- package/dist/index.es.js +12597 -12560
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +14 -14
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/EntityView.d.ts +2 -1
- package/dist/types/collections.d.ts +8 -8
- package/dist/types/firecms.d.ts +25 -6
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modify_collections.d.ts +5 -0
- package/dist/types/navigation.d.ts +9 -0
- package/dist/types/plugins.d.ts +2 -2
- package/dist/ui/ExpandablePanel.d.ts +2 -1
- package/dist/util/join_collections.d.ts +3 -7
- package/package.json +2 -2
- package/src/components/EntityCollectionTable/internal/EntityCollectionRowActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/common.tsx +1 -1
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +7 -7
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -6
- package/src/core/EntitySidePanel.tsx +5 -0
- package/src/core/FireCMS.tsx +28 -4
- package/src/core/NavigationRoutes.tsx +5 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -0
- package/src/hooks/index.tsx +0 -2
- package/src/internal/EntityView.tsx +6 -12
- package/src/{hooks → internal}/useBuildDataSource.ts +2 -4
- package/src/{hooks → internal}/useBuildNavigationController.tsx +34 -9
- package/src/internal/useBuildSideEntityController.tsx +1 -1
- package/src/preview/PropertyPreview.tsx +0 -1
- package/src/types/collections.ts +9 -9
- package/src/types/firecms.tsx +28 -8
- package/src/types/index.ts +1 -0
- package/src/types/modify_collections.tsx +6 -0
- package/src/types/navigation.ts +11 -0
- package/src/types/plugins.tsx +2 -2
- package/src/ui/ExpandablePanel.tsx +9 -2
- package/src/util/builders.ts +2 -1
- package/src/util/join_collections.ts +49 -19
- package/src/util/navigation_from_path.ts +2 -2
- package/src/util/navigation_utils.ts +3 -3
- package/src/util/parent_references_from_path.ts +2 -2
- package/src/util/property_utils.tsx +1 -7
- /package/dist/{hooks → internal}/useBuildDataSource.d.ts +0 -0
- /package/dist/{hooks → internal}/useBuildNavigationController.d.ts +0 -0
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
AuthController,
|
|
6
6
|
CMSView,
|
|
7
7
|
CMSViewsBuilder,
|
|
8
|
-
|
|
8
|
+
DataSourceDelegate,
|
|
9
9
|
EntityCollection,
|
|
10
10
|
EntityCollectionsBuilder,
|
|
11
11
|
EntityReference,
|
|
@@ -78,10 +78,10 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
78
78
|
const navigationEntries: TopNavigationEntry[] = [
|
|
79
79
|
...(collections ?? []).map(collection => (!collection.hideFromNavigation
|
|
80
80
|
? {
|
|
81
|
-
url: buildUrlCollectionPath(collection.
|
|
81
|
+
url: buildUrlCollectionPath(collection.id ?? collection.path),
|
|
82
82
|
type: "collection",
|
|
83
83
|
name: collection.name.trim(),
|
|
84
|
-
path: collection.
|
|
84
|
+
path: collection.id ?? collection.path,
|
|
85
85
|
collection,
|
|
86
86
|
description: collection.description?.trim(),
|
|
87
87
|
group: collection.group?.trim()
|
|
@@ -134,14 +134,14 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
134
134
|
|
|
135
135
|
setNavigationLoading(false);
|
|
136
136
|
setInitialised(true);
|
|
137
|
-
}, [baseCollections, authController.user, authController.initialLoading,
|
|
137
|
+
}, [baseCollections, authController.user, authController.initialLoading, plugins, baseViews, computeTopNavigation]);
|
|
138
138
|
|
|
139
139
|
useEffect(() => {
|
|
140
140
|
refreshNavigation();
|
|
141
141
|
}, [refreshNavigation]);
|
|
142
142
|
|
|
143
143
|
const getCollection = useCallback(<EC extends EntityCollection>(
|
|
144
|
-
|
|
144
|
+
idOrPath: string,
|
|
145
145
|
entityId?: string,
|
|
146
146
|
includeUserOverride = false
|
|
147
147
|
): EC | undefined => {
|
|
@@ -149,9 +149,9 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
149
149
|
if (!collections)
|
|
150
150
|
return undefined;
|
|
151
151
|
|
|
152
|
-
const baseCollection = getCollectionByPathOrAlias(removeInitialAndTrailingSlashes(
|
|
152
|
+
const baseCollection = getCollectionByPathOrAlias(removeInitialAndTrailingSlashes(idOrPath), collections);
|
|
153
153
|
|
|
154
|
-
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(
|
|
154
|
+
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
|
|
155
155
|
|
|
156
156
|
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
|
|
157
157
|
|
|
@@ -186,7 +186,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
186
186
|
|
|
187
187
|
for (let i = 0; i < pathSegments.length; i++) {
|
|
188
188
|
const pathSegment = pathSegments[i];
|
|
189
|
-
const collection: EntityCollection | undefined = currentCollections!.find(c => c.
|
|
189
|
+
const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === pathSegment || c.path === pathSegment);
|
|
190
190
|
if (!collection)
|
|
191
191
|
return undefined;
|
|
192
192
|
currentCollections = collection.subcollections;
|
|
@@ -198,6 +198,25 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
198
198
|
|
|
199
199
|
}, [collections]);
|
|
200
200
|
|
|
201
|
+
const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {
|
|
202
|
+
let currentCollections = collections;
|
|
203
|
+
if (!currentCollections)
|
|
204
|
+
throw Error("Collections have not been initialised yet");
|
|
205
|
+
|
|
206
|
+
for (let i = 0; i < ids.length; i++) {
|
|
207
|
+
const id = ids[i];
|
|
208
|
+
const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === id);
|
|
209
|
+
if (!collection)
|
|
210
|
+
return undefined;
|
|
211
|
+
currentCollections = collection.subcollections;
|
|
212
|
+
if (i === ids.length - 1)
|
|
213
|
+
return collection as EC;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return undefined;
|
|
217
|
+
|
|
218
|
+
}, [collections]);
|
|
219
|
+
|
|
201
220
|
const isUrlCollectionPath = useCallback(
|
|
202
221
|
(path: string): boolean => removeInitialAndTrailingSlashes(path + "/").startsWith(removeInitialAndTrailingSlashes(fullCollectionPath) + "/"),
|
|
203
222
|
[fullCollectionPath]);
|
|
@@ -238,6 +257,10 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
238
257
|
});
|
|
239
258
|
}, [collections]);
|
|
240
259
|
|
|
260
|
+
const getParentCollectionIds = useCallback((path: string): string[] => {
|
|
261
|
+
return getAllParentCollectionsForPath(path).map(r => r.id);
|
|
262
|
+
}, [getAllParentCollectionsForPath])
|
|
263
|
+
|
|
241
264
|
return useMemo(() => ({
|
|
242
265
|
collections: collections ?? [],
|
|
243
266
|
views: views ?? [],
|
|
@@ -249,6 +272,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
249
272
|
initialised,
|
|
250
273
|
getCollection,
|
|
251
274
|
getCollectionFromPaths,
|
|
275
|
+
getCollectionFromIds,
|
|
252
276
|
isUrlCollectionPath,
|
|
253
277
|
urlPathToDataPath,
|
|
254
278
|
buildUrlCollectionPath,
|
|
@@ -258,7 +282,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
258
282
|
topLevelNavigation,
|
|
259
283
|
baseLocation,
|
|
260
284
|
refreshNavigation,
|
|
261
|
-
getParentReferencesFromPath: getAllParentCollectionsForPath
|
|
285
|
+
getParentReferencesFromPath: getAllParentCollectionsForPath,
|
|
286
|
+
getParentCollectionIds
|
|
262
287
|
}), [baseCollectionPath, baseLocation, basePath, buildCMSUrlPath, buildUrlCollectionPath, buildUrlEditCollectionPath, collections, getAllParentCollectionsForPath, getCollection, getCollectionFromPaths, homeUrl, initialised, isUrlCollectionPath, navigationLoading, navigationLoadingError, refreshNavigation, resolveAliasesFrom, topLevelNavigation, urlPathToDataPath, views]);
|
|
263
288
|
}
|
|
264
289
|
|
|
@@ -125,7 +125,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
125
125
|
if (previousEntry.type === "entity") {
|
|
126
126
|
const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];
|
|
127
127
|
if (lastSidePanel)
|
|
128
|
-
lastSidePanel.selectedSubPath = navigationEntry.collection.
|
|
128
|
+
lastSidePanel.selectedSubPath = navigationEntry.collection.id ?? navigationEntry.collection.path;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
}
|
|
@@ -17,7 +17,6 @@ import { UrlComponentPreview } from "./components/UrlComponentPreview";
|
|
|
17
17
|
import { StorageThumbnail } from "./components/StorageThumbnail";
|
|
18
18
|
import { Markdown } from "../ui";
|
|
19
19
|
import { StringPropertyPreview } from "./property_previews/StringPropertyPreview";
|
|
20
|
-
import { ArrayOfMapsPreview } from "./property_previews/ArrayOfMapsPreview";
|
|
21
20
|
import { ArrayPropertyPreview } from "./property_previews/ArrayPropertyPreview";
|
|
22
21
|
import { ArrayOfReferencesPreview } from "./property_previews/ArrayOfReferencesPreview";
|
|
23
22
|
import { ArrayOfStorageComponentsPreview } from "./property_previews/ArrayOfStorageComponentsPreview";
|
package/src/types/collections.ts
CHANGED
|
@@ -18,6 +18,14 @@ import { ExportConfig } from "./export_import";
|
|
|
18
18
|
*/
|
|
19
19
|
export interface EntityCollection<M extends Record<string, any> = any, UserType extends User = User> {
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* You can set an alias that will be used internally instead of the `path`.
|
|
23
|
+
* The `alias` value will be used to determine the URL of the collection,
|
|
24
|
+
* while `path` will still be used in the datasource.
|
|
25
|
+
* Note that you can use this value in reference properties too.
|
|
26
|
+
*/
|
|
27
|
+
id: string;
|
|
28
|
+
|
|
21
29
|
/**
|
|
22
30
|
* Name of the collection, typically plural.
|
|
23
31
|
* E.g. `Products`, `Blog`
|
|
@@ -48,14 +56,6 @@ export interface EntityCollection<M extends Record<string, any> = any, UserType
|
|
|
48
56
|
*/
|
|
49
57
|
collectionGroup?: boolean;
|
|
50
58
|
|
|
51
|
-
/**
|
|
52
|
-
* You can set an alias that will be used internally instead of the `path`.
|
|
53
|
-
* The `alias` value will be used to determine the URL of the collection,
|
|
54
|
-
* while `path` will still be used in the datasource.
|
|
55
|
-
* Note that you can use this value in reference properties too.
|
|
56
|
-
*/
|
|
57
|
-
alias?: string;
|
|
58
|
-
|
|
59
59
|
/**
|
|
60
60
|
* Icon key to use in this collection.
|
|
61
61
|
* You can use any of the icons in the Material specs:
|
|
@@ -300,7 +300,7 @@ export interface CollectionActionsProps<M extends Record<string, any> = any, Use
|
|
|
300
300
|
/**
|
|
301
301
|
* Array of the parent path segments like `['users']`
|
|
302
302
|
*/
|
|
303
|
-
|
|
303
|
+
parentCollectionIds: string[];
|
|
304
304
|
|
|
305
305
|
/**
|
|
306
306
|
* The collection configuration
|
package/src/types/firecms.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { User } from "./user";
|
|
3
3
|
import { AuthController } from "./auth";
|
|
4
|
-
import {
|
|
4
|
+
import { DataSourceDelegate } from "./datasource";
|
|
5
5
|
import { EntityCollection, EntityCustomView } from "./collections";
|
|
6
|
-
import { CMSView
|
|
6
|
+
import { CMSView } from "./navigation";
|
|
7
7
|
import { FireCMSContext } from "./firecms_context";
|
|
8
8
|
import { PropertyConfig } from "./property_config";
|
|
9
9
|
import { Locale } from "./locales";
|
|
@@ -67,6 +67,20 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
|
|
|
67
67
|
loading: boolean;
|
|
68
68
|
}) => React.ReactNode;
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* List of the mapped collections in the CMS.
|
|
72
|
+
* Each entry relates to a collection in the root database.
|
|
73
|
+
* Each of the navigation entries in this field
|
|
74
|
+
* generates an entry in the main menu.
|
|
75
|
+
*/
|
|
76
|
+
collections?: EC[] | EntityCollectionsBuilder<EC>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Custom additional views created by the developer, added to the main
|
|
80
|
+
* navigation
|
|
81
|
+
*/
|
|
82
|
+
views?: CMSView[] | CMSViewsBuilder;
|
|
83
|
+
|
|
70
84
|
/**
|
|
71
85
|
* Record of custom form fields to be used in the CMS.
|
|
72
86
|
* You can use the key to reference the custom field in
|
|
@@ -98,7 +112,7 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
|
|
|
98
112
|
/**
|
|
99
113
|
* Connector to your database
|
|
100
114
|
*/
|
|
101
|
-
|
|
115
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
102
116
|
|
|
103
117
|
/**
|
|
104
118
|
* Connector to your file upload/fetch implementation
|
|
@@ -111,10 +125,18 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
|
|
|
111
125
|
authController: AuthController<UserType>;
|
|
112
126
|
|
|
113
127
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
128
|
+
* Path under the navigation routes of the CMS will be created. Defaults to `/`.
|
|
129
|
+
* Internally FireCMS uses `react-router` to create the routes, the base path is attached to the
|
|
130
|
+
* `BrowserRouter` component. If you are using FireCMS in a subpath of your website, you can use
|
|
131
|
+
* this prop to specify the base path.
|
|
116
132
|
*/
|
|
117
|
-
|
|
133
|
+
basePath?: string;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Path under the collection routes of the CMS will be created.
|
|
137
|
+
* Defaults to `/c`.
|
|
138
|
+
*/
|
|
139
|
+
baseCollectionPath?: string;
|
|
118
140
|
|
|
119
141
|
/**
|
|
120
142
|
* Use this controller to access the configuration that is stored locally,
|
|
@@ -150,6 +172,4 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
|
|
|
150
172
|
|
|
151
173
|
}
|
|
152
174
|
|
|
153
|
-
|
|
154
|
-
|
|
155
175
|
};
|
package/src/types/index.ts
CHANGED
package/src/types/navigation.ts
CHANGED
|
@@ -52,6 +52,11 @@ export type NavigationController = {
|
|
|
52
52
|
getCollection: <EC extends EntityCollection = EntityCollection<any>>(pathOrAlias: string,
|
|
53
53
|
entityId?: string,
|
|
54
54
|
includeUserOverride?: boolean) => EC | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Get the collection configuration from its parent path segments.
|
|
57
|
+
*/
|
|
58
|
+
getCollectionFromIds: <EC extends EntityCollection = EntityCollection<any>>(ids: string[]) => EC | undefined;
|
|
59
|
+
|
|
55
60
|
/**
|
|
56
61
|
* Get the collection configuration from its parent path segments.
|
|
57
62
|
*/
|
|
@@ -128,6 +133,12 @@ export type NavigationController = {
|
|
|
128
133
|
* @param path
|
|
129
134
|
*/
|
|
130
135
|
getParentReferencesFromPath: (path: string) => EntityReference[];
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Retrieve all the related parent collection ids for a given path
|
|
139
|
+
* @param path
|
|
140
|
+
*/
|
|
141
|
+
getParentCollectionIds: (path: string) => string[];
|
|
131
142
|
}
|
|
132
143
|
|
|
133
144
|
/**
|
package/src/types/plugins.tsx
CHANGED
|
@@ -116,7 +116,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
|
|
|
116
116
|
property: ResolvedProperty,
|
|
117
117
|
propertyKey: string,
|
|
118
118
|
fullPath: string,
|
|
119
|
-
|
|
119
|
+
parentCollectionIds: string[],
|
|
120
120
|
onHover: boolean,
|
|
121
121
|
collection: EC;
|
|
122
122
|
}>;
|
|
@@ -127,7 +127,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
|
|
|
127
127
|
*/
|
|
128
128
|
AddColumnComponent?: React.ComponentType<{
|
|
129
129
|
fullPath: string,
|
|
130
|
-
|
|
130
|
+
parentCollectionIds: string[],
|
|
131
131
|
collection: EC;
|
|
132
132
|
}>;
|
|
133
133
|
}
|
|
@@ -10,8 +10,9 @@ export function ExpandablePanel({
|
|
|
10
10
|
title,
|
|
11
11
|
children,
|
|
12
12
|
invisible = false,
|
|
13
|
-
|
|
13
|
+
expanded,
|
|
14
14
|
onExpandedChange,
|
|
15
|
+
initiallyExpanded = true,
|
|
15
16
|
titleClassName,
|
|
16
17
|
asField,
|
|
17
18
|
className
|
|
@@ -19,6 +20,7 @@ export function ExpandablePanel({
|
|
|
19
20
|
title: React.ReactNode,
|
|
20
21
|
invisible?: boolean,
|
|
21
22
|
initiallyExpanded?: boolean;
|
|
23
|
+
expanded?: boolean;
|
|
22
24
|
onExpandedChange?: (expanded: boolean) => void,
|
|
23
25
|
titleClassName?: string,
|
|
24
26
|
asField?: boolean,
|
|
@@ -54,7 +56,7 @@ export function ExpandablePanel({
|
|
|
54
56
|
}
|
|
55
57
|
}`);
|
|
56
58
|
|
|
57
|
-
const [open, setOpen] = useState(
|
|
59
|
+
const [open, setOpen] = useState(expanded !== undefined ? expanded : initiallyExpanded);
|
|
58
60
|
const [allowOverflow, setAllowOverflow] = useState(open);
|
|
59
61
|
|
|
60
62
|
useEffect(() => {
|
|
@@ -67,6 +69,11 @@ export function ExpandablePanel({
|
|
|
67
69
|
}
|
|
68
70
|
}, [open]);
|
|
69
71
|
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (expanded !== undefined)
|
|
74
|
+
setOpen(expanded);
|
|
75
|
+
}, [expanded]);
|
|
76
|
+
|
|
70
77
|
return (<>
|
|
71
78
|
<Collapsible.Root
|
|
72
79
|
className={cn(
|
package/src/util/builders.ts
CHANGED
|
@@ -1,43 +1,67 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
EntityCollection,
|
|
3
|
+
MapProperty,
|
|
4
|
+
ModifyCollectionProps,
|
|
5
|
+
PropertiesOrBuilders,
|
|
6
|
+
Property,
|
|
7
|
+
PropertyOrBuilder
|
|
8
|
+
} from "../types";
|
|
9
|
+
import { mergeDeep } from "./objects";
|
|
10
|
+
import { sortProperties } from "./collections";
|
|
11
|
+
import { isPropertyBuilder } from "./entities";
|
|
5
12
|
|
|
6
13
|
/**
|
|
7
14
|
*
|
|
8
|
-
* @param storedCollections
|
|
9
|
-
* @param codedCollections
|
|
10
15
|
*/
|
|
11
|
-
export function joinCollectionLists(
|
|
16
|
+
export function joinCollectionLists(targetCollections: EntityCollection[],
|
|
17
|
+
sourceCollections: EntityCollection[] | undefined,
|
|
18
|
+
parentPaths: string[] = [],
|
|
19
|
+
modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | undefined): EntityCollection[] {
|
|
12
20
|
|
|
13
21
|
// merge collections that are in both lists
|
|
14
|
-
const updatedCollections = (
|
|
22
|
+
const updatedCollections = (sourceCollections ?? [])
|
|
15
23
|
.map((codedCollection) => {
|
|
16
|
-
const storedCollection =
|
|
17
|
-
return collection.
|
|
24
|
+
const storedCollection = targetCollections?.find((collection) => {
|
|
25
|
+
return collection.id === codedCollection.id;
|
|
26
|
+
// return collection.path === codedCollection.path || collection.id && codedCollection.id;
|
|
18
27
|
});
|
|
19
28
|
if (!storedCollection) {
|
|
20
29
|
return codedCollection;
|
|
21
30
|
} else {
|
|
22
|
-
return mergeCollection(storedCollection, codedCollection);
|
|
31
|
+
return mergeCollection(storedCollection, codedCollection, parentPaths, modifyCollection);
|
|
23
32
|
}
|
|
24
33
|
});
|
|
25
34
|
|
|
26
35
|
// fetched collections that are not in the base collections
|
|
27
|
-
const resultStoredCollections =
|
|
28
|
-
.filter((col) => !updatedCollections.map(c => c.
|
|
36
|
+
const resultStoredCollections = targetCollections
|
|
37
|
+
.filter((col) => !updatedCollections.map(c => c.id).includes(col.id))
|
|
38
|
+
.map((col) => {
|
|
39
|
+
if (modifyCollection) {
|
|
40
|
+
const modified = modifyCollection({ collection: col, parentPaths });
|
|
41
|
+
return modified ?? col;
|
|
42
|
+
} else {
|
|
43
|
+
return col;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
29
46
|
|
|
30
47
|
return [...updatedCollections, ...resultStoredCollections];
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
/**
|
|
34
51
|
*
|
|
35
|
-
* @param target
|
|
36
|
-
* @param source
|
|
37
52
|
*/
|
|
38
|
-
export function mergeCollection(target: EntityCollection,
|
|
53
|
+
export function mergeCollection(target: EntityCollection,
|
|
54
|
+
source: EntityCollection,
|
|
55
|
+
parentPaths: string[] = [],
|
|
56
|
+
modifyCollection?: (props: ModifyCollectionProps) => EntityCollection | undefined
|
|
57
|
+
): EntityCollection {
|
|
39
58
|
|
|
40
|
-
const subcollectionsMerged = joinCollectionLists(
|
|
59
|
+
const subcollectionsMerged = joinCollectionLists(
|
|
60
|
+
target?.subcollections ?? [],
|
|
61
|
+
source?.subcollections ?? [],
|
|
62
|
+
[...parentPaths, target.path],
|
|
63
|
+
modifyCollection
|
|
64
|
+
);
|
|
41
65
|
|
|
42
66
|
const propertiesMerged: PropertiesOrBuilders = { ...target.properties } as PropertiesOrBuilders;
|
|
43
67
|
Object.keys(source.properties).forEach((key) => {
|
|
@@ -51,16 +75,22 @@ export function mergeCollection(target: EntityCollection, source: EntityCollecti
|
|
|
51
75
|
const mergedCollection = mergeDeep(target, source);
|
|
52
76
|
const targetPropertiesOrder = getCollectionKeys(target);
|
|
53
77
|
const sourcePropertiesOrder = getCollectionKeys(source);
|
|
54
|
-
const mergedPropertiesOrder = [...new Set([...
|
|
78
|
+
const mergedPropertiesOrder = [...new Set([...sourcePropertiesOrder, ...targetPropertiesOrder])];
|
|
55
79
|
const mergedEntityViews = [...new Set([...(target.entityViews ?? []), ...(source.entityViews ?? [])])];
|
|
56
80
|
|
|
57
|
-
|
|
81
|
+
let resultCollection: EntityCollection = {
|
|
58
82
|
...mergedCollection,
|
|
59
83
|
subcollections: subcollectionsMerged,
|
|
60
84
|
properties: sortProperties(propertiesMerged, mergedPropertiesOrder),
|
|
61
85
|
propertiesOrder: mergedPropertiesOrder,
|
|
62
86
|
entityViews: mergedEntityViews
|
|
87
|
+
};
|
|
88
|
+
if (modifyCollection) {
|
|
89
|
+
const modifiedCollection = modifyCollection({ collection: resultCollection, parentPaths });
|
|
90
|
+
if (modifiedCollection)
|
|
91
|
+
resultCollection = modifiedCollection;
|
|
63
92
|
}
|
|
93
|
+
return resultCollection
|
|
64
94
|
}
|
|
65
95
|
|
|
66
96
|
function mergePropertyOrBuilder(target: Property, source: PropertyOrBuilder): PropertyOrBuilder {
|
|
@@ -46,10 +46,10 @@ export function getNavigationEntriesFromPathInternal(props: {
|
|
|
46
46
|
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
47
47
|
const subpathCombination = subpathCombinations[i];
|
|
48
48
|
|
|
49
|
-
const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.
|
|
49
|
+
const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);
|
|
50
50
|
|
|
51
51
|
if (collection) {
|
|
52
|
-
const pathOrAlias = collection.
|
|
52
|
+
const pathOrAlias = collection.id ?? collection.path;
|
|
53
53
|
const collectionPath = currentFullPath && currentFullPath.length > 0
|
|
54
54
|
? (currentFullPath + "/" + pathOrAlias)
|
|
55
55
|
: pathOrAlias;
|
|
@@ -54,7 +54,7 @@ export function resolveCollectionPathAliases(path: string, allCollections: Entit
|
|
|
54
54
|
throw Error(`Collection paths must have an odd number of segments: ${path}`);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
const aliasedCollection = allCollections.find((col) => col.
|
|
57
|
+
const aliasedCollection = allCollections.find((col) => col.id === subpaths[0]);
|
|
58
58
|
let resolvedAliased;
|
|
59
59
|
if (aliasedCollection) {
|
|
60
60
|
resolvedAliased = aliasedCollection.path;
|
|
@@ -90,8 +90,8 @@ export function getCollectionByPathOrAlias(pathOrAlias: string, collections: Ent
|
|
|
90
90
|
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
91
91
|
const subpathCombination = subpathCombinations[i];
|
|
92
92
|
const navigationEntry = collections && collections
|
|
93
|
-
.sort((a, b) => (a.
|
|
94
|
-
.find((entry) => entry.
|
|
93
|
+
.sort((a, b) => (a.id ?? "").localeCompare(b.id ?? ""))
|
|
94
|
+
.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);
|
|
95
95
|
|
|
96
96
|
if (navigationEntry) {
|
|
97
97
|
|
|
@@ -20,10 +20,10 @@ export function getParentReferencesFromPath(props: {
|
|
|
20
20
|
for (let i = 0; i < subpathCombinations.length; i++) {
|
|
21
21
|
const subpathCombination = subpathCombinations[i];
|
|
22
22
|
|
|
23
|
-
const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.
|
|
23
|
+
const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);
|
|
24
24
|
|
|
25
25
|
if (collection) {
|
|
26
|
-
const pathOrAlias = collection.
|
|
26
|
+
const pathOrAlias = collection.id ?? collection.path;
|
|
27
27
|
const collectionPath = currentFullPath && currentFullPath.length > 0
|
|
28
28
|
? (currentFullPath + "/" + pathOrAlias)
|
|
29
29
|
: pathOrAlias;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
EntityCollection,
|
|
5
|
-
PropertiesOrBuilders,
|
|
6
|
-
PropertyConfig,
|
|
7
|
-
PropertyOrBuilder,
|
|
8
|
-
ResolvedProperty
|
|
9
|
-
} from "../types";
|
|
3
|
+
import { EntityCollection, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedProperty } from "../types";
|
|
10
4
|
import { isPropertyBuilder } from "./entities";
|
|
11
5
|
import { resolveProperty } from "./resolutions";
|
|
12
6
|
import { CircleIcon, FunctionsIcon } from "../icons";
|
|
File without changes
|
|
File without changes
|