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

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 (267) hide show
  1. package/dist/components/ArrayContainer.d.ts +22 -6
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  5. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  6. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
  8. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  9. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  10. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  11. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  12. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  13. package/dist/components/common/default_entity_actions.d.ts +0 -2
  14. package/dist/components/common/index.d.ts +1 -1
  15. package/dist/components/common/useColumnsIds.d.ts +1 -0
  16. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  17. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  18. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  19. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  20. package/dist/core/EntityEditView.d.ts +30 -22
  21. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  22. package/dist/core/FireCMS.d.ts +1 -1
  23. package/dist/core/FireCMSRouter.d.ts +4 -0
  24. package/dist/core/NavigationRoutes.d.ts +0 -1
  25. package/dist/core/SideDialogs.d.ts +4 -2
  26. package/dist/core/index.d.ts +2 -1
  27. package/dist/form/EntityForm.d.ts +45 -0
  28. package/dist/form/EntityFormActions.d.ts +17 -0
  29. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  30. package/dist/form/components/FormEntry.d.ts +6 -0
  31. package/dist/form/components/FormLayout.d.ts +5 -0
  32. package/dist/form/components/index.d.ts +2 -1
  33. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  34. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  39. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  41. package/dist/form/index.d.ts +16 -16
  42. package/dist/hooks/data/delete.d.ts +4 -4
  43. package/dist/hooks/data/save.d.ts +3 -3
  44. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  45. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  46. package/dist/hooks/useAuthController.d.ts +1 -1
  47. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  48. package/dist/hooks/useBuildNavigationController.d.ts +7 -4
  49. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  50. package/dist/hooks/useModeController.d.ts +1 -2
  51. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  52. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  53. package/dist/index.es.js +17032 -12909
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/index.umd.js +17019 -12898
  56. package/dist/index.umd.js.map +1 -1
  57. package/dist/internal/useBuildSideEntityController.d.ts +2 -2
  58. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  59. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  60. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  61. package/dist/preview/util.d.ts +3 -3
  62. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  63. package/dist/routes/FireCMSRoute.d.ts +1 -0
  64. package/dist/routes/HomePageRoute.d.ts +3 -0
  65. package/dist/types/auth.d.ts +7 -9
  66. package/dist/types/collections.d.ts +44 -23
  67. package/dist/types/datasource.d.ts +2 -6
  68. package/dist/types/dialogs_controller.d.ts +7 -3
  69. package/dist/types/entities.d.ts +1 -1
  70. package/dist/types/entity_actions.d.ts +14 -4
  71. package/dist/types/entity_callbacks.d.ts +16 -16
  72. package/dist/types/export_import.d.ts +4 -4
  73. package/dist/types/fields.d.ts +27 -4
  74. package/dist/types/firecms.d.ts +2 -2
  75. package/dist/types/firecms_context.d.ts +1 -1
  76. package/dist/types/navigation.d.ts +29 -12
  77. package/dist/types/permissions.d.ts +4 -4
  78. package/dist/types/plugins.d.ts +9 -8
  79. package/dist/types/properties.d.ts +18 -3
  80. package/dist/types/property_config.d.ts +0 -2
  81. package/dist/types/side_entity_controller.d.ts +6 -1
  82. package/dist/types/user.d.ts +1 -0
  83. package/dist/util/builders.d.ts +3 -3
  84. package/dist/util/entities.d.ts +1 -1
  85. package/dist/util/entity_actions.d.ts +2 -0
  86. package/dist/util/entity_cache.d.ts +23 -0
  87. package/dist/util/icon_synonyms.d.ts +0 -1
  88. package/dist/util/icons.d.ts +3 -1
  89. package/dist/util/index.d.ts +1 -0
  90. package/dist/util/navigation_from_path.d.ts +6 -1
  91. package/dist/util/navigation_utils.d.ts +12 -1
  92. package/dist/util/objects.d.ts +1 -0
  93. package/dist/util/permissions.d.ts +4 -4
  94. package/dist/util/property_utils.d.ts +2 -2
  95. package/dist/util/resolutions.d.ts +12 -7
  96. package/package.json +129 -125
  97. package/src/app/Scaffold.tsx +4 -4
  98. package/src/components/ArrayContainer.tsx +115 -34
  99. package/src/components/CircularProgressCenter.tsx +1 -1
  100. package/src/components/ConfirmationDialog.tsx +2 -2
  101. package/src/components/DeleteEntityDialog.tsx +10 -19
  102. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +44 -20
  103. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  104. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  105. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
  106. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
  107. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
  108. package/src/components/EntityCollectionTable/index.tsx +1 -1
  109. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  110. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
  111. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
  112. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +77 -73
  113. package/src/components/EntityCollectionView/EntityCollectionView.tsx +90 -49
  114. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  115. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  116. package/src/components/EntityPreview.tsx +39 -30
  117. package/src/components/EntityView.tsx +5 -5
  118. package/src/components/ErrorView.tsx +3 -3
  119. package/src/components/HomePage/DefaultHomePage.tsx +1 -0
  120. package/src/components/HomePage/FavouritesView.tsx +6 -11
  121. package/src/components/HomePage/NavigationCard.tsx +1 -1
  122. package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
  123. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  124. package/src/components/NotFoundPage.tsx +2 -2
  125. package/src/components/PropertyConfigBadge.tsx +1 -1
  126. package/src/components/PropertyIdCopyTooltip.tsx +3 -4
  127. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +13 -8
  128. package/src/components/SelectableTable/SelectableTable.tsx +20 -5
  129. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  130. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  131. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
  132. package/src/components/UnsavedChangesDialog.tsx +42 -0
  133. package/src/components/VirtualTable/VirtualTable.tsx +19 -2
  134. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  135. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  136. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  137. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  138. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  139. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  140. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
  141. package/src/components/common/default_entity_actions.tsx +26 -37
  142. package/src/components/common/index.ts +1 -1
  143. package/src/components/common/useColumnsIds.tsx +1 -1
  144. package/src/components/common/useDataSourceTableController.tsx +420 -0
  145. package/src/components/common/useDebouncedCallback.tsx +20 -0
  146. package/src/components/common/useScrollRestoration.tsx +68 -0
  147. package/src/contexts/BreacrumbsContext.tsx +38 -0
  148. package/src/contexts/DialogsProvider.tsx +3 -2
  149. package/src/contexts/ModeController.tsx +1 -3
  150. package/src/contexts/SnackbarProvider.tsx +2 -0
  151. package/src/core/DefaultAppBar.tsx +56 -25
  152. package/src/core/DefaultDrawer.tsx +11 -9
  153. package/src/core/DrawerNavigationItem.tsx +4 -4
  154. package/src/core/EntityEditView.tsx +282 -1006
  155. package/src/core/EntityEditViewFormActions.tsx +199 -0
  156. package/src/core/EntitySidePanel.tsx +85 -15
  157. package/src/core/FireCMS.tsx +12 -9
  158. package/src/core/FireCMSRouter.tsx +17 -0
  159. package/src/core/NavigationRoutes.tsx +23 -32
  160. package/src/core/SideDialogs.tsx +21 -12
  161. package/src/core/field_configs.tsx +4 -4
  162. package/src/core/index.tsx +4 -2
  163. package/src/form/EntityForm.tsx +774 -0
  164. package/src/form/EntityFormActions.tsx +169 -0
  165. package/src/form/PropertyFieldBinding.tsx +39 -30
  166. package/src/form/components/CustomIdField.tsx +2 -0
  167. package/src/form/components/FormEntry.tsx +22 -0
  168. package/src/form/components/FormLayout.tsx +16 -0
  169. package/src/form/components/LabelWithIcon.tsx +6 -3
  170. package/src/form/components/StorageItemPreview.tsx +3 -3
  171. package/src/form/components/StorageUploadProgress.tsx +1 -1
  172. package/src/form/components/index.tsx +2 -1
  173. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +7 -6
  174. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +20 -12
  175. package/src/form/field_bindings/BlockFieldBinding.tsx +45 -25
  176. package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
  177. package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
  178. package/src/form/field_bindings/MapFieldBinding.tsx +69 -52
  179. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +9 -6
  180. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
  181. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  182. package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -5
  183. package/src/form/field_bindings/RepeatFieldBinding.tsx +30 -22
  184. package/src/form/field_bindings/SelectFieldBinding.tsx +6 -5
  185. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +7 -5
  186. package/src/form/field_bindings/SwitchFieldBinding.tsx +26 -25
  187. package/src/form/field_bindings/TextFieldBinding.tsx +4 -3
  188. package/src/form/index.tsx +16 -32
  189. package/src/form/validation.ts +12 -6
  190. package/src/hooks/data/delete.ts +4 -4
  191. package/src/hooks/data/save.ts +8 -9
  192. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  193. package/src/hooks/data/useEntityFetch.tsx +10 -6
  194. package/src/hooks/useAuthController.tsx +1 -1
  195. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  196. package/src/hooks/useBuildModeController.tsx +15 -28
  197. package/src/hooks/useBuildNavigationController.tsx +74 -29
  198. package/src/hooks/useFireCMSContext.tsx +5 -5
  199. package/src/hooks/useLargeLayout.tsx +0 -35
  200. package/src/hooks/useModeController.tsx +1 -2
  201. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  202. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  203. package/src/internal/useBuildDataSource.ts +1 -1
  204. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  205. package/src/internal/useBuildSideEntityController.tsx +124 -83
  206. package/src/internal/useUnsavedChangesDialog.tsx +127 -93
  207. package/src/preview/PropertyPreview.tsx +11 -11
  208. package/src/preview/PropertyPreviewProps.tsx +1 -1
  209. package/src/preview/components/BooleanPreview.tsx +1 -1
  210. package/src/preview/components/EmptyValue.tsx +1 -1
  211. package/src/preview/components/EnumValuesChip.tsx +1 -1
  212. package/src/preview/components/ImagePreview.tsx +5 -6
  213. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  214. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  215. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  216. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
  217. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
  218. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  219. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
  220. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  221. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  222. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  223. package/src/preview/util.ts +10 -10
  224. package/src/routes/CustomCMSRoute.tsx +21 -0
  225. package/src/routes/FireCMSRoute.tsx +235 -0
  226. package/src/routes/HomePageRoute.tsx +17 -0
  227. package/src/types/auth.tsx +8 -12
  228. package/src/types/collections.ts +52 -26
  229. package/src/types/datasource.ts +2 -6
  230. package/src/types/dialogs_controller.tsx +7 -3
  231. package/src/types/entities.ts +1 -1
  232. package/src/types/entity_actions.tsx +16 -4
  233. package/src/types/entity_callbacks.ts +18 -18
  234. package/src/types/export_import.ts +4 -4
  235. package/src/types/fields.tsx +33 -4
  236. package/src/types/firecms.tsx +2 -2
  237. package/src/types/firecms_context.tsx +1 -1
  238. package/src/types/navigation.ts +36 -16
  239. package/src/types/permissions.ts +5 -5
  240. package/src/types/plugins.tsx +9 -8
  241. package/src/types/properties.ts +21 -3
  242. package/src/types/property_config.tsx +0 -2
  243. package/src/types/side_dialogs_controller.tsx +2 -0
  244. package/src/types/side_entity_controller.tsx +6 -1
  245. package/src/types/user.ts +2 -0
  246. package/src/util/builders.ts +10 -8
  247. package/src/util/entities.ts +3 -1
  248. package/src/util/entity_actions.ts +28 -0
  249. package/src/util/entity_cache.ts +204 -0
  250. package/src/util/icon_list.ts +1 -0
  251. package/src/util/icon_synonyms.ts +0 -1
  252. package/src/util/icons.tsx +12 -8
  253. package/src/util/index.ts +1 -0
  254. package/src/util/join_collections.ts +3 -0
  255. package/src/util/navigation_from_path.ts +13 -6
  256. package/src/util/navigation_utils.ts +53 -1
  257. package/src/util/objects.ts +24 -1
  258. package/src/util/parent_references_from_path.ts +3 -3
  259. package/src/util/permissions.ts +8 -8
  260. package/src/util/property_utils.tsx +10 -3
  261. package/src/util/references.ts +8 -2
  262. package/src/util/resolutions.ts +34 -13
  263. package/src/util/useStorageUploadController.tsx +40 -22
  264. package/dist/form/components/FormikArrayContainer.d.ts +0 -19
  265. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  266. package/src/form/components/FormikArrayContainer.tsx +0 -47
  267. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -1,15 +1,16 @@
1
- import React, { useCallback, useEffect, useState } from "react";
1
+ import React, { 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
@@ -27,7 +28,7 @@ export function BlockFieldBinding<T extends Array<any>>({
27
28
  isSubmitting,
28
29
  setValue,
29
30
  setFieldValue,
30
- minimalistView,
31
+ minimalistView: minimalistViewProp,
31
32
  property,
32
33
  includeDescription,
33
34
  underlyingValueHasChanged,
@@ -35,6 +36,8 @@ export function BlockFieldBinding<T extends Array<any>>({
35
36
  disabled
36
37
  }: FieldProps<T>) {
37
38
 
39
+ const minimalistView = minimalistViewProp || property.minimalistView;
40
+
38
41
  if (!property.oneOf)
39
42
  throw Error("ArrayOneOfField misconfiguration. Property `oneOf` not set");
40
43
 
@@ -47,9 +50,15 @@ export function BlockFieldBinding<T extends Array<any>>({
47
50
 
48
51
  const [lastAddedId, setLastAddedId] = useState<number | undefined>();
49
52
 
50
- const buildEntry = useCallback((index: number, internalId: number) => {
53
+ const buildEntry = ({
54
+ index,
55
+ internalId,
56
+ storedProps,
57
+ storeProps
58
+ }: ArrayEntryParams) => {
59
+
51
60
  return <BlockEntry
52
- key={`array_one_of_${index}`}
61
+ key={`array_one_of_${internalId}`}
53
62
  name={`${propertyKey}.${index}`}
54
63
  index={index}
55
64
  value={value[index]}
@@ -57,8 +66,10 @@ export function BlockFieldBinding<T extends Array<any>>({
57
66
  valueField={property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE}
58
67
  properties={property.oneOf!.properties}
59
68
  autoFocus={internalId === lastAddedId}
60
- context={context}/>;
61
- }, [context, lastAddedId, property.oneOf, propertyKey, value]);
69
+ context={context}
70
+ storeProps={storeProps}
71
+ storedProps={storedProps}/>;
72
+ };
62
73
 
63
74
  const title = (
64
75
  <LabelWithIconAndTooltip
@@ -70,19 +81,19 @@ export function BlockFieldBinding<T extends Array<any>>({
70
81
  );
71
82
 
72
83
  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
- }}/>;
84
+ const body = <ArrayContainer value={value}
85
+ className={"flex flex-col gap-3"}
86
+ droppableId={propertyKey}
87
+ addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
88
+ buildEntry={buildEntry}
89
+ onInternalIdAdded={setLastAddedId}
90
+ disabled={isSubmitting || Boolean(property.disabled)}
91
+ includeAddButton={!property.disabled}
92
+ onValueChange={(value) => setFieldValue(propertyKey, value)}
93
+ newDefaultEntry={{
94
+ [property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
95
+ [property.oneOf!.valueField ?? DEFAULT_ONE_OF_VALUE]: getDefaultValueFor(property.oneOf.properties[firstOneOfKey])
96
+ }}/>;
86
97
  return (
87
98
 
88
99
  <>
@@ -134,6 +145,9 @@ interface BlockEntryProps {
134
145
  */
135
146
  context: FormContext<any>;
136
147
 
148
+ storedProps?: object,
149
+ storeProps: (props: object) => void
150
+
137
151
  }
138
152
 
139
153
  function BlockEntry({
@@ -144,7 +158,9 @@ function BlockEntry({
144
158
  valueField,
145
159
  properties,
146
160
  autoFocus,
147
- context
161
+ context,
162
+ storedProps,
163
+ storeProps
148
164
  }: BlockEntryProps) {
149
165
 
150
166
  const type = value && value[typeField];
@@ -164,7 +180,9 @@ function BlockEntry({
164
180
  }
165
181
  }, [type]);
166
182
 
167
- const property = typeInternal ? properties[typeInternal] : undefined;
183
+ const propertyInternal = typeInternal ? properties[typeInternal] : undefined;
184
+
185
+ const property = storedProps && typeof propertyInternal === "object" ? mergeDeep(propertyInternal, storedProps) : propertyInternal;
168
186
 
169
187
  const enumValuesConfigs = Object.entries(properties)
170
188
  .map(([key, property]) => ({
@@ -182,7 +200,8 @@ function BlockEntry({
182
200
  context,
183
201
  autoFocus,
184
202
  partOfArray: false,
185
- minimalistView: true
203
+ minimalistView: true,
204
+ onPropertyChange: storeProps,
186
205
  }
187
206
  : undefined;
188
207
 
@@ -208,7 +227,8 @@ function BlockEntry({
208
227
  className="mb-2"
209
228
  placeholder={<Typography variant={"caption"}
210
229
  className={"px-4 py-2 font-medium"}>Type</Typography>}
211
- size={"small"}
230
+ size={"medium"}
231
+ fullWidth={true}
212
232
  position={"item-aligned"}
213
233
  value={value1}
214
234
  renderValue={(enumKey: any) =>
@@ -46,11 +46,12 @@ 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}
53
53
  error={showError}
54
+ disabled={disabled}
54
55
  label={<LabelWithIcon
55
56
  icon={getIconForProperty(property, "small")}
56
57
  required={property.validation?.required}
@@ -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,11 +1,11 @@
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
- import { ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
8
+ import { cls, ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
9
9
 
10
10
  /**
11
11
  * Field that renders the children property fields
@@ -21,15 +21,16 @@ export function MapFieldBinding({
21
21
  error,
22
22
  disabled,
23
23
  property,
24
- minimalistView,
24
+ minimalistView: minimalistViewProp,
25
25
  includeDescription,
26
- underlyingValueHasChanged,
27
26
  autoFocus,
28
- context
27
+ context,
28
+ onPropertyChange
29
29
  }: FieldProps<Record<string, any>>) {
30
30
 
31
31
  const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
32
- const expanded = (property.expanded === undefined ? true : property.expanded) || autoFocus;
32
+ const expanded = property.expanded === undefined ? true : property.expanded;
33
+ const minimalistView = minimalistViewProp || property.minimalistView;
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,55 +51,69 @@ 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
- </>;
84
-
85
- const title = (
86
- <LabelWithIconAndTooltip
87
- propertyKey={propertyKey}
88
- icon={getIconForProperty(property, "small")}
89
- required={property.validation?.required}
90
- title={property.name}
91
- className={"text-text-secondary dark:text-text-secondary-dark"}/>
92
- );
54
+ <div className={cls("py-1 flex flex-col space-y-2", minimalistView && property.widthPercentage !== undefined ? "mt-8" : undefined)}>
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
+ context,
65
+ partOfArray: false,
66
+ minimalistView: false,
67
+ autoFocus: autoFocus && index === 0,
68
+ onPropertyChange: function (updatedProperty) {
69
+ onPropertyChange?.({
70
+ properties: {
71
+ [entryKey]: updatedProperty
72
+ }
73
+ } as Partial<MapProperty>);
74
+ }
75
+ };
76
+
77
+ return (
78
+ <div key={`map-${propertyKey}-${index}`} className={"relative"}>
79
+ <ErrorBoundary>
80
+ <PropertyFieldBinding
81
+ {...fieldBindingProps}/>
82
+ </ErrorBoundary>
83
+ </div>
84
+ )
85
+ ;
86
+ }
87
+ )
88
+ }
89
+ </div>
90
+
91
+ {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}
92
+
93
+ </>
94
+ ;
93
95
 
94
96
  return (
95
97
  <ErrorBoundary>
96
98
 
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>}
100
-
101
- {(minimalistView || minimalistView) && mapFormView}
99
+ {!minimalistView && <ExpandablePanel initiallyExpanded={expanded}
100
+ onExpandedChange={(expanded) => {
101
+ onPropertyChange?.({
102
+ expanded
103
+ });
104
+ }}
105
+ className={property.widthPercentage !== undefined ? "mt-8" : undefined}
106
+ innerClassName={"px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2 bg-white dark:bg-surface-900"}
107
+ title={<LabelWithIconAndTooltip
108
+ propertyKey={propertyKey}
109
+ icon={getIconForProperty(property, "small")}
110
+ required={property.validation?.required}
111
+ title={property.name}
112
+ className={"text-text-secondary dark:text-text-secondary-dark"}/>}>
113
+ {mapFormView}
114
+ </ExpandablePanel>}
115
+
116
+ {minimalistView && mapFormView}
102
117
 
103
118
  <FieldHelperText includeDescription={includeDescription}
104
119
  showError={showError ?? false}
@@ -128,6 +143,8 @@ const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue
128
143
  <InputLabel>Add property</InputLabel>
129
144
  <Select
130
145
  value={""}
146
+ size={"large"}
147
+ fullWidth={true}
131
148
  disabled={disabled}
132
149
  onValueChange={handleAddProperty}
133
150
  renderValue={(key) => (properties as Properties)[key].name || key}>
@@ -3,13 +3,14 @@ import {
3
3
  FieldHelperText,
4
4
  FieldProps,
5
5
  getIconForProperty,
6
- LabelWithIconAndTooltip, PropertyOrBuilder,
6
+ LabelWithIconAndTooltip,
7
+ PropertyOrBuilder,
7
8
  randomString,
8
9
  ResolvedArrayProperty,
9
10
  ResolvedStringProperty,
10
11
  useStorageSource
11
12
  } from "../../index";
12
- import { cls, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
13
+ import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
13
14
  import { FireCMSEditor, FireCMSEditorProps } from "@firecms/editor";
14
15
  import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
15
16
 
@@ -27,11 +28,13 @@ export function MarkdownEditorFieldBinding({
27
28
  showError,
28
29
  error,
29
30
  minimalistView,
31
+ disabled: disabledProp,
30
32
  isSubmitting,
31
33
  context,
32
34
  customProps,
33
35
  }: FieldProps<string, MarkdownEditorFieldProps>) {
34
36
 
37
+ const disabled = disabledProp || isSubmitting;
35
38
  const highlight = customProps?.highlight;
36
39
  const editorProps = customProps?.editorProps;
37
40
  const storageSource = useStorageSource();
@@ -54,11 +57,9 @@ export function MarkdownEditorFieldBinding({
54
57
  if (internalValue.current !== value) {
55
58
  internalValue.current = value;
56
59
  setFieldVersion(fieldVersion + 1);
57
- // fieldVersion.current = fieldVersion.current + 1;
58
60
  }
59
61
  }, [value]);
60
62
 
61
-
62
63
  const resolvedProperty = resolveProperty({
63
64
  propertyOrBuilder: property as PropertyOrBuilder,
64
65
  values: entityValues
@@ -107,6 +108,7 @@ export function MarkdownEditorFieldBinding({
107
108
  onMarkdownContentChange={onContentChange}
108
109
  version={context.formex.version + fieldVersion}
109
110
  highlight={highlight}
111
+ disabled={disabled}
110
112
  handleImageUpload={async (file: File) => {
111
113
  const storagePath = storagePathBuilder(file);
112
114
  const fileName = await fileNameBuilder(file);
@@ -135,8 +137,9 @@ export function MarkdownEditorFieldBinding({
135
137
  icon={getIconForProperty(property, "small")}
136
138
  required={property.validation?.required}
137
139
  title={property.name}
138
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
139
- <div className={cls("rounded-md", fieldBackgroundMixin, fieldBackgroundHoverMixin)}>
140
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
141
+ <div
142
+ className={cls("rounded-md", fieldBackgroundMixin, disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin)}>
140
143
  {editor}
141
144
  </div>
142
145
  <FieldHelperText includeDescription={includeDescription}
@@ -92,7 +92,7 @@ export function MultiSelectFieldBinding({
92
92
  icon={getIconForProperty(property, "small")}
93
93
  required={property.validation?.required}
94
94
  title={property.name}
95
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
95
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
96
96
  onValueChange={(updatedValue: string[]) => {
97
97
  let newValue: EnumType[] | null;
98
98
  if (of && (of as ResolvedProperty)?.dataType === "number") {
@@ -39,11 +39,11 @@ export function ReadOnlyFieldBinding({
39
39
  icon={getIconForProperty(property, "small")}
40
40
  required={property.validation?.required}
41
41
  title={property.name}
42
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
42
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
43
43
  }
44
44
 
45
45
  <div
46
- className={cls(paperMixin, "min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
46
+ className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
47
47
 
48
48
  <ErrorBoundary>
49
49
  <PropertyPreview propertyKey={propertyKey}
@@ -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}/>
@@ -90,7 +90,7 @@ function ReferenceFieldBindingInternal({
90
90
  icon={getIconForProperty(property, "small")}
91
91
  required={property.validation?.required}
92
92
  title={property.name}
93
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
93
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
94
94
 
95
95
  {!collection && <ErrorView
96
96
  error={"The specified collection does not exist. Check console"}/>}
@@ -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";
@@ -23,7 +23,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
23
23
  isSubmitting,
24
24
  setValue,
25
25
  setFieldValue,
26
- minimalistView,
26
+ minimalistView: minimalistViewProp,
27
27
  property,
28
28
  includeDescription,
29
29
  underlyingValueHasChanged,
@@ -31,6 +31,8 @@ export function RepeatFieldBinding<T extends Array<any>>({
31
31
  disabled
32
32
  }: FieldProps<T>) {
33
33
 
34
+ const minimalistView = minimalistViewProp || property.minimalistView;
35
+
34
36
  if (!property.of)
35
37
  throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
36
38
 
@@ -43,8 +45,6 @@ export function RepeatFieldBinding<T extends Array<any>>({
43
45
  ignoreMissingFields: false
44
46
  })
45
47
  }
46
- // if (!resolvedProperties || !Array.isArray(resolvedProperties))
47
- // throw Error("RepeatFieldBinding - Internal error: Expected array in 'property.resolvedProperties'");
48
48
 
49
49
  const expanded = property.expanded === undefined ? true : property.expanded;
50
50
  const ofProperty: ResolvedProperty<CMSType[]> = property.of as ResolvedProperty<CMSType[]>;
@@ -57,33 +57,41 @@ export function RepeatFieldBinding<T extends Array<any>>({
57
57
  setValue
58
58
  });
59
59
 
60
- const buildEntry = (index: number, internalId: number) => {
60
+ const buildEntry = ({
61
+ index,
62
+ internalId,
63
+ storedProps,
64
+ storeProps
65
+ }: ArrayEntryParams) => {
61
66
  const childProperty = resolvedProperties[index] ?? ofProperty;
62
- const fieldProps = {
67
+ const fieldProps: PropertyFieldBindingProps<any, any> = {
63
68
  propertyKey: `${propertyKey}.${index}`,
64
69
  disabled,
65
- property: childProperty,
70
+ property: storedProps ? mergeDeep(childProperty, storedProps) : childProperty,
71
+ onPropertyChange: storeProps,
66
72
  includeDescription,
67
73
  underlyingValueHasChanged,
68
74
  context,
69
75
  partOfArray: true,
70
76
  minimalistView: false,
71
- autoFocus: internalId === lastAddedId
77
+ autoFocus: internalId === lastAddedId,
72
78
  };
73
79
  return <ErrorBoundary>
74
80
  <PropertyFieldBinding {...fieldProps} index={index}/>
75
81
  </ErrorBoundary>;
76
82
  };
77
83
 
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)}/>;
84
+ const arrayContainer = <ArrayContainer droppableId={propertyKey}
85
+ addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
86
+ value={value}
87
+ buildEntry={buildEntry}
88
+ onInternalIdAdded={setLastAddedId}
89
+ disabled={isSubmitting || Boolean(property.disabled)}
90
+ includeAddButton={!property.disabled}
91
+ newDefaultEntry={getDefaultValueFor(property.of)}
92
+ onValueChange={(value) => setFieldValue(propertyKey, value)}
93
+ className={property.widthPercentage !== undefined ? "mt-8" : undefined}
94
+ />;
87
95
 
88
96
  const title = (<>
89
97
  <LabelWithIconAndTooltip
@@ -91,7 +99,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
91
99
  icon={getIconForProperty(property, "small")}
92
100
  required={property.validation?.required}
93
101
  title={property.name}
94
- className={"flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
102
+ className={"h-8 flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
95
103
  {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
96
104
  </>);
97
105
 
@@ -109,7 +117,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
109
117
 
110
118
  <FieldHelperText includeDescription={includeDescription}
111
119
  showError={showError}
112
- error={error}
120
+ error={error ? (typeof error === "string" ? error : "A property of this array/repeat has an error") : undefined}
113
121
  disabled={disabled}
114
122
  property={property}/>
115
123