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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/dist/components/ArrayContainer.d.ts +22 -6
  2. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  3. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  4. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  5. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  6. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  7. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +4 -0
  8. package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
  9. package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
  10. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  11. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  12. package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
  13. package/dist/components/common/default_entity_actions.d.ts +0 -2
  14. package/dist/components/common/index.d.ts +1 -1
  15. package/dist/components/common/useColumnsIds.d.ts +1 -0
  16. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  17. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  18. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  19. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  20. package/dist/core/EntityEditView.d.ts +30 -22
  21. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  22. package/dist/core/FireCMS.d.ts +1 -1
  23. package/dist/core/FireCMSRouter.d.ts +4 -0
  24. package/dist/core/NavigationRoutes.d.ts +0 -1
  25. package/dist/core/SideDialogs.d.ts +4 -2
  26. package/dist/core/index.d.ts +2 -1
  27. package/dist/form/EntityForm.d.ts +45 -0
  28. package/dist/form/EntityFormActions.d.ts +17 -0
  29. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  30. package/dist/form/components/FormEntry.d.ts +6 -0
  31. package/dist/form/components/FormLayout.d.ts +5 -0
  32. package/dist/form/components/index.d.ts +2 -1
  33. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  34. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  35. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  36. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  37. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  38. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  39. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  40. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  41. package/dist/form/index.d.ts +16 -16
  42. package/dist/hooks/data/delete.d.ts +4 -4
  43. package/dist/hooks/data/save.d.ts +3 -3
  44. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  45. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  46. package/dist/hooks/useAuthController.d.ts +1 -1
  47. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  48. package/dist/hooks/useBuildNavigationController.d.ts +7 -4
  49. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  50. package/dist/hooks/useModeController.d.ts +1 -2
  51. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  52. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  53. package/dist/index.es.js +17032 -12909
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/index.umd.js +17019 -12898
  56. package/dist/index.umd.js.map +1 -1
  57. package/dist/internal/useBuildSideEntityController.d.ts +2 -2
  58. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  59. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  60. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  61. package/dist/preview/util.d.ts +3 -3
  62. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  63. package/dist/routes/FireCMSRoute.d.ts +1 -0
  64. package/dist/routes/HomePageRoute.d.ts +3 -0
  65. package/dist/types/auth.d.ts +7 -9
  66. package/dist/types/collections.d.ts +44 -23
  67. package/dist/types/datasource.d.ts +2 -6
  68. package/dist/types/dialogs_controller.d.ts +7 -3
  69. package/dist/types/entities.d.ts +1 -1
  70. package/dist/types/entity_actions.d.ts +14 -4
  71. package/dist/types/entity_callbacks.d.ts +16 -16
  72. package/dist/types/export_import.d.ts +4 -4
  73. package/dist/types/fields.d.ts +27 -4
  74. package/dist/types/firecms.d.ts +2 -2
  75. package/dist/types/firecms_context.d.ts +1 -1
  76. package/dist/types/navigation.d.ts +29 -12
  77. package/dist/types/permissions.d.ts +4 -4
  78. package/dist/types/plugins.d.ts +9 -8
  79. package/dist/types/properties.d.ts +18 -3
  80. package/dist/types/property_config.d.ts +0 -2
  81. package/dist/types/side_entity_controller.d.ts +6 -1
  82. package/dist/types/user.d.ts +1 -0
  83. package/dist/util/builders.d.ts +3 -3
  84. package/dist/util/entities.d.ts +1 -1
  85. package/dist/util/entity_actions.d.ts +2 -0
  86. package/dist/util/entity_cache.d.ts +23 -0
  87. package/dist/util/icon_synonyms.d.ts +0 -1
  88. package/dist/util/icons.d.ts +3 -1
  89. package/dist/util/index.d.ts +1 -0
  90. package/dist/util/navigation_from_path.d.ts +6 -1
  91. package/dist/util/navigation_utils.d.ts +12 -1
  92. package/dist/util/objects.d.ts +1 -0
  93. package/dist/util/permissions.d.ts +4 -4
  94. package/dist/util/property_utils.d.ts +2 -2
  95. package/dist/util/resolutions.d.ts +12 -7
  96. package/package.json +129 -125
  97. package/src/app/Scaffold.tsx +4 -4
  98. package/src/components/ArrayContainer.tsx +115 -34
  99. package/src/components/CircularProgressCenter.tsx +1 -1
  100. package/src/components/ConfirmationDialog.tsx +2 -2
  101. package/src/components/DeleteEntityDialog.tsx +10 -19
  102. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +44 -20
  103. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  104. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  105. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +6 -4
  106. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +8 -9
  107. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -11
  108. package/src/components/EntityCollectionTable/index.tsx +1 -1
  109. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
  110. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -5
  111. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +2 -2
  112. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +77 -73
  113. package/src/components/EntityCollectionView/EntityCollectionView.tsx +90 -49
  114. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
  115. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  116. package/src/components/EntityPreview.tsx +39 -30
  117. package/src/components/EntityView.tsx +5 -5
  118. package/src/components/ErrorView.tsx +3 -3
  119. package/src/components/HomePage/DefaultHomePage.tsx +1 -0
  120. package/src/components/HomePage/FavouritesView.tsx +6 -11
  121. package/src/components/HomePage/NavigationCard.tsx +1 -1
  122. package/src/components/HomePage/NavigationCardBinding.tsx +4 -9
  123. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  124. package/src/components/NotFoundPage.tsx +2 -2
  125. package/src/components/PropertyConfigBadge.tsx +1 -1
  126. package/src/components/PropertyIdCopyTooltip.tsx +3 -4
  127. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +13 -8
  128. package/src/components/SelectableTable/SelectableTable.tsx +20 -5
  129. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  130. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  131. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +7 -5
  132. package/src/components/UnsavedChangesDialog.tsx +42 -0
  133. package/src/components/VirtualTable/VirtualTable.tsx +19 -2
  134. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  135. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  136. package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
  137. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  138. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  139. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
  140. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +2 -0
  141. package/src/components/common/default_entity_actions.tsx +26 -37
  142. package/src/components/common/index.ts +1 -1
  143. package/src/components/common/useColumnsIds.tsx +1 -1
  144. package/src/components/common/useDataSourceTableController.tsx +420 -0
  145. package/src/components/common/useDebouncedCallback.tsx +20 -0
  146. package/src/components/common/useScrollRestoration.tsx +68 -0
  147. package/src/contexts/BreacrumbsContext.tsx +38 -0
  148. package/src/contexts/DialogsProvider.tsx +3 -2
  149. package/src/contexts/ModeController.tsx +1 -3
  150. package/src/contexts/SnackbarProvider.tsx +2 -0
  151. package/src/core/DefaultAppBar.tsx +56 -25
  152. package/src/core/DefaultDrawer.tsx +11 -9
  153. package/src/core/DrawerNavigationItem.tsx +4 -4
  154. package/src/core/EntityEditView.tsx +282 -1006
  155. package/src/core/EntityEditViewFormActions.tsx +199 -0
  156. package/src/core/EntitySidePanel.tsx +85 -15
  157. package/src/core/FireCMS.tsx +12 -9
  158. package/src/core/FireCMSRouter.tsx +17 -0
  159. package/src/core/NavigationRoutes.tsx +23 -32
  160. package/src/core/SideDialogs.tsx +21 -12
  161. package/src/core/field_configs.tsx +4 -4
  162. package/src/core/index.tsx +4 -2
  163. package/src/form/EntityForm.tsx +774 -0
  164. package/src/form/EntityFormActions.tsx +169 -0
  165. package/src/form/PropertyFieldBinding.tsx +39 -30
  166. package/src/form/components/CustomIdField.tsx +2 -0
  167. package/src/form/components/FormEntry.tsx +22 -0
  168. package/src/form/components/FormLayout.tsx +16 -0
  169. package/src/form/components/LabelWithIcon.tsx +6 -3
  170. package/src/form/components/StorageItemPreview.tsx +3 -3
  171. package/src/form/components/StorageUploadProgress.tsx +1 -1
  172. package/src/form/components/index.tsx +2 -1
  173. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +7 -6
  174. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +20 -12
  175. package/src/form/field_bindings/BlockFieldBinding.tsx +45 -25
  176. package/src/form/field_bindings/DateTimeFieldBinding.tsx +2 -1
  177. package/src/form/field_bindings/KeyValueFieldBinding.tsx +10 -7
  178. package/src/form/field_bindings/MapFieldBinding.tsx +69 -52
  179. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +9 -6
  180. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
  181. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  182. package/src/form/field_bindings/ReferenceFieldBinding.tsx +5 -5
  183. package/src/form/field_bindings/RepeatFieldBinding.tsx +30 -22
  184. package/src/form/field_bindings/SelectFieldBinding.tsx +6 -5
  185. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +7 -5
  186. package/src/form/field_bindings/SwitchFieldBinding.tsx +26 -25
  187. package/src/form/field_bindings/TextFieldBinding.tsx +4 -3
  188. package/src/form/index.tsx +16 -32
  189. package/src/form/validation.ts +12 -6
  190. package/src/hooks/data/delete.ts +4 -4
  191. package/src/hooks/data/save.ts +8 -9
  192. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  193. package/src/hooks/data/useEntityFetch.tsx +10 -6
  194. package/src/hooks/useAuthController.tsx +1 -1
  195. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  196. package/src/hooks/useBuildModeController.tsx +15 -28
  197. package/src/hooks/useBuildNavigationController.tsx +74 -29
  198. package/src/hooks/useFireCMSContext.tsx +5 -5
  199. package/src/hooks/useLargeLayout.tsx +0 -35
  200. package/src/hooks/useModeController.tsx +1 -2
  201. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  202. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  203. package/src/internal/useBuildDataSource.ts +1 -1
  204. package/src/internal/useBuildSideDialogsController.tsx +3 -2
  205. package/src/internal/useBuildSideEntityController.tsx +124 -83
  206. package/src/internal/useUnsavedChangesDialog.tsx +127 -93
  207. package/src/preview/PropertyPreview.tsx +11 -11
  208. package/src/preview/PropertyPreviewProps.tsx +1 -1
  209. package/src/preview/components/BooleanPreview.tsx +1 -1
  210. package/src/preview/components/EmptyValue.tsx +1 -1
  211. package/src/preview/components/EnumValuesChip.tsx +1 -1
  212. package/src/preview/components/ImagePreview.tsx +5 -6
  213. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  214. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
  215. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -2
  216. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -2
  217. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -1
  218. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
  219. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -2
  220. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  221. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  222. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  223. package/src/preview/util.ts +10 -10
  224. package/src/routes/CustomCMSRoute.tsx +21 -0
  225. package/src/routes/FireCMSRoute.tsx +235 -0
  226. package/src/routes/HomePageRoute.tsx +17 -0
  227. package/src/types/auth.tsx +8 -12
  228. package/src/types/collections.ts +52 -26
  229. package/src/types/datasource.ts +2 -6
  230. package/src/types/dialogs_controller.tsx +7 -3
  231. package/src/types/entities.ts +1 -1
  232. package/src/types/entity_actions.tsx +16 -4
  233. package/src/types/entity_callbacks.ts +18 -18
  234. package/src/types/export_import.ts +4 -4
  235. package/src/types/fields.tsx +33 -4
  236. package/src/types/firecms.tsx +2 -2
  237. package/src/types/firecms_context.tsx +1 -1
  238. package/src/types/navigation.ts +36 -16
  239. package/src/types/permissions.ts +5 -5
  240. package/src/types/plugins.tsx +9 -8
  241. package/src/types/properties.ts +21 -3
  242. package/src/types/property_config.tsx +0 -2
  243. package/src/types/side_dialogs_controller.tsx +2 -0
  244. package/src/types/side_entity_controller.tsx +6 -1
  245. package/src/types/user.ts +2 -0
  246. package/src/util/builders.ts +10 -8
  247. package/src/util/entities.ts +3 -1
  248. package/src/util/entity_actions.ts +28 -0
  249. package/src/util/entity_cache.ts +204 -0
  250. package/src/util/icon_list.ts +1 -0
  251. package/src/util/icon_synonyms.ts +0 -1
  252. package/src/util/icons.tsx +12 -8
  253. package/src/util/index.ts +1 -0
  254. package/src/util/join_collections.ts +3 -0
  255. package/src/util/navigation_from_path.ts +13 -6
  256. package/src/util/navigation_utils.ts +53 -1
  257. package/src/util/objects.ts +24 -1
  258. package/src/util/parent_references_from_path.ts +3 -3
  259. package/src/util/permissions.ts +8 -8
  260. package/src/util/property_utils.tsx +10 -3
  261. package/src/util/references.ts +8 -2
  262. package/src/util/resolutions.ts +34 -13
  263. package/src/util/useStorageUploadController.tsx +40 -22
  264. package/dist/form/components/FormikArrayContainer.d.ts +0 -19
  265. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  266. package/src/form/components/FormikArrayContainer.tsx +0 -47
  267. /package/src/util/{common.tsx → common.ts} +0 -0
package/src/util/index.ts CHANGED
@@ -7,6 +7,7 @@ export * from "./objects";
7
7
  export * from "./paths";
8
8
  export * from "./regexp";
9
9
  export * from "./navigation_utils";
10
+ export * from "./entity_actions";
10
11
  export * from "./useDebouncedCallback";
11
12
  export * from "./property_utils";
12
13
  export * from "./resolutions";
@@ -115,6 +115,9 @@ export function mergeCollection(target: EntityCollection,
115
115
  if (modifiedCollection)
116
116
  resultCollection = modifiedCollection;
117
117
  }
118
+
119
+ // @ts-ignore
120
+ resultCollection["merged"] = true;
118
121
  return resultCollection
119
122
  }
120
123
 
@@ -11,22 +11,27 @@ export interface NavigationViewEntityInternal<M extends Record<string, any>> {
11
11
  type: "entity";
12
12
  entityId: string;
13
13
  path: string;
14
+ fullPath: string;
14
15
  parentCollection: EntityCollection<M>;
15
16
  }
16
17
 
17
18
  export interface NavigationViewCollectionInternal<M extends Record<string, any>> {
18
19
  type: "collection";
20
+ id: string;
19
21
  path: string;
22
+ fullPath: string;
20
23
  collection: EntityCollection<M>;
21
24
  }
22
25
 
23
26
  export interface NavigationViewEntityCustomInternal<M extends Record<string, any>> {
24
27
  type: "custom_view";
25
28
  path: string;
29
+ fullPath: string;
30
+ entityId: string;
26
31
  view: EntityCustomView<M>;
27
32
  }
28
33
 
29
- export function getNavigationEntriesFromPathInternal(props: {
34
+ export function getNavigationEntriesFromPath(props: {
30
35
  path: string,
31
36
  collections: EntityCollection[] | undefined,
32
37
  currentFullPath?: string,
@@ -56,7 +61,9 @@ export function getNavigationEntriesFromPathInternal(props: {
56
61
 
57
62
  result.push({
58
63
  type: "collection",
64
+ id: collection.id,
59
65
  path: collectionPath,
66
+ fullPath: collectionPath,
60
67
  collection
61
68
  });
62
69
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
@@ -68,6 +75,7 @@ export function getNavigationEntriesFromPathInternal(props: {
68
75
  type: "entity",
69
76
  entityId,
70
77
  path: collectionPath,
78
+ fullPath: fullPath,
71
79
  parentCollection: collection
72
80
  });
73
81
  if (nextSegments.length > 1) {
@@ -81,16 +89,15 @@ export function getNavigationEntriesFromPathInternal(props: {
81
89
  .filter(Boolean)
82
90
  .find((entry) => entry!.key === newPath);
83
91
  if (customView) {
84
- const path = currentFullPath && currentFullPath.length > 0
85
- ? (currentFullPath + "/" + customView.key)
86
- : customView.key;
87
92
  result.push({
88
93
  type: "custom_view",
89
- path,
94
+ path: collectionPath,
95
+ entityId: entityId,
96
+ fullPath: fullPath + "/" + customView.key,
90
97
  view: customView
91
98
  });
92
99
  } else if (collection.subcollections) {
93
- result.push(...getNavigationEntriesFromPathInternal({
100
+ result.push(...getNavigationEntriesFromPath({
94
101
  path: newPath,
95
102
  collections: collection.subcollections,
96
103
  currentFullPath: fullPath,
@@ -1,4 +1,4 @@
1
- import { EntityCollection } from "../types";
1
+ import { EntityCollection, NavigationController, SideEntityController } from "../types";
2
2
 
3
3
  export function removeInitialAndTrailingSlashes(s: string): string {
4
4
  return removeInitialSlash(removeTrailingSlash(s));
@@ -109,3 +109,55 @@ export function getCollectionPathsCombinations(subpaths: string[]): string[] {
109
109
  return result;
110
110
 
111
111
  }
112
+
113
+ export function navigateToEntity({
114
+ openEntityMode,
115
+ collection,
116
+ entityId,
117
+ copy,
118
+ path,
119
+ selectedTab,
120
+ sideEntityController,
121
+ onClose,
122
+ navigation
123
+ }:
124
+
125
+ {
126
+ openEntityMode: "side_panel" | "full_screen";
127
+ collection?: EntityCollection;
128
+ entityId?: string;
129
+ selectedTab?: string;
130
+ copy?: boolean;
131
+ path: string;
132
+ sideEntityController: SideEntityController;
133
+ onClose?: () => void;
134
+ navigation: NavigationController
135
+ }) {
136
+
137
+ if (openEntityMode === "side_panel") {
138
+
139
+ sideEntityController.open({
140
+ entityId,
141
+ path,
142
+ copy,
143
+ selectedTab,
144
+ collection,
145
+ updateUrl: true,
146
+ onClose
147
+ });
148
+
149
+ } else {
150
+ let to = navigation.buildUrlCollectionPath(entityId ? `${path}/${entityId}` : path);
151
+ if (entityId && selectedTab) {
152
+ to += `/${selectedTab}`;
153
+ }
154
+ if (!entityId) {
155
+ to += "#new";
156
+ }
157
+ if (copy) {
158
+ to += "#copy";
159
+ }
160
+ navigation.navigate(to);
161
+ }
162
+
163
+ }
@@ -18,7 +18,10 @@ export function mergeDeep<T extends Record<any, any>, U extends Record<any, any>
18
18
  if (targetIsObject && isObject(source)) {
19
19
  Object.keys(source).forEach(key => {
20
20
  const sourceElement = source[key];
21
- if (isObject(sourceElement)) {
21
+ if (sourceElement instanceof Date) {
22
+ // Assign a new Date instance with the same time value
23
+ Object.assign(output, { [key]: new Date(sourceElement.getTime()) });
24
+ } else if (isObject(sourceElement)) {
22
25
  if (!(key in target))
23
26
  Object.assign(output, { [key]: sourceElement });
24
27
  else
@@ -125,6 +128,26 @@ export function removeUndefined(value: any, removeEmptyStrings?: boolean): any {
125
128
  return value;
126
129
  }
127
130
 
131
+ export function removeNulls(value: any): any {
132
+ if (typeof value === "function") {
133
+ return value;
134
+ }
135
+ if (Array.isArray(value)) {
136
+ return value.map((v: any) => removeNulls(v));
137
+ }
138
+ if (typeof value === "object") {
139
+ const res: object = {};
140
+ if (value === null)
141
+ return value;
142
+ Object.keys(value).forEach((key) => {
143
+ if (value[key] !== null)
144
+ (res as any)[key] = removeNulls(value[key]);
145
+ });
146
+ return res;
147
+ }
148
+ return value;
149
+ }
150
+
128
151
  export function isEmptyObject(obj: object) {
129
152
  return obj &&
130
153
  Object.getPrototypeOf(obj) === Object.prototype &&
@@ -22,11 +22,11 @@ export function getParentReferencesFromPath(props: {
22
22
 
23
23
  const collection: EntityCollection<any> | undefined = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);
24
24
 
25
+ // If we find a collection, we add the reference and continue
25
26
  if (collection) {
26
- const pathOrAlias = collection.id ?? collection.path;
27
27
  const collectionPath = currentFullPath && currentFullPath.length > 0
28
- ? (currentFullPath + "/" + pathOrAlias)
29
- : pathOrAlias;
28
+ ? (currentFullPath + "/" + collection.path)
29
+ : collection.path;
30
30
 
31
31
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
32
32
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
@@ -8,9 +8,9 @@ const DEFAULT_PERMISSIONS = {
8
8
  delete: true
9
9
  };
10
10
 
11
- export function resolvePermissions<M extends Record<string, any>, UserType extends User>
11
+ export function resolvePermissions<M extends Record<string, any>, USER extends User>
12
12
  (collection: EntityCollection<M>,
13
- authController: AuthController<UserType>,
13
+ authController: AuthController<USER>,
14
14
  path: string,
15
15
  entity: Entity<M> | null): Permissions | undefined {
16
16
 
@@ -34,29 +34,29 @@ export function resolvePermissions<M extends Record<string, any>, UserType exten
34
34
  throw Error("New type of permission added and not mapped");
35
35
  }
36
36
 
37
- export function canEditEntity<M extends Record<string, any>, UserType extends User>
37
+ export function canEditEntity<M extends Record<string, any>, USER extends User>
38
38
  (
39
39
  collection: EntityCollection<M>,
40
- authController: AuthController<UserType>,
40
+ authController: AuthController<USER>,
41
41
  path: string,
42
42
  entity: Entity<M> | null): boolean {
43
43
  return resolvePermissions(collection, authController, path, entity)?.edit ?? DEFAULT_PERMISSIONS.edit;
44
44
  }
45
45
 
46
- export function canCreateEntity<M extends Record<string, any>, UserType extends User>
46
+ export function canCreateEntity<M extends Record<string, any>, USER extends User>
47
47
  (
48
48
  collection: EntityCollection<M>,
49
- authController: AuthController<UserType>,
49
+ authController: AuthController<USER>,
50
50
  path: string,
51
51
  entity: Entity<M> | null): boolean {
52
52
  if (collection.collectionGroup) return false;
53
53
  return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;
54
54
  }
55
55
 
56
- export function canDeleteEntity<M extends Record<string, any>, UserType extends User>
56
+ export function canDeleteEntity<M extends Record<string, any>, USER extends User>
57
57
  (
58
58
  collection: EntityCollection<M>,
59
- authController: AuthController<UserType>,
59
+ authController: AuthController<USER>,
60
60
  path: string,
61
61
  entity: Entity<M> | null): boolean {
62
62
  return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
@@ -1,6 +1,13 @@
1
1
  import React from "react";
2
2
 
3
- import { EntityCollection, PropertiesOrBuilders, PropertyConfig, PropertyOrBuilder, ResolvedProperty } from "../types";
3
+ import {
4
+ EntityCollection,
5
+ PropertiesOrBuilders,
6
+ PropertyConfig,
7
+ PropertyOrBuilder,
8
+ ResolvedProperties,
9
+ ResolvedProperty
10
+ } from "../types";
4
11
  import { isPropertyBuilder } from "./entities";
5
12
  import { resolveProperty } from "./resolutions";
6
13
  import { CircleIcon, FunctionsIcon } from "@firecms/ui";
@@ -11,7 +18,7 @@ export function isReferenceProperty(propertyOrBuilder: PropertyOrBuilder,
11
18
  const resolvedProperty = resolveProperty({
12
19
  propertyKey: "ignore", // TODO
13
20
  propertyOrBuilder,
14
- fields
21
+ propertyConfigs: fields
15
22
  });
16
23
  if (!resolvedProperty) return null;
17
24
  if (resolvedProperty.dataType === "reference") {
@@ -63,7 +70,7 @@ export function getColorForProperty(property: PropertyOrBuilder, fields: Record<
63
70
  * @param properties
64
71
  * @param path
65
72
  */
66
- export function getPropertyInPath<M extends Record<string, any>>(properties: PropertiesOrBuilders<M>, path: string): PropertyOrBuilder<any, M> | undefined {
73
+ export function getPropertyInPath<M extends Record<string, any>>(properties: PropertiesOrBuilders<M> | ResolvedProperties, path: string): PropertyOrBuilder<any, M> | undefined {
67
74
  if (typeof properties === "object") {
68
75
  if (path in properties) {
69
76
  return properties[path];
@@ -42,13 +42,19 @@ export function getEntityTitlePropertyKey<M extends Record<string, any>>(collect
42
42
 
43
43
  export function getEntityImagePreviewPropertyKey<M extends object>(collection: ResolvedEntityCollection<M>): string | undefined {
44
44
 
45
- // find first text field property
45
+ // find first storage property of type image
46
46
  for (const key in collection.properties) {
47
47
  const property = collection.properties[key];
48
48
  if (property.dataType === "string" && property.storage?.acceptedFiles?.includes("image/*")) {
49
49
  return key;
50
50
  }
51
-
51
+ }
52
+ // alternatively, look for the first array of images
53
+ for (const key in collection.properties) {
54
+ const property = collection.properties[key];
55
+ if (property.dataType === "array" && property.of?.dataType === "string" && property.of.storage?.acceptedFiles?.includes("image/*")) {
56
+ return key;
57
+ }
52
58
  }
53
59
  return undefined;
54
60
  }
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  ArrayProperty,
3
3
  CMSType,
4
+ CustomizationController,
4
5
  EntityCollection,
5
6
  EntityCustomView,
6
7
  EntityValues,
@@ -38,7 +39,7 @@ export const resolveCollection = <M extends Record<string, any>, >
38
39
  values,
39
40
  previousValues,
40
41
  userConfigPersistence,
41
- fields,
42
+ propertyConfigs,
42
43
  ignoreMissingFields = false
43
44
  }: {
44
45
  collection: EntityCollection<M> | ResolvedEntityCollection<M>;
@@ -47,7 +48,7 @@ export const resolveCollection = <M extends Record<string, any>, >
47
48
  values?: Partial<EntityValues<M>>,
48
49
  previousValues?: Partial<EntityValues<M>>,
49
50
  userConfigPersistence?: UserConfigurationPersistence;
50
- fields?: Record<string, PropertyConfig>;
51
+ propertyConfigs?: Record<string, PropertyConfig>;
51
52
  ignoreMissingFields?: boolean;
52
53
  }): ResolvedEntityCollection<M> => {
53
54
 
@@ -67,7 +68,7 @@ export const resolveCollection = <M extends Record<string, any>, >
67
68
  previousValues: usedPreviousValues,
68
69
  path,
69
70
  entityId,
70
- fields,
71
+ propertyConfigs: propertyConfigs,
71
72
  ignoreMissingFields
72
73
  });
73
74
  if (!childResolvedProperty) return {};
@@ -111,7 +112,7 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
111
112
  entityId?: string,
112
113
  index?: number,
113
114
  fromBuilder?: boolean;
114
- fields?: Record<string, PropertyConfig<any>>;
115
+ propertyConfigs?: Record<string, PropertyConfig<any>>;
115
116
  ignoreMissingFields?: boolean;
116
117
  }): ResolvedProperty<T> | null {
117
118
 
@@ -182,7 +183,7 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
182
183
  }
183
184
 
184
185
  if (resolvedProperty.propertyConfig && !isDefaultFieldConfigId(resolvedProperty.propertyConfig)) {
185
- const cmsFields = props.fields;
186
+ const cmsFields = props.propertyConfigs;
186
187
  if (!cmsFields && !ignoreMissingFields) {
187
188
  throw Error(`Trying to resolve a property with key '${resolvedProperty.propertyConfig}' that inherits from a custom property config but no custom property configs were provided. Use the property 'propertyConfigs' in your app config to provide them`);
188
189
  }
@@ -218,11 +219,11 @@ export function resolveProperty<T extends CMSType = CMSType, M extends Record<st
218
219
  }
219
220
 
220
221
  export function getArrayResolvedProperties<M>({
221
- propertyKey,
222
- propertyValue,
223
- property,
224
- ...props
225
- }: {
222
+ propertyKey,
223
+ propertyValue,
224
+ property,
225
+ ...props
226
+ }: {
226
227
  propertyValue: any,
227
228
  propertyKey?: string,
228
229
  property: ArrayProperty<any> | ResolvedArrayProperty<any>,
@@ -233,7 +234,7 @@ export function getArrayResolvedProperties<M>({
233
234
  entityId?: string;
234
235
  index?: number;
235
236
  fromBuilder?: boolean;
236
- fields?: Record<string, PropertyConfig>
237
+ propertyConfigs?: Record<string, PropertyConfig>
237
238
  }) {
238
239
 
239
240
  const of = property.of;
@@ -263,7 +264,7 @@ export function resolveArrayProperty<T extends any[], M>({
263
264
  entityId?: string,
264
265
  index?: number,
265
266
  fromBuilder?: boolean;
266
- fields?: Record<string, PropertyConfig>;
267
+ propertyConfigs?: Record<string, PropertyConfig>;
267
268
  ignoreMissingFields?: boolean;
268
269
  }): ResolvedArrayProperty {
269
270
  const propertyValue = propertyKey ? getIn(props.values, propertyKey) : undefined;
@@ -370,7 +371,7 @@ export function resolveProperties<M extends Record<string, any>>({
370
371
  entityId?: string,
371
372
  index?: number,
372
373
  fromBuilder?: boolean;
373
- fields?: Record<string, PropertyConfig>;
374
+ propertyConfigs?: Record<string, PropertyConfig>;
374
375
  ignoreMissingFields?: boolean;
375
376
  }): ResolvedProperties<M> {
376
377
  return Object.entries<PropertyOrBuilder>(properties as Record<string, PropertyOrBuilder>)
@@ -430,3 +431,23 @@ export function resolveEntityView(entityView: string | EntityCustomView<any>, co
430
431
  return entityView;
431
432
  }
432
433
  }
434
+
435
+ export function resolvedSelectedEntityView<M extends Record<string, any>>(
436
+ customViews: (string | EntityCustomView<M>)[] | undefined,
437
+ customizationController: CustomizationController,
438
+ selectedTab?: string
439
+ ) {
440
+ const resolvedEntityViews = customViews ? customViews
441
+ .map(e => resolveEntityView(e, customizationController.entityViews))
442
+ .filter(Boolean) as EntityCustomView[]
443
+ : [];
444
+
445
+ const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
446
+ const selectedSecondaryForm = customViews
447
+ && resolvedEntityViews.filter(e => e.includeActions).find(e => e.key === selectedTab);
448
+ return {
449
+ resolvedEntityViews,
450
+ selectedEntityView,
451
+ selectedSecondaryForm
452
+ };
453
+ }
@@ -34,6 +34,7 @@ export interface StorageFieldItem {
34
34
  size: PreviewSize
35
35
  }
36
36
 
37
+
37
38
  export function useStorageUploadController<M extends object>({
38
39
  entityId,
39
40
  entityValues,
@@ -45,17 +46,17 @@ export function useStorageUploadController<M extends object>({
45
46
  disabled,
46
47
  onChange
47
48
  }:
48
- {
49
- entityId: string,
50
- entityValues: EntityValues<M>,
51
- value: string | string[] | null;
52
- path?: string,
53
- propertyKey: string,
54
- property: StringProperty | ArrayProperty<string[]> | ResolvedStringProperty | ResolvedArrayProperty<string[]>,
55
- storageSource: StorageSource,
56
- disabled: boolean,
57
- onChange: (value: string | string[] | null) => void
58
- }) {
49
+ {
50
+ entityId: string,
51
+ entityValues: EntityValues<M>,
52
+ value: string | string[] | null;
53
+ path?: string,
54
+ propertyKey: string,
55
+ property: StringProperty | ArrayProperty<string[]> | ResolvedStringProperty | ResolvedArrayProperty<string[]>,
56
+ storageSource: StorageSource,
57
+ disabled: boolean,
58
+ onChange: (value: string | string[] | null) => void
59
+ }) {
59
60
 
60
61
  const storage: StorageConfig | undefined = property.dataType === "string"
61
62
  ? property.storage
@@ -70,21 +71,12 @@ export function useStorageUploadController<M extends object>({
70
71
  throw Error("Storage meta must be specified");
71
72
 
72
73
  const metadata: Record<string, any> | undefined = storage?.metadata;
73
- const size = multipleFilesSupported ? "small" : "medium";
74
+ const size = multipleFilesSupported ? "medium" : "large";
74
75
 
75
76
  const compression: ImageCompression | undefined = storage?.imageCompression;
76
77
 
77
78
  const internalInitialValue: StorageFieldItem[] =
78
- (multipleFilesSupported
79
- ? (value ?? []) as string[]
80
- : value ? [value as string] : []).map(entry => (
81
- {
82
- id: getRandomId(),
83
- storagePathOrDownloadUrl: entry,
84
- metadata,
85
- size
86
- }
87
- ));
79
+ getInternalInitialValue(multipleFilesSupported, value, metadata, size);
88
80
 
89
81
  const [initialValue, setInitialValue] = useState<string | string[] | null>(value);
90
82
  const [internalValue, setInternalValue] = useState<StorageFieldItem[]>(internalInitialValue);
@@ -226,6 +218,32 @@ export function useStorageUploadController<M extends object>({
226
218
  }
227
219
  }
228
220
 
221
+ function getInternalInitialValue(multipleFilesSupported: boolean,
222
+ value: string | string[] | null,
223
+ metadata: Record<string, any> | undefined,
224
+ size: PreviewSize): StorageFieldItem[] {
225
+ let strings: string[] = [];
226
+ if (multipleFilesSupported) {
227
+ if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
228
+ strings = (value ?? []) as string[];
229
+ }
230
+ } else {
231
+ if (typeof value === "string") {
232
+ strings = value ? [value as string] : [];
233
+ }
234
+ }
235
+
236
+ return strings
237
+ .map(entry => (
238
+ {
239
+ id: getRandomId(),
240
+ storagePathOrDownloadUrl: entry,
241
+ metadata,
242
+ size
243
+ }
244
+ ));
245
+ }
246
+
229
247
  function removeDuplicates(items: StorageFieldItem[]) {
230
248
  return items.filter(
231
249
  (item, i) => {
@@ -1,19 +0,0 @@
1
- import React from "react";
2
- interface ArrayContainerProps<T> {
3
- value: T[];
4
- name: string;
5
- addLabel: string;
6
- buildEntry: (index: number, internalId: number) => React.ReactNode;
7
- disabled?: boolean;
8
- small?: boolean;
9
- onInternalIdAdded?: (id: number) => void;
10
- includeAddButton?: boolean;
11
- newDefaultEntry?: T | null;
12
- setFieldValue: (field: string, value: any, shouldValidate?: boolean | undefined) => void;
13
- className?: string;
14
- }
15
- /**
16
- * @group Form custom fields
17
- */
18
- export declare function FormikArrayContainer<T>({ name, addLabel, value, disabled, buildEntry, small, onInternalIdAdded, includeAddButton, newDefaultEntry, setFieldValue, className }: ArrayContainerProps<T>): import("react/jsx-runtime").JSX.Element;
19
- export {};