@firecms/collection_editor 3.0.0-beta.13 → 3.0.0-beta.15
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 +165 -1
- package/dist/ConfigControllerProvider.d.ts +0 -1
- package/dist/index.es.js +1620 -948
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1616 -947
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +0 -1
- package/dist/types/collection_inference.d.ts +3 -0
- package/dist/types/config_controller.d.ts +3 -1
- package/dist/ui/EditorEntityAction.d.ts +2 -0
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +1 -1
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -1
- package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +4 -0
- package/dist/ui/collection_editor/EntityActionsSelectDialog.d.ts +4 -0
- package/dist/ui/collection_editor/PropertyTree.d.ts +2 -3
- package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +2 -1
- package/dist/useCollectionEditorPlugin.d.ts +3 -3
- package/package.json +8 -9
- package/src/ConfigControllerProvider.tsx +0 -5
- package/src/types/collection_editor_controller.tsx +0 -2
- package/src/types/collection_inference.ts +3 -0
- package/src/types/config_controller.tsx +4 -1
- package/src/ui/EditorCollectionAction.tsx +2 -7
- package/src/ui/EditorEntityAction.tsx +51 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +2 -1
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +69 -37
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +18 -5
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +15 -25
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +8 -6
- package/src/ui/collection_editor/EntityActionsEditTab.tsx +163 -0
- package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +41 -0
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -2
- package/src/ui/collection_editor/GetCodeDialog.tsx +5 -3
- package/src/ui/collection_editor/PropertyEditView.tsx +11 -3
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -0
- package/src/ui/collection_editor/PropertyTree.tsx +183 -139
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +6 -2
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +1 -1
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +5 -3
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +2 -0
- package/src/ui/collection_editor/utils/supported_fields.tsx +1 -0
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +9 -0
- package/src/useCollectionEditorPlugin.tsx +12 -7
- package/src/utils/collections.ts +15 -5
|
@@ -37,18 +37,6 @@ export function CollectionEditorWelcomeView({
|
|
|
37
37
|
}
|
|
38
38
|
}, [existingCollectionPaths, path, pathSuggestions]);
|
|
39
39
|
|
|
40
|
-
// const {
|
|
41
|
-
// values,
|
|
42
|
-
// setFieldValue,
|
|
43
|
-
// setValues,
|
|
44
|
-
// handleChange,
|
|
45
|
-
// touched,
|
|
46
|
-
// errors,
|
|
47
|
-
// setFieldTouched,
|
|
48
|
-
// isSubmitting,
|
|
49
|
-
// submitCount
|
|
50
|
-
// } = useFormex<EntityCollection>();
|
|
51
|
-
|
|
52
40
|
const {
|
|
53
41
|
values,
|
|
54
42
|
setFieldValue,
|
|
@@ -56,6 +44,11 @@ export function CollectionEditorWelcomeView({
|
|
|
56
44
|
submitCount
|
|
57
45
|
} = useFormex<EntityCollection>();
|
|
58
46
|
|
|
47
|
+
const noSuggestions = !loadingPathSuggestions && (filteredPathSuggestions ?? [])?.length === 0;
|
|
48
|
+
if (!noSuggestions) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
59
52
|
return (
|
|
60
53
|
<div className={"overflow-auto my-auto"}>
|
|
61
54
|
<Container maxWidth={"4xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
|
|
@@ -96,12 +89,11 @@ export function CollectionEditorWelcomeView({
|
|
|
96
89
|
{suggestion}
|
|
97
90
|
</Chip>
|
|
98
91
|
))}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
92
|
+
{(filteredPathSuggestions ?? []).length === 0 && !loadingPathSuggestions && <Typography
|
|
93
|
+
variant={"caption"}
|
|
94
|
+
color={"secondary"}>
|
|
95
|
+
No existing paths found
|
|
96
|
+
</Typography>}
|
|
105
97
|
|
|
106
98
|
</div>
|
|
107
99
|
|
|
@@ -116,28 +108,29 @@ export function CollectionEditorWelcomeView({
|
|
|
116
108
|
<div className={"flex gap-4"}>
|
|
117
109
|
<TemplateButton title={"Products"}
|
|
118
110
|
subtitle={"A collection of products with images, prices and stock"}
|
|
119
|
-
icon={<Icon size={"small"}
|
|
111
|
+
icon={<Icon size={"small"}
|
|
112
|
+
iconKey={productsCollectionTemplate.icon! as string}/>}
|
|
120
113
|
onClick={() => {
|
|
121
114
|
setValues(productsCollectionTemplate);
|
|
122
115
|
onContinue();
|
|
123
116
|
}}/>
|
|
124
117
|
<TemplateButton title={"Users"}
|
|
125
118
|
subtitle={"A collection of users with emails, names and roles"}
|
|
126
|
-
icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon!}/>}
|
|
119
|
+
icon={<Icon size={"small"} iconKey={usersCollectionTemplate.icon! as string}/>}
|
|
127
120
|
onClick={() => {
|
|
128
121
|
setValues(usersCollectionTemplate);
|
|
129
122
|
onContinue();
|
|
130
123
|
}}/>
|
|
131
124
|
<TemplateButton title={"Blog posts"}
|
|
132
125
|
subtitle={"A collection of blog posts with images, authors and complex content"}
|
|
133
|
-
icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon!}/>}
|
|
126
|
+
icon={<Icon size={"small"} iconKey={blogCollectionTemplate.icon! as string}/>}
|
|
134
127
|
onClick={() => {
|
|
135
128
|
setValues(blogCollectionTemplate);
|
|
136
129
|
onContinue();
|
|
137
130
|
}}/>
|
|
138
131
|
<TemplateButton title={"Pages"}
|
|
139
132
|
subtitle={"A collection of pages with images, authors and complex content"}
|
|
140
|
-
icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon!}/>}
|
|
133
|
+
icon={<Icon size={"small"} iconKey={pagesCollectionTemplate.icon! as string}/>}
|
|
141
134
|
onClick={() => {
|
|
142
135
|
setValues(pagesCollectionTemplate);
|
|
143
136
|
onContinue();
|
|
@@ -202,9 +195,6 @@ export function TemplateButton({
|
|
|
202
195
|
<Typography variant={"subtitle1"}>
|
|
203
196
|
{title}
|
|
204
197
|
</Typography>
|
|
205
|
-
{/*<Typography>*/}
|
|
206
|
-
{/* {subtitle}*/}
|
|
207
|
-
{/*</Typography>*/}
|
|
208
198
|
|
|
209
199
|
</div>
|
|
210
200
|
</Card>
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
DebouncedTextField,
|
|
25
25
|
defaultBorderMixin,
|
|
26
26
|
IconButton,
|
|
27
|
-
Paper,
|
|
28
27
|
Tooltip,
|
|
29
28
|
Typography,
|
|
30
29
|
} from "@firecms/ui";
|
|
@@ -45,7 +44,7 @@ type CollectionEditorFormProps = {
|
|
|
45
44
|
extraIcon: React.ReactNode;
|
|
46
45
|
getUser?: (uid: string) => User | null;
|
|
47
46
|
getData?: () => Promise<object[]>;
|
|
48
|
-
doCollectionInference
|
|
47
|
+
doCollectionInference?: (collection: PersistedCollection) => Promise<Partial<EntityCollection> | null> | undefined;
|
|
49
48
|
propertyConfigs: Record<string, PropertyConfig>;
|
|
50
49
|
collectionEditable: boolean;
|
|
51
50
|
};
|
|
@@ -108,6 +107,8 @@ export function CollectionPropertiesEditorForm({
|
|
|
108
107
|
return;
|
|
109
108
|
|
|
110
109
|
setInferringProperties(true);
|
|
110
|
+
|
|
111
|
+
console.debug("CollectionEditor: inferring properties from data", doCollectionInference, values);
|
|
111
112
|
// @ts-ignore
|
|
112
113
|
doCollectionInference(values)
|
|
113
114
|
.then((newCollection) => {
|
|
@@ -310,8 +311,9 @@ export function CollectionPropertiesEditorForm({
|
|
|
310
311
|
};
|
|
311
312
|
|
|
312
313
|
const body = (
|
|
313
|
-
<div className={"grid grid-cols-12 gap-2 h-full bg-
|
|
314
|
+
<div className={"grid grid-cols-12 gap-2 h-full bg-white dark:bg-surface-950"}>
|
|
314
315
|
<div className={cls(
|
|
316
|
+
"bg-surface-50 dark:bg-surface-900",
|
|
315
317
|
"p-4 md:p-8 pb-20 md:pb-20",
|
|
316
318
|
"col-span-12 lg:col-span-5 h-full overflow-auto",
|
|
317
319
|
!asDialog && "border-r " + defaultBorderMixin
|
|
@@ -401,8 +403,8 @@ export function CollectionPropertiesEditorForm({
|
|
|
401
403
|
|
|
402
404
|
{!asDialog &&
|
|
403
405
|
<div className={"col-span-12 lg:col-span-7 p-4 md:py-8 md:px-4 h-full overflow-auto pb-20 md:pb-20"}>
|
|
404
|
-
<
|
|
405
|
-
className="sticky top-8
|
|
406
|
+
<div
|
|
407
|
+
className="sticky top-8 min-h-full w-full flex flex-col justify-center">
|
|
406
408
|
|
|
407
409
|
{selectedPropertyFullId &&
|
|
408
410
|
selectedProperty &&
|
|
@@ -446,7 +448,7 @@ export function CollectionPropertiesEditorForm({
|
|
|
446
448
|
<Typography variant={"label"} className="flex items-center justify-center">
|
|
447
449
|
{"This property is defined as a property builder in code"}
|
|
448
450
|
</Typography>}
|
|
449
|
-
</
|
|
451
|
+
</div>
|
|
450
452
|
</div>}
|
|
451
453
|
|
|
452
454
|
{asDialog && <PropertyFormDialog
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
ConfirmationDialog,
|
|
4
|
+
EntityAction,
|
|
5
|
+
EntityCollection,
|
|
6
|
+
resolveEntityAction,
|
|
7
|
+
useCustomizationController
|
|
8
|
+
} from "@firecms/core";
|
|
9
|
+
import {
|
|
10
|
+
AddIcon,
|
|
11
|
+
Alert,
|
|
12
|
+
Button,
|
|
13
|
+
Container,
|
|
14
|
+
DeleteIcon,
|
|
15
|
+
IconButton,
|
|
16
|
+
Paper,
|
|
17
|
+
Table,
|
|
18
|
+
TableBody,
|
|
19
|
+
TableCell,
|
|
20
|
+
TableRow,
|
|
21
|
+
Tooltip,
|
|
22
|
+
Typography,
|
|
23
|
+
} from "@firecms/ui";
|
|
24
|
+
import { PersistedCollection } from "../../types/persisted_collection";
|
|
25
|
+
import { useFormex } from "@firecms/formex";
|
|
26
|
+
import { EntityActionsSelectDialog } from "./EntityActionsSelectDialog";
|
|
27
|
+
|
|
28
|
+
export function EntityActionsEditTab({
|
|
29
|
+
collection,
|
|
30
|
+
}: {
|
|
31
|
+
collection: PersistedCollection,
|
|
32
|
+
}) {
|
|
33
|
+
|
|
34
|
+
const { entityActions: contextEntityActions } = useCustomizationController();
|
|
35
|
+
|
|
36
|
+
const [addEntityActionDialogOpen, setAddEntityActionDialogOpen] = React.useState<boolean>(false);
|
|
37
|
+
const [actionToDelete, setActionToDelete] = React.useState<string | undefined>();
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
values,
|
|
41
|
+
setFieldValue
|
|
42
|
+
} = useFormex<EntityCollection>();
|
|
43
|
+
|
|
44
|
+
const resolvedEntityActions = values.entityActions?.filter((e): e is string => typeof e === "string")
|
|
45
|
+
.map(e => resolveEntityAction(e, contextEntityActions))
|
|
46
|
+
.filter(Boolean) as EntityAction<any>[] ?? [];
|
|
47
|
+
const hardCodedEntityActions = collection.entityActions?.filter((e): e is EntityAction<any> => typeof e !== "string") ?? [];
|
|
48
|
+
const totalEntityActions = resolvedEntityActions.length + hardCodedEntityActions.length;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className={"overflow-auto my-auto"}>
|
|
52
|
+
<Container maxWidth={"2xl"} className={"flex flex-col gap-4 p-8 m-auto"}>
|
|
53
|
+
<div className={"flex flex-col gap-16"}>
|
|
54
|
+
<div className={"flex-grow flex flex-col gap-4 items-start"}>
|
|
55
|
+
<Typography variant={"h5"}>
|
|
56
|
+
Custom actions
|
|
57
|
+
</Typography>
|
|
58
|
+
|
|
59
|
+
{totalEntityActions === 0 &&
|
|
60
|
+
<Alert action={<Button variant="text"
|
|
61
|
+
size={"small"}
|
|
62
|
+
href={"https://firecms.co/docs/custom_actions"}
|
|
63
|
+
component={"a"}
|
|
64
|
+
rel="noopener noreferrer"
|
|
65
|
+
target="_blank">More info</Button>}>
|
|
66
|
+
Define your own custom actions by uploading them with the CLI.
|
|
67
|
+
</Alert>
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
{<>
|
|
71
|
+
<Paper className={"flex flex-col gap-4 p-2 w-full"}>
|
|
72
|
+
<Table>
|
|
73
|
+
<TableBody>
|
|
74
|
+
{resolvedEntityActions.map((action) => (
|
|
75
|
+
<TableRow key={action.key}>
|
|
76
|
+
<TableCell
|
|
77
|
+
align="left">
|
|
78
|
+
<Typography variant={"subtitle2"} className={"flex-grow"}>
|
|
79
|
+
{action.name}
|
|
80
|
+
</Typography>
|
|
81
|
+
</TableCell>
|
|
82
|
+
<TableCell
|
|
83
|
+
align="right">
|
|
84
|
+
<Tooltip title={"Remove"}
|
|
85
|
+
asChild={true}>
|
|
86
|
+
<IconButton size="small"
|
|
87
|
+
onClick={(e) => {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
e.stopPropagation();
|
|
90
|
+
setActionToDelete(action.key);
|
|
91
|
+
}}
|
|
92
|
+
color="inherit">
|
|
93
|
+
<DeleteIcon size={"small"}/>
|
|
94
|
+
</IconButton>
|
|
95
|
+
</Tooltip>
|
|
96
|
+
</TableCell>
|
|
97
|
+
</TableRow>
|
|
98
|
+
))}
|
|
99
|
+
{hardCodedEntityActions.map((action) => (
|
|
100
|
+
<TableRow key={action.key}>
|
|
101
|
+
<TableCell
|
|
102
|
+
align="left">
|
|
103
|
+
<Typography variant={"subtitle2"} className={"flex-grow"}>
|
|
104
|
+
{action.name}
|
|
105
|
+
</Typography>
|
|
106
|
+
<Typography variant={"caption"} className={"flex-grow"}>
|
|
107
|
+
This action is defined in code with
|
|
108
|
+
key <code>{action.key}</code>
|
|
109
|
+
</Typography>
|
|
110
|
+
</TableCell>
|
|
111
|
+
</TableRow>
|
|
112
|
+
))}
|
|
113
|
+
</TableBody>
|
|
114
|
+
</Table>
|
|
115
|
+
|
|
116
|
+
<Button
|
|
117
|
+
onClick={() => {
|
|
118
|
+
setAddEntityActionDialogOpen(true);
|
|
119
|
+
}}
|
|
120
|
+
variant={"text"}
|
|
121
|
+
startIcon={<AddIcon/>}>
|
|
122
|
+
Add custom entity action
|
|
123
|
+
</Button>
|
|
124
|
+
</Paper>
|
|
125
|
+
|
|
126
|
+
</>}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
</div>
|
|
132
|
+
</Container>
|
|
133
|
+
|
|
134
|
+
<div style={{ height: "52px" }}/>
|
|
135
|
+
|
|
136
|
+
{actionToDelete &&
|
|
137
|
+
<ConfirmationDialog open={Boolean(actionToDelete)}
|
|
138
|
+
onAccept={() => {
|
|
139
|
+
setFieldValue("entityActions", values.entityActions?.filter(e => e !== actionToDelete));
|
|
140
|
+
setActionToDelete(undefined);
|
|
141
|
+
}}
|
|
142
|
+
onCancel={() => setActionToDelete(undefined)}
|
|
143
|
+
title={<>Remove this action?</>}
|
|
144
|
+
body={<>This will <b>not
|
|
145
|
+
delete any data</b>, only
|
|
146
|
+
the action in the CMS</>}/>}
|
|
147
|
+
|
|
148
|
+
<EntityActionsSelectDialog
|
|
149
|
+
open={addEntityActionDialogOpen}
|
|
150
|
+
onClose={(selectedActionKey) => {
|
|
151
|
+
if (selectedActionKey) {
|
|
152
|
+
console.log("Selected action key:", selectedActionKey);
|
|
153
|
+
const value = [...(values.entityActions ?? []), selectedActionKey]
|
|
154
|
+
// only actions that are defined in the registry
|
|
155
|
+
.filter((e): e is string => typeof e === "string" && (contextEntityActions ?? []).some(action => action.key === e));
|
|
156
|
+
;
|
|
157
|
+
setFieldValue("entityActions", value);
|
|
158
|
+
}
|
|
159
|
+
setAddEntityActionDialogOpen(false);
|
|
160
|
+
}}/>
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useCustomizationController } from "@firecms/core";
|
|
2
|
+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
|
|
3
|
+
import React from "react";
|
|
4
|
+
|
|
5
|
+
export function EntityActionsSelectDialog({
|
|
6
|
+
open,
|
|
7
|
+
onClose
|
|
8
|
+
}: { open: boolean, onClose: (selectedActionKey?: string) => void }) {
|
|
9
|
+
const {
|
|
10
|
+
entityActions
|
|
11
|
+
} = useCustomizationController();
|
|
12
|
+
|
|
13
|
+
return <Dialog
|
|
14
|
+
maxWidth={"md"}
|
|
15
|
+
open={open}>
|
|
16
|
+
<DialogTitle>Select custom action</DialogTitle>
|
|
17
|
+
<DialogContent className={"flex flex-col gap-4"}>
|
|
18
|
+
{entityActions?.map((action) => {
|
|
19
|
+
return <Button
|
|
20
|
+
key={action.key}
|
|
21
|
+
onClick={() => onClose(action.key)}
|
|
22
|
+
fullWidth
|
|
23
|
+
variant={"text"}
|
|
24
|
+
>
|
|
25
|
+
{action.name} ({action.key})
|
|
26
|
+
</Button>;
|
|
27
|
+
})}
|
|
28
|
+
{(entityActions ?? []).length === 0 &&
|
|
29
|
+
<Typography variant={"body2"}>
|
|
30
|
+
No custom actions defined. Define your custom actions in the customization settings, before using this
|
|
31
|
+
dialog.
|
|
32
|
+
</Typography>
|
|
33
|
+
}
|
|
34
|
+
</DialogContent>
|
|
35
|
+
<DialogActions>
|
|
36
|
+
<Button variant={"outlined"}
|
|
37
|
+
color={"primary"}
|
|
38
|
+
onClick={() => onClose()}>Cancel</Button>
|
|
39
|
+
</DialogActions>
|
|
40
|
+
</Dialog>
|
|
41
|
+
}
|
|
@@ -27,12 +27,15 @@ export function EntityCustomViewsSelectDialog({
|
|
|
27
27
|
})}
|
|
28
28
|
{(entityViews ?? []).length === 0 &&
|
|
29
29
|
<Typography variant={"body2"}>
|
|
30
|
-
No custom views defined
|
|
30
|
+
No custom views defined. Define your custom views in the customization settings, before using this
|
|
31
|
+
dialog.
|
|
31
32
|
</Typography>
|
|
32
33
|
}
|
|
33
34
|
</DialogContent>
|
|
34
35
|
<DialogActions>
|
|
35
|
-
<Button variant={"outlined"}
|
|
36
|
+
<Button variant={"outlined"}
|
|
37
|
+
color={"primary"}
|
|
38
|
+
onClick={() => onClose()}>Cancel</Button>
|
|
36
39
|
</DialogActions>
|
|
37
40
|
</Dialog>
|
|
38
41
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EntityCollection, isEmptyObject, useSnackbarController } from "@firecms/core";
|
|
2
|
-
import { Button, ContentCopyIcon, Dialog, DialogActions, DialogContent, DialogTitle, Typography
|
|
2
|
+
import { Button, ContentCopyIcon, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import JSON5 from "json5";
|
|
5
5
|
import { Highlight, themes } from "prism-react-renderer"
|
|
@@ -59,12 +59,13 @@ export function GetCodeDialog({
|
|
|
59
59
|
<Button
|
|
60
60
|
variant={"text"}
|
|
61
61
|
size={"small"}
|
|
62
|
+
color={"primary"}
|
|
62
63
|
onClick={(e) => {
|
|
63
64
|
e.stopPropagation();
|
|
64
65
|
e.preventDefault();
|
|
65
66
|
snackbarController.open({
|
|
66
67
|
type: "success",
|
|
67
|
-
message:
|
|
68
|
+
message: "Copied"
|
|
68
69
|
})
|
|
69
70
|
return navigator.clipboard.writeText(code);
|
|
70
71
|
}}>
|
|
@@ -133,7 +134,8 @@ function collectionToCode(collection: EntityCollection): object {
|
|
|
133
134
|
.map(([key, value]) => ({
|
|
134
135
|
[key]: propertyCleanup(value)
|
|
135
136
|
}))
|
|
136
|
-
.reduce((a, b) => ({ ...a,
|
|
137
|
+
.reduce((a, b) => ({ ...a,
|
|
138
|
+
...b }), {}),
|
|
137
139
|
subcollections: (collection.subcollections ?? []).map(collectionToCode)
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
DEFAULT_FIELD_CONFIGS,
|
|
8
8
|
getFieldConfig,
|
|
9
9
|
getFieldId,
|
|
10
|
-
isEmptyObject,
|
|
11
10
|
isPropertyBuilder,
|
|
12
11
|
isValidRegExp,
|
|
13
12
|
mergeDeep,
|
|
@@ -296,6 +295,7 @@ export function PropertyFormDialog({
|
|
|
296
295
|
|
|
297
296
|
{onCancel && <Button
|
|
298
297
|
variant={"text"}
|
|
298
|
+
color={"primary"}
|
|
299
299
|
onClick={() => {
|
|
300
300
|
onCancel();
|
|
301
301
|
formexRef.current?.resetForm();
|
|
@@ -384,7 +384,7 @@ function PropertyEditFormFields({
|
|
|
384
384
|
}, [deferredValues, includeIdAndTitle, propertyNamespace]);
|
|
385
385
|
|
|
386
386
|
useEffect(() => {
|
|
387
|
-
if (values?.id && onError
|
|
387
|
+
if (values?.id && onError) {
|
|
388
388
|
onError(values?.id, propertyNamespace, errors);
|
|
389
389
|
}
|
|
390
390
|
}, [errors, propertyNamespace, values?.id]);
|
|
@@ -462,6 +462,13 @@ function PropertyEditFormFields({
|
|
|
462
462
|
existing={existing}
|
|
463
463
|
multiple={false}
|
|
464
464
|
disabled={disabled}/>;
|
|
465
|
+
} else if (selectedFieldConfigId === "reference_as_string") {
|
|
466
|
+
childComponent =
|
|
467
|
+
<ReferencePropertyField showErrors={showErrors}
|
|
468
|
+
existing={existing}
|
|
469
|
+
asString={true}
|
|
470
|
+
multiple={false}
|
|
471
|
+
disabled={disabled}/>;
|
|
465
472
|
} else if (selectedFieldConfigId === "date_time") {
|
|
466
473
|
childComponent = <DateTimePropertyField disabled={disabled}/>;
|
|
467
474
|
} else if (selectedFieldConfigId === "multi_references") {
|
|
@@ -606,6 +613,7 @@ const WIDGET_TYPE_MAP: Record<PropertyConfigId, string> = {
|
|
|
606
613
|
file_upload: "File",
|
|
607
614
|
multi_file_upload: "File",
|
|
608
615
|
reference: "Reference",
|
|
616
|
+
reference_as_string: "Text",
|
|
609
617
|
multi_references: "Reference",
|
|
610
618
|
date_time: "Date",
|
|
611
619
|
group: "Group",
|
|
@@ -763,7 +771,7 @@ export function WidgetSelectViewItem({
|
|
|
763
771
|
|
|
764
772
|
return <Card
|
|
765
773
|
onClick={onClick}
|
|
766
|
-
className={"flex flex-row items-center px-4 py-2"}>
|
|
774
|
+
className={"flex flex-row items-center px-4 py-2 m-1"}>
|
|
767
775
|
<div
|
|
768
776
|
className={cls(
|
|
769
777
|
"flex flex-row items-center text-base min-h-[48px]",
|