@firecms/collection_editor 3.0.0-beta.2-pre.5 → 3.0.0-beta.2
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/index.es.js +783 -772
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/ui/RootCollectionSuggestions.tsx +1 -1
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +10 -12
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +0 -1
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +69 -66
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +10 -7
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +18 -16
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/collection_editor",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-beta.2
|
|
4
|
+
"version": "3.0.0-beta.2",
|
|
5
5
|
"main": "./dist/index.umd.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"source": "src/index.ts",
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@firecms/data_import_export": "^3.0.0-beta.2
|
|
11
|
-
"@firecms/formex": "^3.0.0-beta.2
|
|
12
|
-
"@firecms/schema_inference": "^3.0.0-beta.2
|
|
13
|
-
"@firecms/ui": "^3.0.0-beta.2
|
|
10
|
+
"@firecms/data_import_export": "^3.0.0-beta.2",
|
|
11
|
+
"@firecms/formex": "^3.0.0-beta.2",
|
|
12
|
+
"@firecms/schema_inference": "^3.0.0-beta.2",
|
|
13
|
+
"@firecms/ui": "^3.0.0-beta.2",
|
|
14
14
|
"json5": "^2.2.3",
|
|
15
15
|
"prism-react-renderer": "^2.3.1"
|
|
16
16
|
},
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"publishConfig": {
|
|
74
74
|
"access": "public"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "9c3561bc09311f2339bb6fa224c88a62d3b19617"
|
|
77
77
|
}
|
|
@@ -26,7 +26,7 @@ export function RootCollectionSuggestions({ introMode }: { introMode?: "new_proj
|
|
|
26
26
|
className={"flex flex-col gap-1 p-2 my-4"}>
|
|
27
27
|
|
|
28
28
|
{!introMode && <Typography variant={"body2"} color={"secondary"}>
|
|
29
|
-
Create a collection from your data:
|
|
29
|
+
Create a collection <b>automatically</b> from your data:
|
|
30
30
|
</Typography>}
|
|
31
31
|
|
|
32
32
|
{introMode === "existing_project" && <Typography>
|
|
@@ -96,16 +96,14 @@ export function CollectionDetailsForm({
|
|
|
96
96
|
const isSubcollection = !!parentCollection;
|
|
97
97
|
|
|
98
98
|
let customIdValue: "true" | "false" | "optional" | "code_defined" | undefined;
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
customIdValue = "optional";
|
|
108
|
-
}
|
|
99
|
+
if (typeof values.customId === "object") {
|
|
100
|
+
customIdValue = "code_defined";
|
|
101
|
+
} else if (values.customId === true) {
|
|
102
|
+
customIdValue = "true";
|
|
103
|
+
} else if (values.customId === false) {
|
|
104
|
+
customIdValue = "false";
|
|
105
|
+
} else if (values.customId === "optional") {
|
|
106
|
+
customIdValue = "optional";
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
const showErrors = submitCount > 0;
|
|
@@ -226,7 +224,7 @@ export function CollectionDetailsForm({
|
|
|
226
224
|
<div className={"col-span-12"}>
|
|
227
225
|
<TextField
|
|
228
226
|
error={showErrors && Boolean(errors.singularName)}
|
|
229
|
-
|
|
227
|
+
name={"singularName"}
|
|
230
228
|
aria-describedby={"singularName-helper"}
|
|
231
229
|
onChange={(e) => {
|
|
232
230
|
setFieldTouched("singularName", true);
|
|
@@ -241,7 +239,7 @@ export function CollectionDetailsForm({
|
|
|
241
239
|
<div className={"col-span-12"}>
|
|
242
240
|
<TextField
|
|
243
241
|
error={showErrors && Boolean(errors.description)}
|
|
244
|
-
|
|
242
|
+
name="description"
|
|
245
243
|
value={values.description ?? ""}
|
|
246
244
|
onChange={handleChange}
|
|
247
245
|
multiline
|
|
@@ -261,7 +261,6 @@ function CollectionEditorInternal<M extends Record<string, any>>({
|
|
|
261
261
|
const importConfig = useImportConfig();
|
|
262
262
|
const navigation = useNavigationController();
|
|
263
263
|
const snackbarController = useSnackbarController();
|
|
264
|
-
console.log({ importConfig })
|
|
265
264
|
|
|
266
265
|
// Use this ref to store which properties have errors
|
|
267
266
|
const propertyErrorsRef = useRef({});
|
|
@@ -53,7 +53,7 @@ export function SubcollectionsEditTab({
|
|
|
53
53
|
|
|
54
54
|
const [currentDialog, setCurrentDialog] = React.useState<{
|
|
55
55
|
isNewCollection: boolean,
|
|
56
|
-
|
|
56
|
+
editedCollectionId?: string,
|
|
57
57
|
}>();
|
|
58
58
|
|
|
59
59
|
const {
|
|
@@ -78,52 +78,53 @@ export function SubcollectionsEditTab({
|
|
|
78
78
|
Subcollections of {values.name}
|
|
79
79
|
</Typography>
|
|
80
80
|
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
81
|
+
<Paper className={"flex flex-col gap-4 p-2 w-full"}>
|
|
82
|
+
{subcollections && subcollections.length > 0 && <Table>
|
|
83
|
+
<TableBody>
|
|
84
|
+
{subcollections.map((subcollection) => (
|
|
85
|
+
<TableRow key={subcollection.path}
|
|
86
|
+
onClick={() => setCurrentDialog({
|
|
87
|
+
isNewCollection: false,
|
|
88
|
+
editedCollectionId: subcollection.id
|
|
89
|
+
})}>
|
|
90
|
+
<TableCell
|
|
91
|
+
align="left">
|
|
92
|
+
<Typography variant={"subtitle2"} className={"flex-grow"}>
|
|
93
|
+
{subcollection.name}
|
|
94
|
+
</Typography>
|
|
95
|
+
</TableCell>
|
|
96
|
+
<TableCell
|
|
97
|
+
align="right">
|
|
98
|
+
<Tooltip title={"Remove"}>
|
|
99
|
+
<IconButton size="small"
|
|
100
|
+
onClick={(e) => {
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
e.stopPropagation();
|
|
103
|
+
setSubcollectionToDelete(subcollection.id);
|
|
104
|
+
}}
|
|
105
|
+
color="inherit">
|
|
106
|
+
<DeleteIcon size={"small"}/>
|
|
107
|
+
</IconButton>
|
|
108
|
+
</Tooltip>
|
|
109
|
+
</TableCell>
|
|
110
|
+
</TableRow>
|
|
111
|
+
))}
|
|
112
|
+
</TableBody>
|
|
113
|
+
</Table>}
|
|
114
|
+
|
|
115
|
+
<Button
|
|
116
|
+
onClick={() => {
|
|
117
|
+
setCurrentDialog({
|
|
118
|
+
isNewCollection: true
|
|
119
|
+
});
|
|
120
|
+
}}
|
|
121
|
+
variant={"text"}
|
|
122
|
+
startIcon={<AddIcon/>}>
|
|
123
|
+
Add subcollection
|
|
124
|
+
</Button>
|
|
125
|
+
|
|
126
|
+
</Paper>
|
|
116
127
|
|
|
117
|
-
<Button
|
|
118
|
-
onClick={() => {
|
|
119
|
-
setCurrentDialog({
|
|
120
|
-
isNewCollection: true
|
|
121
|
-
});
|
|
122
|
-
}}
|
|
123
|
-
variant={"outlined"}
|
|
124
|
-
startIcon={<AddIcon/>}>
|
|
125
|
-
Add subcollection
|
|
126
|
-
</Button>
|
|
127
128
|
</div>
|
|
128
129
|
|
|
129
130
|
<div className={"flex-grow flex flex-col gap-4 items-start"}>
|
|
@@ -131,7 +132,19 @@ export function SubcollectionsEditTab({
|
|
|
131
132
|
Custom views
|
|
132
133
|
</Typography>
|
|
133
134
|
|
|
134
|
-
|
|
135
|
+
|
|
136
|
+
{totalEntityViews === 0 &&
|
|
137
|
+
<Alert action={<Button variant="text"
|
|
138
|
+
size={"small"}
|
|
139
|
+
href={"https://firecms.co/docs/customization_quickstart"}
|
|
140
|
+
component={"a"}
|
|
141
|
+
rel="noopener noreferrer"
|
|
142
|
+
target="_blank">More info</Button>}>
|
|
143
|
+
Define your own custom views by uploading it with the CLI.
|
|
144
|
+
</Alert>
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
{<>
|
|
135
148
|
<Paper className={"flex flex-col gap-4 p-2 w-full"}>
|
|
136
149
|
<Table>
|
|
137
150
|
<TableBody>
|
|
@@ -175,29 +188,19 @@ export function SubcollectionsEditTab({
|
|
|
175
188
|
))}
|
|
176
189
|
</TableBody>
|
|
177
190
|
</Table>
|
|
191
|
+
|
|
192
|
+
<Button
|
|
193
|
+
onClick={() => {
|
|
194
|
+
setAddEntityViewDialogOpen(true);
|
|
195
|
+
}}
|
|
196
|
+
variant={"text"}
|
|
197
|
+
startIcon={<AddIcon/>}>
|
|
198
|
+
Add custom entity view
|
|
199
|
+
</Button>
|
|
178
200
|
</Paper>
|
|
179
201
|
|
|
180
202
|
</>}
|
|
181
203
|
|
|
182
|
-
{totalEntityViews === 0 &&
|
|
183
|
-
<Alert action={<Button variant="text"
|
|
184
|
-
size={"small"}
|
|
185
|
-
href={"https://firecms.co/docs/customization_quickstart"}
|
|
186
|
-
component={"a"}
|
|
187
|
-
rel="noopener noreferrer"
|
|
188
|
-
target="_blank">More info</Button>}>
|
|
189
|
-
Define your own custom views by uploading it with the CLI.
|
|
190
|
-
</Alert>
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
<Button
|
|
194
|
-
onClick={() => {
|
|
195
|
-
setAddEntityViewDialogOpen(true);
|
|
196
|
-
}}
|
|
197
|
-
variant={"outlined"}
|
|
198
|
-
startIcon={<AddIcon/>}>
|
|
199
|
-
Add custom entity view
|
|
200
|
-
</Button>
|
|
201
204
|
|
|
202
205
|
</div>
|
|
203
206
|
|
|
@@ -23,19 +23,22 @@ export function BlockPropertyField({ disabled, getData, allowDataInference, prop
|
|
|
23
23
|
const [selectedPropertyKey, setSelectedPropertyKey] = useState<string | undefined>();
|
|
24
24
|
const [selectedPropertyNamespace, setSelectedPropertyNamespace] = useState<string | undefined>();
|
|
25
25
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
const onPropertyChanged = ({
|
|
27
|
+
id,
|
|
28
|
+
property
|
|
29
|
+
}: { id?: string, property: Property }) => {
|
|
30
30
|
if (!id)
|
|
31
31
|
throw Error();
|
|
32
|
+
|
|
32
33
|
setFieldValue("oneOf.properties", {
|
|
33
34
|
...(values.oneOf?.properties ?? {}),
|
|
34
35
|
[id]: property
|
|
35
36
|
}, false);
|
|
36
|
-
|
|
37
|
+
const currentPropertiesOrder = values.oneOf?.propertiesOrder ?? Object.keys(values.oneOf?.properties ?? {});
|
|
38
|
+
const newPropertiesOrder = currentPropertiesOrder.includes(id) ? currentPropertiesOrder : [...currentPropertiesOrder, id];
|
|
39
|
+
setFieldValue("oneOf.propertiesOrder", newPropertiesOrder, false);
|
|
37
40
|
setPropertyDialogOpen(false);
|
|
38
|
-
}
|
|
41
|
+
};
|
|
39
42
|
|
|
40
43
|
const selectedPropertyFullId = selectedPropertyKey ? getFullId(selectedPropertyKey, selectedPropertyNamespace) : undefined;
|
|
41
44
|
const selectedProperty = selectedPropertyFullId ? getIn(values.oneOf?.properties, selectedPropertyFullId.replaceAll(".", ".properties.")) : undefined;
|
|
@@ -127,7 +130,7 @@ export function BlockPropertyField({ disabled, getData, allowDataInference, prop
|
|
|
127
130
|
existingProperty={Boolean(selectedPropertyKey)}
|
|
128
131
|
autoUpdateId={!selectedPropertyKey}
|
|
129
132
|
autoOpenTypeSelect={!selectedPropertyKey}
|
|
130
|
-
onPropertyChanged={
|
|
133
|
+
onPropertyChanged={onPropertyChanged}
|
|
131
134
|
existingPropertyKeys={selectedPropertyKey ? undefined : values.oneOf?.propertiesOrder}
|
|
132
135
|
propertyConfigs={propertyConfigs}/>}
|
|
133
136
|
|
|
@@ -25,19 +25,23 @@ export function MapPropertyField({ disabled, getData, allowDataInference, proper
|
|
|
25
25
|
const [selectedPropertyNamespace, setSelectedPropertyNamespace] = useState<string | undefined>();
|
|
26
26
|
|
|
27
27
|
const propertiesOrder = values.propertiesOrder ?? Object.keys(values.properties ?? {});
|
|
28
|
-
const onPropertyCreated =
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const onPropertyCreated = ({
|
|
29
|
+
id,
|
|
30
|
+
property
|
|
31
|
+
}: { id?: string, property: Property }) => {
|
|
32
32
|
if (!id)
|
|
33
33
|
throw Error();
|
|
34
34
|
setFieldValue("properties", {
|
|
35
35
|
...(values.properties ?? {}),
|
|
36
36
|
[id]: property
|
|
37
37
|
}, false);
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
const currentPropertiesOrder = values.propertiesOrder ?? Object.keys(values.properties ?? {});
|
|
40
|
+
const newPropertiesOrder = currentPropertiesOrder.includes(id) ? currentPropertiesOrder : [...currentPropertiesOrder, id];
|
|
41
|
+
setFieldValue("propertiesOrder", newPropertiesOrder, false);
|
|
42
|
+
|
|
39
43
|
setPropertyDialogOpen(false);
|
|
40
|
-
}
|
|
44
|
+
};
|
|
41
45
|
|
|
42
46
|
const deleteProperty = useCallback((propertyKey?: string, namespace?: string) => {
|
|
43
47
|
const fullId = propertyKey ? getFullId(propertyKey, namespace) : undefined;
|
|
@@ -60,15 +64,6 @@ export function MapPropertyField({ disabled, getData, allowDataInference, proper
|
|
|
60
64
|
const selectedPropertyFullId = selectedPropertyKey ? getFullId(selectedPropertyKey, selectedPropertyNamespace) : undefined;
|
|
61
65
|
const selectedProperty = selectedPropertyFullId ? getIn(values.properties, selectedPropertyFullId.replaceAll(".", ".properties.")) : undefined;
|
|
62
66
|
|
|
63
|
-
const addChildButton = <Button
|
|
64
|
-
color="primary"
|
|
65
|
-
variant={"outlined"}
|
|
66
|
-
onClick={() => setPropertyDialogOpen(true)}
|
|
67
|
-
startIcon={<AddIcon/>}
|
|
68
|
-
>
|
|
69
|
-
Add property to {values.name ?? "this group"}
|
|
70
|
-
</Button>;
|
|
71
|
-
|
|
72
67
|
const empty = !propertiesOrder || propertiesOrder.length < 1;
|
|
73
68
|
|
|
74
69
|
const onPropertyMove = useCallback((propertiesOrder: string[], namespace?: string) => {
|
|
@@ -80,7 +75,14 @@ export function MapPropertyField({ disabled, getData, allowDataInference, proper
|
|
|
80
75
|
<div className={"col-span-12"}>
|
|
81
76
|
<div className="flex justify-between items-end my-4">
|
|
82
77
|
<Typography variant={"subtitle2"}>Properties in this group</Typography>
|
|
83
|
-
|
|
78
|
+
<Button
|
|
79
|
+
color="primary"
|
|
80
|
+
variant={"outlined"}
|
|
81
|
+
onClick={() => setPropertyDialogOpen(true)}
|
|
82
|
+
startIcon={<AddIcon/>}
|
|
83
|
+
>
|
|
84
|
+
Add property to {values.name ?? "this group"}
|
|
85
|
+
</Button>
|
|
84
86
|
</div>
|
|
85
87
|
<Paper className="p-2 pl-8">
|
|
86
88
|
<PropertyTree
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useState } from "react";
|
|
2
2
|
import { ArrayProperty, getFieldConfig, Property, PropertyConfig } from "@firecms/core";
|
|
3
3
|
import { Button, Paper, Typography } from "@firecms/ui";
|
|
4
4
|
import { Field, getIn, useFormex } from "@firecms/formex";
|