@firecms/core 3.0.0-alpha.84 → 3.0.0-beta.10

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 (370) hide show
  1. package/README.md +6 -7
  2. package/dist/app/AppBar.d.ts +12 -0
  3. package/dist/app/Drawer.d.ts +16 -0
  4. package/dist/app/Scaffold.d.ts +30 -0
  5. package/dist/app/index.d.ts +4 -0
  6. package/dist/app/useApp.d.ts +16 -0
  7. package/dist/components/ArrayContainer.d.ts +3 -4
  8. package/dist/components/CircularProgressCenter.d.ts +1 -1
  9. package/dist/components/ClearFilterSortButton.d.ts +5 -0
  10. package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
  11. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +13 -18
  12. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -5
  13. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +7 -13
  14. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
  15. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  16. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +3 -1
  17. package/dist/components/EntityCollectionTable/index.d.ts +2 -4
  18. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
  19. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  20. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +3 -3
  21. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +13 -4
  22. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  23. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  24. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  25. package/dist/components/EntityPreview.d.ts +26 -7
  26. package/dist/components/EntityView.d.ts +11 -0
  27. package/dist/components/ErrorView.d.ts +1 -1
  28. package/dist/components/FieldCaption.d.ts +5 -0
  29. package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
  30. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  31. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +3 -3
  32. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  33. package/dist/components/HomePage/index.d.ts +3 -1
  34. package/dist/components/{FieldConfigBadge.d.ts → PropertyConfigBadge.d.ts} +2 -1
  35. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  36. package/dist/components/{ReferenceSelectionInner.d.ts → ReferenceTable/ReferenceSelectionTable.d.ts} +2 -2
  37. package/dist/components/ReferenceWidget.d.ts +6 -4
  38. package/dist/components/{EntityCollectionTable/SimpleEntityCollectionTable.d.ts → SelectableTable/SelectableTable.d.ts} +8 -28
  39. package/dist/components/SelectableTable/SelectableTableContext.d.ts +4 -0
  40. package/dist/components/{EntityCollectionTable → SelectableTable}/filters/ReferenceFilterField.d.ts +2 -1
  41. package/dist/components/VirtualTable/VirtualTableProps.d.ts +16 -13
  42. package/dist/components/VirtualTable/types.d.ts +3 -3
  43. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  44. package/dist/components/common/index.d.ts +6 -0
  45. package/dist/components/common/table_height.d.ts +5 -0
  46. package/dist/components/{EntityCollectionTable → common}/types.d.ts +11 -6
  47. package/dist/components/{EntityCollectionView → common}/useColumnsIds.d.ts +2 -1
  48. package/dist/components/{EntityCollectionTable → common}/useDataSourceEntityCollectionTableController.d.ts +4 -1
  49. package/dist/components/common/useTableSearchHelper.d.ts +12 -0
  50. package/dist/components/index.d.ts +14 -8
  51. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  52. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
  53. package/dist/core/DefaultDrawer.d.ts +19 -0
  54. package/dist/core/DrawerNavigationItem.d.ts +10 -0
  55. package/dist/core/EntityEditView.d.ts +36 -0
  56. package/dist/core/FireCMS.d.ts +1 -1
  57. package/dist/core/NavigationRoutes.d.ts +3 -3
  58. package/dist/core/index.d.ts +3 -6
  59. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  60. package/dist/form/components/CustomIdField.d.ts +2 -1
  61. package/dist/form/components/ErrorFocus.d.ts +1 -1
  62. package/dist/form/components/FieldHelperText.d.ts +3 -3
  63. package/dist/form/components/FormikArrayContainer.d.ts +2 -1
  64. package/dist/{components → form/components}/LabelWithIcon.d.ts +1 -1
  65. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  66. package/dist/form/components/StorageItemPreview.d.ts +4 -3
  67. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  68. package/dist/form/components/index.d.ts +2 -1
  69. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  70. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  71. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  72. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  73. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  74. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  75. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  76. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  77. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  78. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  79. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -4
  80. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  81. package/dist/form/index.d.ts +4 -5
  82. package/dist/form/useClearRestoreValue.d.ts +2 -2
  83. package/dist/form/validation.d.ts +1 -1
  84. package/dist/hooks/data/delete.d.ts +2 -2
  85. package/dist/hooks/data/save.d.ts +2 -3
  86. package/dist/hooks/data/useDataSource.d.ts +2 -2
  87. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  88. package/dist/hooks/index.d.ts +5 -1
  89. package/dist/{core → hooks}/useBuildModeController.d.ts +1 -1
  90. package/dist/hooks/useBuildNavigationController.d.ts +23 -0
  91. package/dist/hooks/useProjectLog.d.ts +14 -0
  92. package/dist/hooks/useSnackbarController.d.ts +1 -0
  93. package/dist/hooks/useStorageSource.d.ts +2 -2
  94. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.es.js +16297 -12643
  97. package/dist/index.es.js.map +1 -1
  98. package/dist/index.umd.js +20043 -587
  99. package/dist/index.umd.js.map +1 -1
  100. package/dist/internal/useBuildDataSource.d.ts +1 -12
  101. package/dist/preview/PropertyPreview.d.ts +1 -1
  102. package/dist/preview/PropertyPreviewProps.d.ts +7 -5
  103. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  104. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  105. package/dist/preview/components/ReferencePreview.d.ts +4 -9
  106. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  107. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  108. package/dist/types/analytics.d.ts +1 -1
  109. package/dist/types/auth.d.ts +38 -2
  110. package/dist/types/collections.d.ts +56 -9
  111. package/dist/types/datasource.d.ts +59 -39
  112. package/dist/types/entities.d.ts +7 -1
  113. package/dist/types/entity_actions.d.ts +14 -0
  114. package/dist/types/entity_callbacks.d.ts +3 -3
  115. package/dist/types/entity_overrides.d.ts +6 -0
  116. package/dist/types/fields.d.ts +47 -42
  117. package/dist/types/firecms.d.ts +8 -23
  118. package/dist/types/index.d.ts +2 -1
  119. package/dist/types/navigation.d.ts +18 -16
  120. package/dist/types/permissions.d.ts +5 -1
  121. package/dist/types/plugins.d.ts +31 -31
  122. package/dist/types/properties.d.ts +36 -23
  123. package/dist/types/property_config.d.ts +2 -2
  124. package/dist/types/roles.d.ts +31 -0
  125. package/dist/types/side_dialogs_controller.d.ts +10 -0
  126. package/dist/types/storage.d.ts +86 -3
  127. package/dist/types/user.d.ts +5 -0
  128. package/dist/util/collections.d.ts +9 -1
  129. package/dist/util/entities.d.ts +2 -2
  130. package/dist/util/icon_list.d.ts +5 -1
  131. package/dist/util/icon_synonyms.d.ts +1 -97
  132. package/dist/util/icons.d.ts +10 -3
  133. package/dist/util/index.d.ts +3 -1
  134. package/dist/util/navigation_utils.d.ts +2 -2
  135. package/dist/util/objects.d.ts +1 -1
  136. package/dist/util/permissions.d.ts +4 -4
  137. package/dist/util/plurals.d.ts +0 -2
  138. package/dist/util/property_utils.d.ts +1 -1
  139. package/dist/util/references.d.ts +4 -2
  140. package/dist/util/resolutions.d.ts +28 -14
  141. package/dist/util/storage.d.ts +23 -2
  142. package/dist/util/strings.d.ts +1 -1
  143. package/dist/util/useDebouncedCallback.d.ts +1 -0
  144. package/dist/util/useStorageUploadController.d.ts +3 -3
  145. package/dist/util/useTraceUpdate.d.ts +1 -0
  146. package/package.json +129 -112
  147. package/src/app/AppBar.tsx +18 -0
  148. package/src/app/Drawer.tsx +24 -0
  149. package/src/app/Scaffold.tsx +243 -0
  150. package/src/app/index.ts +4 -0
  151. package/src/app/useApp.tsx +32 -0
  152. package/src/components/ArrayContainer.tsx +45 -75
  153. package/src/components/CircularProgressCenter.tsx +1 -1
  154. package/src/components/ClearFilterSortButton.tsx +41 -0
  155. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +1 -1
  156. package/src/components/DeleteEntityDialog.tsx +4 -4
  157. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +47 -58
  158. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +253 -448
  159. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +11 -12
  160. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +54 -48
  161. package/src/components/EntityCollectionTable/column_utils.tsx +4 -4
  162. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +40 -32
  163. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +17 -9
  164. package/src/components/EntityCollectionTable/index.tsx +1 -9
  165. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +44 -46
  166. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +32 -30
  167. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
  168. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +145 -142
  169. package/src/components/EntityCollectionView/EntityCollectionView.tsx +184 -171
  170. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  171. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  172. package/src/components/EntityCollectionView/useSelectionController.tsx +42 -0
  173. package/src/components/EntityCollectionView/utils.ts +19 -0
  174. package/src/components/EntityPreview.tsx +208 -71
  175. package/src/components/EntityView.tsx +84 -0
  176. package/src/components/ErrorView.tsx +1 -1
  177. package/src/components/FieldCaption.tsx +14 -0
  178. package/src/components/HomePage/DefaultHomePage.tsx +38 -28
  179. package/src/components/HomePage/NavigationCard.tsx +69 -0
  180. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  181. package/src/components/HomePage/NavigationGroup.tsx +1 -1
  182. package/src/components/HomePage/SmallNavigationCard.tsx +44 -0
  183. package/src/components/HomePage/index.tsx +3 -1
  184. package/src/components/PropertyConfigBadge.tsx +23 -0
  185. package/src/components/PropertyIdCopyTooltip.tsx +48 -0
  186. package/src/components/{ReferenceSelectionInner.tsx → ReferenceTable/ReferenceSelectionTable.tsx} +37 -23
  187. package/src/components/ReferenceWidget.tsx +26 -16
  188. package/src/components/SearchIconsView.tsx +10 -7
  189. package/src/components/{EntityCollectionTable/SimpleEntityCollectionTable.tsx → SelectableTable/SelectableTable.tsx} +46 -84
  190. package/src/components/SelectableTable/SelectableTableContext.tsx +6 -0
  191. package/src/components/{EntityCollectionTable → SelectableTable}/filters/BooleanFilterField.tsx +2 -3
  192. package/src/components/{EntityCollectionTable → SelectableTable}/filters/DateTimeFilterField.tsx +22 -7
  193. package/src/components/{EntityCollectionTable → SelectableTable}/filters/ReferenceFilterField.tsx +38 -24
  194. package/src/components/{EntityCollectionTable → SelectableTable}/filters/StringNumberFilterField.tsx +88 -22
  195. package/src/components/VirtualTable/VirtualTable.tsx +77 -46
  196. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  197. package/src/components/VirtualTable/VirtualTableHeader.tsx +14 -8
  198. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  199. package/src/components/VirtualTable/VirtualTableProps.tsx +19 -15
  200. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  201. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
  202. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +4 -3
  203. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +4 -3
  204. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
  205. package/src/components/VirtualTable/types.tsx +2 -3
  206. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +17 -9
  207. package/src/components/common/index.ts +6 -0
  208. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  209. package/src/components/{EntityCollectionTable → common}/types.tsx +9 -6
  210. package/src/components/{EntityCollectionView → common}/useColumnsIds.tsx +23 -2
  211. package/src/components/{EntityCollectionTable → common}/useDataSourceEntityCollectionTableController.tsx +25 -14
  212. package/src/components/common/useTableSearchHelper.ts +88 -0
  213. package/src/components/index.tsx +15 -8
  214. package/src/contexts/AuthControllerContext.tsx +1 -1
  215. package/src/contexts/DialogsProvider.tsx +2 -2
  216. package/src/core/DefaultAppBar.tsx +176 -0
  217. package/src/core/DefaultDrawer.tsx +183 -0
  218. package/src/core/DrawerNavigationItem.tsx +66 -0
  219. package/src/core/EntityEditView.tsx +1127 -0
  220. package/src/core/EntitySidePanel.tsx +9 -8
  221. package/src/core/FireCMS.tsx +67 -59
  222. package/src/core/NavigationRoutes.tsx +25 -17
  223. package/src/core/SideDialogs.tsx +1 -0
  224. package/src/core/field_configs.tsx +18 -19
  225. package/src/core/index.tsx +3 -6
  226. package/src/form/PropertyFieldBinding.tsx +60 -33
  227. package/src/form/components/CustomIdField.tsx +51 -36
  228. package/src/form/components/ErrorFocus.tsx +3 -3
  229. package/src/form/components/FieldHelperText.tsx +4 -4
  230. package/src/form/components/FormikArrayContainer.tsx +4 -1
  231. package/src/form/components/LabelWithIcon.tsx +41 -0
  232. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  233. package/src/form/components/StorageItemPreview.tsx +22 -10
  234. package/src/form/components/StorageUploadProgress.tsx +8 -8
  235. package/src/form/components/index.tsx +2 -1
  236. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +28 -18
  237. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +37 -37
  238. package/src/form/field_bindings/BlockFieldBinding.tsx +29 -27
  239. package/src/form/field_bindings/DateTimeFieldBinding.tsx +20 -17
  240. package/src/form/field_bindings/KeyValueFieldBinding.tsx +66 -60
  241. package/src/form/field_bindings/MapFieldBinding.tsx +35 -33
  242. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
  243. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -22
  244. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +12 -18
  245. package/src/form/field_bindings/ReferenceFieldBinding.tsx +45 -33
  246. package/src/form/field_bindings/RepeatFieldBinding.tsx +36 -21
  247. package/src/form/field_bindings/SelectFieldBinding.tsx +22 -16
  248. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +41 -42
  249. package/src/form/field_bindings/SwitchFieldBinding.tsx +11 -8
  250. package/src/form/field_bindings/TextFieldBinding.tsx +34 -30
  251. package/src/form/index.tsx +5 -9
  252. package/src/form/useClearRestoreValue.tsx +2 -2
  253. package/src/form/validation.ts +4 -21
  254. package/src/hooks/data/delete.ts +5 -4
  255. package/src/hooks/data/save.ts +7 -2
  256. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  257. package/src/hooks/data/useDataSource.tsx +15 -2
  258. package/src/hooks/data/useEntityFetch.tsx +4 -4
  259. package/src/hooks/index.tsx +7 -1
  260. package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +8 -10
  261. package/src/{core → hooks}/useBuildModeController.tsx +12 -6
  262. package/src/{internal → hooks}/useBuildNavigationController.tsx +244 -99
  263. package/src/hooks/useFireCMSContext.tsx +51 -3
  264. package/src/hooks/useLargeLayout.tsx +10 -7
  265. package/src/hooks/useProjectLog.tsx +63 -0
  266. package/src/hooks/useReferenceDialog.tsx +3 -3
  267. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  268. package/src/hooks/useSnackbarController.tsx +1 -2
  269. package/src/hooks/useStorageSource.tsx +7 -2
  270. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  271. package/src/index.ts +1 -0
  272. package/src/internal/useBuildDataSource.ts +79 -84
  273. package/src/internal/useBuildSideDialogsController.tsx +1 -0
  274. package/src/internal/useBuildSideEntityController.tsx +103 -23
  275. package/src/internal/useUnsavedChangesDialog.tsx +3 -1
  276. package/src/preview/PropertyPreview.tsx +12 -19
  277. package/src/preview/PropertyPreviewProps.tsx +6 -10
  278. package/src/preview/components/BooleanPreview.tsx +19 -4
  279. package/src/preview/components/EnumValuesChip.tsx +2 -2
  280. package/src/preview/components/ImagePreview.tsx +24 -34
  281. package/src/preview/components/ReferencePreview.tsx +73 -176
  282. package/src/preview/components/StorageThumbnail.tsx +5 -1
  283. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  284. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -2
  285. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +3 -2
  286. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -2
  287. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  288. package/src/preview/property_previews/ArrayOneOfPreview.tsx +3 -4
  289. package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -4
  290. package/src/preview/property_previews/MapPropertyPreview.tsx +6 -6
  291. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
  292. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  293. package/src/preview/util.ts +2 -2
  294. package/src/types/analytics.ts +1 -0
  295. package/src/types/auth.tsx +51 -2
  296. package/src/types/collections.ts +65 -9
  297. package/src/types/customization_controller.tsx +0 -1
  298. package/src/types/datasource.ts +69 -47
  299. package/src/types/entities.ts +15 -1
  300. package/src/types/entity_actions.tsx +17 -0
  301. package/src/types/entity_callbacks.ts +4 -3
  302. package/src/types/entity_overrides.tsx +7 -0
  303. package/src/types/fields.tsx +51 -45
  304. package/src/types/firecms.tsx +9 -26
  305. package/src/types/index.ts +2 -1
  306. package/src/types/navigation.ts +20 -19
  307. package/src/types/permissions.ts +6 -1
  308. package/src/types/plugins.tsx +38 -40
  309. package/src/types/properties.ts +42 -24
  310. package/src/types/property_config.tsx +2 -2
  311. package/src/types/roles.ts +41 -0
  312. package/src/types/side_dialogs_controller.tsx +13 -0
  313. package/src/types/side_entity_controller.tsx +1 -0
  314. package/src/types/storage.ts +94 -3
  315. package/src/types/user.ts +7 -0
  316. package/src/util/collections.ts +22 -0
  317. package/src/util/entities.ts +6 -5
  318. package/src/util/enums.ts +1 -1
  319. package/src/util/icon_list.ts +15 -10
  320. package/src/util/icon_synonyms.ts +3 -99
  321. package/src/util/icons.tsx +18 -4
  322. package/src/util/index.ts +3 -1
  323. package/src/util/make_properties_editable.ts +13 -5
  324. package/src/util/navigation_utils.ts +6 -6
  325. package/src/util/objects.ts +25 -28
  326. package/src/util/permissions.ts +12 -8
  327. package/src/util/plurals.ts +0 -2
  328. package/src/util/property_utils.tsx +1 -1
  329. package/src/util/references.ts +39 -5
  330. package/src/util/resolutions.ts +75 -42
  331. package/src/util/storage.ts +79 -21
  332. package/src/util/strings.ts +4 -3
  333. package/src/util/{useDebounce.ts → useDebouncedCallback.ts} +1 -1
  334. package/src/util/useStorageUploadController.tsx +33 -7
  335. package/src/util/useTraceUpdate.tsx +2 -1
  336. package/dist/components/VirtualTable/common.d.ts +0 -2
  337. package/dist/core/Drawer.d.ts +0 -23
  338. package/dist/core/Scaffold.d.ts +0 -52
  339. package/dist/form/EntityForm.d.ts +0 -75
  340. package/dist/form/components/SubmitListener.d.ts +0 -1
  341. package/dist/form/components/SwitchControl.d.ts +0 -8
  342. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  343. package/dist/hooks/useVerifyLicense.d.ts +0 -0
  344. package/dist/internal/EntityView.d.ts +0 -22
  345. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  346. package/dist/internal/useBuildNavigationController.d.ts +0 -14
  347. package/dist/internal/useLocaleConfig.d.ts +0 -1
  348. package/dist/types/appcheck.d.ts +0 -26
  349. package/dist/util/useDebounce.d.ts +0 -1
  350. package/src/components/FieldConfigBadge.tsx +0 -17
  351. package/src/components/FireCMSAppBar.tsx +0 -157
  352. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  353. package/src/components/LabelWithIcon.tsx +0 -33
  354. package/src/core/Drawer.tsx +0 -162
  355. package/src/core/Scaffold.tsx +0 -278
  356. package/src/form/EntityForm.tsx +0 -657
  357. package/src/form/components/SubmitListener.tsx +0 -32
  358. package/src/form/components/SwitchControl.tsx +0 -39
  359. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -696
  360. package/src/hooks/useVerifyLicense.tsx +0 -1
  361. package/src/internal/EntityView.tsx +0 -578
  362. package/src/internal/useBuildCustomizationController.tsx +0 -5
  363. package/src/internal/useLocaleConfig.tsx +0 -18
  364. package/src/types/appcheck.ts +0 -29
  365. /package/dist/components/{EntityCollectionTable → SelectableTable}/filters/BooleanFilterField.d.ts +0 -0
  366. /package/dist/components/{EntityCollectionTable → SelectableTable}/filters/DateTimeFilterField.d.ts +0 -0
  367. /package/dist/components/{EntityCollectionTable → SelectableTable}/filters/StringNumberFilterField.d.ts +0 -0
  368. /package/dist/components/{EntityCollectionTable → common}/useDebouncedData.d.ts +0 -0
  369. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  370. /package/src/components/{EntityCollectionTable → common}/useDebouncedData.ts +0 -0
@@ -1,5 +1,5 @@
1
- import { useCallback, useEffect, useMemo, useState } from "react";
2
- import { useLocation } from "react-router-dom";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import equal from "react-fast-compare"
3
3
 
4
4
  import {
5
5
  AuthController,
@@ -9,16 +9,18 @@ import {
9
9
  EntityCollection,
10
10
  EntityCollectionsBuilder,
11
11
  EntityReference,
12
- FireCMSPlugin,
13
12
  NavigationController,
13
+ PermissionsBuilder,
14
14
  TopNavigationEntry,
15
15
  TopNavigationResult,
16
16
  User,
17
17
  UserConfigurationPersistence
18
18
  } from "../types";
19
19
  import {
20
+ applyPermissionsFunctionIfEmpty,
20
21
  getCollectionByPathOrId,
21
22
  mergeDeep,
23
+ removeFunctions,
22
24
  removeInitialAndTrailingSlashes,
23
25
  resolveCollectionPathIds,
24
26
  resolvePermissions
@@ -28,32 +30,46 @@ import { getParentReferencesFromPath } from "../util/parent_references_from_path
28
30
  const DEFAULT_BASE_PATH = "/";
29
31
  const DEFAULT_COLLECTION_PATH = "/c";
30
32
 
31
- type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
33
+ export type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
32
34
  basePath?: string,
33
35
  baseCollectionPath?: string,
34
36
  authController: AuthController<UserType>;
35
37
  collections?: EC[] | EntityCollectionsBuilder<EC>;
38
+ collectionPermissions?: PermissionsBuilder;
36
39
  views?: CMSView[] | CMSViewsBuilder;
40
+ adminViews?: CMSView[] | CMSViewsBuilder;
41
+ viewsOrder?: string[];
37
42
  userConfigPersistence?: UserConfigurationPersistence;
38
- plugins?: FireCMSPlugin[];
39
- dataSource: DataSourceDelegate;
43
+ dataSourceDelegate: DataSourceDelegate;
44
+ /**
45
+ * Use this method to inject collections to the CMS.
46
+ * You receive the current collections as a parameter, and you can return
47
+ * a new list of collections.
48
+ * @see {@link joinCollectionLists}
49
+ * @param collections
50
+ */
51
+ injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
40
52
  };
41
53
 
42
- export function useBuildNavigationController<EC extends EntityCollection, UserType extends User>({
43
- basePath = DEFAULT_BASE_PATH,
44
- baseCollectionPath = DEFAULT_COLLECTION_PATH,
45
- authController,
46
- collections: baseCollections,
47
- views: baseViews,
48
- userConfigPersistence,
49
- plugins,
50
- dataSource
51
- }: BuildNavigationContextProps<EC, UserType>): NavigationController {
52
-
53
- const location = useLocation();
54
-
55
- const [collections, setCollections] = useState<EntityCollection[] | undefined>();
56
- const [views, setViews] = useState<CMSView[] | undefined>();
54
+ export function useBuildNavigationController<EC extends EntityCollection, UserType extends User>(props: BuildNavigationContextProps<EC, UserType>): NavigationController {
55
+ const {
56
+ basePath = DEFAULT_BASE_PATH,
57
+ baseCollectionPath = DEFAULT_COLLECTION_PATH,
58
+ authController,
59
+ collections: collectionsProp,
60
+ collectionPermissions,
61
+ views: viewsProp,
62
+ adminViews: adminViewsProp,
63
+ viewsOrder,
64
+ userConfigPersistence,
65
+ dataSourceDelegate,
66
+ injectCollections
67
+ } = props;
68
+
69
+ const collectionsRef = useRef<EntityCollection[] | undefined>();
70
+ const viewsRef = useRef<CMSView[] | undefined>();
71
+ const adminViewsRef = useRef<CMSView[] | undefined>();
72
+
57
73
  const [initialised, setInitialised] = useState<boolean>(false);
58
74
 
59
75
  const [topLevelNavigation, setTopLevelNavigation] = useState<TopNavigationResult | undefined>(undefined);
@@ -73,19 +89,18 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
73
89
  const buildUrlCollectionPath = useCallback((path: string): string => `${removeInitialAndTrailingSlashes(baseCollectionPath)}/${encodePath(path)}`,
74
90
  [baseCollectionPath]);
75
91
 
76
- const computeTopNavigation = useCallback((collections: EntityCollection[], views: CMSView[]): TopNavigationResult => {
77
- // return (collection.editable && resolvePermissions(collection, authController, paths).editCollection) ?? DEFAULT_PERMISSIONS.editCollection;
78
- const navigationEntries: TopNavigationEntry[] = [
92
+ const computeTopNavigation = useCallback((collections: EntityCollection[], views: CMSView[], adminViews: CMSView[], viewsOrder?: string[]): TopNavigationResult => {
93
+ let navigationEntries: TopNavigationEntry[] = [
79
94
  ...(collections ?? []).map(collection => (!collection.hideFromNavigation
80
- ? {
95
+ ? ({
81
96
  url: buildUrlCollectionPath(collection.id ?? collection.path),
82
97
  type: "collection",
83
98
  name: collection.name.trim(),
84
99
  path: collection.id ?? collection.path,
85
100
  collection,
86
101
  description: collection.description?.trim(),
87
- group: collection.group?.trim()
88
- }
102
+ group: getGroup(collection)
103
+ } satisfies TopNavigationEntry)
89
104
  : undefined))
90
105
  .filter(Boolean) as TopNavigationEntry[],
91
106
  ...(views ?? []).map(view =>
@@ -94,18 +109,74 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
94
109
  url: buildCMSUrlPath(Array.isArray(view.path) ? view.path[0] : view.path),
95
110
  name: view.name.trim(),
96
111
  type: "view",
112
+ path: view.path,
113
+ view,
114
+ description: view.description?.trim(),
115
+ group: getGroup(view)
116
+ } satisfies TopNavigationEntry)
117
+ : undefined)
118
+ .filter(Boolean) as TopNavigationEntry[],
119
+ ...(adminViews ?? []).map(view =>
120
+ !view.hideFromNavigation
121
+ ? ({
122
+ url: buildCMSUrlPath(Array.isArray(view.path) ? view.path[0] : view.path),
123
+ name: view.name.trim(),
124
+ type: "admin",
125
+ path: view.path,
97
126
  view,
98
127
  description: view.description?.trim(),
99
- group: view.group?.trim()
100
- })
128
+ group: "Admin"
129
+ } satisfies TopNavigationEntry)
101
130
  : undefined)
102
131
  .filter(Boolean) as TopNavigationEntry[]
103
132
  ];
104
133
 
134
+ // Sort by group, entries with group "Admin" will go last, and second to last will be the group "Views"
135
+ navigationEntries = navigationEntries.sort((a, b) => {
136
+ if (a.group !== "Views" && a.group !== "Admin" && (b.group === "Views" || b.group === "Admin")) {
137
+ return -1;
138
+ }
139
+ if (b.group !== "Views" && b.group !== "Admin" && (a.group === "Views" || a.group === "Admin")) {
140
+ return 1;
141
+ }
142
+ if (a.group === "Admin" && b.group !== "Admin") {
143
+ return 1;
144
+ }
145
+ if (a.group !== "Admin" && b.group === "Admin") {
146
+ return -1;
147
+ }
148
+ if (a.group === "Views" && b.group !== "Views") {
149
+ return -1;
150
+ }
151
+ if (a.group !== "Views" && b.group === "Views") {
152
+ return 1;
153
+ }
154
+ return 0;
155
+
156
+ });
157
+
158
+ if (viewsOrder) {
159
+ navigationEntries = navigationEntries.sort((a, b) => {
160
+ const aIndex = viewsOrder.indexOf(a.path);
161
+ const bIndex = viewsOrder.indexOf(b.path);
162
+ if (aIndex === -1 && bIndex === -1) {
163
+ return 0;
164
+ }
165
+ if (aIndex === -1) {
166
+ return 1;
167
+ }
168
+ if (bIndex === -1) {
169
+ return -1;
170
+ }
171
+ return aIndex - bIndex;
172
+ });
173
+ }
174
+
105
175
  const groups: string[] = Object.values(navigationEntries)
106
176
  .map(e => e.group)
107
177
  .filter(Boolean)
108
178
  .filter((value, index, array) => array.indexOf(value) === index) as string[];
179
+
109
180
  return {
110
181
  navigationEntries,
111
182
  groups
@@ -117,43 +188,76 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
117
188
  if (authController.initialLoading)
118
189
  return;
119
190
 
191
+ console.debug("Refreshing navigation");
192
+
120
193
  try {
121
- const [resolvedCollections = [], resolvedViews = []] = await Promise.all([
122
- resolveCollections(baseCollections, authController, dataSource, plugins),
123
- resolveCMSViews(baseViews, authController, dataSource)
194
+
195
+ const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
196
+ resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),
197
+ resolveCMSViews(viewsProp, authController, dataSourceDelegate),
198
+ resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)
124
199
  ]
125
200
  );
126
201
 
127
- setCollections(resolvedCollections);
128
- setViews(resolvedViews);
129
- setTopLevelNavigation(computeTopNavigation(resolvedCollections ?? [], resolvedViews));
202
+ let shouldUpdateTopLevelNav = false;
203
+ if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
204
+ collectionsRef.current = resolvedCollections;
205
+ shouldUpdateTopLevelNav = true;
206
+ }
207
+ if (collectionsRef.current === undefined) {
208
+ collectionsRef.current = resolvedCollections;
209
+ shouldUpdateTopLevelNav = true;
210
+ }
211
+ if (!equal(viewsRef.current, resolvedViews)) {
212
+ viewsRef.current = resolvedViews;
213
+ shouldUpdateTopLevelNav = true;
214
+ }
215
+ if (!equal(adminViewsRef.current, resolvedAdminViews)) {
216
+ adminViewsRef.current = resolvedAdminViews;
217
+ shouldUpdateTopLevelNav = true;
218
+ }
219
+
220
+ const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
221
+ if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
222
+ setTopLevelNavigation(computedTopLevelNav);
223
+ }
130
224
  } catch (e) {
131
225
  console.error(e);
132
226
  setNavigationLoadingError(e as any);
133
227
  }
134
228
 
135
- setNavigationLoading(false);
136
- setInitialised(true);
137
- }, [baseCollections, authController.user, authController.initialLoading, plugins, baseViews, computeTopNavigation]);
229
+ if (navigationLoading)
230
+ setNavigationLoading(false);
231
+ if (!initialised)
232
+ setInitialised(true);
233
+
234
+ }, [
235
+ collectionsProp,
236
+ collectionPermissions,
237
+ authController.user,
238
+ authController.initialLoading,
239
+ viewsProp,
240
+ adminViewsProp,
241
+ computeTopNavigation,
242
+ injectCollections
243
+ ]);
138
244
 
139
245
  useEffect(() => {
140
246
  refreshNavigation();
141
247
  }, [refreshNavigation]);
142
248
 
143
- const getCollection = useCallback(<EC extends EntityCollection>(
249
+ const getCollection = useCallback((
144
250
  idOrPath: string,
145
- entityId?: string,
146
251
  includeUserOverride = false
147
252
  ): EC | undefined => {
148
-
253
+ const collections = collectionsRef.current;
149
254
  if (!collections)
150
255
  return undefined;
151
256
 
152
257
  const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);
153
258
 
154
259
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
155
-
156
- const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
260
+ const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : undefined;
157
261
 
158
262
  let result: Partial<EntityCollection> | undefined = overriddenCollection;
159
263
 
@@ -173,16 +277,14 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
173
277
 
174
278
  return { ...overriddenCollection, ...result } as EC;
175
279
 
176
- }, [
177
- basePath,
178
- baseCollectionPath,
179
- collections,
180
- ]);
280
+ }, [userConfigPersistence]);
181
281
 
182
282
  const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {
183
- let currentCollections = collections;
184
- if (!currentCollections)
185
- throw Error("Collections have not been initialised yet");
283
+
284
+ const collections = collectionsRef.current;
285
+ if (collections === undefined)
286
+ throw Error("getCollectionFromPaths: Collections have not been initialised yet");
287
+ let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
186
288
 
187
289
  for (let i = 0; i < pathSegments.length; i++) {
188
290
  const pathSegment = pathSegments[i];
@@ -196,12 +298,14 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
196
298
 
197
299
  return undefined;
198
300
 
199
- }, [collections]);
301
+ }, []);
200
302
 
201
303
  const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {
202
- let currentCollections = collections;
203
- if (!currentCollections)
204
- throw Error("Collections have not been initialised yet");
304
+
305
+ const collections = collectionsRef.current;
306
+ if (collections === undefined)
307
+ throw Error("getCollectionFromIds: Collections have not been initialised yet");
308
+ let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
205
309
 
206
310
  for (let i = 0; i < ids.length; i++) {
207
311
  const id = ids[i];
@@ -215,7 +319,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
215
319
 
216
320
  return undefined;
217
321
 
218
- }, [collections]);
322
+ }, []);
219
323
 
220
324
  const isUrlCollectionPath = useCallback(
221
325
  (path: string): boolean => removeInitialAndTrailingSlashes(path + "/").startsWith(removeInitialAndTrailingSlashes(fullCollectionPath) + "/"),
@@ -237,48 +341,53 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
237
341
  []);
238
342
 
239
343
  const resolveAliasesFrom = useCallback((path: string): string => {
240
- if (!collections)
241
- throw Error("Collections have not been initialised yet");
344
+ const collections = collectionsRef.current ?? [];
242
345
  return resolveCollectionPathIds(path, collections);
243
- }, [collections]);
244
-
245
- const state = location.state as any;
246
- /**
247
- * The location can be overridden if `base_location` is set in the
248
- * state field of the current location. This can happen if you open
249
- * a side entity, like `products`, from a different one, like `users`
250
- */
251
- const baseLocation = state && state.base_location ? state.base_location : location;
346
+ }, []);
252
347
 
253
- const getAllParentCollectionsForPath = useCallback((path: string): EntityReference[] => {
348
+ const getAllParentReferencesForPath = useCallback((path: string): EntityReference[] => {
349
+ const collections = collectionsRef.current ?? [];
254
350
  return getParentReferencesFromPath({
255
351
  path,
256
352
  collections
257
353
  });
258
- }, [collections]);
354
+ }, []);
259
355
 
260
356
  const getParentCollectionIds = useCallback((path: string): string[] => {
261
- return getAllParentCollectionsForPath(path).map(r => r.id);
262
- }, [getAllParentCollectionsForPath])
357
+
358
+ const strings = path.split("/");
359
+ const oddPathSegments = strings.filter((_, i) => i % 2 === 0);
360
+ oddPathSegments.pop();
361
+
362
+ const result: string[][] = [];
363
+
364
+ for (let i = 1; i <= oddPathSegments.length; i++) {
365
+ result.push(oddPathSegments.slice(0, i));
366
+ }
367
+
368
+ // for each odd path segment, get the collection
369
+ return result.map(r => getCollectionFromPaths(r)?.id).filter(Boolean) as string[];
370
+ }, [getAllParentReferencesForPath])
263
371
 
264
372
  const convertIdsToPaths = useCallback((ids: string[]): string[] => {
265
- let currentCollections = collections;
266
- const paths: string[] = [];
267
- for (let i = 0; i < ids.length; i++) {
268
- const id = ids[i];
269
- const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === id);
270
- if (!collection)
271
- throw Error(`Collection with id ${id} not found`);
272
- paths.push(collection.path);
273
- currentCollections = collection.subcollections;
274
- }
275
- return paths;
373
+ const collections = collectionsRef.current;
374
+ let currentCollections = collections;
375
+ const paths: string[] = [];
376
+ for (let i = 0; i < ids.length; i++) {
377
+ const id = ids[i];
378
+ const collection: EntityCollection | undefined = currentCollections!.find(c => c.id === id);
379
+ if (!collection)
380
+ throw Error(`Collection with id ${id} not found`);
381
+ paths.push(collection.path);
382
+ currentCollections = collection.subcollections;
276
383
  }
277
- , [getCollectionFromIds]);
384
+ return paths;
385
+ }, [getCollectionFromIds]);
278
386
 
279
- return useMemo(() => ({
280
- collections: collections ?? [],
281
- views: views ?? [],
387
+ return {
388
+ collections: collectionsRef.current,
389
+ views: viewsRef.current,
390
+ adminViews: adminViewsRef.current,
282
391
  loading: !initialised || navigationLoading,
283
392
  navigationLoadingError,
284
393
  homeUrl,
@@ -295,12 +404,11 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
295
404
  buildCMSUrlPath,
296
405
  resolveAliasesFrom,
297
406
  topLevelNavigation,
298
- baseLocation,
299
407
  refreshNavigation,
300
- getParentReferencesFromPath: getAllParentCollectionsForPath,
408
+ getParentReferencesFromPath: getAllParentReferencesForPath,
301
409
  getParentCollectionIds,
302
410
  convertIdsToPaths
303
- }), [baseCollectionPath, baseLocation, basePath, buildCMSUrlPath, buildUrlCollectionPath, buildUrlEditCollectionPath, collections, getAllParentCollectionsForPath, getCollection, getCollectionFromPaths, homeUrl, initialised, isUrlCollectionPath, navigationLoading, navigationLoadingError, refreshNavigation, resolveAliasesFrom, topLevelNavigation, urlPathToDataPath, views]);
411
+ };
304
412
  }
305
413
 
306
414
  export function getSidePanelKey(path: string, entityId?: string) {
@@ -320,8 +428,8 @@ function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[],
320
428
  return resolvedCollections
321
429
  .filter((c) => {
322
430
  if (!c.permissions) return true;
323
- const resolvedPermissions = resolvePermissions(c, authController, [c.path], null,)
324
- return resolvedPermissions.read !== false;
431
+ const resolvedPermissions = resolvePermissions(c, authController, c.path, null)
432
+ return resolvedPermissions?.read !== false;
325
433
  })
326
434
  .map((c) => {
327
435
  if (!c.subcollections) return c;
@@ -332,7 +440,11 @@ function filterOutNotAllowedCollections(resolvedCollections: EntityCollection[],
332
440
  });
333
441
  }
334
442
 
335
- async function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder<any>, authController: AuthController, dataSource: DataSourceDelegate, plugins?: FireCMSPlugin[]) {
443
+ async function resolveCollections(collections: undefined | EntityCollection[] | EntityCollectionsBuilder<any>,
444
+ collectionPermissions: PermissionsBuilder | undefined,
445
+ authController: AuthController,
446
+ dataSource: DataSourceDelegate,
447
+ injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {
336
448
  let resolvedCollections: EntityCollection[] = [];
337
449
  if (typeof collections === "function") {
338
450
  resolvedCollections = await collections({
@@ -344,15 +456,14 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
344
456
  resolvedCollections = collections;
345
457
  }
346
458
 
459
+ if (injectCollections) {
460
+ resolvedCollections = injectCollections(resolvedCollections ?? []);
461
+ }
462
+
463
+ resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
464
+
347
465
  resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
348
466
 
349
- if (plugins) {
350
- plugins.forEach((plugin: FireCMSPlugin) => {
351
- if (plugin.collections?.injectCollections) {
352
- resolvedCollections = plugin.collections?.injectCollections(resolvedCollections ?? []);
353
- }
354
- });
355
- }
356
467
  return resolvedCollections;
357
468
  }
358
469
 
@@ -369,3 +480,37 @@ async function resolveCMSViews(baseViews: CMSView[] | CMSViewsBuilder | undefine
369
480
  }
370
481
  return resolvedViews;
371
482
  }
483
+
484
+ function getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {
485
+ const trimmed = collectionOrView.group?.trim();
486
+ if (!trimmed || trimmed === "") {
487
+ return "Views";
488
+ }
489
+ return trimmed ?? "Views";
490
+ }
491
+
492
+ function areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {
493
+ if (a.length !== b.length) {
494
+ return false;
495
+ }
496
+ const aCopy = [...a];
497
+ const bCopy = [...b];
498
+ const aSorted = aCopy.sort((x, y) => x.id.localeCompare(y.id));
499
+ const bSorted = bCopy.sort((x, y) => x.id.localeCompare(y.id));
500
+ return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));
501
+ }
502
+
503
+ function areCollectionsEqual(a: EntityCollection, b: EntityCollection) {
504
+ const {
505
+ subcollections: subcollectionsA,
506
+ ...restA
507
+ } = a;
508
+ const {
509
+ subcollections: subcollectionsB,
510
+ ...restB
511
+ } = b;
512
+ if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {
513
+ return false;
514
+ }
515
+ return equal(removeFunctions(restA), removeFunctions(restB));
516
+ }
@@ -10,6 +10,7 @@ import { useUserConfigurationPersistence } from "./useUserConfigurationPersisten
10
10
  import { useDialogsController } from "./useDialogsController";
11
11
  import { useCustomizationController } from "./useCustomizationController";
12
12
  import { useAnalyticsController } from "./useAnalyticsController";
13
+ import React, { useEffect } from "react";
13
14
 
14
15
  /**
15
16
  * Hook to retrieve the {@link FireCMSContext}.
@@ -34,7 +35,7 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
34
35
  const customizationController = useCustomizationController();
35
36
  const analyticsController = useAnalyticsController();
36
37
 
37
- return {
38
+ const fireCMSContextRef = React.useRef<FireCMSContext<UserType, AuthControllerType>>({
38
39
  authController,
39
40
  sideDialogsController,
40
41
  sideEntityController,
@@ -46,6 +47,53 @@ export const useFireCMSContext = <UserType extends User = User, AuthControllerTy
46
47
  dialogsController,
47
48
  customizationController,
48
49
  analyticsController
49
- };
50
+ });
50
51
 
51
- };
52
+ useEffect(() => {
53
+ fireCMSContextRef.current = {
54
+ authController,
55
+ sideDialogsController,
56
+ sideEntityController,
57
+ navigation,
58
+ dataSource,
59
+ storageSource,
60
+ snackbarController,
61
+ userConfigPersistence,
62
+ dialogsController,
63
+ customizationController,
64
+ analyticsController
65
+ };
66
+ }, [authController, dialogsController, navigation, sideDialogsController]);
67
+
68
+ return fireCMSContextRef.current;
69
+ }
70
+
71
+ // export const useFireCMSContext = <UserType extends User = User, AuthControllerType extends AuthController<UserType> = AuthController<UserType>>(): FireCMSContext<UserType, AuthControllerType> => {
72
+ //
73
+ // const authController = useAuthController<UserType, AuthControllerType>();
74
+ // const sideDialogsController = useSideDialogsController();
75
+ // const sideEntityController = useSideEntityController();
76
+ // const navigation = useNavigationController();
77
+ // const dataSource = useDataSource();
78
+ // const storageSource = useStorageSource();
79
+ // const snackbarController = useSnackbarController();
80
+ // const userConfigPersistence = useUserConfigurationPersistence();
81
+ // const dialogsController = useDialogsController();
82
+ // const customizationController = useCustomizationController();
83
+ // const analyticsController = useAnalyticsController();
84
+ //
85
+ // return {
86
+ // authController,
87
+ // sideDialogsController,
88
+ // sideEntityController,
89
+ // navigation,
90
+ // dataSource,
91
+ // storageSource,
92
+ // snackbarController,
93
+ // userConfigPersistence,
94
+ // dialogsController,
95
+ // customizationController,
96
+ // analyticsController
97
+ // };
98
+ //
99
+ // };
@@ -22,13 +22,14 @@ const notifyListeners = () => {
22
22
  };
23
23
 
24
24
  // Listen to resize events once, at a global level
25
- window.addEventListener("resize", () => {
26
- const newIsLargeLayout = checkLargeLayout("lg");
27
- if (newIsLargeLayout !== isLargeLayoutGlobal) {
28
- isLargeLayoutGlobal = newIsLargeLayout;
29
- notifyListeners();
30
- }
31
- });
25
+ if (typeof window !== "undefined")
26
+ window.addEventListener("resize", () => {
27
+ const newIsLargeLayout = checkLargeLayout("lg");
28
+ if (newIsLargeLayout !== isLargeLayoutGlobal) {
29
+ isLargeLayoutGlobal = newIsLargeLayout;
30
+ notifyListeners();
31
+ }
32
+ });
32
33
 
33
34
  export const useLargeLayout = () => {
34
35
  const [isLargeLayout, setIsLargeLayout] = useState(isLargeLayoutGlobal);
@@ -58,6 +59,8 @@ export const useLargeLayout = () => {
58
59
  };
59
60
 
60
61
  function checkLargeLayout(breakpoint: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" = "lg"): boolean {
62
+ if (typeof window === "undefined")
63
+ return false;
61
64
  return window.matchMedia(`(min-width: ${breakpoints[breakpoint] + 1}px)`).matches;
62
65
  }
63
66