@firecms/core 3.0.0-canary.6 → 3.0.0-canary.61

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 (242) hide show
  1. package/README.md +2 -2
  2. package/dist/components/ClearFilterSortButton.d.ts +5 -0
  3. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -11
  4. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
  5. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
  6. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
  7. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  8. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +2 -0
  9. package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
  10. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  11. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  12. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -3
  13. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
  14. package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
  15. package/dist/components/EntityPreview.d.ts +26 -7
  16. package/dist/components/EntityView.d.ts +11 -0
  17. package/dist/components/FieldCaption.d.ts +5 -0
  18. package/dist/components/FireCMSAppBar.d.ts +4 -2
  19. package/dist/components/HomePage/NavigationCard.d.ts +8 -0
  20. package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
  21. package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
  22. package/dist/components/HomePage/index.d.ts +3 -1
  23. package/dist/components/ReferenceWidget.d.ts +3 -1
  24. package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
  25. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  26. package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -7
  27. package/dist/components/VirtualTable/types.d.ts +3 -3
  28. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  29. package/dist/components/common/index.d.ts +1 -0
  30. package/dist/components/common/table_height.d.ts +5 -0
  31. package/dist/components/common/types.d.ts +4 -6
  32. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  33. package/dist/components/index.d.ts +5 -2
  34. package/dist/contexts/AuthControllerContext.d.ts +1 -1
  35. package/dist/core/Drawer.d.ts +5 -12
  36. package/dist/core/DrawerNavigationItem.d.ts +9 -0
  37. package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
  38. package/dist/core/NavigationRoutes.d.ts +1 -1
  39. package/dist/core/Scaffold.d.ts +8 -12
  40. package/dist/core/index.d.ts +3 -4
  41. package/dist/form/EntityForm.d.ts +1 -1
  42. package/dist/form/components/ErrorFocus.d.ts +1 -1
  43. package/dist/form/components/StorageItemPreview.d.ts +3 -2
  44. package/dist/form/components/StorageUploadProgress.d.ts +1 -1
  45. package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
  46. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  47. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
  48. package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
  49. package/dist/form/validation.d.ts +1 -1
  50. package/dist/hooks/data/delete.d.ts +2 -2
  51. package/dist/hooks/data/save.d.ts +2 -3
  52. package/dist/hooks/data/useDataSource.d.ts +2 -2
  53. package/dist/hooks/data/useEntityFetch.d.ts +3 -3
  54. package/dist/hooks/index.d.ts +2 -0
  55. package/dist/hooks/useBuildNavigationController.d.ts +6 -4
  56. package/dist/hooks/useProjectLog.d.ts +6 -2
  57. package/dist/hooks/useStorageSource.d.ts +2 -2
  58. package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
  59. package/dist/index.es.js +10498 -9944
  60. package/dist/index.es.js.map +1 -1
  61. package/dist/index.umd.js +5 -5
  62. package/dist/index.umd.js.map +1 -1
  63. package/dist/internal/useBuildDataSource.d.ts +1 -16
  64. package/dist/preview/PropertyPreview.d.ts +1 -1
  65. package/dist/preview/PropertyPreviewProps.d.ts +1 -4
  66. package/dist/preview/components/BooleanPreview.d.ts +5 -1
  67. package/dist/preview/components/EnumValuesChip.d.ts +1 -1
  68. package/dist/preview/components/ReferencePreview.d.ts +3 -8
  69. package/dist/types/analytics.d.ts +1 -1
  70. package/dist/types/auth.d.ts +37 -1
  71. package/dist/types/collections.d.ts +30 -6
  72. package/dist/types/datasource.d.ts +21 -14
  73. package/dist/types/entities.d.ts +5 -1
  74. package/dist/types/entity_actions.d.ts +14 -0
  75. package/dist/types/entity_callbacks.d.ts +2 -2
  76. package/dist/types/entity_overrides.d.ts +6 -0
  77. package/dist/types/index.d.ts +2 -1
  78. package/dist/types/navigation.d.ts +15 -14
  79. package/dist/types/permissions.d.ts +5 -1
  80. package/dist/types/plugins.d.ts +20 -20
  81. package/dist/types/properties.d.ts +12 -4
  82. package/dist/types/property_config.d.ts +2 -2
  83. package/dist/types/roles.d.ts +31 -0
  84. package/dist/types/storage.d.ts +11 -3
  85. package/dist/types/user.d.ts +5 -0
  86. package/dist/util/collections.d.ts +9 -1
  87. package/dist/util/entities.d.ts +1 -1
  88. package/dist/util/icon_synonyms.d.ts +1 -97
  89. package/dist/util/icons.d.ts +8 -2
  90. package/dist/util/navigation_utils.d.ts +2 -2
  91. package/dist/util/objects.d.ts +1 -1
  92. package/dist/util/permissions.d.ts +4 -4
  93. package/dist/util/references.d.ts +4 -2
  94. package/dist/util/resolutions.d.ts +14 -14
  95. package/dist/util/useTraceUpdate.d.ts +1 -0
  96. package/package.json +139 -119
  97. package/src/components/ClearFilterSortButton.tsx +41 -0
  98. package/src/components/DeleteEntityDialog.tsx +4 -4
  99. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -4
  100. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +276 -279
  101. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
  102. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +48 -45
  103. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  104. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +18 -17
  105. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
  106. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
  107. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +16 -12
  108. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
  109. package/src/components/EntityCollectionView/EntityCollectionView.tsx +73 -72
  110. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
  111. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
  112. package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
  113. package/src/components/EntityPreview.tsx +209 -70
  114. package/src/components/EntityView.tsx +84 -0
  115. package/src/components/FieldCaption.tsx +14 -0
  116. package/src/components/FireCMSAppBar.tsx +40 -15
  117. package/src/components/HomePage/DefaultHomePage.tsx +15 -11
  118. package/src/components/HomePage/NavigationCard.tsx +69 -0
  119. package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
  120. package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
  121. package/src/components/HomePage/index.tsx +3 -1
  122. package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
  123. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
  124. package/src/components/ReferenceWidget.tsx +22 -12
  125. package/src/components/SearchIconsView.tsx +5 -5
  126. package/src/components/SelectableTable/SelectableTable.tsx +5 -3
  127. package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
  128. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
  129. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -24
  130. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
  131. package/src/components/VirtualTable/VirtualTable.tsx +38 -29
  132. package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
  133. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  134. package/src/components/VirtualTable/VirtualTableProps.tsx +7 -7
  135. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  136. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
  137. package/src/components/VirtualTable/types.tsx +2 -3
  138. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +11 -7
  139. package/src/components/common/index.ts +1 -0
  140. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  141. package/src/components/common/types.tsx +4 -6
  142. package/src/components/common/useColumnsIds.tsx +10 -2
  143. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
  144. package/src/components/common/useTableSearchHelper.ts +39 -9
  145. package/src/components/index.tsx +5 -2
  146. package/src/contexts/AuthControllerContext.tsx +1 -1
  147. package/src/core/Drawer.tsx +78 -103
  148. package/src/core/DrawerNavigationItem.tsx +62 -0
  149. package/src/core/{EntityView.tsx → EntityEditView.tsx} +27 -45
  150. package/src/core/EntitySidePanel.tsx +3 -3
  151. package/src/core/FireCMS.tsx +54 -43
  152. package/src/core/NavigationRoutes.tsx +11 -4
  153. package/src/core/Scaffold.tsx +80 -66
  154. package/src/core/field_configs.tsx +2 -3
  155. package/src/core/index.tsx +3 -4
  156. package/src/form/EntityForm.tsx +42 -27
  157. package/src/form/PropertyFieldBinding.tsx +0 -2
  158. package/src/form/components/StorageItemPreview.tsx +7 -5
  159. package/src/form/components/StorageUploadProgress.tsx +9 -8
  160. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +10 -12
  161. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
  162. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  163. package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -19
  164. package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
  165. package/src/form/field_bindings/MarkdownFieldBinding.tsx +2 -2
  166. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -3
  167. package/src/form/field_bindings/ReferenceFieldBinding.tsx +16 -13
  168. package/src/form/field_bindings/SelectFieldBinding.tsx +3 -3
  169. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +18 -9
  170. package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
  171. package/src/form/validation.ts +3 -4
  172. package/src/hooks/data/delete.ts +3 -3
  173. package/src/hooks/data/save.ts +4 -2
  174. package/src/hooks/data/useCollectionFetch.tsx +1 -1
  175. package/src/hooks/data/useDataSource.tsx +8 -3
  176. package/src/hooks/data/useEntityFetch.tsx +4 -4
  177. package/src/hooks/index.tsx +3 -0
  178. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
  179. package/src/hooks/useBuildModeController.tsx +11 -5
  180. package/src/hooks/useBuildNavigationController.tsx +200 -83
  181. package/src/hooks/useProjectLog.tsx +17 -7
  182. package/src/hooks/useReferenceDialog.tsx +2 -2
  183. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  184. package/src/hooks/useStorageSource.tsx +7 -2
  185. package/src/hooks/useValidateAuthenticator.tsx +115 -0
  186. package/src/internal/useBuildDataSource.ts +54 -47
  187. package/src/internal/useBuildSideEntityController.tsx +88 -21
  188. package/src/preview/PropertyPreview.tsx +5 -15
  189. package/src/preview/PropertyPreviewProps.tsx +1 -11
  190. package/src/preview/components/BooleanPreview.tsx +19 -4
  191. package/src/preview/components/EnumValuesChip.tsx +2 -2
  192. package/src/preview/components/ReferencePreview.tsx +72 -165
  193. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
  194. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
  195. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
  196. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  197. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
  198. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
  199. package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
  200. package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
  201. package/src/types/analytics.ts +1 -0
  202. package/src/types/auth.tsx +50 -1
  203. package/src/types/collections.ts +37 -6
  204. package/src/types/datasource.ts +24 -17
  205. package/src/types/entities.ts +9 -1
  206. package/src/types/entity_actions.tsx +17 -0
  207. package/src/types/entity_callbacks.ts +2 -2
  208. package/src/types/entity_overrides.tsx +7 -0
  209. package/src/types/firecms.tsx +0 -1
  210. package/src/types/index.ts +2 -1
  211. package/src/types/navigation.ts +17 -17
  212. package/src/types/permissions.ts +6 -1
  213. package/src/types/plugins.tsx +26 -28
  214. package/src/types/properties.ts +18 -6
  215. package/src/types/property_config.tsx +2 -2
  216. package/src/types/roles.ts +41 -0
  217. package/src/types/side_entity_controller.tsx +1 -0
  218. package/src/types/storage.ts +12 -3
  219. package/src/types/user.ts +7 -0
  220. package/src/util/collections.ts +22 -0
  221. package/src/util/entities.ts +1 -1
  222. package/src/util/enums.ts +1 -1
  223. package/src/util/icon_list.ts +2 -2
  224. package/src/util/icon_synonyms.ts +3 -99
  225. package/src/util/icons.tsx +11 -3
  226. package/src/util/navigation_utils.ts +6 -6
  227. package/src/util/objects.ts +8 -21
  228. package/src/util/permissions.ts +11 -8
  229. package/src/util/references.ts +36 -5
  230. package/src/util/resolutions.ts +32 -31
  231. package/src/util/strings.ts +2 -2
  232. package/src/util/useTraceUpdate.tsx +2 -1
  233. package/dist/components/VirtualTable/common.d.ts +0 -2
  234. package/dist/core/SideEntityView.d.ts +0 -7
  235. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  236. package/dist/internal/useLocaleConfig.d.ts +0 -1
  237. package/dist/types/appcheck.d.ts +0 -26
  238. package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
  239. package/src/core/SideEntityView.tsx +0 -38
  240. package/src/internal/useBuildCustomizationController.tsx +0 -5
  241. package/src/internal/useLocaleConfig.tsx +0 -18
  242. package/src/types/appcheck.ts +0 -29
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
 
3
3
  import { EntityCollection } from "../../types";
4
- import { useCustomizationController, useFireCMSContext } from "../../hooks";
4
+ import { useCustomizationController, useDataSource, useFireCMSContext } from "../../hooks";
5
5
 
6
6
  export interface UseTableSearchHelperParams<M extends Record<string, any>> {
7
7
  collection: EntityCollection<M>;
@@ -9,27 +9,47 @@ export interface UseTableSearchHelperParams<M extends Record<string, any>> {
9
9
  parentCollectionIds?: string[];
10
10
  }
11
11
 
12
- export function useTableSearchHelper<M extends Record<string, any>>({ collection, fullPath, parentCollectionIds }: UseTableSearchHelperParams<M>) {
12
+ export function useTableSearchHelper<M extends Record<string, any>>({
13
+ collection,
14
+ fullPath,
15
+ parentCollectionIds
16
+ }: UseTableSearchHelperParams<M>) {
13
17
 
14
18
  const context = useFireCMSContext();
15
19
  const customizationController = useCustomizationController();
20
+ const dataSource = useDataSource();
16
21
 
17
22
  const [textSearchLoading, setTextSearchLoading] = useState<boolean>(false);
18
23
  const [textSearchInitialised, setTextSearchInitialised] = useState<boolean>(false);
19
24
  let onTextSearchClick: (() => void) | undefined;
20
25
  let textSearchEnabled = Boolean(collection.textSearchEnabled);
21
26
  if (customizationController?.plugins) {
22
- const addTextSearchClickListener = customizationController.plugins?.find(p => Boolean(p.collectionView?.onTextSearchClick));
27
+ const addTextSearchClickListener = dataSource?.initTextSearch || customizationController.plugins?.find(p => Boolean(p.collectionView?.onTextSearchClick));
23
28
 
24
29
  onTextSearchClick = addTextSearchClickListener
25
30
  ? () => {
26
31
  setTextSearchLoading(true);
27
- Promise.all(customizationController.plugins?.map(p => {
32
+ const promises: Promise<boolean>[] = [];
33
+ if (dataSource?.initTextSearch) {
34
+ promises.push(dataSource.initTextSearch({
35
+ context,
36
+ path: fullPath,
37
+ collection,
38
+ parentCollectionIds
39
+ }));
40
+ }
41
+ customizationController.plugins?.forEach(p => {
28
42
  if (p.collectionView?.onTextSearchClick)
29
- return p.collectionView.onTextSearchClick({ context, path: fullPath, collection, parentCollectionIds });
43
+ promises.push(p.collectionView.onTextSearchClick({
44
+ context,
45
+ path: fullPath,
46
+ collection,
47
+ parentCollectionIds
48
+ }));
30
49
  return Promise.resolve(true);
31
- }) as Promise<boolean>[])
32
- .then((res) => {
50
+ })
51
+ return Promise.all(promises)
52
+ .then((res: boolean[]) => {
33
53
  if (res.every(Boolean)) setTextSearchInitialised(true);
34
54
  })
35
55
  .finally(() => setTextSearchLoading(false));
@@ -39,9 +59,19 @@ export function useTableSearchHelper<M extends Record<string, any>>({ collection
39
59
  customizationController.plugins?.forEach(p => {
40
60
  if (!textSearchEnabled)
41
61
  if (p.collectionView?.showTextSearchBar) {
42
- textSearchEnabled = p.collectionView.showTextSearchBar({ context, path: fullPath, collection, parentCollectionIds });
62
+ textSearchEnabled = p.collectionView.showTextSearchBar({
63
+ context,
64
+ path: fullPath,
65
+ collection,
66
+ parentCollectionIds
67
+ });
43
68
  }
44
69
  })
45
70
  }
46
- return { textSearchLoading, textSearchInitialised, onTextSearchClick, textSearchEnabled };
71
+ return {
72
+ textSearchLoading,
73
+ textSearchInitialised,
74
+ onTextSearchClick,
75
+ textSearchEnabled
76
+ };
47
77
  }
@@ -1,8 +1,8 @@
1
1
  export type { ErrorViewProps } from "./ErrorView";
2
2
  export { ErrorView } from "./ErrorView";
3
3
 
4
- export type { EntityPreviewProps } from "./EntityPreview";
5
- export { EntityPreview } from "./EntityPreview";
4
+ export type { EntityViewProps } from "./EntityView";
5
+ export { EntityView } from "./EntityView";
6
6
 
7
7
  export type { ReferenceSelectionInnerProps } from "./ReferenceTable/ReferenceSelectionTable";
8
8
  export { ReferenceSelectionTable } from "./ReferenceTable/ReferenceSelectionTable";
@@ -13,8 +13,10 @@ export * from "./common";
13
13
 
14
14
  export * from "./HomePage";
15
15
  export * from "./SelectableTable/SelectableTable";
16
+ export * from "./SelectableTable/SelectableTableContext";
16
17
  export * from "./EntityCollectionView/EntityCollectionView";
17
18
  export * from "./EntityCollectionView/EntityCollectionViewActions";
19
+ export * from "./EntityCollectionView/useSelectionController";
18
20
 
19
21
  export * from "./PropertyConfigBadge";
20
22
 
@@ -32,3 +34,4 @@ export * from "./FireCMSAppBar";
32
34
  export * from "./ArrayContainer";
33
35
  export * from "./ReferenceWidget";
34
36
  export * from "./SearchIconsView";
37
+ export * from "./FieldCaption";
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { AuthController } from "../types";
3
3
 
4
- export const AuthControllerContext = React.createContext<AuthController>({} as AuthController);
4
+ export const AuthControllerContext = React.createContext<AuthController<any, any>>({} as AuthController<any, any>);
@@ -2,37 +2,46 @@ import React, { useCallback } from "react";
2
2
 
3
3
  import { useLargeLayout, useNavigationController } from "../hooks";
4
4
 
5
- import { NavLink } from "react-router-dom";
5
+ import { useNavigate } from "react-router-dom";
6
6
  import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
7
7
  import { IconForView } from "../util";
8
- import { cn, Tooltip, Typography } from "@firecms/ui";
8
+ import { cls, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from "@firecms/ui";
9
9
  import { useAnalyticsController } from "../hooks/useAnalyticsController";
10
+ import { useDrawer } from "./Scaffold";
11
+ import { DrawerNavigationItem } from "./DrawerNavigationItem";
10
12
 
11
13
  /**
12
14
  * Props used in case you need to override the default drawer
13
15
  * @group Core
14
16
  */
15
- export type DrawerProps<T = {}> = T & {
17
+ export type DrawerProps = {
16
18
  hovered: boolean,
17
19
  drawerOpen: boolean,
18
- closeDrawer: () => any,
20
+ openDrawer: () => void,
21
+ closeDrawer: () => void,
22
+ autoOpenDrawer?: boolean
19
23
  }
20
24
 
21
25
  /**
22
26
  * Default drawer used in the CMS
23
27
  * @group Core
24
28
  */
25
- export function Drawer({
26
- hovered,
27
- drawerOpen,
28
- closeDrawer
29
- }: DrawerProps) {
29
+ export function Drawer() {
30
+
31
+ const {
32
+ hovered,
33
+ drawerOpen,
34
+ closeDrawer,
35
+ } = useDrawer();
30
36
 
31
37
  const analyticsController = useAnalyticsController();
32
38
  const navigation = useNavigationController();
33
39
 
34
40
  const tooltipsOpen = hovered && !drawerOpen;
35
41
  const largeLayout = useLargeLayout();
42
+ const navigate = useNavigate();
43
+
44
+ const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
36
45
 
37
46
  if (!navigation.topLevelNavigation)
38
47
  throw Error("Navigation not ready in Drawer");
@@ -42,7 +51,8 @@ export function Drawer({
42
51
  groups
43
52
  }: TopNavigationResult = navigation.topLevelNavigation;
44
53
 
45
- const ungroupedNavigationViews = Object.values(navigationEntries).filter(e => !e.group);
54
+ const adminViews = navigationEntries.filter(e => e.type === "admin") ?? [];
55
+ const groupsWithoutAdmin = groups.filter(g => g !== "Admin");
46
56
 
47
57
  const buildGroupHeader = useCallback((group?: string) => {
48
58
  if (!drawerOpen) return <div className="h-12 w-full"/>;
@@ -67,98 +77,63 @@ export function Drawer({
67
77
  };
68
78
 
69
79
  return (
70
- <div className={"flex-grow overflow-scroll no-scrollbar"}>
71
-
72
- {groups.map((group) => (
73
- <React.Fragment
74
- key={`drawer_group_${group}`}>
75
- {buildGroupHeader(group)}
76
- {Object.values(navigationEntries)
77
- .filter(e => e.group === group)
78
- .map((view, index) =>
79
- <DrawerNavigationItem
80
- key={`navigation_${index}`}
81
- icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
82
- tooltipsOpen={tooltipsOpen}
83
- drawerOpen={drawerOpen}
84
- onClick={() => onClick(view)}
85
- url={view.url}
86
- name={view.name}/>)}
87
- </React.Fragment>
88
- ))}
89
-
90
- {ungroupedNavigationViews.length > 0 && buildGroupHeader()}
91
-
92
- {ungroupedNavigationViews.map((view, index) => {
93
-
94
- return <DrawerNavigationItem
95
- key={`navigation_${index}`}
96
- icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
97
- tooltipsOpen={tooltipsOpen}
98
- onClick={() => onClick(view)}
99
- drawerOpen={drawerOpen}
100
- url={view.url}
101
- name={view.name}/>;
102
- })}
103
-
104
- </div>
80
+ <>
81
+
82
+ <div className={"flex-grow overflow-scroll no-scrollbar"}>
83
+
84
+ {groupsWithoutAdmin.map((group) => (
85
+ <React.Fragment
86
+ key={`drawer_group_${group}`}>
87
+ {buildGroupHeader(group)}
88
+ {Object.values(navigationEntries)
89
+ .filter(e => e.group === group)
90
+ .map((view, index) =>
91
+ <DrawerNavigationItem
92
+ key={`navigation_${index}`}
93
+ icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
94
+ tooltipsOpen={tooltipsOpen}
95
+ drawerOpen={drawerOpen}
96
+ onClick={() => onClick(view)}
97
+ url={view.url}
98
+ name={view.name}/>)}
99
+ </React.Fragment>
100
+ ))}
101
+
102
+ </div>
103
+
104
+ {adminViews.length > 0 && <Menu
105
+ open={adminMenuOpen}
106
+ onOpenChange={setAdminMenuOpen}
107
+ trigger={
108
+ <IconButton
109
+ shape={"square"}
110
+ className={"m-4 text-gray-900 dark:text-white w-fit"}>
111
+ <Tooltip title={"Admin"}
112
+ open={tooltipsOpen}
113
+ side={"right"} sideOffset={28}>
114
+ <MoreVertIcon/>
115
+ </Tooltip>
116
+ {drawerOpen && <div
117
+ className={cls(
118
+ drawerOpen ? "opacity-100" : "opacity-0 hidden",
119
+ "mx-4 font-inherit text-inherit"
120
+ )}>
121
+ ADMIN
122
+ </div>}
123
+ </IconButton>}
124
+ >
125
+ {adminViews.map((entry, index) =>
126
+ <MenuItem
127
+ onClick={(event) => {
128
+ event.preventDefault();
129
+ navigate(entry.path);
130
+ }}
131
+ key={`navigation_${index}`}>
132
+ {<IconForView collectionOrView={entry.view}/>}
133
+ {entry.name}
134
+ </MenuItem>)}
135
+
136
+ </Menu>}
137
+ </>
105
138
  );
106
139
  }
107
-
108
- export function DrawerNavigationItem({
109
- name,
110
- icon,
111
- drawerOpen,
112
- tooltipsOpen,
113
- url,
114
- onClick
115
- }: {
116
- icon: React.ReactElement,
117
- name: string,
118
- tooltipsOpen: boolean,
119
- drawerOpen: boolean,
120
- url: string,
121
- onClick?: () => void,
122
- }) {
123
-
124
- const iconWrap = <div
125
- className={"text-gray-600 dark:text-gray-500"}>
126
- {icon}
127
- </div>;
128
-
129
- const listItem = <NavLink
130
- onClick={onClick}
131
- style={{
132
- width: !drawerOpen ? "72px" : "280px",
133
- transition: drawerOpen ? "width 150ms ease-in" : undefined
134
- }}
135
- className={({ isActive }: any) => cn("rounded-r-xl truncate",
136
- "hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-gray-100",
137
- "flex flex-row items-center mr-8",
138
- // "transition-all ease-in-out delay-100 duration-300",
139
- // drawerOpen ? "w-full" : "w-18",
140
- drawerOpen ? "pl-8 h-12" : "pl-6 h-11",
141
- "font-medium text-sm",
142
- isActive ? "bg-slate-200 bg-opacity-75 dark:bg-gray-800" : ""
143
- )}
144
- to={url}
145
- >
146
-
147
- {iconWrap}
148
-
149
- <div
150
- className={cn(
151
- drawerOpen ? "opacity-100" : "opacity-0 hidden",
152
- "ml-4 font-inherit text-inherit"
153
- )}>
154
- {name.toUpperCase()}
155
- </div>
156
- </NavLink>;
157
-
158
- return <Tooltip
159
- open={drawerOpen ? false : tooltipsOpen}
160
- side="right"
161
- title={name}>
162
- {listItem}
163
- </Tooltip>;
164
- }
@@ -0,0 +1,62 @@
1
+ import React from "react";
2
+
3
+ import { NavLink } from "react-router-dom";
4
+ import { cls, Tooltip } from "@firecms/ui";
5
+
6
+ export function DrawerNavigationItem({
7
+ name,
8
+ icon,
9
+ drawerOpen,
10
+ tooltipsOpen,
11
+ url,
12
+ onClick
13
+ }: {
14
+ icon: React.ReactElement,
15
+ name: string,
16
+ tooltipsOpen: boolean,
17
+ drawerOpen: boolean,
18
+ url: string,
19
+ onClick?: () => void,
20
+ }) {
21
+
22
+ const iconWrap = <div
23
+ className={"text-gray-600 dark:text-gray-500"}>
24
+ {icon}
25
+ </div>;
26
+
27
+ const listItem = <NavLink
28
+ onClick={onClick}
29
+ style={{
30
+ width: !drawerOpen ? "72px" : "280px",
31
+ transition: drawerOpen ? "width 150ms ease-in" : undefined
32
+ }}
33
+ className={({ isActive }: any) => cls("rounded-r-lg truncate",
34
+ "hover:bg-slate-300 hover:bg-opacity-75 dark:hover:bg-gray-700 dark:hover:bg-opacity-75 text-gray-800 dark:text-gray-200 hover:text-gray-900 hover:dark:text-white",
35
+ "flex flex-row items-center mr-8",
36
+ // "transition-all ease-in-out delay-100 duration-300",
37
+ // drawerOpen ? "w-full" : "w-18",
38
+ drawerOpen ? "pl-8 h-12" : "pl-6 h-11",
39
+ "font-medium text-sm",
40
+ isActive ? "bg-slate-200 bg-opacity-60 dark:bg-gray-800 dark:bg-opacity-30" : ""
41
+ )}
42
+ to={url}
43
+ >
44
+
45
+ {iconWrap}
46
+
47
+ <div
48
+ className={cls(
49
+ drawerOpen ? "opacity-100" : "opacity-0 hidden",
50
+ "ml-4 font-inherit text-inherit"
51
+ )}>
52
+ {name.toUpperCase()}
53
+ </div>
54
+ </NavLink>;
55
+
56
+ return <Tooltip
57
+ open={drawerOpen ? false : tooltipsOpen}
58
+ side="right"
59
+ title={name}>
60
+ {listItem}
61
+ </Tooltip>;
62
+ }
@@ -9,10 +9,9 @@ import {
9
9
  FormContext,
10
10
  User
11
11
  } from "../types";
12
- import { CircularProgressCenter, EntityCollectionView, EntityPreview, ErrorBoundary, } from "../components";
12
+ import { CircularProgressCenter, EntityCollectionView, EntityView, ErrorBoundary, } from "../components";
13
13
  import {
14
14
  canEditEntity,
15
- fullPathToCollectionSegments,
16
15
  removeInitialAndTrailingSlashes,
17
16
  resolveDefaultSelectedView,
18
17
  resolveEntityView,
@@ -30,14 +29,13 @@ import {
30
29
  useSnackbarController
31
30
  } from "../hooks";
32
31
  import { EntityForm } from "../form";
33
- import { CircularProgress, CloseIcon, cn, defaultBorderMixin, IconButton, Tab, Tabs, Typography } from "@firecms/ui";
32
+ import { CircularProgress, CloseIcon, cls, defaultBorderMixin, IconButton, Tab, Tabs, Typography } from "@firecms/ui";
34
33
  import { EntityFormSaveParams } from "../form/EntityForm";
35
- import { FORM_CONTAINER_WIDTH } from "../internal/common";
36
34
  import { useSideDialogContext } from "./index";
37
35
 
38
36
  const MAIN_TAB_VALUE = "main_##Q$SC^#S6";
39
37
 
40
- export interface EntityViewProps<M extends Record<string, any>> {
38
+ export interface EntityEditViewProps<M extends Record<string, any>> {
41
39
  path: string;
42
40
  collection: EntityCollection<M>;
43
41
  entityId?: string;
@@ -56,18 +54,18 @@ export interface EntityViewProps<M extends Record<string, any>> {
56
54
  * You probably don't want to use this view directly since it is bound to the
57
55
  * side panel. Instead, you might want to use {@link EntityForm} or {@link EntityCollectionView}
58
56
  */
59
- export function EntityView<M extends Record<string, any>, UserType extends User>({
60
- path,
61
- entityId,
62
- selectedSubPath,
63
- copy,
64
- collection,
65
- parentCollectionIds,
66
- onValuesAreModified,
67
- formWidth,
68
- onUpdate,
69
- onClose
70
- }: EntityViewProps<M>) {
57
+ export function EntityEditView<M extends Record<string, any>, UserType extends User>({
58
+ path,
59
+ entityId,
60
+ selectedSubPath,
61
+ copy,
62
+ collection,
63
+ parentCollectionIds,
64
+ onValuesAreModified,
65
+ formWidth,
66
+ onUpdate,
67
+ onClose,
68
+ }: EntityEditViewProps<M>) {
71
69
 
72
70
  if (collection.customId && collection.formAutoSave) {
73
71
  console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
@@ -92,10 +90,9 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
92
90
 
93
91
  // const largeLayout = useLargeLayout();
94
92
  // const largeLayoutTabSelected = useRef(!largeLayout);
93
+ // const resolvedFormWidth: string = typeof formWidth === "number" ? `${formWidth}px` : formWidth ?? FORM_CONTAINER_WIDTH;
95
94
 
96
- const resolvedFormWidth: string = typeof formWidth === "number" ? `${formWidth}px` : formWidth ?? FORM_CONTAINER_WIDTH;
97
-
98
- const dataSource = useDataSource();
95
+ const dataSource = useDataSource(collection);
99
96
  const sideDialogContext = useSideDialogContext();
100
97
  const sideEntityController = useSideEntityController();
101
98
  const snackbarController = useSnackbarController();
@@ -154,29 +151,12 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
154
151
  if (status === "new") {
155
152
  setReadOnly(false);
156
153
  } else {
157
- const editEnabled = usedEntity ? canEditEntity(collection, authController, fullPathToCollectionSegments(path), usedEntity ?? null) : false;
154
+ const editEnabled = usedEntity ? canEditEntity(collection, authController, path, usedEntity ?? null) : false;
158
155
  if (usedEntity)
159
156
  setReadOnly(!editEnabled);
160
157
  }
161
158
  }, [authController, usedEntity, status]);
162
159
 
163
- // useEffect(() => {
164
- // if (largeLayoutTabSelected.current === largeLayout)
165
- // return;
166
- // // open first tab by default in large layouts
167
- // if (selectedSubPath !== defaultSelectedView) {
168
- // console.log("Replacing url 1", defaultSelectedView);
169
- // sideEntityController.replace({
170
- // path,
171
- // entityId,
172
- // selectedSubPath: defaultSelectedView,
173
- // updateUrl: true,
174
- // collection
175
- // });
176
- // }
177
- // largeLayoutTabSelected.current = largeLayout;
178
- // }, [defaultSelectedView, largeLayout, selectedSubPath]);
179
-
180
160
  const onPreSaveHookError = useCallback((e: Error) => {
181
161
  setSaving(false);
182
162
  snackbarController.open({
@@ -213,6 +193,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
213
193
  onUpdate({ entity: updatedEntity });
214
194
 
215
195
  if (closeAfterSave) {
196
+ console.log("Closing side dialog")
216
197
  sideDialogContext.setBlocked(false);
217
198
  sideDialogContext.close(true);
218
199
  onClose?.();
@@ -222,7 +203,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
222
203
  entityId: updatedEntity.id,
223
204
  selectedSubPath: selectedTabRef.current,
224
205
  updateUrl: true,
225
- collection
206
+ collection,
226
207
  });
227
208
  }
228
209
 
@@ -256,7 +237,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
256
237
  closeAfterSave: boolean,
257
238
  }) => {
258
239
  setSaving(true);
259
- saveEntityWithCallbacks({
240
+ return saveEntityWithCallbacks({
260
241
  path,
261
242
  entityId,
262
243
  values,
@@ -287,7 +268,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
287
268
  if (autoSave) {
288
269
  setValuesToBeSaved(values);
289
270
  } else {
290
- saveEntity({
271
+ return saveEntity({
291
272
  collection,
292
273
  path,
293
274
  entityId,
@@ -302,6 +283,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
302
283
  .map(e => resolveEntityView(e, customizationController.entityViews))
303
284
  .filter(Boolean) as EntityCustomView[]
304
285
  : [];
286
+
305
287
  const customViewsView: React.ReactNode[] | undefined = customViews && resolvedEntityViews
306
288
  .map(
307
289
  (customView, colIndex) => {
@@ -315,7 +297,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
315
297
  return null;
316
298
  }
317
299
  return <div
318
- className={cn(defaultBorderMixin,
300
+ className={cls(defaultBorderMixin,
319
301
  "relative flex-grow w-full h-full overflow-auto ")}
320
302
  key={`custom_view_${customView.key}`}
321
303
  role="tabpanel">
@@ -382,7 +364,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
382
364
  entityId,
383
365
  selectedSubPath: value === MAIN_TAB_VALUE ? undefined : value,
384
366
  updateUrl: true,
385
- collection
367
+ collection,
386
368
  });
387
369
  };
388
370
 
@@ -463,7 +445,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
463
445
  className={"mt-16 mb-8 mx-8"}
464
446
  variant={"h4"}>{collection.singularName ?? collection.name}
465
447
  </Typography>
466
- <EntityPreview
448
+ <EntityView
467
449
  className={"px-12"}
468
450
  entity={usedEntity as Entity<M>}
469
451
  path={path}
@@ -499,7 +481,7 @@ export function EntityView<M extends Record<string, any>, UserType extends User>
499
481
  <>
500
482
 
501
483
  <div
502
- className={cn(defaultBorderMixin, "no-scrollbar border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-gray-50 dark:bg-gray-950")}>
484
+ className={cls(defaultBorderMixin, "no-scrollbar border-b pl-2 pr-2 pt-1 flex items-end overflow-scroll bg-gray-50 dark:bg-gray-950")}>
503
485
 
504
486
  <div
505
487
  className="pb-1 self-center">
@@ -4,7 +4,7 @@ import { EntitySidePanelProps } from "../types";
4
4
  import { useNavigationController } from "../hooks";
5
5
 
6
6
  import { ErrorBoundary } from "../components";
7
- import { EntityView } from "./EntityView";
7
+ import { EntityEditView } from "./EntityEditView";
8
8
  import { useSideDialogContext } from "./SideDialogs";
9
9
 
10
10
  /**
@@ -33,7 +33,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
33
33
  if (!props) return undefined;
34
34
  let usedCollection = props.collection;
35
35
 
36
- const registryCollection = navigationController.getCollection(props.path, props.entityId);
36
+ const registryCollection = navigationController.getCollection(props.path);
37
37
  if (registryCollection) {
38
38
  usedCollection = registryCollection;
39
39
  }
@@ -77,7 +77,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
77
77
  return (
78
78
  <>
79
79
  <ErrorBoundary>
80
- <EntityView
80
+ <EntityEditView
81
81
  {...props}
82
82
  formWidth={props.width}
83
83
  collection={collection}