@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
@@ -5,6 +5,7 @@ import { EntityReference } from "./entities";
5
5
  /**
6
6
  * Controller that includes the resolved navigation and utility methods and
7
7
  * attributes.
8
+ * This controller holds the state of the navigation including the collections.
8
9
  * @group Models
9
10
  */
10
11
  export type NavigationController<EC extends EntityCollection = EntityCollection<any>> = {
@@ -56,8 +57,8 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
56
57
  * Get the collection configuration for a given path.
57
58
  * The collection is resolved from the given path or alias.
58
59
  */
59
- getCollection: (pathOrId: string,
60
- includeUserOverride?: boolean) => EC | undefined;
60
+ getCollection: (pathOrId: string, includeUserOverride?: boolean) => EC | undefined;
61
+
61
62
  /**
62
63
  * Get the collection configuration from its parent ids.
63
64
  */
@@ -69,12 +70,14 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
69
70
  getCollectionFromPaths: (pathSegments: string[]) => EC | undefined;
70
71
 
71
72
  /**
72
- * Default path under the navigation routes of the CMS will be created
73
+ * Default path under the navigation routes of the CMS will be created.
74
+ * Defaults to '/'. You may want to change this `basepath` to 'admin' for example.
73
75
  */
74
76
  basePath: string;
75
77
 
76
78
  /**
77
- * Default path under the collection routes of the CMS will be created
79
+ * Default path under the collection routes of the CMS will be created.
80
+ * It defaults to '/c'
78
81
  */
79
82
  baseCollectionPath: string;
80
83
 
@@ -87,16 +90,6 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
87
90
  */
88
91
  urlPathToDataPath: (cmsPath: string) => string;
89
92
 
90
- /**
91
- * Convert a collection or entity path to a URL path
92
- * @param path
93
- */
94
- buildCMSUrlPath: (path: string) => string;
95
-
96
- buildUrlEditCollectionPath: (props: {
97
- path: string
98
- }) => string;
99
-
100
93
  /**
101
94
  * Base url path for the home screen
102
95
  */
@@ -117,10 +110,11 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
117
110
  buildUrlCollectionPath: (path: string) => string;
118
111
 
119
112
  /**
120
- * Turn a path with aliases into a resolved path
113
+ * Turn a path with collection ids into a resolved path.
114
+ * The ids (typically used in urls) will be replaced with relative paths (typically used in database paths)
121
115
  * @param pathWithAliases
122
116
  */
123
- resolveAliasesFrom: (pathWithAliases: string) => string;
117
+ resolveIdsFrom: (pathWithAliases: string) => string;
124
118
 
125
119
  /**
126
120
  * Call this method to recalculate the navigation
@@ -144,8 +138,34 @@ export type NavigationController<EC extends EntityCollection = EntityCollection<
144
138
  * @param ids
145
139
  */
146
140
  convertIdsToPaths: (ids: string[]) => string[];
141
+
142
+ /**
143
+ * A function to navigate to a specified route or URL.
144
+ *
145
+ * @param {string} to - The target route or URL to navigate to.
146
+ * @param {NavigateOptions} [options] - Optional configuration settings for navigation, such as replace behavior or state data.
147
+ */
148
+ navigate: (to: string, options?: NavigateOptions) => void;
149
+
147
150
  }
148
151
 
152
+ export interface NavigateOptions {
153
+ replace?: boolean;
154
+ state?: any;
155
+ preventScrollReset?: boolean;
156
+ relative?: "route" | "path";
157
+ flushSync?: boolean;
158
+ viewTransition?: boolean;
159
+ }
160
+
161
+ // currently not used, in favor of a single blocker in `FireCMSRoute`
162
+ export type NavigationBlocker = {
163
+ updateBlockListener: (path: string, block: boolean, basePath?: string) => () => void;
164
+ isBlocked: (path: string) => boolean;
165
+ proceed?: () => void;
166
+ reset?: () => void;
167
+ };
168
+
149
169
  /**
150
170
  * Custom additional views created by the developer, added to the main
151
171
  * navigation.
@@ -32,7 +32,7 @@ export interface Permissions {
32
32
  * Props passed to a {@link PermissionsBuilder}
33
33
  * @group Models
34
34
  */
35
- export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCollection, UserType extends User = User, M extends object = InferCollectionType<EC>> {
35
+ export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCollection, USER extends User = User, M extends object = InferCollectionType<EC>> {
36
36
  /**
37
37
  * Entity being edited, might be null in some cases, when the operation
38
38
  * refers to the collection.
@@ -54,7 +54,7 @@ export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCol
54
54
  /**
55
55
  * Logged in user
56
56
  */
57
- user: UserType | null;
57
+ user: USER | null;
58
58
 
59
59
  /**
60
60
  * Collection these permissions apply to
@@ -64,7 +64,7 @@ export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCol
64
64
  /**
65
65
  * Auth controller
66
66
  */
67
- authController: AuthController<UserType>;
67
+ authController: AuthController<USER>;
68
68
  }
69
69
 
70
70
  /**
@@ -72,10 +72,10 @@ export interface PermissionsBuilderProps<EC extends EntityCollection = EntityCol
72
72
  * based on the logged user or collection.
73
73
  * @group Models
74
74
  */
75
- export type PermissionsBuilder<EC extends EntityCollection = EntityCollection, UserType extends User = User, M extends object = InferCollectionType<EC>> =
75
+ export type PermissionsBuilder<EC extends EntityCollection = EntityCollection, USER extends User = User, M extends object = InferCollectionType<EC>> =
76
76
  (({
77
77
  pathSegments,
78
78
  user,
79
79
  collection,
80
80
  authController
81
- }: PermissionsBuilderProps<EC, UserType, M>) => Permissions | undefined);
81
+ }: PermissionsBuilderProps<EC, USER, M>) => Permissions | undefined);
@@ -166,7 +166,7 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
166
166
  *
167
167
  * @group Models
168
168
  */
169
- export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, any> = any, UserType extends User = User, EC extends EntityCollection<M> = EntityCollection<M>> {
169
+ export interface PluginHomePageActionsProps<EP extends object = object, M extends Record<string, any> = any, USER extends User = User, EC extends EntityCollection<M> = EntityCollection<M>> {
170
170
  /**
171
171
  * Collection path of this entity. This is the full path, like
172
172
  * `users/1234/addresses`
@@ -181,20 +181,21 @@ export interface PluginHomePageActionsProps<EP extends object = object, M extend
181
181
  /**
182
182
  * Context of the app status
183
183
  */
184
- context: FireCMSContext<UserType>;
184
+ context: FireCMSContext<USER>;
185
185
 
186
186
  extraProps?: EP;
187
187
 
188
188
  }
189
189
 
190
- export interface PluginFormActionProps<UserType extends User = User, EC extends EntityCollection = EntityCollection> {
190
+ export interface PluginFormActionProps<USER extends User = User, EC extends EntityCollection = EntityCollection> {
191
191
  entityId?: string;
192
192
  path: string;
193
193
  status: EntityStatus;
194
194
  collection: EC;
195
195
  formContext?: FormContext<any>;
196
- context: FireCMSContext<UserType>;
196
+ context: FireCMSContext<USER>;
197
197
  currentEntityId?: string;
198
+ openEntityMode: "side_panel" | "full_screen";
198
199
  }
199
200
 
200
201
  export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Record<string, any> = any, EC extends EntityCollection<M> = EntityCollection<M>> = {
@@ -207,11 +208,11 @@ export type PluginFieldBuilderParams<T extends CMSType = CMSType, M extends Reco
207
208
  collection?: EC;
208
209
  };
209
210
 
210
- export interface PluginGenericProps<UserType extends User = User> {
211
- context: FireCMSContext<UserType>;
211
+ export interface PluginGenericProps<USER extends User = User> {
212
+ context: FireCMSContext<USER>;
212
213
  }
213
214
 
214
- export interface PluginHomePageAdditionalCardsProps<UserType extends User = User> {
215
+ export interface PluginHomePageAdditionalCardsProps<USER extends User = User> {
215
216
  group?: string;
216
- context: FireCMSContext<UserType>;
217
+ context: FireCMSContext<USER>;
217
218
  }
@@ -156,6 +156,12 @@ export interface BaseProperty<T extends CMSType, CustomProps = any> {
156
156
  * save the new config. The saved config will then become the source of truth.
157
157
  */
158
158
  editable?: boolean;
159
+
160
+ /**
161
+ * A number between 0 and 100 that indicates the width of the field in the form view.
162
+ * It defaults to 100, but you can set it to 50 to have two fields in the same row.
163
+ */
164
+ widthPercentage?: number;
159
165
  }
160
166
 
161
167
  /**
@@ -285,14 +291,14 @@ export type PropertyBuilder<T extends CMSType = any, M extends Record<string, an
285
291
  /**
286
292
  * @group Entity properties
287
293
  */
288
- export type PropertyOrBuilder<T extends CMSType = CMSType, M extends Record<string, any> = Record<string, any>> =
294
+ export type PropertyOrBuilder<T extends CMSType = CMSType, M extends Record<string, any> = any> =
289
295
  Property<T>
290
296
  | PropertyBuilder<T, M>;
291
297
 
292
298
  /**
293
299
  * @group Entity properties
294
300
  */
295
- export type PropertiesOrBuilders<M extends Record<string, any> = Record<string, any>> =
301
+ export type PropertiesOrBuilders<M extends Record<string, any> = any> =
296
302
  {
297
303
  [k in keyof M]: PropertyOrBuilder<M[k], M>;
298
304
  };
@@ -371,7 +377,7 @@ export interface StringProperty extends BaseProperty<string> {
371
377
 
372
378
  /**
373
379
  * You can specify a `Storage` configuration. It is used to
374
- * indicate that this string refers to a path in Google Cloud Storage.
380
+ * indicate that this string refers to a path in your storage provider.
375
381
  */
376
382
  storage?: StorageConfig;
377
383
 
@@ -469,6 +475,12 @@ export interface ArrayProperty<T extends ArrayT[] = any[], ArrayT extends CMSTyp
469
475
  */
470
476
  expanded?: boolean;
471
477
 
478
+ /**
479
+ * Display the child properties directly, without being wrapped in an
480
+ * extendable panel.
481
+ */
482
+ minimalistView?: boolean;
483
+
472
484
  }
473
485
 
474
486
  /**
@@ -517,6 +529,12 @@ export interface MapProperty<T extends Record<string, CMSType> = Record<string,
517
529
  */
518
530
  spreadChildren?: boolean;
519
531
 
532
+ /**
533
+ * Display the child properties directly, without being wrapped in an
534
+ * extendable panel. Note that this will also hide the title of this property.
535
+ */
536
+ minimalistView?: boolean;
537
+
520
538
  /**
521
539
  * Should the field be initially expanded. Defaults to `true`
522
540
  */
@@ -23,8 +23,6 @@ export type PropertyConfig<T extends CMSType = any> = {
23
23
  * Default config for the property.
24
24
  * This property or builder will be used as the base values for the resulting property.
25
25
  * You can also use a builder function to generate the base property.
26
- * You can use a builder function to generate the property based on the values or the path.
27
- * You can also define a custom Field as a React component to be used for this property.
28
26
  */
29
27
  property: PropertyOrBuilder<T>;
30
28
 
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { EntityFormProps } from "../form";
2
3
 
3
4
  /**
4
5
  * Controller to open the side dialog
@@ -78,4 +79,5 @@ export interface SideDialogPanelProps {
78
79
  * Use this prop to store additional data in the panel
79
80
  */
80
81
  additional?: any;
82
+
81
83
  }
@@ -2,6 +2,7 @@ import { EntityCollection } from "./collections";
2
2
  import { ResolvedEntityCollection } from "./resolved_entities";
3
3
  import { Entity } from "./entities";
4
4
  import { EntityOverrides } from "./entity_overrides";
5
+ import { EntityFormProps } from "../form";
5
6
 
6
7
  /**
7
8
  * Props used to open a side dialog
@@ -28,7 +29,7 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
28
29
  * Open the entity with a selected sub-collection view. If the panel for this
29
30
  * entity was already open, it is replaced.
30
31
  */
31
- selectedSubPath?: string;
32
+ selectedTab?: string;
32
33
 
33
34
  /**
34
35
  * Use this prop to override the width of the form view.
@@ -66,6 +67,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
66
67
  */
67
68
  closeOnSave?: boolean;
68
69
 
70
+ /**
71
+ * Override some form properties
72
+ */
73
+ formProps?: Partial<EntityFormProps<M>>;
69
74
  }
70
75
 
71
76
  /**
package/src/types/user.ts CHANGED
@@ -41,4 +41,6 @@ export type User = {
41
41
  */
42
42
  roles?: Role[];
43
43
 
44
+ getIdToken?: (forceRefresh?: boolean) => Promise<string>;
45
+
44
46
  };
@@ -26,10 +26,12 @@ import {
26
26
  * @param collection
27
27
  * @group Builder
28
28
  */
29
- export function buildCollection<M extends Record<string, any> = any,
30
- UserType extends User = User>(
31
- collection: EntityCollection<M, UserType>
32
- ): EntityCollection<M, UserType> {
29
+ export function buildCollection<
30
+ M extends Record<string, any> = any,
31
+ USER extends User = User>
32
+ (
33
+ collection: EntityCollection<M, USER>
34
+ ): EntityCollection<M, USER> {
33
35
  return collection;
34
36
  }
35
37
 
@@ -39,7 +41,7 @@ export function buildCollection<M extends Record<string, any> = any,
39
41
  * @param property
40
42
  * @group Builder
41
43
  */
42
- export function buildProperty<T extends CMSType = CMSType, P extends PropertyOrBuilder<T> = PropertyOrBuilder<T>, M extends Record<string, any> = Record<string, any>>(
44
+ export function buildProperty<T extends CMSType = CMSType, P extends PropertyOrBuilder<T> = PropertyOrBuilder<T>, M extends Record<string, any> = any>(
43
45
  property: P
44
46
  ):
45
47
  P extends StringProperty ? StringProperty :
@@ -120,9 +122,9 @@ export function buildEntityCallbacks<M extends Record<string, any> = any>(
120
122
  * @param additionalFieldDelegate
121
123
  * @group Builder
122
124
  */
123
- export function buildAdditionalFieldDelegate<M extends Record<string, any>, UserType extends User = User>(
124
- additionalFieldDelegate: AdditionalFieldDelegate<M, UserType>
125
- ): AdditionalFieldDelegate<M, UserType> {
125
+ export function buildAdditionalFieldDelegate<M extends Record<string, any>, USER extends User = User>(
126
+ additionalFieldDelegate: AdditionalFieldDelegate<M, USER>
127
+ ): AdditionalFieldDelegate<M, USER> {
126
128
  return additionalFieldDelegate;
127
129
  }
128
130
 
@@ -40,13 +40,15 @@ export function getDefaultValuesFor<M extends Record<string, any>>(properties: P
40
40
  if (!properties) return {};
41
41
  return Object.entries(properties)
42
42
  .map(([key, property]) => {
43
+ if (!property) return {};
43
44
  const value = getDefaultValueFor(property as PropertyOrBuilder);
44
45
  return value === undefined ? {} : { [key]: value };
45
46
  })
46
47
  .reduce((a, b) => ({ ...a, ...b }), {}) as EntityValues<M>;
47
48
  }
48
49
 
49
- export function getDefaultValueFor(property: PropertyOrBuilder) {
50
+ export function getDefaultValueFor(property?: PropertyOrBuilder) {
51
+ if (!property) return undefined;
50
52
  if (isPropertyBuilder(property)) return undefined;
51
53
  if (property.defaultValue || property.defaultValue === null) {
52
54
  return property.defaultValue;
@@ -0,0 +1,28 @@
1
+ import { EntityAction } from "../types";
2
+
3
+ const reservedKeys = ["edit", "copy", "delete"];
4
+
5
+ export function mergeEntityActions(currentActions: EntityAction[], newActions: EntityAction[]): EntityAction[] {
6
+ // given the current actions, replace the ones with the same key
7
+ // and append the new ones
8
+ const updatedActions: EntityAction[] = [];
9
+ currentActions.forEach(action => {
10
+ const newAction = newActions.find(a => a.key === action.key);
11
+ if (newAction) {
12
+ const mergedAction = {
13
+ ...action,
14
+ ...newAction
15
+ }
16
+ updatedActions.push(mergedAction);
17
+ } else {
18
+ updatedActions.push(action);
19
+ }
20
+ });
21
+ newActions.forEach(action => {
22
+ if (!currentActions.find(a => a.key === action.key) && (!action.key || !reservedKeys.includes(action.key))) {
23
+ updatedActions.push(action);
24
+ }
25
+ });
26
+ return updatedActions;
27
+
28
+ }
@@ -0,0 +1,204 @@
1
+ import { EntityReference, GeoPoint, Vector } from "../types";
2
+
3
+ // Define a unique prefix for entity keys in localStorage to avoid key collisions
4
+ const LOCAL_STORAGE_PREFIX = "entity_cache::";
5
+
6
+ // In-memory cache to store entities for quick access
7
+ const entityCache: Map<string, object> = new Map();
8
+
9
+ // Check `localStorage` availability once during initialization
10
+ const isLocalStorageAvailable = typeof localStorage !== "undefined";
11
+
12
+ // Define custom replacer for JSON.stringify
13
+ function customReplacer(key: string): any {
14
+
15
+ // @ts-ignore
16
+ const value = this[key];
17
+
18
+ // Handle Date objects
19
+ // @ts-ignore
20
+ if (value instanceof Date) {
21
+ return { __type: "Date", value: value.toISOString() };
22
+ }
23
+
24
+ // Handle EntityReference
25
+ // @ts-ignore
26
+ if (value instanceof EntityReference) {
27
+ return { __type: "EntityReference", id: value.id, path: value.path };
28
+ }
29
+
30
+ // Handle GeoPoint
31
+ // @ts-ignore
32
+ if (value instanceof GeoPoint) {
33
+ return { __type: "GeoPoint", latitude: value.latitude, longitude: value.longitude };
34
+ }
35
+
36
+ // Handle Vector
37
+ // @ts-ignore
38
+ if (value instanceof Vector) {
39
+ return { __type: "Vector", value: value.value };
40
+ }
41
+
42
+ return value;
43
+ }
44
+
45
+ // Define custom reviver for JSON.parse
46
+ function customReviver(key: string, value: any): any {
47
+ if (value && typeof value === "object" && "__type" in value) {
48
+ switch (value.__type) {
49
+ case "Date":
50
+ return new Date(value.value);
51
+ case "EntityReference":
52
+ return new EntityReference(value.id, value.path);
53
+ case "GeoPoint":
54
+ return new GeoPoint(value.latitude, value.longitude);
55
+ case "Vector":
56
+ return new Vector(value.value);
57
+ default:
58
+ return value;
59
+ }
60
+ }
61
+ return value;
62
+ }
63
+
64
+ // Initialize the in-memory cache by loading entities from `localStorage`
65
+ if (isLocalStorageAvailable) {
66
+ try {
67
+ // Iterate over all keys in localStorage to find those with the specified prefix
68
+ for (let i = 0; i < localStorage.length; i++) {
69
+ const fullKey = localStorage.key(i);
70
+ if (fullKey && fullKey.startsWith(LOCAL_STORAGE_PREFIX)) {
71
+ const path = fullKey.substring(LOCAL_STORAGE_PREFIX.length);
72
+ const entityString = localStorage.getItem(fullKey);
73
+ if (entityString) {
74
+ try {
75
+ const entity: object = JSON.parse(entityString, customReviver);
76
+ entityCache.set(path, entity);
77
+ } catch (parseError) {
78
+ console.error(
79
+ `Failed to parse entity for path "${path}" from localStorage:`,
80
+ parseError
81
+ );
82
+ }
83
+ }
84
+ }
85
+ }
86
+ } catch (error) {
87
+ console.error("Error accessing localStorage during initialization:", error);
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Saves data to the in-memory cache and persists it individually in `localStorage`.
93
+ * @param path - The unique path/key for the data.
94
+ * @param data - The data to cache and persist.
95
+ */
96
+ export function saveEntityToCache(path: string, data: object): void {
97
+ // Update the in-memory cache
98
+ entityCache.set(path, data);
99
+
100
+ // Persist the data individually in localStorage
101
+ if (isLocalStorageAvailable) {
102
+ try {
103
+ const key = LOCAL_STORAGE_PREFIX + path;
104
+ const entityString = JSON.stringify(data, customReplacer);
105
+ localStorage.setItem(key, entityString);
106
+ } catch (error) {
107
+ console.error(
108
+ `Failed to save entity for path "${path}" to localStorage:`,
109
+ error
110
+ );
111
+ }
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Retrieves an entity from the in-memory cache or `localStorage`.
117
+ * If the entity is not in the cache but exists in `localStorage`, it loads it into the cache.
118
+ * @param path - The unique path/key for the entity.
119
+ * @returns The cached entity or `undefined` if not found.
120
+ */
121
+ export function getEntityFromCache(path: string): object | undefined {
122
+
123
+ // Attempt to retrieve the entity from the in-memory cache
124
+ if (entityCache.has(path)) {
125
+ return entityCache.get(path);
126
+ }
127
+
128
+ // If not in the cache, attempt to load it from localStorage
129
+ if (isLocalStorageAvailable) {
130
+ try {
131
+ const key = LOCAL_STORAGE_PREFIX + path;
132
+ const entityString = localStorage.getItem(key);
133
+ if (entityString) {
134
+ const entity: object = JSON.parse(entityString, customReviver);
135
+ entityCache.set(path, entity); // Update the cache
136
+ return entity;
137
+ }
138
+ } catch (error) {
139
+ console.error(
140
+ `Failed to load entity for path "${path}" from localStorage:`,
141
+ error
142
+ );
143
+ }
144
+ }
145
+
146
+ // Entity not found
147
+ return undefined;
148
+ }
149
+
150
+ export function hasEntityInCache(path: string): boolean {
151
+ return entityCache.has(path);
152
+ }
153
+
154
+ /**
155
+ * Removes an entity from both the in-memory cache and `localStorage`.
156
+ * @param path - The unique path/key for the entity to remove.
157
+ */
158
+ export function removeEntityFromCache(path: string): void {
159
+
160
+
161
+ console.debug("Removing entity from cache", path);
162
+
163
+ // Remove from the in-memory cache
164
+ entityCache.delete(path);
165
+
166
+ // Remove from localStorage
167
+ if (isLocalStorageAvailable) {
168
+ try {
169
+ const key = LOCAL_STORAGE_PREFIX + path;
170
+ localStorage.removeItem(key);
171
+ } catch (error) {
172
+ console.error(
173
+ `Failed to remove entity for path "${path}" from localStorage:`,
174
+ error
175
+ );
176
+ }
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Clears the entire in-memory cache and removes all related entities from `localStorage`.
182
+ */
183
+ export function clearEntityCache(): void {
184
+ // Clear the in-memory cache
185
+ entityCache.clear();
186
+
187
+ // Remove all entities with the specified prefix from localStorage
188
+ if (isLocalStorageAvailable) {
189
+ try {
190
+ const keysToRemove: string[] = [];
191
+ for (let i = 0; i < localStorage.length; i++) {
192
+ const fullKey = localStorage.key(i);
193
+ if (fullKey && fullKey.startsWith(LOCAL_STORAGE_PREFIX)) {
194
+ keysToRemove.push(fullKey);
195
+ }
196
+ }
197
+
198
+ // Remove the keys after collecting them to avoid issues while iterating
199
+ keysToRemove.forEach((key) => localStorage.removeItem(key));
200
+ } catch (error) {
201
+ console.error("Failed to clear entity cache from localStorage:", error);
202
+ }
203
+ }
204
+ }
@@ -15,6 +15,7 @@ const map = iconKeys
15
15
  export const iconsSearch = new Fuse(map, {
16
16
  isCaseSensitive: false,
17
17
  shouldSort: true,
18
+ ignoreLocation: true,
18
19
  distance: 0,
19
20
  keys: ["key", "synonyms"]
20
21
  })
@@ -1222,7 +1222,6 @@ export const iconSynonyms = {
1222
1222
  picture_in_picture_alt: "cropped overlap photo position shape",
1223
1223
  pie_chart: "analytics bars data diagram infographic measure metrics statistics tracking",
1224
1224
  pie_chart_outline: "analytics bars data diagram infographic measure metrics statistics tracking",
1225
- pie_chart_outlined: "graph",
1226
1225
  pin: "1 2 3 digit key login logout number password pattern security star symbol unlock",
1227
1226
  pinch: "arrows compress direction finger grasp hand navigation nip squeeze tweak",
1228
1227
  pin_drop: "destination direction gps location maps navigation place stop",
@@ -1,16 +1,16 @@
1
1
  import React from "react";
2
2
  import { hashString } from "./hash";
3
- import { coolIconKeys, Icon, iconKeys } from "@firecms/ui";
3
+ import { coolIconKeys, Icon, IconColor, iconKeys } from "@firecms/ui";
4
4
  import { slugify } from "./strings";
5
5
  import equal from "react-fast-compare"
6
6
 
7
- export function getIcon(iconKey?: string, className?: string): React.ReactElement | undefined {
7
+ export function getIcon(iconKey?: string, className?: string, color?:IconColor): React.ReactElement | undefined {
8
8
  if (!iconKey) return undefined;
9
9
  iconKey = slugify(iconKey);
10
10
  if (!(iconKey in iconKeysMap)) {
11
11
  return undefined;
12
12
  }
13
- return iconKey in iconKeysMap ? <Icon iconKey={iconKey} size={"medium"} className={className}/> : undefined;
13
+ return iconKey in iconKeysMap ? <Icon iconKey={iconKey} size={"medium"} className={className} color={color}/> : undefined;
14
14
  }
15
15
 
16
16
  export type IconViewProps = {
@@ -25,12 +25,16 @@ export const IconForView = React.memo(
25
25
  function IconForView({
26
26
  collectionOrView,
27
27
  className,
28
- size = "medium"
28
+ color,
29
+ size = "medium",
29
30
  }: {
30
- collectionOrView?: IconViewProps, className?: string, size?: "smallest" | "small" | "medium" | "large" | number,
31
+ collectionOrView?: IconViewProps,
32
+ color?: IconColor,
33
+ className?: string,
34
+ size?: "smallest" | "small" | "medium" | "large" | number,
31
35
  }): React.ReactElement {
32
36
  if (!collectionOrView) return <></>;
33
- const icon = getIcon(collectionOrView.icon, className);
37
+ const icon = getIcon(collectionOrView.icon, className, color);
34
38
  if (collectionOrView?.icon && icon)
35
39
  return icon;
36
40
 
@@ -51,9 +55,9 @@ export const IconForView = React.memo(
51
55
  if (!key)
52
56
  key = coolIconKeys[hashString(collectionOrView.path) % iconsCount];
53
57
 
54
- return <Icon iconKey={key} size={size} className={className}/>;
58
+ return <Icon iconKey={key} size={size} className={className} color={color}/>;
55
59
  }, (prevProps, nextProps) => {
56
- return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon);
60
+ return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon) && equal(prevProps.color, nextProps.color);
57
61
  });
58
62
 
59
63
  const iconKeysMap: Record<string, string> = iconKeys.reduce((acc: Record<string, string>, key) => {