Add navigator button

This commit is contained in:
dominik-zeglen 2020-08-08 14:59:09 +02:00
parent 1eb3ec7b2d
commit 3816ebb0a5
3 changed files with 175 additions and 160 deletions

View file

@ -28,6 +28,7 @@ import useRouter from "use-react-router";
import Container from "../Container";
import ErrorPage from "../ErrorPage";
import Navigator from "../Navigator";
import AppActionContext from "./AppActionContext";
import AppHeaderContext from "./AppHeaderContext";
import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts";
@ -310,6 +311,7 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
const intl = useIntl();
const [appState, dispatchAppState] = useAppState();
const { location } = useRouter();
const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false);
const menuStructure = createMenuStructure(intl);
const configurationMenu = createConfigurationMenu(intl);
@ -356,170 +358,181 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
};
return (
<AppHeaderContext.Provider value={appHeaderAnchor}>
<AppActionContext.Provider value={appActionAnchor}>
<div className={classes.root}>
<div className={classes.sideBar}>
<ResponsiveDrawer
onClose={() => setDrawerState(false)}
open={isDrawerOpened}
small={!isMenuSmall}
>
<div
className={classNames(classes.logo, {
[classes.logoSmall]: isMenuSmall,
[classes.logoDark]: isDark
})}
<>
<Navigator
visible={isNavigatorVisible}
setVisibility={setNavigatorVisibility}
/>
<AppHeaderContext.Provider value={appHeaderAnchor}>
<AppActionContext.Provider value={appActionAnchor}>
<div className={classes.root}>
<div className={classes.sideBar}>
<ResponsiveDrawer
onClose={() => setDrawerState(false)}
open={isDrawerOpened}
small={!isMenuSmall}
>
<SVG src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo} />
</div>
<Hidden smDown>
<div
className={classNames(classes.isMenuSmall, {
[classes.isMenuSmallHide]: isMenuSmall,
[classes.isMenuSmallDark]: isDark
className={classNames(classes.logo, {
[classes.logoSmall]: isMenuSmall,
[classes.logoDark]: isDark
})}
onClick={handleIsMenuSmall}
>
<SVG src={menuArrowIcon} />
<SVG
src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo}
/>
</div>
</Hidden>
<MenuList
className={isMenuSmall ? classes.menuSmall : classes.menu}
menuItems={menuStructure}
isMenuSmall={!isMenuSmall}
location={location.pathname}
user={user}
renderConfigure={renderConfigure}
onMenuItemClick={handleMenuItemClick}
/>
</ResponsiveDrawer>
</div>
<div
className={classNames(classes.content, {
[classes.contentToggle]: isMenuSmall
})}
>
{appState.loading ? (
<LinearProgress className={classes.appLoader} color="primary" />
) : (
<div className={classes.appLoaderPlaceholder} />
)}
<div className={classes.viewContainer}>
<div>
<Container>
<div className={classes.header}>
<div
className={classNames(classes.menuIcon, {
[classes.menuIconOpen]: isDrawerOpened,
[classes.menuIconDark]: isDark
})}
onClick={() => setDrawerState(!isDrawerOpened)}
>
<span />
<span />
<span />
<span />
</div>
<div ref={appHeaderAnchor} />
<div className={classes.spacer} />
<div className={classes.userBar}>
<ThemeSwitch
className={classes.darkThemeSwitch}
checked={isDark}
onClick={toggleTheme}
/>
<div className={classes.userMenuContainer} ref={anchor}>
<Chip
avatar={
user.avatar && (
<Avatar alt="user" src={user.avatar.url} />
)
}
classes={{
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
{user.email}
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
<Hidden smDown>
<div
className={classNames(classes.isMenuSmall, {
[classes.isMenuSmallHide]: isMenuSmall,
[classes.isMenuSmallDark]: isDark
})}
onClick={handleIsMenuSmall}
>
<SVG src={menuArrowIcon} />
</div>
</Hidden>
<MenuList
className={isMenuSmall ? classes.menuSmall : classes.menu}
menuItems={menuStructure}
isMenuSmall={!isMenuSmall}
location={location.pathname}
user={user}
renderConfigure={renderConfigure}
onMenuItemClick={handleMenuItemClick}
/>
</ResponsiveDrawer>
</div>
<div
className={classNames(classes.content, {
[classes.contentToggle]: isMenuSmall
})}
>
{appState.loading ? (
<LinearProgress className={classes.appLoader} color="primary" />
) : (
<div className={classes.appLoaderPlaceholder} />
)}
<div className={classes.viewContainer}>
<div>
<Container>
<div className={classes.header}>
<div
className={classNames(classes.menuIcon, {
[classes.menuIconOpen]: isDrawerOpened,
[classes.menuIconDark]: isDark
})}
onClick={() => setDrawerState(!isDrawerOpened)}
>
<span />
<span />
<span />
<span />
</div>
<div ref={appHeaderAnchor} />
<div className={classes.spacer} />
<div className={classes.userBar}>
<ThemeSwitch
className={classes.darkThemeSwitch}
checked={isDark}
onClick={toggleTheme}
/>
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom"
? "right top"
: "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
<button onClick={() => setNavigatorVisibility(true)}>
naviigator
</button>
<div className={classes.userMenuContainer} ref={anchor}>
<Chip
avatar={
user.avatar && (
<Avatar alt="user" src={user.avatar.url} />
)
}
classes={{
avatar: classes.avatar
}}
className={classes.userChip}
label={
<>
{user.email}
<ArrowDropdown
className={classNames(classes.arrow, {
[classes.rotate]: isMenuOpened
})}
/>
</>
}
onClick={() => setMenuState(!isMenuOpened)}
data-test="userMenu"
/>
<Popper
className={classes.popover}
open={isMenuOpened}
anchorEl={anchor.current}
transition
placement="bottom-end"
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin:
placement === "bottom"
? "right top"
: "right bottom"
}}
>
<Paper>
<ClickAwayListener
onClickAway={() => setMenuState(false)}
mouseEvent="onClick"
>
<Menu>
<MenuItem
className={classes.userMenuItem}
onClick={handleViewerProfile}
data-test="accountSettingsButton"
>
<FormattedMessage
defaultMessage="Account Settings"
description="button"
/>
</MenuItem>
<MenuItem
className={classes.userMenuItem}
onClick={handleLogout}
data-test="logOutButton"
>
<FormattedMessage
defaultMessage="Log out"
description="button"
/>
</MenuItem>
</Menu>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</div>
</div>
</div>
</div>
</Container>
</Container>
</div>
<main className={classes.view}>
{appState.error
? appState.error === "unhandled" && (
<ErrorPage onBack={handleErrorBack} />
)
: children}
</main>
</div>
<main className={classes.view}>
{appState.error
? appState.error === "unhandled" && (
<ErrorPage onBack={handleErrorBack} />
)
: children}
</main>
<div className={classes.appAction} ref={appActionAnchor} />
</div>
<div className={classes.appAction} ref={appActionAnchor} />
</div>
</div>
</AppActionContext.Provider>
</AppHeaderContext.Provider>
</AppActionContext.Provider>
</AppHeaderContext.Provider>
</>
);
};

View file

@ -60,8 +60,12 @@ const useStyles = makeStyles(
}
);
const Navigator: React.FC = () => {
const [visible, setVisible] = React.useState(false);
export interface NavigatorProps {
visible: boolean;
setVisibility: (state: boolean) => void;
}
const Navigator: React.FC<NavigatorProps> = ({ visible, setVisibility }) => {
const input = React.useRef(null);
const [query, mode, change, actions] = useQuickSearch(visible, input);
const intl = useIntl();
@ -76,7 +80,7 @@ const Navigator: React.FC = () => {
React.useEffect(() => {
hotkeys(navigatorHotkey, event => {
event.preventDefault();
setVisible(!visible);
setVisibility(!visible);
});
if (cmp(APP_VERSION, "2.1.0") !== 1 && !notifiedAboutNavigator) {
@ -110,7 +114,7 @@ const Navigator: React.FC = () => {
<Modal
className={classes.modal}
open={visible}
onClose={() => setVisible(false)}
onClose={() => setVisibility(false)}
>
<Fade appear in={visible} timeout={theme.transitions.duration.short}>
<div className={classes.root}>
@ -122,7 +126,7 @@ const Navigator: React.FC = () => {
onSelect={(item: QuickSearchAction) => {
const shouldRemainVisible = item.onClick();
if (!shouldRemainVisible) {
setVisible(false);
setVisibility(false);
}
}}
onInputValueChange={value =>

View file

@ -1,4 +1,3 @@
import Navigator from "@saleor/components/Navigator";
import useAppState from "@saleor/hooks/useAppState";
import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
import { ApolloClient } from "apollo-client";
@ -139,7 +138,6 @@ const Routes: React.FC = () => {
<WindowTitle title={intl.formatMessage(commonMessages.dashboard)} />
{isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading ? (
<AppLayout>
<Navigator />
<ErrorBoundary
onError={() =>
dispatchAppState({