@firecms/core 3.0.0-beta.7 → 3.0.0-beta.9

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 (216) hide show
  1. package/dist/app/AppBar.d.ts +12 -0
  2. package/dist/app/Drawer.d.ts +17 -0
  3. package/dist/app/Scaffold.d.ts +30 -0
  4. package/dist/app/index.d.ts +4 -0
  5. package/dist/app/useApp.d.ts +16 -0
  6. package/dist/components/ArrayContainer.d.ts +2 -1
  7. package/dist/components/CircularProgressCenter.d.ts +1 -1
  8. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  11. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
  12. package/dist/components/EntityPreview.d.ts +1 -1
  13. package/dist/components/ErrorView.d.ts +1 -1
  14. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  15. package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
  16. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  17. package/dist/components/VirtualTable/VirtualTableProps.d.ts +14 -6
  18. package/dist/components/common/useColumnsIds.d.ts +2 -1
  19. package/dist/components/index.d.ts +2 -1
  20. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +3 -8
  21. package/dist/core/DefaultDrawer.d.ts +19 -0
  22. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  23. package/dist/core/EntityEditView.d.ts +18 -4
  24. package/dist/core/FireCMS.d.ts +1 -1
  25. package/dist/core/NavigationRoutes.d.ts +2 -2
  26. package/dist/core/index.d.ts +2 -2
  27. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  28. package/dist/form/components/FieldHelperText.d.ts +3 -3
  29. package/dist/form/components/FormikArrayContainer.d.ts +2 -1
  30. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  31. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  32. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  33. package/dist/form/components/index.d.ts +1 -0
  34. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  39. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  40. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  41. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  42. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  43. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  44. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -5
  45. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  46. package/dist/form/index.d.ts +3 -5
  47. package/dist/form/useClearRestoreValue.d.ts +2 -2
  48. package/dist/hooks/useProjectLog.d.ts +2 -2
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.es.js +14434 -11300
  51. package/dist/index.es.js.map +1 -1
  52. package/dist/index.umd.js +19987 -587
  53. package/dist/index.umd.js.map +1 -1
  54. package/dist/preview/PropertyPreviewProps.d.ts +6 -1
  55. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  56. package/dist/preview/components/ReferencePreview.d.ts +1 -1
  57. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  58. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  59. package/dist/types/auth.d.ts +2 -2
  60. package/dist/types/collections.d.ts +26 -3
  61. package/dist/types/datasource.d.ts +53 -30
  62. package/dist/types/entities.d.ts +1 -0
  63. package/dist/types/entity_overrides.d.ts +2 -2
  64. package/dist/types/fields.d.ts +47 -41
  65. package/dist/types/navigation.d.ts +1 -0
  66. package/dist/types/plugins.d.ts +11 -3
  67. package/dist/types/properties.d.ts +25 -20
  68. package/dist/types/side_dialogs_controller.d.ts +10 -0
  69. package/dist/types/storage.d.ts +75 -0
  70. package/dist/util/entities.d.ts +1 -1
  71. package/dist/util/icon_list.d.ts +5 -1
  72. package/dist/util/icons.d.ts +3 -2
  73. package/dist/util/index.d.ts +1 -0
  74. package/dist/util/plurals.d.ts +0 -2
  75. package/dist/util/property_utils.d.ts +1 -1
  76. package/dist/util/resolutions.d.ts +15 -1
  77. package/dist/util/storage.d.ts +23 -2
  78. package/dist/util/useStorageUploadController.d.ts +3 -3
  79. package/package.json +18 -29
  80. package/src/app/AppBar.tsx +18 -0
  81. package/src/app/Drawer.tsx +25 -0
  82. package/src/{core → app}/Scaffold.tsx +71 -122
  83. package/src/app/index.ts +4 -0
  84. package/src/app/useApp.tsx +32 -0
  85. package/src/components/ArrayContainer.tsx +15 -10
  86. package/src/components/CircularProgressCenter.tsx +1 -1
  87. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +11 -18
  88. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
  89. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
  90. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
  91. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
  92. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
  93. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
  94. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -6
  95. package/src/components/EntityCollectionView/EntityCollectionView.tsx +33 -29
  96. package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
  97. package/src/components/EntityPreview.tsx +30 -31
  98. package/src/components/ErrorView.tsx +1 -1
  99. package/src/components/HomePage/DefaultHomePage.tsx +24 -18
  100. package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
  101. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  102. package/src/components/PropertyIdCopyTooltip.tsx +48 -0
  103. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
  104. package/src/components/SearchIconsView.tsx +5 -2
  105. package/src/components/SelectableTable/SelectableTable.tsx +2 -4
  106. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
  107. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
  108. package/src/components/VirtualTable/VirtualTable.tsx +36 -10
  109. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  110. package/src/components/VirtualTable/VirtualTableProps.tsx +17 -8
  111. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
  112. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
  113. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  114. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
  115. package/src/components/common/useColumnsIds.tsx +13 -0
  116. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
  117. package/src/components/common/useTableSearchHelper.ts +53 -12
  118. package/src/components/index.tsx +2 -1
  119. package/src/contexts/DialogsProvider.tsx +2 -2
  120. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +28 -30
  121. package/src/core/DefaultDrawer.tsx +183 -0
  122. package/src/core/DrawerNavigationItem.tsx +31 -27
  123. package/src/core/EntityEditView.tsx +712 -145
  124. package/src/core/EntitySidePanel.tsx +0 -1
  125. package/src/core/FireCMS.tsx +2 -2
  126. package/src/core/NavigationRoutes.tsx +4 -4
  127. package/src/core/SideDialogs.tsx +1 -0
  128. package/src/core/field_configs.tsx +5 -5
  129. package/src/core/index.tsx +2 -2
  130. package/src/form/PropertyFieldBinding.tsx +53 -19
  131. package/src/form/components/CustomIdField.tsx +4 -2
  132. package/src/form/components/FieldHelperText.tsx +4 -4
  133. package/src/form/components/FormikArrayContainer.tsx +4 -1
  134. package/src/form/components/LabelWithIcon.tsx +27 -19
  135. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  136. package/src/form/components/StorageItemPreview.tsx +20 -10
  137. package/src/form/components/StorageUploadProgress.tsx +0 -1
  138. package/src/form/components/index.tsx +1 -0
  139. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +26 -15
  140. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +28 -25
  141. package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
  142. package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
  143. package/src/form/field_bindings/KeyValueFieldBinding.tsx +48 -42
  144. package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
  145. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
  146. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
  147. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -14
  148. package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
  149. package/src/form/field_bindings/RepeatFieldBinding.tsx +32 -19
  150. package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
  151. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +33 -43
  152. package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
  153. package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
  154. package/src/form/index.tsx +4 -9
  155. package/src/form/useClearRestoreValue.tsx +2 -2
  156. package/src/form/validation.ts +1 -17
  157. package/src/hooks/data/delete.ts +2 -1
  158. package/src/hooks/data/save.ts +5 -2
  159. package/src/hooks/data/useDataSource.tsx +11 -3
  160. package/src/hooks/useBuildNavigationController.tsx +10 -3
  161. package/src/hooks/useProjectLog.tsx +18 -7
  162. package/src/index.ts +1 -0
  163. package/src/internal/useBuildDataSource.ts +69 -74
  164. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  165. package/src/internal/useBuildSideEntityController.tsx +17 -4
  166. package/src/internal/useUnsavedChangesDialog.tsx +3 -1
  167. package/src/preview/PropertyPreview.tsx +7 -4
  168. package/src/preview/PropertyPreviewProps.tsx +7 -1
  169. package/src/preview/components/BooleanPreview.tsx +1 -1
  170. package/src/preview/components/EnumValuesChip.tsx +1 -1
  171. package/src/preview/components/ImagePreview.tsx +24 -34
  172. package/src/preview/components/ReferencePreview.tsx +2 -12
  173. package/src/preview/components/StorageThumbnail.tsx +5 -1
  174. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  175. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  176. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
  177. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
  178. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  179. package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
  180. package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
  181. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  182. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  183. package/src/preview/util.ts +2 -2
  184. package/src/types/auth.tsx +2 -2
  185. package/src/types/collections.ts +29 -4
  186. package/src/types/customization_controller.tsx +0 -1
  187. package/src/types/datasource.ts +62 -43
  188. package/src/types/entities.ts +2 -0
  189. package/src/types/entity_overrides.tsx +2 -2
  190. package/src/types/fields.tsx +51 -45
  191. package/src/types/navigation.ts +1 -0
  192. package/src/types/plugins.tsx +12 -3
  193. package/src/types/properties.ts +25 -19
  194. package/src/types/side_dialogs_controller.tsx +13 -0
  195. package/src/types/storage.ts +82 -0
  196. package/src/util/entities.ts +5 -4
  197. package/src/util/icon_list.ts +14 -9
  198. package/src/util/icons.tsx +8 -2
  199. package/src/util/index.ts +1 -0
  200. package/src/util/objects.ts +17 -7
  201. package/src/util/permissions.ts +1 -0
  202. package/src/util/plurals.ts +0 -2
  203. package/src/util/property_utils.tsx +1 -1
  204. package/src/util/references.ts +3 -0
  205. package/src/util/resolutions.ts +43 -11
  206. package/src/util/storage.ts +79 -21
  207. package/src/util/useStorageUploadController.tsx +33 -7
  208. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  209. package/dist/core/Drawer.d.ts +0 -16
  210. package/dist/core/Scaffold.d.ts +0 -51
  211. package/dist/form/EntityForm.d.ts +0 -77
  212. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  213. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  214. package/src/core/Drawer.tsx +0 -139
  215. package/src/form/EntityForm.tsx +0 -736
  216. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
@@ -1,6 +1,6 @@
1
- import { EntityValues } from "./entities";
2
- import { CMSType, PropertyOrBuilder } from "./properties";
1
+ import { CMSType, Property, PropertyOrBuilder } from "./properties";
3
2
  import { ResolvedEntityCollection, ResolvedProperty } from "./resolved_entities";
3
+ import { FormexController } from "@firecms/formex";
4
4
 
5
5
  /**
6
6
  * When building a custom field you need to create a React component that takes
@@ -21,11 +21,6 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
21
21
  */
22
22
  value: T;
23
23
 
24
- /**
25
- * Initial value of this field
26
- */
27
- // initialValue: T | undefined;
28
-
29
24
  /**
30
25
  * Set value of field directly
31
26
  */
@@ -42,7 +37,7 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
42
37
  /**
43
38
  * Is the form currently submitting
44
39
  */
45
- isSubmitting: boolean;
40
+ isSubmitting?: boolean;
46
41
 
47
42
  /**
48
43
  * Should this field show the error indicator.
@@ -50,55 +45,50 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
50
45
  * filled) but we don't want to show the error until the user has tried
51
46
  * saving.
52
47
  */
53
- showError: boolean;
48
+ showError?: boolean;
54
49
 
55
50
  /**
56
51
  * Is there an error in this field. The error field has the same shape as
57
52
  * the field, replacing values with a string containing the error.
58
53
  * It takes the value `null` if there is no error
59
54
  */
60
- error: any | null;
55
+ error?: any | null;
61
56
 
62
57
  /**
63
58
  * Has this field been touched
64
59
  */
65
- touched: boolean;
60
+ touched?: boolean;
66
61
 
67
62
  /**
68
63
  * Property related to this field
69
64
  */
70
- property: ResolvedProperty<T>;
65
+ property: Property<T> | ResolvedProperty<T>;
71
66
 
72
67
  /**
73
68
  * Should this field include a description
74
69
  */
75
- includeDescription: boolean;
70
+ includeDescription?: boolean;
76
71
 
77
72
  /**
78
73
  * Flag to indicate that the underlying value has been updated in the
79
74
  * datasource
80
75
  */
81
- underlyingValueHasChanged: boolean;
76
+ underlyingValueHasChanged?: boolean;
82
77
 
83
78
  /**
84
79
  * Is this field part of an array
85
80
  */
86
- partOfArray: boolean;
87
-
88
- /**
89
- * Is this field part of a block (oneOf array)
90
- */
91
- partOfBlock: boolean;
81
+ partOfArray?: boolean;
92
82
 
93
83
  /**
94
- * Is this field being rendered in the entity table popup
84
+ * Should this field render with the minimal amount of UI elements
95
85
  */
96
- tableMode: boolean;
86
+ minimalistView?: boolean;
97
87
 
98
88
  /**
99
89
  * Should this field autofocus on mount
100
90
  */
101
- autoFocus: boolean;
91
+ autoFocus?: boolean;
102
92
 
103
93
  /**
104
94
  * Additional properties set by the developer
@@ -113,7 +103,12 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
113
103
  /**
114
104
  * Flag to indicate if this field should be disabled
115
105
  */
116
- disabled: boolean;
106
+ disabled?: boolean;
107
+
108
+ /**
109
+ * Size of the field
110
+ */
111
+ size?: "smallest" | "small" | "medium";
117
112
 
118
113
  }
119
114
 
@@ -124,37 +119,42 @@ export interface FieldProps<T extends CMSType = any, CustomProps = any, M extend
124
119
  export interface FormContext<M extends Record<string, any> = any> {
125
120
 
126
121
  /**
127
- * Collection of the entity being modified
122
+ * Current values of the entity
128
123
  */
129
- collection: ResolvedEntityCollection<M>;
124
+ values: M;
130
125
 
131
126
  /**
132
- * Current values of the entity
127
+ * Update the value of a field
128
+ * @param key
129
+ * @param value
130
+ * @param shouldValidate
133
131
  */
134
- values: EntityValues<M>;
132
+ setFieldValue: (key: string, value: any, shouldValidate?: boolean) => void;
135
133
 
136
134
  /**
137
- * Entity id, it can be null if it's a new entity
135
+ * Save the entity.
138
136
  */
139
- entityId?: string;
137
+ save: (values: M) => void;
140
138
 
141
139
  /**
142
- * Path this entity is located at
140
+ * Collection of the entity being modified
143
141
  */
144
- path: string;
142
+ collection?: ResolvedEntityCollection<M>;
145
143
 
146
144
  /**
147
- * Update the value of a field
148
- * @param key
149
- * @param value
150
- * @param shouldValidate
145
+ * Entity id, it can be null if it's a new entity
151
146
  */
152
- setFieldValue: (key: string, value: any, shouldValidate?: boolean) => void;
147
+ entityId: string;
148
+
149
+ /**
150
+ * Path this entity is located at
151
+ */
152
+ path?: string;
153
153
 
154
154
  /**
155
- * Save the entity
155
+ * This is the underlying formex controller that powers the form
156
156
  */
157
- save: (values: EntityValues<M>) => void;
157
+ formex: FormexController<M>;
158
158
  }
159
159
 
160
160
  /**
@@ -192,11 +192,6 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
192
192
  */
193
193
  underlyingValueHasChanged?: boolean;
194
194
 
195
- /**
196
- * Is this field being rendered in a table
197
- */
198
- tableMode?: boolean;
199
-
200
195
  /**
201
196
  * Is this field part of an array
202
197
  */
@@ -205,7 +200,7 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
205
200
  /**
206
201
  * Is this field part of a block (oneOf array)
207
202
  */
208
- partOfBlock?: boolean;
203
+ minimalistView?: boolean;
209
204
 
210
205
  /**
211
206
  * Should the field take focus when rendered. When opening the popup view
@@ -217,4 +212,15 @@ export interface PropertyFieldBindingProps<T extends CMSType, M extends Record<s
217
212
  * Should this field be disabled
218
213
  */
219
214
  disabled?: boolean;
215
+
216
+ /**
217
+ * Index of the field in the array.
218
+ * Only used when the field is part of an array.
219
+ */
220
+ index?: number;
221
+
222
+ /**
223
+ * The size of the field
224
+ */
225
+ size?: "smallest" | "small" | "medium",
220
226
  }
@@ -173,6 +173,7 @@ export interface CMSView {
173
173
  * You can use any of the icons in the Material specs:
174
174
  * https://fonts.google.com/icons
175
175
  * e.g. 'account_tree' or 'person'
176
+ * Find all the icons in https://firecms.co/docs/icons
176
177
  */
177
178
  icon?: string;
178
179
 
@@ -1,7 +1,7 @@
1
1
  import React, { PropsWithChildren } from "react";
2
2
 
3
3
  import { FireCMSContext } from "./firecms_context";
4
- import { CollectionActionsProps, EntityCollection } from "./collections";
4
+ import { CollectionActionsProps, EntityCollection, EntityTableController } from "./collections";
5
5
  import { User } from "./user";
6
6
  import { FieldProps, FormContext } from "./fields";
7
7
  import { CMSType, Property } from "./properties";
@@ -98,6 +98,13 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
98
98
  CollectionActionsStart?: React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_START__PROPS> | React.ComponentType<CollectionActionsProps<any, any, EC> & COL_ACTIONS_START__PROPS>[];
99
99
  collectionActionsStartProps?: COL_ACTIONS_START__PROPS;
100
100
 
101
+ blockSearch?: (props: {
102
+ context: FireCMSContext,
103
+ path: string,
104
+ collection: EC,
105
+ parentCollectionIds?: string[]
106
+ }) => boolean;
107
+
101
108
  showTextSearchBar?: (props: {
102
109
  context: FireCMSContext,
103
110
  path: string,
@@ -123,6 +130,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
123
130
  parentCollectionIds: string[],
124
131
  onHover: boolean,
125
132
  collection: EC;
133
+ tableController: EntityTableController;
126
134
  }>;
127
135
 
128
136
  /**
@@ -133,6 +141,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
133
141
  fullPath: string,
134
142
  parentCollectionIds: string[],
135
143
  collection: EC;
144
+ tableController: EntityTableController;
136
145
  }>;
137
146
  }
138
147
 
@@ -194,8 +203,8 @@ export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Reco
194
203
  property: Property<T> | ResolvedProperty<T>;
195
204
  Field: React.ComponentType<FieldProps<T, any, M>>;
196
205
  plugin: FireCMSPlugin;
197
- path: string;
198
- collection: EC;
206
+ path?: string;
207
+ collection?: EC;
199
208
  };
200
209
 
201
210
  export interface PluginGenericProps<UserType extends User = User> {
@@ -17,7 +17,7 @@ export type DataType<T extends CMSType = CMSType> =
17
17
  T extends GeoPoint ? "geopoint" :
18
18
  T extends Vector ? "vector" :
19
19
  T extends EntityReference ? "reference" :
20
- T extends Array<CMSType> ? "array" :
20
+ T extends Array<any> ? "array" :
21
21
  T extends Record<string, any> ? "map" : never;
22
22
 
23
23
  /**
@@ -49,7 +49,7 @@ export type AnyProperty =
49
49
  /**
50
50
  * @group Entity properties
51
51
  */
52
- export type Property<T extends CMSType = CMSType> =
52
+ export type Property<T extends CMSType = any> =
53
53
  T extends string ? StringProperty :
54
54
  T extends number ? NumberProperty :
55
55
  T extends boolean ? BooleanProperty :
@@ -149,7 +149,7 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
149
149
  /**
150
150
  * This value will be set by default for new entities.
151
151
  */
152
- defaultValue?: T;
152
+ defaultValue?: T | null;
153
153
 
154
154
  /**
155
155
  * Should this property be editable. If set to true, the user will be able to modify the property and
@@ -277,6 +277,7 @@ export type PropertyBuilder<T extends CMSType = any, M extends Record<string, an
277
277
  values,
278
278
  previousValues,
279
279
  propertyValue,
280
+ index,
280
281
  path,
281
282
  entityId
282
283
  }: PropertyBuilderProps<M>) => Property<T> | null;
@@ -404,7 +405,7 @@ export interface StringProperty extends BaseProperty<string> {
404
405
  /**
405
406
  * @group Entity properties
406
407
  */
407
- export interface ArrayProperty<T extends ArrayT[] = any[], ArrayT extends CMSType = CMSType> extends BaseProperty<T> {
408
+ export interface ArrayProperty<T extends ArrayT[] = any[], ArrayT extends CMSType = any> extends BaseProperty<T> {
408
409
 
409
410
  dataType: "array";
410
411
 
@@ -733,13 +734,13 @@ export type StorageConfig = {
733
734
  * You can use this prop to customize the uploaded filename.
734
735
  * You can use a function as a callback or a string where you
735
736
  * specify some placeholders that get replaced with the corresponding values.
736
- * - {file} - Full file name
737
- * - {file.name} - Name of the file without extension
738
- * - {file.ext} - Extension of the file
739
- * - {rand} - Random value used to avoid name collisions
740
- * - {entityId} - ID of the entity
741
- * - {propertyKey} - ID of this property
742
- * - {path} - Path of this entity
737
+ * - `{file}` - Full file name
738
+ * - `{file.name}` - Name of the file without extension
739
+ * - `{file.ext}` - Extension of the file
740
+ * - `{rand}` - Random value used to avoid name collisions
741
+ * - `{entityId}` - ID of the entity
742
+ * - `{propertyKey}` - ID of this property
743
+ * - `{path}` - Path of this entity
743
744
  *
744
745
  * @param context
745
746
  */
@@ -750,13 +751,13 @@ export type StorageConfig = {
750
751
  *
751
752
  * You can use a function as a callback or a string where you
752
753
  * specify some placeholders that get replaced with the corresponding values.
753
- * - {file} - Full file name
754
- * - {file.name} - Name of the file without extension
755
- * - {file.ext} - Extension of the file
756
- * - {rand} - Random value used to avoid name collisions
757
- * - {entityId} - ID of the entity
758
- * - {propertyKey} - ID of this property
759
- * - {path} - Path of this entity
754
+ * - `{file}` - Full file name
755
+ * - `{file.name}` - Name of the file without extension
756
+ * - `{file.ext}` - Extension of the file
757
+ * - `{rand}` - Random value used to avoid name collisions
758
+ * - `{entityId}` - ID of the entity
759
+ * - `{propertyKey}` - ID of this property
760
+ * - `{path}` - Path of this entity
760
761
  */
761
762
  storagePath: string | ((context: UploadedFileContext) => string);
762
763
 
@@ -783,6 +784,11 @@ export type StorageConfig = {
783
784
  */
784
785
  postProcess?: (pathOrUrl: string) => Promise<string>;
785
786
 
787
+ /**
788
+ * You can use this prop in order to provide a custom preview URL.
789
+ * Useful when the file's path is different from the original field value
790
+ */
791
+ previewUrl?: (fileName: string) => string;
786
792
  }
787
793
 
788
794
  /**
@@ -812,7 +818,7 @@ export interface UploadedFileContext {
812
818
  /**
813
819
  * Entity path. E.g. `products/PID/locales`
814
820
  */
815
- path: string;
821
+ path?: string;
816
822
 
817
823
  /**
818
824
  * Values of the current entity
@@ -1,3 +1,5 @@
1
+ import React from "react";
2
+
1
3
  /**
2
4
  * Controller to open the side dialog
3
5
  * @group Hooks and utilities
@@ -14,6 +16,12 @@ export interface SideDialogsController {
14
16
  */
15
17
  sidePanels: SideDialogPanelProps[];
16
18
 
19
+ /**
20
+ * Override the current side panels
21
+ * @param panels
22
+ */
23
+ setSidePanels: (panels: SideDialogPanelProps[]) => void;
24
+
17
25
  /**
18
26
  * Open one or multiple side panels
19
27
  * @param props
@@ -65,4 +73,9 @@ export interface SideDialogPanelProps {
65
73
  * Callback when the panel is closed
66
74
  */
67
75
  onClose?: () => void;
76
+
77
+ /**
78
+ * Use this prop to store additional data in the panel
79
+ */
80
+ additional?: any;
68
81
  }
@@ -102,4 +102,86 @@ export interface StorageSource {
102
102
  * @param bucket
103
103
  */
104
104
  getFile: (path: string, bucket?: string) => Promise<File | null>;
105
+
106
+ /**
107
+ * Delete a file.
108
+ * @param path
109
+ * @param bucket
110
+ */
111
+ deleteFile: (path: string, bucket?: string) => Promise<void>;
112
+
113
+ /**
114
+ * List the contents of a path.
115
+ * @param path
116
+ * @param options
117
+ */
118
+ list: (path: string, options?: {
119
+ bucket?: string,
120
+ maxResults?: number,
121
+ pageToken?: string
122
+ }) => Promise<StorageListResult>;
123
+
124
+ }
125
+
126
+ /**
127
+ * Result returned by list().
128
+ * @public
129
+ */
130
+ export declare interface StorageListResult {
131
+ /**
132
+ * References to prefixes (sub-folders). You can call list() on them to
133
+ * get its contents.
134
+ *
135
+ * Folders are implicit based on '/' in the object paths.
136
+ * For example, if a bucket has two objects '/a/b/1' and '/a/b/2', list('/a')
137
+ * will return '/a/b' as a prefix.
138
+ */
139
+ prefixes: StorageReference[];
140
+ /**
141
+ * Objects in this directory.
142
+ * You can call getMetadata() and getDownloadUrl() on them.
143
+ */
144
+ items: StorageReference[];
145
+ /**
146
+ * If set, there might be more results for this list. Use this token to resume the list.
147
+ */
148
+ nextPageToken?: string;
149
+ }
150
+
151
+ /**
152
+ * Represents a reference to a Google Cloud Storage object. Developers can
153
+ * upload, download, and delete objects, as well as get/set object metadata.
154
+ * @public
155
+ */
156
+ export declare interface StorageReference {
157
+ /**
158
+ * Returns a gs:// URL for this object in the form
159
+ * `gs://<bucket>/<path>/<to>/<object>`
160
+ * @returns The gs:// URL.
161
+ */
162
+ toString(): string;
163
+
164
+ /**
165
+ * A reference to the root of this object's bucket.
166
+ */
167
+ root: StorageReference;
168
+ /**
169
+ * The name of the bucket containing this reference's object.
170
+ */
171
+ bucket: string;
172
+ /**
173
+ * The full path of this object.
174
+ */
175
+ fullPath: string;
176
+ /**
177
+ * The short name of this object, which is the last component of the full path.
178
+ * For example, if fullPath is 'full/path/image.png', name is 'image.png'.
179
+ */
180
+ name: string;
181
+
182
+ /**
183
+ * A reference pointing to the parent location of this reference, or null if
184
+ * this reference is the root.
185
+ */
186
+ parent: StorageReference | null;
105
187
  }
@@ -15,7 +15,7 @@ import {
15
15
  } from "../types";
16
16
  import { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from "./common";
17
17
 
18
- export function isReadOnly(property: Property | ResolvedProperty): boolean {
18
+ export function isReadOnly(property: Property<any> | ResolvedProperty<any>): boolean {
19
19
  if (property.readOnly)
20
20
  return true;
21
21
  if (property.dataType === "date") {
@@ -48,12 +48,12 @@ export function getDefaultValuesFor<M extends Record<string, any>>(properties: P
48
48
 
49
49
  export function getDefaultValueFor(property: PropertyOrBuilder) {
50
50
  if (isPropertyBuilder(property)) return undefined;
51
- if (property.dataType === "map" && property.properties) {
51
+ if (property.defaultValue || property.defaultValue === null) {
52
+ return property.defaultValue;
53
+ } else if (property.dataType === "map" && property.properties) {
52
54
  const defaultValuesFor = getDefaultValuesFor(property.properties as Properties);
53
55
  if (Object.keys(defaultValuesFor).length === 0) return undefined;
54
56
  return defaultValuesFor;
55
- } else if (property.defaultValue) {
56
- return property.defaultValue;
57
57
  } else {
58
58
  return getDefaultValueForDataType(property.dataType);
59
59
  }
@@ -152,6 +152,7 @@ export function traverseValuesProperties<M extends Record<string, any>>(
152
152
  .map(([key, property]) => {
153
153
  const inputValue = inputValues && (inputValues)[key];
154
154
  const updatedValue = traverseValueProperty(inputValue, property as Property, operation);
155
+ if (updatedValue === null) return null;
155
156
  if (updatedValue === undefined) return undefined;
156
157
  return ({ [key]: updatedValue });
157
158
  })
@@ -1,17 +1,22 @@
1
1
  import { iconSynonyms } from "./icon_synonyms";
2
2
  import { iconKeys } from "@firecms/ui";
3
+ import Fuse from "fuse.js";
3
4
 
4
- // @ts-ignore
5
- import * as JsSearch from "js-search";
6
5
 
7
- export const iconsSearch = new JsSearch.Search("key");
8
- iconsSearch.addIndex("synonyms");
9
-
10
- iconsSearch.addDocuments(iconKeys
6
+ const map = iconKeys
11
7
  .map((importName) => {
8
+ // @ts-ignore
9
+ const iconSynonym = importName in iconSynonyms ? iconSynonyms[importName] : "";
12
10
  return {
13
11
  key: importName,
14
- // @ts-ignore
15
- synonyms: iconSynonyms[importName] ?? [],
12
+ synonyms: iconSynonym,
16
13
  }
17
- }));
14
+ });
15
+ export const iconsSearch = new Fuse(map, {
16
+ isCaseSensitive: false,
17
+ shouldSort: true,
18
+ distance: 0,
19
+ keys: ["key", "synonyms"]
20
+ })
21
+
22
+
@@ -22,7 +22,13 @@ export type IconViewProps = {
22
22
  }
23
23
 
24
24
  export const IconForView = React.memo(
25
- function IconForView({ collectionOrView, className }: { collectionOrView?: IconViewProps, className?: string }): React.ReactElement {
25
+ function IconForView({
26
+ collectionOrView,
27
+ className,
28
+ size = "medium"
29
+ }: {
30
+ collectionOrView?: IconViewProps, className?: string, size?: "smallest" | "small" | "medium" | "large" | number,
31
+ }): React.ReactElement {
26
32
  if (!collectionOrView) return <></>;
27
33
  const icon = getIcon(collectionOrView.icon, className);
28
34
  if (collectionOrView?.icon && icon)
@@ -45,7 +51,7 @@ export const IconForView = React.memo(
45
51
  if (!key)
46
52
  key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];
47
53
 
48
- return <Icon iconKey={key} size={"medium"} className={className}/>;
54
+ return <Icon iconKey={key} size={size} className={className}/>;
49
55
  }, (prevProps, nextProps) => {
50
56
  return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon);
51
57
  });
package/src/util/index.ts CHANGED
@@ -21,3 +21,4 @@ export * from "./make_properties_editable";
21
21
  export * from "./join_collections";
22
22
  export * from "./builders";
23
23
  export * from "./useTraceUpdate";
24
+ export * from "./storage";
@@ -141,15 +141,25 @@ export function removePropsIfExisting(source: any, comparison: any) {
141
141
 
142
142
  const res = isArray(source) ? [...source] : { ...source };
143
143
 
144
- Object.keys(comparison).forEach(key => {
145
- if (key in res) {
146
- if (isObject(res[key]) && isObject(comparison[key])) {
147
- res[key] = removePropsIfExisting(res[key], comparison[key]);
148
- } else if (res[key] === comparison[key]) {
149
- isArray(res) ? res.splice(key, 1) : delete res[key];
144
+ if (isArray(res)) {
145
+ for (let i = res.length - 1; i >= 0; i--) {
146
+ if (res[i] === comparison[i]) {
147
+ res.splice(i, 1);
148
+ } else if (isObject(res[i]) && isObject(comparison[i])) {
149
+ res[i] = removePropsIfExisting(res[i], comparison[i]);
150
150
  }
151
151
  }
152
- });
152
+ } else {
153
+ Object.keys(comparison).forEach(key => {
154
+ if (key in res) {
155
+ if (isObject(res[key]) && isObject(comparison[key])) {
156
+ res[key] = removePropsIfExisting(res[key], comparison[key]);
157
+ } else if (res[key] === comparison[key]) {
158
+ delete res[key];
159
+ }
160
+ }
161
+ });
162
+ }
153
163
 
154
164
  return res;
155
165
  }
@@ -49,6 +49,7 @@ export function canCreateEntity<M extends Record<string, any>, UserType extends
49
49
  authController: AuthController<UserType>,
50
50
  path: string,
51
51
  entity: Entity<M> | null): boolean {
52
+ if (collection.collectionGroup) return false;
52
53
  return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;
53
54
  }
54
55
 
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Returns the plural of an English word.
3
3
  *
4
- * @export
5
4
  * @param {string} word
6
5
  * @param {number} [amount]
7
6
  * @returns {string}
@@ -92,7 +91,6 @@ export function plural(word: string, amount?: number): string {
92
91
  /**
93
92
  * Returns the singular of an English word.
94
93
  *
95
- * @export
96
94
  * @param {string} word
97
95
  * @param {number} [amount]
98
96
  * @returns {string}
@@ -35,7 +35,7 @@ export function getIconForWidget(widget: PropertyConfig | undefined,
35
35
  }
36
36
 
37
37
  export function getIconForProperty(
38
- property: PropertyOrBuilder | ResolvedProperty,
38
+ property: PropertyOrBuilder<any> | ResolvedProperty<any>,
39
39
  size: "small" | "medium" | "large" = "small",
40
40
  fields: Record<string, PropertyConfig> = {}
41
41
  ): React.ReactNode {
@@ -9,6 +9,9 @@ export function getEntityPreviewKeys(targetCollection: EntityCollection<any>,
9
9
  limit = 3) {
10
10
  const allProperties = Object.keys(targetCollection.properties);
11
11
  let listProperties = previewProperties?.filter(p => allProperties.includes(p as string));
12
+ if (!listProperties && targetCollection.previewProperties) {
13
+ listProperties = targetCollection.previewProperties?.filter(p => allProperties.includes(p as string));
14
+ }
12
15
  if (listProperties && listProperties.length > 0) {
13
16
  return listProperties;
14
17
  } else {