@firecms/collection_editor 3.0.0-beta.2-pre.2 → 3.0.0-beta.2-pre.3

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.
Files changed (71) hide show
  1. package/dist/form/Field.d.ts +53 -0
  2. package/dist/form/Formex.d.ts +4 -0
  3. package/dist/form/index.d.ts +5 -0
  4. package/dist/form/types.d.ts +25 -0
  5. package/dist/form/useCreateFormex.d.ts +9 -0
  6. package/dist/form/utils.d.ts +44 -0
  7. package/dist/index.es.js +2612 -2328
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.umd.js +2 -2
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/types/collection_editor_controller.d.ts +3 -2
  12. package/dist/types/config_controller.d.ts +3 -3
  13. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +3 -5
  14. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +2 -2
  15. package/dist/ui/collection_editor/CollectionPropertiesEditorForm.d.ts +1 -2
  16. package/dist/ui/collection_editor/EnumForm.d.ts +1 -2
  17. package/dist/ui/collection_editor/PropertyEditView.d.ts +5 -5
  18. package/dist/ui/collection_editor/PropertyTree.d.ts +14 -13
  19. package/dist/ui/collection_editor/SwitchControl.d.ts +8 -0
  20. package/dist/ui/collection_editor/properties/CommonPropertyFields.d.ts +0 -1
  21. package/dist/ui/collection_editor/util.d.ts +1 -0
  22. package/package.json +5 -5
  23. package/src/ConfigControllerProvider.tsx +23 -21
  24. package/src/form/Field.tsx +162 -0
  25. package/src/form/Formex.tsx +8 -0
  26. package/src/form/README.md +165 -0
  27. package/src/form/index.ts +5 -0
  28. package/src/form/types.ts +27 -0
  29. package/src/form/useCreateFormex.tsx +137 -0
  30. package/src/form/utils.ts +169 -0
  31. package/src/types/collection_editor_controller.tsx +4 -3
  32. package/src/types/config_controller.tsx +3 -3
  33. package/src/ui/CollectionViewHeaderAction.tsx +1 -1
  34. package/src/ui/EditorCollectionAction.tsx +3 -3
  35. package/src/ui/HomePageEditorCollectionAction.tsx +2 -2
  36. package/src/ui/MissingReferenceWidget.tsx +2 -1
  37. package/src/ui/NewCollectionButton.tsx +3 -3
  38. package/src/ui/NewCollectionCard.tsx +2 -1
  39. package/src/ui/PropertyAddColumnComponent.tsx +1 -1
  40. package/src/ui/RootCollectionSuggestions.tsx +2 -1
  41. package/src/ui/collection_editor/CollectionDetailsForm.tsx +2 -2
  42. package/src/ui/collection_editor/CollectionEditorDialog.tsx +422 -374
  43. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +19 -12
  44. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +26 -18
  45. package/src/ui/collection_editor/EnumForm.tsx +118 -114
  46. package/src/ui/collection_editor/GetCodeDialog.tsx +1 -1
  47. package/src/ui/collection_editor/PropertyEditView.tsx +198 -142
  48. package/src/ui/collection_editor/PropertyFieldPreview.tsx +5 -1
  49. package/src/ui/collection_editor/PropertyTree.tsx +132 -113
  50. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +18 -11
  51. package/src/ui/collection_editor/SwitchControl.tsx +39 -0
  52. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +10 -2
  53. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +2 -2
  54. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +13 -9
  55. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +11 -37
  56. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +2 -2
  57. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +3 -6
  58. package/src/ui/collection_editor/properties/MapPropertyField.tsx +2 -2
  59. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +2 -2
  60. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +11 -14
  61. package/src/ui/collection_editor/properties/RepeatPropertyField.tsx +10 -9
  62. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +15 -9
  63. package/src/ui/collection_editor/properties/StringPropertyField.tsx +2 -2
  64. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +2 -2
  65. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +27 -18
  66. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +2 -2
  67. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +27 -16
  68. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +33 -18
  69. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +99 -80
  70. package/src/ui/collection_editor/util.ts +7 -0
  71. package/src/ui/collection_editor/utils/strings.ts +2 -1
@@ -1,124 +1,143 @@
1
+ import React, { useCallback } from "react";
2
+ import equal from "react-fast-compare"
3
+
1
4
  import {
2
5
  AdditionalFieldDelegate,
3
6
  CMSType,
4
7
  ErrorBoundary,
5
8
  isPropertyBuilder,
6
9
  PropertiesOrBuilders,
7
- PropertyOrBuilder,
10
+ PropertyOrBuilder
8
11
  } from "@firecms/core";
9
12
  import { AutoAwesomeIcon, defaultBorderMixin, DragHandleIcon, IconButton, RemoveIcon, Tooltip } from "@firecms/ui";
10
13
  import { NonEditablePropertyPreview, PropertyFieldPreview } from "./PropertyFieldPreview";
11
14
  import { DragDropContext, Draggable, DraggableProvided, Droppable } from "@hello-pangea/dnd";
12
- import { getFullId, idToPropertiesPath } from "./util";
13
- import { getIn } from "formik";
15
+ import { getFullId, getFullIdPath } from "./util";
14
16
  import { editableProperty } from "../../utils/entities";
15
- import { useCallback } from "react";
16
-
17
- export function PropertyTree<M extends {
18
- [Key: string]: CMSType
19
- }>({
20
- namespace,
21
- selectedPropertyKey,
22
- onPropertyClick,
23
- properties,
24
- propertiesOrder: propertiesOrderProp,
25
- additionalFields,
26
- errors,
27
- onPropertyMove,
28
- onPropertyRemove,
29
- className,
30
- inferredPropertyKeys,
31
- collectionEditable,
32
- }: {
33
- namespace?: string;
34
- selectedPropertyKey?: string;
35
- onPropertyClick?: (propertyKey: string, namespace?: string) => void;
36
- properties: PropertiesOrBuilders<M>;
37
- propertiesOrder?: string[];
38
- additionalFields?: AdditionalFieldDelegate<M>[];
39
- errors: Record<string, any>;
40
- onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
41
- onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
42
- className?: string;
43
- inferredPropertyKeys?: string[];
44
- collectionEditable: boolean;
45
- }) {
46
17
 
47
- const propertiesOrder = propertiesOrderProp ?? Object.keys(properties);
48
-
49
- const onDragEnd = useCallback((result: any) => {
50
- // dropped outside the list
51
- if (!result.destination) {
52
- return;
53
- }
54
- const startIndex = result.source.index;
55
- const endIndex = result.destination.index;
56
-
57
- const newPropertiesOrder = Array.from(propertiesOrder);
58
- const [removed] = newPropertiesOrder.splice(startIndex, 1);
59
- newPropertiesOrder.splice(endIndex, 0, removed);
60
- if (onPropertyMove)
61
- onPropertyMove(newPropertiesOrder, namespace);
62
- }, [namespace, onPropertyMove, propertiesOrder])
63
-
64
- return (
65
- <>
66
-
67
- <DragDropContext onDragEnd={onDragEnd}>
68
- <Droppable droppableId={`droppable_${namespace}`}>
69
- {(droppableProvided, droppableSnapshot) => (
70
- <div
71
- {...droppableProvided.droppableProps}
72
- ref={droppableProvided.innerRef}
73
- className={className}>
74
- {propertiesOrder && propertiesOrder
75
- // .filter((propertyKey) => Boolean(properties[propertyKey]))
76
- .map((propertyKey: string, index: number) => {
77
- const property = properties[propertyKey] as PropertyOrBuilder;
78
- const additionalField = additionalFields?.find(field => field.key === propertyKey);
79
-
80
- if (!property && !additionalField) {
81
- console.warn(`Property ${propertyKey} not found in properties or additionalFields`);
82
- return null;
83
- }
84
- return (
85
- <Draggable
86
- key={`array_field_${namespace}_${propertyKey}}`}
87
- draggableId={`array_field_${namespace}_${propertyKey}}`}
88
- index={index}>
89
- {(provided, snapshot) => {
90
- return (
91
- <ErrorBoundary>
92
- <PropertyTreeEntry
93
- propertyKey={propertyKey as string}
94
- propertyOrBuilder={property}
95
- additionalField={additionalField}
96
- provided={provided}
97
- errors={errors}
98
- namespace={namespace}
99
- inferredPropertyKeys={inferredPropertyKeys}
100
- onPropertyMove={onPropertyMove}
101
- onPropertyRemove={onPropertyRemove}
102
- onPropertyClick={snapshot.isDragging ? undefined : onPropertyClick}
103
- selectedPropertyKey={selectedPropertyKey}
104
- collectionEditable={collectionEditable}
105
- />
106
- </ErrorBoundary>
107
- );
108
- }}
109
- </Draggable>);
110
- }).filter(Boolean)}
111
-
112
- {droppableProvided.placeholder}
113
-
114
- </div>
115
- )}
116
- </Droppable>
117
- </DragDropContext>
118
-
119
- </>
120
- );
121
- }
18
+ export const PropertyTree = React.memo(
19
+ function PropertyTree<M extends {
20
+ [Key: string]: CMSType
21
+ }>({
22
+ namespace,
23
+ selectedPropertyKey,
24
+ onPropertyClick,
25
+ properties,
26
+ propertiesOrder: propertiesOrderProp,
27
+ additionalFields,
28
+ errors,
29
+ onPropertyMove,
30
+ onPropertyRemove,
31
+ className,
32
+ inferredPropertyKeys,
33
+ collectionEditable
34
+ }: {
35
+ namespace?: string;
36
+ selectedPropertyKey?: string;
37
+ onPropertyClick?: (propertyKey: string, namespace?: string) => void;
38
+ properties: PropertiesOrBuilders<M>;
39
+ propertiesOrder?: string[];
40
+ additionalFields?: AdditionalFieldDelegate<M>[];
41
+ errors: Record<string, any>;
42
+ onPropertyMove?: (propertiesOrder: string[], namespace?: string) => void;
43
+ onPropertyRemove?: (propertyKey: string, namespace?: string) => void;
44
+ className?: string;
45
+ inferredPropertyKeys?: string[];
46
+ collectionEditable: boolean;
47
+ }) {
48
+
49
+ const propertiesOrder = propertiesOrderProp ?? Object.keys(properties);
50
+
51
+ const onDragEnd = useCallback((result: any) => {
52
+ // dropped outside the list
53
+ if (!result.destination) {
54
+ return;
55
+ }
56
+ const startIndex = result.source.index;
57
+ const endIndex = result.destination.index;
58
+
59
+ const newPropertiesOrder = Array.from(propertiesOrder);
60
+ const [removed] = newPropertiesOrder.splice(startIndex, 1);
61
+ newPropertiesOrder.splice(endIndex, 0, removed);
62
+ if (onPropertyMove)
63
+ onPropertyMove(newPropertiesOrder, namespace);
64
+ }, [namespace, onPropertyMove, propertiesOrder])
65
+
66
+ return (
67
+ <>
68
+
69
+ <DragDropContext onDragEnd={onDragEnd}>
70
+ <Droppable droppableId={`droppable_${namespace}`}>
71
+ {(droppableProvided, droppableSnapshot) => (
72
+ <div
73
+ {...droppableProvided.droppableProps}
74
+ ref={droppableProvided.innerRef}
75
+ className={className}>
76
+ {propertiesOrder && propertiesOrder
77
+ .map((propertyKey: string, index: number) => {
78
+ const property = properties[propertyKey] as PropertyOrBuilder;
79
+ const additionalField = additionalFields?.find(field => field.key === propertyKey);
80
+
81
+ if (!property && !additionalField) {
82
+ console.warn(`Property ${propertyKey} not found in properties or additionalFields`);
83
+ return null;
84
+ }
85
+ return (
86
+ <Draggable
87
+ key={`array_field_${namespace}_${propertyKey}}`}
88
+ draggableId={`array_field_${namespace}_${propertyKey}}`}
89
+ index={index}>
90
+ {(provided, snapshot) => {
91
+ return (
92
+ <ErrorBoundary>
93
+ <PropertyTreeEntry
94
+ propertyKey={propertyKey as string}
95
+ propertyOrBuilder={property}
96
+ additionalField={additionalField}
97
+ provided={provided}
98
+ errors={errors}
99
+ namespace={namespace}
100
+ inferredPropertyKeys={inferredPropertyKeys}
101
+ onPropertyMove={onPropertyMove}
102
+ onPropertyRemove={onPropertyRemove}
103
+ onPropertyClick={snapshot.isDragging ? undefined : onPropertyClick}
104
+ selectedPropertyKey={selectedPropertyKey}
105
+ collectionEditable={collectionEditable}
106
+ />
107
+ </ErrorBoundary>
108
+ );
109
+ }}
110
+ </Draggable>);
111
+ }).filter(Boolean)}
112
+
113
+ {droppableProvided.placeholder}
114
+
115
+ </div>
116
+ )}
117
+ </Droppable>
118
+ </DragDropContext>
119
+
120
+ </>
121
+ );
122
+ },
123
+ (prevProps, nextProps) => {
124
+
125
+ const isSelected = nextProps.selectedPropertyKey?.startsWith(nextProps.namespace ?? "");
126
+ const wasSelected = prevProps.selectedPropertyKey?.startsWith(prevProps.namespace ?? "");
127
+ if (isSelected || wasSelected)
128
+ return false;
129
+
130
+ return equal(prevProps.properties, nextProps.properties) &&
131
+ prevProps.propertiesOrder === nextProps.propertiesOrder &&
132
+ equal(prevProps.additionalFields, nextProps.additionalFields) &&
133
+ equal(prevProps.errors, nextProps.errors) &&
134
+ equal(prevProps.onPropertyClick, nextProps.onPropertyClick) &&
135
+ // equal(prevProps.onPropertyMove, nextProps.onPropertyMove) &&
136
+ // equal(prevProps.onPropertyRemove, nextProps.onPropertyRemove) &&
137
+ prevProps.namespace === nextProps.namespace &&
138
+ prevProps.collectionEditable === nextProps.collectionEditable;
139
+ }
140
+ );
122
141
 
123
142
  export function PropertyTreeEntry({
124
143
  propertyKey,
@@ -132,7 +151,7 @@ export function PropertyTreeEntry({
132
151
  onPropertyMove,
133
152
  onPropertyRemove,
134
153
  inferredPropertyKeys,
135
- collectionEditable,
154
+ collectionEditable
136
155
  }: {
137
156
  propertyKey: string;
138
157
  namespace?: string;
@@ -149,8 +168,9 @@ export function PropertyTreeEntry({
149
168
  }) {
150
169
 
151
170
  const isPropertyInferred = inferredPropertyKeys?.includes(namespace ? `${namespace}.${propertyKey}` : propertyKey);
152
-
153
171
  const fullId = getFullId(propertyKey, namespace);
172
+ const fullIdPath = getFullIdPath(propertyKey, namespace);
173
+ const hasError = fullIdPath in errors;
154
174
 
155
175
  let subtree;
156
176
  if (typeof propertyOrBuilder === "object") {
@@ -170,7 +190,7 @@ export function PropertyTreeEntry({
170
190
  }
171
191
  }
172
192
 
173
- const hasError = fullId ? getIn(errors, idToPropertiesPath(fullId)) : false;
193
+ // const hasError = fullId ? getIn(errors, idToPropertiesPath(fullId)) : false;
174
194
  const selected = selectedPropertyKey === fullId;
175
195
  const editable = propertyOrBuilder && ((collectionEditable && !isPropertyBuilder(propertyOrBuilder)) || editableProperty(propertyOrBuilder));
176
196
 
@@ -225,7 +245,6 @@ export function PropertyTreeEntry({
225
245
  </Tooltip>}
226
246
  </div>
227
247
 
228
-
229
248
  {subtree && <div className={"ml-16"}>{subtree}</div>}
230
249
  </div>
231
250
  );
@@ -9,11 +9,11 @@ import {
9
9
  } from "@firecms/core";
10
10
  import {
11
11
  AddIcon,
12
+ Alert,
12
13
  Button,
13
14
  Container,
14
15
  DeleteIcon,
15
16
  IconButton,
16
- InfoLabel,
17
17
  Paper,
18
18
  Table,
19
19
  TableBody,
@@ -22,12 +22,12 @@ import {
22
22
  Tooltip,
23
23
  Typography,
24
24
  } from "@firecms/ui";
25
- import { useFormikContext } from "formik";
26
25
  import { CollectionEditorDialog } from "./CollectionEditorDialog";
27
26
  import { CollectionsConfigController } from "../../types/config_controller";
28
27
  import { PersistedCollection } from "../../types/persisted_collection";
29
28
  import { CollectionInference } from "../../types/collection_inference";
30
29
  import { EntityCustomViewsSelectDialog } from "./EntityCustomViewsSelectDialog";
30
+ import { useFormex } from "../../form/Formex";
31
31
 
32
32
  export function SubcollectionsEditTab({
33
33
  collection,
@@ -59,7 +59,7 @@ export function SubcollectionsEditTab({
59
59
  const {
60
60
  values,
61
61
  setFieldValue,
62
- } = useFormikContext<EntityCollection>();
62
+ } = useFormex<EntityCollection>();
63
63
 
64
64
  const subcollections = collection.subcollections ?? [];
65
65
  const resolvedEntityViews = values.entityViews?.filter(e => typeof e === "string")
@@ -101,7 +101,7 @@ export function SubcollectionsEditTab({
101
101
  onClick={(e) => {
102
102
  e.preventDefault();
103
103
  e.stopPropagation();
104
- setSubcollectionToDelete(subcollection.path);
104
+ setSubcollectionToDelete(subcollection.id);
105
105
  }}
106
106
  color="inherit">
107
107
  <DeleteIcon size={"small"}/>
@@ -180,9 +180,14 @@ export function SubcollectionsEditTab({
180
180
  </>}
181
181
 
182
182
  {totalEntityViews === 0 &&
183
- <InfoLabel>
184
- <b>COMING SOON</b> Define your own custom views by uploading it with the CLI
185
- </InfoLabel>
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>
186
191
  }
187
192
 
188
193
  <Button
@@ -204,10 +209,12 @@ export function SubcollectionsEditTab({
204
209
  {subcollectionToDelete &&
205
210
  <DeleteConfirmationDialog open={Boolean(subcollectionToDelete)}
206
211
  onAccept={() => {
207
- configController.deleteCollection({
208
- path: subcollectionToDelete,
209
- parentCollectionIds: [...(parentCollectionIds ?? []), collection.path]
210
- });
212
+ const props = {
213
+ id: subcollectionToDelete,
214
+ parentCollectionIds: [...(parentCollectionIds ?? []), collection.id]
215
+ };
216
+ console.debug("Deleting subcollection", props)
217
+ configController.deleteCollection(props);
211
218
  setSubcollectionToDelete(undefined);
212
219
  }}
213
220
  onCancel={() => setSubcollectionToDelete(undefined)}
@@ -0,0 +1,39 @@
1
+ import React from "react";
2
+
3
+ import { BooleanSwitchWithLabel, Tooltip } from "@firecms/ui";
4
+ import { FormexFieldProps } from "../../form";
5
+
6
+ export function SwitchControl({
7
+ field,
8
+ form,
9
+ label,
10
+ tooltip,
11
+ disabled,
12
+ size = "small",
13
+ allowIndeterminate
14
+ }: FormexFieldProps & {
15
+ label: string,
16
+ tooltip?: string,
17
+ disabled?: boolean,
18
+ size?: "small" | "medium",
19
+ allowIndeterminate?: boolean
20
+ }) {
21
+
22
+ const formControlLabel = <BooleanSwitchWithLabel
23
+ label={label}
24
+ size={size}
25
+ position={"start"}
26
+ value={field.value}
27
+ disabled={disabled}
28
+ allowIndeterminate={allowIndeterminate}
29
+ onValueChange={(checked:boolean | null) => form.setFieldValue(field.name, checked)}/>;
30
+
31
+ if (tooltip)
32
+ return (
33
+ <Tooltip
34
+ title={tooltip}>
35
+ {formControlLabel}
36
+ </Tooltip>
37
+ );
38
+ return formControlLabel;
39
+ }
@@ -4,7 +4,7 @@ import {
4
4
  ImportConfig,
5
5
  ImportNewPropertyFieldPreview
6
6
  } from "@firecms/data_import_export";
7
- import { getIn, useFormikContext } from "formik";
7
+ import { getIn, useFormex } from "../../../form";
8
8
 
9
9
  import { PropertyConfigBadge, getFieldConfig, getFieldId, Properties, Property, PropertyConfig, } from "@firecms/core";
10
10
  import { Container, Select, Tooltip, Typography } from "@firecms/ui";
@@ -28,11 +28,19 @@ export function CollectionEditorImportMapping({
28
28
  collectionEditable: boolean
29
29
  }) {
30
30
 
31
+ // const {
32
+ // values,
33
+ // setFieldValue,
34
+ // setFieldTouched,
35
+ // setValues,
36
+ // submitCount
37
+ // } = useFormex();
38
+
31
39
  const {
32
40
  setFieldValue,
33
41
  setFieldTouched,
34
42
  values
35
- } = useFormikContext<PersistedCollection>();
43
+ } = useFormex<PersistedCollection>();
36
44
  const [selectedProperty, setSelectedProperty] = useState<PropertyWithId | undefined>(undefined);
37
45
 
38
46
  const currentPropertiesOrderRef = React.useRef<{
@@ -1,6 +1,6 @@
1
1
  import React, { useCallback, useState } from "react";
2
2
  import { AddIcon, Button, Paper, Typography } from "@firecms/ui";
3
- import { getIn, useFormikContext } from "formik";
3
+ import { getIn, useFormex } from "../../../form";
4
4
  import { PropertyFormDialog } from "../PropertyEditView";
5
5
  import { getFullId, idToPropertiesPath, namespaceToPropertiesOrderPath } from "../util";
6
6
  import { PropertyTree } from "../PropertyTree";
@@ -17,7 +17,7 @@ export function BlockPropertyField({ disabled, getData, allowDataInference, prop
17
17
  const {
18
18
  values,
19
19
  setFieldValue
20
- } = useFormikContext<ArrayProperty>();
20
+ } = useFormex<ArrayProperty>();
21
21
 
22
22
  const [propertyDialogOpen, setPropertyDialogOpen] = useState<boolean>(false);
23
23
  const [selectedPropertyKey, setSelectedPropertyKey] = useState<string | undefined>();
@@ -1,14 +1,14 @@
1
1
  import React from "react";
2
- import { FastField, getIn, useFormikContext } from "formik";
2
+ import { Field, FormexFieldProps, getIn, useFormex } from "../../../form";
3
3
 
4
4
  import { GeneralPropertyValidation } from "./validation/GeneralPropertyValidation";
5
5
  import { ValidationPanel } from "./validation/ValidationPanel";
6
- import { SwitchControl } from "@firecms/core";
6
+ import { SwitchControl } from "../SwitchControl";
7
7
 
8
8
  export function BooleanPropertyField({ disabled }: {
9
9
  disabled: boolean;
10
10
  }) {
11
- const { values } = useFormikContext();
11
+ const { values } = useFormex();
12
12
  const defaultValue = getIn(values, "defaultValue");
13
13
 
14
14
  return (
@@ -23,12 +23,16 @@ export function BooleanPropertyField({ disabled }: {
23
23
 
24
24
  <div className={"col-span-12"}>
25
25
 
26
- <FastField type="checkbox"
27
- name={"defaultValue"}
28
- label={defaultValue === null || defaultValue === undefined ? "Default value not set" : ("Default value is " + defaultValue.toString())}
29
- disabled={disabled}
30
- allowIndeterminate={true}
31
- component={SwitchControl}/>
26
+ <Field
27
+ name={"defaultValue"}>
28
+ {({ field, form }: FormexFieldProps) => {
29
+ return <SwitchControl
30
+ label={defaultValue === null || defaultValue === undefined ? "Default value not set" : ("Default value is " + defaultValue.toString())}
31
+ disabled={disabled}
32
+ allowIndeterminate={true} field={field}
33
+ form={form}/>
34
+ }}
35
+ </Field>
32
36
 
33
37
  </div>
34
38
  </>
@@ -1,4 +1,4 @@
1
- import { Field, getIn, useFormikContext } from "formik";
1
+ import { Field, getIn, useFormex } from "../../../form";
2
2
  import { DebouncedTextField } from "@firecms/ui";
3
3
  import { PropertyWithId } from "../PropertyEditView";
4
4
  import React from "react";
@@ -8,7 +8,6 @@ import { toSnakeCase, unslugify } from "@firecms/core";
8
8
  type CommonPropertyFieldsProps = {
9
9
  showErrors: boolean,
10
10
  disabledId: boolean,
11
- existingPropertyKeys?: string[];
12
11
  disabled: boolean;
13
12
  isNewProperty: boolean;
14
13
  autoUpdateId: boolean;
@@ -18,7 +17,6 @@ export const CommonPropertyFields = React.forwardRef<HTMLDivElement, CommonPrope
18
17
  function CommonPropertyFields({
19
18
  showErrors,
20
19
  disabledId,
21
- existingPropertyKeys,
22
20
  disabled,
23
21
  autoUpdateId,
24
22
  isNewProperty
@@ -29,8 +27,9 @@ export const CommonPropertyFields = React.forwardRef<HTMLDivElement, CommonPrope
29
27
  values,
30
28
  setFieldValue,
31
29
  setFieldTouched,
32
- touched
33
- } = useFormikContext<PropertyWithId>();
30
+ touched,
31
+ validate
32
+ } = useFormex<PropertyWithId>();
34
33
 
35
34
  const name = "name";
36
35
  const nameError = showErrors && getIn(errors, name);
@@ -46,20 +45,20 @@ export const CommonPropertyFields = React.forwardRef<HTMLDivElement, CommonPrope
46
45
 
47
46
  <div>
48
47
  <Field
48
+ name={name}
49
49
  inputRef={ref}
50
50
  as={DebouncedTextField}
51
51
  value={values[name]}
52
52
  onChange={(e: any) => {
53
53
  const newNameValue = e.target.value;
54
- setFieldValue(name, newNameValue);
55
- setFieldTouched(name, true, true);
56
54
  const idTouched = getIn(touched, id);
57
55
  if (!idTouched && autoUpdateId) {
58
- setFieldValue(id, newNameValue ? toSnakeCase(newNameValue) : "")
56
+ setFieldValue(id, newNameValue ? toSnakeCase(newNameValue) : "", false)
59
57
  }
58
+ setFieldValue(name, newNameValue, true);
59
+ setFieldTouched(name, true);
60
60
  }}
61
61
  style={{ fontSize: 20 }}
62
- validate={validateName}
63
62
  placeholder={"Field name"}
64
63
  required
65
64
  disabled={disabled}
@@ -72,19 +71,19 @@ export const CommonPropertyFields = React.forwardRef<HTMLDivElement, CommonPrope
72
71
 
73
72
  <div>
74
73
  <Field
74
+ name={id}
75
75
  as={DebouncedTextField}
76
76
  label={"ID"}
77
77
  value={values[id]}
78
78
  onChange={(e: any) => {
79
79
  const newIdValue = e.target.value;
80
- setFieldValue(id, newIdValue);
81
- setFieldTouched(id, true, true);
82
80
  const nameTouched = getIn(touched, name);
83
81
  if (!nameTouched && autoUpdateId) {
84
82
  setFieldValue(name, newIdValue ? unslugify(newIdValue) : "")
85
83
  }
84
+ setFieldValue(id, newIdValue, true);
85
+ setFieldTouched(id, true);
86
86
  }}
87
- validate={() => validateId(values[id], existingPropertyKeys)}
88
87
  disabled={disabledId || disabled}
89
88
  required
90
89
  size="small"
@@ -110,28 +109,3 @@ export const CommonPropertyFields = React.forwardRef<HTMLDivElement, CommonPrope
110
109
 
111
110
  }
112
111
  );
113
-
114
- const idRegEx = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
115
-
116
- function validateId(value?: string, existingPropertyKeys?: string[]) {
117
-
118
- let error;
119
- if (!value) {
120
- error = "You must specify an id for the field";
121
- }
122
- if (value && !value.match(idRegEx)) {
123
- error = "The id can only contain letters, numbers and underscores (_), and not start with a number";
124
- }
125
- if (value && existingPropertyKeys && existingPropertyKeys.includes(value)) {
126
- error = "There is another field with this ID already";
127
- }
128
- return error;
129
- }
130
-
131
- function validateName(value: string) {
132
- let error;
133
- if (!value) {
134
- error = "You must specify a title for the field";
135
- }
136
- return error;
137
- }
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { getIn, useFormikContext } from "formik";
2
+ import { getIn, useFormex } from "../../../form";
3
3
  import { NumberProperty, StringProperty } from "@firecms/core";
4
4
  import { Select, SelectItem } from "@firecms/ui";
5
5
  import { GeneralPropertyValidation } from "./validation/GeneralPropertyValidation";
@@ -15,7 +15,7 @@ export function DateTimePropertyField({ disabled }: {
15
15
  errors,
16
16
  touched,
17
17
  setFieldValue
18
- } = useFormikContext<StringProperty | NumberProperty>();
18
+ } = useFormex<StringProperty | NumberProperty>();
19
19
 
20
20
  const modePath = "mode";
21
21
  const modeValue: string | undefined = getIn(values, modePath);
@@ -1,5 +1,5 @@
1
1
  import React, { useMemo } from "react";
2
- import { getIn, useFormikContext } from "formik";
2
+ import { getIn, useFormex } from "../../../form";
3
3
  import { EnumValueConfig, resolveEnumValues, useSnackbarController } from "@firecms/core";
4
4
  import { Select, SelectItem } from "@firecms/ui";
5
5
  import { EnumForm } from "../EnumForm";
@@ -26,12 +26,9 @@ export function EnumPropertyField({
26
26
 
27
27
  const {
28
28
  values,
29
- handleChange,
30
- errors,
31
- touched,
32
29
  setFieldError,
33
30
  setFieldValue
34
- } = useFormikContext<PropertyWithId>();
31
+ } = useFormex<PropertyWithId>();
35
32
 
36
33
  const snackbarContext = useSnackbarController();
37
34
 
@@ -70,7 +67,7 @@ export function EnumPropertyField({
70
67
  disabled={disabled}
71
68
  allowDataInference={allowDataInference}
72
69
  onError={(hasError) => {
73
- setFieldError(enumValuesPath, hasError ? "" : undefined);
70
+ setFieldError(enumValuesPath, hasError ? "This enum property is missing some values" : undefined);
74
71
  }}
75
72
  getData={getData
76
73
  ? () => getData()