@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
@@ -217,6 +217,38 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
217
217
  : null;
218
218
  }
219
219
 
220
+ export function getArrayResolvedProperties<M>({
221
+ propertyKey,
222
+ propertyValue,
223
+ property,
224
+ ...props
225
+ }: {
226
+ propertyValue: any,
227
+ propertyKey?: string,
228
+ property: ArrayProperty<any> | ResolvedArrayProperty<any>,
229
+ ignoreMissingFields: boolean,
230
+ values?: Partial<M>;
231
+ previousValues?: Partial<M>;
232
+ path?: string;
233
+ entityId?: string;
234
+ index?: number;
235
+ fromBuilder?: boolean;
236
+ fields?: Record<string, PropertyConfig>
237
+ }) {
238
+
239
+ const of = property.of;
240
+ return Array.isArray(propertyValue)
241
+ ? propertyValue.map((v: any, index: number) => {
242
+ return resolveProperty({
243
+ propertyKey: `${propertyKey}.${index}`,
244
+ propertyOrBuilder: of,
245
+ ...props,
246
+ index
247
+ });
248
+ }).filter(e => Boolean(e)) as ResolvedProperty[]
249
+ : [];
250
+ }
251
+
220
252
  export function resolveArrayProperty<T extends any[], M>({
221
253
  propertyKey,
222
254
  property,
@@ -254,17 +286,14 @@ export function resolveArrayProperty<T extends any[], M>({
254
286
  } as ResolvedArrayProperty;
255
287
  } else {
256
288
  const of = property.of;
257
- const resolvedProperties: ResolvedProperty[] = Array.isArray(propertyValue)
258
- ? propertyValue.map((v: any, index: number) => resolveProperty({
259
- propertyKey: `${propertyKey}.${index}`,
260
- propertyOrBuilder: of,
261
- ignoreMissingFields,
262
- ...props,
263
- index
264
- })).filter(e => Boolean(e)) as ResolvedProperty[]
265
- : [];
289
+ const resolvedProperties = getArrayResolvedProperties({
290
+ propertyValue,
291
+ propertyKey,
292
+ property,
293
+ ignoreMissingFields,
294
+ ...props
295
+ });
266
296
  const ofProperty = resolveProperty({
267
- propertyKey: `${propertyKey}`,
268
297
  propertyOrBuilder: of,
269
298
  ignoreMissingFields,
270
299
  ...props
@@ -295,6 +324,7 @@ export function resolveArrayProperty<T extends any[], M>({
295
324
  }).filter(e => Boolean(e)) as ResolvedProperty[]
296
325
  : [];
297
326
  const properties = resolveProperties<any>({
327
+ propertyKey,
298
328
  properties: property.oneOf.properties,
299
329
  ignoreMissingFields,
300
330
  ...props
@@ -327,10 +357,12 @@ export function resolveArrayProperty<T extends any[], M>({
327
357
  * @param value
328
358
  */
329
359
  export function resolveProperties<M extends Record<string, any>>({
360
+ propertyKey,
330
361
  properties,
331
362
  ignoreMissingFields,
332
363
  ...props
333
364
  }: {
365
+ propertyKey?: string,
334
366
  properties: PropertiesOrBuilders<M>,
335
367
  values?: Partial<M>,
336
368
  previousValues?: Partial<M>,
@@ -344,7 +376,7 @@ export function resolveProperties<M extends Record<string, any>>({
344
376
  return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)
345
377
  .map(([key, property]) => {
346
378
  const childResolvedProperty = resolveProperty({
347
- propertyKey: key,
379
+ propertyKey: propertyKey ? `${propertyKey}.${key}` : undefined,
348
380
  propertyOrBuilder: property,
349
381
  ignoreMissingFields,
350
382
  ...props
@@ -1,22 +1,39 @@
1
1
  import {
2
+ ArrayProperty,
2
3
  EntityValues,
4
+ PropertyOrBuilder,
3
5
  ResolvedArrayProperty,
4
6
  ResolvedStringProperty,
5
7
  StorageConfig,
8
+ StringProperty,
6
9
  UploadedFileContext
7
10
  } from "../types";
8
11
  import { randomString } from "./strings";
9
12
 
10
- export async function resolveFilenameString<M extends object>(
11
- input: string | ((context: UploadedFileContext) => Promise<string> | string),
12
- storage: StorageConfig,
13
- values: EntityValues<M>,
14
- entityId: string,
15
- path: string,
13
+ interface ResolveFilenameStringParams<M extends object> {
14
+ input: string | ((context: UploadedFileContext) => (Promise<string> | string));
15
+ storage: StorageConfig;
16
+ values: EntityValues<M>;
17
+ entityId: string;
18
+ path?: string;
16
19
  property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,
17
- file: File,
18
- propertyKey: string): Promise<string> {
20
+ file: File;
21
+ propertyKey: string;
22
+ }
23
+
24
+ export async function resolveStorageFilenameString<M extends object>(
25
+ {
26
+ input,
27
+ storage,
28
+ values,
29
+ entityId,
30
+ path,
31
+ property,
32
+ file,
33
+ propertyKey
34
+ }: ResolveFilenameStringParams<M>): Promise<string> {
19
35
  let result;
36
+
20
37
  if (typeof input === "function") {
21
38
  result = await input({
22
39
  path,
@@ -30,7 +47,13 @@ export async function resolveFilenameString<M extends object>(
30
47
  if (!result)
31
48
  console.warn("Storage callback returned empty result. Using default name value")
32
49
  } else {
33
- result = replacePlaceholders(file, input, entityId, propertyKey, path);
50
+ result = replacePlaceholders({
51
+ file,
52
+ input,
53
+ entityId,
54
+ propertyKey,
55
+ path
56
+ });
34
57
  }
35
58
 
36
59
  if (!result)
@@ -39,15 +62,28 @@ export async function resolveFilenameString<M extends object>(
39
62
  return result;
40
63
  }
41
64
 
65
+ interface ResolveStoragePathStringParams<M extends object> {
66
+ input: string | ((context: UploadedFileContext) => string);
67
+ storage: StorageConfig;
68
+ values: EntityValues<M>;
69
+ entityId: string;
70
+ path?: string;
71
+ property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;
72
+ file: File;
73
+ propertyKey: string;
74
+ }
75
+
42
76
  export function resolveStoragePathString<M extends object>(
43
- input: string | ((context: UploadedFileContext) => string),
44
- storage: StorageConfig,
45
- values: EntityValues<M>,
46
- entityId: string,
47
- path: string,
48
- property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,
49
- file: File,
50
- propertyKey: string): string {
77
+ {
78
+ input,
79
+ storage,
80
+ values,
81
+ entityId,
82
+ path,
83
+ property,
84
+ file,
85
+ propertyKey
86
+ }: ResolveStoragePathStringParams<M>): string {
51
87
  let result;
52
88
  if (typeof input === "function") {
53
89
  result = input({
@@ -62,7 +98,13 @@ export function resolveStoragePathString<M extends object>(
62
98
  if (!result)
63
99
  console.warn("Storage callback returned empty result. Using default name value")
64
100
  } else {
65
- result = replacePlaceholders(file, input, entityId, propertyKey, path);
101
+ result = replacePlaceholders({
102
+ file,
103
+ input,
104
+ entityId,
105
+ propertyKey,
106
+ path
107
+ });
66
108
  }
67
109
 
68
110
  if (!result)
@@ -71,14 +113,30 @@ export function resolveStoragePathString<M extends object>(
71
113
  return result;
72
114
  }
73
115
 
74
- function replacePlaceholders(file: File, input: string, entityId: string, propertyKey: string, path: string) {
116
+ interface Placeholders {
117
+ file: File;
118
+ input: string;
119
+ entityId: string;
120
+ propertyKey: string;
121
+ path?: string;
122
+ }
123
+
124
+ function replacePlaceholders({
125
+ file,
126
+ input,
127
+ entityId,
128
+ propertyKey,
129
+ path
130
+ }: Placeholders) {
75
131
  const ext = file.name.split(".").pop();
76
132
  let result = input.replace("{entityId}", entityId)
77
133
  .replace("{propertyKey}", propertyKey)
78
134
  .replace("{rand}", randomString())
79
135
  .replace("{file}", file.name)
80
- .replace("{file.type}", file.type)
81
- .replace("{path}", path);
136
+ .replace("{file.type}", file.type);
137
+ if (path) {
138
+ result = result.replace("{path}", path);
139
+ }
82
140
  if (ext) {
83
141
  result = result.replace("{file.ext}", ext);
84
142
  const name = file.name.replace(`.${ext}`, "");
@@ -2,9 +2,11 @@ import Resizer from "react-image-file-resizer";
2
2
  import equal from "react-fast-compare";
3
3
 
4
4
  import {
5
+ ArrayProperty,
5
6
  EntityValues,
6
7
  ImageCompression,
7
8
  Property,
9
+ PropertyOrBuilder,
8
10
  ResolvedArrayProperty,
9
11
  ResolvedStringProperty,
10
12
  StorageConfig,
@@ -14,7 +16,8 @@ import {
14
16
  import { useCallback, useEffect, useState } from "react";
15
17
  import { PreviewSize } from "../preview";
16
18
  import { randomString } from "./strings";
17
- import { resolveFilenameString, resolveStoragePathString } from "./storage";
19
+ import { resolveStorageFilenameString, resolveStoragePathString } from "./storage";
20
+ import { resolveProperty } from "./resolutions";
18
21
 
19
22
  /**
20
23
  * Internal representation of an item in the storage
@@ -46,9 +49,9 @@ export function useStorageUploadController<M extends object>({
46
49
  entityId: string,
47
50
  entityValues: EntityValues<M>,
48
51
  value: string | string[] | null;
49
- path: string,
52
+ path?: string,
50
53
  propertyKey: string,
51
- property: ResolvedStringProperty | ResolvedArrayProperty<string[]>,
54
+ property: StringProperty | ArrayProperty<string[]> | ResolvedStringProperty | ResolvedArrayProperty<string[]>,
52
55
  storageSource: StorageSource,
53
56
  disabled: boolean,
54
57
  onChange: (value: string | string[] | null) => void
@@ -93,20 +96,43 @@ export function useStorageUploadController<M extends object>({
93
96
  }
94
97
  }, [internalInitialValue, value, initialValue]);
95
98
 
99
+ const resolvedProperty = resolveProperty({
100
+ propertyOrBuilder: property as PropertyOrBuilder,
101
+ values: entityValues
102
+ }) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
103
+
96
104
  const fileNameBuilder = useCallback(async (file: File) => {
97
105
  if (storage.fileName) {
98
- const fileName = await resolveFilenameString(storage.fileName, storage, entityValues, entityId, path, property, file, propertyKey);
106
+ const fileName = await resolveStorageFilenameString({
107
+ input: storage.fileName,
108
+ storage,
109
+ values: entityValues,
110
+ entityId,
111
+ path,
112
+ property: resolvedProperty,
113
+ file,
114
+ propertyKey
115
+ });
99
116
  if (!fileName || fileName.length === 0) {
100
117
  throw Error("You need to return a valid filename");
101
118
  }
102
119
  return fileName;
103
120
  }
104
121
  return randomString() + "_" + file.name;
105
- }, [entityId, entityValues, path, property, propertyKey, storage]);
122
+ }, [entityId, entityValues, path, resolvedProperty, propertyKey, storage]);
106
123
 
107
124
  const storagePathBuilder = useCallback((file: File) => {
108
- return resolveStoragePathString(storage.storagePath, storage, entityValues, entityId, path, property, file, propertyKey) ?? "/";
109
- }, [entityId, entityValues, path, property, propertyKey, storage]);
125
+ return resolveStoragePathString({
126
+ input: storage.storagePath,
127
+ storage,
128
+ values: entityValues,
129
+ entityId,
130
+ path,
131
+ property: resolvedProperty,
132
+ file,
133
+ propertyKey
134
+ }) ?? "/";
135
+ }, [entityId, entityValues, path, resolvedProperty, propertyKey, storage]);
110
136
 
111
137
  const onFileUploadComplete = useCallback(async (uploadedPath: string,
112
138
  entry: StorageFieldItem,
@@ -1,3 +0,0 @@
1
- export declare function PropertyIdCopyTooltipContent({ propertyId }: {
2
- propertyId: string;
3
- }): import("react/jsx-runtime").JSX.Element;
@@ -1,16 +0,0 @@
1
- /**
2
- * Props used in case you need to override the default drawer
3
- * @group Core
4
- */
5
- export type DrawerProps = {
6
- hovered: boolean;
7
- drawerOpen: boolean;
8
- openDrawer: () => void;
9
- closeDrawer: () => void;
10
- autoOpenDrawer?: boolean;
11
- };
12
- /**
13
- * Default drawer used in the CMS
14
- * @group Core
15
- */
16
- export declare function Drawer(): import("react/jsx-runtime").JSX.Element;
@@ -1,51 +0,0 @@
1
- import React from "react";
2
- import { DrawerProps } from "./Drawer";
3
- import { FireCMSAppBarProps } from "../components";
4
- export declare const DRAWER_WIDTH = 280;
5
- export declare function useDrawer(): DrawerProps;
6
- /**
7
- * @group Core
8
- */
9
- export interface ScaffoldProps<ExtraAppbarProps = object> {
10
- /**
11
- * Name of the app, displayed as the main title and in the tab title
12
- */
13
- name?: React.ReactNode;
14
- /**
15
- * Logo to be displayed in the drawer of the CMS
16
- */
17
- logo?: string;
18
- /**
19
- * Whether to include the drawer in the scaffold
20
- */
21
- includeDrawer?: boolean;
22
- /**
23
- * You can define a custom drawer to be displayed in the scaffold.
24
- * Use the hook `useDrawer` to access the context values.
25
- */
26
- drawer?: React.ReactNode;
27
- /**
28
- * Open the drawer on hover
29
- */
30
- autoOpenDrawer?: boolean;
31
- /**
32
- * The AppBar component to be used in the scaffold.
33
- */
34
- FireCMSAppBar?: React.ComponentType<FireCMSAppBarProps<ExtraAppbarProps>>;
35
- /**
36
- * Additional props passed to the custom AppBar
37
- */
38
- fireCMSAppBarProps?: Partial<FireCMSAppBarProps> & ExtraAppbarProps;
39
- }
40
- /**
41
- * This view acts as a scaffold for FireCMS.
42
- *
43
- * It is in charge of displaying the navigation drawer, top bar and main
44
- * collection views.
45
- * This component needs a parent {@link FireCMS}
46
- *
47
- * @param props
48
- * @constructor
49
- * @group Core
50
- */
51
- export declare const Scaffold: React.NamedExoticComponent<React.PropsWithChildren<ScaffoldProps<object>>>;
@@ -1,77 +0,0 @@
1
- import { Entity, EntityCollection, EntityStatus, EntityValues, FormContext, ResolvedEntityCollection } from "../types";
2
- import { ValidationError } from "yup";
3
- /**
4
- * @group Components
5
- */
6
- export interface EntityFormProps<M extends Record<string, any>> {
7
- /**
8
- * New or existing status
9
- */
10
- status: EntityStatus;
11
- /**
12
- * Path of the collection this entity is located
13
- */
14
- path: string;
15
- /**
16
- * The collection is used to build the fields of the form
17
- */
18
- collection: EntityCollection<M>;
19
- /**
20
- * The updated entity is passed from the parent component when the underlying data
21
- * has changed in the datasource
22
- */
23
- entity?: Entity<M>;
24
- /**
25
- * The callback function called when Save is clicked and validation is correct
26
- */
27
- onEntitySaveRequested: (props: EntityFormSaveParams<M>) => Promise<void>;
28
- /**
29
- * The callback function called when discard is clicked
30
- */
31
- onDiscard?: () => void;
32
- /**
33
- * The callback function when the form is dirty, so the values are different
34
- * from the original ones
35
- */
36
- onModified?: (dirty: boolean) => void;
37
- /**
38
- * The callback function when the form original values have been modified
39
- */
40
- onValuesChanged?: (values?: EntityValues<M>) => void;
41
- /**
42
- *
43
- * @param id
44
- */
45
- onIdChange?: (id: string) => void;
46
- currentEntityId?: string;
47
- onFormContextChange?: (formContext: FormContext<M>) => void;
48
- hideId?: boolean;
49
- autoSave?: boolean;
50
- onIdUpdateError?: (error: any) => void;
51
- }
52
- export type EntityFormSaveParams<M extends Record<string, any>> = {
53
- collection: ResolvedEntityCollection<M>;
54
- path: string;
55
- entityId: string | undefined;
56
- values: EntityValues<M>;
57
- previousValues?: EntityValues<M>;
58
- closeAfterSave: boolean;
59
- autoSave: boolean;
60
- };
61
- /**
62
- * This is the form used internally by the CMS
63
- * @param status
64
- * @param path
65
- * @param collection
66
- * @param entity
67
- * @param onEntitySave
68
- * @param onDiscard
69
- * @param onModified
70
- * @param onValuesChanged
71
- * @constructor
72
- * @group Components
73
- */
74
- export declare const EntityForm: typeof EntityFormInternal;
75
- declare function EntityFormInternal<M extends Record<string, any>>({ status, path, collection: inputCollection, entity, onEntitySaveRequested, onDiscard, onModified, onValuesChanged, onIdChange, onFormContextChange, hideId, autoSave, onIdUpdateError, }: EntityFormProps<M>): import("react/jsx-runtime").JSX.Element;
76
- export declare function yupToFormErrors(yupError: ValidationError): Record<string, any>;
77
- export {};
@@ -1,9 +0,0 @@
1
- import { FieldProps } from "../../types";
2
- /**
3
- * Render a markdown field that allows edition and seeing the preview.
4
- *
5
- * This is one of the internal components that get mapped natively inside forms
6
- * and tables to the specified properties.
7
- * @group Form fields
8
- */
9
- export declare function MarkdownFieldBinding({ propertyKey, value, setValue, error, showError, disabled, autoFocus, touched, property, tableMode, includeDescription, context }: FieldProps<string>): import("react/jsx-runtime").JSX.Element;
@@ -1,27 +0,0 @@
1
- import { ContentCopyIcon, IconButton, Typography } from "@firecms/ui";
2
- import { useCallback, useState } from "react";
3
-
4
- export function PropertyIdCopyTooltipContent({ propertyId }: { propertyId: string }) {
5
-
6
- const [copied, setCopied] = useState(false);
7
-
8
- return (
9
- <div className={"flex flex-row gap-2 items-center justify-center text-white"}>
10
- <div>
11
- <Typography variant={"caption"} className={"min-w-20 text-slate-400"}
12
- color={"disabled"}>{copied ? "Copied" : "Property ID"}</Typography>
13
- <Typography variant={"caption"} className={"text-white"}><code>{propertyId}</code></Typography>
14
- </div>
15
- <IconButton size={"small"}>
16
- <ContentCopyIcon size={"smallest"}
17
- className={"text-white"}
18
- onClick={useCallback(() => {
19
- navigator.clipboard.writeText(propertyId);
20
- setCopied(true);
21
- setTimeout(() => setCopied(false), 2000);
22
- }, [propertyId])}
23
- />
24
- </IconButton>
25
- </div>
26
- );
27
- }
@@ -1,139 +0,0 @@
1
- import React, { useCallback } from "react";
2
-
3
- import { useLargeLayout, useNavigationController } from "../hooks";
4
-
5
- import { useNavigate } from "react-router-dom";
6
- import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
7
- import { IconForView } from "../util";
8
- import { cls, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from "@firecms/ui";
9
- import { useAnalyticsController } from "../hooks/useAnalyticsController";
10
- import { useDrawer } from "./Scaffold";
11
- import { DrawerNavigationItem } from "./DrawerNavigationItem";
12
-
13
- /**
14
- * Props used in case you need to override the default drawer
15
- * @group Core
16
- */
17
- export type DrawerProps = {
18
- hovered: boolean,
19
- drawerOpen: boolean,
20
- openDrawer: () => void,
21
- closeDrawer: () => void,
22
- autoOpenDrawer?: boolean
23
- }
24
-
25
- /**
26
- * Default drawer used in the CMS
27
- * @group Core
28
- */
29
- export function Drawer() {
30
-
31
- const {
32
- hovered,
33
- drawerOpen,
34
- closeDrawer,
35
- } = useDrawer();
36
-
37
- const analyticsController = useAnalyticsController();
38
- const navigation = useNavigationController();
39
-
40
- const tooltipsOpen = hovered && !drawerOpen;
41
- const largeLayout = useLargeLayout();
42
- const navigate = useNavigate();
43
-
44
- const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
45
-
46
- if (!navigation.topLevelNavigation)
47
- throw Error("Navigation not ready in Drawer");
48
-
49
- const {
50
- navigationEntries,
51
- groups
52
- }: TopNavigationResult = navigation.topLevelNavigation;
53
-
54
- const adminViews = navigationEntries.filter(e => e.type === "admin") ?? [];
55
- const groupsWithoutAdmin = groups.filter(g => g !== "Admin");
56
-
57
- const buildGroupHeader = useCallback((group?: string) => {
58
- if (!drawerOpen) return <div className="h-12 w-full"/>;
59
- return <div
60
- className="pt-8 pl-6 pr-8 pb-2 flex flex-row items-center">
61
- <Typography variant={"caption"}
62
- color={"secondary"}
63
- className="font-medium flex-grow line-clamp-1">
64
- {group ? group.toUpperCase() : "Views".toUpperCase()}
65
- </Typography>
66
-
67
- </div>;
68
- }, [drawerOpen]);
69
-
70
- const onClick = (view: TopNavigationEntry) => {
71
- const eventName: CMSAnalyticsEvent = view.type === "collection"
72
- ? "drawer_navigate_to_collection"
73
- : (view.type === "view" ? "drawer_navigate_to_view" : "unmapped_event");
74
- analyticsController.onAnalyticsEvent?.(eventName, { url: view.url });
75
- if (!largeLayout)
76
- closeDrawer();
77
- };
78
-
79
- return (
80
- <>
81
-
82
- <div className={"flex-grow overflow-scroll no-scrollbar"}>
83
-
84
- {groupsWithoutAdmin.map((group) => (
85
- <React.Fragment
86
- key={`drawer_group_${group}`}>
87
- {buildGroupHeader(group)}
88
- {Object.values(navigationEntries)
89
- .filter(e => e.group === group)
90
- .map((view, index) =>
91
- <DrawerNavigationItem
92
- key={`navigation_${index}`}
93
- icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
94
- tooltipsOpen={tooltipsOpen}
95
- drawerOpen={drawerOpen}
96
- onClick={() => onClick(view)}
97
- url={view.url}
98
- name={view.name}/>)}
99
- </React.Fragment>
100
- ))}
101
-
102
- </div>
103
-
104
- {adminViews.length > 0 && <Menu
105
- open={adminMenuOpen}
106
- onOpenChange={setAdminMenuOpen}
107
- trigger={
108
- <IconButton
109
- shape={"square"}
110
- className={"m-4 text-gray-900 dark:text-white w-fit"}>
111
- <Tooltip title={"Admin"}
112
- open={tooltipsOpen}
113
- side={"right"} sideOffset={28}>
114
- <MoreVertIcon/>
115
- </Tooltip>
116
- {drawerOpen && <div
117
- className={cls(
118
- drawerOpen ? "opacity-100" : "opacity-0 hidden",
119
- "mx-4 font-inherit text-inherit"
120
- )}>
121
- ADMIN
122
- </div>}
123
- </IconButton>}
124
- >
125
- {adminViews.map((entry, index) =>
126
- <MenuItem
127
- onClick={(event) => {
128
- event.preventDefault();
129
- navigate(entry.path);
130
- }}
131
- key={`navigation_${index}`}>
132
- {<IconForView collectionOrView={entry.view}/>}
133
- {entry.name}
134
- </MenuItem>)}
135
-
136
- </Menu>}
137
- </>
138
- );
139
- }