@firecms/core 3.0.0-beta.10 → 3.0.0-beta.11

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 (166) hide show
  1. package/dist/components/ArrayContainer.d.ts +17 -5
  2. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  5. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +1 -1
  6. package/dist/core/EntityEditView.d.ts +1 -1
  7. package/dist/core/FireCMS.d.ts +1 -1
  8. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  9. package/dist/form/components/index.d.ts +0 -1
  10. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  11. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  12. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  13. package/dist/hooks/data/delete.d.ts +4 -4
  14. package/dist/hooks/data/save.d.ts +3 -3
  15. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  16. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  17. package/dist/hooks/useAuthController.d.ts +1 -1
  18. package/dist/hooks/useBuildNavigationController.d.ts +3 -3
  19. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  20. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  21. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  22. package/dist/index.es.js +17515 -14786
  23. package/dist/index.es.js.map +1 -1
  24. package/dist/index.umd.js +17912 -15184
  25. package/dist/index.umd.js.map +1 -1
  26. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  27. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  28. package/dist/preview/util.d.ts +3 -3
  29. package/dist/types/auth.d.ts +7 -9
  30. package/dist/types/collections.d.ts +14 -13
  31. package/dist/types/datasource.d.ts +0 -4
  32. package/dist/types/entity_actions.d.ts +4 -4
  33. package/dist/types/entity_callbacks.d.ts +16 -16
  34. package/dist/types/export_import.d.ts +4 -4
  35. package/dist/types/fields.d.ts +18 -2
  36. package/dist/types/firecms.d.ts +2 -2
  37. package/dist/types/firecms_context.d.ts +1 -1
  38. package/dist/types/permissions.d.ts +4 -4
  39. package/dist/types/plugins.d.ts +8 -8
  40. package/dist/types/property_config.d.ts +0 -2
  41. package/dist/types/user.d.ts +1 -0
  42. package/dist/util/builders.d.ts +2 -2
  43. package/dist/util/entities.d.ts +1 -1
  44. package/dist/util/icon_synonyms.d.ts +0 -1
  45. package/dist/util/icons.d.ts +3 -1
  46. package/dist/util/objects.d.ts +1 -0
  47. package/dist/util/permissions.d.ts +4 -4
  48. package/dist/util/property_utils.d.ts +2 -2
  49. package/dist/util/resolutions.d.ts +6 -6
  50. package/package.json +131 -125
  51. package/src/app/Scaffold.tsx +4 -4
  52. package/src/components/ArrayContainer.tsx +79 -17
  53. package/src/components/CircularProgressCenter.tsx +1 -1
  54. package/src/components/ConfirmationDialog.tsx +2 -2
  55. package/src/components/DeleteEntityDialog.tsx +9 -18
  56. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -1
  57. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +14 -14
  58. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +2 -2
  59. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
  60. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
  61. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
  62. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
  63. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
  64. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
  65. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +79 -69
  66. package/src/components/EntityCollectionView/EntityCollectionView.tsx +9 -10
  67. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  68. package/src/components/EntityPreview.tsx +39 -30
  69. package/src/components/EntityView.tsx +5 -5
  70. package/src/components/ErrorView.tsx +3 -3
  71. package/src/components/HomePage/DefaultHomePage.tsx +1 -0
  72. package/src/components/HomePage/FavouritesView.tsx +6 -11
  73. package/src/components/HomePage/NavigationCard.tsx +1 -1
  74. package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
  75. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  76. package/src/components/PropertyConfigBadge.tsx +1 -1
  77. package/src/components/PropertyIdCopyTooltip.tsx +1 -1
  78. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +2 -2
  79. package/src/components/SelectableTable/SelectableTable.tsx +2 -2
  80. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  81. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +3 -1
  82. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
  83. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  84. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  85. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  86. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  87. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
  88. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +2 -2
  89. package/src/contexts/SnackbarProvider.tsx +2 -0
  90. package/src/core/DefaultAppBar.tsx +12 -11
  91. package/src/core/DefaultDrawer.tsx +11 -9
  92. package/src/core/DrawerNavigationItem.tsx +4 -4
  93. package/src/core/EntityEditView.tsx +50 -52
  94. package/src/core/FireCMS.tsx +5 -5
  95. package/src/core/SideDialogs.tsx +1 -1
  96. package/src/core/field_configs.tsx +4 -4
  97. package/src/form/PropertyFieldBinding.tsx +27 -20
  98. package/src/form/components/CustomIdField.tsx +2 -0
  99. package/src/form/components/StorageItemPreview.tsx +3 -3
  100. package/src/form/components/index.tsx +0 -1
  101. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +3 -2
  102. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +16 -10
  103. package/src/form/field_bindings/BlockFieldBinding.tsx +41 -23
  104. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  105. package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
  106. package/src/form/field_bindings/MapFieldBinding.tsx +58 -39
  107. package/src/form/field_bindings/ReferenceFieldBinding.tsx +4 -4
  108. package/src/form/field_bindings/RepeatFieldBinding.tsx +25 -20
  109. package/src/form/field_bindings/SelectFieldBinding.tsx +5 -4
  110. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +1 -1
  111. package/src/form/field_bindings/SwitchFieldBinding.tsx +25 -25
  112. package/src/form/field_bindings/TextFieldBinding.tsx +3 -3
  113. package/src/hooks/data/delete.ts +4 -4
  114. package/src/hooks/data/save.ts +7 -8
  115. package/src/hooks/data/useCollectionFetch.tsx +2 -2
  116. package/src/hooks/data/useEntityFetch.tsx +5 -5
  117. package/src/hooks/useAuthController.tsx +1 -1
  118. package/src/hooks/useBuildNavigationController.tsx +5 -6
  119. package/src/hooks/useFireCMSContext.tsx +5 -5
  120. package/src/hooks/useResolvedNavigationFrom.tsx +5 -5
  121. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  122. package/src/internal/useBuildDataSource.ts +1 -1
  123. package/src/internal/useUnsavedChangesDialog.tsx +2 -2
  124. package/src/preview/PropertyPreview.tsx +3 -3
  125. package/src/preview/PropertyPreviewProps.tsx +1 -1
  126. package/src/preview/components/BooleanPreview.tsx +1 -1
  127. package/src/preview/components/EmptyValue.tsx +1 -1
  128. package/src/preview/components/EnumValuesChip.tsx +1 -1
  129. package/src/preview/components/ImagePreview.tsx +5 -6
  130. package/src/preview/components/UrlComponentPreview.tsx +4 -4
  131. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  132. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  133. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
  134. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
  135. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  136. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
  137. package/src/preview/property_previews/MapPropertyPreview.tsx +4 -4
  138. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  139. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  140. package/src/preview/util.ts +10 -10
  141. package/src/types/auth.tsx +8 -12
  142. package/src/types/collections.ts +14 -13
  143. package/src/types/datasource.ts +0 -5
  144. package/src/types/entity_actions.tsx +4 -4
  145. package/src/types/entity_callbacks.ts +18 -18
  146. package/src/types/export_import.ts +4 -4
  147. package/src/types/fields.tsx +20 -2
  148. package/src/types/firecms.tsx +2 -2
  149. package/src/types/firecms_context.tsx +1 -1
  150. package/src/types/permissions.ts +5 -5
  151. package/src/types/plugins.tsx +8 -8
  152. package/src/types/property_config.tsx +0 -2
  153. package/src/types/user.ts +2 -0
  154. package/src/util/builders.ts +6 -6
  155. package/src/util/entities.ts +3 -1
  156. package/src/util/icon_list.ts +1 -0
  157. package/src/util/icon_synonyms.ts +0 -1
  158. package/src/util/icons.tsx +12 -8
  159. package/src/util/objects.ts +20 -0
  160. package/src/util/permissions.ts +8 -8
  161. package/src/util/property_utils.tsx +10 -3
  162. package/src/util/references.ts +8 -2
  163. package/src/util/resolutions.ts +8 -8
  164. package/src/util/useStorageUploadController.tsx +1 -1
  165. package/dist/form/components/FormikArrayContainer.d.ts +0 -19
  166. package/src/form/components/FormikArrayContainer.tsx +0 -47
@@ -1,8 +1,8 @@
1
1
  import React, { useCallback, useMemo } from "react";
2
2
  import { Entity, EntityCollection, EntityReference, FieldProps, ResolvedProperty } from "../../types";
3
3
  import { ReferencePreview } from "../../preview";
4
- import { FieldHelperText, FormikArrayContainer, LabelWithIconAndTooltip } from "../components";
5
- import { ErrorView } from "../../components";
4
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
5
+ import { ArrayContainer, ArrayEntryParams, ErrorView } from "../../components";
6
6
  import { getIconForProperty, getReferenceFrom } from "../../util";
7
7
 
8
8
  import { useNavigationController, useReferenceDialog } from "../../hooks";
@@ -74,7 +74,12 @@ export function ArrayOfReferencesFieldBinding({
74
74
  referenceDialogController.open();
75
75
  };
76
76
 
77
- const buildEntry = useCallback((index: number, internalId: number) => {
77
+ const buildEntry = useCallback(({
78
+ index,
79
+ internalId,
80
+ storedProps,
81
+ storeProps
82
+ }: ArrayEntryParams) => {
78
83
  const entryValue = value && value.length > index ? value[index] : undefined;
79
84
  if (!entryValue)
80
85
  return <div>Internal ERROR</div>;
@@ -109,13 +114,14 @@ export function ArrayOfReferencesFieldBinding({
109
114
 
110
115
  {collection && <div className={"group"}>
111
116
 
112
- <FormikArrayContainer value={value}
113
- addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
114
- name={propertyKey}
115
- buildEntry={buildEntry}
116
- disabled={isSubmitting}
117
- setFieldValue={setFieldValue}
118
- newDefaultEntry={property.of.defaultValue}/>
117
+ <ArrayContainer droppableId={propertyKey}
118
+ value={value}
119
+ disabled={isSubmitting}
120
+ buildEntry={buildEntry}
121
+ addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
122
+ newDefaultEntry={property.of.defaultValue}
123
+ onValueChange={(value) => setFieldValue(propertyKey, value)}
124
+ />
119
125
 
120
126
  <Button
121
127
  className="my-4 justify-center text-left"
@@ -2,14 +2,15 @@ import React, { useCallback, useEffect, useState } from "react";
2
2
 
3
3
  import { Field, useFormex } from "@firecms/formex";
4
4
 
5
- import { FieldHelperText, FormikArrayContainer, LabelWithIconAndTooltip } from "../components";
5
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
6
6
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
7
7
  import { EnumValuesChip } from "../../preview";
8
8
  import { FieldProps, FormContext, PropertyFieldBindingProps, PropertyOrBuilder } from "../../types";
9
- import { getDefaultValueFor, getIconForProperty, } from "../../util";
9
+ import { getDefaultValueFor, getIconForProperty, mergeDeep, } from "../../util";
10
10
  import { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from "../../util/common";
11
11
  import { cls, ExpandablePanel, paperMixin, Select, SelectItem, Typography } from "@firecms/ui";
12
12
  import { useClearRestoreValue } from "../useClearRestoreValue";
13
+ import { ArrayContainer, ArrayEntryParams } from "../../components";
13
14
 
14
15
  /**
15
16
  * If the `oneOf` property is specified, this fields render each array entry as
@@ -47,9 +48,15 @@ export function BlockFieldBinding<T extends Array<any>>({
47
48
 
48
49
  const [lastAddedId, setLastAddedId] = useState<number | undefined>();
49
50
 
50
- const buildEntry = useCallback((index: number, internalId: number) => {
51
+ const buildEntry = ({
52
+ index,
53
+ internalId,
54
+ storedProps,
55
+ storeProps
56
+ }: ArrayEntryParams) => {
57
+
51
58
  return <BlockEntry
52
- key={`array_one_of_${index}`}
59
+ key={`array_one_of_${internalId}`}
53
60
  name={`${propertyKey}.${index}`}
54
61
  index={index}
55
62
  value={value[index]}
@@ -57,8 +64,10 @@ export function BlockFieldBinding<T extends Array<any>>({
57
64
  valueField={property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE}
58
65
  properties={property.oneOf!.properties}
59
66
  autoFocus={internalId === lastAddedId}
60
- context={context}/>;
61
- }, [context, lastAddedId, property.oneOf, propertyKey, value]);
67
+ context={context}
68
+ storeProps={storeProps}
69
+ storedProps={storedProps}/>;
70
+ };
62
71
 
63
72
  const title = (
64
73
  <LabelWithIconAndTooltip
@@ -70,19 +79,19 @@ export function BlockFieldBinding<T extends Array<any>>({
70
79
  );
71
80
 
72
81
  const firstOneOfKey = Object.keys(property.oneOf.properties)[0];
73
- const body = <FormikArrayContainer value={value}
74
- className={"flex flex-col gap-3"}
75
- name={propertyKey}
76
- addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
77
- buildEntry={buildEntry}
78
- onInternalIdAdded={setLastAddedId}
79
- disabled={isSubmitting || Boolean(property.disabled)}
80
- includeAddButton={!property.disabled}
81
- setFieldValue={setFieldValue}
82
- newDefaultEntry={{
83
- [property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
84
- [property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE]: getDefaultValueFor(property.oneOf.properties[firstOneOfKey])
85
- }}/>;
82
+ const body = <ArrayContainer value={value}
83
+ className={"flex flex-col gap-3"}
84
+ droppableId={propertyKey}
85
+ addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
86
+ buildEntry={buildEntry}
87
+ onInternalIdAdded={setLastAddedId}
88
+ disabled={isSubmitting || Boolean(property.disabled)}
89
+ includeAddButton={!property.disabled}
90
+ onValueChange={(value) => setFieldValue(propertyKey, value)}
91
+ newDefaultEntry={{
92
+ [property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
93
+ [property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE]: getDefaultValueFor(property.oneOf.properties[firstOneOfKey])
94
+ }}/>;
86
95
  return (
87
96
 
88
97
  <>
@@ -134,6 +143,9 @@ interface BlockEntryProps {
134
143
  */
135
144
  context: FormContext<any>;
136
145
 
146
+ storedProps?: object,
147
+ storeProps: (props: object) => void
148
+
137
149
  }
138
150
 
139
151
  function BlockEntry({
@@ -144,7 +156,9 @@ function BlockEntry({
144
156
  valueField,
145
157
  properties,
146
158
  autoFocus,
147
- context
159
+ context,
160
+ storedProps,
161
+ storeProps
148
162
  }: BlockEntryProps) {
149
163
 
150
164
  const type = value && value[typeField];
@@ -164,7 +178,9 @@ function BlockEntry({
164
178
  }
165
179
  }, [type]);
166
180
 
167
- const property = typeInternal ? properties[typeInternal] : undefined;
181
+ const propertyInternal = typeInternal ? properties[typeInternal] : undefined;
182
+
183
+ const property = storedProps && typeof propertyInternal === "object" ? mergeDeep(propertyInternal, storedProps) : propertyInternal;
168
184
 
169
185
  const enumValuesConfigs = Object.entries(properties)
170
186
  .map(([key, property]) => ({
@@ -182,7 +198,8 @@ function BlockEntry({
182
198
  context,
183
199
  autoFocus,
184
200
  partOfArray: false,
185
- minimalistView: true
201
+ minimalistView: true,
202
+ onPropertyChange: storeProps,
186
203
  }
187
204
  : undefined;
188
205
 
@@ -208,7 +225,8 @@ function BlockEntry({
208
225
  className="mb-2"
209
226
  placeholder={<Typography variant={"caption"}
210
227
  className={"px-4 py-2 font-medium"}>Type</Typography>}
211
- size={"small"}
228
+ size={"medium"}
229
+ fullWidth={true}
212
230
  position={"item-aligned"}
213
231
  value={value1}
214
232
  renderValue={(enumKey: any) =>
@@ -46,7 +46,7 @@ export function DateTimeFieldBinding({
46
46
  <DateTimeField
47
47
  value={internalValue}
48
48
  onChange={(dateValue) => setValue(dateValue)}
49
- size={"medium"}
49
+ size={"large"}
50
50
  mode={property.mode}
51
51
  clearable={property.clearable}
52
52
  locale={locale}
@@ -270,7 +270,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
270
270
  placeholder={"value"}
271
271
  value={entryValue}
272
272
  type={dataType === "number" ? "number" : "text"}
273
- size={"small"}
273
+ size={"medium"}
274
274
  disabled={disabled || !fieldKey}
275
275
  onChange={(event) => {
276
276
  if (dataType === "number") {
@@ -300,7 +300,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
300
300
  }}/>;
301
301
  } else if (dataType === "date") {
302
302
  return <DateTimeField value={entryValue}
303
- size={"small"}
303
+ size={"medium"}
304
304
  locale={locale}
305
305
  disabled={disabled || !fieldKey}
306
306
  onChange={(date) => {
@@ -311,7 +311,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
311
311
  }}/>;
312
312
  } else if (dataType === "boolean") {
313
313
  return <BooleanSwitchWithLabel value={entryValue}
314
- size={"small"}
314
+ size={"medium"}
315
315
  position={"start"}
316
316
  disabled={disabled || !fieldKey}
317
317
  onValueChange={(newValue) => {
@@ -336,7 +336,10 @@ function MapKeyValueRow<T extends Record<string, any>>({
336
336
  [fieldKey]: newValue
337
337
  });
338
338
  }}
339
- buildEntry={(index, internalId) => {
339
+ buildEntry={({
340
+ index,
341
+ internalId
342
+ }) => {
340
343
  return <ArrayKeyValueRow
341
344
  index={index}
342
345
  id={internalId}
@@ -386,7 +389,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
386
389
  value={fieldKey}
387
390
  placeholder={"key"}
388
391
  disabled={disabled || (entryValue !== undefined && entryValue !== null && entryValue !== "")}
389
- size={"small"}
392
+ size={"medium"}
390
393
  onChange={(event) => {
391
394
  onFieldKeyChange(event.target.value);
392
395
  }}/>
@@ -454,7 +457,7 @@ function ArrayKeyValueRow<T>({
454
457
  if (dataType === "string" || dataType === "number") {
455
458
  return <TextField value={entryValue}
456
459
  type={dataType === "number" ? "number" : "text"}
457
- size={"small"}
460
+ size={"medium"}
458
461
  onChange={(event) => {
459
462
  if (dataType === "number") {
460
463
  const numberValue = event.target.value ? parseFloat(event.target.value) : undefined;
@@ -471,7 +474,7 @@ function ArrayKeyValueRow<T>({
471
474
  }}/>;
472
475
  } else if (dataType === "date") {
473
476
  return <DateTimeField value={entryValue}
474
- size={"small"}
477
+ size={"medium"}
475
478
  locale={locale}
476
479
  onChange={(date) => {
477
480
  setValue(date as T);
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
- import { FieldProps, Properties, ResolvedProperties } from "../../types";
2
+ import { FieldProps, MapProperty, Properties, PropertyFieldBindingProps, ResolvedProperties } from "../../types";
3
3
 
4
4
  import { ErrorBoundary } from "../../components";
5
- import { getIconForProperty, isHidden, pick } from "../../util";
5
+ import { getIconForProperty, isHidden, isReadOnly, pick } from "../../util";
6
6
  import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
7
7
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
8
8
  import { ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
@@ -25,11 +25,12 @@ export function MapFieldBinding({
25
25
  includeDescription,
26
26
  underlyingValueHasChanged,
27
27
  autoFocus,
28
- context
28
+ context,
29
+ onPropertyChange
29
30
  }: FieldProps<Record<string, any>>) {
30
31
 
31
32
  const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
32
- const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
33
+ const expanded = property.expanded === undefined ? true : property.expanded;
33
34
 
34
35
  if (!property.properties) {
35
36
  throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
@@ -50,37 +51,48 @@ export function MapFieldBinding({
50
51
  }
51
52
 
52
53
  const mapFormView = <>
53
- <div className="py-1 flex flex-col space-y-2">
54
- {Object.entries(mapProperties)
55
- .filter(([_, property]) => !isHidden(property))
56
- .map(([entryKey, childProperty], index) => {
57
- const fieldBindingProps = {
58
- propertyKey: `${propertyKey}.${entryKey}`,
59
- disabled,
60
- property: childProperty,
61
- includeDescription,
62
- underlyingValueHasChanged,
63
- context,
64
- partOfArray: false,
65
- minimalistView: false,
66
- autoFocus: autoFocus && index === 0
67
- };
68
-
69
- return (
70
- <div key={`map-${propertyKey}-${index}`}>
71
- <ErrorBoundary>
72
- <PropertyFieldBinding
73
- {...fieldBindingProps}/>
74
- </ErrorBoundary>
75
- </div>
76
- );
77
- }
78
- )}
79
- </div>
80
-
81
- {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}
82
-
83
- </>;
54
+ <div className="py-1 flex flex-col space-y-2">
55
+ {Object.entries(mapProperties)
56
+ .filter(([_, property]) => !isHidden(property))
57
+ .map(([entryKey, childProperty], index) => {
58
+ const thisDisabled = isReadOnly(childProperty) || Boolean(childProperty.disabled);
59
+ const fieldBindingProps: PropertyFieldBindingProps<any> = {
60
+ propertyKey: `${propertyKey}.${entryKey}`,
61
+ disabled: disabled || thisDisabled,
62
+ property: childProperty,
63
+ includeDescription,
64
+ underlyingValueHasChanged,
65
+ context,
66
+ partOfArray: false,
67
+ minimalistView: false,
68
+ autoFocus: autoFocus && index === 0,
69
+ onPropertyChange: function (updatedProperty) {
70
+ onPropertyChange?.({
71
+ properties: {
72
+ [entryKey]: updatedProperty
73
+ }
74
+ } as Partial<MapProperty>);
75
+ }
76
+ };
77
+
78
+ return (
79
+ <div key={`map-${propertyKey}-${index}`}>
80
+ <ErrorBoundary>
81
+ <PropertyFieldBinding
82
+ {...fieldBindingProps}/>
83
+ </ErrorBoundary>
84
+ </div>
85
+ )
86
+ ;
87
+ }
88
+ )
89
+ }
90
+ </div>
91
+
92
+ {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}
93
+
94
+ </>
95
+ ;
84
96
 
85
97
  const title = (
86
98
  <LabelWithIconAndTooltip
@@ -94,11 +106,16 @@ export function MapFieldBinding({
94
106
  return (
95
107
  <ErrorBoundary>
96
108
 
97
- {!minimalistView && !minimalistView && <ExpandablePanel initiallyExpanded={expanded}
98
- innerClassName={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-white dark:bg-gray-900"}
99
- title={title}>{mapFormView}</ExpandablePanel>}
109
+ {!minimalistView && <ExpandablePanel initiallyExpanded={expanded}
110
+ onExpandedChange={(expanded) => {
111
+ onPropertyChange?.({
112
+ expanded
113
+ });
114
+ }}
115
+ innerClassName={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-white dark:bg-surface-900"}
116
+ title={title}>{mapFormView}</ExpandablePanel>}
100
117
 
101
- {(minimalistView || minimalistView) && mapFormView}
118
+ {minimalistView && mapFormView}
102
119
 
103
120
  <FieldHelperText includeDescription={includeDescription}
104
121
  showError={showError ?? false}
@@ -128,6 +145,8 @@ const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue
128
145
  <InputLabel>Add property</InputLabel>
129
146
  <Select
130
147
  value={""}
148
+ size={"large"}
149
+ fullWidth={true}
131
150
  disabled={disabled}
132
151
  onValueChange={handleAddProperty}
133
152
  renderValue={(key) => (properties as Properties)[key].name || key}>
@@ -18,7 +18,7 @@ import { cls } from "@firecms/ui";
18
18
  * and tables to the specified properties.
19
19
  * @group Form fields
20
20
  */
21
- export function ReferenceFieldBinding<M extends Record<string, any>>(props: FieldProps<EntityReference>) {
21
+ export function ReferenceFieldBinding(props: FieldProps) {
22
22
 
23
23
  if (typeof props.property.path !== "string") {
24
24
  return <ReadOnlyFieldBinding {...props}/>
@@ -111,12 +111,12 @@ function ReferenceFieldBindingInternal({
111
111
  {!value && <div className="justify-center text-left">
112
112
  <EntityPreviewContainer className={cls("px-6 h-16 text-sm font-medium flex items-center gap-6",
113
113
  disabled || isSubmitting
114
- ? "text-slate-500"
115
- : "cursor-pointer text-slate-700 dark:text-slate-300 hover:bg-slate-50 dark:hover:bg-gray-800 group-hover:bg-slate-50 dark:group-hover:bg-gray-800")}
114
+ ? "text-surface-accent-500"
115
+ : "cursor-pointer text-surface-accent-700 dark:text-surface-accent-300 hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800")}
116
116
  onClick={onEntryClick}
117
117
  size={"medium"}>
118
118
  <IconForView collectionOrView={collection}
119
- className={"text-gray-300 dark:text-gray-600"}/>
119
+ className={"text-surface-300 dark:text-surface-600"}/>
120
120
  {`Edit ${property.name}`.toUpperCase()}
121
121
  </EntityPreviewContainer>
122
122
  </div>}
@@ -1,8 +1,8 @@
1
1
  import React, { useState } from "react";
2
- import { CMSType, FieldProps, ResolvedProperty } from "../../types";
3
- import { FieldHelperText, FormikArrayContainer, LabelWithIconAndTooltip } from "../components";
4
- import { ErrorBoundary } from "../../components";
5
- import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty } from "../../util";
2
+ import { CMSType, FieldProps, PropertyFieldBindingProps, ResolvedProperty } from "../../types";
3
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
4
+ import { ArrayContainer, ArrayEntryParams, ErrorBoundary } from "../../components";
5
+ import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty, mergeDeep } from "../../util";
6
6
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
7
7
  import { ExpandablePanel, Typography } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
@@ -43,8 +43,6 @@ export function RepeatFieldBinding<T extends Array<any>>({
43
43
  ignoreMissingFields: false
44
44
  })
45
45
  }
46
- // if (!resolvedProperties || !Array.isArray(resolvedProperties))
47
- // throw Error("RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'");
48
46
 
49
47
  const expanded = property.expanded === undefined ? true : property.expanded;
50
48
  const ofProperty: ResolvedProperty<CMSType[]> = property.of as ResolvedProperty<CMSType[]>;
@@ -57,33 +55,40 @@ export function RepeatFieldBinding<T extends Array<any>>({
57
55
  setValue
58
56
  });
59
57
 
60
- const buildEntry = (index: number, internalId: number) => {
58
+ const buildEntry = ({
59
+ index,
60
+ internalId,
61
+ storedProps,
62
+ storeProps
63
+ }: ArrayEntryParams) => {
61
64
  const childProperty = resolvedProperties[index] ?? ofProperty;
62
- const fieldProps = {
65
+ const fieldProps: PropertyFieldBindingProps<any, any> = {
63
66
  propertyKey: `${propertyKey}.${index}`,
64
67
  disabled,
65
- property: childProperty,
68
+ property: storedProps ? mergeDeep(childProperty, storedProps) : childProperty,
69
+ onPropertyChange: storeProps,
66
70
  includeDescription,
67
71
  underlyingValueHasChanged,
68
72
  context,
69
73
  partOfArray: true,
70
74
  minimalistView: false,
71
- autoFocus: internalId === lastAddedId
75
+ autoFocus: internalId === lastAddedId,
72
76
  };
73
77
  return <ErrorBoundary>
74
78
  <PropertyFieldBinding {...fieldProps} index={index}/>
75
79
  </ErrorBoundary>;
76
80
  };
77
81
 
78
- const arrayContainer = <FormikArrayContainer value={value}
79
- addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
80
- name={propertyKey}
81
- setFieldValue={setFieldValue}
82
- buildEntry={buildEntry}
83
- onInternalIdAdded={setLastAddedId}
84
- disabled={isSubmitting || Boolean(property.disabled)}
85
- includeAddButton={!property.disabled}
86
- newDefaultEntry={getDefaultValueFor(property.of)}/>;
82
+ const arrayContainer = <ArrayContainer droppableId={propertyKey}
83
+ addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
84
+ value={value}
85
+ buildEntry={buildEntry}
86
+ onInternalIdAdded={setLastAddedId}
87
+ disabled={isSubmitting || Boolean(property.disabled)}
88
+ includeAddButton={!property.disabled}
89
+ newDefaultEntry={getDefaultValueFor(property.of)}
90
+ onValueChange={(value) => setFieldValue(propertyKey, value)}
91
+ />;
87
92
 
88
93
  const title = (<>
89
94
  <LabelWithIconAndTooltip
@@ -109,7 +114,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
109
114
 
110
115
  <FieldHelperText includeDescription={includeDescription}
111
116
  showError={showError}
112
- error={error}
117
+ error={error ? (typeof error === "string" ? error : "A property of this array/repeat has an error") : undefined}
113
118
  disabled={disabled}
114
119
  property={property}/>
115
120
 
@@ -4,7 +4,7 @@ import { EnumType, FieldProps } from "../../types";
4
4
  import { FieldHelperText, LabelWithIcon } from "../components";
5
5
  import { EnumValuesChip } from "../../preview";
6
6
  import { getIconForProperty, resolveEnumValues } from "../../util";
7
- import { ClearIcon, cls, IconButton, Select, SelectItem } from "@firecms/ui";
7
+ import { CloseIcon, cls, IconButton, Select, SelectItem } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
  import { PropertyIdCopyTooltip } from "../../components";
10
10
 
@@ -29,7 +29,7 @@ export function SelectFieldBinding<T extends EnumType>({
29
29
  touched,
30
30
  property,
31
31
  includeDescription,
32
- size = "medium"
32
+ size = "large"
33
33
  }: SelectProps<T>) {
34
34
 
35
35
  const enumValues = resolveEnumValues(property.enumValues ?? []);
@@ -50,9 +50,10 @@ export function SelectFieldBinding<T extends EnumType>({
50
50
  <>
51
51
 
52
52
  <Select
53
- size={size === "medium" ? "medium" : "small"}
54
53
  value={value !== undefined && value != null ? value.toString() : ""}
55
54
  disabled={disabled}
55
+ size={size}
56
+ fullWidth={true}
56
57
  position="item-aligned"
57
58
  inputClassName={cls("w-full")}
58
59
  label={
@@ -67,7 +68,7 @@ export function SelectFieldBinding<T extends EnumType>({
67
68
  endAdornment={
68
69
  property.clearable && <IconButton
69
70
  onClick={handleClearClick}>
70
- <ClearIcon/>
71
+ <CloseIcon/>
71
72
  </IconButton>
72
73
  }
73
74
  onValueChange={(updatedValue: string) => {
@@ -339,7 +339,7 @@ export function StorageUpload({
339
339
  }
340
340
 
341
341
  const metadata: Record<string, unknown> | undefined = storage?.metadata;
342
- const size = multipleFilesSupported ? "small" : "medium";
342
+ const size = multipleFilesSupported ? "medium" : "large";
343
343
 
344
344
  const moveItem = useCallback((fromIndex: number, toIndex: number) => {
345
345
  if (!multipleFilesSupported) return;
@@ -16,18 +16,18 @@ type SwitchFieldProps = FieldProps<boolean>;
16
16
  * and tables to the specified properties.
17
17
  * @group Form fields
18
18
  */
19
- export const SwitchFieldBinding = React.forwardRef(function SwitchFieldBinding({
20
- propertyKey,
21
- value,
22
- setValue,
23
- error,
24
- showError,
25
- autoFocus,
26
- disabled,
27
- size = "medium",
28
- property,
29
- includeDescription
30
- }: SwitchFieldProps, ref) {
19
+ export const SwitchFieldBinding = function SwitchFieldBinding({
20
+ propertyKey,
21
+ value,
22
+ setValue,
23
+ error,
24
+ showError,
25
+ autoFocus,
26
+ disabled,
27
+ size = "large",
28
+ property,
29
+ includeDescription
30
+ }: SwitchFieldProps) {
31
31
 
32
32
  useClearRestoreValue({
33
33
  property,
@@ -39,18 +39,18 @@ export const SwitchFieldBinding = React.forwardRef(function SwitchFieldBinding({
39
39
  <>
40
40
 
41
41
  <PropertyIdCopyTooltip propertyKey={propertyKey}>
42
- <BooleanSwitchWithLabel
43
- value={value}
44
- onValueChange={(v) => setValue(v)}
45
- error={showError}
46
- label={<LabelWithIcon
47
- icon={getIconForProperty(property, "small")}
48
- required={property.validation?.required}
49
- title={property.name}/>}
50
- disabled={disabled}
51
- autoFocus={autoFocus}
52
- size={size}
53
- />
42
+ <BooleanSwitchWithLabel
43
+ value={value}
44
+ onValueChange={(v) => setValue(v)}
45
+ error={showError}
46
+ label={<LabelWithIcon
47
+ icon={getIconForProperty(property, "small")}
48
+ required={property.validation?.required}
49
+ title={property.name}/>}
50
+ disabled={disabled}
51
+ autoFocus={autoFocus}
52
+ size={size}
53
+ />
54
54
  </PropertyIdCopyTooltip>
55
55
 
56
56
  <FieldHelperText includeDescription={includeDescription}
@@ -61,4 +61,4 @@ export const SwitchFieldBinding = React.forwardRef(function SwitchFieldBinding({
61
61
  </>
62
62
 
63
63
  );
64
- });
64
+ };