@firecms/core 3.0.0-canary.210 → 3.0.0-canary.212
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ArrayContainer.d.ts +12 -5
- package/dist/components/EntityJsonPreview.d.ts +3 -0
- package/dist/core/EntityEditView.d.ts +3 -1
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/index.es.js +10632 -10671
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +10501 -10541
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +3 -2
- package/dist/internal/useBuildSideEntityController.d.ts +3 -3
- package/dist/types/collections.d.ts +2 -0
- package/dist/types/properties.d.ts +16 -1
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/references.d.ts +2 -2
- package/dist/util/resolutions.d.ts +7 -2
- package/package.json +6 -5
- package/src/components/ArrayContainer.tsx +40 -23
- package/src/components/DeleteEntityDialog.tsx +4 -2
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +4 -2
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -2
- package/src/components/EntityJsonPreview.tsx +66 -0
- package/src/components/EntityPreview.tsx +10 -3
- package/src/components/EntityView.tsx +4 -1
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +3 -1
- package/src/core/EntityEditView.tsx +30 -7
- package/src/core/FireCMS.tsx +12 -11
- package/src/form/EntityForm.tsx +11 -6
- package/src/form/PropertyFieldBinding.tsx +6 -3
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +4 -1
- package/src/form/field_bindings/BlockFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +6 -2
- package/src/form/field_bindings/RepeatFieldBinding.tsx +8 -2
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +4 -1
- package/src/hooks/data/save.ts +24 -29
- package/src/hooks/useFireCMSContext.tsx +0 -30
- package/src/internal/useBuildDataSource.ts +9 -5
- package/src/internal/useBuildSideEntityController.tsx +24 -17
- package/src/preview/PropertyPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
- package/src/types/collections.ts +2 -0
- package/src/types/properties.ts +20 -1
- package/src/util/property_utils.tsx +7 -3
- package/src/util/references.ts +8 -6
- package/src/util/resolutions.ts +13 -7
- package/src/util/useStorageUploadController.tsx +4 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import {
|
|
3
|
+
AuthController,
|
|
3
4
|
CustomizationController,
|
|
4
5
|
EntityCollection,
|
|
5
6
|
EntitySidePanelProps,
|
|
@@ -20,18 +21,19 @@ import {
|
|
|
20
21
|
import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
|
|
21
22
|
import { useCustomizationController, useLargeLayout } from "../hooks";
|
|
22
23
|
import { EntitySidePanel } from "../core/EntitySidePanel";
|
|
24
|
+
import { JSON_TAB_VALUE } from "../core/EntityEditView";
|
|
23
25
|
|
|
24
26
|
const NEW_URL_HASH = "new_side";
|
|
25
27
|
const SIDE_URL_HASH = "side";
|
|
26
28
|
|
|
27
|
-
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController): string {
|
|
29
|
+
export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController, authController: AuthController): string {
|
|
28
30
|
if (small) return CONTAINER_FULL_WIDTH;
|
|
29
31
|
|
|
30
32
|
const {
|
|
31
33
|
selectedSecondaryForm
|
|
32
34
|
} = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
|
|
33
35
|
|
|
34
|
-
const shouldUseSmallLayout = !props.selectedTab || Boolean(selectedSecondaryForm);
|
|
36
|
+
const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || Boolean(selectedSecondaryForm);
|
|
35
37
|
|
|
36
38
|
let resolvedWidth: string | undefined;
|
|
37
39
|
if (props.width) {
|
|
@@ -48,21 +50,22 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
|
|
|
48
50
|
} else if (!props.collection) {
|
|
49
51
|
return FORM_CONTAINER_WIDTH;
|
|
50
52
|
} else {
|
|
51
|
-
return calculateCollectionDesiredWidth(props.collection);
|
|
53
|
+
return calculateCollectionDesiredWidth(props.collection, authController);
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
const collectionViewWidthCache: { [key: string]: string } = {};
|
|
57
59
|
|
|
58
|
-
function calculateCollectionDesiredWidth(collection: EntityCollection<any
|
|
60
|
+
function calculateCollectionDesiredWidth(collection: EntityCollection<any>, authController: AuthController): string {
|
|
59
61
|
if (collectionViewWidthCache[collection.id]) {
|
|
60
62
|
return collectionViewWidthCache[collection.id];
|
|
61
63
|
}
|
|
62
64
|
const resolvedCollection = resolveCollection({
|
|
63
65
|
collection,
|
|
64
66
|
path: "__ignored",
|
|
65
|
-
ignoreMissingFields: true
|
|
67
|
+
ignoreMissingFields: true,
|
|
68
|
+
authController
|
|
66
69
|
});
|
|
67
70
|
|
|
68
71
|
let result = FORM_CONTAINER_WIDTH
|
|
@@ -97,7 +100,9 @@ function getNestedPropertiesDepth(property: ResolvedProperty, accumulator: numbe
|
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
export const useBuildSideEntityController = (navigation: NavigationController,
|
|
100
|
-
sideDialogsController: SideDialogsController
|
|
103
|
+
sideDialogsController: SideDialogsController,
|
|
104
|
+
authController: AuthController
|
|
105
|
+
): SideEntityController => {
|
|
101
106
|
|
|
102
107
|
const location = useLocation();
|
|
103
108
|
const initialised = useRef<boolean>(false);
|
|
@@ -105,7 +110,6 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
105
110
|
|
|
106
111
|
const smallLayout = !useLargeLayout();
|
|
107
112
|
|
|
108
|
-
// only on initialisation, create panels from URL
|
|
109
113
|
useEffect(() => {
|
|
110
114
|
|
|
111
115
|
const newFlag = location.hash === `#${NEW_URL_HASH}`;
|
|
@@ -118,9 +122,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
118
122
|
for (let i = 0; i < panelsFromUrl.length; i++) {
|
|
119
123
|
const props = panelsFromUrl[i];
|
|
120
124
|
if (i === 0)
|
|
121
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
125
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
|
|
122
126
|
else
|
|
123
|
-
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController))
|
|
127
|
+
sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController))
|
|
124
128
|
}
|
|
125
129
|
}
|
|
126
130
|
initialised.current = true;
|
|
@@ -140,7 +144,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
140
144
|
return;
|
|
141
145
|
}
|
|
142
146
|
const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
|
|
143
|
-
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
147
|
+
const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
|
|
144
148
|
const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
|
|
145
149
|
if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
|
|
146
150
|
sideDialogsController.replace(panelProps);
|
|
@@ -153,7 +157,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
153
157
|
useEffect(() => {
|
|
154
158
|
const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
|
|
155
159
|
if (sidePanelProps.additional) {
|
|
156
|
-
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController);
|
|
160
|
+
return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
|
|
157
161
|
}
|
|
158
162
|
return sidePanelProps;
|
|
159
163
|
});
|
|
@@ -186,10 +190,11 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
186
190
|
navigation.buildUrlCollectionPath,
|
|
187
191
|
navigation.resolveIdsFrom,
|
|
188
192
|
smallLayout,
|
|
189
|
-
customizationController
|
|
193
|
+
customizationController,
|
|
194
|
+
authController
|
|
190
195
|
));
|
|
191
196
|
|
|
192
|
-
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout]);
|
|
197
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, authController.user]);
|
|
193
198
|
|
|
194
199
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
195
200
|
|
|
@@ -197,9 +202,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
197
202
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
198
203
|
}
|
|
199
204
|
|
|
200
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController));
|
|
205
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
|
|
201
206
|
|
|
202
|
-
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout]);
|
|
207
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout, authController.user]);
|
|
203
208
|
|
|
204
209
|
return {
|
|
205
210
|
close,
|
|
@@ -260,7 +265,9 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
260
265
|
buildUrlCollectionPath: (path: string) => string,
|
|
261
266
|
resolveIdsFrom: (pathWithAliases: string) => string,
|
|
262
267
|
smallLayout: boolean,
|
|
263
|
-
customizationController: CustomizationController
|
|
268
|
+
customizationController: CustomizationController,
|
|
269
|
+
authController: AuthController
|
|
270
|
+
): SideDialogPanelProps => {
|
|
264
271
|
|
|
265
272
|
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
266
273
|
|
|
@@ -275,7 +282,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
275
282
|
formProps: props.formProps
|
|
276
283
|
};
|
|
277
284
|
|
|
278
|
-
const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController);
|
|
285
|
+
const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController, authController);
|
|
279
286
|
|
|
280
287
|
return {
|
|
281
288
|
key: `${props.path}/${props.entityId}`,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import { resolveProperty } from "../util";
|
|
14
14
|
|
|
15
15
|
import { PropertyPreviewProps } from "./PropertyPreviewProps";
|
|
16
|
-
import { useCustomizationController } from "../hooks";
|
|
16
|
+
import { useAuthController, useCustomizationController } from "../hooks";
|
|
17
17
|
import { EmptyValue } from "./components/EmptyValue";
|
|
18
18
|
import { UrlComponentPreview } from "./components/UrlComponentPreview";
|
|
19
19
|
import { StorageThumbnail } from "./components/StorageThumbnail";
|
|
@@ -37,6 +37,7 @@ import { ErrorView } from "../components";
|
|
|
37
37
|
*/
|
|
38
38
|
export const PropertyPreview = React.memo(function PropertyPreview<T extends CMSType>(props: PropertyPreviewProps<T>) {
|
|
39
39
|
|
|
40
|
+
const authController = useAuthController();
|
|
40
41
|
const customizationController = useCustomizationController();
|
|
41
42
|
|
|
42
43
|
let content: React.ReactNode | any;
|
|
@@ -53,7 +54,8 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
|
|
|
53
54
|
const property = resolveProperty({
|
|
54
55
|
propertyKey,
|
|
55
56
|
propertyOrBuilder: inputProperty,
|
|
56
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
57
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
58
|
+
authController
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
if (property === null) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ErrorBoundary } from "../../components";
|
|
3
|
-
import { useCustomizationController } from "../../hooks";
|
|
3
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
4
4
|
import { PropertyPreviewProps } from "../PropertyPreviewProps";
|
|
5
5
|
import { PropertyPreview } from "../PropertyPreview";
|
|
6
6
|
import { resolveArrayProperty } from "../../util";
|
|
@@ -15,12 +15,13 @@ export function ArrayOfMapsPreview({
|
|
|
15
15
|
size,
|
|
16
16
|
// entity
|
|
17
17
|
}: PropertyPreviewProps<Record<string, any>[]>) {
|
|
18
|
-
|
|
18
|
+
const authController = useAuthController();
|
|
19
19
|
const customizationController = useCustomizationController();
|
|
20
20
|
const property = resolveArrayProperty({
|
|
21
21
|
propertyKey,
|
|
22
22
|
property: inputProperty,
|
|
23
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
23
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
24
|
+
authController
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
if (Array.isArray(property?.of)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedReferenceProperty } from "../../types";
|
|
2
2
|
import { resolveArrayProperty } from "../../util";
|
|
3
|
-
import { useCustomizationController } from "../../hooks";
|
|
3
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
4
4
|
import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
|
|
5
5
|
import { ReferencePreview } from "../components/ReferencePreview";
|
|
6
6
|
|
|
@@ -13,12 +13,13 @@ export function ArrayOfReferencesPreview({
|
|
|
13
13
|
property: inputProperty,
|
|
14
14
|
size
|
|
15
15
|
}: PropertyPreviewProps<any[]>) {
|
|
16
|
-
|
|
16
|
+
const authController = useAuthController();
|
|
17
17
|
const customizationController = useCustomizationController();
|
|
18
18
|
const property = resolveArrayProperty({
|
|
19
19
|
propertyKey,
|
|
20
20
|
property: inputProperty,
|
|
21
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
21
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
22
|
+
authController
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
if (Array.isArray(property?.of)) {
|
|
@@ -3,7 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { resolveArrayProperty } from "../../util";
|
|
4
4
|
import { ResolvedProperty } from "../../types";
|
|
5
5
|
|
|
6
|
-
import { useCustomizationController } from "../../hooks";
|
|
6
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
7
7
|
import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
|
|
8
8
|
import { PropertyPreview } from "../PropertyPreview";
|
|
9
9
|
import { ErrorBoundary } from "../../components";
|
|
@@ -19,11 +19,13 @@ export function ArrayOfStorageComponentsPreview({
|
|
|
19
19
|
size
|
|
20
20
|
}: PropertyPreviewProps<any[]>) {
|
|
21
21
|
|
|
22
|
+
const authController = useAuthController();
|
|
22
23
|
const customizationController = useCustomizationController();
|
|
23
24
|
const property = resolveArrayProperty({
|
|
24
25
|
propertyKey,
|
|
25
26
|
property: inputProperty,
|
|
26
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
27
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
28
|
+
authController
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
if (Array.isArray(property.of)) {
|
|
@@ -3,7 +3,7 @@ import { ResolvedStringProperty } from "../../types";
|
|
|
3
3
|
|
|
4
4
|
import { resolveArrayProperty } from "../../util";
|
|
5
5
|
import { PropertyPreviewProps, StringPropertyPreview } from "../../preview";
|
|
6
|
-
import { useCustomizationController } from "../../hooks";
|
|
6
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
7
7
|
import { ErrorBoundary } from "../../components";
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -16,12 +16,13 @@ export function ArrayOfStringsPreview({
|
|
|
16
16
|
// entity,
|
|
17
17
|
size
|
|
18
18
|
}: PropertyPreviewProps<string[]>) {
|
|
19
|
-
|
|
19
|
+
const authController = useAuthController();
|
|
20
20
|
const customizationController = useCustomizationController();
|
|
21
21
|
const property = resolveArrayProperty({
|
|
22
22
|
propertyKey,
|
|
23
23
|
property: inputProperty,
|
|
24
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
24
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
25
|
+
authController
|
|
25
26
|
});
|
|
26
27
|
|
|
27
28
|
if (Array.isArray(property.of)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { resolveArrayProperty } from "../../util";
|
|
3
3
|
import { ResolvedProperty } from "../../types";
|
|
4
|
-
import { useCustomizationController } from "../../hooks";
|
|
4
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
5
5
|
import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
|
|
6
6
|
import { PropertyPreview } from "../PropertyPreview";
|
|
7
7
|
import { cls, defaultBorderMixin } from "@firecms/ui";
|
|
@@ -19,11 +19,13 @@ export function ArrayOneOfPreview({
|
|
|
19
19
|
// entity
|
|
20
20
|
}: PropertyPreviewProps<any[]>) {
|
|
21
21
|
|
|
22
|
+
const authController = useAuthController();
|
|
22
23
|
const customizationController = useCustomizationController();
|
|
23
24
|
const property = resolveArrayProperty({
|
|
24
25
|
propertyKey,
|
|
25
26
|
property: inputProperty,
|
|
26
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
27
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
28
|
+
authController
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
if (property?.dataType !== "array")
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import { resolveArrayProperty } from "../../util";
|
|
4
4
|
import { ResolvedProperty } from "../../types";
|
|
5
|
-
import { useCustomizationController } from "../../hooks";
|
|
5
|
+
import { useAuthController, useCustomizationController } from "../../hooks";
|
|
6
6
|
import { PreviewSize, PropertyPreviewProps } from "../PropertyPreviewProps";
|
|
7
7
|
import { PropertyPreview } from "../PropertyPreview";
|
|
8
8
|
import { cls, defaultBorderMixin } from "@firecms/ui";
|
|
@@ -19,11 +19,13 @@ export function ArrayPropertyPreview({
|
|
|
19
19
|
size
|
|
20
20
|
}: PropertyPreviewProps<any[]>) {
|
|
21
21
|
|
|
22
|
+
const authController = useAuthController();
|
|
22
23
|
const customizationController = useCustomizationController();
|
|
23
24
|
const property = resolveArrayProperty({
|
|
24
25
|
propertyKey,
|
|
25
26
|
property: inputProperty,
|
|
26
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
27
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
28
|
+
authController
|
|
27
29
|
});
|
|
28
30
|
|
|
29
31
|
if (!property.of) {
|
package/src/types/collections.ts
CHANGED
|
@@ -215,6 +215,7 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
|
|
|
215
215
|
* Force a filter in this view. If applied, the rest of the filters will
|
|
216
216
|
* be disabled. Filters applied with this prop cannot be changed.
|
|
217
217
|
* e.g. `forceFilter: { age: [">=", 18] }`
|
|
218
|
+
* e.g. `forceFilter: { related_user: ["==", new EntityReference("sdc43dsw2", "users")] }`
|
|
218
219
|
*/
|
|
219
220
|
forceFilter?: FilterValues<Extract<keyof M, string>>;
|
|
220
221
|
|
|
@@ -222,6 +223,7 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
|
|
|
222
223
|
* Initial filters applied to the collection this collection is related to.
|
|
223
224
|
* Defaults to none. Filters applied with this prop can be changed.
|
|
224
225
|
* e.g. `initialFilter: { age: [">=", 18] }`
|
|
226
|
+
* e.g. `initialFilter: { related_user: ["==", new EntityReference("sdc43dsw2", "users")] }`
|
|
225
227
|
*/
|
|
226
228
|
initialFilter?: FilterValues<Extract<keyof M, string>>; // setting FilterValues<M> can break defining collections by code
|
|
227
229
|
|
package/src/types/properties.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { EntityReference, EntityValues, GeoPoint, Vector } from "./entities";
|
|
|
5
5
|
import { ResolvedArrayProperty, ResolvedStringProperty } from "./resolved_entities";
|
|
6
6
|
import { FilterValues } from "./collections";
|
|
7
7
|
import { ChipColorKey, ChipColorScheme } from "@firecms/ui";
|
|
8
|
+
import { AuthController } from "./auth";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @group Entity properties
|
|
@@ -270,6 +271,11 @@ export type PropertyBuilderProps<M extends Record<string, any> = any> =
|
|
|
270
271
|
* Entity ID
|
|
271
272
|
*/
|
|
272
273
|
entityId?: string;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Controller to manage authentication
|
|
277
|
+
*/
|
|
278
|
+
authController: AuthController;
|
|
273
279
|
};
|
|
274
280
|
|
|
275
281
|
/**
|
|
@@ -285,7 +291,8 @@ export type PropertyBuilder<T extends CMSType = any, M extends Record<string, an
|
|
|
285
291
|
propertyValue,
|
|
286
292
|
index,
|
|
287
293
|
path,
|
|
288
|
-
entityId
|
|
294
|
+
entityId,
|
|
295
|
+
authController
|
|
289
296
|
}: PropertyBuilderProps<M>) => Property<T> | null;
|
|
290
297
|
|
|
291
298
|
/**
|
|
@@ -481,6 +488,18 @@ export interface ArrayProperty<T extends ArrayT[] = any[], ArrayT extends CMSTyp
|
|
|
481
488
|
*/
|
|
482
489
|
minimalistView?: boolean;
|
|
483
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Can the elements in this array be reordered. Defaults to `true`.
|
|
493
|
+
* This prop has no effect if `disabled` is set to true.
|
|
494
|
+
*/
|
|
495
|
+
sortable?: boolean;
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Can the elements in this array be added. Defaults to `true`
|
|
499
|
+
* This prop has no effect if `disabled` is set to true.
|
|
500
|
+
*/
|
|
501
|
+
canAddElements?: boolean;
|
|
502
|
+
|
|
484
503
|
}
|
|
485
504
|
|
|
486
505
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
AuthController,
|
|
4
5
|
EntityCollection,
|
|
5
6
|
PropertiesOrBuilders,
|
|
6
7
|
PropertyConfig,
|
|
@@ -13,12 +14,15 @@ import { resolveProperty } from "./resolutions";
|
|
|
13
14
|
import { CircleIcon, FunctionsIcon } from "@firecms/ui";
|
|
14
15
|
import { getFieldConfig } from "../core";
|
|
15
16
|
|
|
16
|
-
export function isReferenceProperty(
|
|
17
|
-
|
|
17
|
+
export function isReferenceProperty(
|
|
18
|
+
authController: AuthController,
|
|
19
|
+
propertyOrBuilder: PropertyOrBuilder,
|
|
20
|
+
fields: Record<string, PropertyConfig>) {
|
|
18
21
|
const resolvedProperty = resolveProperty({
|
|
19
22
|
propertyKey: "ignore", // TODO
|
|
20
23
|
propertyOrBuilder,
|
|
21
|
-
propertyConfigs: fields
|
|
24
|
+
propertyConfigs: fields,
|
|
25
|
+
authController
|
|
22
26
|
});
|
|
23
27
|
if (!resolvedProperty) return null;
|
|
24
28
|
if (resolvedProperty.dataType === "reference") {
|
package/src/util/references.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { EntityCollection, PropertyConfig, ResolvedEntityCollection } from "../types";
|
|
1
|
+
import { AuthController, EntityCollection, PropertyConfig, ResolvedEntityCollection } from "../types";
|
|
2
2
|
import { isReferenceProperty } from "./property_utils";
|
|
3
3
|
import { isPropertyBuilder } from "./entities";
|
|
4
4
|
import { getFieldConfig } from "../core";
|
|
5
5
|
|
|
6
|
-
export function getEntityPreviewKeys(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export function getEntityPreviewKeys(
|
|
7
|
+
authController: AuthController,
|
|
8
|
+
targetCollection: EntityCollection<any>,
|
|
9
|
+
fields: Record<string, PropertyConfig>,
|
|
10
|
+
previewProperties?: string[],
|
|
11
|
+
limit = 3) {
|
|
10
12
|
const allProperties = Object.keys(targetCollection.properties);
|
|
11
13
|
let listProperties = previewProperties?.filter(p => allProperties.includes(p as string));
|
|
12
14
|
if (!listProperties && targetCollection.previewProperties) {
|
|
@@ -18,7 +20,7 @@ export function getEntityPreviewKeys(targetCollection: EntityCollection<any>,
|
|
|
18
20
|
listProperties = allProperties;
|
|
19
21
|
return listProperties.filter(key => {
|
|
20
22
|
const propertyOrBuilder = targetCollection.properties[key];
|
|
21
|
-
return propertyOrBuilder && !isPropertyBuilder(propertyOrBuilder) && !isReferenceProperty(propertyOrBuilder, fields);
|
|
23
|
+
return propertyOrBuilder && !isPropertyBuilder(propertyOrBuilder) && !isReferenceProperty(authController, propertyOrBuilder, fields);
|
|
22
24
|
}).slice(0, limit);
|
|
23
25
|
}
|
|
24
26
|
}
|
package/src/util/resolutions.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ArrayProperty,
|
|
3
|
+
AuthController,
|
|
3
4
|
CMSType,
|
|
4
5
|
CustomizationController,
|
|
5
6
|
EntityCollection,
|
|
@@ -27,9 +28,7 @@ import { getDefaultValuesFor, isPropertyBuilder } from "./entities";
|
|
|
27
28
|
import { DEFAULT_ONE_OF_TYPE } from "./common";
|
|
28
29
|
import { getIn } from "@firecms/formex";
|
|
29
30
|
import { enumToObjectEntries } from "./enums";
|
|
30
|
-
import { isDefaultFieldConfigId } from "../core
|
|
31
|
-
|
|
32
|
-
// import util from "util";
|
|
31
|
+
import { isDefaultFieldConfigId } from "../core";
|
|
33
32
|
|
|
34
33
|
export const resolveCollection = <M extends Record<string, any>, >
|
|
35
34
|
({
|
|
@@ -40,7 +39,8 @@ export const resolveCollection = <M extends Record<string, any>, >
|
|
|
40
39
|
previousValues,
|
|
41
40
|
userConfigPersistence,
|
|
42
41
|
propertyConfigs,
|
|
43
|
-
ignoreMissingFields = false
|
|
42
|
+
ignoreMissingFields = false,
|
|
43
|
+
authController
|
|
44
44
|
}: {
|
|
45
45
|
collection: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
46
46
|
path: string,
|
|
@@ -50,6 +50,7 @@ export const resolveCollection = <M extends Record<string, any>, >
|
|
|
50
50
|
userConfigPersistence?: UserConfigurationPersistence;
|
|
51
51
|
propertyConfigs?: Record<string, PropertyConfig>;
|
|
52
52
|
ignoreMissingFields?: boolean;
|
|
53
|
+
authController: AuthController;
|
|
53
54
|
}): ResolvedEntityCollection<M> => {
|
|
54
55
|
|
|
55
56
|
const collectionOverride = userConfigPersistence?.getCollectionConfig<M>(path);
|
|
@@ -69,7 +70,8 @@ export const resolveCollection = <M extends Record<string, any>, >
|
|
|
69
70
|
path,
|
|
70
71
|
entityId,
|
|
71
72
|
propertyConfigs: propertyConfigs,
|
|
72
|
-
ignoreMissingFields
|
|
73
|
+
ignoreMissingFields,
|
|
74
|
+
authController
|
|
73
75
|
});
|
|
74
76
|
if (!childResolvedProperty) return {};
|
|
75
77
|
return ({
|
|
@@ -114,6 +116,7 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
|
|
|
114
116
|
fromBuilder?: boolean;
|
|
115
117
|
propertyConfigs?: Record<string, PropertyConfig<any>>;
|
|
116
118
|
ignoreMissingFields?: boolean;
|
|
119
|
+
authController: AuthController;
|
|
117
120
|
}): ResolvedProperty<T> | null {
|
|
118
121
|
|
|
119
122
|
if (typeof propertyOrBuilder === "object" && "resolved" in propertyOrBuilder) {
|
|
@@ -234,7 +237,8 @@ export function getArrayResolvedProperties<M>({
|
|
|
234
237
|
entityId?: string;
|
|
235
238
|
index?: number;
|
|
236
239
|
fromBuilder?: boolean;
|
|
237
|
-
propertyConfigs?: Record<string, PropertyConfig
|
|
240
|
+
propertyConfigs?: Record<string, PropertyConfig>;
|
|
241
|
+
authController: AuthController;
|
|
238
242
|
}) {
|
|
239
243
|
|
|
240
244
|
const of = property.of;
|
|
@@ -266,6 +270,7 @@ export function resolveArrayProperty<T extends any[], M>({
|
|
|
266
270
|
fromBuilder?: boolean;
|
|
267
271
|
propertyConfigs?: Record<string, PropertyConfig>;
|
|
268
272
|
ignoreMissingFields?: boolean;
|
|
273
|
+
authController: AuthController;
|
|
269
274
|
}): ResolvedArrayProperty {
|
|
270
275
|
const propertyValue = propertyKey ? getIn(props.values, propertyKey) : undefined;
|
|
271
276
|
|
|
@@ -281,7 +286,7 @@ export function resolveArrayProperty<T extends any[], M>({
|
|
|
281
286
|
propertyOrBuilder: p as Property<any>,
|
|
282
287
|
ignoreMissingFields,
|
|
283
288
|
...props,
|
|
284
|
-
index
|
|
289
|
+
index,
|
|
285
290
|
});
|
|
286
291
|
})
|
|
287
292
|
} as ResolvedArrayProperty;
|
|
@@ -373,6 +378,7 @@ export function resolveProperties<M extends Record<string, any>>({
|
|
|
373
378
|
fromBuilder?: boolean;
|
|
374
379
|
propertyConfigs?: Record<string, PropertyConfig>;
|
|
375
380
|
ignoreMissingFields?: boolean;
|
|
381
|
+
authController: AuthController;
|
|
376
382
|
}): ResolvedProperties<M> {
|
|
377
383
|
return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)
|
|
378
384
|
.map(([key, property]) => {
|
|
@@ -18,6 +18,7 @@ import { PreviewSize } from "../preview";
|
|
|
18
18
|
import { randomString } from "./strings";
|
|
19
19
|
import { resolveStorageFilenameString, resolveStoragePathString } from "./storage";
|
|
20
20
|
import { resolveProperty } from "./resolutions";
|
|
21
|
+
import { useAuthController } from "../hooks";
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Internal representation of an item in the storage
|
|
@@ -34,7 +35,6 @@ export interface StorageFieldItem {
|
|
|
34
35
|
size: PreviewSize
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
|
|
38
38
|
export function useStorageUploadController<M extends object>({
|
|
39
39
|
entityId,
|
|
40
40
|
entityValues,
|
|
@@ -58,6 +58,7 @@ export function useStorageUploadController<M extends object>({
|
|
|
58
58
|
onChange: (value: string | string[] | null) => void
|
|
59
59
|
}) {
|
|
60
60
|
|
|
61
|
+
const authController = useAuthController();
|
|
61
62
|
const storage: StorageConfig | undefined = property.dataType === "string"
|
|
62
63
|
? property.storage
|
|
63
64
|
: property.dataType === "array" &&
|
|
@@ -90,7 +91,8 @@ export function useStorageUploadController<M extends object>({
|
|
|
90
91
|
|
|
91
92
|
const resolvedProperty = resolveProperty({
|
|
92
93
|
propertyOrBuilder: property as PropertyOrBuilder,
|
|
93
|
-
values: entityValues
|
|
94
|
+
values: entityValues,
|
|
95
|
+
authController
|
|
94
96
|
}) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
|
|
95
97
|
|
|
96
98
|
const fileNameBuilder = useCallback(async (file: File) => {
|