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

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 (201) hide show
  1. package/dist/app/Scaffold.d.ts +4 -0
  2. package/dist/components/ArrayContainer.d.ts +14 -3
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +15 -1
  6. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  8. package/dist/components/EntityJsonPreview.d.ts +3 -0
  9. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  10. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  11. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  12. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  13. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  14. package/dist/components/common/default_entity_actions.d.ts +0 -2
  15. package/dist/components/common/index.d.ts +1 -1
  16. package/dist/components/common/useColumnsIds.d.ts +1 -0
  17. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  18. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  19. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  20. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  21. package/dist/core/DefaultAppBar.d.ts +8 -2
  22. package/dist/core/EntityEditView.d.ts +36 -21
  23. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  24. package/dist/core/FireCMS.d.ts +2 -2
  25. package/dist/core/FireCMSRouter.d.ts +4 -0
  26. package/dist/core/NavigationRoutes.d.ts +0 -1
  27. package/dist/core/SideDialogs.d.ts +4 -2
  28. package/dist/core/index.d.ts +2 -1
  29. package/dist/form/EntityForm.d.ts +49 -0
  30. package/dist/form/EntityFormActions.d.ts +17 -0
  31. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  32. package/dist/form/components/FormEntry.d.ts +6 -0
  33. package/dist/form/components/FormLayout.d.ts +5 -0
  34. package/dist/form/components/index.d.ts +2 -0
  35. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  41. package/dist/form/index.d.ts +16 -16
  42. package/dist/hooks/data/save.d.ts +1 -1
  43. package/dist/hooks/data/useEntityFetch.d.ts +2 -1
  44. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  45. package/dist/hooks/useBuildNavigationController.d.ts +4 -1
  46. package/dist/hooks/useModeController.d.ts +1 -2
  47. package/dist/index.es.js +15842 -14396
  48. package/dist/index.es.js.map +1 -1
  49. package/dist/index.umd.js +15833 -14389
  50. package/dist/index.umd.js.map +1 -1
  51. package/dist/internal/useBuildDataSource.d.ts +3 -2
  52. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  53. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  54. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  55. package/dist/routes/FireCMSRoute.d.ts +1 -0
  56. package/dist/routes/HomePageRoute.d.ts +3 -0
  57. package/dist/types/collections.d.ts +36 -10
  58. package/dist/types/datasource.d.ts +2 -2
  59. package/dist/types/dialogs_controller.d.ts +7 -3
  60. package/dist/types/entities.d.ts +1 -1
  61. package/dist/types/entity_actions.d.ts +10 -0
  62. package/dist/types/fields.d.ts +13 -3
  63. package/dist/types/firecms.d.ts +1 -1
  64. package/dist/types/navigation.d.ts +33 -12
  65. package/dist/types/plugins.d.ts +2 -0
  66. package/dist/types/properties.d.ts +40 -4
  67. package/dist/types/side_entity_controller.d.ts +6 -1
  68. package/dist/util/builders.d.ts +1 -1
  69. package/dist/util/createFormexStub.d.ts +2 -0
  70. package/dist/util/entity_actions.d.ts +2 -0
  71. package/dist/util/entity_cache.d.ts +23 -0
  72. package/dist/util/index.d.ts +1 -0
  73. package/dist/util/navigation_from_path.d.ts +6 -1
  74. package/dist/util/navigation_utils.d.ts +13 -1
  75. package/dist/util/objects.d.ts +1 -1
  76. package/dist/util/property_utils.d.ts +2 -2
  77. package/dist/util/references.d.ts +2 -2
  78. package/dist/util/resolutions.d.ts +12 -2
  79. package/package.json +20 -21
  80. package/src/app/Scaffold.tsx +13 -3
  81. package/src/components/ArrayContainer.tsx +60 -24
  82. package/src/components/CircularProgressCenter.tsx +1 -1
  83. package/src/components/DeleteEntityDialog.tsx +5 -3
  84. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +46 -23
  85. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -4
  86. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +18 -1
  87. package/src/components/EntityCollectionTable/index.tsx +1 -1
  88. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  89. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +10 -13
  90. package/src/components/EntityCollectionView/EntityCollectionView.tsx +105 -47
  91. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  92. package/src/components/EntityJsonPreview.tsx +66 -0
  93. package/src/components/EntityPreview.tsx +10 -3
  94. package/src/components/EntityView.tsx +4 -1
  95. package/src/components/NotFoundPage.tsx +2 -2
  96. package/src/components/PropertyIdCopyTooltip.tsx +2 -3
  97. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +14 -7
  98. package/src/components/SelectableTable/SelectableTable.tsx +18 -3
  99. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +7 -7
  100. package/src/components/UnsavedChangesDialog.tsx +42 -0
  101. package/src/components/VirtualTable/VirtualTable.tsx +48 -3
  102. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  103. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  104. package/src/components/common/default_entity_actions.tsx +37 -37
  105. package/src/components/common/index.ts +1 -1
  106. package/src/components/common/useColumnsIds.tsx +1 -1
  107. package/src/components/common/useDataSourceTableController.tsx +420 -0
  108. package/src/components/common/useDebouncedCallback.tsx +20 -0
  109. package/src/components/common/useScrollRestoration.tsx +68 -0
  110. package/src/contexts/BreacrumbsContext.tsx +38 -0
  111. package/src/contexts/DialogsProvider.tsx +3 -2
  112. package/src/contexts/ModeController.tsx +1 -3
  113. package/src/core/DefaultAppBar.tsx +59 -17
  114. package/src/core/DefaultDrawer.tsx +1 -1
  115. package/src/core/EntityEditView.tsx +354 -1000
  116. package/src/core/EntityEditViewFormActions.tsx +199 -0
  117. package/src/core/EntitySidePanel.tsx +85 -15
  118. package/src/core/FireCMS.tsx +20 -16
  119. package/src/core/FireCMSRouter.tsx +17 -0
  120. package/src/core/NavigationRoutes.tsx +23 -32
  121. package/src/core/SideDialogs.tsx +20 -11
  122. package/src/core/index.tsx +4 -2
  123. package/src/form/EntityForm.tsx +782 -0
  124. package/src/form/EntityFormActions.tsx +169 -0
  125. package/src/form/PropertyFieldBinding.tsx +21 -16
  126. package/src/form/components/FormEntry.tsx +22 -0
  127. package/src/form/components/FormLayout.tsx +16 -0
  128. package/src/form/components/LabelWithIcon.tsx +6 -3
  129. package/src/form/components/StorageUploadProgress.tsx +1 -1
  130. package/src/form/components/index.tsx +2 -0
  131. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
  132. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -2
  133. package/src/form/field_bindings/BlockFieldBinding.tsx +5 -3
  134. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -0
  135. package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
  136. package/src/form/field_bindings/MapFieldBinding.tsx +14 -16
  137. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +15 -8
  138. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +3 -3
  139. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  140. package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
  141. package/src/form/field_bindings/RepeatFieldBinding.tsx +13 -4
  142. package/src/form/field_bindings/SelectFieldBinding.tsx +2 -2
  143. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +11 -6
  144. package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -0
  145. package/src/form/field_bindings/TextFieldBinding.tsx +1 -0
  146. package/src/form/index.tsx +16 -32
  147. package/src/form/validation.ts +12 -6
  148. package/src/hooks/data/save.ts +25 -30
  149. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  150. package/src/hooks/data/useEntityFetch.tsx +5 -1
  151. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  152. package/src/hooks/useBuildModeController.tsx +15 -28
  153. package/src/hooks/useBuildNavigationController.tsx +81 -24
  154. package/src/hooks/useFireCMSContext.tsx +0 -30
  155. package/src/hooks/useLargeLayout.tsx +0 -35
  156. package/src/hooks/useModeController.tsx +1 -2
  157. package/src/hooks/useResolvedNavigationFrom.tsx +4 -6
  158. package/src/internal/useBuildDataSource.ts +9 -5
  159. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  160. package/src/internal/useBuildSideEntityController.tsx +135 -88
  161. package/src/internal/useUnsavedChangesDialog.tsx +126 -92
  162. package/src/preview/PropertyPreview.tsx +12 -10
  163. package/src/preview/components/UrlComponentPreview.tsx +17 -18
  164. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +4 -3
  165. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
  166. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
  167. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  168. package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
  169. package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
  170. package/src/preview/property_previews/MapPropertyPreview.tsx +3 -2
  171. package/src/routes/CustomCMSRoute.tsx +21 -0
  172. package/src/routes/FireCMSRoute.tsx +246 -0
  173. package/src/routes/HomePageRoute.tsx +17 -0
  174. package/src/types/collections.ts +45 -13
  175. package/src/types/datasource.ts +2 -1
  176. package/src/types/dialogs_controller.tsx +7 -3
  177. package/src/types/entities.ts +1 -1
  178. package/src/types/entity_actions.tsx +12 -0
  179. package/src/types/fields.tsx +18 -3
  180. package/src/types/firecms.tsx +1 -1
  181. package/src/types/navigation.ts +41 -16
  182. package/src/types/plugins.tsx +2 -0
  183. package/src/types/properties.ts +48 -4
  184. package/src/types/side_dialogs_controller.tsx +2 -0
  185. package/src/types/side_entity_controller.tsx +11 -1
  186. package/src/util/builders.ts +5 -3
  187. package/src/util/createFormexStub.tsx +62 -0
  188. package/src/util/entity_actions.ts +28 -0
  189. package/src/util/entity_cache.ts +204 -0
  190. package/src/util/index.ts +1 -0
  191. package/src/util/join_collections.ts +6 -1
  192. package/src/util/navigation_from_path.ts +18 -7
  193. package/src/util/navigation_utils.ts +115 -14
  194. package/src/util/objects.ts +9 -2
  195. package/src/util/parent_references_from_path.ts +3 -3
  196. package/src/util/property_utils.tsx +7 -3
  197. package/src/util/references.ts +8 -6
  198. package/src/util/resolutions.ts +41 -12
  199. package/src/util/useStorageUploadController.tsx +60 -23
  200. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  201. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -0,0 +1,169 @@
1
+ import React from "react";
2
+ import { Entity, EntityAction, FireCMSContext, ResolvedEntityCollection, SideEntityController } from "../types";
3
+ import { Button, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Typography } from "@firecms/ui";
4
+ import { FormexController } from "@firecms/formex";
5
+ import { useFireCMSContext, useSideEntityController } from "../hooks";
6
+
7
+ export interface EntityFormActionsProps {
8
+ collection: ResolvedEntityCollection;
9
+ path: string;
10
+ entity?: Entity;
11
+ layout: "bottom" | "side";
12
+ savingError?: Error;
13
+ formex: FormexController<any>;
14
+ disabled: boolean;
15
+ status: "new" | "existing" | "copy";
16
+ pluginActions: React.ReactNode[];
17
+ openEntityMode: "side_panel" | "full_screen";
18
+ showDefaultActions?: boolean;
19
+ }
20
+
21
+ export function EntityFormActions({
22
+ collection,
23
+ entity,
24
+ layout,
25
+ savingError,
26
+ formex,
27
+ disabled,
28
+ status,
29
+ pluginActions,
30
+ openEntityMode
31
+ }: EntityFormActionsProps) {
32
+
33
+ const context = useFireCMSContext();
34
+ const sideEntityController = useSideEntityController();
35
+
36
+ return layout === "bottom"
37
+ ? buildBottomActions({
38
+ savingError,
39
+ entity,
40
+ collection,
41
+ context,
42
+ sideEntityController,
43
+ isSubmitting: formex.isSubmitting,
44
+ disabled,
45
+ status,
46
+ pluginActions,
47
+ openEntityMode
48
+ })
49
+ : buildSideActions({
50
+ savingError,
51
+ entity,
52
+ collection,
53
+ context,
54
+ sideEntityController,
55
+ isSubmitting: formex.isSubmitting,
56
+ disabled,
57
+ status,
58
+ pluginActions,
59
+ openEntityMode
60
+ });
61
+ }
62
+
63
+ type ActionsViewProps<M extends object> = {
64
+ savingError: Error | undefined,
65
+ entity: Entity<M> | undefined,
66
+ formActions?: EntityAction[],
67
+ collection: ResolvedEntityCollection,
68
+ context: FireCMSContext,
69
+ sideEntityController: SideEntityController,
70
+ isSubmitting: boolean,
71
+ disabled: boolean,
72
+ status: "new" | "existing" | "copy",
73
+ pluginActions?: React.ReactNode[],
74
+ openEntityMode: "side_panel" | "full_screen";
75
+ };
76
+
77
+ function buildBottomActions<M extends object>({
78
+ savingError,
79
+ entity,
80
+ formActions,
81
+ collection,
82
+ context,
83
+ sideEntityController,
84
+ isSubmitting,
85
+ disabled,
86
+ status,
87
+ pluginActions,
88
+ openEntityMode
89
+ }: ActionsViewProps<M>) {
90
+
91
+ return <DialogActions position={"absolute"}>
92
+ {savingError &&
93
+ <div className="text-right">
94
+ <Typography color={"error"}>{savingError.message}</Typography>
95
+ </div>
96
+ }
97
+ {entity && (formActions ?? []).length > 0 && <div className="flex-grow flex overflow-auto no-scrollbar">
98
+ {(formActions ?? []).map(action => (
99
+ <IconButton
100
+ key={action.name}
101
+ color="primary"
102
+ onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
103
+ event.stopPropagation();
104
+ if (entity)
105
+ action.onClick({
106
+ entity,
107
+ fullPath: collection.path,
108
+ collection: collection,
109
+ context,
110
+ sideEntityController,
111
+ openEntityMode: openEntityMode
112
+ });
113
+ }}>
114
+ {action.icon}
115
+ </IconButton>
116
+ ))}
117
+ </div>}
118
+ {pluginActions}
119
+ <Button variant="text" disabled={disabled || isSubmitting} type="reset">
120
+ {status === "existing" ? "Discard" : "Clear"}
121
+ </Button>
122
+ <Button variant={"filled"} color="primary" type="submit"
123
+ disabled={disabled || isSubmitting}>
124
+ {status === "existing" && "Save"}
125
+ {status === "copy" && "Create copy"}
126
+ {status === "new" && "Create"}
127
+ </Button>
128
+
129
+ </DialogActions>;
130
+ }
131
+
132
+ function buildSideActions<M extends object>({
133
+ savingError,
134
+ entity,
135
+ formActions,
136
+ collection,
137
+ context,
138
+ sideEntityController,
139
+ isSubmitting,
140
+ disabled,
141
+ status,
142
+ pluginActions
143
+ }: ActionsViewProps<M>) {
144
+
145
+ return <div
146
+ className={cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin)}>
147
+ <LoadingButton fullWidth={true}
148
+ variant="filled"
149
+ color="primary"
150
+ type="submit"
151
+ size={"large"}
152
+ disabled={disabled || isSubmitting}>
153
+ {status === "existing" && "Save"}
154
+ {status === "copy" && "Create copy"}
155
+ {status === "new" && "Create"}
156
+ </LoadingButton>
157
+ <Button fullWidth={true} variant="text" disabled={disabled || isSubmitting} type="reset">
158
+ {status === "existing" ? "Discard" : "Clear"}
159
+ </Button>
160
+
161
+ {pluginActions}
162
+
163
+ {savingError &&
164
+ <div className="text-right">
165
+ <Typography color={"error"}>{savingError.message}</Typography>
166
+ </div>
167
+ }
168
+ </div>;
169
+ }
@@ -5,19 +5,19 @@ import { Field, FieldProps as FormexFieldProps, getIn } from "@firecms/formex";
5
5
 
6
6
  import {
7
7
  CMSType,
8
- EntityCollection,
9
8
  FieldProps,
10
9
  FireCMSPlugin,
11
10
  PluginFieldBuilderParams,
12
11
  Property,
13
12
  PropertyFieldBindingProps,
14
13
  PropertyOrBuilder,
14
+ ResolvedEntityCollection,
15
15
  ResolvedProperty
16
16
  } from "../types";
17
17
  import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
18
18
 
19
19
  import { isHidden, isPropertyBuilder, isReadOnly, resolveProperty } from "../util";
20
- import { useCustomizationController } from "../hooks";
20
+ import { useAuthController, useCustomizationController } from "../hooks";
21
21
  import { Typography } from "@firecms/ui";
22
22
  import { getFieldConfig, getFieldId } from "../core";
23
23
  import { ErrorBoundary } from "../components";
@@ -74,7 +74,7 @@ export const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a:
74
74
  return false;
75
75
  }) as typeof PropertyFieldBindingInternal;
76
76
 
77
- function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>>
77
+ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Record<string, any> = any>
78
78
  ({
79
79
  propertyKey,
80
80
  property,
@@ -87,9 +87,10 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
87
87
  autoFocus,
88
88
  index,
89
89
  size,
90
- onPropertyChange
90
+ onPropertyChange,
91
91
  }: PropertyFieldBindingProps<T, M>): ReactElement<PropertyFieldBindingProps<T, M>> {
92
92
 
93
+ const authController = useAuthController();
93
94
  const customizationController = useCustomizationController();
94
95
 
95
96
  return (
@@ -107,10 +108,11 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
107
108
  path: context.path,
108
109
  entityId: context.entityId,
109
110
  propertyConfigs: customizationController.propertyConfigs,
110
- index
111
+ index,
112
+ authController
111
113
  });
112
114
 
113
- const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled);
115
+ const disabled = disabledProp || isReadOnly(resolvedProperty) || Boolean(resolvedProperty?.disabled) || context.disabled;
114
116
 
115
117
  if (resolvedProperty === null || isHidden(resolvedProperty)) {
116
118
  return <></>;
@@ -139,7 +141,8 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
139
141
  path: context.path,
140
142
  entityId: context.entityId,
141
143
  propertyConfigs: customizationController.propertyConfigs,
142
- index
144
+ index,
145
+ authController
143
146
  });
144
147
  Component = configProperty.Field as ComponentType<FieldProps<T>>;
145
148
  }
@@ -147,7 +150,9 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
147
150
  console.warn(`No field component found for property ${propertyKey}`);
148
151
  console.warn("Property:", property);
149
152
  return (
150
- <div>{`Currently the field ${resolvedProperty.dataType} is not supported`}</div>
153
+ <div className={"w-full"}>
154
+ {`Currently the field ${resolvedProperty.dataType} is not supported`}
155
+ </div>
151
156
  );
152
157
  }
153
158
 
@@ -175,7 +180,7 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
175
180
 
176
181
  }
177
182
 
178
- type ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>> =
183
+ type ResolvedPropertyFieldBindingProps<T extends CMSType = CMSType, M extends Record<string, any> = any> =
179
184
  Omit<PropertyFieldBindingProps<T, M>, "property">
180
185
  & {
181
186
  property: ResolvedProperty<T>
@@ -199,11 +204,11 @@ function FieldInternal<T extends CMSType, CustomProps, M extends Record<string,
199
204
  },
200
205
  formexFieldProps
201
206
  }:
202
- {
203
- Component: ComponentType<FieldProps<T, any, M>>,
204
- componentProps: ResolvedPropertyFieldBindingProps<T, M>,
205
- formexFieldProps: FormexFieldProps<T, any>
206
- }) {
207
+ {
208
+ Component: ComponentType<FieldProps<T, any, M>>,
209
+ componentProps: ResolvedPropertyFieldBindingProps<T, M>,
210
+ formexFieldProps: FormexFieldProps<T, any>
211
+ }) {
207
212
 
208
213
  const { plugins } = useCustomizationController();
209
214
 
@@ -296,7 +301,7 @@ const shouldPropertyReRender = (property: PropertyOrBuilder | ResolvedProperty,
296
301
 
297
302
  interface UseWrappedComponentParams<T extends CMSType = CMSType, M extends Record<string, any> = any> {
298
303
  path?: string,
299
- collection?: EntityCollection<M>,
304
+ collection?: ResolvedEntityCollection<M>,
300
305
  propertyKey: string,
301
306
  property: ResolvedProperty<T>,
302
307
  Component: ComponentType<FieldProps<T, any, M>>,
@@ -327,7 +332,7 @@ function useWrappedComponent<T extends CMSType = CMSType, M extends Record<strin
327
332
  Field: Component,
328
333
  plugin,
329
334
  path,
330
- collection
335
+ collection,
331
336
  };
332
337
  const enabled = plugin.form?.fieldBuilderEnabled?.(params);
333
338
  if (enabled === undefined || enabled)
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { ErrorBoundary } from "../../components";
3
+
4
+ export function FormEntry({
5
+ propertyKey,
6
+ widthPercentage = 100,
7
+ children
8
+ }: {
9
+ propertyKey: string;
10
+ widthPercentage?: number;
11
+ children: React.ReactNode;
12
+ }) {
13
+ return (
14
+ <div id={`form_field_${propertyKey}`}
15
+ className={"relative"}
16
+ style={{ width: widthPercentage === 100 ? "100%" : `calc(${widthPercentage}% - 8px)` }}>
17
+ <ErrorBoundary>
18
+ {children}
19
+ </ErrorBoundary>
20
+ </div>
21
+ );
22
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { cls } from "@firecms/ui";
3
+
4
+ export function FormLayout({
5
+ children,
6
+ className
7
+ }: {
8
+ children: React.ReactNode;
9
+ className?: string;
10
+ }) {
11
+ return (
12
+ <div className={cls("flex flex-wrap gap-x-4 w-full space-y-8", className)}>
13
+ {children}
14
+ </div>
15
+ );
16
+ }
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef } from "react";
2
+ import { cls } from "@firecms/ui";
2
3
 
3
4
  interface LabelWithIconProps {
4
5
  icon: React.ReactNode;
@@ -23,9 +24,11 @@ export const LabelWithIcon = forwardRef<HTMLDivElement, LabelWithIconProps>(
23
24
  return (
24
25
  <div
25
26
  ref={ref}
26
- className={`inline-flex items-center my-0.5 ${small ? "gap-1" : "gap-2"} ${className ?? ""}`}
27
+ className={cls("inline-flex items-center my-0.5",
28
+ small ? "gap-1" : "gap-2",
29
+ className)}
27
30
  >
28
- {icon}
31
+ {icon}
29
32
  <span
30
33
  className={`text-start font-medium text-${small ? "base" : "sm"} origin-top-left transform ${
31
34
  small ? "translate-x-2 scale-75" : ""
@@ -33,7 +36,7 @@ export const LabelWithIcon = forwardRef<HTMLDivElement, LabelWithIconProps>(
33
36
  >
34
37
  {(title ?? "") + (required ? " *" : "")}
35
38
  </span>
36
- </div>
39
+ </div>
37
40
  );
38
41
  }
39
42
  );
@@ -92,7 +92,7 @@ export function StorageUploadProgress({
92
92
  `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
93
93
 
94
94
  {loading &&
95
- <Skeleton className="w-full h-full"/>}
95
+ <Skeleton className="m-4 w-full h-full"/>}
96
96
 
97
97
  {error && <ErrorView title={"Error uploading file"}
98
98
  error={error}/>}
@@ -1,3 +1,5 @@
1
1
  export * from "./FieldHelperText";
2
2
  export * from "./LabelWithIcon";
3
3
  export * from "./LabelWithIconAndTooltip";
4
+ export * from "./FormEntry";
5
+ export * from "./FormLayout";
@@ -5,6 +5,7 @@ import { PropertyFieldBinding } from "../PropertyFieldBinding";
5
5
  import { ExpandablePanel, Typography } from "@firecms/ui";
6
6
  import { getArrayResolvedProperties, getIconForProperty, isReadOnly } from "../../util";
7
7
  import { useClearRestoreValue } from "../useClearRestoreValue";
8
+ import { useAuthController } from "../../hooks";
8
9
 
9
10
  /**
10
11
  * Array field used for custom
@@ -20,21 +21,24 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
20
21
  showError,
21
22
  isSubmitting,
22
23
  setValue,
23
- minimalistView,
24
+ minimalistView: minimalistViewProp,
24
25
  property,
25
26
  includeDescription,
26
- underlyingValueHasChanged,
27
27
  context,
28
28
  disabled
29
29
  }: FieldProps<T, any, any>) {
30
30
 
31
+ const authController = useAuthController();
32
+ const minimalistView = minimalistViewProp || property.minimalistView;
33
+
31
34
  let resolvedProperties = "resolvedProperties" in property ? property.resolvedProperties : undefined;
32
35
  if (!resolvedProperties) {
33
36
  resolvedProperties = getArrayResolvedProperties({
34
37
  propertyValue: value,
35
38
  propertyKey,
36
39
  property,
37
- ignoreMissingFields: false
40
+ ignoreMissingFields: false,
41
+ authController
38
42
  })
39
43
  }
40
44
 
@@ -52,7 +56,7 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
52
56
  icon={getIconForProperty(property, "small")}
53
57
  required={property.validation?.required}
54
58
  title={property.name}
55
- className={"flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
59
+ className={"h-8 flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
56
60
  {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
57
61
  </>);
58
62
 
@@ -63,7 +67,6 @@ export function ArrayCustomShapedFieldBinding<T extends Array<any>>({
63
67
  disabled: disabled || thisDisabled,
64
68
  property: childProperty,
65
69
  includeDescription,
66
- underlyingValueHasChanged,
67
70
  context,
68
71
  partOfArray: true,
69
72
  minimalistView: false,
@@ -25,13 +25,15 @@ export function ArrayOfReferencesFieldBinding({
25
25
  showError,
26
26
  disabled,
27
27
  isSubmitting,
28
- minimalistView,
28
+ minimalistView: minimalistViewProp,
29
29
  property,
30
30
  includeDescription,
31
31
  setValue,
32
32
  setFieldValue
33
33
  }: ArrayOfReferencesFieldProps) {
34
34
 
35
+ const minimalistView = minimalistViewProp || property.minimalistView;
36
+
35
37
  const ofProperty = property.of as ResolvedProperty;
36
38
  if (ofProperty.dataType !== "reference") {
37
39
  throw Error("ArrayOfReferencesField expected a property containing references");
@@ -104,7 +106,7 @@ export function ArrayOfReferencesFieldBinding({
104
106
  icon={getIconForProperty(property, "small")}
105
107
  required={property.validation?.required}
106
108
  title={property.name}
107
- className={"flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
109
+ className={"h-8 flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
108
110
  {Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
109
111
  </>);
110
112
 
@@ -118,6 +120,7 @@ export function ArrayOfReferencesFieldBinding({
118
120
  value={value}
119
121
  disabled={isSubmitting}
120
122
  buildEntry={buildEntry}
123
+ canAddElements={false}
121
124
  addLabel={property.name ? "Add reference to " + property.name : "Add reference"}
122
125
  newDefaultEntry={property.of.defaultValue}
123
126
  onValueChange={(value) => setFieldValue(propertyKey, value)}
@@ -1,4 +1,4 @@
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
 
@@ -28,7 +28,7 @@ export function BlockFieldBinding<T extends Array<any>>({
28
28
  isSubmitting,
29
29
  setValue,
30
30
  setFieldValue,
31
- minimalistView,
31
+ minimalistView: minimalistViewProp,
32
32
  property,
33
33
  includeDescription,
34
34
  underlyingValueHasChanged,
@@ -36,6 +36,8 @@ export function BlockFieldBinding<T extends Array<any>>({
36
36
  disabled
37
37
  }: FieldProps<T>) {
38
38
 
39
+ const minimalistView = minimalistViewProp || property.minimalistView;
40
+
39
41
  if (!property.oneOf)
40
42
  throw Error("ArrayOneOfField misconfiguration. Property `oneOf` not set");
41
43
 
@@ -86,7 +88,7 @@ export function BlockFieldBinding<T extends Array<any>>({
86
88
  buildEntry={buildEntry}
87
89
  onInternalIdAdded={setLastAddedId}
88
90
  disabled={isSubmitting || Boolean(property.disabled)}
89
- includeAddButton={!property.disabled}
91
+ canAddElements={!property.disabled}
90
92
  onValueChange={(value) => setFieldValue(propertyKey, value)}
91
93
  newDefaultEntry={{
92
94
  [property.oneOf!.typeField ?? DEFAULT_ONE_OF_TYPE]: firstOneOfKey,
@@ -51,6 +51,7 @@ export function DateTimeFieldBinding({
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}
@@ -329,7 +329,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
329
329
  addLabel={fieldKey ? `Add to ${fieldKey}` : "Add"}
330
330
  size={"small"}
331
331
  disabled={disabled || !fieldKey}
332
- includeAddButton={true}
332
+ canAddElements={true}
333
333
  onValueChange={(newValue) => {
334
334
  setValue({
335
335
  ...value,
@@ -5,7 +5,7 @@ import { ErrorBoundary } from "../../components";
5
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,9 +21,8 @@ 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
27
  context,
29
28
  onPropertyChange
@@ -31,6 +30,7 @@ export function MapFieldBinding({
31
30
 
32
31
  const pickOnlySomeKeys = property.pickOnlySomeKeys || false;
33
32
  const expanded = property.expanded === undefined ? true : property.expanded;
33
+ const minimalistView = minimalistViewProp || property.minimalistView;
34
34
 
35
35
  if (!property.properties) {
36
36
  throw Error(`You need to specify a 'properties' prop (or specify a custom field) in your map property ${propertyKey}`);
@@ -51,7 +51,7 @@ export function MapFieldBinding({
51
51
  }
52
52
 
53
53
  const mapFormView = <>
54
- <div className="py-1 flex flex-col space-y-2">
54
+ <div className={cls("py-1 flex flex-col space-y-2", minimalistView && property.widthPercentage !== undefined ? "mt-8" : undefined)}>
55
55
  {Object.entries(mapProperties)
56
56
  .filter(([_, property]) => !isHidden(property))
57
57
  .map(([entryKey, childProperty], index) => {
@@ -61,7 +61,6 @@ export function MapFieldBinding({
61
61
  disabled: disabled || thisDisabled,
62
62
  property: childProperty,
63
63
  includeDescription,
64
- underlyingValueHasChanged,
65
64
  context,
66
65
  partOfArray: false,
67
66
  minimalistView: false,
@@ -76,7 +75,7 @@ export function MapFieldBinding({
76
75
  };
77
76
 
78
77
  return (
79
- <div key={`map-${propertyKey}-${index}`}>
78
+ <div key={`map-${propertyKey}-${index}`} className={"relative"}>
80
79
  <ErrorBoundary>
81
80
  <PropertyFieldBinding
82
81
  {...fieldBindingProps}/>
@@ -94,15 +93,6 @@ export function MapFieldBinding({
94
93
  </>
95
94
  ;
96
95
 
97
- const title = (
98
- <LabelWithIconAndTooltip
99
- propertyKey={propertyKey}
100
- icon={getIconForProperty(property, "small")}
101
- required={property.validation?.required}
102
- title={property.name}
103
- className={"text-text-secondary dark:text-text-secondary-dark"}/>
104
- );
105
-
106
96
  return (
107
97
  <ErrorBoundary>
108
98
 
@@ -112,8 +102,16 @@ export function MapFieldBinding({
112
102
  expanded
113
103
  });
114
104
  }}
105
+ className={property.widthPercentage !== undefined ? "mt-8" : undefined}
115
106
  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>}
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>}
117
115
 
118
116
  {minimalistView && mapFormView}
119
117