@firecms/core 3.0.0-beta.6 → 3.0.0-beta.7

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 (129) hide show
  1. package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
  2. package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +4 -2
  3. package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
  4. package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
  5. package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +2 -0
  6. package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
  7. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
  8. package/dist/components/EntityPreview.d.ts +3 -2
  9. package/dist/components/FireCMSAppBar.d.ts +4 -2
  10. package/dist/components/ReferenceWidget.d.ts +3 -1
  11. package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
  12. package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -6
  13. package/dist/components/VirtualTable/types.d.ts +3 -3
  14. package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
  15. package/dist/components/common/index.d.ts +1 -0
  16. package/dist/components/common/table_height.d.ts +5 -0
  17. package/dist/components/common/types.d.ts +3 -5
  18. package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
  19. package/dist/components/index.d.ts +1 -0
  20. package/dist/core/Drawer.d.ts +5 -12
  21. package/dist/core/DrawerNavigationItem.d.ts +9 -0
  22. package/dist/core/NavigationRoutes.d.ts +1 -1
  23. package/dist/core/Scaffold.d.ts +8 -12
  24. package/dist/core/index.d.ts +3 -4
  25. package/dist/hooks/data/save.d.ts +1 -2
  26. package/dist/hooks/index.d.ts +1 -0
  27. package/dist/index.es.js +9950 -9912
  28. package/dist/index.es.js.map +1 -1
  29. package/dist/index.umd.js +5 -5
  30. package/dist/index.umd.js.map +1 -1
  31. package/dist/preview/components/ReferencePreview.d.ts +2 -1
  32. package/dist/types/collections.d.ts +8 -1
  33. package/dist/types/entity_actions.d.ts +14 -0
  34. package/dist/types/navigation.d.ts +2 -2
  35. package/dist/types/properties.d.ts +8 -0
  36. package/dist/util/icon_synonyms.d.ts +1 -97
  37. package/dist/util/objects.d.ts +1 -1
  38. package/dist/util/resolutions.d.ts +8 -8
  39. package/package.json +139 -122
  40. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  41. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +9 -7
  42. package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
  43. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +22 -15
  44. package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
  45. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -1
  46. package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +2 -2
  47. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
  48. package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +5 -6
  49. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
  50. package/src/components/EntityCollectionView/EntityCollectionView.tsx +19 -20
  51. package/src/components/EntityPreview.tsx +9 -7
  52. package/src/components/EntityView.tsx +4 -4
  53. package/src/components/FireCMSAppBar.tsx +32 -15
  54. package/src/components/HomePage/NavigationCard.tsx +2 -2
  55. package/src/components/HomePage/SmallNavigationCard.tsx +5 -5
  56. package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
  57. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +1 -0
  58. package/src/components/ReferenceWidget.tsx +21 -11
  59. package/src/components/SearchIconsView.tsx +5 -5
  60. package/src/components/SelectableTable/SelectableTable.tsx +4 -2
  61. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +4 -1
  62. package/src/components/VirtualTable/VirtualTable.tsx +10 -11
  63. package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
  64. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
  65. package/src/components/VirtualTable/VirtualTableProps.tsx +1 -6
  66. package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
  67. package/src/components/VirtualTable/types.tsx +2 -3
  68. package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +2 -2
  69. package/src/components/common/index.ts +1 -0
  70. package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
  71. package/src/components/common/types.tsx +3 -5
  72. package/src/components/common/useColumnsIds.tsx +10 -2
  73. package/src/components/common/useDataSourceEntityCollectionTableController.tsx +11 -0
  74. package/src/components/index.tsx +1 -0
  75. package/src/core/Drawer.tsx +16 -68
  76. package/src/core/DrawerNavigationItem.tsx +62 -0
  77. package/src/core/EntityEditView.tsx +7 -8
  78. package/src/core/EntitySidePanel.tsx +1 -1
  79. package/src/core/FireCMS.tsx +36 -40
  80. package/src/core/NavigationRoutes.tsx +3 -4
  81. package/src/core/Scaffold.tsx +80 -66
  82. package/src/core/field_configs.tsx +1 -1
  83. package/src/core/index.tsx +3 -4
  84. package/src/form/EntityForm.tsx +29 -21
  85. package/src/form/PropertyFieldBinding.tsx +0 -2
  86. package/src/form/components/StorageItemPreview.tsx +2 -2
  87. package/src/form/components/StorageUploadProgress.tsx +3 -3
  88. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -2
  89. package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
  90. package/src/form/field_bindings/KeyValueFieldBinding.tsx +4 -4
  91. package/src/form/field_bindings/MarkdownFieldBinding.tsx +2 -2
  92. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
  93. package/src/form/field_bindings/ReferenceFieldBinding.tsx +15 -13
  94. package/src/form/field_bindings/SelectFieldBinding.tsx +3 -3
  95. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +4 -4
  96. package/src/hooks/data/save.ts +2 -1
  97. package/src/hooks/index.tsx +1 -0
  98. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +2 -3
  99. package/src/hooks/useBuildNavigationController.tsx +1 -2
  100. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  101. package/src/hooks/useValidateAuthenticator.tsx +15 -15
  102. package/src/internal/useBuildSideEntityController.tsx +72 -11
  103. package/src/preview/PropertyPreview.tsx +2 -2
  104. package/src/preview/components/BooleanPreview.tsx +2 -2
  105. package/src/preview/components/EnumValuesChip.tsx +1 -1
  106. package/src/preview/components/ReferencePreview.tsx +21 -22
  107. package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
  108. package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
  109. package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
  110. package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
  111. package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
  112. package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
  113. package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
  114. package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
  115. package/src/types/collections.ts +14 -2
  116. package/src/types/entity_actions.tsx +16 -3
  117. package/src/types/navigation.ts +1 -2
  118. package/src/types/properties.ts +10 -0
  119. package/src/types/storage.ts +1 -1
  120. package/src/util/enums.ts +1 -1
  121. package/src/util/icon_list.ts +2 -2
  122. package/src/util/icon_synonyms.ts +3 -99
  123. package/src/util/objects.ts +8 -21
  124. package/src/util/resolutions.ts +32 -31
  125. package/dist/components/VirtualTable/common.d.ts +0 -2
  126. package/dist/core/SideEntityView.d.ts +0 -7
  127. package/dist/internal/useBuildCustomizationController.d.ts +0 -2
  128. package/src/core/SideEntityView.tsx +0 -38
  129. package/src/internal/useBuildCustomizationController.tsx +0 -5
@@ -1,9 +1,9 @@
1
1
  import React, { useMemo } from "react";
2
2
 
3
- import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
- import { AuthControllerContext, ModeControllerContext } from "../contexts";
3
+ import { CustomizationController, EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
4
+ import { AuthControllerContext } from "../contexts";
5
5
  import { useBuildSideEntityController } from "../internal/useBuildSideEntityController";
6
- import { useCustomizationController, useFireCMSContext, useModeController } from "../hooks";
6
+ import { useCustomizationController, useFireCMSContext } from "../hooks";
7
7
  import { useBuildSideDialogsController } from "../internal/useBuildSideDialogsController";
8
8
  import { ErrorView } from "../components";
9
9
  import { StorageSourceContext } from "../contexts/StorageSourceContext";
@@ -15,7 +15,6 @@ import { SideDialogsControllerContext } from "../contexts/SideDialogsControllerC
15
15
  import { CenteredView, Typography, useLocaleConfig } from "@firecms/ui";
16
16
  import { DialogsProvider } from "../contexts/DialogsProvider";
17
17
  import { useBuildDataSource } from "../internal/useBuildDataSource";
18
- import { useBuildCustomizationController } from "../internal/useBuildCustomizationController";
19
18
  import { CustomizationControllerContext } from "../contexts/CustomizationControllerContext";
20
19
  import { AnalyticsContext } from "../contexts/AnalyticsContext";
21
20
  import { useProjectLog } from "../hooks/useProjectLog";
@@ -34,7 +33,6 @@ import { useProjectLog } from "../hooks/useProjectLog";
34
33
  */
35
34
  export function FireCMS<UserType extends User, EC extends EntityCollection>(props: FireCMSProps<UserType, EC>) {
36
35
 
37
- const modeController = useModeController();
38
36
  const {
39
37
  children,
40
38
  entityLinkBuilder,
@@ -70,7 +68,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
70
68
 
71
69
  const loading = authController.initialLoading || navigationController.loading || pluginsLoading;
72
70
 
73
- const customizationController = useBuildCustomizationController({
71
+ const customizationController: CustomizationController = {
74
72
  dateTimeFormat,
75
73
  locale,
76
74
  entityLinkBuilder,
@@ -78,7 +76,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
78
76
  entityViews: entityViews ?? [],
79
77
  propertyConfigs: propertyConfigs ?? {},
80
78
  components
81
- });
79
+ };
82
80
 
83
81
  const analyticsController = useMemo(() => ({
84
82
  onAnalyticsEvent
@@ -123,39 +121,37 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
123
121
  }
124
122
 
125
123
  return (
126
- <ModeControllerContext.Provider value={modeController}>
127
- <AnalyticsContext.Provider value={analyticsController}>
128
- <CustomizationControllerContext.Provider value={customizationController}>
129
- <UserConfigurationPersistenceContext.Provider
130
- value={userConfigPersistence}>
131
- <StorageSourceContext.Provider
132
- value={storageSource}>
133
- <DataSourceContext.Provider
134
- value={dataSource}>
135
- <AuthControllerContext.Provider
136
- value={authController}>
137
- <SideDialogsControllerContext.Provider
138
- value={sideDialogsController}>
139
- <SideEntityControllerContext.Provider
140
- value={sideEntityController}>
141
- <NavigationContext.Provider
142
- value={navigationController}>
143
- <DialogsProvider>
144
- <FireCMSInternal
145
- loading={loading}>
146
- {children}
147
- </FireCMSInternal>
148
- </DialogsProvider>
149
- </NavigationContext.Provider>
150
- </SideEntityControllerContext.Provider>
151
- </SideDialogsControllerContext.Provider>
152
- </AuthControllerContext.Provider>
153
- </DataSourceContext.Provider>
154
- </StorageSourceContext.Provider>
155
- </UserConfigurationPersistenceContext.Provider>
156
- </CustomizationControllerContext.Provider>
157
- </AnalyticsContext.Provider>
158
- </ModeControllerContext.Provider>
124
+ <AnalyticsContext.Provider value={analyticsController}>
125
+ <CustomizationControllerContext.Provider value={customizationController}>
126
+ <UserConfigurationPersistenceContext.Provider
127
+ value={userConfigPersistence}>
128
+ <StorageSourceContext.Provider
129
+ value={storageSource}>
130
+ <DataSourceContext.Provider
131
+ value={dataSource}>
132
+ <AuthControllerContext.Provider
133
+ value={authController}>
134
+ <SideDialogsControllerContext.Provider
135
+ value={sideDialogsController}>
136
+ <SideEntityControllerContext.Provider
137
+ value={sideEntityController}>
138
+ <NavigationContext.Provider
139
+ value={navigationController}>
140
+ <DialogsProvider>
141
+ <FireCMSInternal
142
+ loading={loading}>
143
+ {children}
144
+ </FireCMSInternal>
145
+ </DialogsProvider>
146
+ </NavigationContext.Provider>
147
+ </SideEntityControllerContext.Provider>
148
+ </SideDialogsControllerContext.Provider>
149
+ </AuthControllerContext.Provider>
150
+ </DataSourceContext.Provider>
151
+ </StorageSourceContext.Provider>
152
+ </UserConfigurationPersistenceContext.Provider>
153
+ </CustomizationControllerContext.Provider>
154
+ </AnalyticsContext.Provider>
159
155
  );
160
156
 
161
157
  }
@@ -13,7 +13,7 @@ export type NavigationRoutesProps = {
13
13
  /**
14
14
  * In case you need to override the home page
15
15
  */
16
- HomePage?: React.ComponentType;
16
+ homePage?: React.ReactNode;
17
17
 
18
18
  customRoutes?: React.ReactNode[]
19
19
 
@@ -28,10 +28,9 @@ export type NavigationRoutesProps = {
28
28
  * @constructor
29
29
  * @group Components
30
30
  */
31
-
32
31
  export const NavigationRoutes = React.memo<NavigationRoutesProps>(
33
32
  function NavigationRoutes({
34
- HomePage = DefaultHomePage,
33
+ homePage = <DefaultHomePage/>,
35
34
  customRoutes
36
35
  }: NavigationRoutesProps) {
37
36
 
@@ -93,7 +92,7 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
93
92
 
94
93
  const homeRoute = (
95
94
  <Route path={"/"}
96
- element={<HomePage/>}/>
95
+ element={homePage}/>
97
96
  );
98
97
 
99
98
  const notFoundRoute = <Route path={"*"}
@@ -5,19 +5,35 @@ import { Link } from "react-router-dom";
5
5
  import { Drawer as DefaultDrawer, DrawerProps } from "./Drawer";
6
6
  import { useLargeLayout, useNavigationController } from "../hooks";
7
7
  import { ErrorBoundary, FireCMSAppBar as DefaultFireCMSAppBar, FireCMSAppBarProps, FireCMSLogo } from "../components";
8
- import { ChevronLeftIcon, cn, defaultBorderMixin, IconButton, MenuIcon, Sheet, Tooltip } from "@firecms/ui";
8
+ import { ChevronLeftIcon, cls, defaultBorderMixin, IconButton, MenuIcon, Sheet, Tooltip } from "@firecms/ui";
9
9
 
10
10
  export const DRAWER_WIDTH = 280;
11
11
 
12
+ const DrawerContext = React.createContext<DrawerProps>({
13
+ hovered: false,
14
+ drawerOpen: false,
15
+ openDrawer: () => {
16
+ throw new Error("openDrawer not implemented");
17
+ },
18
+ closeDrawer: () => {
19
+ throw new Error("closeDrawer not implemented");
20
+ },
21
+ autoOpenDrawer: false
22
+ });
23
+
24
+ export function useDrawer() {
25
+ return React.useContext(DrawerContext);
26
+ }
27
+
12
28
  /**
13
29
  * @group Core
14
30
  */
15
- export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = object> {
31
+ export interface ScaffoldProps<ExtraAppbarProps = object> {
16
32
 
17
33
  /**
18
34
  * Name of the app, displayed as the main title and in the tab title
19
35
  */
20
- name: string;
36
+ name?: React.ReactNode;
21
37
 
22
38
  /**
23
39
  * Logo to be displayed in the drawer of the CMS
@@ -30,15 +46,10 @@ export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = obj
30
46
  includeDrawer?: boolean;
31
47
 
32
48
  /**
33
- * In case you need to override the view that gets rendered as a drawer
34
- * @see DefaultDrawer
35
- */
36
- Drawer?: React.ComponentType<DrawerProps<ExtraDrawerProps>>;
37
-
38
- /**
39
- * Additional props passed to the custom Drawer
49
+ * You can define a custom drawer to be displayed in the scaffold.
50
+ * Use the hook `useDrawer` to access the context values.
40
51
  */
41
- drawerProps?: Partial<DrawerProps> & ExtraDrawerProps;
52
+ drawer?: React.ReactNode;
42
53
 
43
54
  /**
44
55
  * Open the drawer on hover
@@ -46,8 +57,7 @@ export interface ScaffoldProps<ExtraDrawerProps = object, ExtraAppbarProps = obj
46
57
  autoOpenDrawer?: boolean;
47
58
 
48
59
  /**
49
- * A component that gets rendered on the upper side of the main toolbar.
50
- * `toolbarExtraWidget` has no effect if this is set.
60
+ * The AppBar component to be used in the scaffold.
51
61
  */
52
62
  FireCMSAppBar?: React.ComponentType<FireCMSAppBarProps<ExtraAppbarProps>>;
53
63
 
@@ -78,8 +88,7 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
78
88
  logo,
79
89
  includeDrawer = true,
80
90
  autoOpenDrawer,
81
- Drawer = DefaultDrawer,
82
- drawerProps,
91
+ drawer = <DefaultDrawer/>,
83
92
  FireCMSAppBar = DefaultFireCMSAppBar,
84
93
  fireCMSAppBarProps,
85
94
  } = props;
@@ -92,60 +101,65 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
92
101
  const setOnHoverTrue = useCallback(() => setOnHover(true), []);
93
102
  const setOnHoverFalse = useCallback(() => setOnHover(false), []);
94
103
 
104
+ const handleDrawerOpen = useCallback(() => {
105
+ setDrawerOpen(true);
106
+ }, []);
107
+
95
108
  const handleDrawerClose = useCallback(() => {
96
109
  setDrawerOpen(false);
97
110
  }, []);
98
111
 
99
112
  const computedDrawerOpen: boolean = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);
113
+
100
114
  return (
101
- <div
102
- className="flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden"
103
- style={{
104
- paddingTop: "env(safe-area-inset-top)",
105
- paddingLeft: "env(safe-area-inset-left)",
106
- paddingRight: "env(safe-area-inset-right)",
107
- paddingBottom: "env(safe-area-inset-bottom)",
108
- height: "100dvh"
109
- // "@supports (height: 100dvh)": {
110
- // height: "100dvh"
111
- // }
112
- }}>
113
-
114
- <FireCMSAppBar title={name}
115
- includeDrawer={includeDrawer}
116
- drawerOpen={computedDrawerOpen}
117
- {...fireCMSAppBarProps}/>
118
-
119
- <StyledDrawer
120
- displayed={includeDrawer}
121
- onMouseEnter={setOnHoverTrue}
122
- onMouseMove={setOnHoverTrue}
123
- onMouseLeave={setOnHoverFalse}
124
- open={computedDrawerOpen}
125
- logo={logo}
126
- hovered={onHover}
127
- setDrawerOpen={setDrawerOpen}>
128
- {includeDrawer && (
129
- <Drawer
130
- hovered={onHover}
131
- drawerOpen={computedDrawerOpen}
132
- closeDrawer={handleDrawerClose}
133
- {...drawerProps}/>)}
134
- </StyledDrawer>
135
-
136
- <main
137
- className="flex flex-col flex-grow overflow-auto">
138
- <DrawerHeader/>
139
- <div
140
- className={cn(defaultBorderMixin, "flex-grow overflow-auto lg:m-0 lg:mx-4 lg:mb-4 lg:rounded-lg lg:border lg:border-solid m-0 mt-1")}>
141
-
142
- <ErrorBoundary>
143
- {children}
144
- </ErrorBoundary>
145
-
146
- </div>
147
- </main>
148
- </div>
115
+ <DrawerContext.Provider value={{
116
+ hovered: onHover,
117
+ drawerOpen: computedDrawerOpen,
118
+ closeDrawer: handleDrawerClose,
119
+ openDrawer: handleDrawerOpen,
120
+ autoOpenDrawer
121
+ }}>
122
+ <div
123
+ className="flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden"
124
+ style={{
125
+ paddingTop: "env(safe-area-inset-top)",
126
+ paddingLeft: "env(safe-area-inset-left)",
127
+ paddingRight: "env(safe-area-inset-right)",
128
+ paddingBottom: "env(safe-area-inset-bottom)",
129
+ height: "100dvh"
130
+ }}>
131
+
132
+ <FireCMSAppBar title={name}
133
+ includeDrawer={includeDrawer}
134
+ logo={logo}
135
+ drawerOpen={computedDrawerOpen}
136
+ {...fireCMSAppBarProps}/>
137
+ <DrawerWrapper
138
+ displayed={includeDrawer}
139
+ onMouseEnter={setOnHoverTrue}
140
+ onMouseMove={setOnHoverTrue}
141
+ onMouseLeave={setOnHoverFalse}
142
+ open={computedDrawerOpen}
143
+ logo={logo}
144
+ hovered={onHover}
145
+ setDrawerOpen={setDrawerOpen}>
146
+ {includeDrawer && drawer}
147
+ </DrawerWrapper>
148
+
149
+ <main
150
+ className="flex flex-col flex-grow overflow-auto">
151
+ <DrawerHeader/>
152
+ <div
153
+ className={cls(defaultBorderMixin, "flex-grow overflow-auto lg:m-0 lg:mx-4 lg:mb-4 lg:rounded-lg lg:border lg:border-solid m-0 mt-1")}>
154
+
155
+ <ErrorBoundary>
156
+ {children}
157
+ </ErrorBoundary>
158
+
159
+ </div>
160
+ </main>
161
+ </div>
162
+ </DrawerContext.Provider>
149
163
  );
150
164
  },
151
165
  equal
@@ -157,7 +171,7 @@ const DrawerHeader = () => {
157
171
  );
158
172
  };
159
173
 
160
- function StyledDrawer(props: {
174
+ function DrawerWrapper(props: {
161
175
  children: React.ReactNode,
162
176
  displayed: boolean,
163
177
  open: boolean,
@@ -204,7 +218,7 @@ function StyledDrawer(props: {
204
218
  transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
205
219
  padding: props.open ? "32px 144px 0px 24px" : "72px 16px 0px"
206
220
  }}
207
- className={cn("cursor-pointer")}>
221
+ className={cls("cursor-pointer")}>
208
222
 
209
223
  <Tooltip title={"Home"}
210
224
  sideOffset={20}
@@ -214,7 +228,7 @@ function StyledDrawer(props: {
214
228
  {props.logo
215
229
  ? <img src={props.logo}
216
230
  alt="Logo"
217
- className={cn("max-w-full max-h-full",
231
+ className={cls("max-w-full max-h-full",
218
232
  props.open ?? "w-[112px] h-[112px]")}/>
219
233
  : <FireCMSLogo/>}
220
234
 
@@ -331,7 +331,7 @@ export function getFieldConfig(property: Property | ResolvedProperty, propertyCo
331
331
  }
332
332
  const defaultFieldConfig = DEFAULT_FIELD_CONFIGS[defaultFieldId];
333
333
  const customField = fieldId ? propertyConfigs[fieldId] : undefined;
334
- return mergeDeep(defaultFieldConfig ?? {}, customField ?? {});
334
+ return mergeDeep(defaultFieldConfig ?? {}, customField ?? {} as PropertyConfig);
335
335
  }
336
336
 
337
337
  export function getDefaultFieldId(property: Property | ResolvedProperty) {
@@ -1,10 +1,9 @@
1
1
  export * from "./FireCMS";
2
2
 
3
- export type { ScaffoldProps } from "./Scaffold";
4
- export { Scaffold } from "./Scaffold";
3
+ export * from "./Scaffold";
5
4
 
6
- export type { DrawerProps } from "./Drawer";
7
- export { Drawer, DrawerNavigationItem } from "./Drawer";
5
+ export * from "./Drawer";
6
+ export * from "./DrawerNavigationItem";
8
7
 
9
8
  export * from "./field_configs";
10
9
 
@@ -35,12 +35,9 @@ import {
35
35
  } from "../hooks";
36
36
  import { ErrorFocus } from "./components/ErrorFocus";
37
37
  import { CustomIdField } from "./components/CustomIdField";
38
- import { Alert, Button, cn, DialogActions, IconButton, Tooltip, Typography } from "@firecms/ui";
39
- import { ErrorBoundary } from "../components";
40
- import {
41
- copyEntityAction,
42
- deleteEntityAction
43
- } from "../components/EntityCollectionTable/internal/default_entity_actions";
38
+ import { Alert, Button, CircularProgress, cls, DialogActions, IconButton, Tooltip, Typography } from "@firecms/ui";
39
+ import { CircularProgressCenter, ErrorBoundary } from "../components";
40
+ import { copyEntityAction, deleteEntityAction } from "../components/common/default_entity_actions";
44
41
  import { useAnalyticsController } from "../hooks/useAnalyticsController";
45
42
  import { ValidationError } from "yup";
46
43
  import { PropertyIdCopyTooltipContent } from "../components/PropertyIdCopyTooltipContent";
@@ -135,12 +132,13 @@ export type EntityFormSaveParams<M extends Record<string, any>> = {
135
132
  * @constructor
136
133
  * @group Components
137
134
  */
138
- export const EntityForm = React.memo<EntityFormProps<any>>(EntityFormInternal,
139
- (a: EntityFormProps<any>, b: EntityFormProps<any>) => {
140
- return a.status === b.status &&
141
- a.path === b.path &&
142
- equal(a.entity?.values, b.entity?.values);
143
- }) as typeof EntityFormInternal;
135
+ export const EntityForm = EntityFormInternal;
136
+ // export const EntityForm = React.memo<EntityFormProps<any>>(EntityFormInternal,
137
+ // (a: EntityFormProps<any>, b: EntityFormProps<any>) => {
138
+ // return a.status === b.status &&
139
+ // a.path === b.path &&
140
+ // equal(a.entity?.values, b.entity?.values);
141
+ // }) as typeof EntityFormInternal;
144
142
 
145
143
  function getDataSourceEntityValues<M extends object>(initialResolvedCollection: ResolvedEntityCollection,
146
144
  status: "new" | "existing" | "copy",
@@ -188,7 +186,7 @@ function EntityFormInternal<M extends Record<string, any>>({
188
186
  path,
189
187
  values: entity?.values,
190
188
  fields: customizationController.propertyConfigs
191
- }), [entity?.values, path]);
189
+ }), [entity?.values, path, customizationController.propertyConfigs]);
192
190
 
193
191
  const mustSetCustomId: boolean = (status === "new" || status === "copy") &&
194
192
  (Boolean(initialResolvedCollection.customId) && initialResolvedCollection.customId !== "optional");
@@ -415,7 +413,8 @@ function EntityFormInternal<M extends Record<string, any>>({
415
413
  const pluginActions: React.ReactNode[] = [];
416
414
 
417
415
  const formContext: FormContext<M> = {
418
- setFieldValue: formex.setFieldValue,
416
+ // @ts-ignore
417
+ setFieldValue: useCallback(formex.setFieldValue, []),
419
418
  values: formex.values,
420
419
  collection: resolvedCollection,
421
420
  entityId,
@@ -423,12 +422,14 @@ function EntityFormInternal<M extends Record<string, any>>({
423
422
  save
424
423
  };
425
424
 
425
+ const submittedFormContext = useRef<FormContext<M> | null>(null);
426
426
  // eslint-disable-next-line react-hooks/rules-of-hooks
427
427
  useEffect(() => {
428
- if (onFormContextChange) {
428
+ if (onFormContextChange && !formContextsEqual(submittedFormContext.current ?? undefined, formContext)) {
429
429
  onFormContextChange(formContext);
430
+ submittedFormContext.current = formContext;
430
431
  }
431
- }, [onFormContextChange, formContext]);
432
+ }, [formContext, onFormContextChange]);
432
433
 
433
434
  if (plugins && inputCollection) {
434
435
  const actionProps: PluginFormActionProps = {
@@ -452,7 +453,7 @@ function EntityFormInternal<M extends Record<string, any>>({
452
453
  <div className="h-full overflow-auto">
453
454
 
454
455
  {pluginActions.length > 0 && <div
455
- className={cn("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
456
+ className={cls("w-full flex justify-end items-center sticky top-0 right-0 left-0 z-10 bg-opacity-60 bg-slate-200 dark:bg-opacity-60 dark:bg-slate-800 backdrop-blur-md")}>
456
457
  {pluginActions}
457
458
  </div>}
458
459
 
@@ -670,10 +671,10 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
670
671
  </IconButton>
671
672
  ))}
672
673
  </div>}
673
-
674
+ {isSubmitting && <CircularProgress size={"small"}/>}
674
675
  <Button
675
676
  variant="text"
676
- disabled={disabled}
677
+ disabled={disabled || isSubmitting}
677
678
  type="reset"
678
679
  >
679
680
  {status === "existing" ? "Discard" : "Clear"}
@@ -683,7 +684,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
683
684
  variant="text"
684
685
  color="primary"
685
686
  type="submit"
686
- disabled={disabled}
687
+ disabled={disabled || isSubmitting}
687
688
  onClick={() => {
688
689
  closeAfterSaveRef.current = false;
689
690
  }}
@@ -697,7 +698,7 @@ function InnerForm<M extends Record<string, any>>(props: FormexController<M> & {
697
698
  variant="filled"
698
699
  color="primary"
699
700
  type="submit"
700
- disabled={disabled}
701
+ disabled={disabled || isSubmitting}
701
702
  onClick={() => {
702
703
  closeAfterSaveRef.current = true;
703
704
  }}
@@ -726,3 +727,10 @@ export function yupToFormErrors(yupError: ValidationError): Record<string, any>
726
727
  }
727
728
  return errors;
728
729
  }
730
+
731
+ function formContextsEqual(a: FormContext<any> | undefined, b: FormContext<any> | undefined): boolean {
732
+ return a?.path === b?.path &&
733
+ a?.entityId === b?.entityId &&
734
+ equal(a?.values, b?.values) &&
735
+ equal(a?.collection, b?.collection);
736
+ }
@@ -92,7 +92,6 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
92
92
  let Component: ComponentType<FieldProps<T>> | undefined;
93
93
  const resolvedProperty: ResolvedProperty<T> | null = resolveProperty({
94
94
  propertyKey,
95
- propertyValue: fieldProps.field.value,
96
95
  propertyOrBuilder: property,
97
96
  values: fieldProps.form.values,
98
97
  path: context.path,
@@ -116,7 +115,6 @@ function PropertyFieldBindingInternal<T extends CMSType = CMSType, M extends Rec
116
115
  }
117
116
  const configProperty = resolveProperty({
118
117
  propertyOrBuilder: propertyConfig.property,
119
- propertyValue: fieldProps.field.value,
120
118
  values: fieldProps.form.values,
121
119
  path: context.path,
122
120
  entityId: context.entityId,
@@ -3,7 +3,7 @@ import React from "react";
3
3
  import { Entity, EntityCollection, ResolvedStringProperty } from "../../types";
4
4
  import { PreviewSize, PropertyPreview } from "../../preview";
5
5
 
6
- import { cn, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
6
+ import { cls, IconButton, paperMixin, RemoveIcon, Tooltip } from "@firecms/ui";
7
7
  import { ErrorBoundary } from "../../components";
8
8
 
9
9
  interface StorageItemPreviewProps {
@@ -29,7 +29,7 @@ export function StorageItemPreview({
29
29
  }: StorageItemPreviewProps) {
30
30
 
31
31
  return (
32
- <div className={cn(paperMixin,
32
+ <div className={cls(paperMixin,
33
33
  "relative m-4 border-box flex items-center justify-center",
34
34
  size === "medium" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]")}>
35
35
 
@@ -3,7 +3,7 @@ import React, { useCallback } from "react";
3
3
  import { useSnackbarController, useStorageSource } from "../../hooks";
4
4
  import { StorageFieldItem } from "../../util/useStorageUploadController";
5
5
  import { ErrorView } from "../../components";
6
- import { cn, paperMixin, Skeleton } from "@firecms/ui";
6
+ import { cls, paperMixin, Skeleton } from "@firecms/ui";
7
7
  import { EntityCollection, StorageSource } from "../../types";
8
8
 
9
9
  export interface StorageUploadItemProps {
@@ -49,7 +49,7 @@ export function StorageUploadProgress({
49
49
  metadata
50
50
  })
51
51
  .then(async ({ path }) => {
52
- console.debug("Upload successful");
52
+ console.debug("Upload successful", path);
53
53
  await onFileUploadComplete(path, entry, metadata);
54
54
  if (mounted.current)
55
55
  setLoading(false);
@@ -88,7 +88,7 @@ export function StorageUploadProgress({
88
88
  }
89
89
  return (
90
90
 
91
- <div className={cn(paperMixin,
91
+ <div className={cls(paperMixin,
92
92
  "relative m-4 border-box flex items-center justify-center",
93
93
  `min-w-[${imageSize}px] min-h-[${imageSize}px]`)}>
94
94
 
@@ -6,7 +6,7 @@ import { ErrorView } from "../../components";
6
6
  import { getIconForProperty, getReferenceFrom } from "../../util";
7
7
 
8
8
  import { useNavigationController, useReferenceDialog } from "../../hooks";
9
- import { Button, cn, ExpandablePanel, fieldBackgroundMixin } from "@firecms/ui";
9
+ import { Button, cls, ExpandablePanel, fieldBackgroundMixin } from "@firecms/ui";
10
10
  import { useClearRestoreValue } from "../useClearRestoreValue";
11
11
 
12
12
  type ArrayOfReferencesFieldProps = FieldProps<EntityReference[]>;
@@ -88,6 +88,8 @@ export function ArrayOfReferencesFieldBinding({
88
88
  onClick={onEntryClick}
89
89
  hover={!disabled}
90
90
  reference={entryValue}
91
+ includeId={ofProperty.includeId}
92
+ includeEntityLink={ofProperty.includeEntityLink}
91
93
  />
92
94
  );
93
95
  }, [ofProperty.path, ofProperty.previewProperties, value]);
@@ -130,7 +132,7 @@ export function ArrayOfReferencesFieldBinding({
130
132
  {!tableMode &&
131
133
  <ExpandablePanel
132
134
  titleClassName={fieldBackgroundMixin}
133
- className={cn("px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2", fieldBackgroundMixin)}
135
+ className={cls("px-2 md:px-4 pb-2 md:pb-4 pt-1 md:pt-2", fieldBackgroundMixin)}
134
136
  initiallyExpanded={expanded}
135
137
  title={title}>
136
138
  {body}
@@ -8,7 +8,7 @@ import { EnumValuesChip } from "../../preview";
8
8
  import { FieldProps, FormContext, PropertyFieldBindingProps, PropertyOrBuilder } from "../../types";
9
9
  import { getDefaultValueFor, getIconForProperty, } from "../../util";
10
10
  import { DEFAULT_ONE_OF_TYPE, DEFAULT_ONE_OF_VALUE } from "../../util/common";
11
- import { cn, ExpandablePanel, paperMixin, Select, SelectItem, Typography } from "@firecms/ui";
11
+ import { cls, ExpandablePanel, paperMixin, Select, SelectItem, Typography } from "@firecms/ui";
12
12
  import { useClearRestoreValue } from "../useClearRestoreValue";
13
13
 
14
14
  /**
@@ -193,7 +193,7 @@ function BlockEntry({
193
193
  };
194
194
 
195
195
  return (
196
- <div className={cn(paperMixin, "bg-transparent p-4 my-4 py-8")}>
196
+ <div className={cls(paperMixin, "bg-transparent p-4 my-4 py-8")}>
197
197
 
198
198
  <Field
199
199
  name={typeFieldName}