@firecms/core 3.0.0-canary.99 → 3.0.0-rc.2

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 (371) hide show
  1. package/README.md +2 -2
  2. package/dist/app/Drawer.d.ts +0 -1
  3. package/dist/app/Scaffold.d.ts +4 -0
  4. package/dist/components/ArrayContainer.d.ts +31 -12
  5. package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
  6. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +3 -1
  7. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  8. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  11. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  12. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  13. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  14. package/dist/components/EntityJsonPreview.d.ts +3 -0
  15. package/dist/components/EntityPreview.d.ts +8 -6
  16. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  17. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  18. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  19. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  20. package/dist/components/HomePage/NavigationGroup.d.ts +8 -1
  21. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  22. package/dist/components/PropertyConfigBadge.d.ts +2 -1
  23. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  24. package/dist/components/SelectableTable/SelectableTable.d.ts +13 -3
  25. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  26. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  27. package/dist/components/UserDisplay.d.ts +7 -0
  28. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -2
  29. package/dist/components/VirtualTable/fields/VirtualTableUserSelect.d.ts +12 -0
  30. package/dist/components/common/default_entity_actions.d.ts +0 -2
  31. package/dist/components/common/index.d.ts +1 -1
  32. package/dist/components/common/useColumnsIds.d.ts +1 -0
  33. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  34. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  35. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  36. package/dist/components/index.d.ts +3 -1
  37. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  38. package/dist/contexts/InternalUserManagementContext.d.ts +3 -0
  39. package/dist/core/DefaultAppBar.d.ts +8 -2
  40. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  41. package/dist/core/EntityEditView.d.ts +40 -22
  42. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  43. package/dist/core/FireCMS.d.ts +2 -3
  44. package/dist/core/FireCMSRouter.d.ts +4 -0
  45. package/dist/core/NavigationRoutes.d.ts +0 -1
  46. package/dist/core/SideDialogs.d.ts +4 -2
  47. package/dist/core/field_configs.d.ts +1 -1
  48. package/dist/core/index.d.ts +2 -1
  49. package/dist/form/EntityForm.d.ts +50 -0
  50. package/dist/form/EntityFormActions.d.ts +21 -0
  51. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  52. package/dist/form/components/FormEntry.d.ts +6 -0
  53. package/dist/form/components/FormLayout.d.ts +5 -0
  54. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  55. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  56. package/dist/form/components/index.d.ts +3 -1
  57. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  58. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  59. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  60. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  61. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  62. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  63. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  64. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  65. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  66. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  67. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  68. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  69. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -10
  70. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  71. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  72. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +12 -0
  73. package/dist/form/index.d.ts +17 -16
  74. package/dist/form/useClearRestoreValue.d.ts +2 -2
  75. package/dist/hooks/data/delete.d.ts +4 -4
  76. package/dist/hooks/data/save.d.ts +3 -3
  77. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  78. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  79. package/dist/hooks/index.d.ts +2 -0
  80. package/dist/hooks/useAuthController.d.ts +1 -1
  81. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  82. package/dist/hooks/useBuildNavigationController.d.ts +57 -12
  83. package/dist/hooks/useCollapsedGroups.d.ts +9 -0
  84. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  85. package/dist/hooks/useInternalUserManagementController.d.ts +12 -0
  86. package/dist/hooks/useModeController.d.ts +1 -2
  87. package/dist/hooks/useProjectLog.d.ts +7 -1
  88. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  89. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  90. package/dist/index.es.js +20480 -14434
  91. package/dist/index.es.js.map +1 -1
  92. package/dist/index.umd.js +20250 -14209
  93. package/dist/index.umd.js.map +1 -1
  94. package/dist/internal/useBuildDataSource.d.ts +3 -2
  95. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  96. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  97. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  98. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  99. package/dist/preview/components/ReferencePreview.d.ts +2 -2
  100. package/dist/preview/components/UserPreview.d.ts +8 -0
  101. package/dist/preview/index.d.ts +1 -0
  102. package/dist/preview/util.d.ts +3 -3
  103. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  104. package/dist/routes/FireCMSRoute.d.ts +1 -0
  105. package/dist/routes/HomePageRoute.d.ts +3 -0
  106. package/dist/types/analytics.d.ts +1 -1
  107. package/dist/types/auth.d.ts +7 -9
  108. package/dist/types/collections.d.ts +88 -25
  109. package/dist/types/customization_controller.d.ts +8 -0
  110. package/dist/types/datasource.d.ts +19 -17
  111. package/dist/types/dialogs_controller.d.ts +7 -3
  112. package/dist/types/entities.d.ts +7 -2
  113. package/dist/types/entity_actions.d.ts +58 -8
  114. package/dist/types/entity_callbacks.d.ts +16 -16
  115. package/dist/types/entity_overrides.d.ts +2 -2
  116. package/dist/types/export_import.d.ts +4 -4
  117. package/dist/types/fields.d.ts +43 -17
  118. package/dist/types/firecms.d.ts +31 -3
  119. package/dist/types/firecms_context.d.ts +17 -1
  120. package/dist/types/index.d.ts +1 -0
  121. package/dist/types/internal_user_management.d.ts +20 -0
  122. package/dist/types/navigation.d.ts +60 -17
  123. package/dist/types/permissions.d.ts +4 -4
  124. package/dist/types/plugins.d.ts +44 -9
  125. package/dist/types/properties.d.ts +74 -22
  126. package/dist/types/property_config.d.ts +1 -3
  127. package/dist/types/roles.d.ts +3 -0
  128. package/dist/types/side_dialogs_controller.d.ts +10 -0
  129. package/dist/types/side_entity_controller.d.ts +14 -1
  130. package/dist/types/storage.d.ts +75 -0
  131. package/dist/types/user.d.ts +2 -1
  132. package/dist/util/builders.d.ts +3 -3
  133. package/dist/util/callbacks.d.ts +2 -0
  134. package/dist/util/createFormexStub.d.ts +2 -0
  135. package/dist/util/entities.d.ts +2 -2
  136. package/dist/util/entity_actions.d.ts +2 -0
  137. package/dist/util/entity_cache.d.ts +23 -0
  138. package/dist/util/icon_synonyms.d.ts +0 -1
  139. package/dist/util/icons.d.ts +5 -2
  140. package/dist/util/index.d.ts +3 -0
  141. package/dist/util/navigation_from_path.d.ts +10 -1
  142. package/dist/util/navigation_utils.d.ts +13 -1
  143. package/dist/util/objects.d.ts +2 -1
  144. package/dist/util/permissions.d.ts +4 -4
  145. package/dist/util/property_utils.d.ts +4 -4
  146. package/dist/util/references.d.ts +2 -2
  147. package/dist/util/resolutions.d.ts +30 -6
  148. package/dist/util/storage.d.ts +1 -1
  149. package/dist/util/useStorageUploadController.d.ts +2 -2
  150. package/package.json +133 -125
  151. package/src/app/Drawer.tsx +0 -1
  152. package/src/app/Scaffold.tsx +33 -29
  153. package/src/components/ArrayContainer.tsx +447 -229
  154. package/src/components/CircularProgressCenter.tsx +1 -1
  155. package/src/components/ClearFilterSortButton.tsx +1 -1
  156. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +12 -11
  157. package/src/components/DeleteEntityDialog.tsx +13 -20
  158. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +59 -25
  159. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  160. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  161. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +47 -9
  162. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -16
  163. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +6 -12
  164. package/src/components/EntityCollectionTable/index.tsx +1 -1
  165. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +6 -6
  166. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +35 -26
  167. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
  168. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +132 -101
  169. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
  170. package/src/components/EntityCollectionView/EntityCollectionView.tsx +178 -85
  171. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +7 -4
  172. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  173. package/src/components/EntityCollectionView/utils.ts +19 -0
  174. package/src/components/EntityJsonPreview.tsx +66 -0
  175. package/src/components/EntityPreview.tsx +75 -57
  176. package/src/components/EntityView.tsx +8 -5
  177. package/src/components/ErrorView.tsx +3 -3
  178. package/src/components/FireCMSLogo.tsx +7 -51
  179. package/src/components/HomePage/DefaultHomePage.tsx +506 -161
  180. package/src/components/HomePage/FavouritesView.tsx +9 -14
  181. package/src/components/HomePage/HomePageDnD.tsx +600 -0
  182. package/src/components/HomePage/NavigationCard.tsx +47 -38
  183. package/src/components/HomePage/NavigationCardBinding.tsx +16 -15
  184. package/src/components/HomePage/NavigationGroup.tsx +144 -30
  185. package/src/components/HomePage/RenameGroupDialog.tsx +123 -0
  186. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  187. package/src/components/NotFoundPage.tsx +2 -2
  188. package/src/components/PropertyConfigBadge.tsx +10 -4
  189. package/src/components/PropertyIdCopyTooltip.tsx +47 -0
  190. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +22 -13
  191. package/src/components/SearchIconsView.tsx +2 -2
  192. package/src/components/SelectableTable/SelectableTable.tsx +154 -142
  193. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  194. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  195. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +60 -11
  196. package/src/components/UnsavedChangesDialog.tsx +46 -0
  197. package/src/components/UserDisplay.tsx +55 -0
  198. package/src/components/VirtualTable/VirtualTable.tsx +65 -44
  199. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -8
  200. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  201. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  202. package/src/components/VirtualTable/VirtualTableProps.tsx +12 -2
  203. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  204. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
  205. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -2
  206. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  207. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
  208. package/src/components/VirtualTable/fields/VirtualTableUserSelect.tsx +99 -0
  209. package/src/components/common/default_entity_actions.tsx +62 -42
  210. package/src/components/common/index.ts +1 -1
  211. package/src/components/common/useColumnsIds.tsx +2 -9
  212. package/src/components/common/useDataSourceTableController.tsx +420 -0
  213. package/src/components/common/useDebouncedCallback.tsx +20 -0
  214. package/src/components/common/useScrollRestoration.tsx +68 -0
  215. package/src/components/common/useTableSearchHelper.ts +1 -0
  216. package/src/components/index.tsx +4 -1
  217. package/src/contexts/BreacrumbsContext.tsx +38 -0
  218. package/src/contexts/DialogsProvider.tsx +3 -2
  219. package/src/contexts/InternalUserManagementContext.tsx +4 -0
  220. package/src/contexts/ModeController.tsx +1 -3
  221. package/src/contexts/SnackbarProvider.tsx +2 -0
  222. package/src/core/DefaultAppBar.tsx +124 -85
  223. package/src/core/DefaultDrawer.tsx +30 -22
  224. package/src/core/DrawerNavigationItem.tsx +32 -28
  225. package/src/core/EntityEditView.tsx +388 -995
  226. package/src/core/EntityEditViewFormActions.tsx +329 -0
  227. package/src/core/EntitySidePanel.tsx +88 -20
  228. package/src/core/FireCMS.tsx +58 -28
  229. package/src/core/FireCMSRouter.tsx +17 -0
  230. package/src/core/NavigationRoutes.tsx +23 -32
  231. package/src/core/SideDialogs.tsx +22 -12
  232. package/src/core/field_configs.tsx +39 -11
  233. package/src/core/index.tsx +4 -2
  234. package/src/form/EntityForm.tsx +814 -0
  235. package/src/form/EntityFormActions.tsx +211 -0
  236. package/src/form/PropertyFieldBinding.tsx +59 -41
  237. package/src/form/components/CustomIdField.tsx +9 -3
  238. package/src/form/components/FieldHelperText.tsx +1 -1
  239. package/src/form/components/FormEntry.tsx +22 -0
  240. package/src/form/components/FormLayout.tsx +16 -0
  241. package/src/form/components/LabelWithIcon.tsx +30 -19
  242. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  243. package/src/form/components/StorageItemPreview.tsx +5 -4
  244. package/src/form/components/StorageUploadProgress.tsx +2 -3
  245. package/src/form/components/index.tsx +3 -1
  246. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +30 -18
  247. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +47 -36
  248. package/src/form/field_bindings/BlockFieldBinding.tsx +55 -33
  249. package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -14
  250. package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -15
  251. package/src/form/field_bindings/MapFieldBinding.tsx +72 -62
  252. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +159 -0
  253. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -21
  254. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +10 -8
  255. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  256. package/src/form/field_bindings/ReferenceFieldBinding.tsx +28 -19
  257. package/src/form/field_bindings/RepeatFieldBinding.tsx +56 -32
  258. package/src/form/field_bindings/SelectFieldBinding.tsx +22 -13
  259. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +247 -168
  260. package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
  261. package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
  262. package/src/form/field_bindings/UserSelectFieldBinding.tsx +94 -0
  263. package/src/form/index.tsx +17 -37
  264. package/src/form/useClearRestoreValue.tsx +2 -2
  265. package/src/form/validation.ts +12 -6
  266. package/src/hooks/data/delete.ts +6 -5
  267. package/src/hooks/data/save.ts +26 -35
  268. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  269. package/src/hooks/data/useDataSource.tsx +10 -2
  270. package/src/hooks/data/useEntityFetch.tsx +10 -6
  271. package/src/hooks/index.tsx +3 -0
  272. package/src/hooks/useAuthController.tsx +1 -1
  273. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  274. package/src/hooks/useBrowserTitleAndIcon.tsx +1 -1
  275. package/src/hooks/useBuildModeController.tsx +15 -28
  276. package/src/hooks/useBuildNavigationController.tsx +386 -124
  277. package/src/hooks/useCollapsedGroups.ts +64 -0
  278. package/src/hooks/useFireCMSContext.tsx +9 -35
  279. package/src/hooks/useInternalUserManagementController.tsx +16 -0
  280. package/src/hooks/useLargeLayout.tsx +0 -35
  281. package/src/hooks/useModeController.tsx +1 -2
  282. package/src/hooks/useProjectLog.tsx +16 -5
  283. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  284. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  285. package/src/internal/useBuildDataSource.ts +67 -80
  286. package/src/internal/useBuildSideDialogsController.tsx +4 -2
  287. package/src/internal/useBuildSideEntityController.tsx +149 -86
  288. package/src/internal/useUnsavedChangesDialog.tsx +127 -91
  289. package/src/preview/PropertyPreview.tsx +36 -12
  290. package/src/preview/PropertyPreviewProps.tsx +1 -1
  291. package/src/preview/components/BooleanPreview.tsx +1 -1
  292. package/src/preview/components/EmptyValue.tsx +1 -1
  293. package/src/preview/components/EnumValuesChip.tsx +1 -1
  294. package/src/preview/components/ImagePreview.tsx +10 -9
  295. package/src/preview/components/ReferencePreview.tsx +10 -18
  296. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  297. package/src/preview/components/UserPreview.tsx +27 -0
  298. package/src/preview/index.ts +1 -0
  299. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +6 -5
  300. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +5 -4
  301. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +5 -3
  302. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  303. package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -4
  304. package/src/preview/property_previews/ArrayPropertyPreview.tsx +6 -4
  305. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  306. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +13 -13
  307. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  308. package/src/preview/util.ts +10 -10
  309. package/src/routes/CustomCMSRoute.tsx +21 -0
  310. package/src/routes/FireCMSRoute.tsx +246 -0
  311. package/src/routes/HomePageRoute.tsx +17 -0
  312. package/src/types/analytics.ts +3 -0
  313. package/src/types/auth.tsx +8 -12
  314. package/src/types/collections.ts +103 -28
  315. package/src/types/customization_controller.tsx +9 -0
  316. package/src/types/datasource.ts +21 -20
  317. package/src/types/dialogs_controller.tsx +7 -3
  318. package/src/types/entities.ts +10 -2
  319. package/src/types/entity_actions.tsx +71 -8
  320. package/src/types/entity_callbacks.ts +18 -18
  321. package/src/types/entity_overrides.tsx +2 -2
  322. package/src/types/export_import.ts +4 -4
  323. package/src/types/fields.tsx +52 -19
  324. package/src/types/firecms.tsx +34 -4
  325. package/src/types/firecms_context.tsx +18 -1
  326. package/src/types/index.ts +1 -0
  327. package/src/types/internal_user_management.ts +24 -0
  328. package/src/types/navigation.ts +76 -22
  329. package/src/types/permissions.ts +5 -5
  330. package/src/types/plugins.tsx +53 -9
  331. package/src/types/properties.ts +84 -22
  332. package/src/types/property_config.tsx +2 -2
  333. package/src/types/roles.ts +3 -0
  334. package/src/types/side_dialogs_controller.tsx +15 -0
  335. package/src/types/side_entity_controller.tsx +16 -1
  336. package/src/types/storage.ts +82 -0
  337. package/src/types/user.ts +3 -1
  338. package/src/util/builders.ts +10 -8
  339. package/src/util/callbacks.ts +119 -0
  340. package/src/util/createFormexStub.tsx +62 -0
  341. package/src/util/entities.ts +6 -4
  342. package/src/util/entity_actions.ts +28 -0
  343. package/src/util/entity_cache.ts +204 -0
  344. package/src/util/icon_list.ts +1 -1
  345. package/src/util/icon_synonyms.ts +0 -1
  346. package/src/util/icons.tsx +36 -11
  347. package/src/util/index.ts +3 -0
  348. package/src/util/join_collections.ts +9 -2
  349. package/src/util/make_properties_editable.ts +13 -5
  350. package/src/util/navigation_from_path.ts +33 -12
  351. package/src/util/navigation_utils.ts +135 -19
  352. package/src/util/objects.ts +74 -14
  353. package/src/util/parent_references_from_path.ts +3 -3
  354. package/src/util/permissions.ts +8 -8
  355. package/src/util/property_utils.tsx +17 -6
  356. package/src/util/references.ts +19 -8
  357. package/src/util/resolutions.ts +93 -24
  358. package/src/util/storage.ts +6 -2
  359. package/src/util/useStorageUploadController.tsx +74 -29
  360. package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
  361. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  362. package/dist/form/PropertiesForm.d.ts +0 -8
  363. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  364. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  365. package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
  366. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  367. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  368. package/src/form/PropertiesForm.tsx +0 -81
  369. package/src/form/components/FormikArrayContainer.tsx +0 -44
  370. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
  371. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -1,45 +1,42 @@
1
- import React, { useCallback, useEffect, useRef, useState } from "react";
2
-
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import Fuse from "fuse.js";
3
+ import { Container, SearchBar } from "@firecms/ui";
3
4
  import { useCustomizationController, useFireCMSContext, useNavigationController } from "../../hooks";
5
+ import { useCollapsedGroups } from "../../hooks/useCollapsedGroups";
4
6
  import {
5
7
  CMSAnalyticsEvent,
8
+ NavigationEntry,
9
+ NavigationGroupMapping,
6
10
  PluginGenericProps,
7
- PluginHomePageAdditionalCardsProps,
8
- TopNavigationEntry
11
+ PluginHomePageAdditionalCardsProps
9
12
  } from "../../types";
10
-
11
13
  import { toArray } from "../../util/arrays";
12
- import { NavigationGroup } from "./NavigationGroup";
13
- import { NavigationCardBinding } from "./NavigationCardBinding";
14
-
15
- import Fuse from "fuse.js"
16
-
17
- import { Container, SearchBar } from "@firecms/ui";
18
14
  import { FavouritesView } from "./FavouritesView";
19
15
  import { useRestoreScroll } from "../../internal/useRestoreScroll";
16
+ import { NavigationGroup } from "./NavigationGroup";
17
+ import {
18
+ NavigationGroupDroppable,
19
+ NewGroupDropZone,
20
+ SortableNavigationCard,
21
+ SortableNavigationGroup,
22
+ useHomePageDnd
23
+ } from "./HomePageDnD";
24
+ import { DndContext, DragOverlay, MeasuringStrategy } from "@dnd-kit/core";
25
+ import { NavigationCardBinding } from "./NavigationCardBinding";
26
+ import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
27
+ import { restrictToVerticalAxis, restrictToWindowEdges } from "@dnd-kit/modifiers";
28
+ import { RenameGroupDialog } from "./RenameGroupDialog";
20
29
 
21
- /**
22
- * Default entry view for the CMS. This component renders navigation cards
23
- * for each collection defined in the navigation.
30
+ export const DEFAULT_GROUP_NAME = "Views";
31
+ export const ADMIN_GROUP_NAME = "Admin";
24
32
 
25
- * @group Components
26
- */
27
33
  export function DefaultHomePage({
28
34
  additionalActions,
29
35
  additionalChildrenStart,
30
36
  additionalChildrenEnd
31
37
  }: {
32
- /**
33
- * Additional actions to be rendered in the home page, close to the search bar.
34
- */
35
38
  additionalActions?: React.ReactNode;
36
- /**
37
- * Additional children to be rendered in the beginning of the home page.
38
- */
39
39
  additionalChildrenStart?: React.ReactNode;
40
- /**
41
- * Additional children to be rendered at the end of the home page.
42
- */
43
40
  additionalChildrenEnd?: React.ReactNode;
44
41
  }) {
45
42
 
@@ -47,177 +44,525 @@ export function DefaultHomePage({
47
44
  const customizationController = useCustomizationController();
48
45
  const navigationController = useNavigationController();
49
46
 
50
- const fuse = useRef<Fuse<TopNavigationEntry> | null>(null);
51
-
52
47
  if (!navigationController.topLevelNavigation)
53
- throw Error("Navigation not ready in FireCMSHomePage");
48
+ throw Error("Navigation not ready");
54
49
 
55
50
  const {
56
- containerRef,
57
- scroll,
58
- direction
59
- } = useRestoreScroll();
60
-
61
- const {
62
- navigationEntries,
63
- groups
51
+ allowDragAndDrop,
52
+ navigationEntries: rawNavigationEntries,
53
+ groups: groupOrderFromNavController,
54
+ onNavigationEntriesUpdate
64
55
  } = navigationController.topLevelNavigation;
65
56
 
57
+ const fuse = useRef<Fuse<NavigationEntry> | null>(null);
66
58
  const [filteredUrls, setFilteredUrls] = useState<string[] | null>(null);
59
+ const performingSearch = Boolean(filteredUrls);
67
60
 
68
- const filteredNavigationEntries = filteredUrls
69
- ? navigationEntries.filter((entry) => filteredUrls.includes(entry.url))
70
- : navigationEntries;
61
+ // Memoize filtered navigation entries to prevent unnecessary recalculations
62
+ const filteredNavigationEntries = useMemo(() => {
63
+ return filteredUrls
64
+ ? rawNavigationEntries.filter((e) => filteredUrls.includes(e.url))
65
+ : rawNavigationEntries;
66
+ }, [filteredUrls, rawNavigationEntries]);
71
67
 
72
68
  useEffect(() => {
73
- fuse.current = new Fuse(navigationEntries, {
74
- keys: ["name",
75
- "description",
76
- "group",
77
- "path"
78
- ]
69
+ fuse.current = new Fuse(rawNavigationEntries, {
70
+ keys: ["name", "description", "group", "path"]
79
71
  });
80
- }, [navigationEntries]);
81
-
82
- const updateSearchResults = useCallback(
83
- (value?: string) => {
84
- if (!value || value === "") {
85
- setFilteredUrls(null);
86
- } else {
87
- const searchResult = fuse.current?.search(value);
88
- console.log("Search result", searchResult);
89
- if (searchResult) {
90
- setFilteredUrls(searchResult.map((e) => e.item.url));
91
- }
72
+ }, [rawNavigationEntries]);
73
+
74
+ const updateSearch = useCallback((v?: string) => {
75
+ if (!v?.trim()) {
76
+ setFilteredUrls(null);
77
+ return;
78
+ }
79
+ const results = fuse.current?.search(v.trim());
80
+ setFilteredUrls(results ? results.map((x) => x.item.url) : []);
81
+ }, []);
82
+
83
+ /* ───────────────────────────────────────────────────────────────
84
+ Build groups (all items) + isolate Admin
85
+ ─────────────────────────────────────────────────────────────── */
86
+ const [items, setItems] = useState<
87
+ { name: string; entries: NavigationEntry[] }[]
88
+ >([]);
89
+ const [adminGroupData, setAdminGroupData] = useState<{
90
+ name: string;
91
+ entries: NavigationEntry[];
92
+ } | null>(null);
93
+
94
+ // Memoize the processed groups to avoid unnecessary recalculations
95
+ const processedGroups = useMemo(() => {
96
+ const src = filteredNavigationEntries;
97
+ const entriesByGroup: Record<string, NavigationEntry[]> = {};
98
+
99
+ src.forEach((e) => {
100
+ const g =
101
+ e.type === "admin"
102
+ ? ADMIN_GROUP_NAME
103
+ : e.group ?? DEFAULT_GROUP_NAME;
104
+ (entriesByGroup[g] ??= []).push(e);
105
+ });
106
+
107
+ // Check if there are custom actions from plugins that should show in the default group
108
+ const hasPluginAdditionalCards = customizationController.plugins?.some(p => p.homePage?.AdditionalCards);
109
+
110
+ let allProcessed: { name: string; entries: NavigationEntry[] }[];
111
+
112
+ if (performingSearch) {
113
+ const ordered = [
114
+ ...new Set(src.map((e) => e.group ?? DEFAULT_GROUP_NAME))
115
+ ];
116
+ allProcessed = ordered
117
+ .map((name) => ({
118
+ name,
119
+ entries: entriesByGroup[name] || []
120
+ }))
121
+ .filter((g) => g.entries.length);
122
+ } else {
123
+ allProcessed = groupOrderFromNavController.map((g) => ({
124
+ name: g,
125
+ entries: entriesByGroup[g] || []
126
+ }));
127
+ Object.keys(entriesByGroup).forEach((g) => {
128
+ if (!groupOrderFromNavController.includes(g))
129
+ allProcessed.push({
130
+ name: g,
131
+ entries: entriesByGroup[g]
132
+ });
133
+ });
134
+
135
+ // Ensure default group exists if there are plugin additional cards but no collections
136
+ if (hasPluginAdditionalCards && !allProcessed.some(g => g.name === DEFAULT_GROUP_NAME)) {
137
+ allProcessed.push({
138
+ name: DEFAULT_GROUP_NAME,
139
+ entries: []
140
+ });
92
141
  }
93
- }, []);
94
142
 
95
- const allGroups: Array<string | undefined> = [...groups];
96
- if (filteredNavigationEntries.filter(e => !e.group).length > 0 || filteredNavigationEntries.length === 0) {
97
- allGroups.push(undefined);
98
- }
143
+ allProcessed = allProcessed.filter(
144
+ (g) =>
145
+ g.entries.length ||
146
+ groupOrderFromNavController.includes(g.name) ||
147
+ (g.name === DEFAULT_GROUP_NAME && hasPluginAdditionalCards)
148
+ );
149
+ }
150
+
151
+ const admin = allProcessed.find((g) => g.name === ADMIN_GROUP_NAME);
152
+ return {
153
+ adminGroupData: admin || null,
154
+ items: allProcessed.filter((g) => g.name !== ADMIN_GROUP_NAME)
155
+ };
156
+ }, [filteredNavigationEntries, performingSearch, groupOrderFromNavController, customizationController.plugins]);
157
+
158
+ // Update state only when processedGroups actually changes
159
+ useEffect(() => {
160
+ setAdminGroupData(processedGroups.adminGroupData);
161
+ setItems(processedGroups.items);
162
+ }, [processedGroups]);
163
+
164
+ /* ───────────────────────────────────────────────────────────────
165
+ Local update vs. persistence helpers
166
+ ─────────────────────────────────────────────────────────────── */
167
+ const updateItems = (
168
+ updater:
169
+ | { name: string; entries: NavigationEntry[] }[]
170
+ | ((
171
+ prev: { name: string; entries: NavigationEntry[] }[]
172
+ ) => { name: string; entries: NavigationEntry[] }[])
173
+ ) => {
174
+ setItems(updater); // local only
175
+ };
176
+
177
+ const persistNavigationGroups = (
178
+ latest: { name: string; entries: NavigationEntry[] }[]
179
+ ) => {
180
+ const draggable: NavigationGroupMapping[] = latest.map((g) => ({
181
+ name: g.name,
182
+ entries: g.entries.map((e) => e.path)
183
+ }));
99
184
 
185
+ const all: NavigationGroupMapping[] = adminGroupData
186
+ ? [
187
+ ...draggable,
188
+ {
189
+ name: adminGroupData.name,
190
+ entries: adminGroupData.entries.map((e) => e.path)
191
+ }
192
+ ]
193
+ : draggable;
194
+
195
+ onNavigationEntriesUpdate(all);
196
+ };
197
+
198
+ // Use custom hook for collapsed groups with localStorage persistence
199
+ const groupNames = useMemo(() => [
200
+ ...items.map(item => item.name),
201
+ ...(adminGroupData ? [adminGroupData.name] : [])
202
+ ], [items, adminGroupData]);
203
+
204
+ const { isGroupCollapsed, toggleGroupCollapsed } = useCollapsedGroups(groupNames);
205
+
206
+
207
+ const {
208
+ sensors,
209
+ collisionDetection,
210
+ onDragStart,
211
+ onDragOver,
212
+ onDragEnd,
213
+ dropAnimation,
214
+ activeItemForOverlay,
215
+ activeGroupData,
216
+ draggingGroupId,
217
+ containers,
218
+ dndKitActiveNode,
219
+ onDragCancel,
220
+ isDraggingCardOnly,
221
+ dialogOpenForGroup,
222
+ setDialogOpenForGroup,
223
+ handleRenameGroup,
224
+ isHoveringNewGroupDropZone,
225
+ setIsHoveringNewGroupDropZone
226
+ } = useHomePageDnd({
227
+ items,
228
+ setItems: updateItems,
229
+ disabled: !allowDragAndDrop || performingSearch,
230
+ onPersist: persistNavigationGroups, // ——► persistence here
231
+ onGroupMoved: (g) =>
232
+ context.analyticsController?.onAnalyticsEvent?.("home_move_group", {
233
+ name: g
234
+ }),
235
+ onCardMovedBetweenGroups: (card) =>
236
+ context.analyticsController?.onAnalyticsEvent?.("home_move_card", {
237
+ id: card.id
238
+ }),
239
+ onNewGroupDrop: () =>
240
+ context.analyticsController?.onAnalyticsEvent?.(
241
+ "home_drop_new_group"
242
+ )
243
+ });
244
+
245
+ const {
246
+ containerRef,
247
+ direction
248
+ } = useRestoreScroll();
249
+
250
+ const dndDisabled = !allowDragAndDrop || performingSearch;
251
+
252
+ const dndModifiers = dndKitActiveNode?.data.current?.type === "group"
253
+ ? [restrictToVerticalAxis, restrictToWindowEdges]
254
+ : [restrictToWindowEdges];
255
+
256
+ /* ───────────────────────────────────────────────────────────────
257
+ Plugin extras
258
+ ─────────────────────────────────────────────────────────────── */
100
259
  let additionalPluginChildrenStart: React.ReactNode | undefined;
101
260
  let additionalPluginChildrenEnd: React.ReactNode | undefined;
102
261
  let additionalPluginSections: React.ReactNode | undefined;
262
+
103
263
  if (customizationController.plugins) {
104
- const sectionProps: PluginGenericProps = {
105
- context
106
- };
107
- additionalPluginSections = <>
108
- {customizationController.plugins.filter(plugin => plugin.homePage?.includeSection)
109
- .map((plugin, i) => {
110
- const section = plugin.homePage!.includeSection!(sectionProps)
111
- return (
112
- <NavigationGroup
113
- group={section.title}
114
- key={`plugin_section_${plugin.key}`}>
115
- {section.children}
116
- </NavigationGroup>
117
- );
118
- })}
119
- </>;
120
- additionalPluginChildrenStart = <div className={"flex flex-col gap-2"}>
121
- {customizationController.plugins.filter(plugin => plugin.homePage?.additionalChildrenStart)
122
- .map((plugin, i) => {
123
- return <div key={`plugin_children_start_${i}`}>{plugin.homePage!.additionalChildrenStart}</div>;
124
- })}
125
- </div>;
126
-
127
- additionalPluginChildrenEnd = <div className={"flex flex-col gap-2"}>
128
- {customizationController.plugins.filter(plugin => plugin.homePage?.additionalChildrenEnd)
129
- .map((plugin, i) => {
130
- return <div key={`plugin_children_start_${i}`}>{plugin.homePage!.additionalChildrenEnd}</div>;
131
- })}
132
- </div>;
264
+ const sectionProps: PluginGenericProps = { context };
265
+
266
+ additionalPluginSections = (
267
+ <>
268
+ {customizationController.plugins
269
+ .filter((p) => p.homePage?.includeSection)
270
+ .map((plugin) => {
271
+ const section = plugin.homePage!.includeSection!(
272
+ sectionProps
273
+ );
274
+ return (
275
+ <NavigationGroup
276
+ group={section.title}
277
+ key={`plugin_section_${plugin.key}`}
278
+ >
279
+ {section.children}
280
+ </NavigationGroup>
281
+ );
282
+ })}
283
+ </>
284
+ );
285
+
286
+ additionalPluginChildrenStart = (
287
+ <div className="flex flex-col gap-2">
288
+ {customizationController.plugins
289
+ .filter((p) => p.homePage?.additionalChildrenStart)
290
+ .map((plugin, i) => (
291
+ <div key={`plugin_children_start_${i}`}>
292
+ {plugin.homePage!.additionalChildrenStart}
293
+ </div>
294
+ ))}
295
+ </div>
296
+ );
297
+
298
+ additionalPluginChildrenEnd = (
299
+ <div className="flex flex-col gap-2">
300
+ {customizationController.plugins
301
+ .filter((p) => p.homePage?.additionalChildrenEnd)
302
+ .map((plugin, i) => (
303
+ <div key={`plugin_children_end_${i}`}>
304
+ {plugin.homePage!.additionalChildrenEnd}
305
+ </div>
306
+ ))}
307
+ </div>
308
+ );
133
309
  }
134
310
 
311
+ /* ───────────────────────────────────────────────────────────────
312
+ Render
313
+ ─────────────────────────────────────────────────────────────── */
135
314
  return (
136
- <div id="home_page"
137
- ref={containerRef}
138
- className="py-2 overflow-auto h-full w-full">
139
- <Container maxWidth={"6xl"}>
315
+ <div ref={containerRef} className="py-2 overflow-auto h-full w-full">
316
+ <Container maxWidth="6xl">
317
+ {/* search & actions */}
140
318
  <div
141
319
  className="w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4"
142
- style={{ top: direction === "down" ? -84 : 0 }}>
143
- <SearchBar onTextSearch={updateSearchResults}
144
- placeholder={"Search collections"}
145
- large={false}
146
- innerClassName={"w-full"}
147
- className={"w-full flex-grow"}/>
320
+ style={{ top: direction === "down" ? -84 : 0 }}
321
+ >
322
+ <SearchBar
323
+ onTextSearch={updateSearch}
324
+ placeholder="Search collections"
325
+ autoFocus
326
+ innerClassName="w-full"
327
+ className="w-full flex-grow"
328
+ />
148
329
  {additionalActions}
149
330
  </div>
150
331
 
151
- <FavouritesView hidden={Boolean(filteredUrls)}/>
332
+ <FavouritesView hidden={performingSearch}/>
152
333
 
153
334
  {additionalChildrenStart}
154
-
155
335
  {additionalPluginChildrenStart}
156
336
 
157
- {allGroups.map((group, index) => {
158
-
159
- const AdditionalCards: React.ComponentType<PluginHomePageAdditionalCardsProps>[] = [];
160
- const actionProps: PluginHomePageAdditionalCardsProps = {
161
- group,
162
- context
163
- };
164
-
165
- if (customizationController.plugins) {
166
- customizationController.plugins.forEach(plugin => {
167
- if (plugin.homePage?.AdditionalCards) {
168
- AdditionalCards.push(...toArray(plugin.homePage?.AdditionalCards));
169
- }
170
- });
171
- }
172
-
173
- const thisGroupCollections = filteredNavigationEntries
174
- .filter((entry) => entry.group === group || (!entry.group && group === undefined));
175
- if (thisGroupCollections.length === 0 && AdditionalCards.length === 0)
176
- return null;
177
- return (
178
- <NavigationGroup
179
- group={group}
180
- key={`plugin_section_${group}`}>
181
-
182
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
183
- {thisGroupCollections.map((entry) => (
184
- <div key={`nav_${entry.group}_${entry.name}`} className="col-span-1">
185
- <NavigationCardBinding
186
- {...entry}
187
- onClick={() => {
188
- let event: CMSAnalyticsEvent;
189
- if (entry.type === "collection") {
190
- event = "home_navigate_to_collection";
191
- } else if (entry.type === "view") {
192
- event = "home_navigate_to_view";
193
- } else if (entry.type === "admin") {
194
- event = "home_navigate_to_admin_view";
195
- } else {
196
- event = "unmapped_event";
197
- }
198
- context.analyticsController?.onAnalyticsEvent?.(event, { path: entry.path });
199
- }}
200
- />
201
- </div>
202
- ))}
203
- {group?.toLowerCase() !== "admin" && AdditionalCards &&
204
- AdditionalCards.map((AdditionalCard, i) => (
205
- <div key={`nav_${group}_add_${i}`}>
206
- <AdditionalCard {...actionProps} />
207
- </div>
208
- ))}
337
+ {/* ─────── DND context ─────── */}
338
+ <DndContext
339
+ sensors={sensors}
340
+ collisionDetection={collisionDetection}
341
+ measuring={{
342
+ droppable: {
343
+ strategy: MeasuringStrategy.Always,
344
+ frequency: 500
345
+ }
346
+ }}
347
+ onDragStart={onDragStart}
348
+ onDragOver={onDragOver}
349
+ onDragEnd={onDragEnd}
350
+ onDragCancel={onDragCancel}
351
+ modifiers={dndModifiers}
352
+ >
353
+ <SortableContext
354
+ key={JSON.stringify(containers)}
355
+ items={containers}
356
+ strategy={verticalListSortingStrategy}
357
+ >
358
+ {items.map((groupData) => {
359
+ const groupKey = groupData.name;
360
+ const entriesInGroup = groupData.entries;
361
+
362
+ const AdditionalCards: React.ComponentType<PluginHomePageAdditionalCardsProps>[] =
363
+ [];
364
+ customizationController.plugins?.forEach((p) => {
365
+ if (p.homePage?.AdditionalCards)
366
+ AdditionalCards.push(
367
+ ...toArray(p.homePage.AdditionalCards)
368
+ );
369
+ });
370
+
371
+ const actionProps: PluginHomePageAdditionalCardsProps = {
372
+ group:
373
+ groupKey === DEFAULT_GROUP_NAME
374
+ ? undefined
375
+ : groupKey,
376
+ context
377
+ };
378
+
379
+ if (
380
+ entriesInGroup.length === 0 &&
381
+ (AdditionalCards.length === 0 || performingSearch) &&
382
+ !groupOrderFromNavController.includes(groupKey)
383
+ )
384
+ return null;
385
+
386
+ return (
387
+ <SortableNavigationGroup
388
+ key={groupKey}
389
+ groupName={groupKey}
390
+ disabled={dndDisabled}
391
+ >
392
+ <NavigationGroup
393
+ group={
394
+ groupKey === DEFAULT_GROUP_NAME
395
+ ? undefined
396
+ : groupKey
397
+ }
398
+ minimised={
399
+ draggingGroupId === groupKey &&
400
+ !isDraggingCardOnly
401
+ }
402
+ isPotentialCardDropTarget={
403
+ isDraggingCardOnly
404
+ }
405
+ dndDisabled={dndDisabled}
406
+ onEditGroup={() => {
407
+ if (dndDisabled) return;
408
+ setDialogOpenForGroup(groupKey);
409
+ }}
410
+ collapsed={isGroupCollapsed(groupKey)}
411
+ onToggleCollapsed={() => toggleGroupCollapsed(groupKey)}
412
+ >
413
+ <NavigationGroupDroppable
414
+ id={groupKey}
415
+ itemIds={entriesInGroup.map(
416
+ (e) => e.url
417
+ )}
418
+ isPotentialCardDropTarget={
419
+ isDraggingCardOnly
420
+ }
421
+ >
422
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ">
423
+ {entriesInGroup.map(
424
+ (entry) => (
425
+ <SortableNavigationCard
426
+ key={entry.url}
427
+ entry={entry}
428
+ onClick={() => {
429
+ let event: CMSAnalyticsEvent =
430
+ "unmapped_event";
431
+ if (
432
+ entry.type ===
433
+ "collection"
434
+ )
435
+ event =
436
+ "home_navigate_to_collection";
437
+ else if (
438
+ entry.type ===
439
+ "view"
440
+ )
441
+ event =
442
+ "home_navigate_to_view";
443
+ else if (
444
+ entry.type ===
445
+ "admin"
446
+ )
447
+ event =
448
+ "home_navigate_to_admin_view";
449
+
450
+ context.analyticsController?.onAnalyticsEvent?.(
451
+ event,
452
+ {
453
+ path: entry.path
454
+ }
455
+ );
456
+ }}
457
+ />
458
+ )
459
+ )}
460
+ {!performingSearch &&
461
+ groupKey.toLowerCase() !==
462
+ ADMIN_GROUP_NAME.toLowerCase() &&
463
+ AdditionalCards.map(
464
+ (C, i) => (
465
+ <C
466
+ key={`extra_${groupKey}_${i}`}
467
+ {...actionProps}
468
+ />
469
+ )
470
+ )}
471
+ </div>
472
+ </NavigationGroupDroppable>
473
+ </NavigationGroup>
474
+ </SortableNavigationGroup>
475
+ );
476
+ })}
477
+ </SortableContext>
478
+
479
+ <NewGroupDropZone
480
+ disabled={dndDisabled}
481
+ setIsHovering={setIsHoveringNewGroupDropZone}
482
+ />
483
+
484
+ <DragOverlay adjustScale={false} dropAnimation={dropAnimation}>
485
+ {activeGroupData &&
486
+ draggingGroupId === activeGroupData.name ? (
487
+ <div
488
+ className="rounded-lg bg-transparent"
489
+ style={{
490
+ padding: 0,
491
+ margin: 0
492
+ }}
493
+ >
494
+ <NavigationGroup
495
+ group={
496
+ activeGroupData.name ===
497
+ DEFAULT_GROUP_NAME
498
+ ? undefined
499
+ : activeGroupData.name
500
+ }
501
+ isPreview={false}
502
+ minimised
503
+ />
209
504
  </div>
210
- </NavigationGroup>
211
- );
212
- })}
505
+ ) : activeItemForOverlay ? (
506
+ <NavigationCardBinding
507
+ {...activeItemForOverlay}
508
+ shrink={isHoveringNewGroupDropZone}
509
+ />
510
+ ) : null}
511
+ </DragOverlay>
512
+ </DndContext>
213
513
 
214
- {additionalPluginSections}
514
+ {!performingSearch && adminGroupData && (
515
+ <NavigationGroup
516
+ group={adminGroupData.name}
517
+ collapsed={isGroupCollapsed(adminGroupData.name)}
518
+ onToggleCollapsed={() => toggleGroupCollapsed(adminGroupData.name)}
519
+ >
520
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ">
521
+ {adminGroupData.entries.map((entry) => (
522
+ <NavigationCardBinding
523
+ key={entry.url}
524
+ {...entry}
525
+ onClick={() => {
526
+ let event: CMSAnalyticsEvent =
527
+ "unmapped_event";
528
+ if (entry.type === "collection")
529
+ event =
530
+ "home_navigate_to_collection";
531
+ else if (entry.type === "view")
532
+ event = "home_navigate_to_view";
533
+ else if (entry.type === "admin")
534
+ event =
535
+ "home_navigate_to_admin_view";
215
536
 
216
- {additionalPluginChildrenEnd}
537
+ context.analyticsController?.onAnalyticsEvent?.(
538
+ event,
539
+ { path: entry.path }
540
+ );
541
+ }}
542
+ />
543
+ ))}
544
+ </div>
545
+ </NavigationGroup>
546
+ )}
217
547
 
548
+ {additionalPluginSections}
549
+ {additionalPluginChildrenEnd}
218
550
  {additionalChildrenEnd}
219
-
220
551
  </Container>
552
+
553
+ {dialogOpenForGroup && (
554
+ <RenameGroupDialog
555
+ open
556
+ initialName={dialogOpenForGroup}
557
+ existingGroupNames={items
558
+ .map((g) => g.name)
559
+ .filter((n) => n !== dialogOpenForGroup)}
560
+ onClose={() => setDialogOpenForGroup(null)}
561
+ onRename={(newName) => {
562
+ handleRenameGroup(dialogOpenForGroup, newName);
563
+ }}
564
+ />
565
+ )}
221
566
  </div>
222
567
  );
223
568
  }