@firecms/collection_editor 3.0.0-canary.28 → 3.0.0-canary.280
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/LICENSE +114 -21
- package/README.md +165 -1
- package/dist/ConfigControllerProvider.d.ts +1 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +10792 -4791
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +11458 -3
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +3 -2
- package/dist/types/collection_inference.d.ts +4 -1
- package/dist/types/config_controller.d.ts +3 -1
- package/dist/types/config_permissions.d.ts +2 -2
- package/dist/types/persisted_collection.d.ts +1 -1
- package/dist/ui/CollectionViewHeaderAction.d.ts +3 -2
- package/dist/ui/EditorCollectionActionStart.d.ts +2 -0
- package/dist/ui/EditorEntityAction.d.ts +2 -0
- package/dist/ui/PropertyAddColumnComponent.d.ts +3 -1
- package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +3 -1
- package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -2
- package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
- package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +2 -2
- 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/LayoutModeSwitch.d.ts +5 -0
- package/dist/ui/collection_editor/PropertyEditView.d.ts +8 -0
- package/dist/ui/collection_editor/PropertyTree.d.ts +11 -12
- package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +1 -1
- package/dist/ui/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
- package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +8 -1
- package/dist/ui/collection_editor/import/clean_import_data.d.ts +1 -1
- package/dist/ui/collection_editor/properties/MarkdownPropertyField.d.ts +4 -0
- package/dist/ui/collection_editor/properties/ReferencePropertyField.d.ts +2 -1
- package/dist/ui/collection_editor/properties/StringPropertyField.d.ts +1 -1
- package/dist/useCollectionEditorPlugin.d.ts +8 -11
- package/dist/utils/collections.d.ts +6 -0
- package/package.json +25 -37
- package/src/ConfigControllerProvider.tsx +64 -66
- package/src/index.ts +1 -0
- package/src/types/collection_editor_controller.tsx +6 -5
- package/src/types/collection_inference.ts +4 -1
- package/src/types/config_controller.tsx +4 -1
- package/src/types/config_permissions.ts +1 -1
- package/src/types/persisted_collection.ts +2 -3
- package/src/ui/CollectionViewHeaderAction.tsx +10 -5
- package/src/ui/EditorCollectionAction.tsx +12 -70
- package/src/ui/EditorCollectionActionStart.tsx +87 -0
- package/src/ui/EditorEntityAction.tsx +51 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +21 -14
- package/src/ui/NewCollectionButton.tsx +1 -1
- package/src/ui/NewCollectionCard.tsx +3 -3
- package/src/ui/PropertyAddColumnComponent.tsx +11 -6
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +157 -50
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +119 -39
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +24 -33
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +46 -41
- 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 +11 -7
- package/src/ui/collection_editor/EnumForm.tsx +11 -7
- package/src/ui/collection_editor/GetCodeDialog.tsx +60 -28
- package/src/ui/collection_editor/LayoutModeSwitch.tsx +54 -0
- package/src/ui/collection_editor/PropertyEditView.tsx +266 -79
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +8 -10
- package/src/ui/collection_editor/PropertyTree.tsx +184 -138
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +26 -19
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +9 -7
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +41 -9
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +43 -10
- package/src/ui/collection_editor/import/clean_import_data.ts +1 -1
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +32 -20
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +54 -47
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -1
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -7
- package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +139 -0
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +7 -3
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +0 -1
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +34 -19
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +4 -9
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +1 -0
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +2 -0
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +2 -2
- package/src/ui/collection_editor/templates/pages_template.ts +1 -6
- package/src/ui/collection_editor/utils/strings.ts +13 -6
- package/src/ui/collection_editor/utils/supported_fields.tsx +2 -0
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +37 -6
- package/src/useCollectionEditorPlugin.tsx +38 -32
- package/src/utils/collections.ts +46 -0
- package/dist/ui/RootCollectionSuggestions.d.ts +0 -3
- package/dist/ui/collection_editor/PropertySelectItem.d.ts +0 -8
- package/src/ui/RootCollectionSuggestions.tsx +0 -63
- package/src/ui/collection_editor/PropertySelectItem.tsx +0 -32
|
@@ -1,35 +1,47 @@
|
|
|
1
|
-
import { EntityCollection, useSnackbarController } from "@firecms/core";
|
|
2
|
-
import { Button, ContentCopyIcon, Dialog, DialogActions, DialogContent,
|
|
1
|
+
import { EntityCollection, isEmptyObject, useSnackbarController } from "@firecms/core";
|
|
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"
|
|
6
6
|
import { camelCase } from "./utils/strings";
|
|
7
|
+
import { clone } from "@firecms/formex";
|
|
7
8
|
|
|
8
|
-
export function GetCodeDialog({
|
|
9
|
+
export function GetCodeDialog({
|
|
10
|
+
collection,
|
|
11
|
+
onOpenChange,
|
|
12
|
+
open
|
|
13
|
+
}: { onOpenChange: (open: boolean) => void, collection: any, open: any }) {
|
|
9
14
|
|
|
10
15
|
const snackbarController = useSnackbarController();
|
|
11
16
|
|
|
12
|
-
const code =
|
|
17
|
+
const code = collection
|
|
18
|
+
? "import { EntityCollection } from \"@firecms/core\";\n\nconst " + (collection?.name ? camelCase(collection.name) : "my") + "Collection:EntityCollection = " + JSON5.stringify(collectionToCode({ ...collection }), null, "\t")
|
|
19
|
+
: "No collection selected";
|
|
13
20
|
return <Dialog open={open}
|
|
14
21
|
onOpenChange={onOpenChange}
|
|
15
22
|
maxWidth={"4xl"}>
|
|
23
|
+
<DialogTitle variant={"h6"}>Code for {collection.name}</DialogTitle>
|
|
16
24
|
<DialogContent>
|
|
17
|
-
|
|
18
|
-
Code for {collection.name}
|
|
19
|
-
</Typography>
|
|
25
|
+
|
|
20
26
|
<Typography variant={"body2"} className={"my-4 mb-8"}>
|
|
21
27
|
If you want to customise the collection in code, you can add this collection code to your CMS
|
|
22
28
|
app configuration.
|
|
23
29
|
More info in the <a
|
|
24
30
|
rel="noopener noreferrer"
|
|
25
|
-
href={"https://firecms.co/docs/
|
|
31
|
+
href={"https://firecms.co/docs/cloud/quickstart"}>docs</a>.
|
|
26
32
|
</Typography>
|
|
27
33
|
<Highlight
|
|
28
34
|
theme={themes.vsDark}
|
|
29
35
|
code={code}
|
|
30
36
|
language="typescript"
|
|
31
37
|
>
|
|
32
|
-
{({
|
|
38
|
+
{({
|
|
39
|
+
className,
|
|
40
|
+
style,
|
|
41
|
+
tokens,
|
|
42
|
+
getLineProps,
|
|
43
|
+
getTokenProps
|
|
44
|
+
}) => (
|
|
33
45
|
<pre style={style} className={"p-4 rounded text-sm"}>
|
|
34
46
|
{tokens.map((line, i) => (
|
|
35
47
|
<div key={i} {...getLineProps({ line })}>
|
|
@@ -47,12 +59,13 @@ export function GetCodeDialog({ collection, onOpenChange, open }: { onOpenChange
|
|
|
47
59
|
<Button
|
|
48
60
|
variant={"text"}
|
|
49
61
|
size={"small"}
|
|
62
|
+
color={"primary"}
|
|
50
63
|
onClick={(e) => {
|
|
51
64
|
e.stopPropagation();
|
|
52
65
|
e.preventDefault();
|
|
53
66
|
snackbarController.open({
|
|
54
67
|
type: "success",
|
|
55
|
-
message:
|
|
68
|
+
message: "Copied"
|
|
56
69
|
})
|
|
57
70
|
return navigator.clipboard.writeText(code);
|
|
58
71
|
}}>
|
|
@@ -66,24 +79,40 @@ export function GetCodeDialog({ collection, onOpenChange, open }: { onOpenChange
|
|
|
66
79
|
|
|
67
80
|
function collectionToCode(collection: EntityCollection): object {
|
|
68
81
|
|
|
69
|
-
const propertyCleanup = (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
const propertyCleanup = (value: any): any => {
|
|
83
|
+
if (value === undefined || value === null) {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
const valueCopy = clone(value);
|
|
87
|
+
if (typeof valueCopy === "function") {
|
|
88
|
+
return valueCopy;
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(valueCopy)) {
|
|
91
|
+
return valueCopy.map((v: any) => propertyCleanup(v));
|
|
92
|
+
}
|
|
93
|
+
if (typeof valueCopy === "object") {
|
|
94
|
+
if (valueCopy === null)
|
|
95
|
+
return valueCopy;
|
|
96
|
+
Object.keys(valueCopy).forEach((key) => {
|
|
97
|
+
if (!isEmptyObject(valueCopy)) {
|
|
98
|
+
const childRes = propertyCleanup(valueCopy[key]);
|
|
99
|
+
if (childRes !== null && childRes !== undefined && childRes !== false && !isEmptyObject(childRes)) {
|
|
100
|
+
valueCopy[key] = childRes;
|
|
101
|
+
} else {
|
|
102
|
+
delete valueCopy[key];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
delete valueCopy.fromBuilder;
|
|
107
|
+
delete valueCopy.resolved;
|
|
108
|
+
delete valueCopy.propertiesOrder;
|
|
109
|
+
delete valueCopy.propertyConfig;
|
|
110
|
+
delete valueCopy.resolvedProperties;
|
|
111
|
+
delete valueCopy.editable;
|
|
79
112
|
|
|
80
|
-
if (updatedProperty.type === "map") {
|
|
81
|
-
return {
|
|
82
|
-
...updatedProperty,
|
|
83
|
-
properties: updatedProperty.properties.map(propertyCleanup)
|
|
84
|
-
}
|
|
85
113
|
}
|
|
86
|
-
|
|
114
|
+
|
|
115
|
+
return valueCopy;
|
|
87
116
|
}
|
|
88
117
|
|
|
89
118
|
return {
|
|
@@ -99,11 +128,14 @@ function collectionToCode(collection: EntityCollection): object {
|
|
|
99
128
|
customId: collection.customId,
|
|
100
129
|
initialFilter: collection.initialFilter,
|
|
101
130
|
initialSort: collection.initialSort,
|
|
102
|
-
properties: Object.entries(
|
|
131
|
+
properties: Object.entries({
|
|
132
|
+
...(collection.properties ?? {})
|
|
133
|
+
})
|
|
103
134
|
.map(([key, value]) => ({
|
|
104
135
|
[key]: propertyCleanup(value)
|
|
105
136
|
}))
|
|
106
|
-
.reduce((a, b) => ({ ...a,
|
|
137
|
+
.reduce((a, b) => ({ ...a,
|
|
138
|
+
...b }), {}),
|
|
107
139
|
subcollections: (collection.subcollections ?? []).map(collectionToCode)
|
|
108
140
|
}
|
|
109
141
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Card, cls, SquareIcon, Tooltip, Typography, VerticalSplitIcon } from "@firecms/ui";
|
|
2
|
+
|
|
3
|
+
export function LayoutModeSwitch({
|
|
4
|
+
value,
|
|
5
|
+
onChange,
|
|
6
|
+
className
|
|
7
|
+
}: {
|
|
8
|
+
value: "side_panel" | "full_screen";
|
|
9
|
+
onChange: (value: "side_panel" | "full_screen") => void;
|
|
10
|
+
className?: string;
|
|
11
|
+
}) {
|
|
12
|
+
|
|
13
|
+
return <div className={cls(className)}>
|
|
14
|
+
<Typography variant={"label"} color={"secondary"} className={"ml-3.5"}>Document view</Typography>
|
|
15
|
+
<div className={cls("flex flex-row gap-4")}>
|
|
16
|
+
|
|
17
|
+
<Tooltip title={"Documents are open in a side panel"}>
|
|
18
|
+
<Card
|
|
19
|
+
onClick={() => onChange("side_panel")}
|
|
20
|
+
className={cls(
|
|
21
|
+
"my-2 rounded-md mx-0 p-4 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
|
|
22
|
+
"text-surface-700 dark:text-surface-accent-300",
|
|
23
|
+
"hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
|
|
24
|
+
value === "side_panel" ? "border-primary dark:border-primary" : "border-surface-400 dark:border-surface-600",
|
|
25
|
+
)}
|
|
26
|
+
>
|
|
27
|
+
<VerticalSplitIcon/>
|
|
28
|
+
<Typography variant={"label"}>
|
|
29
|
+
Side panel
|
|
30
|
+
</Typography>
|
|
31
|
+
</Card>
|
|
32
|
+
</Tooltip>
|
|
33
|
+
|
|
34
|
+
<Tooltip title={"Documents are open full-screen"}>
|
|
35
|
+
<Card
|
|
36
|
+
onClick={() => onChange("full_screen")}
|
|
37
|
+
className={cls(
|
|
38
|
+
"my-2 rounded-md mx-0 p-4 focus:outline-none transition ease-in-out duration-150 flex flex-row gap-4 items-center",
|
|
39
|
+
"text-surface-700 dark:text-surface-accent-300",
|
|
40
|
+
"hover:text-primary-dark dark:hover:text-primary focus:ring-primary hover:ring-1 hover:ring-primary",
|
|
41
|
+
value === "full_screen" ? "border-primary dark:border-primary" : "border-surface-400 dark:border-surface-600",
|
|
42
|
+
)}
|
|
43
|
+
>
|
|
44
|
+
<SquareIcon/>
|
|
45
|
+
<Typography variant={"label"}>
|
|
46
|
+
Full screen
|
|
47
|
+
</Typography>
|
|
48
|
+
</Card>
|
|
49
|
+
</Tooltip>
|
|
50
|
+
|
|
51
|
+
</div>
|
|
52
|
+
<Typography variant={"caption"} color={"secondary"} className={"ml-3.5"}>Should documents be opened full screen or in an inline side dialog</Typography>
|
|
53
|
+
</div>
|
|
54
|
+
}
|