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

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.61",
4
+ "version": "3.0.0-canary.63",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/firecmsco"
@@ -46,8 +46,8 @@
46
46
  "./package.json": "./package.json"
47
47
  },
48
48
  "dependencies": {
49
- "@firecms/formex": "^3.0.0-canary.61",
50
- "@firecms/ui": "^3.0.0-canary.61",
49
+ "@firecms/formex": "^3.0.0-canary.63",
50
+ "@firecms/ui": "^3.0.0-canary.63",
51
51
  "@fontsource/jetbrains-mono": "^5.0.20",
52
52
  "@hello-pangea/dnd": "^16.6.0",
53
53
  "@radix-ui/react-portal": "^1.0.4",
@@ -111,7 +111,7 @@
111
111
  "dist",
112
112
  "src"
113
113
  ],
114
- "gitHead": "bd4ff11fc59df78b8967e20c2229afab86e35d81",
114
+ "gitHead": "ebf432414a10a3e316be86d4b6ad4aa7be2786ad",
115
115
  "publishConfig": {
116
116
  "access": "public"
117
117
  },
@@ -0,0 +1,18 @@
1
+ import { DefaultAppBar, DefaultAppBarProps } from "../core/DefaultAppBar";
2
+
3
+ /**
4
+ * This component renders the main app bar of FireCMS.
5
+ */
6
+ export function AppBar({
7
+ children,
8
+ ...props
9
+ }: {
10
+ children?: React.ReactNode,
11
+ className?: string,
12
+ style?: React.CSSProperties
13
+ } & DefaultAppBarProps) {
14
+ const usedChildren = children ?? <DefaultAppBar {...props}/>;
15
+ return <>{usedChildren}</>;
16
+ }
17
+
18
+ AppBar.componentType = "AppBar";
@@ -0,0 +1,25 @@
1
+ import { DefaultDrawer } from "../core";
2
+
3
+ /**
4
+ * This component is in charge of rendering the drawer.
5
+ * If you add this component under your {@link Scaffold}, it will be rendered
6
+ * as a drawer, and the open and close functionality will be handled automatically.
7
+ * If you want to customise the drawer, you can create your own component and pass it as a child.
8
+ * For custom drawers, you can use the {@link useApp} to open and close the drawer.
9
+ *
10
+ * @constructor
11
+ */
12
+ export function Drawer({
13
+ children,
14
+ className,
15
+ style
16
+ }: {
17
+ children?: React.ReactNode,
18
+ className?: string,
19
+ style?: React.CSSProperties
20
+ }) {
21
+ const usedChildren = children ?? <DefaultDrawer className={className} style={style}/>;
22
+ return <>{usedChildren}</>;
23
+ }
24
+
25
+ Drawer.componentType = "Drawer";
@@ -1,55 +1,16 @@
1
1
  import React, { PropsWithChildren, useCallback } from "react";
2
- import equal from "react-fast-compare"
3
- import { Link } from "react-router-dom";
4
-
5
- import { Drawer as DefaultDrawer, DrawerProps } from "./Drawer";
6
- import { useLargeLayout, useNavigationController } from "../hooks";
7
- import { ErrorBoundary, FireCMSAppBar as DefaultFireCMSAppBar, FireCMSAppBarProps, FireCMSLogo } from "../components";
8
2
  import { ChevronLeftIcon, cls, defaultBorderMixin, IconButton, MenuIcon, Sheet, Tooltip } from "@firecms/ui";
3
+ import equal from "react-fast-compare"
4
+ import { useLargeLayout } from "../hooks";
5
+ import { ErrorBoundary } from "../components";
6
+ import { AppContext } from "./useApp";
9
7
 
10
8
  export const DRAWER_WIDTH = 280;
11
9
 
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
-
28
10
  /**
29
11
  * @group Core
30
12
  */
31
- export interface ScaffoldProps<ExtraAppbarProps = object> {
32
-
33
- /**
34
- * Name of the app, displayed as the main title and in the tab title
35
- */
36
- name?: React.ReactNode;
37
-
38
- /**
39
- * Logo to be displayed in the drawer of the CMS
40
- */
41
- logo?: string;
42
-
43
- /**
44
- * Whether to include the drawer in the scaffold
45
- */
46
- includeDrawer?: boolean;
47
-
48
- /**
49
- * You can define a custom drawer to be displayed in the scaffold.
50
- * Use the hook `useDrawer` to access the context values.
51
- */
52
- drawer?: React.ReactNode;
13
+ export interface ScaffoldProps {
53
14
 
54
15
  /**
55
16
  * Open the drawer on hover
@@ -57,15 +18,14 @@ export interface ScaffoldProps<ExtraAppbarProps = object> {
57
18
  autoOpenDrawer?: boolean;
58
19
 
59
20
  /**
60
- * The AppBar component to be used in the scaffold.
21
+ * Logo to be displayed in the top bar and drawer.
22
+ * Note that this has no effect if you are using a custom AppBar or Drawer.
61
23
  */
62
- FireCMSAppBar?: React.ComponentType<FireCMSAppBarProps<ExtraAppbarProps>>;
24
+ logo?: string;
63
25
 
64
- /**
65
- * Additional props passed to the custom AppBar
66
- */
67
- fireCMSAppBarProps?: Partial<FireCMSAppBarProps> & ExtraAppbarProps;
26
+ className?: string;
68
27
 
28
+ style?: React.CSSProperties;
69
29
  }
70
30
 
71
31
  /**
@@ -84,15 +44,23 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
84
44
 
85
45
  const {
86
46
  children,
87
- name,
88
- logo,
89
- includeDrawer = true,
90
47
  autoOpenDrawer,
91
- drawer = <DefaultDrawer/>,
92
- FireCMSAppBar = DefaultFireCMSAppBar,
93
- fireCMSAppBarProps,
48
+ logo,
49
+ className,
50
+ style
94
51
  } = props;
95
52
 
53
+ const drawerChildren = React.Children.toArray(children).filter((child: any) => child.type.componentType === "Drawer");
54
+ if (drawerChildren.length > 1) {
55
+ throw Error("Only one Drawer component is allowed in Scaffold");
56
+ }
57
+ const appBarChildren = React.Children.toArray(children).filter((child: any) => child.type.componentType === "AppBar");
58
+ if (appBarChildren.length > 1) {
59
+ throw Error("Only one AppBar component is allowed in Scaffold");
60
+ }
61
+ const otherChildren = React.Children.toArray(children)
62
+ .filter((child: any) => child.type.componentType !== "Drawer" && child.type.componentType !== "AppBar");
63
+ const includeDrawer = drawerChildren.length > 0;
96
64
  const largeLayout = useLargeLayout();
97
65
 
98
66
  const [drawerOpen, setDrawerOpen] = React.useState(false);
@@ -112,38 +80,37 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
112
80
  const computedDrawerOpen: boolean = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);
113
81
 
114
82
  return (
115
- <DrawerContext.Provider value={{
116
- hovered: onHover,
83
+ <AppContext.Provider value={{
84
+ logo,
85
+ hasDrawer: includeDrawer,
86
+ drawerHovered: onHover,
117
87
  drawerOpen: computedDrawerOpen,
118
88
  closeDrawer: handleDrawerClose,
119
89
  openDrawer: handleDrawerOpen,
120
90
  autoOpenDrawer
121
91
  }}>
122
92
  <div
123
- className="flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden"
93
+ className={cls("flex h-screen w-screen bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white overflow-hidden", className)}
124
94
  style={{
125
95
  paddingTop: "env(safe-area-inset-top)",
126
96
  paddingLeft: "env(safe-area-inset-left)",
127
97
  paddingRight: "env(safe-area-inset-right)",
128
98
  paddingBottom: "env(safe-area-inset-bottom)",
129
- height: "100dvh"
99
+ height: "100dvh",
100
+ ...style
130
101
  }}>
131
102
 
132
- <FireCMSAppBar title={name}
133
- includeDrawer={includeDrawer}
134
- logo={logo}
135
- drawerOpen={computedDrawerOpen}
136
- {...fireCMSAppBarProps}/>
103
+ {appBarChildren}
104
+
137
105
  <DrawerWrapper
138
106
  displayed={includeDrawer}
139
107
  onMouseEnter={setOnHoverTrue}
140
108
  onMouseMove={setOnHoverTrue}
141
109
  onMouseLeave={setOnHoverFalse}
142
110
  open={computedDrawerOpen}
143
- logo={logo}
144
111
  hovered={onHover}
145
112
  setDrawerOpen={setDrawerOpen}>
146
- {includeDrawer && drawer}
113
+ {includeDrawer && drawerChildren}
147
114
  </DrawerWrapper>
148
115
 
149
116
  <main
@@ -153,13 +120,13 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
153
120
  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
121
 
155
122
  <ErrorBoundary>
156
- {children}
123
+ {otherChildren}
157
124
  </ErrorBoundary>
158
125
 
159
126
  </div>
160
127
  </main>
161
128
  </div>
162
- </DrawerContext.Provider>
129
+ </AppContext.Provider>
163
130
  );
164
131
  },
165
132
  equal
@@ -183,8 +150,6 @@ function DrawerWrapper(props: {
183
150
  onMouseLeave: () => void
184
151
  }) {
185
152
 
186
- const navigation = useNavigationController();
187
-
188
153
  const width = !props.displayed ? 0 : (props.open ? DRAWER_WIDTH : 72);
189
154
  const innerDrawer = <div
190
155
  className={"relative h-full no-scrollbar overflow-y-auto overflow-x-hidden"}
@@ -198,7 +163,7 @@ function DrawerWrapper(props: {
198
163
  <Tooltip title="Open menu"
199
164
  side="right"
200
165
  sideOffset={12}
201
- className="fixed top-2 left-3 !bg-gray-50 dark:!bg-gray-900 rounded-full w-fit"
166
+ className="fixed top-2 left-3 !bg-gray-50 dark:!bg-gray-900 rounded-full w-fit z-20"
202
167
  >
203
168
  <IconButton
204
169
  color="inherit"
@@ -212,30 +177,19 @@ function DrawerWrapper(props: {
212
177
  </Tooltip>
213
178
  )}
214
179
 
215
- <div className={"flex flex-col h-full"}>
216
- <div
217
- style={{
218
- transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
219
- padding: props.open ? "32px 144px 0px 24px" : "72px 16px 0px"
220
- }}
221
- className={cls("cursor-pointer")}>
222
-
223
- <Tooltip title={"Home"}
224
- sideOffset={20}
225
- side="right">
226
- <Link
227
- to={navigation.basePath}>
228
- {props.logo
229
- ? <img src={props.logo}
230
- alt="Logo"
231
- className={cls("max-w-full max-h-full",
232
- props.open ?? "w-[112px] h-[112px]")}/>
233
- : <FireCMSLogo/>}
234
-
235
- </Link>
236
- </Tooltip>
237
- </div>
180
+ <div
181
+ className={`z-20 absolute right-0 top-4 ${
182
+ props.open ? "opacity-100" : "opacity-0 invisible"
183
+ } transition-opacity duration-200 ease-in-out`}>
184
+ <IconButton
185
+ aria-label="Close drawer"
186
+ onClick={() => props.setDrawerOpen(false)}
187
+ >
188
+ <ChevronLeftIcon/>
189
+ </IconButton>
190
+ </div>
238
191
 
192
+ <div className={"flex flex-col h-full"}>
239
193
  {props.children}
240
194
  </div>
241
195
 
@@ -267,7 +221,7 @@ function DrawerWrapper(props: {
267
221
 
268
222
  return (
269
223
  <div
270
- className="relative"
224
+ className="z-20 relative"
271
225
  onMouseEnter={props.onMouseEnter}
272
226
  onMouseMove={props.onMouseMove}
273
227
  onMouseLeave={props.onMouseLeave}
@@ -278,17 +232,17 @@ function DrawerWrapper(props: {
278
232
 
279
233
  {innerDrawer}
280
234
 
281
- <div
282
- className={`absolute right-0 top-4 ${
283
- props.open ? "opacity-100" : "opacity-0 invisible"
284
- } transition-opacity duration-1000 ease-in-out`}>
285
- <IconButton
286
- aria-label="Close drawer"
287
- onClick={() => props.setDrawerOpen(false)}
288
- >
289
- <ChevronLeftIcon/>
290
- </IconButton>
291
- </div>
235
+ {/*<div*/}
236
+ {/* className={`z-20 absolute right-0 top-4 ${*/}
237
+ {/* props.open ? "opacity-100" : "opacity-0 invisible"*/}
238
+ {/* } transition-opacity duration-1000 ease-in-out`}>*/}
239
+ {/* <IconButton*/}
240
+ {/* aria-label="Close drawer"*/}
241
+ {/* onClick={() => props.setDrawerOpen(false)}*/}
242
+ {/* >*/}
243
+ {/* <ChevronLeftIcon/>*/}
244
+ {/* </IconButton>*/}
245
+ {/*</div>*/}
292
246
 
293
247
  </div>
294
248
  );
@@ -0,0 +1,4 @@
1
+ export * from "./Drawer";
2
+ export * from "./AppBar";
3
+ export * from "./Scaffold";
4
+ export * from "./useApp";
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+
3
+ /**
4
+ * This context represents the state of the app in terms of layout.
5
+ * @group Core
6
+ */
7
+ export type AppState = {
8
+ hasDrawer: boolean,
9
+ drawerHovered: boolean,
10
+ drawerOpen: boolean,
11
+ openDrawer: () => void,
12
+ closeDrawer: () => void,
13
+ autoOpenDrawer?: boolean,
14
+ logo?: string
15
+ }
16
+
17
+ export const AppContext = React.createContext<AppState>({
18
+ hasDrawer: false,
19
+ drawerHovered: false,
20
+ drawerOpen: false,
21
+ openDrawer: () => {
22
+ throw new Error("openDrawer not implemented");
23
+ },
24
+ closeDrawer: () => {
25
+ throw new Error("closeDrawer not implemented");
26
+ },
27
+ autoOpenDrawer: false
28
+ });
29
+
30
+ export function useApp() {
31
+ return React.useContext(AppContext);
32
+ }
@@ -29,7 +29,7 @@ export * from "./DeleteConfirmationDialog";
29
29
 
30
30
  export * from "./FireCMSLogo";
31
31
 
32
- export * from "./FireCMSAppBar";
32
+ export * from "../core/DefaultAppBar";
33
33
 
34
34
  export * from "./ArrayContainer";
35
35
  export * from "./ReferenceWidget";
@@ -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();
@@ -96,20 +93,15 @@ export const FireCMSAppBar = function FireCMSAppBar({
96
93
  return (
97
94
  <div
98
95
  style={style}
99
- className={cls("pr-2",
96
+ className={cls("pr-2 w-full h-16 transition-all ease-in duration-75 fixed",
100
97
  {
101
- "ml-[17rem]": drawerOpen && largeLayout,
102
- "ml-16": includeDrawer && !(drawerOpen && largeLayout),
103
- "h-16": true,
98
+ "pl-[17rem]": drawerOpen && largeLayout,
99
+ "pl-20": hasDrawer && !(drawerOpen && largeLayout),
104
100
  "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),
101
+ // "w-full": !hasDrawer,
102
+ // "w-[calc(100%-64px)]": hasDrawer && !(drawerOpen && largeLayout),
103
+ // "w-[calc(100%-17rem)]": hasDrawer && (drawerOpen && largeLayout),
111
104
  "duration-150": drawerOpen && largeLayout,
112
- fixed: true
113
105
  },
114
106
  className)}>
115
107
 
@@ -121,7 +113,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
121
113
  to={navigation?.basePath ?? "/"}
122
114
  >
123
115
  <div className={"flex flex-row gap-4"}>
124
- {!includeDrawer && (logo
116
+ {!hasDrawer && (logo
125
117
  ? <img src={logo}
126
118
  alt="Logo"
127
119
  className={cls("w-[32px] h-[32px]")}/>
@@ -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
+ }