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

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 (349) hide show
  1. package/README.md +2 -2
  2. package/dist/app/Drawer.d.ts +0 -1
  3. package/dist/app/Scaffold.d.ts +4 -0
  4. package/dist/components/ArrayContainer.d.ts +31 -12
  5. package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
  6. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +3 -1
  7. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  8. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +17 -3
  9. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
  10. package/dist/components/EntityCollectionTable/index.d.ts +1 -1
  11. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +6 -3
  12. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
  13. package/dist/components/EntityCollectionView/utils.d.ts +3 -0
  14. package/dist/components/EntityJsonPreview.d.ts +3 -0
  15. package/dist/components/EntityPreview.d.ts +8 -6
  16. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  17. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  18. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  19. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  20. package/dist/components/HomePage/NavigationGroup.d.ts +8 -1
  21. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  22. package/dist/components/PropertyConfigBadge.d.ts +2 -1
  23. package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
  24. package/dist/components/SelectableTable/SelectableTable.d.ts +13 -3
  25. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
  26. package/dist/components/UnsavedChangesDialog.d.ts +8 -0
  27. package/dist/components/VirtualTable/VirtualTableProps.d.ts +11 -2
  28. package/dist/components/common/default_entity_actions.d.ts +0 -2
  29. package/dist/components/common/index.d.ts +1 -1
  30. package/dist/components/common/useColumnsIds.d.ts +1 -0
  31. package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
  32. package/dist/components/common/useDebouncedCallback.d.ts +1 -0
  33. package/dist/components/common/useScrollRestoration.d.ts +14 -0
  34. package/dist/components/index.d.ts +3 -1
  35. package/dist/contexts/BreacrumbsContext.d.ts +8 -0
  36. package/dist/core/DefaultAppBar.d.ts +8 -2
  37. package/dist/core/DrawerNavigationItem.d.ts +2 -1
  38. package/dist/core/EntityEditView.d.ts +40 -22
  39. package/dist/core/EntityEditViewFormActions.d.ts +2 -0
  40. package/dist/core/FireCMS.d.ts +2 -2
  41. package/dist/core/FireCMSRouter.d.ts +4 -0
  42. package/dist/core/NavigationRoutes.d.ts +0 -1
  43. package/dist/core/SideDialogs.d.ts +4 -2
  44. package/dist/core/field_configs.d.ts +1 -1
  45. package/dist/core/index.d.ts +2 -1
  46. package/dist/form/EntityForm.d.ts +50 -0
  47. package/dist/form/EntityFormActions.d.ts +21 -0
  48. package/dist/form/PropertyFieldBinding.d.ts +1 -1
  49. package/dist/form/components/FormEntry.d.ts +6 -0
  50. package/dist/form/components/FormLayout.d.ts +5 -0
  51. package/dist/form/components/LabelWithIcon.d.ts +1 -1
  52. package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
  53. package/dist/form/components/index.d.ts +3 -1
  54. package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
  55. package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
  56. package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
  57. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  58. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  59. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +11 -0
  60. package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
  61. package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
  62. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  63. package/dist/form/field_bindings/ReferenceFieldBinding.d.ts +2 -2
  64. package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
  65. package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
  66. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -10
  67. package/dist/form/field_bindings/SwitchFieldBinding.d.ts +1 -2
  68. package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
  69. package/dist/form/index.d.ts +17 -16
  70. package/dist/form/useClearRestoreValue.d.ts +2 -2
  71. package/dist/hooks/data/delete.d.ts +4 -4
  72. package/dist/hooks/data/save.d.ts +3 -3
  73. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  74. package/dist/hooks/data/useEntityFetch.d.ts +4 -3
  75. package/dist/hooks/useAuthController.d.ts +1 -1
  76. package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
  77. package/dist/hooks/useBuildNavigationController.d.ts +57 -12
  78. package/dist/hooks/useFireCMSContext.d.ts +1 -1
  79. package/dist/hooks/useModeController.d.ts +1 -2
  80. package/dist/hooks/useProjectLog.d.ts +7 -1
  81. package/dist/hooks/useResolvedNavigationFrom.d.ts +3 -3
  82. package/dist/hooks/useValidateAuthenticator.d.ts +3 -3
  83. package/dist/index.es.js +20108 -14471
  84. package/dist/index.es.js.map +1 -1
  85. package/dist/index.umd.js +20039 -14407
  86. package/dist/index.umd.js.map +1 -1
  87. package/dist/internal/useBuildDataSource.d.ts +3 -2
  88. package/dist/internal/useBuildSideEntityController.d.ts +3 -3
  89. package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
  90. package/dist/preview/PropertyPreviewProps.d.ts +1 -1
  91. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  92. package/dist/preview/components/ReferencePreview.d.ts +2 -2
  93. package/dist/preview/util.d.ts +3 -3
  94. package/dist/routes/CustomCMSRoute.d.ts +4 -0
  95. package/dist/routes/FireCMSRoute.d.ts +1 -0
  96. package/dist/routes/HomePageRoute.d.ts +3 -0
  97. package/dist/types/analytics.d.ts +1 -1
  98. package/dist/types/auth.d.ts +7 -9
  99. package/dist/types/collections.d.ts +86 -25
  100. package/dist/types/customization_controller.d.ts +8 -0
  101. package/dist/types/datasource.d.ts +19 -17
  102. package/dist/types/dialogs_controller.d.ts +7 -3
  103. package/dist/types/entities.d.ts +2 -1
  104. package/dist/types/entity_actions.d.ts +58 -8
  105. package/dist/types/entity_callbacks.d.ts +16 -16
  106. package/dist/types/entity_overrides.d.ts +2 -2
  107. package/dist/types/export_import.d.ts +4 -4
  108. package/dist/types/fields.d.ts +43 -17
  109. package/dist/types/firecms.d.ts +16 -3
  110. package/dist/types/firecms_context.d.ts +1 -1
  111. package/dist/types/navigation.d.ts +60 -17
  112. package/dist/types/permissions.d.ts +4 -4
  113. package/dist/types/plugins.d.ts +42 -9
  114. package/dist/types/properties.d.ts +65 -22
  115. package/dist/types/property_config.d.ts +1 -3
  116. package/dist/types/roles.d.ts +3 -0
  117. package/dist/types/side_dialogs_controller.d.ts +10 -0
  118. package/dist/types/side_entity_controller.d.ts +14 -1
  119. package/dist/types/storage.d.ts +75 -0
  120. package/dist/types/user.d.ts +1 -0
  121. package/dist/util/builders.d.ts +3 -3
  122. package/dist/util/callbacks.d.ts +2 -0
  123. package/dist/util/createFormexStub.d.ts +2 -0
  124. package/dist/util/entities.d.ts +2 -2
  125. package/dist/util/entity_actions.d.ts +2 -0
  126. package/dist/util/entity_cache.d.ts +23 -0
  127. package/dist/util/icon_synonyms.d.ts +0 -1
  128. package/dist/util/icons.d.ts +5 -2
  129. package/dist/util/index.d.ts +3 -0
  130. package/dist/util/navigation_from_path.d.ts +10 -1
  131. package/dist/util/navigation_utils.d.ts +13 -1
  132. package/dist/util/objects.d.ts +2 -1
  133. package/dist/util/permissions.d.ts +4 -4
  134. package/dist/util/property_utils.d.ts +4 -4
  135. package/dist/util/references.d.ts +2 -2
  136. package/dist/util/resolutions.d.ts +30 -6
  137. package/dist/util/storage.d.ts +1 -1
  138. package/dist/util/useStorageUploadController.d.ts +2 -2
  139. package/package.json +133 -125
  140. package/src/app/Drawer.tsx +0 -1
  141. package/src/app/Scaffold.tsx +33 -29
  142. package/src/components/ArrayContainer.tsx +447 -229
  143. package/src/components/CircularProgressCenter.tsx +1 -1
  144. package/src/components/ClearFilterSortButton.tsx +1 -1
  145. package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +12 -11
  146. package/src/components/DeleteEntityDialog.tsx +13 -20
  147. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +59 -25
  148. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +23 -17
  149. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +20 -3
  150. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +35 -9
  151. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -16
  152. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +6 -12
  153. package/src/components/EntityCollectionTable/index.tsx +1 -1
  154. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +6 -6
  155. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +35 -26
  156. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +20 -8
  157. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +132 -101
  158. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +9 -9
  159. package/src/components/EntityCollectionView/EntityCollectionView.tsx +178 -85
  160. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +7 -4
  161. package/src/components/EntityCollectionView/useSelectionController.tsx +5 -4
  162. package/src/components/EntityCollectionView/utils.ts +19 -0
  163. package/src/components/EntityJsonPreview.tsx +66 -0
  164. package/src/components/EntityPreview.tsx +75 -57
  165. package/src/components/EntityView.tsx +8 -5
  166. package/src/components/ErrorView.tsx +3 -3
  167. package/src/components/FireCMSLogo.tsx +7 -51
  168. package/src/components/HomePage/DefaultHomePage.tsx +522 -160
  169. package/src/components/HomePage/FavouritesView.tsx +9 -14
  170. package/src/components/HomePage/HomePageDnD.tsx +642 -0
  171. package/src/components/HomePage/NavigationCard.tsx +47 -38
  172. package/src/components/HomePage/NavigationCardBinding.tsx +16 -15
  173. package/src/components/HomePage/NavigationGroup.tsx +144 -30
  174. package/src/components/HomePage/RenameGroupDialog.tsx +117 -0
  175. package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
  176. package/src/components/NotFoundPage.tsx +2 -2
  177. package/src/components/PropertyConfigBadge.tsx +9 -3
  178. package/src/components/PropertyIdCopyTooltip.tsx +47 -0
  179. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +22 -13
  180. package/src/components/SearchIconsView.tsx +2 -2
  181. package/src/components/SelectableTable/SelectableTable.tsx +154 -142
  182. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +4 -2
  183. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +10 -8
  184. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +59 -10
  185. package/src/components/UnsavedChangesDialog.tsx +46 -0
  186. package/src/components/VirtualTable/VirtualTable.tsx +65 -44
  187. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -8
  188. package/src/components/VirtualTable/VirtualTableHeader.tsx +8 -8
  189. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  190. package/src/components/VirtualTable/VirtualTableProps.tsx +12 -2
  191. package/src/components/VirtualTable/VirtualTableRow.tsx +1 -1
  192. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
  193. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -2
  194. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
  195. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +16 -28
  196. package/src/components/common/default_entity_actions.tsx +62 -42
  197. package/src/components/common/index.ts +1 -1
  198. package/src/components/common/useColumnsIds.tsx +1 -1
  199. package/src/components/common/useDataSourceTableController.tsx +420 -0
  200. package/src/components/common/useDebouncedCallback.tsx +20 -0
  201. package/src/components/common/useScrollRestoration.tsx +68 -0
  202. package/src/components/common/useTableSearchHelper.ts +1 -0
  203. package/src/components/index.tsx +4 -1
  204. package/src/contexts/BreacrumbsContext.tsx +38 -0
  205. package/src/contexts/DialogsProvider.tsx +3 -2
  206. package/src/contexts/ModeController.tsx +1 -3
  207. package/src/contexts/SnackbarProvider.tsx +2 -0
  208. package/src/core/DefaultAppBar.tsx +124 -85
  209. package/src/core/DefaultDrawer.tsx +30 -22
  210. package/src/core/DrawerNavigationItem.tsx +32 -28
  211. package/src/core/EntityEditView.tsx +388 -995
  212. package/src/core/EntityEditViewFormActions.tsx +329 -0
  213. package/src/core/EntitySidePanel.tsx +88 -20
  214. package/src/core/FireCMS.tsx +46 -25
  215. package/src/core/FireCMSRouter.tsx +17 -0
  216. package/src/core/NavigationRoutes.tsx +23 -32
  217. package/src/core/SideDialogs.tsx +22 -12
  218. package/src/core/field_configs.tsx +24 -10
  219. package/src/core/index.tsx +4 -2
  220. package/src/form/EntityForm.tsx +814 -0
  221. package/src/form/EntityFormActions.tsx +211 -0
  222. package/src/form/PropertyFieldBinding.tsx +55 -41
  223. package/src/form/components/CustomIdField.tsx +9 -3
  224. package/src/form/components/FieldHelperText.tsx +1 -1
  225. package/src/form/components/FormEntry.tsx +22 -0
  226. package/src/form/components/FormLayout.tsx +16 -0
  227. package/src/form/components/LabelWithIcon.tsx +30 -19
  228. package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
  229. package/src/form/components/StorageItemPreview.tsx +5 -4
  230. package/src/form/components/StorageUploadProgress.tsx +2 -3
  231. package/src/form/components/index.tsx +3 -1
  232. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +30 -18
  233. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +47 -36
  234. package/src/form/field_bindings/BlockFieldBinding.tsx +55 -33
  235. package/src/form/field_bindings/DateTimeFieldBinding.tsx +18 -14
  236. package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -15
  237. package/src/form/field_bindings/MapFieldBinding.tsx +72 -62
  238. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +159 -0
  239. package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +26 -21
  240. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +10 -8
  241. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  242. package/src/form/field_bindings/ReferenceFieldBinding.tsx +28 -19
  243. package/src/form/field_bindings/RepeatFieldBinding.tsx +56 -32
  244. package/src/form/field_bindings/SelectFieldBinding.tsx +22 -13
  245. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +247 -168
  246. package/src/form/field_bindings/SwitchFieldBinding.tsx +29 -24
  247. package/src/form/field_bindings/TextFieldBinding.tsx +28 -24
  248. package/src/form/index.tsx +17 -37
  249. package/src/form/useClearRestoreValue.tsx +2 -2
  250. package/src/form/validation.ts +12 -6
  251. package/src/hooks/data/delete.ts +6 -5
  252. package/src/hooks/data/save.ts +26 -35
  253. package/src/hooks/data/useCollectionFetch.tsx +3 -3
  254. package/src/hooks/data/useDataSource.tsx +10 -2
  255. package/src/hooks/data/useEntityFetch.tsx +10 -6
  256. package/src/hooks/useAuthController.tsx +1 -1
  257. package/src/hooks/useBreadcrumbsController.tsx +31 -0
  258. package/src/hooks/useBrowserTitleAndIcon.tsx +1 -1
  259. package/src/hooks/useBuildModeController.tsx +15 -28
  260. package/src/hooks/useBuildNavigationController.tsx +386 -124
  261. package/src/hooks/useFireCMSContext.tsx +3 -33
  262. package/src/hooks/useLargeLayout.tsx +0 -35
  263. package/src/hooks/useModeController.tsx +1 -2
  264. package/src/hooks/useProjectLog.tsx +16 -5
  265. package/src/hooks/useResolvedNavigationFrom.tsx +9 -11
  266. package/src/hooks/useValidateAuthenticator.tsx +3 -3
  267. package/src/internal/useBuildDataSource.ts +67 -80
  268. package/src/internal/useBuildSideDialogsController.tsx +4 -2
  269. package/src/internal/useBuildSideEntityController.tsx +149 -86
  270. package/src/internal/useUnsavedChangesDialog.tsx +127 -91
  271. package/src/preview/PropertyPreview.tsx +28 -12
  272. package/src/preview/PropertyPreviewProps.tsx +1 -1
  273. package/src/preview/components/BooleanPreview.tsx +1 -1
  274. package/src/preview/components/EmptyValue.tsx +1 -1
  275. package/src/preview/components/EnumValuesChip.tsx +1 -1
  276. package/src/preview/components/ImagePreview.tsx +10 -9
  277. package/src/preview/components/ReferencePreview.tsx +6 -16
  278. package/src/preview/components/UrlComponentPreview.tsx +20 -21
  279. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +6 -5
  280. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +5 -4
  281. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +5 -3
  282. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
  283. package/src/preview/property_previews/ArrayOneOfPreview.tsx +6 -4
  284. package/src/preview/property_previews/ArrayPropertyPreview.tsx +5 -3
  285. package/src/preview/property_previews/MapPropertyPreview.tsx +7 -6
  286. package/src/preview/property_previews/SkeletonPropertyComponent.tsx +13 -13
  287. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  288. package/src/preview/util.ts +10 -10
  289. package/src/routes/CustomCMSRoute.tsx +21 -0
  290. package/src/routes/FireCMSRoute.tsx +246 -0
  291. package/src/routes/HomePageRoute.tsx +17 -0
  292. package/src/types/analytics.ts +3 -0
  293. package/src/types/auth.tsx +8 -12
  294. package/src/types/collections.ts +101 -28
  295. package/src/types/customization_controller.tsx +9 -0
  296. package/src/types/datasource.ts +21 -20
  297. package/src/types/dialogs_controller.tsx +7 -3
  298. package/src/types/entities.ts +3 -1
  299. package/src/types/entity_actions.tsx +71 -8
  300. package/src/types/entity_callbacks.ts +18 -18
  301. package/src/types/entity_overrides.tsx +2 -2
  302. package/src/types/export_import.ts +4 -4
  303. package/src/types/fields.tsx +52 -19
  304. package/src/types/firecms.tsx +18 -4
  305. package/src/types/firecms_context.tsx +1 -1
  306. package/src/types/navigation.ts +76 -22
  307. package/src/types/permissions.ts +5 -5
  308. package/src/types/plugins.tsx +50 -9
  309. package/src/types/properties.ts +74 -22
  310. package/src/types/property_config.tsx +1 -2
  311. package/src/types/roles.ts +3 -0
  312. package/src/types/side_dialogs_controller.tsx +15 -0
  313. package/src/types/side_entity_controller.tsx +16 -1
  314. package/src/types/storage.ts +82 -0
  315. package/src/types/user.ts +2 -0
  316. package/src/util/builders.ts +10 -8
  317. package/src/util/callbacks.ts +119 -0
  318. package/src/util/createFormexStub.tsx +62 -0
  319. package/src/util/entities.ts +5 -3
  320. package/src/util/entity_actions.ts +28 -0
  321. package/src/util/entity_cache.ts +204 -0
  322. package/src/util/icon_list.ts +1 -1
  323. package/src/util/icon_synonyms.ts +0 -1
  324. package/src/util/icons.tsx +36 -11
  325. package/src/util/index.ts +3 -0
  326. package/src/util/join_collections.ts +9 -2
  327. package/src/util/make_properties_editable.ts +13 -5
  328. package/src/util/navigation_from_path.ts +33 -12
  329. package/src/util/navigation_utils.ts +135 -19
  330. package/src/util/objects.ts +74 -14
  331. package/src/util/parent_references_from_path.ts +3 -3
  332. package/src/util/permissions.ts +8 -8
  333. package/src/util/property_utils.tsx +17 -6
  334. package/src/util/references.ts +19 -8
  335. package/src/util/resolutions.ts +93 -24
  336. package/src/util/storage.ts +6 -2
  337. package/src/util/useStorageUploadController.tsx +74 -29
  338. package/dist/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.d.ts +0 -5
  339. package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
  340. package/dist/form/PropertiesForm.d.ts +0 -8
  341. package/dist/form/components/FormikArrayContainer.d.ts +0 -18
  342. package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
  343. package/src/components/EntityCollectionTable/internal/popup_field/ElementResizeListener.tsx +0 -59
  344. package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
  345. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
  346. package/src/form/PropertiesForm.tsx +0 -81
  347. package/src/form/components/FormikArrayContainer.tsx +0 -44
  348. package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
  349. /package/src/util/{common.tsx → common.ts} +0 -0
@@ -1,25 +1,40 @@
1
1
  import { useCallback, useEffect, useRef } from "react";
2
2
  import {
3
+ AuthController,
4
+ CustomizationController,
3
5
  EntityCollection,
4
6
  EntitySidePanelProps,
5
- NavigationController, PropertyConfig,
7
+ NavigationController,
6
8
  ResolvedProperty,
7
9
  SideDialogPanelProps,
8
10
  SideDialogsController,
9
11
  SideEntityController
10
12
  } from "../types";
11
- import { getNavigationEntriesFromPathInternal, NavigationViewInternal } from "../util/navigation_from_path";
13
+ import { getNavigationEntriesFromPath, NavigationViewInternal } from "../util/navigation_from_path";
12
14
  import { useLocation } from "react-router-dom";
13
- import { removeInitialAndTrailingSlashes, resolveCollection, resolveDefaultSelectedView } from "../util";
15
+ import {
16
+ removeInitialAndTrailingSlashes,
17
+ resolveCollection,
18
+ resolveDefaultSelectedView,
19
+ resolvedSelectedEntityView
20
+ } from "../util";
14
21
  import { ADDITIONAL_TAB_WIDTH, CONTAINER_FULL_WIDTH, FORM_CONTAINER_WIDTH } from "./common";
15
- import { useLargeLayout } from "../hooks";
22
+ import { useCustomizationController, useLargeLayout } from "../hooks";
16
23
  import { EntitySidePanel } from "../core/EntitySidePanel";
24
+ import { JSON_TAB_VALUE } from "../core/EntityEditView";
17
25
 
18
- const NEW_URL_HASH = "new";
26
+ const NEW_URL_HASH = "new_side";
27
+ const SIDE_URL_HASH = "side";
19
28
 
20
- export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string {
29
+ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean, customizationController: CustomizationController, authController: AuthController): string {
21
30
  if (small) return CONTAINER_FULL_WIDTH;
22
- const mainViewSelected = !props.selectedSubPath;
31
+
32
+ const {
33
+ selectedSecondaryForm
34
+ } = resolvedSelectedEntityView(props.collection?.entityViews, customizationController, props.selectedTab);
35
+
36
+ const shouldUseSmallLayout = !props.selectedTab || props.selectedTab === JSON_TAB_VALUE || props.selectedTab === "__history" || Boolean(selectedSecondaryForm);
37
+
23
38
  let resolvedWidth: string | undefined;
24
39
  if (props.width) {
25
40
  resolvedWidth = typeof props.width === "number" ? `${props.width}px` : props.width;
@@ -27,7 +42,7 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
27
42
  resolvedWidth = typeof props.collection.sideDialogWidth === "number" ? `${props.collection.sideDialogWidth}px` : props.collection.sideDialogWidth;
28
43
  }
29
44
 
30
- if (!mainViewSelected) {
45
+ if (!shouldUseSmallLayout) {
31
46
  return `calc(${ADDITIONAL_TAB_WIDTH} + ${resolvedWidth ?? FORM_CONTAINER_WIDTH})`
32
47
  } else {
33
48
  if (resolvedWidth) {
@@ -35,21 +50,22 @@ export function getEntityViewWidth(props: EntitySidePanelProps<any>, small: bool
35
50
  } else if (!props.collection) {
36
51
  return FORM_CONTAINER_WIDTH;
37
52
  } else {
38
- return calculateCollectionDesiredWidth(props.collection);
53
+ return calculateCollectionDesiredWidth(props.collection, authController);
39
54
  }
40
55
  }
41
56
  }
42
57
 
43
58
  const collectionViewWidthCache: { [key: string]: string } = {};
44
59
 
45
- function calculateCollectionDesiredWidth(collection: EntityCollection<any>): string {
60
+ function calculateCollectionDesiredWidth(collection: EntityCollection<any>, authController: AuthController): string {
46
61
  if (collectionViewWidthCache[collection.id]) {
47
62
  return collectionViewWidthCache[collection.id];
48
63
  }
49
64
  const resolvedCollection = resolveCollection({
50
65
  collection,
51
66
  path: "__ignored",
52
- ignoreMissingFields: true
67
+ ignoreMissingFields: true,
68
+ authController
53
69
  });
54
70
 
55
71
  let result = FORM_CONTAINER_WIDTH
@@ -84,36 +100,69 @@ function getNestedPropertiesDepth(property: ResolvedProperty, accumulator: numbe
84
100
  }
85
101
 
86
102
  export const useBuildSideEntityController = (navigation: NavigationController,
87
- sideDialogsController: SideDialogsController): SideEntityController => {
103
+ sideDialogsController: SideDialogsController,
104
+ authController: AuthController
105
+ ): SideEntityController => {
88
106
 
89
107
  const location = useLocation();
90
108
  const initialised = useRef<boolean>(false);
109
+ const customizationController = useCustomizationController();
91
110
 
92
111
  const smallLayout = !useLargeLayout();
93
112
 
94
- // only on initialisation, create panels from URL
95
113
  useEffect(() => {
96
- if (!navigation.loading && !initialised.current) {
97
- console.debug("Initialising side entity controller");
98
- if (navigation.isUrlCollectionPath(location.pathname)) {
99
- const newFlag = location.hash === `#${NEW_URL_HASH}`;
114
+
115
+ const newFlag = location.hash === `#${NEW_URL_HASH}`;
116
+ const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
117
+
118
+ if (!navigation.loading) {
119
+ if ((newFlag || sideFlag) && navigation.isUrlCollectionPath(location.pathname)) {
100
120
  const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
101
121
  const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], newFlag);
102
122
  for (let i = 0; i < panelsFromUrl.length; i++) {
103
123
  const props = panelsFromUrl[i];
104
- setTimeout(() => {
105
- if (i === 0)
106
- sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
107
- else
108
- sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))
109
- }, 1);
124
+ if (i === 0)
125
+ sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
126
+ else
127
+ sideDialogsController.open(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController))
110
128
  }
111
- } else {
112
- // console.warn("Location path is not a collection path");
113
129
  }
114
130
  initialised.current = true;
115
131
  }
116
- }, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);
132
+ }, [navigation.loading]);
133
+
134
+ // sync panels if URL changes with #side
135
+ const currentPanelKeys = sideDialogsController.sidePanels.map(p => p.key);
136
+ useEffect(() => {
137
+ if (initialised.current) {
138
+ const sideFlag = location.hash === `#${SIDE_URL_HASH}`;
139
+ if (sideFlag) {
140
+ const entityOrCollectionPath = navigation.urlPathToDataPath(location.pathname);
141
+ const panelsFromUrl = buildSidePanelsFromUrl(entityOrCollectionPath, navigation.collections ?? [], false);
142
+ // if we have more panels than determined by the url, we ignore the url. We might have references open
143
+ if (panelsFromUrl.length <= currentPanelKeys.length) {
144
+ return;
145
+ }
146
+ const lastPanel = panelsFromUrl[panelsFromUrl.length - 1];
147
+ const panelProps = propsToSidePanel(lastPanel, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
148
+ const lastCurrentPanel = currentPanelKeys.length > 0 ? currentPanelKeys[currentPanelKeys.length - 1] : undefined;
149
+ if (!lastCurrentPanel || lastCurrentPanel !== panelProps.key) {
150
+ sideDialogsController.replace(panelProps);
151
+ }
152
+ }
153
+ }
154
+ }, [location.pathname, location.hash, currentPanelKeys]);
155
+
156
+ // update side panels to match browser size
157
+ useEffect(() => {
158
+ const updatedSidePanels = sideDialogsController.sidePanels.map(sidePanelProps => {
159
+ if (sidePanelProps.additional) {
160
+ return propsToSidePanel(sidePanelProps.additional, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController);
161
+ }
162
+ return sidePanelProps;
163
+ });
164
+ sideDialogsController.setSidePanels(updatedSidePanels);
165
+ }, [smallLayout]);
117
166
 
118
167
  const close = useCallback(() => {
119
168
  sideDialogsController.close();
@@ -133,12 +182,19 @@ export const useBuildSideEntityController = (navigation: NavigationController,
133
182
  }
134
183
  );
135
184
 
136
- sideDialogsController.open(propsToSidePanel({
137
- selectedSubPath: defaultSelectedView,
138
- ...props,
139
- }, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
185
+ sideDialogsController.open(
186
+ propsToSidePanel({
187
+ selectedTab: defaultSelectedView,
188
+ ...props
189
+ },
190
+ navigation.buildUrlCollectionPath,
191
+ navigation.resolveIdsFrom,
192
+ smallLayout,
193
+ customizationController,
194
+ authController
195
+ ));
140
196
 
141
- }, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout]);
197
+ }, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, authController.user]);
142
198
 
143
199
  const replace = useCallback((props: EntitySidePanelProps<any>) => {
144
200
 
@@ -146,9 +202,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
146
202
  throw Error("If you want to copy an entity you need to provide an entityId");
147
203
  }
148
204
 
149
- sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
205
+ sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, smallLayout, customizationController, authController));
150
206
 
151
- }, [navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout]);
207
+ }, [navigation.buildUrlCollectionPath, navigation.resolveIdsFrom, sideDialogsController, smallLayout, authController.user]);
152
208
 
153
209
  return {
154
210
  close,
@@ -159,81 +215,88 @@ export const useBuildSideEntityController = (navigation: NavigationController,
159
215
 
160
216
  export function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {
161
217
 
162
- const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPathInternal({
218
+
219
+ const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPath({
163
220
  path,
164
221
  collections
165
222
  });
166
223
 
167
- const sidePanels: EntitySidePanelProps<any>[] = [];
224
+ let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
168
225
  let lastCollectionPath = "";
226
+ let lastCollectionId: string | undefined = undefined;
169
227
  for (let i = 0; i < navigationViewsForPath.length; i++) {
170
228
  const navigationEntry = navigationViewsForPath[i];
171
229
 
172
230
  if (navigationEntry.type === "collection") {
173
231
  lastCollectionPath = navigationEntry.path;
232
+ lastCollectionId = navigationEntry.collection.id;
174
233
  }
175
234
 
176
- if (i > 0) { // the first collection is handled by the main navigation
177
- const previousEntry = navigationViewsForPath[i - 1];
178
- if (navigationEntry.type === "entity") {
179
- sidePanels.push({
180
- path: navigationEntry.path,
181
- entityId: navigationEntry.entityId,
182
- copy: false,
183
- width: navigationEntry.parentCollection?.sideDialogWidth
184
- }
185
- );
186
- } else if (navigationEntry.type === "custom_view") {
187
- if (previousEntry.type === "entity") {
188
- const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];
189
- if (lastSidePanel)
190
- lastSidePanel.selectedSubPath = navigationEntry.view.key;
191
- }
192
- } else if (navigationEntry.type === "collection") {
193
- if (previousEntry.type === "entity") {
194
- const lastSidePanel: EntitySidePanelProps<any> = sidePanels[sidePanels.length - 1];
195
- if (lastSidePanel)
196
- lastSidePanel.selectedSubPath = navigationEntry.collection.id ?? navigationEntry.collection.path;
197
- }
235
+ const previousEntry = navigationViewsForPath[i - 1];
236
+ if (navigationEntry.type === "entity") {
237
+ sidePanel = {
238
+ path: navigationEntry.path,
239
+ fullIdPath: navigationEntry.fullIdPath,
240
+ entityId: navigationEntry.entityId,
241
+ copy: false,
242
+ width: navigationEntry.parentCollection?.sideDialogWidth
243
+ };
244
+ } else if (navigationEntry.type === "custom_view") {
245
+ if (previousEntry?.type === "entity") {
246
+ if (sidePanel)
247
+ sidePanel.selectedTab = navigationEntry.view.key;
248
+ }
249
+ } else if (navigationEntry.type === "collection") {
250
+ if (previousEntry?.type === "entity") {
251
+ if (sidePanel)
252
+ sidePanel.selectedTab = navigationEntry.collection.id ?? navigationEntry.collection.path;
198
253
  }
199
254
  }
200
255
 
201
256
  }
202
257
 
203
258
  if (newFlag) {
204
- sidePanels.push({
259
+ sidePanel = {
205
260
  path: lastCollectionPath,
261
+ fullIdPath: lastCollectionId,
206
262
  copy: false
207
- });
263
+ }
208
264
  }
209
265
 
210
- return sidePanels;
266
+ return sidePanel ? [sidePanel] : [];
211
267
  }
212
268
 
213
- const propsToSidePanel = (props: EntitySidePanelProps<any>,
269
+ const propsToSidePanel = (props: EntitySidePanelProps,
214
270
  buildUrlCollectionPath: (path: string) => string,
215
- resolveAliasesFrom: (pathWithAliases: string) => string,
216
- smallLayout: boolean): SideDialogPanelProps => {
217
-
218
- const collectionPath = removeInitialAndTrailingSlashes(props.path);
219
-
220
- const newPath = props.entityId
221
- ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || ""}`)
222
- : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
223
- const resolvedPath = resolveAliasesFrom(props.path);
224
-
225
- const resolvedPanelProps: EntitySidePanelProps<any> = {
226
- ...props,
227
- path: resolvedPath,
228
- };
229
-
230
- return {
231
- key: `${props.path}/${props.entityId}`,
232
- component: <EntitySidePanel {...resolvedPanelProps}/>,
233
- urlPath: newPath,
234
- parentUrlPath: buildUrlCollectionPath(collectionPath),
235
- width: getEntityViewWidth(props, smallLayout),
236
- onClose: props.onClose
237
- };
238
- }
239
- ;
271
+ resolveIdsFrom: (pathWithAliases: string) => string,
272
+ smallLayout: boolean,
273
+ customizationController: CustomizationController,
274
+ authController: AuthController
275
+ ): SideDialogPanelProps => {
276
+
277
+ const collectionPath = removeInitialAndTrailingSlashes(props.path);
278
+
279
+ const urlPath = props.entityId
280
+ ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
281
+ : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
282
+
283
+ const resolvedPanelProps: EntitySidePanelProps<any> = {
284
+ ...props,
285
+ formProps: props.formProps
286
+ };
287
+
288
+ const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController, authController);
289
+ return {
290
+ key: `${props.path}/${props.entityId}`,
291
+ component: <EntitySidePanel {...resolvedPanelProps}/>,
292
+ urlPath: urlPath,
293
+ parentUrlPath: buildUrlCollectionPath(collectionPath),
294
+ width: entityViewWidth,
295
+ onClose: props.onClose,
296
+ additional: props
297
+ };
298
+ }
299
+
300
+ function isSideUrl(url: string): boolean {
301
+ return url.endsWith("#" + SIDE_URL_HASH) || url.endsWith("#" + NEW_URL_HASH);
302
+ }
@@ -1,106 +1,142 @@
1
- import React, { useCallback } from "react";
2
- import { Blocker, Transition } from "history";
3
- import { UNSAFE_NavigationContext, useNavigate } from "react-router-dom";
4
- import { Button, Dialog, DialogActions, DialogContent, Typography } from "@firecms/ui";
1
+ import React, { useCallback, useEffect, useState } from "react";
2
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
5
3
 
6
- export function useNavigationUnsavedChangesDialog(when: boolean, onSuccess: () => void):
7
- {
8
- navigationWasBlocked: boolean,
9
- handleCancel: () => void,
10
- handleOk: () => void
11
- } {
12
-
13
- const [nextLocation, setNextLocation] = React.useState<any | undefined>();
14
- const { navigator } = React.useContext(UNSAFE_NavigationContext);
4
+ /**
5
+ * Type representing a pending navigation action.
6
+ */
7
+ type PendingNavigation =
8
+ | {
9
+ type: "popstate";
10
+ delta: number;
11
+ }
12
+ | {
13
+ type: "link";
14
+ href: string;
15
+ }
16
+ | null;
15
17
 
16
- const navigate = useNavigate();
18
+ /**
19
+ * Custom hook to handle navigation blocking when there are unsaved changes.
20
+ *
21
+ * @param when - Indicates whether to block navigation.
22
+ * @param onSuccess - Callback invoked when navigation is confirmed.
23
+ * @returns An object containing the state of navigation blocking and handlers.
24
+ */
25
+ export function useNavigationUnsavedChangesDialog(
26
+ when: boolean,
27
+ onSuccess: () => void
28
+ ): {
29
+ navigationWasBlocked: boolean;
30
+ handleCancel: () => void;
31
+ handleOk: () => void;
32
+ } {
33
+ const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
34
+ const [pendingNavigation, setPendingNavigation] = useState<PendingNavigation>(null);
17
35
 
18
- const handleCancel = () => {
19
- setNextLocation(undefined);
20
- };
36
+ /**
37
+ * Handler to cancel the navigation attempt.
38
+ */
39
+ const handleCancel = useCallback(() => {
40
+ setIsDialogOpen(false);
41
+ setPendingNavigation(null);
42
+ }, []);
21
43
 
22
- const handleOk = () => {
23
- onSuccess();
24
- setNextLocation(undefined);
25
- navigate(-1);
26
- };
44
+ /**
45
+ * Handler to confirm and proceed with the navigation.
46
+ */
47
+ const handleOk = useCallback(() => {
48
+ setIsDialogOpen(false);
49
+ if (pendingNavigation) {
50
+ onSuccess();
51
+ if (pendingNavigation.type === "popstate") {
52
+ window.history.go(pendingNavigation.delta);
53
+ } else if (pendingNavigation.type === "link") {
54
+ window.location.href = pendingNavigation.href;
55
+ }
56
+ setPendingNavigation(null);
57
+ }
58
+ }, [onSuccess, pendingNavigation]);
27
59
 
28
- const blocker: Blocker = useCallback(({
29
- action,
30
- location: nextLocation,
31
- retry
32
- }) => {
33
- switch (action) {
34
- case "REPLACE": {
35
- retry();
36
- return;
60
+ /**
61
+ * Event handler for beforeunload to handle page refresh or tab close.
62
+ */
63
+ const handleBeforeUnload = useCallback(
64
+ (e: BeforeUnloadEvent) => {
65
+ if (when) {
66
+ e.preventDefault();
67
+ e.returnValue = "";
37
68
  }
38
- case "POP": {
39
- setNextLocation(nextLocation);
69
+ },
70
+ [when]
71
+ );
72
+
73
+ /**
74
+ * Event handler for popstate to handle back and forward browser buttons.
75
+ */
76
+ const handlePopState = useCallback(
77
+ (e: PopStateEvent) => {
78
+ if (when) {
79
+ e.preventDefault();
80
+ // Assuming backward navigation; adjust delta as needed
81
+ setPendingNavigation({
82
+ type: "popstate",
83
+ delta: -1
84
+ });
85
+ setIsDialogOpen(true);
40
86
  }
41
- }
42
- }, []);
87
+ },
88
+ [when]
89
+ );
90
+
91
+ /**
92
+ * Event handler to intercept link clicks within the application.
93
+ */
94
+ const handleLinkClick = useCallback(
95
+ (e: MouseEvent) => {
96
+ if (!when) return;
43
97
 
44
- React.useEffect(() => {
45
- if (!when) return;
46
- if (nextLocation) return;
47
- if (!("block" in navigator)) return;
48
- const unblock = (navigator as any).block((tx: Transition) => {
49
- const autoUnblockingTx = {
50
- ...tx,
51
- retry() {
52
- unblock();
53
- tx.retry();
98
+ const target = e.target as HTMLElement;
99
+ const anchor = target.closest("a[href]") as HTMLAnchorElement | null;
100
+ if (anchor && anchor.host === window.location.host) {
101
+ e.preventDefault();
102
+ const href = anchor.getAttribute("href");
103
+ if (href) {
104
+ setPendingNavigation({
105
+ type: "link",
106
+ href
107
+ });
108
+ setIsDialogOpen(true);
54
109
  }
55
- };
56
- blocker(autoUnblockingTx);
57
- });
110
+ }
111
+ },
112
+ [when]
113
+ );
114
+
115
+ /**
116
+ * Effect hook to add and clean up event listeners based on the `when` condition.
117
+ */
118
+ useEffect(() => {
119
+ if (when) {
120
+ window.addEventListener("beforeunload", handleBeforeUnload);
121
+ window.addEventListener("popstate", handlePopState);
122
+ document.addEventListener("click", handleLinkClick);
123
+ } else {
124
+ window.removeEventListener("beforeunload", handleBeforeUnload);
125
+ window.removeEventListener("popstate", handlePopState);
126
+ document.removeEventListener("click", handleLinkClick);
127
+ }
58
128
 
59
- return unblock;
60
- }, [navigator, blocker, when, nextLocation]);
129
+ // Cleanup on unmount or when `when` changes
130
+ return () => {
131
+ window.removeEventListener("beforeunload", handleBeforeUnload);
132
+ window.removeEventListener("popstate", handlePopState);
133
+ document.removeEventListener("click", handleLinkClick);
134
+ };
135
+ }, [when, handleBeforeUnload, handlePopState, handleLinkClick]);
61
136
 
62
137
  return {
63
- navigationWasBlocked: Boolean(nextLocation),
138
+ navigationWasBlocked: isDialogOpen,
64
139
  handleCancel,
65
- handleOk
140
+ handleOk,
66
141
  };
67
142
  }
68
-
69
- export interface UnsavedChangesDialogProps {
70
- open: boolean;
71
- body?: React.ReactNode;
72
- title?: string;
73
- handleOk: () => void;
74
- handleCancel: () => void;
75
- }
76
-
77
- export function UnsavedChangesDialog({
78
- open,
79
- handleOk,
80
- handleCancel,
81
- body,
82
- title
83
- }: UnsavedChangesDialogProps) {
84
-
85
- return (
86
- <Dialog
87
- open={open}
88
- onOpenChange={(open) => open ? handleCancel() : handleOk()}
89
- >
90
- <DialogContent>
91
- <Typography variant={"h6"}>{title}</Typography>
92
-
93
- {body}
94
-
95
- <Typography>
96
- Are you sure you want to leave this page?
97
- </Typography>
98
-
99
- </DialogContent>
100
- <DialogActions>
101
- <Button variant="text" onClick={handleCancel} autoFocus> Cancel </Button>
102
- <Button onClick={handleOk}> Ok </Button>
103
- </DialogActions>
104
- </Dialog>
105
- );
106
- }
@@ -13,7 +13,7 @@ import {
13
13
  import { resolveProperty } from "../util";
14
14
 
15
15
  import { PropertyPreviewProps } from "./PropertyPreviewProps";
16
- import { useCustomizationController } from "../hooks";
16
+ import { useAuthController, useCustomizationController } from "../hooks";
17
17
  import { EmptyValue } from "./components/EmptyValue";
18
18
  import { UrlComponentPreview } from "./components/UrlComponentPreview";
19
19
  import { StorageThumbnail } from "./components/StorageThumbnail";
@@ -37,6 +37,7 @@ import { ErrorView } from "../components";
37
37
  */
38
38
  export const PropertyPreview = React.memo(function PropertyPreview<T extends CMSType>(props: PropertyPreviewProps<T>) {
39
39
 
40
+ const authController = useAuthController();
40
41
  const customizationController = useCustomizationController();
41
42
 
42
43
  let content: React.ReactNode | any;
@@ -53,10 +54,11 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
53
54
  const property = resolveProperty({
54
55
  propertyKey,
55
56
  propertyOrBuilder: inputProperty,
56
- fields: customizationController.propertyConfigs
57
+ propertyConfigs: customizationController.propertyConfigs,
58
+ authController
57
59
  });
58
60
 
59
- if (value === undefined || property === null) {
61
+ if (property === null) {
60
62
  content = <EmptyValue/>;
61
63
  } else if (property.Preview) {
62
64
  content = createElement(property.Preview as React.ComponentType<PropertyPreviewProps>,
@@ -70,12 +72,19 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
70
72
  // entity,
71
73
  customProps: property.customProps
72
74
  });
73
- } else if (value === null) {
75
+ } else if (value === undefined || value === null) {
74
76
  content = <EmptyValue/>;
75
77
  } else if (property.dataType === "string") {
76
78
  const stringProperty = property as ResolvedStringProperty;
77
79
  if (typeof value === "string") {
78
- if (stringProperty.url) {
80
+ if (stringProperty.storage) {
81
+ const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
82
+ content = <StorageThumbnail
83
+ interactive={interactive}
84
+ storeUrl={property.storage?.storeUrl ?? false}
85
+ size={props.size}
86
+ storagePathOrDownloadUrl={filePath}/>;
87
+ } else if (stringProperty.url) {
79
88
  if (typeof stringProperty.url === "boolean")
80
89
  content =
81
90
  <UrlComponentPreview size={props.size}
@@ -86,15 +95,22 @@ export const PropertyPreview = React.memo(function PropertyPreview<T extends CMS
86
95
  url={value}
87
96
  interactive={interactive}
88
97
  previewType={stringProperty.url}/>;
89
- } else if (stringProperty.storage) {
90
- const filePath = stringProperty.storage.previewUrl ? stringProperty.storage.previewUrl(value) : value;
91
- content = <StorageThumbnail
92
- interactive={interactive}
93
- storeUrl={property.storage?.storeUrl ?? false}
94
- size={props.size}
95
- storagePathOrDownloadUrl={filePath}/>;
96
98
  } else if (stringProperty.markdown) {
97
99
  content = <Markdown source={value} size={"small"}/>;
100
+ } else if (stringProperty.reference) {
101
+ if (typeof stringProperty.reference.path === "string") {
102
+ content = <ReferencePreview
103
+ disabled={!stringProperty.reference.path}
104
+ previewProperties={stringProperty.reference.previewProperties}
105
+ includeId={stringProperty.reference.includeId}
106
+ includeEntityLink={stringProperty.reference.includeEntityLink}
107
+ size={props.size}
108
+ reference={new EntityReference(value, stringProperty.reference.path)}
109
+ />;
110
+ } else {
111
+ content = <EmptyValue/>;
112
+ }
113
+
98
114
  } else {
99
115
  content = <StringPropertyPreview {...props}
100
116
  property={stringProperty}