@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
@@ -0,0 +1,455 @@
1
+ import React, { useEffect, useMemo, useState } from "react";
2
+ import { Entity, EntityCollection, EntityCustomView, EntityStatus, FireCMSPlugin, FormContext, User } from "../types";
3
+
4
+ import { CircularProgressCenter, EntityCollectionView, EntityView, ErrorBoundary } from "../components";
5
+ import { canEditEntity, removeInitialAndTrailingSlashes, resolveDefaultSelectedView, resolveEntityView } from "../util";
6
+
7
+ import {
8
+ useAuthController,
9
+ useCustomizationController,
10
+ useEntityFetch,
11
+ useFireCMSContext,
12
+ useLargeLayout
13
+ } from "../hooks";
14
+ import { CircularProgress, cls, defaultBorderMixin, Tab, Tabs, Typography } from "@firecms/ui";
15
+ import { getEntityFromCache } from "../util/entity_cache";
16
+ import { EntityForm, EntityFormProps, FormLayoutInner } from "../form";
17
+ import { EntityEditViewFormActions } from "./EntityEditViewFormActions";
18
+
19
+ const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
20
+
21
+ export type OnUpdateParams = {
22
+ entity: Entity<any>,
23
+ status: EntityStatus,
24
+ path: string,
25
+ entityId?: string;
26
+ selectedTab?: string;
27
+ collection: EntityCollection<any>
28
+ };
29
+
30
+ export type OnTabChangeParams<M extends Record<string, any>> = {
31
+ path: string;
32
+ entityId?: string;
33
+ selectedTab?: string;
34
+ collection: EntityCollection<M>;
35
+ };
36
+
37
+ export interface EntityEditViewProps<M extends Record<string, any>> {
38
+ path: string;
39
+ collection: EntityCollection<M>;
40
+ entityId?: string;
41
+ databaseId?: string;
42
+ copy?: boolean;
43
+ selectedTab?: string;
44
+ parentCollectionIds: string[];
45
+ onValuesModified?: (modified: boolean) => void;
46
+ onSaved?: (params: OnUpdateParams) => void;
47
+ onTabChange?: (props: OnTabChangeParams<M>) => void;
48
+ layout?: "side_panel" | "full_screen";
49
+ barActions?: React.ReactNode;
50
+ formProps?: Partial<EntityFormProps<M>>
51
+ }
52
+
53
+ /**
54
+ * This is the default view that is used as the content of a side panel when
55
+ * an entity is opened.
56
+ */
57
+ export function EntityEditView<M extends Record<string, any>, USER extends User>({
58
+ entityId,
59
+ ...props
60
+ }: EntityEditViewProps<M>) {
61
+
62
+ const {
63
+ entity,
64
+ dataLoading,
65
+ // eslint-disable-next-line no-unused-vars
66
+ dataLoadingError
67
+ } = useEntityFetch<M, USER>({
68
+ path: props.path,
69
+ entityId: entityId,
70
+ collection: props.collection,
71
+ databaseId: props.databaseId,
72
+ useCache: false
73
+ });
74
+
75
+ const cachedValues = entityId
76
+ ? getEntityFromCache(props.path + "/" + entityId)
77
+ : getEntityFromCache(props.path + "#new");
78
+
79
+ const authController = useAuthController();
80
+
81
+ const initialStatus = props.copy ? "copy" : (entityId ? "existing" : "new");
82
+ const [status, setStatus] = useState<EntityStatus>(initialStatus);
83
+
84
+ const canEdit = useMemo(() => {
85
+ if (status === "new" || status === "copy") {
86
+ return true;
87
+ } else {
88
+ return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null) : undefined;
89
+ }
90
+ }, [authController, entity, status]);
91
+
92
+ if ((dataLoading && !cachedValues) || (!entity || canEdit === undefined) && (status === "existing" || status === "copy")) {
93
+ return <CircularProgressCenter/>;
94
+ }
95
+
96
+ if (entityId && !entity && !cachedValues) {
97
+ console.error(`Entity with id ${entityId} not found in collection ${props.path}`);
98
+ }
99
+
100
+ if (!canEdit) {
101
+ return <div className={"flex flex-col"}>
102
+ <Typography className={"mt-16 mb-8 mx-8"} variant={"h4"}>
103
+ {props.collection.singularName ?? props.collection.name}
104
+ </Typography>
105
+ <EntityView
106
+ className={"px-8"}
107
+ entity={entity as Entity<M>}
108
+ path={props.path}
109
+ collection={props.collection}/>
110
+ </div>
111
+ }
112
+
113
+ return <EntityEditViewInner<M> {...props}
114
+ entityId={entityId}
115
+ entity={entity}
116
+ cachedDirtyValues={cachedValues as Partial<M>}
117
+ dataLoading={dataLoading}
118
+ status={status}
119
+ setStatus={setStatus}
120
+ />;
121
+ }
122
+
123
+ function SecondaryForm<M extends object>({
124
+ collection,
125
+ className,
126
+ customView,
127
+ entity,
128
+ formContext,
129
+ forceActionsAtTheBottom,
130
+ }: {
131
+ className?: string,
132
+ customView: EntityCustomView,
133
+ formContext: FormContext<M>,
134
+ collection: EntityCollection<M>,
135
+ forceActionsAtTheBottom?: boolean,
136
+ entity: Entity<M> | undefined,
137
+ }) {
138
+
139
+ if (!customView.Builder) {
140
+ console.error("customView.Builder is not defined");
141
+ return null;
142
+ }
143
+
144
+ return <FormLayoutInner
145
+ className={className}
146
+ forceActionsAtTheBottom={forceActionsAtTheBottom}
147
+ formContext={formContext}
148
+ EntityFormActionsComponent={EntityEditViewFormActions}>
149
+ <ErrorBoundary>
150
+ {formContext && <customView.Builder
151
+ collection={collection}
152
+ entity={entity}
153
+ modifiedValues={formContext.formex.values ?? entity?.values}
154
+ formContext={formContext}
155
+ />}
156
+ </ErrorBoundary>
157
+ </FormLayoutInner>;
158
+ }
159
+
160
+ export function EntityEditViewInner<M extends Record<string, any>>({
161
+ path,
162
+ entityId,
163
+ selectedTab: selectedTabProp,
164
+ collection,
165
+ parentCollectionIds,
166
+ onValuesModified,
167
+ onSaved,
168
+ onTabChange,
169
+ entity,
170
+ cachedDirtyValues,
171
+ dataLoading,
172
+ layout = "side_panel",
173
+ barActions,
174
+ status,
175
+ setStatus,
176
+ formProps,
177
+ }: EntityEditViewProps<M> & {
178
+ entity?: Entity<M>,
179
+ cachedDirtyValues?: Partial<M>, // dirty cached entity in memory
180
+ dataLoading: boolean,
181
+ status: EntityStatus,
182
+ setStatus: (status: EntityStatus) => void,
183
+ }) {
184
+
185
+ const context = useFireCMSContext();
186
+
187
+ const [usedEntity, setUsedEntity] = useState<Entity<M> | undefined>(entity);
188
+
189
+ useEffect(() => {
190
+ if (entity)
191
+ setUsedEntity(entity);
192
+ }, [entity]);
193
+
194
+ // Instead of using a ref (which does not trigger re-render), we use state for the form context.
195
+ const [formContext, setFormContext] = useState<FormContext<M> | undefined>(undefined);
196
+
197
+ const largeLayout = useLargeLayout();
198
+
199
+ const customizationController = useCustomizationController();
200
+
201
+ const defaultSelectedView = useMemo(() => resolveDefaultSelectedView(
202
+ collection ? collection.defaultSelectedView : undefined,
203
+ {
204
+ status,
205
+ entityId
206
+ }
207
+ ), []);
208
+
209
+ const [selectedTab, setSelectedTab] = useState<string>(selectedTabProp ?? defaultSelectedView ?? MAIN_TAB_VALUE);
210
+
211
+ useEffect(() => {
212
+ if ((selectedTabProp ?? MAIN_TAB_VALUE) !== selectedTab) {
213
+ setSelectedTab(selectedTabProp ?? MAIN_TAB_VALUE);
214
+ }
215
+ }, [selectedTabProp]);
216
+
217
+ const mainViewVisible = selectedTab === MAIN_TAB_VALUE;
218
+
219
+ const subcollections = (collection.subcollections ?? []).filter(c => !c.hideFromNavigation);
220
+ const subcollectionsCount = subcollections?.length ?? 0;
221
+ const customViews = collection.entityViews;
222
+ const customViewsCount = customViews?.length ?? 0;
223
+ const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0;
224
+
225
+ const resolvedEntityViews = customViews ? customViews
226
+ .map(e => resolveEntityView(e, customizationController.entityViews))
227
+ .filter(Boolean) as EntityCustomView[]
228
+ : [];
229
+
230
+ const selectedEntityView = resolvedEntityViews.find(e => e.key === selectedTab);
231
+ const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
232
+
233
+ const secondaryForms: React.ReactNode[] | undefined = formContext && customViews && resolvedEntityViews
234
+ .filter(e => e.includeActions)
235
+ .map((customView) => {
236
+ if (!customView || !formContext)
237
+ return null;
238
+
239
+ if (!customView.Builder) {
240
+ console.error("customView.Builder is not defined");
241
+ return null;
242
+ }
243
+
244
+ return <SecondaryForm key={`custom_view_${customView.key}`}
245
+ className={selectedTab !== customView.key ? "hidden" : ""}
246
+ customView={customView}
247
+ formContext={formContext}
248
+ collection={collection}
249
+ forceActionsAtTheBottom={!largeLayout || layout === "side_panel" || customView.includeActions === "bottom"}
250
+ entity={usedEntity}/>;
251
+
252
+ }).filter(Boolean);
253
+
254
+ const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews
255
+ .filter(e => !e.includeActions)
256
+ .map((customView) => {
257
+ if (!customView)
258
+ return null;
259
+ const Builder = customView.Builder;
260
+ if (!Builder) {
261
+ console.error("customView.Builder is not defined");
262
+ return null;
263
+ }
264
+
265
+ return <div
266
+ className={cls(defaultBorderMixin,
267
+ "relative flex-1 w-full h-full overflow-auto",
268
+ { "hidden": selectedTab !== customView.key }
269
+ )}
270
+ key={`custom_view_${customView.key}`}
271
+ role="tabpanel">
272
+ <ErrorBoundary>
273
+ {formContext && <Builder
274
+ collection={collection}
275
+ entity={usedEntity}
276
+ modifiedValues={formContext.formex.values ?? usedEntity?.values}
277
+ formContext={formContext}
278
+ />}
279
+ </ErrorBoundary>
280
+ </div>;
281
+ }).filter(Boolean);
282
+
283
+ const globalLoading = dataLoading && !usedEntity;
284
+
285
+ const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
286
+ const subcollectionId = subcollection.id ?? subcollection.path;
287
+ const fullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : undefined;
288
+ if (selectedTab !== subcollectionId) return null;
289
+ return (
290
+ <div
291
+ className={"relative flex-1 h-full overflow-auto w-full"}
292
+ key={`subcol_${subcollectionId}`}
293
+ role="tabpanel">
294
+
295
+ {globalLoading && <CircularProgressCenter/>}
296
+
297
+ {!globalLoading &&
298
+ (usedEntity && fullPath
299
+ ? <EntityCollectionView
300
+ fullPath={fullPath}
301
+ parentCollectionIds={[...parentCollectionIds, collection.id]}
302
+ isSubCollection={true}
303
+ updateUrl={false}
304
+ {...subcollection}
305
+ openEntityMode={layout}/>
306
+ : <div className="flex items-center justify-center w-full h-full p-3">
307
+ <Typography variant={"label"}>
308
+ You need to save your entity before
309
+ adding additional collections
310
+ </Typography>
311
+ </div>)
312
+ }
313
+
314
+ </div>
315
+ );
316
+ }).filter(Boolean);
317
+
318
+ const onSideTabClick = (value: string) => {
319
+ setSelectedTab(value);
320
+ if (status === "existing") {
321
+ onTabChange?.({
322
+ path,
323
+ entityId,
324
+ selectedTab: value === MAIN_TAB_VALUE ? undefined : value,
325
+ collection
326
+ });
327
+ }
328
+ };
329
+
330
+ // Render the main entity form view (or a read-only view if the user cannot edit)
331
+ const entityView = <EntityForm<M>
332
+ collection={collection}
333
+ path={path}
334
+ entityId={entityId ?? usedEntity?.id}
335
+ onValuesModified={onValuesModified}
336
+ entity={entity}
337
+ initialDirtyValues={cachedDirtyValues}
338
+ openEntityMode={layout}
339
+ forceActionsAtTheBottom={actionsAtTheBottom}
340
+ initialStatus={status}
341
+ className={cls(!mainViewVisible ? "hidden" : "", formProps?.className)}
342
+ EntityFormActionsComponent={EntityEditViewFormActions}
343
+ {...formProps}
344
+ onEntityChange={(entity) => {
345
+ setUsedEntity(entity);
346
+ formProps?.onEntityChange?.(entity);
347
+ }}
348
+ onStatusChange={(status) => {
349
+ setStatus(status);
350
+ formProps?.onStatusChange?.(status);
351
+ }}
352
+ onFormContextReady={(formContext) => {
353
+ setFormContext(formContext);
354
+ formProps?.onFormContextReady?.(formContext);
355
+ }}
356
+ onSaved={(params) => {
357
+ const res = {
358
+ ...params,
359
+ selectedTab: MAIN_TAB_VALUE === selectedTab ? undefined : selectedTab,
360
+ };
361
+ onSaved?.(res);
362
+ formProps?.onSaved?.(res);
363
+ }}
364
+ />;
365
+
366
+ const subcollectionTabs = subcollections && subcollections.map((subcollection) =>
367
+ <Tab
368
+ className="text-sm min-w-[120px]"
369
+ value={subcollection.id}
370
+ key={`entity_detail_collection_tab_${subcollection.name}`}>
371
+ {subcollection.name}
372
+ </Tab>
373
+ );
374
+
375
+ const customViewTabs = resolvedEntityViews.map((view) =>
376
+ <Tab
377
+ className="text-sm min-w-[120px]"
378
+ value={view.key}
379
+ key={`entity_detail_collection_tab_${view.name}`}>
380
+ {view.name}
381
+ </Tab>
382
+ );
383
+
384
+ const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews;
385
+
386
+ let result = <div className="relative flex flex-col h-full w-full bg-white dark:bg-surface-900">
387
+
388
+ {shouldShowTopBar && <div
389
+ className={cls("h-14 flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex items-end bg-surface-50 dark:bg-surface-900", defaultBorderMixin)}>
390
+
391
+ {barActions}
392
+
393
+ <div className={"flex-grow"}/>
394
+
395
+ {globalLoading && <div className="self-center">
396
+ <CircularProgress size={"small"}/>
397
+ </div>}
398
+
399
+ {hasAdditionalViews && <Tabs
400
+ value={selectedTab}
401
+ onValueChange={(value) => {
402
+ onSideTabClick(value);
403
+ }}>
404
+
405
+ <Tab
406
+ disabled={!hasAdditionalViews}
407
+ value={MAIN_TAB_VALUE}
408
+ className={"text-sm min-w-[120px]"}>
409
+ {collection.singularName ?? collection.name}
410
+ </Tab>
411
+
412
+ {customViewTabs}
413
+
414
+ {subcollectionTabs}
415
+ </Tabs>}
416
+ </div>}
417
+
418
+ {globalLoading
419
+ ? <div className="w-full pt-12 pb-16 px-4 sm:px-8 md:px-10">
420
+ <CircularProgressCenter/>
421
+ </div>
422
+ : entityView}
423
+
424
+ {secondaryForms}
425
+
426
+ {customViewsView}
427
+
428
+ {subCollectionsViews}
429
+
430
+ </div>;
431
+
432
+ const plugins = customizationController.plugins;
433
+
434
+ if (plugins) {
435
+ plugins.forEach((plugin: FireCMSPlugin) => {
436
+ if (plugin.form?.provider) {
437
+ result = (
438
+ <plugin.form.provider.Component
439
+ status={status}
440
+ path={path}
441
+ collection={collection}
442
+ entity={usedEntity}
443
+ context={context}
444
+ formContext={formContext}
445
+ {...plugin.form.provider.props}>
446
+ {result}
447
+ </plugin.form.provider.Component>
448
+ );
449
+ }
450
+ });
451
+ }
452
+
453
+ return result;
454
+ }
455
+
@@ -0,0 +1,199 @@
1
+ import React, { useMemo } from "react";
2
+ import { Entity, EntityAction, FireCMSContext, ResolvedEntityCollection, SideEntityController } from "../types";
3
+
4
+ import { copyEntityAction, deleteEntityAction } from "../components";
5
+ import { canCreateEntity, canDeleteEntity, mergeEntityActions } from "../util";
6
+ import { Button, cls, defaultBorderMixin, DialogActions, IconButton, LoadingButton, Typography } from "@firecms/ui";
7
+ import { useAuthController, useFireCMSContext, useSideEntityController } from "../hooks";
8
+ import { EntityFormActionsProps } from "../form/EntityFormActions";
9
+ import { SideDialogController, useSideDialogContext } from "./SideDialogs";
10
+
11
+ export function EntityEditViewFormActions({
12
+ collection,
13
+ path,
14
+ entity,
15
+ layout,
16
+ savingError,
17
+ formex,
18
+ disabled,
19
+ status,
20
+ pluginActions,
21
+ openEntityMode,
22
+ showDefaultActions = true
23
+ }: EntityFormActionsProps) {
24
+
25
+ const authController = useAuthController();
26
+ const context = useFireCMSContext();
27
+ const sideEntityController = useSideEntityController();
28
+ const sideDialogContext = useSideDialogContext();
29
+
30
+ const entityActions = useMemo((): EntityAction[] => {
31
+ const customEntityActions = collection.entityActions
32
+ const createEnabled = canCreateEntity(collection, authController, path, null);
33
+ const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity) : false;
34
+ const actions: EntityAction[] = [];
35
+ if (createEnabled)
36
+ actions.push(copyEntityAction);
37
+ if (deleteEnabled)
38
+ actions.push(deleteEntityAction);
39
+ if (customEntityActions)
40
+ return mergeEntityActions(actions, customEntityActions);
41
+ return actions;
42
+ }, [authController, collection, path]);
43
+
44
+ const formActions = showDefaultActions ? entityActions.filter(a => a.includeInForm === undefined || a.includeInForm) : [];
45
+
46
+ return layout === "bottom"
47
+ ? buildBottomActions({
48
+ savingError,
49
+ entity,
50
+ formActions,
51
+ collection,
52
+ context,
53
+ sideEntityController,
54
+ isSubmitting: formex.isSubmitting,
55
+ disabled,
56
+ status,
57
+ sideDialogContext,
58
+ pluginActions,
59
+ openEntityMode,
60
+ })
61
+ : buildSideActions({
62
+ savingError,
63
+ entity,
64
+ formActions,
65
+ collection,
66
+ context,
67
+ sideEntityController,
68
+ isSubmitting: formex.isSubmitting,
69
+ sideDialogContext,
70
+ disabled,
71
+ status,
72
+ pluginActions,
73
+ openEntityMode,
74
+ });
75
+ }
76
+
77
+ type ActionsViewProps<M extends object> = {
78
+ savingError: Error | undefined,
79
+ entity: Entity<M> | undefined,
80
+ formActions: EntityAction[],
81
+ collection: ResolvedEntityCollection,
82
+ context: FireCMSContext,
83
+ sideEntityController: SideEntityController,
84
+ isSubmitting: boolean,
85
+ disabled: boolean,
86
+ status: "new" | "existing" | "copy",
87
+ sideDialogContext: SideDialogController,
88
+ pluginActions?: React.ReactNode[],
89
+ openEntityMode: "side_panel" | "full_screen";
90
+ };
91
+
92
+ function buildBottomActions<M extends object>({
93
+ savingError,
94
+ entity,
95
+ formActions,
96
+ collection,
97
+ context,
98
+ sideEntityController,
99
+ isSubmitting,
100
+ disabled,
101
+ status,
102
+ sideDialogContext,
103
+ pluginActions,
104
+ openEntityMode,
105
+ }: ActionsViewProps<M>) {
106
+
107
+ const canClose = openEntityMode === "side_panel";
108
+ return <DialogActions position={"absolute"}>
109
+ {savingError &&
110
+ <div className="text-right">
111
+ <Typography color={"error"}>{savingError.message}</Typography>
112
+ </div>
113
+ }
114
+ {entity && formActions.length > 0 && <div className="flex-grow flex overflow-auto no-scrollbar">
115
+ {formActions.map(action => (
116
+ <IconButton
117
+ key={action.name}
118
+ color="primary"
119
+ onClick={(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
120
+ event.stopPropagation();
121
+ if (entity)
122
+ action.onClick({
123
+ entity,
124
+ fullPath: collection.path,
125
+ collection: collection,
126
+ context,
127
+ sideEntityController,
128
+ openEntityMode: openEntityMode
129
+ });
130
+ }}>
131
+ {action.icon}
132
+ </IconButton>
133
+ ))}
134
+ </div>}
135
+ {pluginActions}
136
+ <Button variant="text" disabled={disabled || isSubmitting} type="reset">
137
+ {status === "existing" ? "Discard" : "Clear"}
138
+ </Button>
139
+ <Button variant={canClose ? "text" : "filled"} color="primary" type="submit"
140
+ disabled={disabled || isSubmitting}
141
+ onClick={() => {
142
+ sideDialogContext.setPendingClose(false);
143
+ }}>
144
+ {status === "existing" && "Save"}
145
+ {status === "copy" && "Create copy"}
146
+ {status === "new" && "Create"}
147
+ </Button>
148
+ {canClose && <LoadingButton variant="filled"
149
+ color="primary"
150
+ type="submit"
151
+ loading={isSubmitting}
152
+ disabled={disabled}
153
+ onClick={() => {
154
+ sideDialogContext.setPendingClose?.(true);
155
+ }}>
156
+ {status === "existing" && "Save and close"}
157
+ {status === "copy" && "Create copy and close"}
158
+ {status === "new" && "Create and close"}
159
+ </LoadingButton>}
160
+ </DialogActions>;
161
+ }
162
+
163
+ function buildSideActions<M extends object>({
164
+ savingError,
165
+ entity,
166
+ formActions,
167
+ collection,
168
+ context,
169
+ sideEntityController,
170
+ isSubmitting,
171
+ disabled,
172
+ status,
173
+ sideDialogContext,
174
+ pluginActions
175
+ }: ActionsViewProps<M>) {
176
+
177
+ return <div
178
+ className={cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", defaultBorderMixin)}>
179
+ <LoadingButton fullWidth={true} variant="filled" color="primary" type="submit" size={"large"}
180
+ disabled={disabled || isSubmitting} onClick={() => {
181
+ sideDialogContext.setPendingClose?.(false);
182
+ }}>
183
+ {status === "existing" && "Save"}
184
+ {status === "copy" && "Create copy"}
185
+ {status === "new" && "Create"}
186
+ </LoadingButton>
187
+ <Button fullWidth={true} variant="text" disabled={disabled || isSubmitting} type="reset">
188
+ {status === "existing" ? "Discard" : "Clear"}
189
+ </Button>
190
+
191
+ {pluginActions}
192
+
193
+ {savingError &&
194
+ <div className="text-right">
195
+ <Typography color={"error"}>{savingError.message}</Typography>
196
+ </div>
197
+ }
198
+ </div>;
199
+ }