@firecms/core 3.0.0-canary.29 → 3.0.0-canary.290

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 (433) hide show
  1. package/README.md +3 -3
  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 +34 -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 +31 -12
  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 +14 -13
  12. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  13. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +22 -6
  14. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
  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 +20 -2
  22. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  23. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  24. package/dist/components/EntityJsonPreview.d.ts +3 -0
  25. package/dist/components/EntityPreview.d.ts +10 -7
  26. package/dist/components/ErrorView.d.ts +1 -1
  27. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  28. package/dist/components/HomePage/HomePageDnD.d.ts +77 -0
  29. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  30. package/dist/components/HomePage/NavigationCardBinding.d.ts +4 -3
  31. package/dist/components/HomePage/NavigationGroup.d.ts +8 -1
  32. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  33. package/dist/components/PropertyCollectionView.d.ts +23 -0
  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 +3 -1
  37. package/dist/components/SelectableTable/SelectableTable.d.ts +14 -4
  38. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  39. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  40. package/dist/components/UserDisplay.d.ts +7 -0
  41. package/dist/components/VirtualTable/VirtualTableProps.d.ts +24 -12
  42. package/dist/components/VirtualTable/fields/VirtualTableUserSelect.d.ts +12 -0
  43. package/dist/components/VirtualTable/types.d.ts +3 -3
  44. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -3
  45. package/dist/components/common/index.d.ts +2 -1
  46. package/dist/components/common/table_height.d.ts +5 -0
  47. package/dist/components/common/types.d.ts +4 -6
  48. package/dist/components/common/useColumnsIds.d.ts +3 -1
  49. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +13 -2
  50. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  51. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  52. package/dist/components/index.d.ts +5 -2
  53. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  54. package/dist/contexts/InternalUserManagementContext.d.ts +3 -0
  55. package/dist/core/DefaultAppBar.d.ts +29 -0
  56. package/dist/core/DefaultDrawer.d.ts +19 -0
  57. package/dist/core/DrawerNavigationItem.d.ts +10 -0
  58. package/dist/core/EntityEditView.d.ts +49 -11
  59. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  60. package/dist/core/FireCMS.d.ts +2 -3
  61. package/dist/core/FireCMSRouter.d.ts +4 -0
  62. package/dist/core/NavigationRoutes.d.ts +2 -3
  63. package/dist/core/SideDialogs.d.ts +4 -2
  64. package/dist/core/field_configs.d.ts +1 -1
  65. package/dist/core/index.d.ts +4 -4
  66. package/dist/form/EntityForm.d.ts +40 -64
  67. package/dist/form/EntityFormActions.d.ts +21 -0
  68. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  69. package/dist/form/components/ErrorFocus.d.ts +1 -1
  70. package/dist/form/components/FieldHelperText.d.ts +3 -3
  71. package/dist/form/components/FormEntry.d.ts +6 -0
  72. package/dist/form/components/FormLayout.d.ts +5 -0
  73. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  74. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  75. package/dist/form/components/LocalChangesMenu.d.ts +11 -0
  76. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  77. package/dist/form/components/index.d.ts +3 -1
  78. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  79. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  80. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  81. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  82. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  83. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  84. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  85. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  86. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  87. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  88. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  89. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  90. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +5 -13
  91. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  92. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  93. package/dist/form/field_bindings/UserSelectFieldBinding.d.ts +12 -0
  94. package/dist/form/index.d.ts +18 -18
  95. package/dist/form/useClearRestoreValue.d.ts +2 -2
  96. package/dist/hooks/data/delete.d.ts +4 -4
  97. package/dist/hooks/data/save.d.ts +4 -5
  98. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  99. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  100. package/dist/hooks/index.d.ts +3 -0
  101. package/dist/hooks/useAuthController.d.ts +1 -1
  102. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  103. package/dist/hooks/useBuildNavigationController.d.ts +57 -13
  104. package/dist/hooks/useCollapsedGroups.d.ts +9 -0
  105. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  106. package/dist/hooks/useInternalUserManagementController.d.ts +12 -0
  107. package/dist/hooks/useModeController.d.ts +1 -2
  108. package/dist/hooks/useProjectLog.d.ts +8 -2
  109. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  110. package/dist/hooks/useValidateAuthenticator.d.ts +4 -8
  111. package/dist/index.d.ts +1 -0
  112. package/dist/index.es.js +24546 -13965
  113. package/dist/index.es.js.map +1 -1
  114. package/dist/index.umd.js +27256 -588
  115. package/dist/index.umd.js.map +1 -1
  116. package/dist/internal/useBuildDataSource.d.ts +3 -17
  117. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  118. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  119. package/dist/preview/PropertyPreviewProps.d.ts +6 -1
  120. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  121. package/dist/preview/components/ReferencePreview.d.ts +4 -3
  122. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  123. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  124. package/dist/preview/components/UserPreview.d.ts +8 -0
  125. package/dist/preview/index.d.ts +1 -0
  126. package/dist/preview/util.d.ts +3 -3
  127. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  128. package/dist/routes/FireCMSRoute.d.ts +1 -0
  129. package/dist/routes/HomePageRoute.d.ts +3 -0
  130. package/dist/types/analytics.d.ts +1 -1
  131. package/dist/types/auth.d.ts +8 -10
  132. package/dist/types/collections.d.ts +123 -25
  133. package/dist/types/customization_controller.d.ts +8 -0
  134. package/dist/types/datasource.d.ts +52 -36
  135. package/dist/types/dialogs_controller.d.ts +7 -3
  136. package/dist/types/entities.d.ts +12 -3
  137. package/dist/types/entity_actions.d.ts +72 -8
  138. package/dist/types/entity_callbacks.d.ts +16 -16
  139. package/dist/types/entity_overrides.d.ts +2 -2
  140. package/dist/types/export_import.d.ts +4 -4
  141. package/dist/types/fields.d.ts +79 -39
  142. package/dist/types/firecms.d.ts +31 -3
  143. package/dist/types/firecms_context.d.ts +17 -1
  144. package/dist/types/index.d.ts +1 -1
  145. package/dist/types/internal_user_management.d.ts +20 -0
  146. package/dist/types/navigation.d.ts +62 -19
  147. package/dist/types/permissions.d.ts +4 -4
  148. package/dist/types/plugins.d.ts +58 -13
  149. package/dist/types/properties.d.ts +122 -31
  150. package/dist/types/property_config.d.ts +1 -3
  151. package/dist/types/roles.d.ts +3 -0
  152. package/dist/types/side_dialogs_controller.d.ts +10 -0
  153. package/dist/types/side_entity_controller.d.ts +14 -1
  154. package/dist/types/storage.d.ts +75 -0
  155. package/dist/types/user.d.ts +2 -1
  156. package/dist/util/builders.d.ts +3 -3
  157. package/dist/util/callbacks.d.ts +2 -0
  158. package/dist/util/collections.d.ts +1 -0
  159. package/dist/util/createFormexStub.d.ts +2 -0
  160. package/dist/util/entities.d.ts +3 -3
  161. package/dist/util/entity_actions.d.ts +2 -0
  162. package/dist/util/entity_cache.d.ts +28 -0
  163. package/dist/util/icon_list.d.ts +5 -1
  164. package/dist/util/icon_synonyms.d.ts +1 -98
  165. package/dist/util/icons.d.ts +7 -4
  166. package/dist/util/index.d.ts +3 -0
  167. package/dist/util/make_properties_editable.d.ts +1 -2
  168. package/dist/util/navigation_from_path.d.ts +10 -1
  169. package/dist/util/navigation_utils.d.ts +15 -3
  170. package/dist/util/objects.d.ts +3 -1
  171. package/dist/util/permissions.d.ts +4 -4
  172. package/dist/util/plurals.d.ts +0 -2
  173. package/dist/util/property_utils.d.ts +4 -4
  174. package/dist/util/references.d.ts +2 -2
  175. package/dist/util/resolutions.d.ts +42 -17
  176. package/dist/util/storage.d.ts +23 -2
  177. package/dist/util/useStorageUploadController.d.ts +4 -3
  178. package/package.json +70 -53
  179. package/src/app/AppBar.tsx +18 -0
  180. package/src/app/Drawer.tsx +24 -0
  181. package/src/app/Scaffold.tsx +253 -0
  182. package/src/app/index.ts +4 -0
  183. package/src/app/useApp.tsx +32 -0
  184. package/src/components/ArrayContainer.tsx +447 -229
  185. package/src/components/CircularProgressCenter.tsx +2 -2
  186. package/src/components/ClearFilterSortButton.tsx +41 -0
  187. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +12 -11
  188. package/src/components/DeleteEntityDialog.tsx +13 -20
  189. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +87 -62
  190. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +38 -31
  191. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +30 -9
  192. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +84 -42
  193. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  194. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +30 -16
  195. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +19 -17
  196. package/src/components/EntityCollectionTable/index.tsx +1 -1
  197. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +34 -39
  198. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +49 -36
  199. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
  200. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +135 -105
  201. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
  202. package/src/components/EntityCollectionView/EntityCollectionView.tsx +241 -119
  203. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +7 -4
  204. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  205. package/src/components/EntityCollectionView/useSelectionController.tsx +20 -7
  206. package/src/components/EntityCollectionView/utils.ts +19 -0
  207. package/src/components/EntityJsonPreview.tsx +66 -0
  208. package/src/components/EntityPreview.tsx +83 -62
  209. package/src/components/EntityView.tsx +34 -42
  210. package/src/components/ErrorView.tsx +4 -4
  211. package/src/components/FireCMSLogo.tsx +7 -51
  212. package/src/components/HomePage/DefaultHomePage.tsx +516 -158
  213. package/src/components/HomePage/FavouritesView.tsx +9 -14
  214. package/src/components/HomePage/HomePageDnD.tsx +702 -0
  215. package/src/components/HomePage/NavigationCard.tsx +48 -39
  216. package/src/components/HomePage/NavigationCardBinding.tsx +17 -16
  217. package/src/components/HomePage/NavigationGroup.tsx +144 -30
  218. package/src/components/HomePage/RenameGroupDialog.tsx +123 -0
  219. package/src/components/HomePage/SmallNavigationCard.tsx +5 -6
  220. package/src/components/NotFoundPage.tsx +2 -2
  221. package/src/components/PropertyCollectionView.tsx +329 -0
  222. package/src/components/PropertyConfigBadge.tsx +10 -4
  223. package/src/components/PropertyIdCopyTooltip.tsx +47 -0
  224. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +23 -13
  225. package/src/components/ReferenceWidget.tsx +21 -11
  226. package/src/components/SearchIconsView.tsx +10 -7
  227. package/src/components/SelectableTable/SelectableTable.tsx +157 -157
  228. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  229. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +27 -9
  230. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +36 -12
  231. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +92 -24
  232. package/src/components/UnsavedChangesDialog.tsx +46 -0
  233. package/src/components/UserDisplay.tsx +55 -0
  234. package/src/components/VirtualTable/VirtualTable.tsx +105 -51
  235. package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
  236. package/src/components/VirtualTable/VirtualTableHeader.tsx +10 -10
  237. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  238. package/src/components/VirtualTable/VirtualTableProps.tsx +28 -14
  239. package/src/components/VirtualTable/VirtualTableRow.tsx +5 -6
  240. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +5 -5
  241. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -2
  242. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  243. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
  244. package/src/components/VirtualTable/fields/VirtualTableUserSelect.tsx +99 -0
  245. package/src/components/VirtualTable/types.tsx +2 -3
  246. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +64 -44
  247. package/src/components/common/index.ts +2 -1
  248. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  249. package/src/components/common/types.tsx +4 -6
  250. package/src/components/common/useColumnsIds.tsx +16 -2
  251. package/src/components/common/useDataSourceTableController.tsx +420 -0
  252. package/src/components/common/useDebouncedCallback.tsx +20 -0
  253. package/src/components/common/useScrollRestoration.tsx +68 -0
  254. package/src/components/common/useTableSearchHelper.ts +53 -12
  255. package/src/components/index.tsx +6 -2
  256. package/src/contexts/BreacrumbsContext.tsx +38 -0
  257. package/src/contexts/DialogsProvider.tsx +5 -4
  258. package/src/contexts/InternalUserManagementContext.tsx +4 -0
  259. package/src/contexts/ModeController.tsx +1 -3
  260. package/src/contexts/SnackbarProvider.tsx +2 -0
  261. package/src/core/DefaultAppBar.tsx +219 -0
  262. package/src/core/DefaultDrawer.tsx +185 -0
  263. package/src/core/DrawerNavigationItem.tsx +66 -0
  264. package/src/core/EntityEditView.tsx +447 -469
  265. package/src/core/EntityEditViewFormActions.tsx +344 -0
  266. package/src/core/EntitySidePanel.tsx +96 -23
  267. package/src/core/FireCMS.tsx +85 -60
  268. package/src/core/FireCMSRouter.tsx +17 -0
  269. package/src/core/NavigationRoutes.tsx +28 -38
  270. package/src/core/SideDialogs.tsx +22 -12
  271. package/src/core/field_configs.tsx +41 -14
  272. package/src/core/index.tsx +6 -5
  273. package/src/form/EntityForm.tsx +740 -523
  274. package/src/form/EntityFormActions.tsx +226 -0
  275. package/src/form/PropertyFieldBinding.tsx +88 -41
  276. package/src/form/components/CustomIdField.tsx +9 -3
  277. package/src/form/components/ErrorFocus.tsx +22 -29
  278. package/src/form/components/FieldHelperText.tsx +4 -4
  279. package/src/form/components/FormEntry.tsx +22 -0
  280. package/src/form/components/FormLayout.tsx +16 -0
  281. package/src/form/components/LabelWithIcon.tsx +30 -19
  282. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  283. package/src/form/components/LocalChangesMenu.tsx +144 -0
  284. package/src/form/components/StorageItemPreview.tsx +23 -13
  285. package/src/form/components/StorageUploadProgress.tsx +5 -6
  286. package/src/form/components/index.tsx +3 -1
  287. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +34 -19
  288. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +50 -36
  289. package/src/form/field_bindings/BlockFieldBinding.tsx +56 -33
  290. package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -14
  291. package/src/form/field_bindings/KeyValueFieldBinding.tsx +61 -52
  292. package/src/form/field_bindings/MapFieldBinding.tsx +73 -55
  293. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +159 -0
  294. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -21
  295. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +11 -16
  296. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  297. package/src/form/field_bindings/ReferenceFieldBinding.tsx +42 -31
  298. package/src/form/field_bindings/RepeatFieldBinding.tsx +62 -35
  299. package/src/form/field_bindings/SelectFieldBinding.tsx +24 -15
  300. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +257 -199
  301. package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
  302. package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
  303. package/src/form/field_bindings/UserSelectFieldBinding.tsx +94 -0
  304. package/src/form/index.tsx +21 -37
  305. package/src/form/useClearRestoreValue.tsx +2 -2
  306. package/src/form/validation.ts +13 -23
  307. package/src/hooks/data/delete.ts +6 -5
  308. package/src/hooks/data/save.ts +26 -33
  309. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  310. package/src/hooks/data/useDataSource.tsx +11 -3
  311. package/src/hooks/data/useEntityFetch.tsx +10 -6
  312. package/src/hooks/index.tsx +4 -0
  313. package/src/hooks/useAuthController.tsx +1 -1
  314. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  315. package/src/hooks/useBrowserTitleAndIcon.tsx +1 -1
  316. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
  317. package/src/hooks/useBuildModeController.tsx +22 -29
  318. package/src/hooks/useBuildNavigationController.tsx +515 -121
  319. package/src/hooks/useCollapsedGroups.ts +64 -0
  320. package/src/hooks/useFireCMSContext.tsx +9 -35
  321. package/src/hooks/useInternalUserManagementController.tsx +16 -0
  322. package/src/hooks/useLargeLayout.tsx +0 -35
  323. package/src/hooks/useModeController.tsx +1 -2
  324. package/src/hooks/useProjectLog.tsx +32 -10
  325. package/src/hooks/useResolvedNavigationFrom.tsx +10 -12
  326. package/src/hooks/useValidateAuthenticator.tsx +17 -37
  327. package/src/index.ts +1 -0
  328. package/src/internal/useBuildDataSource.ts +79 -85
  329. package/src/internal/useBuildSideDialogsController.tsx +4 -2
  330. package/src/internal/useBuildSideEntityController.tsx +204 -77
  331. package/src/internal/useUnsavedChangesDialog.tsx +127 -91
  332. package/src/preview/PropertyPreview.tsx +42 -25
  333. package/src/preview/PropertyPreviewProps.tsx +7 -1
  334. package/src/preview/components/BooleanPreview.tsx +2 -2
  335. package/src/preview/components/EmptyValue.tsx +1 -1
  336. package/src/preview/components/EnumValuesChip.tsx +2 -2
  337. package/src/preview/components/ImagePreview.tsx +26 -37
  338. package/src/preview/components/ReferencePreview.tsx +30 -38
  339. package/src/preview/components/StorageThumbnail.tsx +5 -1
  340. package/src/preview/components/UrlComponentPreview.tsx +60 -28
  341. package/src/preview/components/UserPreview.tsx +27 -0
  342. package/src/preview/index.ts +1 -0
  343. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +6 -6
  344. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +7 -5
  345. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +5 -4
  346. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -4
  347. package/src/preview/property_previews/ArrayOneOfPreview.tsx +7 -6
  348. package/src/preview/property_previews/ArrayPropertyPreview.tsx +8 -7
  349. package/src/preview/property_previews/MapPropertyPreview.tsx +14 -13
  350. package/src/preview/property_previews/NumberPropertyPreview.tsx +2 -2
  351. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +13 -13
  352. package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
  353. package/src/preview/util.ts +10 -10
  354. package/src/routes/CustomCMSRoute.tsx +21 -0
  355. package/src/routes/FireCMSRoute.tsx +246 -0
  356. package/src/routes/HomePageRoute.tsx +17 -0
  357. package/src/types/analytics.ts +3 -0
  358. package/src/types/auth.tsx +9 -13
  359. package/src/types/collections.ts +146 -30
  360. package/src/types/customization_controller.tsx +9 -1
  361. package/src/types/datasource.ts +61 -43
  362. package/src/types/dialogs_controller.tsx +7 -3
  363. package/src/types/entities.ts +19 -3
  364. package/src/types/entity_actions.tsx +86 -10
  365. package/src/types/entity_callbacks.ts +18 -18
  366. package/src/types/entity_overrides.tsx +2 -2
  367. package/src/types/export_import.ts +4 -4
  368. package/src/types/fields.tsx +91 -42
  369. package/src/types/firecms.tsx +34 -4
  370. package/src/types/firecms_context.tsx +18 -1
  371. package/src/types/index.ts +1 -1
  372. package/src/types/internal_user_management.ts +24 -0
  373. package/src/types/navigation.ts +77 -24
  374. package/src/types/permissions.ts +5 -5
  375. package/src/types/plugins.tsx +69 -15
  376. package/src/types/properties.ts +141 -33
  377. package/src/types/property_config.tsx +2 -2
  378. package/src/types/roles.ts +3 -0
  379. package/src/types/side_dialogs_controller.tsx +15 -0
  380. package/src/types/side_entity_controller.tsx +16 -1
  381. package/src/types/storage.ts +83 -1
  382. package/src/types/user.ts +3 -1
  383. package/src/util/builders.ts +10 -8
  384. package/src/util/callbacks.ts +119 -0
  385. package/src/util/collections.ts +8 -0
  386. package/src/util/createFormexStub.tsx +66 -0
  387. package/src/util/entities.ts +11 -8
  388. package/src/util/entity_actions.ts +28 -0
  389. package/src/util/entity_cache.ts +223 -0
  390. package/src/util/enums.ts +1 -1
  391. package/src/util/icon_list.ts +16 -10
  392. package/src/util/icon_synonyms.ts +3 -100
  393. package/src/util/icons.tsx +36 -11
  394. package/src/util/index.ts +3 -0
  395. package/src/util/join_collections.ts +11 -4
  396. package/src/util/make_properties_editable.ts +5 -19
  397. package/src/util/navigation_from_path.ts +33 -12
  398. package/src/util/navigation_utils.ts +141 -25
  399. package/src/util/objects.ts +128 -33
  400. package/src/util/parent_references_from_path.ts +3 -3
  401. package/src/util/permissions.ts +9 -8
  402. package/src/util/plurals.ts +0 -2
  403. package/src/util/property_utils.tsx +17 -6
  404. package/src/util/references.ts +19 -8
  405. package/src/util/resolutions.ts +122 -48
  406. package/src/util/storage.ts +79 -21
  407. package/src/util/strings.ts +2 -2
  408. package/src/util/useStorageUploadController.tsx +162 -62
  409. package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
  410. package/dist/components/FireCMSAppBar.d.ts +0 -26
  411. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  412. package/dist/components/VirtualTable/common.d.ts +0 -2
  413. package/dist/core/Drawer.d.ts +0 -23
  414. package/dist/core/Scaffold.d.ts +0 -55
  415. package/dist/core/SideEntityView.d.ts +0 -7
  416. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  417. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  418. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  419. package/dist/internal/useLocaleConfig.d.ts +0 -1
  420. package/dist/types/appcheck.d.ts +0 -26
  421. package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
  422. package/src/components/FireCMSAppBar.tsx +0 -165
  423. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -28
  424. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -225
  425. package/src/core/Drawer.tsx +0 -191
  426. package/src/core/Scaffold.tsx +0 -281
  427. package/src/core/SideEntityView.tsx +0 -38
  428. package/src/form/components/FormikArrayContainer.tsx +0 -44
  429. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
  430. package/src/internal/useBuildCustomizationController.tsx +0 -5
  431. package/src/internal/useLocaleConfig.tsx +0 -18
  432. package/src/types/appcheck.ts +0 -29
  433. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -1,50 +1,56 @@
1
- import React, { useCallback } from "react";
1
+ import React, { useCallback, useState } from "react";
2
2
 
3
3
  import {
4
- ArrayProperty,
5
- Entity,
6
- EntityCollection,
7
4
  FieldProps,
5
+ PropertyOrBuilder,
8
6
  ResolvedArrayProperty,
9
7
  ResolvedStringProperty,
10
8
  StorageConfig
11
9
  } from "../../types";
12
10
  import { useDropzone } from "react-dropzone";
13
11
  import { PreviewSize } from "../../preview";
14
- import { FieldHelperText, LabelWithIcon } from "../components";
12
+ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
15
13
 
16
- import { getIconForProperty, isReadOnly } from "../../util";
17
- import { useSnackbarController, useStorageSource } from "../../hooks";
18
- import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
14
+ import { getIconForProperty, isReadOnly, resolveProperty } from "../../util";
15
+ import { useAuthController, useSnackbarController, useStorageSource } from "../../hooks";
16
+ import {
17
+ closestCenter,
18
+ DndContext,
19
+ DragEndEvent,
20
+ DragStartEvent,
21
+ KeyboardSensor,
22
+ PointerSensor,
23
+ useSensor,
24
+ useSensors
25
+ } from "@dnd-kit/core";
26
+ import {
27
+ horizontalListSortingStrategy,
28
+ SortableContext,
29
+ sortableKeyboardCoordinates,
30
+ useSortable
31
+ } from "@dnd-kit/sortable";
32
+ import { CSS } from "@dnd-kit/utilities";
19
33
  import { StorageFieldItem, useStorageUploadController } from "../../util/useStorageUploadController";
20
34
  import { StorageUploadProgress } from "../components/StorageUploadProgress";
21
35
  import { StorageItemPreview } from "../components/StorageItemPreview";
22
36
  import {
23
- cn,
37
+ cls,
24
38
  fieldBackgroundDisabledMixin,
25
39
  fieldBackgroundHoverMixin,
26
40
  fieldBackgroundMixin,
27
- focusedMixin,
28
41
  Typography
29
42
  } from "@firecms/ui";
30
43
  import { useClearRestoreValue } from "../useClearRestoreValue";
31
44
 
32
45
  const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
33
- const disabledClasses = "border-dotted-gray"
34
- const nonActiveDropClasses = "hover:bg-field-hover dark:hover:bg-field-hover-dark"
46
+ const disabledClasses = fieldBackgroundDisabledMixin;
47
+ const nonActiveDropClasses = fieldBackgroundHoverMixin
35
48
  const activeDropClasses = "pt-0 border-2 border-solid"
36
49
  const acceptDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500"
37
50
  const rejectDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-red-500"
38
51
 
39
52
  type StorageUploadFieldProps = FieldProps<string | string[]>;
40
53
 
41
- /**
42
- * Field that allows to upload files to Google Cloud Storage.
43
- *
44
- * This is one of the internal components that get mapped natively inside forms
45
- * and tables to the specified properties.
46
- * @group Form fields
47
- */
48
54
  export function StorageUploadFieldBinding({
49
55
  propertyKey,
50
56
  value,
@@ -52,18 +58,20 @@ export function StorageUploadFieldBinding({
52
58
  error,
53
59
  showError,
54
60
  autoFocus,
55
- tableMode,
61
+ minimalistView,
56
62
  property,
57
63
  includeDescription,
58
64
  context,
59
65
  isSubmitting,
60
66
  }: StorageUploadFieldProps) {
61
67
 
68
+ const authController = useAuthController();
69
+
62
70
  if (!context.entityId)
63
71
  throw new Error("StorageUploadFieldBinding: Entity id is null");
64
72
 
65
73
  const storageSource = useStorageSource(context.collection);
66
- const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
74
+ const disabled = isReadOnly(property) || !!property.disabled || isSubmitting || context.disabled;
67
75
 
68
76
  const {
69
77
  internalValue,
@@ -81,7 +89,7 @@ export function StorageUploadFieldBinding({
81
89
  propertyKey,
82
90
  value,
83
91
  storageSource,
84
- disabled,
92
+ disabled: disabled ?? false,
85
93
  onChange: setValue
86
94
  });
87
95
 
@@ -91,33 +99,32 @@ export function StorageUploadFieldBinding({
91
99
  setValue
92
100
  });
93
101
 
94
- const entity: Entity<any> = {
95
- id: context.entityId,
96
- values: context.values,
97
- path: context.path
98
- };
102
+ const resolvedProperty = resolveProperty({
103
+ propertyOrBuilder: property as PropertyOrBuilder,
104
+ authController
105
+ }) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
99
106
 
100
107
  return (
101
108
 
102
109
  <>
103
110
 
104
- {!tableMode &&
105
- <LabelWithIcon icon={getIconForProperty(property, "small")}
106
- required={property.validation?.required}
107
- title={property.name}
108
- className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
111
+ {!minimalistView &&
112
+ <LabelWithIconAndTooltip
113
+ propertyKey={propertyKey}
114
+ icon={getIconForProperty(property, "small")}
115
+ required={property.validation?.required}
116
+ title={property.name}
117
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
109
118
 
110
119
  <StorageUpload
111
120
  value={internalValue}
112
- collection={context.collection}
113
121
  name={propertyKey}
114
- disabled={disabled}
115
- autoFocus={autoFocus}
116
- property={property}
122
+ disabled={disabled ?? false}
123
+ autoFocus={autoFocus ?? false}
124
+ property={resolvedProperty}
117
125
  onChange={setValue}
118
126
  setInternalValue={setInternalValue}
119
127
  onFilesAdded={onFilesAdded}
120
- entity={entity}
121
128
  onFileUploadComplete={onFileUploadComplete}
122
129
  storagePathBuilder={storagePathBuilder}
123
130
  storage={storage}
@@ -133,44 +140,126 @@ export function StorageUploadFieldBinding({
133
140
  );
134
141
  }
135
142
 
143
+ interface SortableStorageItemProps {
144
+ id: number;
145
+ entry: StorageFieldItem;
146
+ property: ResolvedStringProperty;
147
+ name: string;
148
+ metadata?: Record<string, unknown>;
149
+ storagePathBuilder: (file: File) => string;
150
+ onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>;
151
+ onClear: (clearedStoragePathOrDownloadUrl: string) => void;
152
+ disabled: boolean;
153
+ isSortable: boolean; // Kept for consistency, though dnd-kit handles sortability via context
154
+ }
155
+
156
+ function SortableStorageItem({
157
+ id,
158
+ entry,
159
+ property,
160
+ metadata,
161
+ storagePathBuilder,
162
+ onFileUploadComplete,
163
+ onClear,
164
+ disabled,
165
+ }: SortableStorageItemProps) {
166
+
167
+ const {
168
+ attributes,
169
+ listeners,
170
+ setNodeRef,
171
+ transform,
172
+ transition,
173
+ isDragging
174
+ } = useSortable({ id });
175
+
176
+ const style: React.CSSProperties = {
177
+ transform: CSS.Transform.toString(transform),
178
+ transition,
179
+ zIndex: isDragging ? 100 : undefined
180
+ };
181
+
182
+ const getImageSizeNumber = (previewSize: PreviewSize): number => {
183
+ switch (previewSize) {
184
+ case "small":
185
+ return 40;
186
+ case "medium":
187
+ return 118;
188
+ case "large":
189
+ return 220;
190
+ default:
191
+ return 118;
192
+ }
193
+ };
194
+
195
+ let child: React.ReactNode;
196
+ if (entry.storagePathOrDownloadUrl) {
197
+ child = (
198
+ <StorageItemPreview
199
+ name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
200
+ property={property}
201
+ disabled={disabled}
202
+ value={entry.storagePathOrDownloadUrl}
203
+ onRemove={() => onClear(entry.storagePathOrDownloadUrl!)}
204
+ size={entry.size}/>
205
+ );
206
+ } else if (entry.file) {
207
+ child = (
208
+ <StorageUploadProgress
209
+ entry={entry}
210
+ metadata={metadata}
211
+ storagePath={storagePathBuilder(entry.file)}
212
+ onFileUploadComplete={onFileUploadComplete}
213
+ imageSize={getImageSizeNumber(entry.size)}
214
+ simple={false}
215
+ />
216
+ );
217
+ }
218
+
219
+ return (
220
+ <div
221
+ ref={setNodeRef}
222
+ style={style}
223
+ {...attributes}
224
+ {...listeners}
225
+ className={cls("rounded-md m-1")}
226
+ tabIndex={-1}
227
+ >
228
+ {child}
229
+ </div>
230
+ );
231
+ }
232
+
136
233
  function FileDropComponent({
137
234
  storage,
138
- collection,
139
235
  disabled,
140
- isDraggingOver,
141
236
  onFilesAdded,
142
237
  multipleFilesSupported,
143
- droppableProvided,
144
238
  autoFocus,
145
239
  internalValue,
146
240
  property,
147
- entity,
148
241
  onClear,
149
242
  metadata,
150
243
  storagePathBuilder,
151
244
  onFileUploadComplete,
152
- size,
153
245
  name,
154
- helpText
246
+ helpText,
247
+ isDndItemDragging
155
248
  }: {
156
249
  storage: StorageConfig,
157
- collection: EntityCollection,
158
250
  disabled: boolean,
159
- isDraggingOver: boolean,
160
- droppableProvided: any,
161
- onFilesAdded: (acceptedFiles: File[]) => void,
251
+ onFilesAdded: (acceptedFiles: File[]) => Promise<void>,
162
252
  multipleFilesSupported: boolean,
163
253
  autoFocus: boolean,
164
254
  internalValue: StorageFieldItem[],
165
255
  property: ResolvedStringProperty,
166
256
  onClear: (clearedStoragePathOrDownloadUrl: string) => void,
167
- metadata: any,
168
- entity: Entity<any>;
257
+ metadata?: any,
169
258
  storagePathBuilder: (file: File) => string,
170
259
  onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>,
171
- size: PreviewSize,
172
260
  name: string,
173
- helpText: string
261
+ helpText: string,
262
+ isDndItemDragging?: boolean
174
263
  }) {
175
264
 
176
265
  const snackbarContext = useSnackbarController();
@@ -178,22 +267,33 @@ function FileDropComponent({
178
267
  const {
179
268
  getRootProps,
180
269
  getInputProps,
181
- isDragActive,
270
+ isDragActive, // This is for files dragged from OS
182
271
  isDragAccept,
183
272
  isDragReject
184
273
  } = useDropzone({
185
- accept: storage.acceptedFiles ? storage.acceptedFiles.map(e => ({ [e]: [] })).reduce((a, b) => ({ ...a, ...b }), {}) : undefined,
186
- disabled: disabled || isDraggingOver,
274
+ accept: storage.acceptedFiles ? storage.acceptedFiles.reduce((acc, ext) => ({
275
+ ...acc,
276
+ [ext]: []
277
+ }), {}) : undefined,
278
+ disabled: disabled || isDndItemDragging,
187
279
  noDragEventsBubbling: true,
188
280
  maxSize: storage.maxSize,
189
281
  onDrop: onFilesAdded,
190
- onDropRejected: (fileRejections, event) => {
282
+ onDropRejected: (fileRejections) => {
191
283
  for (const fileRejection of fileRejections) {
192
284
  for (const error of fileRejection.errors) {
193
- snackbarContext.open({
194
- type: "error",
195
- message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
196
- });
285
+ console.error("Error uploading file: ", error);
286
+ if (error.code === "file-too-large") {
287
+ snackbarContext.open({
288
+ type: "error",
289
+ message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
290
+ });
291
+ } else if (error.code === "file-invalid-type") {
292
+ snackbarContext.open({
293
+ type: "error",
294
+ message: "Error uploading file: File type is not supported"
295
+ });
296
+ }
197
297
  }
198
298
  }
199
299
  }
@@ -203,103 +303,63 @@ function FileDropComponent({
203
303
  return (
204
304
  <div
205
305
  {...getRootProps()}
206
- className={cn(
306
+ className={cls(
207
307
  fieldBackgroundMixin,
208
308
  disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
309
+ disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "",
209
310
  dropZoneClasses,
210
311
  multipleFilesSupported && internalValue.length ? "" : "flex",
211
- focusedMixin,
212
312
  {
213
313
  [nonActiveDropClasses]: !isDragActive,
214
- [activeDropClasses]: isDragActive,
215
- [rejectDropClasses]: isDragReject,
216
- [acceptDropClasses]: isDragAccept,
217
- [disabledClasses]: disabled
314
+ [activeDropClasses]: isDragActive, // OS file drag active
315
+ [rejectDropClasses]: isDragReject, // OS file drag reject
316
+ [acceptDropClasses]: isDragAccept, // OS file drag accept
317
+ [disabledClasses]: disabled || isDndItemDragging // Visually disable if internal drag
218
318
  })}
219
319
  >
220
320
  <div
221
- {...droppableProvided.droppableProps}
222
- ref={droppableProvided.innerRef}
223
- className={cn("flex items-center p-1 no-scrollbar",
321
+ className={cls("flex items-center p-1 px-4 no-scrollbar",
224
322
  multipleFilesSupported && internalValue.length ? "overflow-auto" : "",
225
323
  multipleFilesSupported && internalValue.length ? "min-h-[180px]" : "min-h-[250px]"
226
324
  )}
227
325
  >
228
-
229
326
  <input
230
327
  autoFocus={autoFocus}
231
328
  {...getInputProps()} />
232
329
 
233
- {internalValue.map((entry, index) => {
234
- let child: any;
235
- if (entry.storagePathOrDownloadUrl) {
236
- child = (
237
- <StorageItemPreview
238
- collection={collection}
239
- name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
240
- property={property}
241
- disabled={disabled}
242
- entity={entity}
243
- value={entry.storagePathOrDownloadUrl}
244
- onRemove={onClear}
245
- size={entry.size}/>
246
- );
247
- } else if (entry.file) {
248
- child = (
249
- <StorageUploadProgress
250
- entry={entry}
251
- metadata={metadata}
252
- storagePath={storagePathBuilder(entry.file)}
253
- onFileUploadComplete={onFileUploadComplete}
254
- imageSize={size === "medium" ? 220 : 118}
255
- simple={false}
256
- />
257
- );
258
- }
259
-
260
- return (
261
- <Draggable
262
- key={`array_field_${name}_${entry.id}`}
263
- draggableId={`array_field_${name}_${entry.id}`}
264
- index={index}>
265
- {(provided, snapshot) => (
266
- <div
267
- tabIndex={-1}
268
- ref={provided.innerRef}
269
- {...provided.draggableProps}
270
- {...provided.dragHandleProps}
271
- className={cn(focusedMixin, "rounded-md")}
272
- style={{
273
- ...provided.draggableProps.style
274
- }}
275
- >
276
- {child}
277
- </div>
278
- )}
279
- </Draggable>
280
- );
281
- })
282
- }
283
-
284
- {droppableProvided.placeholder}
285
-
330
+ {internalValue.map((entry) => (
331
+ <SortableStorageItem
332
+ key={entry.id}
333
+ id={entry.id}
334
+ entry={entry}
335
+ property={property}
336
+ name={name}
337
+ metadata={metadata}
338
+ storagePathBuilder={storagePathBuilder}
339
+ onFileUploadComplete={onFileUploadComplete}
340
+ onClear={onClear}
341
+ disabled={disabled}
342
+ isSortable={multipleFilesSupported}
343
+ />
344
+ ))}
345
+
346
+ {/* Placeholder for empty dropzone text is handled by the outer Typography */}
286
347
  </div>
287
348
 
288
349
  <div
289
350
  className="flex-grow min-h-[38px] box-border m-2 text-center">
290
351
  <Typography align={"center"}
291
- variant={"label"}>
352
+ variant={"label"}
353
+ className={disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : ""}>
292
354
  {helpText}
293
355
  </Typography>
294
356
  </div>
295
-
296
357
  </div>
297
358
  );
298
359
  }
299
360
 
300
361
  export interface StorageUploadProps {
301
362
  value: StorageFieldItem[];
302
- collection: EntityCollection;
303
363
  setInternalValue: (v: StorageFieldItem[]) => void;
304
364
  name: string;
305
365
  property: ResolvedStringProperty | ResolvedArrayProperty<string[]>;
@@ -307,18 +367,16 @@ export interface StorageUploadProps {
307
367
  multipleFilesSupported: boolean;
308
368
  autoFocus: boolean;
309
369
  disabled: boolean;
310
- entity: Entity<any>;
311
370
  storage: StorageConfig;
312
- onFilesAdded: (acceptedFiles: File[]) => void;
371
+ onFilesAdded: (acceptedFiles: File[]) => Promise<void>; // Updated from useStorageUploadController
313
372
  storagePathBuilder: (file: File) => string;
314
373
  onFileUploadComplete: (uploadedPath: string, entry: StorageFieldItem, fileMetadata?: any) => Promise<void>;
315
374
  }
316
375
 
317
376
  export function StorageUpload({
318
- collection,
319
377
  property,
320
378
  name,
321
- value,
379
+ value, // This is internalValue from useStorageUploadController
322
380
  setInternalValue,
323
381
  onChange,
324
382
  multipleFilesSupported,
@@ -327,7 +385,6 @@ export function StorageUpload({
327
385
  onFilesAdded,
328
386
  autoFocus,
329
387
  storage,
330
- entity,
331
388
  storagePathBuilder,
332
389
  }: StorageUploadProps) {
333
390
 
@@ -346,10 +403,10 @@ export function StorageUpload({
346
403
  }
347
404
 
348
405
  const metadata: Record<string, unknown> | undefined = storage?.metadata;
349
- const size = multipleFilesSupported ? "small" : "medium";
406
+ const [isDndItemDragging, setIsDndItemDragging] = useState(false);
350
407
 
351
408
  const moveItem = useCallback((fromIndex: number, toIndex: number) => {
352
- if (!multipleFilesSupported) return;
409
+ if (!multipleFilesSupported || fromIndex === toIndex) return;
353
410
  const newValue = [...value];
354
411
  const item = newValue[fromIndex];
355
412
  newValue.splice(fromIndex, 1);
@@ -361,87 +418,88 @@ export function StorageUpload({
361
418
  onChange(fieldValue);
362
419
  }, [multipleFilesSupported, onChange, setInternalValue, value]);
363
420
 
364
- const onDragEnd = useCallback((result: any) => {
365
- // dropped outside the list
366
- if (!result.destination) {
367
- return;
368
- }
369
-
370
- moveItem(result.source.index, result.destination.index);
421
+ const sensors = useSensors(
422
+ useSensor(PointerSensor, {
423
+ activationConstraint: {
424
+ distance: 5, // Start dragging after 5px movement
425
+ },
426
+ }),
427
+ useSensor(KeyboardSensor, {
428
+ coordinateGetter: sortableKeyboardCoordinates,
429
+ })
430
+ );
371
431
 
372
- }, [moveItem])
432
+ const handleDragStart = useCallback((event: DragStartEvent) => {
433
+ setIsDndItemDragging(true);
434
+ }, []);
435
+
436
+ const handleDragEnd = useCallback((event: DragEndEvent) => {
437
+ setIsDndItemDragging(false);
438
+ const {
439
+ active,
440
+ over
441
+ } = event;
442
+ if (over && active.id !== over.id) {
443
+ const oldIndex = value.findIndex(item => item.id === active.id);
444
+ const newIndex = value.findIndex(item => item.id === over.id);
445
+ if (oldIndex !== -1 && newIndex !== -1) {
446
+ moveItem(oldIndex, newIndex);
447
+ }
448
+ }
449
+ }, [value, moveItem]);
373
450
 
374
451
  const onClear = useCallback((clearedStoragePathOrDownloadUrl: string) => {
452
+ let newValue: StorageFieldItem[];
375
453
  if (multipleFilesSupported) {
376
- const newValue: StorageFieldItem[] = value.filter(v => v.storagePathOrDownloadUrl !== clearedStoragePathOrDownloadUrl);
454
+ newValue = value.filter(v => v.storagePathOrDownloadUrl !== clearedStoragePathOrDownloadUrl);
377
455
  onChange(newValue.filter(v => !!v.storagePathOrDownloadUrl).map(v => v.storagePathOrDownloadUrl as string));
378
- setInternalValue(newValue);
379
456
  } else {
457
+ newValue = [];
380
458
  onChange(null);
381
- setInternalValue([]);
382
459
  }
383
- }, [value, multipleFilesSupported, onChange]);
460
+ setInternalValue(newValue);
461
+ }, [value, multipleFilesSupported, onChange, setInternalValue]);
384
462
 
385
463
  const helpText = multipleFilesSupported
386
- ? "Drag 'n' drop some files here, or click to select files"
464
+ ? "Drag 'n' drop some files here, or click to select files. Drag to reorder."
387
465
  : "Drag 'n' drop a file here, or click to select one";
388
466
 
389
467
  const renderProperty: ResolvedStringProperty = multipleFilesSupported
390
- ? (property as ArrayProperty<string[]>).of as ResolvedStringProperty
468
+ ? (property as ResolvedArrayProperty<string[]>).of as ResolvedStringProperty
391
469
  : property as ResolvedStringProperty;
392
470
 
393
- return (
394
- <DragDropContext onDragEnd={onDragEnd}>
395
- <Droppable
396
- droppableId={`droppable_${name}`}
397
- direction="horizontal"
398
- renderClone={(provided, snapshot, rubric) => {
399
- const entry = value[rubric.source.index];
400
- return (
401
- <div
402
- ref={provided.innerRef}
403
- {...provided.draggableProps}
404
- {...provided.dragHandleProps}
405
- style={
406
- provided.draggableProps.style
407
- }
408
- className="rounded"
409
- >
410
- <StorageItemPreview
411
- collection={collection}
412
- name={`storage_preview_${entry.storagePathOrDownloadUrl}`}
413
- property={renderProperty}
414
- disabled={true}
415
- entity={entity}
416
- value={entry.storagePathOrDownloadUrl as string}
417
- onRemove={onClear}
418
- size={entry.size}/>
419
- </div>
420
- );
421
- }}
422
- >
423
- {(provided, snapshot) => {
424
- return <FileDropComponent storage={storage}
425
- collection={collection}
426
- disabled={disabled}
427
- isDraggingOver={snapshot.isDraggingOver}
428
- droppableProvided={provided}
429
- onFilesAdded={onFilesAdded}
430
- multipleFilesSupported={multipleFilesSupported}
431
- autoFocus={autoFocus}
432
- internalValue={value}
433
- property={renderProperty}
434
- entity={entity}
435
- onClear={onClear}
436
- metadata={metadata}
437
- storagePathBuilder={storagePathBuilder}
438
- onFileUploadComplete={onFileUploadComplete}
439
- size={size}
440
- name={name}
441
- helpText={helpText}/>
442
- }}
443
- </Droppable>
444
- </DragDropContext>
445
- );
471
+ const fileDropProps = {
472
+ storage,
473
+ disabled,
474
+ onFilesAdded,
475
+ multipleFilesSupported,
476
+ autoFocus,
477
+ internalValue: value, // Pass current internalValue
478
+ property: renderProperty,
479
+ onClear,
480
+ metadata,
481
+ storagePathBuilder,
482
+ onFileUploadComplete,
483
+ name,
484
+ helpText,
485
+ isDndItemDragging // Pass this down
486
+ };
446
487
 
488
+ if (multipleFilesSupported) {
489
+ return (
490
+ <DndContext
491
+ sensors={sensors}
492
+ collisionDetection={closestCenter}
493
+ onDragStart={handleDragStart}
494
+ onDragEnd={handleDragEnd}
495
+ >
496
+ <SortableContext items={value.map(v => v.id)} strategy={horizontalListSortingStrategy}>
497
+ <FileDropComponent {...fileDropProps} />
498
+ </SortableContext>
499
+ </DndContext>
500
+ );
501
+ } else {
502
+ // For single file, no D&D context is needed
503
+ return <FileDropComponent {...fileDropProps} isDndItemDragging={false}/>;
504
+ }
447
505
  }