@firecms/collection_editor 3.0.0-alpha.9 → 3.0.0-beta.2-pre.1
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/ConfigControllerProvider.d.ts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.es.js +3128 -4094
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +3 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collection_editor_controller.d.ts +22 -7
- package/dist/types/collection_inference.d.ts +1 -1
- package/dist/types/config_controller.d.ts +32 -5
- package/dist/types/persisted_collection.d.ts +3 -1
- package/dist/ui/CollectionViewHeaderAction.d.ts +10 -0
- package/dist/{components → ui}/EditorCollectionAction.d.ts +1 -1
- package/dist/ui/MissingReferenceWidget.d.ts +3 -0
- package/dist/ui/NewCollectionButton.d.ts +1 -0
- package/dist/ui/PropertyAddColumnComponent.d.ts +6 -0
- package/dist/ui/RootCollectionSuggestions.d.ts +1 -0
- package/dist/{components → ui}/collection_editor/CollectionDetailsForm.d.ts +3 -2
- package/dist/{components → ui}/collection_editor/CollectionEditorDialog.d.ts +11 -6
- package/dist/{components → ui}/collection_editor/CollectionPropertiesEditorForm.d.ts +6 -3
- package/dist/{components → ui}/collection_editor/CollectionYupValidation.d.ts +3 -0
- package/dist/ui/collection_editor/EntityCustomViewsSelectDialog.d.ts +4 -0
- package/dist/ui/collection_editor/GetCodeDialog.d.ts +5 -0
- package/dist/{components → ui}/collection_editor/PropertyEditView.d.ts +8 -6
- package/dist/{components → ui}/collection_editor/PropertyFieldPreview.d.ts +4 -3
- package/dist/ui/collection_editor/PropertySelectItem.d.ts +8 -0
- package/dist/{components → ui}/collection_editor/PropertyTree.d.ts +8 -5
- package/dist/{components → ui}/collection_editor/SubcollectionsEditTab.d.ts +2 -2
- package/dist/{components → ui}/collection_editor/import/CollectionEditorImportDataPreview.d.ts +1 -1
- package/dist/ui/collection_editor/import/CollectionEditorImportMapping.d.ts +7 -0
- package/dist/{components → ui}/collection_editor/import/clean_import_data.d.ts +1 -1
- package/dist/{components → ui}/collection_editor/properties/BlockPropertyField.d.ts +4 -1
- package/dist/{components → ui}/collection_editor/properties/CommonPropertyFields.d.ts +1 -0
- package/dist/{components → ui}/collection_editor/properties/MapPropertyField.d.ts +4 -1
- package/dist/{components → ui}/collection_editor/properties/RepeatPropertyField.d.ts +4 -1
- package/dist/{components → ui}/collection_editor/properties/StringPropertyField.d.ts +1 -1
- package/dist/ui/collection_editor/properties/UrlPropertyField.d.ts +4 -0
- package/dist/ui/collection_editor/templates/blog_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/pages_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/products_template.d.ts +2 -0
- package/dist/ui/collection_editor/templates/users_template.d.ts +2 -0
- package/dist/ui/collection_editor/utils/strings.d.ts +1 -0
- package/dist/ui/collection_editor/utils/supported_fields.d.ts +3 -0
- package/dist/ui/collection_editor/utils/update_property_for_widget.d.ts +2 -0
- package/dist/useCollectionEditorPlugin.d.ts +5 -3
- package/dist/utils/entities.d.ts +3 -4
- package/package.json +22 -19
- package/src/ConfigControllerProvider.tsx +336 -0
- package/src/index.ts +35 -0
- package/src/types/collection_editor_controller.tsx +42 -0
- package/src/types/collection_inference.ts +3 -0
- package/src/types/config_controller.tsx +60 -0
- package/src/types/config_permissions.ts +20 -0
- package/src/types/persisted_collection.ts +9 -0
- package/src/ui/CollectionViewHeaderAction.tsx +43 -0
- package/src/ui/EditorCollectionAction.tsx +109 -0
- package/src/ui/HomePageEditorCollectionAction.tsx +84 -0
- package/src/ui/MissingReferenceWidget.tsx +35 -0
- package/src/ui/NewCollectionButton.tsx +16 -0
- package/src/ui/NewCollectionCard.tsx +47 -0
- package/src/ui/PropertyAddColumnComponent.tsx +42 -0
- package/src/ui/RootCollectionSuggestions.tsx +55 -0
- package/src/ui/collection_editor/CollectionDetailsForm.tsx +366 -0
- package/src/ui/collection_editor/CollectionEditorDialog.tsx +754 -0
- package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +206 -0
- package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +481 -0
- package/src/ui/collection_editor/CollectionYupValidation.tsx +7 -0
- package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +37 -0
- package/src/ui/collection_editor/EnumForm.tsx +354 -0
- package/src/ui/collection_editor/GetCodeDialog.tsx +110 -0
- package/src/ui/collection_editor/PropertyEditView.tsx +558 -0
- package/src/ui/collection_editor/PropertyFieldPreview.tsx +203 -0
- package/src/ui/collection_editor/PropertySelectItem.tsx +32 -0
- package/src/ui/collection_editor/PropertyTree.tsx +233 -0
- package/src/ui/collection_editor/SubcollectionsEditTab.tsx +253 -0
- package/src/ui/collection_editor/UnsavedChangesDialog.tsx +47 -0
- package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +37 -0
- package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +260 -0
- package/src/ui/collection_editor/import/clean_import_data.ts +53 -0
- package/src/ui/collection_editor/properties/BlockPropertyField.tsx +135 -0
- package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +36 -0
- package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +137 -0
- package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +87 -0
- package/src/ui/collection_editor/properties/EnumPropertyField.tsx +117 -0
- package/src/ui/collection_editor/properties/FieldHelperView.tsx +13 -0
- package/src/ui/collection_editor/properties/KeyValuePropertyField.tsx +20 -0
- package/src/ui/collection_editor/properties/MapPropertyField.tsx +149 -0
- package/src/ui/collection_editor/properties/NumberPropertyField.tsx +38 -0
- package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +165 -0
- package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +108 -0
- package/src/ui/collection_editor/properties/StoragePropertyField.tsx +194 -0
- package/src/ui/collection_editor/properties/StringPropertyField.tsx +79 -0
- package/src/ui/collection_editor/properties/UrlPropertyField.tsx +89 -0
- package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +36 -0
- package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +50 -0
- package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +50 -0
- package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +100 -0
- package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +132 -0
- package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +28 -0
- package/src/ui/collection_editor/templates/blog_template.ts +115 -0
- package/src/ui/collection_editor/templates/pages_template.ts +188 -0
- package/src/ui/collection_editor/templates/products_template.ts +88 -0
- package/src/ui/collection_editor/templates/users_template.ts +42 -0
- package/src/ui/collection_editor/util.ts +21 -0
- package/src/ui/collection_editor/utils/strings.ts +8 -0
- package/src/ui/collection_editor/utils/supported_fields.tsx +29 -0
- package/src/ui/collection_editor/utils/update_property_for_widget.ts +271 -0
- package/src/ui/collection_editor/utils/useTraceUpdate.tsx +23 -0
- package/src/useCollectionEditorController.tsx +9 -0
- package/src/useCollectionEditorPlugin.tsx +137 -0
- package/src/useCollectionsConfigController.tsx +9 -0
- package/src/utils/arrays.ts +3 -0
- package/src/utils/entities.ts +38 -0
- package/src/vite-env.d.ts +1 -0
- package/dist/components/collection_editor/PropertySelectItem.d.ts +0 -8
- package/dist/components/collection_editor/SelectIcons.d.ts +0 -6
- package/dist/components/collection_editor/import/CollectionEditorImportMapping.d.ts +0 -4
- package/dist/components/collection_editor/templates/blog_template.d.ts +0 -10
- package/dist/components/collection_editor/templates/products_template.d.ts +0 -12
- package/dist/components/collection_editor/templates/users_template.d.ts +0 -7
- package/dist/components/collection_editor/utils/supported_fields.d.ts +0 -3
- package/dist/components/collection_editor/utils/update_property_for_widget.d.ts +0 -3
- package/dist/types/editable_properties.d.ts +0 -10
- package/dist/utils/icons.d.ts +0 -2
- package/dist/utils/synonyms.d.ts +0 -1951
- /package/dist/{components → ui}/HomePageEditorCollectionAction.d.ts +0 -0
- /package/dist/{components → ui}/NewCollectionCard.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/CollectionEditorWelcomeView.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/EnumForm.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/UnsavedChangesDialog.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/BooleanPropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/DateTimePropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/EnumPropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/FieldHelperView.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/KeyValuePropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/NumberPropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/ReferencePropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/StoragePropertyField.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/advanced/AdvancedPropertyValidation.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/validation/ArrayPropertyValidation.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/validation/GeneralPropertyValidation.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/validation/NumberPropertyValidation.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/validation/StringPropertyValidation.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/properties/validation/ValidationPanel.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/util.d.ts +0 -0
- /package/dist/{components → ui}/collection_editor/utils/useTraceUpdate.d.ts +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StringPropertyValidation } from "./validation/StringPropertyValidation";
|
|
3
|
+
import { ValidationPanel } from "./validation/ValidationPanel";
|
|
4
|
+
import { getIn, useFormikContext } from "formik";
|
|
5
|
+
|
|
6
|
+
import { TextField } from "@firecms/ui";
|
|
7
|
+
|
|
8
|
+
export function StringPropertyField({
|
|
9
|
+
widgetId,
|
|
10
|
+
disabled,
|
|
11
|
+
showErrors
|
|
12
|
+
}: {
|
|
13
|
+
widgetId: "text_field" | "multiline" | "markdown" | "email";
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
showErrors: boolean;
|
|
16
|
+
}) {
|
|
17
|
+
|
|
18
|
+
const { values, setFieldValue } = useFormikContext();
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<div className={"col-span-12"}>
|
|
23
|
+
|
|
24
|
+
<ValidationPanel>
|
|
25
|
+
|
|
26
|
+
{widgetId === "text_field" &&
|
|
27
|
+
<StringPropertyValidation disabled={disabled}
|
|
28
|
+
length={true}
|
|
29
|
+
lowercase={true}
|
|
30
|
+
matches={true}
|
|
31
|
+
max={true}
|
|
32
|
+
min={true}
|
|
33
|
+
trim={true}
|
|
34
|
+
uppercase={true}
|
|
35
|
+
showErrors={showErrors}/>}
|
|
36
|
+
{widgetId === "multiline" &&
|
|
37
|
+
<StringPropertyValidation disabled={disabled}
|
|
38
|
+
length={true}
|
|
39
|
+
lowercase={true}
|
|
40
|
+
max={true}
|
|
41
|
+
min={true}
|
|
42
|
+
trim={true}
|
|
43
|
+
uppercase={true}
|
|
44
|
+
showErrors={showErrors}/>}
|
|
45
|
+
{widgetId === "markdown" &&
|
|
46
|
+
<StringPropertyValidation disabled={disabled}
|
|
47
|
+
length={true}
|
|
48
|
+
lowercase={true}
|
|
49
|
+
max={true}
|
|
50
|
+
min={true}
|
|
51
|
+
trim={true}
|
|
52
|
+
uppercase={true}
|
|
53
|
+
showErrors={showErrors}/>}
|
|
54
|
+
|
|
55
|
+
{widgetId === "email" &&
|
|
56
|
+
<StringPropertyValidation disabled={disabled}
|
|
57
|
+
max={true}
|
|
58
|
+
min={true}
|
|
59
|
+
trim={true}
|
|
60
|
+
showErrors={showErrors}/>}
|
|
61
|
+
|
|
62
|
+
</ValidationPanel>
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div className={"col-span-12"}>
|
|
67
|
+
|
|
68
|
+
<TextField name={"defaultValue"}
|
|
69
|
+
disabled={disabled}
|
|
70
|
+
onChange={(e: any) => {
|
|
71
|
+
setFieldValue("defaultValue", e.target.value === "" ? undefined : e.target.value);
|
|
72
|
+
}}
|
|
73
|
+
label={"Default value"}
|
|
74
|
+
value={getIn(values, "defaultValue") ?? ""}/>
|
|
75
|
+
|
|
76
|
+
</div>
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StringPropertyValidation } from "./validation/StringPropertyValidation";
|
|
3
|
+
import { ValidationPanel } from "./validation/ValidationPanel";
|
|
4
|
+
import { getIn, useFormikContext } from "formik";
|
|
5
|
+
|
|
6
|
+
import { Select, SelectItem, TextField } from "@firecms/ui";
|
|
7
|
+
|
|
8
|
+
export function UrlPropertyField({
|
|
9
|
+
disabled,
|
|
10
|
+
showErrors
|
|
11
|
+
}: {
|
|
12
|
+
disabled: boolean;
|
|
13
|
+
showErrors: boolean;
|
|
14
|
+
}) {
|
|
15
|
+
|
|
16
|
+
const { values, setFieldValue } = useFormikContext();
|
|
17
|
+
|
|
18
|
+
const urlValue = getIn(values, "url");
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<div className={"col-span-12"}>
|
|
23
|
+
|
|
24
|
+
<Select
|
|
25
|
+
disabled={disabled}
|
|
26
|
+
position={"item-aligned"}
|
|
27
|
+
onValueChange={(value: string) => {
|
|
28
|
+
if (value === "[NONE]")
|
|
29
|
+
setFieldValue("url", true);
|
|
30
|
+
else
|
|
31
|
+
setFieldValue("url", value);
|
|
32
|
+
}}
|
|
33
|
+
label={"Preview type"}
|
|
34
|
+
renderValue={(value: string) => {
|
|
35
|
+
switch (value) {
|
|
36
|
+
case "image":
|
|
37
|
+
return "Image";
|
|
38
|
+
case "video":
|
|
39
|
+
return "Video";
|
|
40
|
+
case "audio":
|
|
41
|
+
return "Audio";
|
|
42
|
+
default:
|
|
43
|
+
return "Display URL";
|
|
44
|
+
}
|
|
45
|
+
}}
|
|
46
|
+
value={urlValue ?? "[NONE]"}>
|
|
47
|
+
<SelectItem value={"[NONE]"}>
|
|
48
|
+
Display URL
|
|
49
|
+
</SelectItem>
|
|
50
|
+
<SelectItem value={"image"}>
|
|
51
|
+
Image
|
|
52
|
+
</SelectItem>
|
|
53
|
+
<SelectItem value={"video"}>
|
|
54
|
+
Video
|
|
55
|
+
</SelectItem>
|
|
56
|
+
<SelectItem value={"audio"}>
|
|
57
|
+
Audio
|
|
58
|
+
</SelectItem>
|
|
59
|
+
</Select>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div className={"col-span-12"}>
|
|
63
|
+
|
|
64
|
+
<ValidationPanel>
|
|
65
|
+
|
|
66
|
+
<StringPropertyValidation disabled={disabled}
|
|
67
|
+
max={true}
|
|
68
|
+
min={true}
|
|
69
|
+
trim={true}
|
|
70
|
+
showErrors={showErrors}/>
|
|
71
|
+
|
|
72
|
+
</ValidationPanel>
|
|
73
|
+
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div className={"col-span-12"}>
|
|
77
|
+
|
|
78
|
+
<TextField name={"defaultValue"}
|
|
79
|
+
disabled={disabled}
|
|
80
|
+
onChange={(e: any) => {
|
|
81
|
+
setFieldValue("defaultValue", e.target.value === "" ? undefined : e.target.value);
|
|
82
|
+
}}
|
|
83
|
+
label={"Default value"}
|
|
84
|
+
value={getIn(values, "defaultValue") ?? ""}/>
|
|
85
|
+
|
|
86
|
+
</div>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { FastField, useFormikContext } from "formik";
|
|
4
|
+
import { SwitchControl } from "@firecms/core";
|
|
5
|
+
|
|
6
|
+
export function AdvancedPropertyValidation({ disabled }: {disabled: boolean}) {
|
|
7
|
+
|
|
8
|
+
const { values, handleChange } = useFormikContext();
|
|
9
|
+
|
|
10
|
+
const columnWidth = "columnWidth";
|
|
11
|
+
const hideFromCollection = "hideFromCollection";
|
|
12
|
+
const readOnly = "readOnly";
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
|
|
16
|
+
<div className={"grid grid-cols-12 gap-2"} >
|
|
17
|
+
<div className={"col-span-12"}>
|
|
18
|
+
<FastField type="checkbox"
|
|
19
|
+
name={hideFromCollection}
|
|
20
|
+
label={"Hide from collection"}
|
|
21
|
+
disabled={disabled}
|
|
22
|
+
tooltip={"Hide this field from the collection view. It will still be visible in the form view"}
|
|
23
|
+
component={SwitchControl}/>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div className={"col-span-12"}>
|
|
27
|
+
<FastField type="checkbox"
|
|
28
|
+
name={readOnly}
|
|
29
|
+
label={"Read only"}
|
|
30
|
+
disabled={disabled}
|
|
31
|
+
tooltip={"Is this a read only field. Display only as a preview"}
|
|
32
|
+
component={SwitchControl}/>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { getIn, useFormikContext } from "formik";
|
|
4
|
+
import { DebouncedTextField } from "@firecms/ui";
|
|
5
|
+
import { GeneralPropertyValidation } from "./GeneralPropertyValidation";
|
|
6
|
+
|
|
7
|
+
export function ArrayPropertyValidation({
|
|
8
|
+
max = true,
|
|
9
|
+
min = true,
|
|
10
|
+
disabled
|
|
11
|
+
}: {
|
|
12
|
+
min?: boolean;
|
|
13
|
+
max?: boolean;
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
}) {
|
|
16
|
+
|
|
17
|
+
const {
|
|
18
|
+
values,
|
|
19
|
+
handleChange
|
|
20
|
+
} = useFormikContext();
|
|
21
|
+
|
|
22
|
+
const validationMin = "validation.min";
|
|
23
|
+
const validationMax = "validation.max";
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className={"grid grid-cols-12 gap-2"}>
|
|
27
|
+
|
|
28
|
+
<GeneralPropertyValidation disabled={disabled}/>
|
|
29
|
+
|
|
30
|
+
{min && <div className={"col-span-6"}>
|
|
31
|
+
<DebouncedTextField value={getIn(values, validationMin)}
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
label={"Min length"}
|
|
34
|
+
name={validationMin}
|
|
35
|
+
type="number"
|
|
36
|
+
size="small"
|
|
37
|
+
onChange={handleChange}/>
|
|
38
|
+
</div>}
|
|
39
|
+
{max && <div className={"col-span-6"}>
|
|
40
|
+
<DebouncedTextField value={getIn(values, validationMax)}
|
|
41
|
+
disabled={disabled}
|
|
42
|
+
label={"Max length"}
|
|
43
|
+
name={validationMax}
|
|
44
|
+
type="number"
|
|
45
|
+
size="small"
|
|
46
|
+
onChange={handleChange}/>
|
|
47
|
+
</div>}
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { FastField, getIn, useFormikContext } from "formik";
|
|
4
|
+
import { SwitchControl } from "@firecms/core";
|
|
5
|
+
import { DebouncedTextField } from "@firecms/ui";
|
|
6
|
+
|
|
7
|
+
export function GeneralPropertyValidation({ disabled }: {
|
|
8
|
+
required?: boolean;
|
|
9
|
+
disabled:boolean;
|
|
10
|
+
}) {
|
|
11
|
+
|
|
12
|
+
const { values, handleChange } = useFormikContext();
|
|
13
|
+
|
|
14
|
+
const validationRequired = "validation.required";
|
|
15
|
+
const validationRequiredMessage = "validation.requiredMessage";
|
|
16
|
+
const validationUnique = "validation.unique";
|
|
17
|
+
const validationUniqueInArray = "validation.uniqueInArray";
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<div className={"col-span-6"}>
|
|
22
|
+
<FastField type="checkbox"
|
|
23
|
+
disabled={disabled}
|
|
24
|
+
name={validationRequired}
|
|
25
|
+
label={"Required"}
|
|
26
|
+
tooltip={"You won't be able to save this entity if this value is not set"}
|
|
27
|
+
component={SwitchControl}/>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div className={"col-span-6"}>
|
|
31
|
+
<FastField type="checkbox"
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
name={validationUnique}
|
|
34
|
+
label={"Unique"}
|
|
35
|
+
tooltip={"There cannot be multiple entities with the same value"}
|
|
36
|
+
component={SwitchControl}/>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
{getIn(values, validationRequired) && <div className={"col-span-12"}>
|
|
40
|
+
<DebouncedTextField
|
|
41
|
+
disabled={disabled}
|
|
42
|
+
value={getIn(values, validationRequiredMessage)}
|
|
43
|
+
label={"Required message"}
|
|
44
|
+
name={validationRequiredMessage}
|
|
45
|
+
size="small"
|
|
46
|
+
onChange={handleChange}/>
|
|
47
|
+
</div>}
|
|
48
|
+
</>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { FastField, getIn, useFormikContext } from "formik";
|
|
4
|
+
import { SwitchControl } from "@firecms/core";
|
|
5
|
+
import { DebouncedTextField } from "@firecms/ui";
|
|
6
|
+
import { GeneralPropertyValidation } from "./GeneralPropertyValidation";
|
|
7
|
+
|
|
8
|
+
export function NumberPropertyValidation({ disabled }: {
|
|
9
|
+
disabled: boolean;
|
|
10
|
+
}) {
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
values,
|
|
14
|
+
handleChange
|
|
15
|
+
} = useFormikContext();
|
|
16
|
+
|
|
17
|
+
const validationMin = "validation.min";
|
|
18
|
+
const validationMax = "validation.max";
|
|
19
|
+
const validationLessThan = "validation.lessThan";
|
|
20
|
+
const validationMoreThan = "validation.moreThan";
|
|
21
|
+
const validationPositive = "validation.positive";
|
|
22
|
+
const validationNegative = "validation.negative";
|
|
23
|
+
const validationInteger = "validation.integer";
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
|
|
27
|
+
<div className={"grid grid-cols-12 gap-2"}>
|
|
28
|
+
<GeneralPropertyValidation disabled={disabled}/>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
<div className={"col-span-6"}>
|
|
32
|
+
<DebouncedTextField value={getIn(values, validationMin)}
|
|
33
|
+
label={"Min value"}
|
|
34
|
+
name={validationMin}
|
|
35
|
+
type="number"
|
|
36
|
+
size="small"
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
onChange={handleChange}/>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div className={"col-span-6"}>
|
|
42
|
+
<DebouncedTextField value={getIn(values, validationMax)}
|
|
43
|
+
label={"Max value"}
|
|
44
|
+
name={validationMax}
|
|
45
|
+
type="number"
|
|
46
|
+
size="small"
|
|
47
|
+
|
|
48
|
+
disabled={disabled}
|
|
49
|
+
onChange={handleChange}/>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
<div className={"col-span-6"}>
|
|
54
|
+
<DebouncedTextField
|
|
55
|
+
value={getIn(values, validationLessThan)}
|
|
56
|
+
label={"Less than"}
|
|
57
|
+
name={validationLessThan}
|
|
58
|
+
type="number"
|
|
59
|
+
size="small"
|
|
60
|
+
|
|
61
|
+
disabled={disabled}
|
|
62
|
+
onChange={handleChange}/>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div className={"col-span-6"}>
|
|
66
|
+
<DebouncedTextField
|
|
67
|
+
value={getIn(values, validationMoreThan)}
|
|
68
|
+
label={"More than"}
|
|
69
|
+
name={validationMoreThan}
|
|
70
|
+
type="number"
|
|
71
|
+
size="small"
|
|
72
|
+
|
|
73
|
+
disabled={disabled}
|
|
74
|
+
onChange={handleChange}/>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div className={"col-span-4"}>
|
|
78
|
+
<FastField type="checkbox"
|
|
79
|
+
name={validationPositive}
|
|
80
|
+
label={"Positive value"}
|
|
81
|
+
disabled={disabled}
|
|
82
|
+
component={SwitchControl}/>
|
|
83
|
+
</div>
|
|
84
|
+
<div className={"col-span-4"}>
|
|
85
|
+
<FastField type="checkbox"
|
|
86
|
+
name={validationNegative}
|
|
87
|
+
label={"Negative value"}
|
|
88
|
+
disabled={disabled}
|
|
89
|
+
component={SwitchControl}/>
|
|
90
|
+
</div>
|
|
91
|
+
<div className={"col-span-4"}>
|
|
92
|
+
<FastField type="checkbox"
|
|
93
|
+
name={validationInteger}
|
|
94
|
+
label={"Integer value"}
|
|
95
|
+
disabled={disabled}
|
|
96
|
+
component={SwitchControl}/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { FastField, getIn, useFormikContext } from "formik";
|
|
4
|
+
import { isValidRegExp, serializeRegExp, SwitchControl } from "@firecms/core";
|
|
5
|
+
import { DebouncedTextField, } from "@firecms/ui";
|
|
6
|
+
import { GeneralPropertyValidation } from "./GeneralPropertyValidation";
|
|
7
|
+
import { FieldHelperView } from "../FieldHelperView";
|
|
8
|
+
|
|
9
|
+
export function StringPropertyValidation({
|
|
10
|
+
length,
|
|
11
|
+
lowercase,
|
|
12
|
+
matches,
|
|
13
|
+
max,
|
|
14
|
+
min,
|
|
15
|
+
trim,
|
|
16
|
+
uppercase,
|
|
17
|
+
disabled,
|
|
18
|
+
showErrors
|
|
19
|
+
}: {
|
|
20
|
+
length?: boolean;
|
|
21
|
+
min?: boolean;
|
|
22
|
+
max?: boolean;
|
|
23
|
+
trim?: boolean;
|
|
24
|
+
matches?: boolean;
|
|
25
|
+
lowercase?: boolean;
|
|
26
|
+
uppercase?: boolean;
|
|
27
|
+
disabled: boolean;
|
|
28
|
+
showErrors: boolean;
|
|
29
|
+
}) {
|
|
30
|
+
|
|
31
|
+
const {
|
|
32
|
+
values,
|
|
33
|
+
handleChange,
|
|
34
|
+
errors
|
|
35
|
+
} = useFormikContext();
|
|
36
|
+
|
|
37
|
+
const validationLength = "validation.length";
|
|
38
|
+
const validationMin = "validation.min";
|
|
39
|
+
const validationMax = "validation.max";
|
|
40
|
+
const validationTrim = "validation.trim";
|
|
41
|
+
const validationMatches = "validation.matches";
|
|
42
|
+
const validationLowercase = "validation.lowercase";
|
|
43
|
+
const validationUppercase = "validation.uppercase";
|
|
44
|
+
|
|
45
|
+
const matchesError = getIn(errors, validationMatches);
|
|
46
|
+
|
|
47
|
+
const matchesValue = getIn(values, validationMatches);
|
|
48
|
+
const matchesStringValue = typeof matchesValue === "string" ? matchesValue : serializeRegExp(matchesValue);
|
|
49
|
+
return (
|
|
50
|
+
<div className={"grid grid-cols-12 gap-2"}>
|
|
51
|
+
|
|
52
|
+
<GeneralPropertyValidation disabled={disabled}/>
|
|
53
|
+
|
|
54
|
+
<div className={"grid grid-cols-12 gap-2 col-span-12"}>
|
|
55
|
+
{lowercase && <div className={"col-span-4"}>
|
|
56
|
+
<FastField type="checkbox"
|
|
57
|
+
name={validationLowercase}
|
|
58
|
+
label={"Lowercase"}
|
|
59
|
+
disabled={disabled}
|
|
60
|
+
component={SwitchControl}/>
|
|
61
|
+
</div>}
|
|
62
|
+
{uppercase && <div className={"col-span-4"}>
|
|
63
|
+
<FastField type="checkbox"
|
|
64
|
+
name={validationUppercase}
|
|
65
|
+
label={"Uppercase"}
|
|
66
|
+
disabled={disabled}
|
|
67
|
+
component={SwitchControl}/>
|
|
68
|
+
</div>}
|
|
69
|
+
{trim && <div className={"col-span-4"}>
|
|
70
|
+
<FastField type="checkbox"
|
|
71
|
+
name={validationTrim}
|
|
72
|
+
label={"Trim"}
|
|
73
|
+
disabled={disabled}
|
|
74
|
+
component={SwitchControl}/>
|
|
75
|
+
</div>}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div className={"grid grid-cols-12 gap-2 col-span-12"}>
|
|
79
|
+
{length && <div className={"col-span-4"}>
|
|
80
|
+
<DebouncedTextField
|
|
81
|
+
value={getIn(values, validationLength)}
|
|
82
|
+
label={"Exact length"}
|
|
83
|
+
name={validationLength}
|
|
84
|
+
type="number"
|
|
85
|
+
size="small"
|
|
86
|
+
|
|
87
|
+
disabled={disabled}
|
|
88
|
+
onChange={handleChange}/>
|
|
89
|
+
</div>}
|
|
90
|
+
|
|
91
|
+
{min && <div className={"col-span-4"}>
|
|
92
|
+
<DebouncedTextField value={getIn(values, validationMin)}
|
|
93
|
+
label={"Min length"}
|
|
94
|
+
name={validationMin}
|
|
95
|
+
type="number"
|
|
96
|
+
size="small"
|
|
97
|
+
|
|
98
|
+
disabled={disabled}
|
|
99
|
+
onChange={handleChange}/>
|
|
100
|
+
</div>}
|
|
101
|
+
|
|
102
|
+
{max && <div className={"col-span-4"}>
|
|
103
|
+
<DebouncedTextField value={getIn(values, validationMax)}
|
|
104
|
+
label={"Max length"}
|
|
105
|
+
name={validationMax}
|
|
106
|
+
type="number"
|
|
107
|
+
size="small"
|
|
108
|
+
|
|
109
|
+
disabled={disabled}
|
|
110
|
+
onChange={handleChange}/>
|
|
111
|
+
</div>}
|
|
112
|
+
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
{matches && <div className={"col-span-12"}>
|
|
116
|
+
<FastField name={validationMatches}
|
|
117
|
+
as={DebouncedTextField}
|
|
118
|
+
validate={(value: string) => value && !isValidRegExp(value)}
|
|
119
|
+
label={"Matches regex"}
|
|
120
|
+
size="small"
|
|
121
|
+
disabled={disabled}
|
|
122
|
+
value={matchesStringValue}
|
|
123
|
+
error={Boolean(matchesError)}/>
|
|
124
|
+
<FieldHelperView error={Boolean(matchesError)}>
|
|
125
|
+
{matchesError ? "Not a valid regexp" : "e.g. /^\\d+$/ for digits only"}
|
|
126
|
+
</FieldHelperView>
|
|
127
|
+
</div>}
|
|
128
|
+
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PropsWithChildren } from "react";
|
|
2
|
+
|
|
3
|
+
import { ExpandablePanel, RuleIcon, Typography } from "@firecms/ui";
|
|
4
|
+
|
|
5
|
+
export function ValidationPanel({
|
|
6
|
+
children
|
|
7
|
+
}: PropsWithChildren<{}>) {
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<ExpandablePanel
|
|
11
|
+
initiallyExpanded={false}
|
|
12
|
+
asField={true}
|
|
13
|
+
className="p-4"
|
|
14
|
+
title={
|
|
15
|
+
<div className="flex flex-row text-gray-500">
|
|
16
|
+
<RuleIcon/>
|
|
17
|
+
<Typography variant={"subtitle2"}
|
|
18
|
+
className="ml-2">
|
|
19
|
+
Validation
|
|
20
|
+
</Typography>
|
|
21
|
+
</div>
|
|
22
|
+
}>
|
|
23
|
+
|
|
24
|
+
{children}
|
|
25
|
+
|
|
26
|
+
</ExpandablePanel>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { EntityCollection, makePropertiesEditable } from "@firecms/core";
|
|
2
|
+
|
|
3
|
+
export const blogCollectionTemplate:EntityCollection = {
|
|
4
|
+
id: "blog",
|
|
5
|
+
path: "blog",
|
|
6
|
+
name: "Blog",
|
|
7
|
+
singularName: "Blog entry",
|
|
8
|
+
icon: "article",
|
|
9
|
+
description: "A collection of blog entries",
|
|
10
|
+
defaultSize: "l",
|
|
11
|
+
properties: makePropertiesEditable({
|
|
12
|
+
name: {
|
|
13
|
+
name: "Name",
|
|
14
|
+
validation: { required: true },
|
|
15
|
+
dataType: "string"
|
|
16
|
+
},
|
|
17
|
+
header_image: {
|
|
18
|
+
name: "Header image",
|
|
19
|
+
dataType: "string",
|
|
20
|
+
storage: {
|
|
21
|
+
storagePath: "images",
|
|
22
|
+
acceptedFiles: ["image/*"],
|
|
23
|
+
metadata: {
|
|
24
|
+
cacheControl: "max-age=1000000"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
content: {
|
|
29
|
+
name: "Content",
|
|
30
|
+
description: "Content blocks for the blog entry",
|
|
31
|
+
validation: { required: true },
|
|
32
|
+
dataType: "array",
|
|
33
|
+
oneOf: {
|
|
34
|
+
typeField: "type",
|
|
35
|
+
valueField: "value",
|
|
36
|
+
properties: {
|
|
37
|
+
text: {
|
|
38
|
+
dataType: "string",
|
|
39
|
+
name: "Text",
|
|
40
|
+
markdown: true
|
|
41
|
+
},
|
|
42
|
+
quote: {
|
|
43
|
+
dataType: "string",
|
|
44
|
+
name: "Quote",
|
|
45
|
+
multiline: true
|
|
46
|
+
},
|
|
47
|
+
images: {
|
|
48
|
+
name: "Images",
|
|
49
|
+
dataType: "array",
|
|
50
|
+
of: {
|
|
51
|
+
dataType: "string",
|
|
52
|
+
storage: {
|
|
53
|
+
storagePath: "images",
|
|
54
|
+
acceptedFiles: ["image/*"],
|
|
55
|
+
metadata: {
|
|
56
|
+
cacheControl: "max-age=1000000"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
description: "This fields allows uploading multiple images at once and reordering"
|
|
61
|
+
},
|
|
62
|
+
products: {
|
|
63
|
+
name: "Products",
|
|
64
|
+
dataType: "array",
|
|
65
|
+
of: {
|
|
66
|
+
dataType: "reference",
|
|
67
|
+
path: "products",
|
|
68
|
+
previewProperties: ["name", "main_image"]
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
propertiesOrder: ["text", "quote", "images", "products"]
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
created_on: {
|
|
76
|
+
name: "Created on",
|
|
77
|
+
dataType: "date",
|
|
78
|
+
autoValue: "on_create"
|
|
79
|
+
},
|
|
80
|
+
status: {
|
|
81
|
+
name: "Status",
|
|
82
|
+
validation: { required: true },
|
|
83
|
+
dataType: "string",
|
|
84
|
+
enumValues: {
|
|
85
|
+
published: {
|
|
86
|
+
id: "published",
|
|
87
|
+
label: "Published",
|
|
88
|
+
},
|
|
89
|
+
draft: "Draft"
|
|
90
|
+
},
|
|
91
|
+
defaultValue: "draft"
|
|
92
|
+
},
|
|
93
|
+
publish_date: {
|
|
94
|
+
name: "Publish date",
|
|
95
|
+
dataType: "date",
|
|
96
|
+
clearable: true
|
|
97
|
+
},
|
|
98
|
+
reviewed: {
|
|
99
|
+
name: "Reviewed",
|
|
100
|
+
dataType: "boolean"
|
|
101
|
+
},
|
|
102
|
+
tags: {
|
|
103
|
+
name: "Tags",
|
|
104
|
+
description: "Example of generic array",
|
|
105
|
+
dataType: "array",
|
|
106
|
+
of: {
|
|
107
|
+
dataType: "string",
|
|
108
|
+
previewAsTag: true
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}),
|
|
112
|
+
initialFilter: {
|
|
113
|
+
status: ["==", "published"]
|
|
114
|
+
}
|
|
115
|
+
};
|