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

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 (94) hide show
  1. package/dist/app/AppBar.d.ts +12 -0
  2. package/dist/app/Drawer.d.ts +17 -0
  3. package/dist/app/Scaffold.d.ts +30 -0
  4. package/dist/app/index.d.ts +4 -0
  5. package/dist/app/useApp.d.ts +16 -0
  6. package/dist/components/VirtualTable/VirtualTableProps.d.ts +4 -0
  7. package/dist/components/index.d.ts +1 -1
  8. package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +2 -7
  9. package/dist/core/DefaultDrawer.d.ts +19 -0
  10. package/dist/core/EntityEditView.d.ts +17 -3
  11. package/dist/core/NavigationRoutes.d.ts +1 -1
  12. package/dist/core/index.d.ts +2 -2
  13. package/dist/form/PropertiesForm.d.ts +8 -0
  14. package/dist/form/components/FieldHelperText.d.ts +3 -3
  15. package/dist/form/components/StorageItemPreview.d.ts +4 -4
  16. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  17. package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +2 -4
  18. package/dist/form/index.d.ts +0 -2
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.es.js +5595 -5574
  21. package/dist/index.es.js.map +1 -1
  22. package/dist/index.umd.js +5 -5
  23. package/dist/index.umd.js.map +1 -1
  24. package/dist/preview/PropertyPreviewProps.d.ts +5 -0
  25. package/dist/preview/components/StorageThumbnail.d.ts +2 -1
  26. package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
  27. package/dist/types/auth.d.ts +1 -1
  28. package/dist/types/collections.d.ts +14 -0
  29. package/dist/types/datasource.d.ts +18 -8
  30. package/dist/types/fields.d.ts +31 -30
  31. package/dist/types/plugins.d.ts +11 -3
  32. package/dist/types/properties.d.ts +7 -2
  33. package/dist/util/icons.d.ts +2 -2
  34. package/dist/util/storage.d.ts +23 -2
  35. package/dist/util/useStorageUploadController.d.ts +1 -1
  36. package/package.json +13 -22
  37. package/src/app/AppBar.tsx +18 -0
  38. package/src/app/Drawer.tsx +25 -0
  39. package/src/{core → app}/Scaffold.tsx +61 -107
  40. package/src/app/index.ts +4 -0
  41. package/src/app/useApp.tsx +32 -0
  42. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +7 -9
  43. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -1
  44. package/src/components/EntityCollectionView/EntityCollectionView.tsx +7 -4
  45. package/src/components/VirtualTable/VirtualTable.tsx +3 -1
  46. package/src/components/VirtualTable/VirtualTableProps.tsx +5 -0
  47. package/src/components/common/useTableSearchHelper.ts +52 -12
  48. package/src/components/index.tsx +1 -1
  49. package/src/contexts/DialogsProvider.tsx +2 -2
  50. package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +26 -28
  51. package/src/core/DefaultDrawer.tsx +177 -0
  52. package/src/core/EntityEditView.tsx +669 -129
  53. package/src/core/EntitySidePanel.tsx +0 -1
  54. package/src/core/NavigationRoutes.tsx +3 -3
  55. package/src/core/index.tsx +2 -2
  56. package/src/form/PropertiesForm.tsx +81 -0
  57. package/src/form/PropertyFieldBinding.tsx +29 -5
  58. package/src/form/components/FieldHelperText.tsx +3 -3
  59. package/src/form/components/StorageItemPreview.tsx +19 -10
  60. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
  61. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -4
  62. package/src/form/field_bindings/KeyValueFieldBinding.tsx +40 -35
  63. package/src/form/field_bindings/MapFieldBinding.tsx +11 -3
  64. package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +0 -7
  65. package/src/form/field_bindings/RepeatFieldBinding.tsx +10 -7
  66. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +6 -35
  67. package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -1
  68. package/src/form/index.tsx +4 -4
  69. package/src/form/validation.ts +1 -17
  70. package/src/index.ts +1 -0
  71. package/src/internal/useBuildDataSource.ts +12 -0
  72. package/src/preview/PropertyPreview.tsx +5 -2
  73. package/src/preview/PropertyPreviewProps.tsx +6 -0
  74. package/src/preview/components/ImagePreview.tsx +21 -33
  75. package/src/preview/components/ReferencePreview.tsx +2 -1
  76. package/src/preview/components/StorageThumbnail.tsx +5 -1
  77. package/src/preview/components/UrlComponentPreview.tsx +44 -11
  78. package/src/types/auth.tsx +1 -1
  79. package/src/types/collections.ts +14 -0
  80. package/src/types/customization_controller.tsx +0 -1
  81. package/src/types/datasource.ts +20 -16
  82. package/src/types/fields.tsx +33 -33
  83. package/src/types/plugins.tsx +12 -3
  84. package/src/types/properties.ts +7 -2
  85. package/src/util/entities.ts +4 -3
  86. package/src/util/objects.ts +17 -7
  87. package/src/util/permissions.ts +1 -0
  88. package/src/util/storage.ts +75 -21
  89. package/src/util/useStorageUploadController.tsx +21 -3
  90. package/dist/core/Drawer.d.ts +0 -16
  91. package/dist/core/Scaffold.d.ts +0 -51
  92. package/dist/form/EntityForm.d.ts +0 -77
  93. package/src/core/Drawer.tsx +0 -139
  94. package/src/form/EntityForm.tsx +0 -736
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Link as ReactLink } from "react-router-dom";
3
+ import { Link as ReactLink, useNavigate } from "react-router-dom";
4
4
  import { ErrorBoundary, FireCMSLogo } from "../components";
5
5
  import {
6
6
  Avatar,
@@ -16,8 +16,9 @@ import {
16
16
  } from "@firecms/ui";
17
17
  import { useAuthController, useLargeLayout, useModeController, useNavigationController } from "../hooks";
18
18
  import { User } from "../types";
19
+ import { useApp } from "../app/useApp";
19
20
 
20
- export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
21
+ export type DefaultAppBarProps<ADDITIONAL_PROPS = object> = {
21
22
 
22
23
  title?: React.ReactNode;
23
24
  /**
@@ -29,12 +30,8 @@ export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
29
30
 
30
31
  dropDownActions?: React.ReactNode;
31
32
 
32
- includeDrawer?: boolean;
33
-
34
33
  includeModeToggle?: boolean;
35
34
 
36
- drawerOpen: boolean;
37
-
38
35
  className?: string;
39
36
 
40
37
  style?: React.CSSProperties;
@@ -48,24 +45,24 @@ export type FireCMSAppBarProps<ADDITIONAL_PROPS = object> = {
48
45
  * This component renders the main app bar of FireCMS.
49
46
  * You will likely not need to use this component directly.
50
47
  *
51
- * @param title
52
- * @param toolbarExtraWidget
53
- * @param drawerOpen
54
48
  * @constructor
55
49
  */
56
- export const FireCMSAppBar = function FireCMSAppBar({
50
+ export const DefaultAppBar = function DefaultAppBar({
57
51
  title,
58
52
  endAdornment,
59
53
  startAdornment,
60
- drawerOpen,
61
54
  dropDownActions,
62
- includeDrawer,
63
55
  includeModeToggle = true,
64
56
  className,
65
57
  style,
66
- logo,
67
58
  user: userProp
68
- }: FireCMSAppBarProps) {
59
+ }: DefaultAppBarProps) {
60
+
61
+ const {
62
+ hasDrawer,
63
+ drawerOpen,
64
+ logo
65
+ } = useApp();
69
66
  const navigation = useNavigationController();
70
67
 
71
68
  const authController = useAuthController();
@@ -74,6 +71,8 @@ export const FireCMSAppBar = function FireCMSAppBar({
74
71
  toggleMode
75
72
  } = useModeController();
76
73
 
74
+ const navigate = useNavigate();
75
+
77
76
  const largeLayout = useLargeLayout();
78
77
 
79
78
  const user = userProp ?? authController.user;
@@ -96,20 +95,15 @@ export const FireCMSAppBar = function FireCMSAppBar({
96
95
  return (
97
96
  <div
98
97
  style={style}
99
- className={cls("pr-2",
98
+ className={cls("pr-2 w-full h-16 transition-all ease-in duration-75 fixed",
100
99
  {
101
- "ml-[17rem]": drawerOpen && largeLayout,
102
- "ml-16": includeDrawer && !(drawerOpen && largeLayout),
103
- "h-16": true,
100
+ "pl-[17rem]": drawerOpen && largeLayout,
101
+ "pl-20": hasDrawer && !(drawerOpen && largeLayout),
104
102
  "z-10": largeLayout,
105
- "transition-all": true,
106
- "ease-in": true,
107
- "duration-75": true,
108
- "w-full": !includeDrawer,
109
- "w-[calc(100%-64px)]": includeDrawer && !(drawerOpen && largeLayout),
110
- "w-[calc(100%-17rem)]": includeDrawer && (drawerOpen && largeLayout),
103
+ // "w-full": !hasDrawer,
104
+ // "w-[calc(100%-64px)]": hasDrawer && !(drawerOpen && largeLayout),
105
+ // "w-[calc(100%-17rem)]": hasDrawer && (drawerOpen && largeLayout),
111
106
  "duration-150": drawerOpen && largeLayout,
112
- fixed: true
113
107
  },
114
108
  className)}>
115
109
 
@@ -121,10 +115,10 @@ export const FireCMSAppBar = function FireCMSAppBar({
121
115
  to={navigation?.basePath ?? "/"}
122
116
  >
123
117
  <div className={"flex flex-row gap-4"}>
124
- {!includeDrawer && (logo
118
+ {!hasDrawer && (logo
125
119
  ? <img src={logo}
126
120
  alt="Logo"
127
- className={cls("w-[32px] h-[32px]")}/>
121
+ className={cls("w-[32px] h-[32px] object-contain")}/>
128
122
  : <FireCMSLogo width={"32px"} height={"32px"}/>)}
129
123
 
130
124
  {typeof title === "string"
@@ -169,7 +163,11 @@ export const FireCMSAppBar = function FireCMSAppBar({
169
163
 
170
164
  {dropDownActions}
171
165
 
172
- {!dropDownActions && <MenuItem onClick={authController.signOut}>
166
+ {!dropDownActions && <MenuItem onClick={async () => {
167
+ await authController.signOut();
168
+ // replace current route with home
169
+ navigate("/");
170
+ }}>
173
171
  <LogoutIcon/>
174
172
  Log Out
175
173
  </MenuItem>}
@@ -0,0 +1,177 @@
1
+ import React, { useCallback } from "react";
2
+
3
+ import { useLargeLayout, useNavigationController } from "../hooks";
4
+
5
+ import { Link, useNavigate } from "react-router-dom";
6
+ import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
7
+ import { IconForView } from "../util";
8
+ import { cls, IconButton, Menu, MenuItem, MoreVertIcon, Tooltip, Typography } from "@firecms/ui";
9
+ import { useAnalyticsController } from "../hooks/useAnalyticsController";
10
+ import { DrawerNavigationItem } from "./DrawerNavigationItem";
11
+ import { FireCMSLogo } from "../components";
12
+ import { useApp } from "../app/useApp";
13
+
14
+ /**
15
+ * Default drawer used in the CMS
16
+ * @group Core
17
+ */
18
+ export function DefaultDrawer({
19
+ className,
20
+ style,
21
+ }: {
22
+ className?: string
23
+ style?: React.CSSProperties,
24
+ }) {
25
+
26
+ const {
27
+ drawerHovered,
28
+ drawerOpen,
29
+ closeDrawer,
30
+ logo
31
+ } = useApp();
32
+
33
+ const analyticsController = useAnalyticsController();
34
+ const navigation = useNavigationController();
35
+
36
+ const tooltipsOpen = drawerHovered && !drawerOpen;
37
+ const largeLayout = useLargeLayout();
38
+ const navigate = useNavigate();
39
+
40
+ const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
41
+
42
+ if (!navigation.topLevelNavigation)
43
+ throw Error("Navigation not ready in Drawer");
44
+
45
+ const {
46
+ navigationEntries,
47
+ groups
48
+ }: TopNavigationResult = navigation.topLevelNavigation;
49
+
50
+ const adminViews = navigationEntries.filter(e => e.type === "admin") ?? [];
51
+ const groupsWithoutAdmin = groups.filter(g => g !== "Admin");
52
+
53
+ const buildGroupHeader = useCallback((group?: string) => {
54
+ if (!drawerOpen) return <div className="h-12 w-full"/>;
55
+ return <div
56
+ className="pt-8 pl-6 pr-8 pb-2 flex flex-row items-center">
57
+ <Typography variant={"caption"}
58
+ color={"secondary"}
59
+ className="font-medium flex-grow line-clamp-1">
60
+ {group ? group.toUpperCase() : "Views".toUpperCase()}
61
+ </Typography>
62
+
63
+ </div>;
64
+ }, [drawerOpen]);
65
+
66
+ const onClick = (view: TopNavigationEntry) => {
67
+ const eventName: CMSAnalyticsEvent = view.type === "collection"
68
+ ? "drawer_navigate_to_collection"
69
+ : (view.type === "view" ? "drawer_navigate_to_view" : "unmapped_event");
70
+ analyticsController.onAnalyticsEvent?.(eventName, { url: view.url });
71
+ if (!largeLayout)
72
+ closeDrawer();
73
+ };
74
+
75
+ return (
76
+ <>
77
+ <div className={cls("flex flex-col h-full relative flex-grow w-full", className)} style={style}>
78
+
79
+ <DrawerLogo logo={logo}/>
80
+
81
+ <div className={"overflow-scroll no-scrollbar"}>
82
+
83
+ {groupsWithoutAdmin.map((group) => (
84
+ <React.Fragment
85
+ key={`drawer_group_${group}`}>
86
+ {buildGroupHeader(group)}
87
+ {Object.values(navigationEntries)
88
+ .filter(e => e.group === group)
89
+ .map((view, index) =>
90
+ <DrawerNavigationItem
91
+ key={`navigation_${index}`}
92
+ icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
93
+ tooltipsOpen={tooltipsOpen}
94
+ drawerOpen={drawerOpen}
95
+ onClick={() => onClick(view)}
96
+ url={view.url}
97
+ name={view.name}/>)}
98
+ </React.Fragment>
99
+ ))}
100
+
101
+ </div>
102
+
103
+ {adminViews.length > 0 && <Menu
104
+ open={adminMenuOpen}
105
+ onOpenChange={setAdminMenuOpen}
106
+ trigger={
107
+ <IconButton
108
+ shape={"square"}
109
+ className={"m-4 text-gray-900 dark:text-white w-fit"}>
110
+ <Tooltip title={"Admin"}
111
+ open={tooltipsOpen}
112
+ side={"right"} sideOffset={28}>
113
+ <MoreVertIcon/>
114
+ </Tooltip>
115
+ {drawerOpen && <div
116
+ className={cls(
117
+ drawerOpen ? "opacity-100" : "opacity-0 hidden",
118
+ "mx-4 font-inherit text-inherit"
119
+ )}>
120
+ ADMIN
121
+ </div>}
122
+ </IconButton>}
123
+ >
124
+ {adminViews.map((entry, index) =>
125
+ <MenuItem
126
+ onClick={(event) => {
127
+ event.preventDefault();
128
+ navigate(entry.path);
129
+ }}
130
+ key={`navigation_${index}`}>
131
+ {<IconForView collectionOrView={entry.view}/>}
132
+ {entry.name}
133
+ </MenuItem>)}
134
+
135
+ </Menu>}
136
+ </div>
137
+
138
+ </>
139
+ );
140
+ }
141
+
142
+ /**
143
+ * This is the logo displayed in the drawer
144
+ * It expands when the drawer is open.
145
+ *
146
+ * @param logo
147
+ * @constructor
148
+ */
149
+ export function DrawerLogo({ logo }: {
150
+ logo?: string;
151
+ }) {
152
+
153
+ const navigation = useNavigationController();
154
+ const { drawerOpen } = useApp();
155
+ return <div
156
+ style={{
157
+ transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
158
+ padding: drawerOpen ? "32px 144px 0px 24px" : "72px 16px 0px"
159
+ }}
160
+ className={cls("cursor-pointer")}>
161
+
162
+ <Tooltip title={"Home"}
163
+ sideOffset={20}
164
+ side="right">
165
+ <Link
166
+ to={navigation.basePath}>
167
+ {logo
168
+ ? <img src={logo}
169
+ alt="Logo"
170
+ className={cls("max-w-full max-h-full",
171
+ drawerOpen ?? "w-[112px] h-[112px]")}/>
172
+ : <FireCMSLogo/>}
173
+
174
+ </Link>
175
+ </Tooltip>
176
+ </div>;
177
+ }