@firecms/core 3.0.0-canary.118 → 3.0.0-canary.119
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/core/DrawerNavigationItem.d.ts +2 -1
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/index.es.js +46 -24
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +46 -24
- package/dist/index.umd.js.map +1 -1
- package/dist/types/datasource.d.ts +4 -0
- package/dist/types/properties.d.ts +1 -1
- package/dist/util/resolutions.d.ts +13 -0
- package/package.json +5 -5
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +0 -2
- package/src/core/DefaultDrawer.tsx +5 -3
- package/src/core/DrawerNavigationItem.tsx +3 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +2 -2
- package/src/form/field_bindings/RepeatFieldBinding.tsx +13 -4
- package/src/form/field_bindings/SelectFieldBinding.tsx +44 -43
- package/src/form/field_bindings/TextFieldBinding.tsx +0 -1
- package/src/form/index.tsx +0 -5
- package/src/types/datasource.ts +5 -0
- package/src/types/properties.ts +1 -1
- package/src/util/resolutions.ts +39 -11
|
@@ -177,6 +177,10 @@ export interface DataSourceDelegate {
|
|
|
177
177
|
* If the data source has been initialised
|
|
178
178
|
*/
|
|
179
179
|
initialised?: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* If the user is authenticated to use the data source
|
|
182
|
+
*/
|
|
183
|
+
authenticated?: boolean;
|
|
180
184
|
/**
|
|
181
185
|
* Fetch data from a collection
|
|
182
186
|
* @param path
|
|
@@ -8,7 +8,7 @@ import { ChipColorKey, ChipColorScheme } from "@firecms/ui";
|
|
|
8
8
|
/**
|
|
9
9
|
* @group Entity properties
|
|
10
10
|
*/
|
|
11
|
-
export type DataType<T extends CMSType = CMSType> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends Date ? "date" : T extends GeoPoint ? "geopoint" : T extends Vector ? "vector" : T extends EntityReference ? "reference" : T extends Array<CMSType> ? "array" : T extends Record<string,
|
|
11
|
+
export type DataType<T extends CMSType = CMSType> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends Date ? "date" : T extends GeoPoint ? "geopoint" : T extends Vector ? "vector" : T extends EntityReference ? "reference" : T extends Array<CMSType> ? "array" : T extends Record<string, CMSType> ? "map" : never;
|
|
12
12
|
/**
|
|
13
13
|
* @group Entity properties
|
|
14
14
|
*/
|
|
@@ -26,6 +26,19 @@ export declare function resolveProperty<T extends CMSType = CMSType, M extends R
|
|
|
26
26
|
fields?: Record<string, PropertyConfig<any>>;
|
|
27
27
|
ignoreMissingFields?: boolean;
|
|
28
28
|
}): ResolvedProperty<T> | null;
|
|
29
|
+
export declare function getArrayResolvedProperties<M>({ propertyKey, propertyValue, property, ...props }: {
|
|
30
|
+
propertyValue: any;
|
|
31
|
+
propertyKey?: string;
|
|
32
|
+
property: ArrayProperty<any> | ResolvedArrayProperty<any>;
|
|
33
|
+
ignoreMissingFields: boolean;
|
|
34
|
+
values?: Partial<M>;
|
|
35
|
+
previousValues?: Partial<M>;
|
|
36
|
+
path?: string;
|
|
37
|
+
entityId?: string;
|
|
38
|
+
index?: number;
|
|
39
|
+
fromBuilder?: boolean;
|
|
40
|
+
fields?: Record<string, PropertyConfig>;
|
|
41
|
+
}): ResolvedProperty[];
|
|
29
42
|
export declare function resolveArrayProperty<T extends any[], M>({ propertyKey, property, ignoreMissingFields, ...props }: {
|
|
30
43
|
propertyKey?: string;
|
|
31
44
|
property: ArrayProperty<T> | ResolvedArrayProperty<T>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.119",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"./package.json": "./package.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
50
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
51
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
49
|
+
"@firecms/editor": "^3.0.0-canary.119",
|
|
50
|
+
"@firecms/formex": "^3.0.0-canary.119",
|
|
51
|
+
"@firecms/ui": "^3.0.0-canary.119",
|
|
52
52
|
"@hello-pangea/dnd": "^16.6.0",
|
|
53
53
|
"@radix-ui/react-portal": "^1.1.1",
|
|
54
54
|
"clsx": "^2.1.1",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"dist",
|
|
101
101
|
"src"
|
|
102
102
|
],
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "22e1ffb78b12816a576df70e3aa7df1ee29e26ad",
|
|
104
104
|
"publishConfig": {
|
|
105
105
|
"access": "public"
|
|
106
106
|
},
|
|
@@ -82,8 +82,6 @@ export function VirtualTableSelect(props: {
|
|
|
82
82
|
className="w-full h-full p-0 bg-transparent"
|
|
83
83
|
position={"item-aligned"}
|
|
84
84
|
disabled={disabled}
|
|
85
|
-
padding={false}
|
|
86
|
-
includeFocusOutline={false}
|
|
87
85
|
value={validValue
|
|
88
86
|
? ((internalValue as any[]).map(v => v.toString()))
|
|
89
87
|
: ([])}
|
|
@@ -30,15 +30,15 @@ export function DefaultDrawer({
|
|
|
30
30
|
logo
|
|
31
31
|
} = useApp();
|
|
32
32
|
|
|
33
|
+
const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
|
|
34
|
+
|
|
33
35
|
const analyticsController = useAnalyticsController();
|
|
34
36
|
const navigation = useNavigationController();
|
|
35
37
|
|
|
36
|
-
const tooltipsOpen = drawerHovered && !drawerOpen;
|
|
38
|
+
const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
|
|
37
39
|
const largeLayout = useLargeLayout();
|
|
38
40
|
const navigate = useNavigate();
|
|
39
41
|
|
|
40
|
-
const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
|
|
41
|
-
|
|
42
42
|
if (!navigation.topLevelNavigation)
|
|
43
43
|
throw Error("Navigation not ready in Drawer");
|
|
44
44
|
|
|
@@ -91,6 +91,7 @@ export function DefaultDrawer({
|
|
|
91
91
|
key={`navigation_${index}`}
|
|
92
92
|
icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
|
|
93
93
|
tooltipsOpen={tooltipsOpen}
|
|
94
|
+
adminMenuOpen={adminMenuOpen}
|
|
94
95
|
drawerOpen={drawerOpen}
|
|
95
96
|
onClick={() => onClick(view)}
|
|
96
97
|
url={view.url}
|
|
@@ -101,6 +102,7 @@ export function DefaultDrawer({
|
|
|
101
102
|
</div>
|
|
102
103
|
|
|
103
104
|
{adminViews.length > 0 && <Menu
|
|
105
|
+
side={"right"}
|
|
104
106
|
open={adminMenuOpen}
|
|
105
107
|
onOpenChange={setAdminMenuOpen}
|
|
106
108
|
trigger={
|
|
@@ -7,6 +7,7 @@ export function DrawerNavigationItem({
|
|
|
7
7
|
name,
|
|
8
8
|
icon,
|
|
9
9
|
drawerOpen,
|
|
10
|
+
adminMenuOpen,
|
|
10
11
|
tooltipsOpen,
|
|
11
12
|
url,
|
|
12
13
|
onClick
|
|
@@ -15,6 +16,7 @@ export function DrawerNavigationItem({
|
|
|
15
16
|
name: string,
|
|
16
17
|
tooltipsOpen: boolean,
|
|
17
18
|
drawerOpen: boolean,
|
|
19
|
+
adminMenuOpen?: boolean,
|
|
18
20
|
url: string,
|
|
19
21
|
onClick?: () => void,
|
|
20
22
|
}) {
|
|
@@ -56,7 +58,7 @@ export function DrawerNavigationItem({
|
|
|
56
58
|
</div>;
|
|
57
59
|
|
|
58
60
|
return <Tooltip
|
|
59
|
-
open={drawerOpen ? false : tooltipsOpen}
|
|
61
|
+
open={drawerOpen || adminMenuOpen ? false : tooltipsOpen}
|
|
60
62
|
side="right"
|
|
61
63
|
title={name}>
|
|
62
64
|
{listItem}
|
|
@@ -54,7 +54,7 @@ export function MapFieldBinding({
|
|
|
54
54
|
{Object.entries(mapProperties)
|
|
55
55
|
.filter(([_, property]) => !isHidden(property))
|
|
56
56
|
.map(([entryKey, childProperty], index) => {
|
|
57
|
-
const
|
|
57
|
+
const fieldBindingProps = {
|
|
58
58
|
propertyKey: `${propertyKey}.${entryKey}`,
|
|
59
59
|
disabled,
|
|
60
60
|
property: childProperty,
|
|
@@ -70,7 +70,7 @@ export function MapFieldBinding({
|
|
|
70
70
|
<div key={`map-${propertyKey}-${index}`}>
|
|
71
71
|
<ErrorBoundary>
|
|
72
72
|
<PropertyFieldBinding
|
|
73
|
-
{...
|
|
73
|
+
{...fieldBindingProps}/>
|
|
74
74
|
</ErrorBoundary>
|
|
75
75
|
</div>
|
|
76
76
|
);
|
|
@@ -2,7 +2,7 @@ import React, { useState } from "react";
|
|
|
2
2
|
import { CMSType, FieldProps, ResolvedProperty } from "../../types";
|
|
3
3
|
import { FieldHelperText, FormikArrayContainer, LabelWithIconAndTooltip } from "../components";
|
|
4
4
|
import { ErrorBoundary } from "../../components";
|
|
5
|
-
import { getDefaultValueFor, getIconForProperty } from "../../util";
|
|
5
|
+
import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty } from "../../util";
|
|
6
6
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
7
7
|
import { ExpandablePanel, Typography } from "@firecms/ui";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
@@ -34,8 +34,17 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
34
34
|
if (!property.of)
|
|
35
35
|
throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
let resolvedProperties = property.resolvedProperties;
|
|
38
|
+
if (!resolvedProperties) {
|
|
39
|
+
resolvedProperties = getArrayResolvedProperties({
|
|
40
|
+
propertyValue: value,
|
|
41
|
+
propertyKey,
|
|
42
|
+
property,
|
|
43
|
+
ignoreMissingFields: false
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
// if (!resolvedProperties || !Array.isArray(resolvedProperties))
|
|
47
|
+
// throw Error("RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'");
|
|
39
48
|
|
|
40
49
|
const expanded = property.expanded === undefined ? true : property.expanded;
|
|
41
50
|
const ofProperty: ResolvedProperty<CMSType[]> = property.of as ResolvedProperty<CMSType[]>;
|
|
@@ -49,7 +58,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
49
58
|
});
|
|
50
59
|
|
|
51
60
|
const buildEntry = (index: number, internalId: number) => {
|
|
52
|
-
const childProperty =
|
|
61
|
+
const childProperty = resolvedProperties[index] ?? ofProperty;
|
|
53
62
|
const fieldProps = {
|
|
54
63
|
propertyKey: `${propertyKey}.${index}`,
|
|
55
64
|
disabled,
|
|
@@ -49,50 +49,51 @@ export function SelectFieldBinding<T extends EnumType>({
|
|
|
49
49
|
return (
|
|
50
50
|
<>
|
|
51
51
|
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
52
|
+
<Select
|
|
53
|
+
size={size === "medium" ? "medium" : "small"}
|
|
54
|
+
value={value !== undefined && value != null ? value.toString() : ""}
|
|
55
|
+
disabled={disabled}
|
|
56
|
+
position="item-aligned"
|
|
57
|
+
inputClassName={cls("w-full")}
|
|
58
|
+
label={
|
|
59
|
+
<PropertyIdCopyTooltip propertyKey={propertyKey}>
|
|
60
|
+
<LabelWithIcon
|
|
61
|
+
icon={getIconForProperty(property, "small")}
|
|
62
|
+
required={property.validation?.required}
|
|
63
|
+
title={property.name}
|
|
64
|
+
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}
|
|
65
|
+
/>
|
|
66
|
+
</PropertyIdCopyTooltip>}
|
|
67
|
+
endAdornment={
|
|
68
|
+
property.clearable && <IconButton
|
|
69
|
+
onClick={handleClearClick}>
|
|
70
|
+
<ClearIcon/>
|
|
71
|
+
</IconButton>
|
|
72
|
+
}
|
|
73
|
+
onValueChange={(updatedValue: string) => {
|
|
74
|
+
const newValue = updatedValue
|
|
75
|
+
? (property.dataType === "number" ? parseFloat(updatedValue) : updatedValue)
|
|
76
|
+
: null;
|
|
77
|
+
return setValue(newValue as T);
|
|
78
|
+
}}
|
|
79
|
+
renderValue={(enumKey: any) => {
|
|
80
|
+
return <EnumValuesChip
|
|
81
|
+
enumKey={enumKey}
|
|
82
|
+
enumValues={enumValues}
|
|
83
|
+
size={size}/>;
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
{enumValues && enumValues.map((option) => {
|
|
87
|
+
return <SelectItem
|
|
88
|
+
key={option.id}
|
|
89
|
+
value={String(option.id)}>
|
|
90
|
+
<EnumValuesChip
|
|
91
|
+
enumKey={String(option.id)}
|
|
80
92
|
enumValues={enumValues}
|
|
81
|
-
size={size}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return <SelectItem
|
|
86
|
-
key={option.id}
|
|
87
|
-
value={String(option.id)}>
|
|
88
|
-
<EnumValuesChip
|
|
89
|
-
enumKey={String(option.id)}
|
|
90
|
-
enumValues={enumValues}
|
|
91
|
-
size={size}/>
|
|
92
|
-
</SelectItem>
|
|
93
|
-
})}
|
|
94
|
-
</Select>
|
|
95
|
-
</PropertyIdCopyTooltip>
|
|
93
|
+
size={size}/>
|
|
94
|
+
</SelectItem>
|
|
95
|
+
})}
|
|
96
|
+
</Select>
|
|
96
97
|
|
|
97
98
|
<FieldHelperText includeDescription={includeDescription}
|
|
98
99
|
showError={showError}
|
package/src/form/index.tsx
CHANGED
|
@@ -34,10 +34,5 @@ export {
|
|
|
34
34
|
|
|
35
35
|
export * from "./components";
|
|
36
36
|
|
|
37
|
-
// export type { EntityFormProps } from "./EntityForm";
|
|
38
|
-
// export {
|
|
39
|
-
// EntityForm
|
|
40
|
-
// } from "./EntityForm";
|
|
41
|
-
|
|
42
37
|
export { PropertyFieldBinding } from "./PropertyFieldBinding";
|
|
43
38
|
export * from "./useClearRestoreValue";
|
package/src/types/datasource.ts
CHANGED
package/src/types/properties.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type DataType<T extends CMSType = CMSType> =
|
|
|
18
18
|
T extends Vector ? "vector" :
|
|
19
19
|
T extends EntityReference ? "reference" :
|
|
20
20
|
T extends Array<CMSType> ? "array" :
|
|
21
|
-
T extends Record<string,
|
|
21
|
+
T extends Record<string, CMSType> ? "map" : never;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* @group Entity properties
|
package/src/util/resolutions.ts
CHANGED
|
@@ -217,6 +217,38 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
|
|
|
217
217
|
: null;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
export function getArrayResolvedProperties<M>({
|
|
221
|
+
propertyKey,
|
|
222
|
+
propertyValue,
|
|
223
|
+
property,
|
|
224
|
+
...props
|
|
225
|
+
}: {
|
|
226
|
+
propertyValue: any,
|
|
227
|
+
propertyKey?: string,
|
|
228
|
+
property: ArrayProperty<any> | ResolvedArrayProperty<any>,
|
|
229
|
+
ignoreMissingFields: boolean,
|
|
230
|
+
values?: Partial<M>;
|
|
231
|
+
previousValues?: Partial<M>;
|
|
232
|
+
path?: string;
|
|
233
|
+
entityId?: string;
|
|
234
|
+
index?: number;
|
|
235
|
+
fromBuilder?: boolean;
|
|
236
|
+
fields?: Record<string, PropertyConfig>
|
|
237
|
+
}) {
|
|
238
|
+
|
|
239
|
+
const of = property.of;
|
|
240
|
+
return Array.isArray(propertyValue)
|
|
241
|
+
? propertyValue.map((v: any, index: number) => {
|
|
242
|
+
return resolveProperty({
|
|
243
|
+
propertyKey: `${propertyKey}.${index}`,
|
|
244
|
+
propertyOrBuilder: of,
|
|
245
|
+
...props,
|
|
246
|
+
index
|
|
247
|
+
});
|
|
248
|
+
}).filter(e => Boolean(e)) as ResolvedProperty[]
|
|
249
|
+
: [];
|
|
250
|
+
}
|
|
251
|
+
|
|
220
252
|
export function resolveArrayProperty<T extends any[], M>({
|
|
221
253
|
propertyKey,
|
|
222
254
|
property,
|
|
@@ -254,17 +286,13 @@ export function resolveArrayProperty<T extends any[], M>({
|
|
|
254
286
|
} as ResolvedArrayProperty;
|
|
255
287
|
} else {
|
|
256
288
|
const of = property.of;
|
|
257
|
-
const resolvedProperties
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
index
|
|
265
|
-
});
|
|
266
|
-
}).filter(e => Boolean(e)) as ResolvedProperty[]
|
|
267
|
-
: [];
|
|
289
|
+
const resolvedProperties = getArrayResolvedProperties({
|
|
290
|
+
propertyValue,
|
|
291
|
+
propertyKey,
|
|
292
|
+
property,
|
|
293
|
+
ignoreMissingFields,
|
|
294
|
+
...props
|
|
295
|
+
});
|
|
268
296
|
const ofProperty = resolveProperty({
|
|
269
297
|
propertyOrBuilder: of,
|
|
270
298
|
ignoreMissingFields,
|