@firecms/core 3.0.0-canary.2 → 3.0.0-canary.200

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 (409) hide show
  1. package/README.md +4 -4
  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 +23 -6
  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 -13
  12. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +3 -3
  13. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +22 -6
  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 +1 -1
  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 +7 -4
  21. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +17 -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/PropertyConfigBadge.d.ts +2 -1
  35. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  36. package/dist/components/ReferenceWidget.d.ts +6 -4
  37. package/dist/components/SelectableTable/SelectableTable.d.ts +13 -3
  38. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  39. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  40. package/dist/components/VirtualTable/VirtualTableProps.d.ts +29 -13
  41. package/dist/components/VirtualTable/types.d.ts +3 -3
  42. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -3
  43. package/dist/components/common/index.d.ts +2 -1
  44. package/dist/components/common/table_height.d.ts +5 -0
  45. package/dist/components/common/types.d.ts +4 -6
  46. package/dist/components/common/useColumnsIds.d.ts +3 -1
  47. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +13 -2
  48. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  49. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  50. package/dist/components/index.d.ts +8 -5
  51. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  52. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  53. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
  54. package/dist/core/DefaultDrawer.d.ts +19 -0
  55. package/dist/core/DrawerNavigationItem.d.ts +10 -0
  56. package/dist/core/EntityEditView.d.ts +44 -0
  57. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  58. package/dist/core/FireCMS.d.ts +2 -2
  59. package/dist/core/FireCMSRouter.d.ts +4 -0
  60. package/dist/core/NavigationRoutes.d.ts +2 -3
  61. package/dist/core/SideDialogs.d.ts +4 -2
  62. package/dist/core/index.d.ts +4 -6
  63. package/dist/form/EntityForm.d.ts +45 -69
  64. package/dist/form/EntityFormActions.d.ts +17 -0
  65. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  66. package/dist/form/components/ErrorFocus.d.ts +1 -1
  67. package/dist/form/components/FieldHelperText.d.ts +3 -3
  68. package/dist/form/components/FormEntry.d.ts +6 -0
  69. package/dist/form/components/FormLayout.d.ts +5 -0
  70. package/dist/{components → form/components}/LabelWithIcon.d.ts +1 -1
  71. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  72. package/dist/form/components/StorageItemPreview.d.ts +4 -3
  73. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  74. package/dist/form/components/index.d.ts +4 -1
  75. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  76. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  77. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  78. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  79. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  80. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  81. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  82. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  83. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  84. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  85. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  86. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +3 -4
  87. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  88. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  89. package/dist/form/index.d.ts +17 -18
  90. package/dist/form/useClearRestoreValue.d.ts +2 -2
  91. package/dist/form/validation.d.ts +1 -1
  92. package/dist/hooks/data/delete.d.ts +4 -4
  93. package/dist/hooks/data/save.d.ts +4 -5
  94. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  95. package/dist/hooks/data/useDataSource.d.ts +2 -2
  96. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  97. package/dist/hooks/index.d.ts +4 -1
  98. package/dist/hooks/useAuthController.d.ts +1 -1
  99. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  100. package/dist/{core → hooks}/useBuildModeController.d.ts +1 -1
  101. package/dist/hooks/useBuildNavigationController.d.ts +11 -6
  102. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  103. package/dist/hooks/useModeController.d.ts +1 -2
  104. package/dist/hooks/useProjectLog.d.ts +12 -2
  105. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  106. package/dist/hooks/useStorageSource.d.ts +2 -2
  107. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  108. package/dist/index.d.ts +1 -0
  109. package/dist/index.es.js +22131 -14039
  110. package/dist/index.es.js.map +1 -1
  111. package/dist/index.umd.js +24420 -588
  112. package/dist/index.umd.js.map +1 -1
  113. package/dist/internal/useBuildDataSource.d.ts +1 -12
  114. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  115. package/dist/preview/PropertyPreview.d.ts +1 -1
  116. package/dist/preview/PropertyPreviewProps.d.ts +7 -5
  117. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  118. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  119. package/dist/preview/components/ReferencePreview.d.ts +4 -9
  120. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  121. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  122. package/dist/preview/util.d.ts +3 -3
  123. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  124. package/dist/routes/FireCMSRoute.d.ts +1 -0
  125. package/dist/routes/HomePageRoute.d.ts +3 -0
  126. package/dist/types/analytics.d.ts +1 -1
  127. package/dist/types/auth.d.ts +37 -3
  128. package/dist/types/collections.d.ts +86 -24
  129. package/dist/types/datasource.d.ts +53 -37
  130. package/dist/types/dialogs_controller.d.ts +7 -3
  131. package/dist/types/entities.d.ts +8 -2
  132. package/dist/types/entity_actions.d.ts +28 -4
  133. package/dist/types/entity_callbacks.d.ts +16 -16
  134. package/dist/types/entity_overrides.d.ts +6 -0
  135. package/dist/types/export_import.d.ts +4 -4
  136. package/dist/types/fields.d.ts +71 -42
  137. package/dist/types/firecms.d.ts +6 -2
  138. package/dist/types/firecms_context.d.ts +1 -1
  139. package/dist/types/index.d.ts +2 -1
  140. package/dist/types/navigation.d.ts +45 -26
  141. package/dist/types/permissions.d.ts +8 -4
  142. package/dist/types/plugins.d.ts +40 -31
  143. package/dist/types/properties.d.ts +54 -26
  144. package/dist/types/property_config.d.ts +2 -4
  145. package/dist/types/roles.d.ts +31 -0
  146. package/dist/types/side_dialogs_controller.d.ts +10 -0
  147. package/dist/types/side_entity_controller.d.ts +6 -1
  148. package/dist/types/storage.d.ts +86 -3
  149. package/dist/types/user.d.ts +6 -0
  150. package/dist/util/builders.d.ts +3 -3
  151. package/dist/util/collections.d.ts +9 -1
  152. package/dist/util/entities.d.ts +3 -3
  153. package/dist/util/entity_actions.d.ts +2 -0
  154. package/dist/util/entity_cache.d.ts +23 -0
  155. package/dist/util/icon_list.d.ts +5 -1
  156. package/dist/util/icon_synonyms.d.ts +1 -98
  157. package/dist/util/icons.d.ts +13 -4
  158. package/dist/util/index.d.ts +2 -0
  159. package/dist/util/navigation_from_path.d.ts +6 -1
  160. package/dist/util/navigation_utils.d.ts +14 -3
  161. package/dist/util/objects.d.ts +2 -1
  162. package/dist/util/permissions.d.ts +4 -4
  163. package/dist/util/plurals.d.ts +0 -2
  164. package/dist/util/property_utils.d.ts +3 -3
  165. package/dist/util/references.d.ts +4 -2
  166. package/dist/util/resolutions.d.ts +31 -17
  167. package/dist/util/storage.d.ts +23 -2
  168. package/dist/util/useStorageUploadController.d.ts +3 -3
  169. package/dist/util/useTraceUpdate.d.ts +1 -0
  170. package/package.json +64 -51
  171. package/src/app/AppBar.tsx +18 -0
  172. package/src/app/Drawer.tsx +24 -0
  173. package/src/app/Scaffold.tsx +243 -0
  174. package/src/app/index.ts +4 -0
  175. package/src/app/useApp.tsx +32 -0
  176. package/src/components/ArrayContainer.tsx +126 -40
  177. package/src/components/CircularProgressCenter.tsx +2 -2
  178. package/src/components/ClearFilterSortButton.tsx +41 -0
  179. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +3 -3
  180. package/src/components/DeleteEntityDialog.tsx +14 -23
  181. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +56 -39
  182. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +283 -280
  183. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +29 -8
  184. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +58 -50
  185. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  186. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +40 -33
  187. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +22 -20
  188. package/src/components/EntityCollectionTable/index.tsx +1 -1
  189. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +31 -36
  190. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +36 -34
  191. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
  192. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +81 -80
  193. package/src/components/EntityCollectionView/EntityCollectionView.tsx +228 -155
  194. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +9 -8
  195. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  196. package/src/components/EntityCollectionView/useSelectionController.tsx +43 -0
  197. package/src/components/EntityCollectionView/utils.ts +19 -0
  198. package/src/components/EntityPreview.tsx +218 -71
  199. package/src/components/EntityView.tsx +84 -0
  200. package/src/components/ErrorView.tsx +4 -4
  201. package/src/components/FieldCaption.tsx +14 -0
  202. package/src/components/HomePage/DefaultHomePage.tsx +39 -28
  203. package/src/components/HomePage/FavouritesView.tsx +6 -11
  204. package/src/components/HomePage/NavigationCard.tsx +69 -0
  205. package/src/components/HomePage/NavigationCardBinding.tsx +111 -0
  206. package/src/components/HomePage/NavigationGroup.tsx +2 -2
  207. package/src/components/HomePage/SmallNavigationCard.tsx +44 -0
  208. package/src/components/HomePage/index.tsx +3 -1
  209. package/src/components/NotFoundPage.tsx +2 -2
  210. package/src/components/PropertyConfigBadge.tsx +9 -3
  211. package/src/components/PropertyIdCopyTooltip.tsx +47 -0
  212. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +22 -17
  213. package/src/components/ReferenceWidget.tsx +26 -16
  214. package/src/components/SearchIconsView.tsx +10 -7
  215. package/src/components/SelectableTable/SelectableTable.tsx +27 -12
  216. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  217. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +25 -8
  218. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +46 -30
  219. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +92 -23
  220. package/src/components/UnsavedChangesDialog.tsx +42 -0
  221. package/src/components/VirtualTable/VirtualTable.tsx +96 -48
  222. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  223. package/src/components/VirtualTable/VirtualTableHeader.tsx +10 -10
  224. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  225. package/src/components/VirtualTable/VirtualTableProps.tsx +34 -15
  226. package/src/components/VirtualTable/VirtualTableRow.tsx +5 -6
  227. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +5 -5
  228. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +3 -2
  229. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  230. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
  231. package/src/components/VirtualTable/types.tsx +2 -3
  232. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +40 -43
  233. package/src/components/common/index.ts +2 -1
  234. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  235. package/src/components/common/types.tsx +4 -6
  236. package/src/components/common/useColumnsIds.tsx +24 -3
  237. package/src/components/common/useDataSourceTableController.tsx +420 -0
  238. package/src/components/common/useDebouncedCallback.tsx +20 -0
  239. package/src/components/common/useScrollRestoration.tsx +68 -0
  240. package/src/components/common/useTableSearchHelper.ts +53 -12
  241. package/src/components/index.tsx +8 -5
  242. package/src/contexts/AuthControllerContext.tsx +1 -1
  243. package/src/contexts/BreacrumbsContext.tsx +38 -0
  244. package/src/contexts/DialogsProvider.tsx +5 -4
  245. package/src/contexts/ModeController.tsx +1 -3
  246. package/src/contexts/SnackbarProvider.tsx +2 -0
  247. package/src/core/DefaultAppBar.tsx +207 -0
  248. package/src/core/DefaultDrawer.tsx +185 -0
  249. package/src/core/DrawerNavigationItem.tsx +66 -0
  250. package/src/core/EntityEditView.tsx +455 -0
  251. package/src/core/EntityEditViewFormActions.tsx +199 -0
  252. package/src/core/EntitySidePanel.tsx +87 -18
  253. package/src/core/FireCMS.tsx +67 -44
  254. package/src/core/FireCMSRouter.tsx +17 -0
  255. package/src/core/NavigationRoutes.tsx +36 -38
  256. package/src/core/SideDialogs.tsx +22 -12
  257. package/src/core/field_configs.tsx +11 -12
  258. package/src/core/index.tsx +6 -7
  259. package/src/form/EntityForm.tsx +565 -519
  260. package/src/form/EntityFormActions.tsx +169 -0
  261. package/src/form/PropertyFieldBinding.tsx +85 -44
  262. package/src/form/components/CustomIdField.tsx +6 -2
  263. package/src/form/components/FieldHelperText.tsx +4 -4
  264. package/src/form/components/FormEntry.tsx +22 -0
  265. package/src/form/components/FormLayout.tsx +16 -0
  266. package/src/form/components/LabelWithIcon.tsx +44 -0
  267. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  268. package/src/form/components/StorageItemPreview.tsx +23 -11
  269. package/src/form/components/StorageUploadProgress.tsx +9 -9
  270. package/src/form/components/index.tsx +4 -1
  271. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +32 -21
  272. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +54 -45
  273. package/src/form/field_bindings/BlockFieldBinding.tsx +57 -36
  274. package/src/form/field_bindings/DateTimeFieldBinding.tsx +21 -17
  275. package/src/form/field_bindings/KeyValueFieldBinding.tsx +76 -67
  276. package/src/form/field_bindings/MapFieldBinding.tsx +82 -65
  277. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +153 -0
  278. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -22
  279. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +12 -17
  280. package/src/form/field_bindings/ReferenceFieldBinding.tsx +47 -34
  281. package/src/form/field_bindings/RepeatFieldBinding.tsx +57 -36
  282. package/src/form/field_bindings/SelectFieldBinding.tsx +24 -17
  283. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +47 -46
  284. package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -27
  285. package/src/form/field_bindings/TextFieldBinding.tsx +35 -30
  286. package/src/form/index.tsx +17 -37
  287. package/src/form/useClearRestoreValue.tsx +2 -2
  288. package/src/form/validation.ts +15 -26
  289. package/src/hooks/data/delete.ts +7 -6
  290. package/src/hooks/data/save.ts +13 -9
  291. package/src/hooks/data/useCollectionFetch.tsx +4 -4
  292. package/src/hooks/data/useDataSource.tsx +15 -2
  293. package/src/hooks/data/useEntityFetch.tsx +11 -7
  294. package/src/hooks/index.tsx +6 -1
  295. package/src/hooks/useAuthController.tsx +1 -1
  296. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  297. package/src/{core → hooks}/useBuildLocalConfigurationPersistence.tsx +8 -10
  298. package/src/{core → hooks}/useBuildModeController.tsx +23 -30
  299. package/src/hooks/useBuildNavigationController.tsx +278 -117
  300. package/src/hooks/useFireCMSContext.tsx +5 -5
  301. package/src/hooks/useLargeLayout.tsx +0 -35
  302. package/src/hooks/useModeController.tsx +1 -2
  303. package/src/hooks/useProjectLog.tsx +41 -9
  304. package/src/hooks/useReferenceDialog.tsx +2 -2
  305. package/src/hooks/useResolvedNavigationFrom.tsx +10 -12
  306. package/src/hooks/useStorageSource.tsx +7 -2
  307. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  308. package/src/index.ts +1 -0
  309. package/src/internal/useBuildDataSource.ts +72 -77
  310. package/src/internal/useBuildSideDialogsController.tsx +4 -2
  311. package/src/internal/useBuildSideEntityController.tsx +177 -70
  312. package/src/internal/useUnsavedChangesDialog.tsx +127 -91
  313. package/src/preview/PropertyPreview.tsx +19 -26
  314. package/src/preview/PropertyPreviewProps.tsx +5 -9
  315. package/src/preview/components/BooleanPreview.tsx +19 -4
  316. package/src/preview/components/EmptyValue.tsx +1 -1
  317. package/src/preview/components/EnumValuesChip.tsx +2 -2
  318. package/src/preview/components/ImagePreview.tsx +25 -36
  319. package/src/preview/components/ReferencePreview.tsx +73 -176
  320. package/src/preview/components/StorageThumbnail.tsx +5 -1
  321. package/src/preview/components/UrlComponentPreview.tsx +60 -28
  322. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +2 -3
  323. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
  324. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +2 -3
  325. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +1 -2
  326. package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -5
  327. package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -5
  328. package/src/preview/property_previews/MapPropertyPreview.tsx +12 -11
  329. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +12 -12
  330. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  331. package/src/preview/util.ts +10 -10
  332. package/src/routes/CustomCMSRoute.tsx +21 -0
  333. package/src/routes/FireCMSRoute.tsx +236 -0
  334. package/src/routes/HomePageRoute.tsx +17 -0
  335. package/src/types/analytics.ts +1 -0
  336. package/src/types/auth.tsx +48 -3
  337. package/src/types/collections.ts +102 -27
  338. package/src/types/customization_controller.tsx +0 -1
  339. package/src/types/datasource.ts +62 -44
  340. package/src/types/dialogs_controller.tsx +7 -3
  341. package/src/types/entities.ts +16 -2
  342. package/src/types/entity_actions.tsx +33 -4
  343. package/src/types/entity_callbacks.ts +18 -18
  344. package/src/types/entity_overrides.tsx +7 -0
  345. package/src/types/export_import.ts +4 -4
  346. package/src/types/fields.tsx +81 -46
  347. package/src/types/firecms.tsx +6 -2
  348. package/src/types/firecms_context.tsx +1 -1
  349. package/src/types/index.ts +2 -1
  350. package/src/types/navigation.ts +52 -31
  351. package/src/types/permissions.ts +10 -5
  352. package/src/types/plugins.tsx +47 -39
  353. package/src/types/properties.ts +63 -27
  354. package/src/types/property_config.tsx +2 -4
  355. package/src/types/roles.ts +41 -0
  356. package/src/types/side_dialogs_controller.tsx +15 -0
  357. package/src/types/side_entity_controller.tsx +7 -1
  358. package/src/types/storage.ts +94 -3
  359. package/src/types/user.ts +9 -0
  360. package/src/util/builders.ts +10 -8
  361. package/src/util/collections.ts +22 -0
  362. package/src/util/entities.ts +9 -6
  363. package/src/util/entity_actions.ts +28 -0
  364. package/src/util/entity_cache.ts +204 -0
  365. package/src/util/enums.ts +1 -1
  366. package/src/util/icon_list.ts +16 -10
  367. package/src/util/icon_synonyms.ts +3 -100
  368. package/src/util/icons.tsx +26 -8
  369. package/src/util/index.ts +2 -0
  370. package/src/util/join_collections.ts +3 -0
  371. package/src/util/make_properties_editable.ts +13 -5
  372. package/src/util/navigation_from_path.ts +13 -6
  373. package/src/util/navigation_utils.ts +59 -7
  374. package/src/util/objects.ts +45 -28
  375. package/src/util/parent_references_from_path.ts +3 -3
  376. package/src/util/permissions.ts +20 -16
  377. package/src/util/plurals.ts +0 -2
  378. package/src/util/property_utils.tsx +11 -4
  379. package/src/util/references.ts +45 -5
  380. package/src/util/resolutions.ts +79 -46
  381. package/src/util/storage.ts +79 -21
  382. package/src/util/strings.ts +2 -2
  383. package/src/util/useStorageUploadController.tsx +71 -27
  384. package/src/util/useTraceUpdate.tsx +2 -1
  385. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  386. package/dist/components/VirtualTable/common.d.ts +0 -2
  387. package/dist/core/Drawer.d.ts +0 -23
  388. package/dist/core/Scaffold.d.ts +0 -55
  389. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  390. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  391. package/dist/internal/EntityView.d.ts +0 -22
  392. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  393. package/dist/internal/useLocaleConfig.d.ts +0 -1
  394. package/dist/types/appcheck.d.ts +0 -26
  395. package/src/components/FireCMSAppBar.tsx +0 -157
  396. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  397. package/src/components/LabelWithIcon.tsx +0 -33
  398. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -28
  399. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -225
  400. package/src/core/Drawer.tsx +0 -164
  401. package/src/core/Scaffold.tsx +0 -281
  402. package/src/form/components/FormikArrayContainer.tsx +0 -44
  403. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -696
  404. package/src/internal/EntityView.tsx +0 -578
  405. package/src/internal/useBuildCustomizationController.tsx +0 -5
  406. package/src/internal/useLocaleConfig.tsx +0 -18
  407. package/src/types/appcheck.ts +0 -29
  408. /package/dist/{core → hooks}/useBuildLocalConfigurationPersistence.d.ts +0 -0
  409. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -8,26 +8,28 @@ import {
8
8
  Entity,
9
9
  EntityAction,
10
10
  EntityCollection,
11
+ EntityReference,
12
+ EntityTableController,
11
13
  FilterValues,
12
14
  PartialEntityCollection,
13
15
  PropertyOrBuilder,
14
16
  ResolvedProperty,
15
- SaveEntityProps,
16
- SelectionController
17
+ SaveEntityProps
17
18
  } from "../../types";
18
19
  import {
19
20
  EntityCollectionRowActions,
20
21
  EntityCollectionTable,
21
- useDataSourceEntityCollectionTableController
22
+ useDataSourceTableController
22
23
  } from "../EntityCollectionTable";
23
24
 
24
25
  import {
25
26
  canCreateEntity,
26
27
  canDeleteEntity,
27
28
  canEditEntity,
28
- fullPathToCollectionSegments,
29
29
  getPropertyInPath,
30
30
  mergeDeep,
31
+ mergeEntityActions,
32
+ navigateToEntity,
31
33
  resolveCollection,
32
34
  resolveProperty
33
35
  } from "../../util";
@@ -37,6 +39,7 @@ import {
37
39
  useAuthController,
38
40
  useCustomizationController,
39
41
  useDataSource,
42
+ useFireCMSContext,
40
43
  useLargeLayout,
41
44
  useNavigationController,
42
45
  useSideEntityController
@@ -46,7 +49,8 @@ import { EntityCollectionViewActions } from "./EntityCollectionViewActions";
46
49
  import {
47
50
  AddIcon,
48
51
  Button,
49
- cn,
52
+ cls,
53
+ focusedDisabled,
50
54
  IconButton,
51
55
  KeyboardTabIcon,
52
56
  Markdown,
@@ -59,6 +63,10 @@ import {
59
63
  import { setIn } from "@firecms/formex";
60
64
  import { getSubcollectionColumnId } from "../EntityCollectionTable/internal/common";
61
65
  import {
66
+ COLLECTION_GROUP_PARENT_ID,
67
+ copyEntityAction,
68
+ deleteEntityAction,
69
+ editEntityAction,
62
70
  OnCellValueChange,
63
71
  OnColumnResizeParams,
64
72
  UniqueFieldValidator,
@@ -67,24 +75,40 @@ import {
67
75
  } from "../common";
68
76
  import { PopupFormField } from "../EntityCollectionTable/internal/popup_field/PopupFormField";
69
77
  import { GetPropertyForProps } from "../EntityCollectionTable/EntityCollectionTableProps";
70
- import {
71
- copyEntityAction,
72
- deleteEntityAction,
73
- editEntityAction
74
- } from "../EntityCollectionTable/internal/default_entity_actions";
75
78
  import { DeleteEntityDialog } from "../DeleteEntityDialog";
76
79
  import { useAnalyticsController } from "../../hooks/useAnalyticsController";
80
+ import { useSelectionController } from "./useSelectionController";
81
+ import { EntityCollectionViewStartActions } from "./EntityCollectionViewStartActions";
82
+ import { addRecentId, getRecentIds } from "./utils";
83
+ import { useScrollRestoration } from "../common/useScrollRestoration";
77
84
 
78
- const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
85
+ const DEFAULT_ENTITY_OPEN_MODE: "side_panel" | "full_screen" = "side_panel";
79
86
 
80
87
  /**
81
88
  * @group Components
82
89
  */
83
90
  export type EntityCollectionViewProps<M extends Record<string, any>> = {
84
- fullPath: string;
91
+ /**
92
+ * Complete path where this collection is located.
93
+ * It defaults to the collection path if not provided.
94
+ */
95
+ fullPath?: string;
96
+ /**
97
+ * If this is a subcollection, specify the parent collection ids.
98
+ */
85
99
  parentCollectionIds?: string[];
100
+ /**
101
+ * Whether this is a subcollection or not.
102
+ */
86
103
  isSubCollection?: boolean;
104
+
87
105
  className?: string;
106
+
107
+ /**
108
+ * If true, this view will store its filter and sorting status in the url params
109
+ */
110
+ updateUrl?: boolean;
111
+
88
112
  } & EntityCollection<M>;
89
113
 
90
114
  /**
@@ -108,20 +132,23 @@ export type EntityCollectionViewProps<M extends Record<string, any>> = {
108
132
  *
109
133
  * @param fullPath
110
134
  * @param collection
111
- * @constructor
135
+
112
136
  * @group Components
113
137
  */
114
138
  export const EntityCollectionView = React.memo(
115
139
  function EntityCollectionView<M extends Record<string, any>>({
116
- fullPath,
140
+ fullPath: fullPathProp,
117
141
  parentCollectionIds,
118
142
  isSubCollection,
119
143
  className,
144
+ updateUrl,
120
145
  ...collectionProp
121
146
  }: EntityCollectionViewProps<M>
122
147
  ) {
123
148
 
124
- const dataSource = useDataSource();
149
+ const context = useFireCMSContext();
150
+ const fullPath = fullPathProp ?? collectionProp.path;
151
+ const dataSource = useDataSource(collectionProp);
125
152
  const navigation = useNavigationController();
126
153
  const sideEntityController = useSideEntityController();
127
154
  const authController = useAuthController();
@@ -131,18 +158,22 @@ export const EntityCollectionView = React.memo(
131
158
 
132
159
  const containerRef = React.useRef<HTMLDivElement>(null);
133
160
 
161
+ const scrollRestoration = useScrollRestoration();
162
+
134
163
  const collection = useMemo(() => {
135
164
  const userOverride = userConfigPersistence?.getCollectionConfig<M>(fullPath);
136
165
  return (userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp) as EntityCollection<M>;
137
166
  }, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
138
167
 
168
+ const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
169
+
139
170
  const collectionRef = React.useRef(collection);
140
171
  useEffect(() => {
141
172
  collectionRef.current = collection;
142
173
  }, [collection]);
143
174
 
144
- const canCreateEntities = canCreateEntity(collection, authController, fullPathToCollectionSegments(fullPath), null);
145
- const [selectedNavigationEntity, setSelectedNavigationEntity] = useState<Entity<M> | undefined>(undefined);
175
+ const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
176
+ const [highlightedEntity, setHighlightedEntity] = useState<Entity<M> | undefined>(undefined);
146
177
  const [deleteEntityClicked, setDeleteEntityClicked] = React.useState<Entity<M> | Entity<M>[] | undefined>(undefined);
147
178
 
148
179
  const [lastDeleteTimestamp, setLastDeleteTimestamp] = React.useState<number>(0);
@@ -151,16 +182,16 @@ export const EntityCollectionView = React.memo(
151
182
  const [docsCount, setDocsCount] = useState<number>(0);
152
183
 
153
184
  const unselectNavigatedEntity = useCallback(() => {
154
- const currentSelection = selectedNavigationEntity;
185
+ const currentSelection = highlightedEntity;
155
186
  setTimeout(() => {
156
- if (currentSelection === selectedNavigationEntity)
157
- setSelectedNavigationEntity(undefined);
187
+ if (currentSelection === highlightedEntity)
188
+ setHighlightedEntity(undefined);
158
189
  }, 2400);
159
- }, [selectedNavigationEntity]);
190
+ }, [highlightedEntity]);
160
191
 
161
192
  const checkInlineEditing = useCallback((entity?: Entity<any>): boolean => {
162
193
  const collection = collectionRef.current;
163
- if (!canEditEntity(collection, authController, fullPathToCollectionSegments(fullPath), entity ?? null)) {
194
+ if (!canEditEntity(collection, authController, fullPath, entity ?? null)) {
164
195
  return false;
165
196
  }
166
197
  return collection.inlineEditing === undefined || collection.inlineEditing;
@@ -175,20 +206,15 @@ export const EntityCollectionView = React.memo(
175
206
  const usedSelectionController = collection.selectionController ?? selectionController;
176
207
  const {
177
208
  selectedEntities,
178
- toggleEntitySelection,
179
- isEntitySelected,
180
209
  setSelectedEntities
181
210
  } = usedSelectionController;
182
211
 
183
- useEffect(() => {
184
- setDeleteEntityClicked(undefined);
185
- }, [selectedEntities]);
186
-
187
- const tableController = useDataSourceEntityCollectionTableController<M>({
212
+ const tableController = useDataSourceTableController<M>({
188
213
  fullPath,
189
- collection: collectionRef.current,
190
- entitiesDisplayedFirst: [],
191
- lastDeleteTimestamp
214
+ collection,
215
+ lastDeleteTimestamp,
216
+ scrollRestoration,
217
+ updateUrl
192
218
  });
193
219
 
194
220
  const tableKey = React.useRef<string>(Math.random().toString(36));
@@ -200,19 +226,27 @@ export const EntityCollectionView = React.memo(
200
226
 
201
227
  const onEntityClick = useCallback((clickedEntity: Entity<M>) => {
202
228
  const collection = collectionRef.current;
203
- setSelectedNavigationEntity(clickedEntity);
229
+ setHighlightedEntity(clickedEntity);
204
230
  analyticsController.onAnalyticsEvent?.("edit_entity_clicked", {
205
231
  path: clickedEntity.path,
206
232
  entityId: clickedEntity.id
207
233
  });
208
- return sideEntityController.open({
209
- entityId: clickedEntity.id,
210
- path: clickedEntity.path,
234
+
235
+ if (collection) {
236
+ addRecentId(collection.id, clickedEntity.id);
237
+ }
238
+
239
+ const path = collection?.collectionGroup ? clickedEntity.path : (fullPath ?? clickedEntity.path);
240
+ navigateToEntity({
241
+ navigation,
242
+ path,
243
+ sideEntityController,
244
+ openEntityMode,
211
245
  collection,
212
- updateUrl: true,
213
- onClose: unselectNavigatedEntity
246
+ entityId: clickedEntity.id
214
247
  });
215
- }, [unselectNavigatedEntity]);
248
+
249
+ }, [unselectNavigatedEntity, sideEntityController]);
216
250
 
217
251
  const onNewClick = useCallback(() => {
218
252
 
@@ -220,13 +254,16 @@ export const EntityCollectionView = React.memo(
220
254
  analyticsController.onAnalyticsEvent?.("new_entity_click", {
221
255
  path: fullPath
222
256
  });
223
- sideEntityController.open({
224
- path: fullPath,
257
+ navigateToEntity({
258
+ openEntityMode,
225
259
  collection,
226
- updateUrl: true,
260
+ entityId: undefined,
261
+ path: fullPath,
262
+ sideEntityController,
263
+ navigation,
227
264
  onClose: unselectNavigatedEntity
228
- });
229
- }, [fullPath]);
265
+ })
266
+ }, [fullPath, sideEntityController]);
230
267
 
231
268
  const onMultipleDeleteClick = () => {
232
269
  analyticsController.onAnalyticsEvent?.("multiple_delete_dialog_open", {
@@ -256,6 +293,7 @@ export const EntityCollectionView = React.memo(
256
293
  fullPath: string,
257
294
  parentCollectionIds: string[],
258
295
  collection: EntityCollection;
296
+ tableController: EntityTableController;
259
297
  }> | undefined
260
298
 
261
299
  // we are only using the first plugin that implements this
@@ -288,7 +326,7 @@ export const EntityCollectionView = React.memo(
288
326
  onCollectionModifiedForUser(fullPath, { defaultSize: size })
289
327
  }, [onCollectionModifiedForUser, fullPath, userConfigPersistence]);
290
328
 
291
- const createEnabled = canCreateEntity(collection, authController, fullPathToCollectionSegments(fullPath), null);
329
+ const createEnabled = canCreateEntity(collection, authController, fullPath, null);
292
330
 
293
331
  const uniqueFieldValidator: UniqueFieldValidator = useCallback(
294
332
  ({
@@ -296,23 +334,21 @@ export const EntityCollectionView = React.memo(
296
334
  value,
297
335
  property,
298
336
  entityId
299
- }) => dataSource.checkUniqueField(fullPath, name, value, entityId),
337
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection),
300
338
  [fullPath]);
301
339
 
302
340
  const onValueChange: OnCellValueChange<any, any> = ({
303
- fullPath,
304
- context,
305
341
  value,
306
342
  propertyKey,
307
343
  onValueUpdated,
308
344
  setError,
309
- entity,
345
+ data: entity,
310
346
  }) => {
311
347
 
312
348
  const updatedValues = setIn({ ...entity.values }, propertyKey, value);
313
349
 
314
350
  const saveProps: SaveEntityProps = {
315
- path: fullPath,
351
+ path: entity.path ?? fullPath,
316
352
  entityId: entity.id,
317
353
  values: updatedValues,
318
354
  previousValues: entity.values,
@@ -323,10 +359,12 @@ export const EntityCollectionView = React.memo(
323
359
  return saveEntityWithCallbacks({
324
360
  ...saveProps,
325
361
  collection,
326
- callbacks: collection.callbacks,
327
362
  dataSource,
328
363
  context,
329
- onSaveSuccess: () => onValueUpdated(),
364
+ onSaveSuccess: () => {
365
+ setError(undefined);
366
+ onValueUpdated();
367
+ },
330
368
  onSaveFailure: (e: Error) => {
331
369
  console.error("Save failure");
332
370
  console.error(e);
@@ -336,16 +374,15 @@ export const EntityCollectionView = React.memo(
336
374
 
337
375
  };
338
376
 
339
- const resolvedFullPath = navigation.resolveAliasesFrom(fullPath);
377
+ const resolvedFullPath = navigation.resolveIdsFrom(fullPath);
340
378
  const resolvedCollection = useMemo(() => resolveCollection<M>({
341
379
  collection,
342
380
  path: fullPath,
343
- fields: customizationController.propertyConfigs
381
+ propertyConfigs: customizationController.propertyConfigs
344
382
  }), [collection, fullPath]);
345
383
 
346
384
  const getPropertyFor = useCallback(({
347
385
  propertyKey,
348
- propertyValue,
349
386
  entity
350
387
  }: GetPropertyForProps<M>) => {
351
388
  let propertyOrBuilder: PropertyOrBuilder<any, M> | undefined = getPropertyInPath<M>(collection.properties, propertyKey);
@@ -359,13 +396,12 @@ export const EntityCollectionView = React.memo(
359
396
  return resolveProperty({
360
397
  propertyKey,
361
398
  propertyOrBuilder,
362
- path: fullPath,
363
- propertyValue,
399
+ path: entity.path,
364
400
  values: entity.values,
365
401
  entityId: entity.id,
366
- fields: customizationController.propertyConfigs
402
+ propertyConfigs: customizationController.propertyConfigs
367
403
  });
368
- }, [collection.properties, customizationController.propertyConfigs, fullPath, resolvedCollection.properties]);
404
+ }, [collection.properties, customizationController.propertyConfigs, resolvedCollection.properties]);
369
405
 
370
406
  const displayedColumnIds = useColumnIds(resolvedCollection, true);
371
407
 
@@ -382,13 +418,15 @@ export const EntityCollectionView = React.memo(
382
418
  startIcon={<KeyboardTabIcon size={"small"}/>}
383
419
  onClick={(event: any) => {
384
420
  event.stopPropagation();
385
- sideEntityController.open({
386
- path: fullPath,
387
- entityId: entity.id,
388
- selectedSubPath: subcollection.id ?? subcollection.path,
421
+ navigateToEntity({
422
+ openEntityMode,
389
423
  collection,
390
- updateUrl: true
391
- });
424
+ entityId: entity.id,
425
+ selectedTab: subcollection.id ?? subcollection.path,
426
+ path: fullPath,
427
+ navigation,
428
+ sideEntityController
429
+ })
392
430
  }}>
393
431
  {subcollection.name}
394
432
  </Button>
@@ -405,16 +443,16 @@ export const EntityCollectionView = React.memo(
405
443
  Builder: ({ entity }) => {
406
444
  const collectionsWithPath = navigation.getParentReferencesFromPath(entity.path);
407
445
  return (
408
- <>
446
+ <div className={"flex flex-col gap-2 w-full"}>
409
447
  {collectionsWithPath.map((reference) => {
410
448
  return (
411
449
  <ReferencePreview
412
450
  key={reference.path + "/" + reference.id}
413
451
  reference={reference}
414
- size={"tiny"}/>
452
+ size={"small"}/>
415
453
  );
416
454
  })}
417
- </>
455
+ </div>
418
456
  );
419
457
  }
420
458
  }]
@@ -425,7 +463,7 @@ export const EntityCollectionView = React.memo(
425
463
  ...subcollectionColumns,
426
464
  ...collectionGroupParentCollections
427
465
  ];
428
- }, [collection, fullPath]);
466
+ }, [collection, fullPath, sideEntityController]);
429
467
 
430
468
  const updateLastDeleteTimestamp = useCallback(() => {
431
469
  setLastDeleteTimestamp(Date.now());
@@ -433,44 +471,50 @@ export const EntityCollectionView = React.memo(
433
471
 
434
472
  const largeLayout = useLargeLayout();
435
473
 
436
- const getActionsForEntity = ({ entity, customEntityActions }: {
474
+ const getActionsForEntity = ({
475
+ entity,
476
+ customEntityActions
477
+ }: {
437
478
  entity?: Entity<M>,
438
479
  customEntityActions?: EntityAction[]
439
480
  }): EntityAction[] => {
440
- const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPathToCollectionSegments(fullPath), entity) : true;
481
+ const deleteEnabled = entity ? canDeleteEntity(collection, authController, fullPath, entity) : true;
441
482
  const actions: EntityAction[] = [editEntityAction];
442
483
  if (createEnabled)
443
484
  actions.push(copyEntityAction);
444
485
  if (deleteEnabled)
445
486
  actions.push(deleteEntityAction);
446
487
  if (customEntityActions)
447
- actions.push(...customEntityActions);
488
+ return mergeEntityActions(actions, customEntityActions);
448
489
  return actions;
449
490
  };
450
491
 
451
- const getIdColumnWidth = useCallback(() => {
492
+ const getIdColumnWidth = () => {
452
493
  const entityActions = getActionsForEntity({});
453
494
  const collapsedActions = entityActions.filter(a => a.collapsed !== false);
454
495
  const uncollapsedActions = entityActions.filter(a => a.collapsed === false);
455
496
  const actionsWidth = uncollapsedActions.length * (largeLayout ? 40 : 30);
456
497
  return (largeLayout ? (80 + actionsWidth) : (70 + actionsWidth)) + (collapsedActions.length > 0 ? (largeLayout ? 40 : 30) : 0);
457
- }, [largeLayout]);
458
-
459
- const tableRowActionsBuilder = ({
460
- entity,
461
- size,
462
- width,
463
- frozen
464
- }: {
498
+ };
499
+
500
+ const tableRowActionsBuilder = useCallback(({
501
+ entity,
502
+ size,
503
+ width,
504
+ frozen
505
+ }: {
465
506
  entity: Entity<any>,
466
507
  size: CollectionSize,
467
508
  width: number,
468
509
  frozen?: boolean
469
510
  }) => {
470
511
 
471
- const isSelected = isEntitySelected(entity);
512
+ const isSelected = Boolean(usedSelectionController.selectedEntities.find(e => e.id == entity.id && e.path == entity.path));
472
513
 
473
- const actions = getActionsForEntity({ entity, customEntityActions: collection.entityActions });
514
+ const actions = getActionsForEntity({
515
+ entity,
516
+ customEntityActions: collection.entityActions
517
+ });
474
518
 
475
519
  return (
476
520
  <EntityCollectionRowActions
@@ -480,7 +524,7 @@ export const EntityCollectionView = React.memo(
480
524
  isSelected={isSelected}
481
525
  selectionEnabled={selectionEnabled}
482
526
  size={size}
483
- highlightEntity={setSelectedNavigationEntity}
527
+ highlightEntity={setHighlightedEntity}
484
528
  unhighlightEntity={unselectNavigatedEntity}
485
529
  collection={collection}
486
530
  fullPath={fullPath}
@@ -488,10 +532,11 @@ export const EntityCollectionView = React.memo(
488
532
  hideId={collection?.hideIdFromCollection}
489
533
  onCollectionChange={updateLastDeleteTimestamp}
490
534
  selectionController={usedSelectionController}
535
+ openEntityMode={openEntityMode}
491
536
  />
492
537
  );
493
538
 
494
- };
539
+ }, [updateLastDeleteTimestamp, usedSelectionController]);
495
540
 
496
541
  const title = <Popover
497
542
  open={popOverOpen}
@@ -521,7 +566,7 @@ export const EntityCollectionView = React.memo(
521
566
  </div>}
522
567
  >
523
568
 
524
- {collection.description && <div className="m-4 text-gray-900 dark:text-white">
569
+ {collection.description && <div className="m-4 text-surface-900 dark:text-white">
525
570
  <Markdown source={collection.description}/>
526
571
  </div>}
527
572
 
@@ -550,6 +595,7 @@ export const EntityCollectionView = React.memo(
550
595
  property={property}
551
596
  fullPath={fullPath}
552
597
  collection={collection}
598
+ tableController={tableController}
553
599
  parentCollectionIds={parentCollectionIds ?? []}/>;
554
600
  })}
555
601
  </>;
@@ -560,7 +606,8 @@ export const EntityCollectionView = React.memo(
560
606
  if (typeof AddColumnComponent === "function")
561
607
  return <AddColumnComponent fullPath={fullPath}
562
608
  parentCollectionIds={parentCollectionIds ?? []}
563
- collection={collection}/>;
609
+ collection={collection}
610
+ tableController={tableController}/>;
564
611
  return null;
565
612
  }
566
613
  : undefined;
@@ -577,12 +624,13 @@ export const EntityCollectionView = React.memo(
577
624
  });
578
625
 
579
626
  return (
580
- <div className={cn("overflow-hidden h-full w-full", className)}
627
+ <div className={cls("overflow-hidden h-full w-full rounded-md", className)}
581
628
  ref={containerRef}>
582
629
  <EntityCollectionTable
583
630
  key={`collection_table_${fullPath}`}
584
631
  additionalFields={additionalFields}
585
632
  tableController={tableController}
633
+ enablePopupIcon={true}
586
634
  displayedColumnIds={displayedColumnIds}
587
635
  onSizeChanged={onSizeChanged}
588
636
  onEntityClick={onEntityClick}
@@ -592,13 +640,23 @@ export const EntityCollectionView = React.memo(
592
640
  uniqueFieldValidator={uniqueFieldValidator}
593
641
  title={title}
594
642
  selectionController={usedSelectionController}
595
- highlightedEntities={selectedNavigationEntity ? [selectedNavigationEntity] : []}
643
+ highlightedEntities={highlightedEntity ? [highlightedEntity] : []}
596
644
  defaultSize={collection.defaultSize}
597
645
  properties={resolvedCollection.properties}
598
646
  getPropertyFor={getPropertyFor}
599
647
  onTextSearchClick={textSearchInitialised ? undefined : onTextSearchClick}
648
+ onScroll={tableController.onScroll}
649
+ initialScroll={tableController.initialScroll}
600
650
  textSearchLoading={textSearchLoading}
601
651
  textSearchEnabled={textSearchEnabled}
652
+ actionsStart={<EntityCollectionViewStartActions
653
+ parentCollectionIds={parentCollectionIds ?? []}
654
+ collection={collection}
655
+ tableController={tableController}
656
+ path={fullPath}
657
+ relativePath={collection.path}
658
+ selectionController={usedSelectionController}
659
+ collectionEntitiesCount={docsCount}/>}
602
660
  actions={<EntityCollectionViewActions
603
661
  parentCollectionIds={parentCollectionIds ?? []}
604
662
  collection={collection}
@@ -634,21 +692,22 @@ export const EntityCollectionView = React.memo(
634
692
  additionalIDHeaderWidget={<EntityIdHeaderWidget
635
693
  path={fullPath}
636
694
  collection={collection}/>}
695
+ openEntityMode={openEntityMode}
637
696
  />
638
697
 
639
- <PopupFormField
640
- key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entity?.id}`}
698
+ {popupCell && <PopupFormField
699
+ key={`popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`}
641
700
  open={Boolean(popupCell)}
642
701
  onClose={onPopupClose}
643
702
  cellRect={popupCell?.cellRect}
644
703
  propertyKey={popupCell?.propertyKey}
645
704
  collection={collection}
646
- entity={popupCell?.entity}
705
+ entityId={popupCell.entityId}
647
706
  tableKey={tableKey.current}
648
707
  customFieldValidator={uniqueFieldValidator}
649
708
  path={resolvedFullPath}
650
709
  onCellValueChange={onValueChange}
651
- container={containerRef.current}/>
710
+ container={containerRef.current}/>}
652
711
 
653
712
  {deleteEntityClicked &&
654
713
  <DeleteEntityDialog
@@ -664,7 +723,7 @@ export const EntityCollectionView = React.memo(
664
723
  </div>
665
724
  );
666
725
  }, (a, b) => {
667
- return equal(a.fullPath, b.fullPath) &&
726
+ return equal(a.path, b.path) &&
668
727
  equal(a.parentCollectionIds, b.parentCollectionIds) &&
669
728
  equal(a.isSubCollection, b.isSubCollection) &&
670
729
  equal(a.className, b.className) &&
@@ -676,39 +735,15 @@ export const EntityCollectionView = React.memo(
676
735
  equal(a.selectionController, b.selectionController) &&
677
736
  equal(a.Actions, b.Actions) &&
678
737
  equal(a.defaultSize, b.defaultSize) &&
738
+ equal(a.initialFilter, b.initialFilter) &&
739
+ equal(a.initialSort, b.initialSort) &&
679
740
  equal(a.textSearchEnabled, b.textSearchEnabled) &&
680
741
  equal(a.additionalFields, b.additionalFields) &&
742
+ equal(a.sideDialogWidth, b.sideDialogWidth) &&
743
+ equal(a.openEntityMode, b.openEntityMode) &&
681
744
  equal(a.forceFilter, b.forceFilter);
682
745
  }) as React.FunctionComponent<EntityCollectionViewProps<any>>
683
746
 
684
- export function useSelectionController<M extends Record<string, any> = any>(
685
- onSelectionChange?: (entity: Entity<M>, selected: boolean) => void
686
- ): SelectionController<M> {
687
-
688
- const [selectedEntities, setSelectedEntities] = useState<Entity<M>[]>([]);
689
-
690
- const toggleEntitySelection = useCallback((entity: Entity<M>) => {
691
- let newValue;
692
- if (selectedEntities.map(e => e.id).includes(entity.id)) {
693
- onSelectionChange?.(entity, false);
694
- newValue = selectedEntities.filter((item: Entity<M>) => item.id !== entity.id);
695
- } else {
696
- onSelectionChange?.(entity, true);
697
- newValue = [...selectedEntities, entity];
698
- }
699
- setSelectedEntities(newValue);
700
- }, [selectedEntities]);
701
-
702
- const isEntitySelected = useCallback((entity: Entity<M>) => selectedEntities.map(e => e.id).includes(entity.id), [selectedEntities]);
703
-
704
- return {
705
- selectedEntities,
706
- setSelectedEntities,
707
- isEntitySelected,
708
- toggleEntitySelection
709
- };
710
- }
711
-
712
747
  function EntitiesCount({
713
748
  fullPath,
714
749
  collection,
@@ -723,14 +758,14 @@ function EntitiesCount({
723
758
  onCountChange?: (count: number) => void,
724
759
  }) {
725
760
 
726
- const dataSource = useDataSource();
761
+ const dataSource = useDataSource(collection);
727
762
  const navigation = useNavigationController();
728
763
  const [count, setCount] = useState<number | undefined>(undefined);
729
764
  const [error, setError] = useState<Error | undefined>(undefined);
730
765
 
731
766
  const sortByProperty = sortBy ? sortBy[0] : undefined;
732
767
  const currentSort = sortBy ? sortBy[1] : undefined;
733
- const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);
768
+ const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
734
769
 
735
770
  useEffect(() => {
736
771
  if (dataSource.countEntities)
@@ -745,6 +780,7 @@ function EntitiesCount({
745
780
 
746
781
  useEffect(() => {
747
782
  if (onCountChange) {
783
+ setError(undefined);
748
784
  onCountChange(count ?? 0);
749
785
  }
750
786
  }, [onCountChange, count]);
@@ -776,48 +812,85 @@ function EntityIdHeaderWidget({
776
812
  collection: EntityCollection,
777
813
  path: string
778
814
  }) {
815
+
816
+ const navigation = useNavigationController();
779
817
  const [openPopup, setOpenPopup] = React.useState(false);
780
818
  const [searchString, setSearchString] = React.useState("");
819
+ const [recentIds, setRecentIds] = React.useState<string[]>(getRecentIds(collection.id));
781
820
  const sideEntityController = useSideEntityController();
821
+
822
+ const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
823
+
782
824
  return (
783
- <Tooltip title={!openPopup ? "Find by ID" : undefined}>
825
+ <Tooltip title={!openPopup ? "Find by ID" : undefined} asChild={false}>
784
826
  <Popover
785
827
  open={openPopup}
786
828
  onOpenChange={setOpenPopup}
829
+ sideOffset={0}
830
+ align={"start"}
831
+ alignOffset={-117}
787
832
  trigger={
788
833
  <IconButton size={"small"}>
789
834
  <SearchIcon size={"small"}/>
790
835
  </IconButton>
791
- }
792
- >
793
- <form noValidate={true}
794
- onSubmit={(e) => {
795
- e.preventDefault();
796
- if (!searchString) return;
797
- setOpenPopup(false);
798
- return sideEntityController.open({
799
- entityId: searchString,
800
- path,
801
- collection,
802
- updateUrl: true
803
- });
804
- }}
805
- className={"text-gray-900 dark:text-white w-96 max-w-full"}>
806
-
807
- <div className="flex p-2 w-full gap-4">
808
- <input
809
- autoFocus={openPopup}
810
- placeholder={"Find entity by ID"}
811
- // size={"small"}
812
- onChange={(e) => setSearchString(e.target.value)}
813
- value={searchString}
814
- className={"flex-grow bg-transparent outline-none p-1"}/>
815
- <Button variant={"outlined"}
816
- disabled={!searchString}
817
- type={"submit"}
818
- >Go</Button>
819
- </div>
820
- </form>
836
+ }>
837
+ <div
838
+ className={cls("my-2 rounded-lg bg-surface-50 dark:bg-surface-950 text-surface-900 dark:text-white")}>
839
+ <form noValidate={true}
840
+ onSubmit={(e) => {
841
+ e.preventDefault();
842
+ if (!searchString) return;
843
+ setOpenPopup(false);
844
+ const entityId = searchString.trim();
845
+ setRecentIds(addRecentId(collection.id, entityId));
846
+ navigateToEntity({
847
+ openEntityMode,
848
+ collection,
849
+ entityId,
850
+ path,
851
+ sideEntityController,
852
+ navigation
853
+ })
854
+ }}
855
+ className={"w-96 max-w-full"}>
856
+
857
+ <div className="flex p-2 w-full gap-2">
858
+ <input
859
+ autoFocus={openPopup}
860
+ placeholder={"Find entity by ID"}
861
+ // size={"small"}
862
+ onChange={(e) => {
863
+ setSearchString(e.target.value);
864
+ }}
865
+ value={searchString}
866
+ className={"rounded-lg bg-white dark:bg-surface-800 flex-grow bg-transparent outline-none p-2 " + focusedDisabled}/>
867
+ <Button variant={"text"}
868
+ disabled={!(searchString.trim())}
869
+ type={"submit"}
870
+ ><KeyboardTabIcon/></Button>
871
+ </div>
872
+ </form>
873
+ {recentIds && recentIds.length > 0 && <div className="flex flex-col gap-2 p-2">
874
+ {recentIds.map(id => (
875
+ <ReferencePreview reference={new EntityReference(id, path)}
876
+ key={id}
877
+ hover={true}
878
+ onClick={() => {
879
+ setOpenPopup(false);
880
+ navigateToEntity({
881
+ openEntityMode,
882
+ collection,
883
+ entityId: id,
884
+ path,
885
+ sideEntityController,
886
+ navigation
887
+ })
888
+ }}
889
+ includeEntityLink={false}
890
+ size={"small"}/>
891
+ ))}
892
+ </div>}
893
+ </div>
821
894
  </Popover>
822
895
 
823
896
  </Tooltip>