From 42931a1d31cdfaa7e7ded5e504a2cc25315b7d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20G=C4=99bala?= Date: Fri, 25 Sep 2020 16:38:59 +0200 Subject: [PATCH 1/4] Revert "Merge pull request #703 from mirumee/ref/sidebar-mobile" This reverts commit acfd04e81af1d4f21de3331c26acfd935aa34870, reversing changes made to 40d27a92805db9cd2b4e7029571e670b1196d892. --- locale/defaultMessages.json | 16 +- src/components/AppHeader/AppHeader.tsx | 7 +- src/components/AppLayout/AppLayout.tsx | 216 +++++++++++++----- src/components/Navigator/Navigator.tsx | 3 - .../NavigatorButton/NavigatorButton.tsx | 4 - src/components/SideBar/ExpandButton.tsx | 24 +- src/components/SideBar/SideBar.tsx | 19 +- src/components/SideBarDrawer/MenuItemBtn.tsx | 32 --- .../SideBarDrawer/SideBarDrawer.stories.tsx | 37 --- .../SideBarDrawer/SideBarDrawer.tsx | 132 ----------- src/components/SideBarDrawer/index.ts | 0 src/components/SideBarDrawer/styles.ts | 68 ------ .../SquareButton/SquareButton.stories.tsx | 14 -- src/components/SquareButton/SquareButton.tsx | 34 --- src/components/SquareButton/index.ts | 2 - src/components/UserChip/UserChip.tsx | 183 --------------- src/components/UserChip/index.ts | 2 - .../__snapshots__/Stories.test.ts.snap | 48 ---- 18 files changed, 204 insertions(+), 637 deletions(-) delete mode 100644 src/components/SideBarDrawer/MenuItemBtn.tsx delete mode 100644 src/components/SideBarDrawer/SideBarDrawer.stories.tsx delete mode 100644 src/components/SideBarDrawer/SideBarDrawer.tsx delete mode 100644 src/components/SideBarDrawer/index.ts delete mode 100644 src/components/SideBarDrawer/styles.ts delete mode 100644 src/components/SquareButton/SquareButton.stories.tsx delete mode 100644 src/components/SquareButton/SquareButton.tsx delete mode 100644 src/components/SquareButton/index.ts delete mode 100644 src/components/UserChip/UserChip.tsx delete mode 100644 src/components/UserChip/index.ts diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 6a8bf9090..4822081e1 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -1373,6 +1373,14 @@ "src_dot_components_dot_AddressEdit_dot_944851093": { "string": "Country area" }, + "src_dot_components_dot_AppLayout_dot_21332146": { + "context": "button", + "string": "Log out" + }, + "src_dot_components_dot_AppLayout_dot_248888005": { + "context": "button", + "string": "Account Settings" + }, "src_dot_components_dot_AppStatus_dot_1624959454": { "string": "If you want to disable this App please uncheck the box below." }, @@ -1856,14 +1864,6 @@ "src_dot_components_dot_Timeline_dot_3028189627": { "string": "Leave your note here..." }, - "src_dot_components_dot_UserChip_dot_21332146": { - "context": "button", - "string": "Log out" - }, - "src_dot_components_dot_UserChip_dot_248888005": { - "context": "button", - "string": "Account Settings" - }, "src_dot_components_dot_VisibilityCard_dot_1311467573": { "string": "Show in product listings" }, diff --git a/src/components/AppHeader/AppHeader.tsx b/src/components/AppHeader/AppHeader.tsx index d38731269..f4bdc4ab4 100644 --- a/src/components/AppHeader/AppHeader.tsx +++ b/src/components/AppHeader/AppHeader.tsx @@ -34,7 +34,7 @@ const useStyles = makeStyles( marginTop: theme.spacing(0.5), transition: theme.transitions.duration.standard + "ms", [theme.breakpoints.down("sm")]: { - margin: theme.spacing(4, 0, 0, 0) + display: "none" } }, skeleton: { @@ -45,7 +45,10 @@ const useStyles = makeStyles( color: "inherit", flex: 1, marginLeft: theme.spacing(), - textTransform: "uppercase" + textTransform: "uppercase", + [theme.breakpoints.down("sm")]: { + display: "none" + } } }), { name: "AppHeader" } diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 9c1fc3f35..23d64337a 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -1,14 +1,23 @@ +import Avatar from "@material-ui/core/Avatar"; +import Chip from "@material-ui/core/Chip"; +import ClickAwayListener from "@material-ui/core/ClickAwayListener"; +import Grow from "@material-ui/core/Grow"; import LinearProgress from "@material-ui/core/LinearProgress"; -import { makeStyles, Theme } from "@material-ui/core/styles"; -import useMediaQuery from "@material-ui/core/useMediaQuery"; +import MenuItem from "@material-ui/core/MenuItem"; +import Menu from "@material-ui/core/MenuList"; +import Paper from "@material-ui/core/Paper"; +import Popper from "@material-ui/core/Popper"; +import { makeStyles } from "@material-ui/core/styles"; import { createConfigurationMenu } from "@saleor/configuration"; import useAppState from "@saleor/hooks/useAppState"; import useNavigator from "@saleor/hooks/useNavigator"; import useTheme from "@saleor/hooks/useTheme"; import useUser from "@saleor/hooks/useUser"; +import ArrowDropdown from "@saleor/icons/ArrowDropdown"; import { staffMemberDetailsUrl } from "@saleor/staff/urls"; +import classNames from "classnames"; import React from "react"; -import { useIntl } from "react-intl"; +import { FormattedMessage, useIntl } from "react-intl"; import useRouter from "use-react-router"; import Container from "../Container"; @@ -16,8 +25,6 @@ import ErrorPage from "../ErrorPage"; import Navigator from "../Navigator"; import NavigatorButton from "../NavigatorButton/NavigatorButton"; import SideBar from "../SideBar"; -import SideBarDrawer from "../SideBarDrawer/SideBarDrawer"; -import UserChip from "../UserChip"; import AppActionContext from "./AppActionContext"; import AppHeaderContext from "./AppHeaderContext"; import { appLoaderHeight } from "./consts"; @@ -45,13 +52,22 @@ const useStyles = makeStyles( height: appLoaderHeight, marginBottom: theme.spacing(4) }, - + arrow: { + marginLeft: theme.spacing(2), + transition: theme.transitions.duration.standard + "ms" + }, + avatar: { + "&&": { + height: 32, + width: 32 + } + }, content: { flex: 1 }, darkThemeSwitch: { [theme.breakpoints.down("sm")]: { - marginRight: theme.spacing(1) + marginRight: -theme.spacing(1.5) }, marginRight: theme.spacing(2) }, @@ -59,8 +75,8 @@ const useStyles = makeStyles( display: "grid", gridTemplateAreas: `"headerAnchor headerToolbar"`, [theme.breakpoints.down("sm")]: { - gridTemplateAreas: `"headerToolbar" - "headerAnchor"` + height: 88, + marginBottom: 0 }, marginBottom: theme.spacing(3) }, @@ -75,20 +91,54 @@ const useStyles = makeStyles( height: "auto" } }, + menu: { + background: theme.palette.background.paper, + height: "100vh", + padding: "25px 20px" + }, + menuSmall: { + background: theme.palette.background.paper, + height: "100vh", + overflow: "hidden", + padding: 25 + }, + popover: { + zIndex: 1 + }, root: { [theme.breakpoints.up("md")]: { display: "flex" }, width: `100%` }, + rotate: { + transform: "rotate(180deg)" + }, spacer: { flex: 1 }, userBar: { + [theme.breakpoints.down("sm")]: { + alignItems: "flex-end", + flexDirection: "column-reverse", + overflow: "hidden" + }, alignItems: "center", display: "flex" }, - + userChip: { + backgroundColor: theme.palette.background.paper, + borderRadius: 24, + color: theme.palette.text.primary, + height: 40, + padding: theme.spacing(0.5) + }, + userMenuContainer: { + position: "relative" + }, + userMenuItem: { + textAlign: "right" + }, view: { flex: 1, flexGrow: 1, @@ -114,15 +164,16 @@ interface AppLayoutProps { const AppLayout: React.FC = ({ children }) => { const classes = useStyles({}); const { isDark, toggleTheme } = useTheme(); + const [isMenuOpened, setMenuState] = React.useState(false); const appActionAnchor = React.useRef(); const appHeaderAnchor = React.useRef(); + const anchor = React.useRef(); const { logout, user } = useUser(); const navigate = useNavigator(); const intl = useIntl(); const [appState, dispatchAppState] = useAppState(); const { location } = useRouter(); const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false); - const isMdUp = useMediaQuery((theme: Theme) => theme.breakpoints.up("md")); const menuStructure = createMenuStructure(intl); const configurationMenu = createConfigurationMenu(intl); @@ -137,6 +188,16 @@ const AppLayout: React.FC = ({ children }) => { ) ); + const handleLogout = () => { + setMenuState(false); + logout(); + }; + + const handleViewerProfile = () => { + setMenuState(false); + navigate(staffMemberDetailsUrl(user.id)); + }; + const handleErrorBack = () => { navigate("/"); dispatchAppState({ @@ -156,15 +217,13 @@ const AppLayout: React.FC = ({ children }) => {
- {isMdUp && ( - - )} +
{appState.loading ? ( @@ -175,40 +234,93 @@ const AppLayout: React.FC = ({ children }) => {
-
-
- {!isMdUp && ( - - )} -
-
- - setNavigatorVisibility(true)} - /> - - navigate(staffMemberDetailsUrl(user.id)) +
+
+
+ + setNavigatorVisibility(true)} + /> +
+ + ) } - user={user} + classes={{ + avatar: classes.avatar + }} + className={classes.userChip} + label={ + <> + {user.email} + + + } + onClick={() => setMenuState(!isMenuOpened)} + data-test="userMenu" /> + + {({ TransitionProps, placement }) => ( + + + setMenuState(false)} + mouseEvent="onClick" + > + + + + + + + + + + + + )} +
diff --git a/src/components/Navigator/Navigator.tsx b/src/components/Navigator/Navigator.tsx index 203c39b5e..569eede26 100644 --- a/src/components/Navigator/Navigator.tsx +++ b/src/components/Navigator/Navigator.tsx @@ -49,9 +49,6 @@ const useStyles = makeStyles( overflow: "hidden" }, root: { - [theme.breakpoints.down("sm")]: { - height: "auto" - }, height: 500, maxWidth: 600, outline: 0, diff --git a/src/components/NavigatorButton/NavigatorButton.tsx b/src/components/NavigatorButton/NavigatorButton.tsx index 5e3c07341..ad3189280 100644 --- a/src/components/NavigatorButton/NavigatorButton.tsx +++ b/src/components/NavigatorButton/NavigatorButton.tsx @@ -66,10 +66,6 @@ const useStyles = makeStyles( "&:not(:hover)": { backgroundColor: theme.palette.background.paper }, - [theme.breakpoints.down("sm")]: { - border: "none", - borderRadius: 16 - }, border: `1px solid ${theme.palette.divider}`, height: 40, marginRight: theme.spacing(2), diff --git a/src/components/SideBar/ExpandButton.tsx b/src/components/SideBar/ExpandButton.tsx index 379d6be95..9a9550537 100644 --- a/src/components/SideBar/ExpandButton.tsx +++ b/src/components/SideBar/ExpandButton.tsx @@ -1,16 +1,26 @@ import { ButtonProps } from "@material-ui/core/Button"; +import ButtonBase from "@material-ui/core/ButtonBase"; import makeStyles from "@material-ui/core/styles/makeStyles"; import ArrowIcon from "@material-ui/icons/ArrowBack"; import classNames from "classnames"; import React from "react"; -import SquareButton from "../SquareButton"; - const useStyles = makeStyles( theme => ({ arrow: { transition: theme.transitions.duration.shortest + "ms" }, + root: { + "&:hover, &:focus": { + background: "#daedeb" + }, + background: theme.palette.background.paper, + borderRadius: 16, + color: theme.palette.primary.main, + height: 48, + transition: theme.transitions.duration.shortest + "ms", + width: 48 + }, shrunk: { transform: "scaleX(-1)" } @@ -24,17 +34,21 @@ export interface ExpandButtonProps extends ButtonProps { isShrunk: boolean; } -const ExpandButton: React.FC = ({ isShrunk, ...rest }) => { +const ExpandButton: React.FC = ({ + className, + isShrunk, + ...rest +}) => { const classes = useStyles({}); return ( - + - + ); }; diff --git a/src/components/SideBar/SideBar.tsx b/src/components/SideBar/SideBar.tsx index 77b4f3ee4..04570317e 100644 --- a/src/components/SideBar/SideBar.tsx +++ b/src/components/SideBar/SideBar.tsx @@ -9,7 +9,7 @@ import { sectionNames } from "@saleor/intl"; import classNames from "classnames"; import React from "react"; import SVG from "react-inlinesvg"; -import { IntlShape, useIntl } from "react-intl"; +import { useIntl } from "react-intl"; import { IMenuItem } from "../AppLayout/menuStructure"; import ExpandButton from "./ExpandButton"; @@ -55,14 +55,6 @@ export interface IActiveSubMenu { label: string | null; } -export const getConfigureMenuItem = (intl: IntlShape): IMenuItem => ({ - ariaLabel: "configure", - icon: configurationIcon, - label: intl.formatMessage(sectionNames.configuration), - testingContextId: "configure", - url: configurationMenuUrl -}); - const SideBar: React.FC = ({ location, menuItems, @@ -73,7 +65,6 @@ const SideBar: React.FC = ({ const classes = useStyles({}); const [isShrunk, setShrink] = useLocalStorage("isMenuSmall", false); const intl = useIntl(); - const configureMenuItem = getConfigureMenuItem(intl); return (
= ({ ) } isMenuShrunk={isShrunk} - menuItem={configureMenuItem} + menuItem={{ + ariaLabel: "configure", + icon: configurationIcon, + label: intl.formatMessage(sectionNames.configuration), + testingContextId: "configure", + url: configurationMenuUrl + }} onClick={onMenuItemClick} /> )} diff --git a/src/components/SideBarDrawer/MenuItemBtn.tsx b/src/components/SideBarDrawer/MenuItemBtn.tsx deleted file mode 100644 index 9013d5f36..000000000 --- a/src/components/SideBarDrawer/MenuItemBtn.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import Typography from "@material-ui/core/Typography"; -import { UseNavigatorResult } from "@saleor/hooks/useNavigator"; -import React from "react"; -import SVG from "react-inlinesvg"; - -import { IMenuItem } from "../AppLayout/menuStructure"; -import useStyles from "./styles"; - -export interface MenuItemBtnProps { - menuItem: IMenuItem; - onClick: UseNavigatorResult; -} -const MenuItemBtn: React.FC = ({ menuItem, onClick }) => { - const classes = useStyles({}); - - return ( - - ); -}; - -MenuItemBtn.displayName = "MenuItemBtn"; -export default MenuItemBtn; diff --git a/src/components/SideBarDrawer/SideBarDrawer.stories.tsx b/src/components/SideBarDrawer/SideBarDrawer.stories.tsx deleted file mode 100644 index 057ee7b90..000000000 --- a/src/components/SideBarDrawer/SideBarDrawer.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { staffMember } from "@saleor/staff/fixtures"; -import Decorator from "@saleor/storybook/Decorator"; -import { storiesOf } from "@storybook/react"; -import { config } from "@test/intl"; -import React from "react"; -import { createIntl } from "react-intl"; - -import createMenuStructure from "../AppLayout/menuStructure"; -import SideBarDrawer from "./SideBarDrawer"; - -const intl = createIntl(config); -const user = { - __typename: staffMember.__typename, - avatar: { - __typename: staffMember.avatar.__typename, - url: staffMember.avatar.url - }, - email: staffMember.email, - firstName: "Adam Evan", - id: staffMember.id, - isStaff: true, - lastName: "Newton", - note: null, - userPermissions: staffMember.userPermissions -}; - -storiesOf("Generics / Mobile Side Menu", module) - .addDecorator(Decorator) - .add("default", () => ( - undefined} - renderConfigure={true} - user={user} - /> - )); diff --git a/src/components/SideBarDrawer/SideBarDrawer.tsx b/src/components/SideBarDrawer/SideBarDrawer.tsx deleted file mode 100644 index e7963401c..000000000 --- a/src/components/SideBarDrawer/SideBarDrawer.tsx +++ /dev/null @@ -1,132 +0,0 @@ -import logoLight from "@assets/images/logo-sidebar-light.svg"; -import { Typography } from "@material-ui/core"; -import Drawer from "@material-ui/core/Drawer"; -import ArrowLeftIcon from "@material-ui/icons/ArrowLeft"; -import MenuIcon from "@material-ui/icons/Menu"; -import classNames from "classnames"; -import React from "react"; -import SVG from "react-inlinesvg"; -import { useIntl } from "react-intl"; - -import { IMenuItem } from "../AppLayout/menuStructure"; -import { getConfigureMenuItem, SideBarProps } from "../SideBar/SideBar"; -import SquareButton from "../SquareButton"; -import MenuItemBtn from "./MenuItemBtn"; -import useStyles from "./styles"; - -export type SideBarDrawerProps = SideBarProps; - -const SideBarDrawer: React.FC = ({ - menuItems, - onMenuItemClick, - renderConfigure, - user -}) => { - const [isOpened, setOpened] = React.useState(false); - const classes = useStyles({}); - const intl = useIntl(); - const [activeMenu, setActiveMenu] = React.useState(null); - const [showSubmenu, setShowSubmenu] = React.useState(false); - const container = React.useRef(null); - - const configureMenuItem = getConfigureMenuItem(intl); - - const handleMenuItemClick = (url: string) => { - setOpened(false); - setShowSubmenu(false); - onMenuItemClick(url); - }; - - const handleMenuItemWithChildrenClick = (menuItem: IMenuItem) => { - setActiveMenu(menuItem); - setShowSubmenu(true); - container.current.scrollTo({ - top: 0 - }); - }; - - return ( - <> - setOpened(true)}> - - - setOpened(false)} - > -
-
-
- - {menuItems.map(menuItem => { - if ( - menuItem.permission && - !user.userPermissions - .map(perm => perm.code) - .includes(menuItem.permission) - ) { - return null; - } - - return ( - handleMenuItemWithChildrenClick(menuItem) - : handleMenuItemClick - } - key={menuItem.ariaLabel} - /> - ); - })} - {renderConfigure && ( - - )} -
- {activeMenu && ( -
-
-
- - - {activeMenu.label} - -
- setShowSubmenu(false)}> - - -
- {activeMenu.children.map(subMenuItem => ( - - ))} -
- )} -
-
-
- - ); -}; - -SideBarDrawer.displayName = "SideBarDrawer"; -export default SideBarDrawer; diff --git a/src/components/SideBarDrawer/index.ts b/src/components/SideBarDrawer/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/components/SideBarDrawer/styles.ts b/src/components/SideBarDrawer/styles.ts deleted file mode 100644 index 92cda2a00..000000000 --- a/src/components/SideBarDrawer/styles.ts +++ /dev/null @@ -1,68 +0,0 @@ -import makeStyles from "@material-ui/core/styles/makeStyles"; - -const useStyles = makeStyles( - theme => ({ - activeMenuLabel: { - display: "flex" - }, - container: { - overflowX: "hidden", - width: "100%" - }, - containerSubMenu: { - "&$container": { - overflow: "hidden" - } - }, - content: { - width: "50%" - }, - icon: { - marginRight: theme.spacing(2) - }, - innerContainer: { - display: "flex", - position: "relative", - right: 0, - transition: theme.transitions.duration.short + "ms", - width: "200%" - }, - label: { - fontWeight: "bold" - }, - logo: { - display: "block", - marginBottom: theme.spacing(4) - }, - menuItemBtn: { - alignItems: "center", - background: "none", - border: "none", - color: theme.palette.text.secondary, - display: "flex", - marginBottom: theme.spacing(3), - padding: 0 - }, - root: { - background: theme.palette.background.default, - borderBottomRightRadius: 32, - borderTopRightRadius: 32, - padding: theme.spacing(3), - width: 260 - }, - secondaryContentActive: { - right: "100%" - }, - subMenuTopBar: { - alignItems: "center", - display: "flex", - justifyContent: "space-between", - marginBottom: theme.spacing(3) - } - }), - { - name: "SideBarDrawer" - } -); - -export default useStyles; diff --git a/src/components/SquareButton/SquareButton.stories.tsx b/src/components/SquareButton/SquareButton.stories.tsx deleted file mode 100644 index 2458c5d9f..000000000 --- a/src/components/SquareButton/SquareButton.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import CloseIcon from "@material-ui/icons/Close"; -import Decorator from "@saleor/storybook/Decorator"; -import { storiesOf } from "@storybook/react"; -import React from "react"; - -import SquareButton from "./SquareButton"; - -storiesOf("Generics / Square Button", module) - .addDecorator(Decorator) - .add("default", () => ( - - - - )); diff --git a/src/components/SquareButton/SquareButton.tsx b/src/components/SquareButton/SquareButton.tsx deleted file mode 100644 index 5e69a2fd9..000000000 --- a/src/components/SquareButton/SquareButton.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import ButtonBase, { ButtonBaseProps } from "@material-ui/core/ButtonBase"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import classNames from "classnames"; -import React from "react"; - -const useStyles = makeStyles( - theme => ({ - root: { - "&:hover, &:focus": { - background: "#daedeb" - }, - background: theme.palette.background.paper, - borderRadius: 16, - color: theme.palette.primary.main, - height: 48, - transition: theme.transitions.duration.shortest + "ms", - width: 48 - } - }), - { - name: "ExpandButton" - } -); - -const SquareButton: React.FC = ({ className, ...rest }) => { - const classes = useStyles({}); - - return ( - - ); -}; - -SquareButton.displayName = "SquareButton"; -export default SquareButton; diff --git a/src/components/SquareButton/index.ts b/src/components/SquareButton/index.ts deleted file mode 100644 index 7f406f96b..000000000 --- a/src/components/SquareButton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./SquareButton"; -export { default } from "./SquareButton"; diff --git a/src/components/UserChip/UserChip.tsx b/src/components/UserChip/UserChip.tsx deleted file mode 100644 index 165499ea7..000000000 --- a/src/components/UserChip/UserChip.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import Avatar from "@material-ui/core/Avatar"; -import Chip from "@material-ui/core/Chip"; -import ClickAwayListener from "@material-ui/core/ClickAwayListener"; -import Grow from "@material-ui/core/Grow"; -import Hidden from "@material-ui/core/Hidden"; -import MenuItem from "@material-ui/core/MenuItem"; -import Menu from "@material-ui/core/MenuList"; -import Paper from "@material-ui/core/Paper"; -import Popper from "@material-ui/core/Popper"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import { User } from "@saleor/fragments/types/User"; -import ArrowDropdown from "@saleor/icons/ArrowDropdown"; -import { getUserInitials, getUserName } from "@saleor/misc"; -import classNames from "classnames"; -import React from "react"; -import { FormattedMessage } from "react-intl"; - -const useStyles = makeStyles( - theme => ({ - arrow: { - [theme.breakpoints.down("sm")]: { - marginLeft: 0 - }, - marginLeft: theme.spacing(2), - transition: theme.transitions.duration.standard + "ms" - }, - avatar: { - "&&": { - [theme.breakpoints.down("sm")]: { - height: 40, - width: 40 - }, - height: 32, - width: 32 - } - }, - avatarInitials: { - color: theme.palette.primary.contrastText - }, - avatarPlaceholder: { - alignItems: "center", - background: theme.palette.primary.main, - borderRadius: "100%", - display: "flex", - justifyContent: "center" - }, - popover: { - marginTop: theme.spacing(2), - zIndex: 1 - }, - rotate: { - transform: "rotate(180deg)" - }, - userChip: { - [theme.breakpoints.down("sm")]: { - height: 48 - }, - backgroundColor: theme.palette.background.paper, - borderRadius: 24, - color: theme.palette.text.primary, - height: 40, - padding: theme.spacing(0.5) - }, - userMenuContainer: { - position: "relative" - }, - userMenuItem: { - textAlign: "right" - } - }), - { - name: "UserChip" - } -); - -export interface UserChipProps { - user: User; - onLogout: () => void; - onProfileClick: () => void; -} - -const UserChip: React.FC = ({ - user, - onLogout, - onProfileClick -}) => { - const classes = useStyles({}); - const [isMenuOpened, setMenuState] = React.useState(false); - const anchor = React.useRef(); - - const handleLogout = () => { - setMenuState(false); - onLogout(); - }; - - const handleViewerProfile = () => { - setMenuState(false); - onProfileClick(); - }; - - return ( -
- - ) : ( -
-
- {getUserInitials(user)} -
-
- ) - } - classes={{ - avatar: classes.avatar - }} - className={classes.userChip} - label={ - <> - {getUserName(user, true)} - - - } - onClick={() => setMenuState(!isMenuOpened)} - data-test="userMenu" - /> - - {({ TransitionProps, placement }) => ( - - - setMenuState(false)} - mouseEvent="onClick" - > - - - - - - - - - - - - )} - -
- ); -}; -UserChip.displayName = "UserChip"; -export default UserChip; diff --git a/src/components/UserChip/index.ts b/src/components/UserChip/index.ts deleted file mode 100644 index 125a4544b..000000000 --- a/src/components/UserChip/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./UserChip"; -export { default } from "./UserChip"; diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index 0e0ff0b0d..b06612519 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -4753,30 +4753,6 @@ exports[`Storyshots Generics / Metadata loading 1`] = `
`; -exports[`Storyshots Generics / Mobile Side Menu default 1`] = ` -
- -
-`; - exports[`Storyshots Generics / Money formatting default 1`] = `
`; -exports[`Storyshots Generics / Square Button default 1`] = ` -
- -
-`; - exports[`Storyshots Generics / StatusLabel when error 1`] = `
Date: Fri, 25 Sep 2020 16:45:27 +0200 Subject: [PATCH 2/4] Revert "Merge pull request #697 from mirumee/ref/sidebar" This reverts commit b1623eaaf5ac1045bac0f09cd6f700b39014cee9, reversing changes made to 14da39ebfa38392ba875bda408bf229896069864. --- CHANGELOG.md | 1 - assets/images/logo-sidebar-light.svg | 5 - assets/images/logo-white.svg | 1 + assets/images/menu-apps-icon.svg | 4 +- assets/images/menu-catalog-icon.svg | 4 +- assets/images/menu-configure-icon.svg | 4 +- assets/images/menu-customers-icon.svg | 4 +- assets/images/menu-discounts-icon.svg | 4 +- assets/images/menu-home-icon.svg | 4 +- assets/images/menu-orders-icon.svg | 4 +- assets/images/menu-translation-icon.svg | 4 +- .../account/left-menu/left-menu-selectors.js | 2 +- cypress/elements/catalog/product-selectors.js | 2 +- cypress/integration/warehouse.js | 2 +- locale/defaultMessages.json | 2 +- src/components/AppLayout/AppLayout.tsx | 242 +++++++++++- src/components/AppLayout/MenuList.tsx | 369 ++++++++++++++++++ src/components/AppLayout/MenuNested.tsx | 194 +++++++++ src/components/AppLayout/ResponsiveDrawer.tsx | 74 ++++ .../SaveButtonBar/SaveButtonBar.tsx | 18 +- src/components/SideBar/ExpandButton.tsx | 56 --- src/components/SideBar/MenuItem.tsx | 199 ---------- src/components/SideBar/SideBar.tsx | 131 ------- src/components/SideBar/SubMenu.tsx | 0 src/components/SideBar/index.ts | 2 - src/components/SideBar/utils.ts | 24 -- src/configuration/ConfigurationPage.tsx | 2 +- src/intl.ts | 2 +- .../__snapshots__/Stories.test.ts.snap | 42 +- .../WarehouseList/WarehouseList.tsx | 2 +- 30 files changed, 909 insertions(+), 495 deletions(-) delete mode 100644 assets/images/logo-sidebar-light.svg create mode 100644 assets/images/logo-white.svg create mode 100644 src/components/AppLayout/MenuList.tsx create mode 100644 src/components/AppLayout/MenuNested.tsx create mode 100644 src/components/AppLayout/ResponsiveDrawer.tsx delete mode 100644 src/components/SideBar/ExpandButton.tsx delete mode 100644 src/components/SideBar/MenuItem.tsx delete mode 100644 src/components/SideBar/SideBar.tsx delete mode 100644 src/components/SideBar/SubMenu.tsx delete mode 100644 src/components/SideBar/index.ts delete mode 100644 src/components/SideBar/utils.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b4fbc234b..8b082964c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,6 @@ All notable, unreleased changes to this project will be documented in this file. - Add lazyload to locales - #692 by @eaglesemanation - Fix not closed address update modal with two confirmations - #699 by @orzechdev - Update schema with PositiveDecimal type - #695 by @AlicjaSzu -- Restyle side menu - #697 by @dominik-zeglen - Add error info when fetching taxes - #701 by @dominik-zeglen - Fix return to previous page on screen size change - #710 by @orzechdev - Add variants reordering possibility - #716 by @orzechdev diff --git a/assets/images/logo-sidebar-light.svg b/assets/images/logo-sidebar-light.svg deleted file mode 100644 index 6d186cce1..000000000 --- a/assets/images/logo-sidebar-light.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/assets/images/logo-white.svg b/assets/images/logo-white.svg new file mode 100644 index 000000000..d01d84844 --- /dev/null +++ b/assets/images/logo-white.svg @@ -0,0 +1 @@ + diff --git a/assets/images/menu-apps-icon.svg b/assets/images/menu-apps-icon.svg index 85d36954a..3033691d1 100644 --- a/assets/images/menu-apps-icon.svg +++ b/assets/images/menu-apps-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-catalog-icon.svg b/assets/images/menu-catalog-icon.svg index 159804b6d..6b67b5aac 100644 --- a/assets/images/menu-catalog-icon.svg +++ b/assets/images/menu-catalog-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-configure-icon.svg b/assets/images/menu-configure-icon.svg index 7a435af97..c1defe727 100644 --- a/assets/images/menu-configure-icon.svg +++ b/assets/images/menu-configure-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-customers-icon.svg b/assets/images/menu-customers-icon.svg index 989bc7b0d..b46a2fc1e 100644 --- a/assets/images/menu-customers-icon.svg +++ b/assets/images/menu-customers-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-discounts-icon.svg b/assets/images/menu-discounts-icon.svg index 30ca87a8e..6f15dce79 100644 --- a/assets/images/menu-discounts-icon.svg +++ b/assets/images/menu-discounts-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-home-icon.svg b/assets/images/menu-home-icon.svg index 2c90eedf3..f91bd00a1 100644 --- a/assets/images/menu-home-icon.svg +++ b/assets/images/menu-home-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-orders-icon.svg b/assets/images/menu-orders-icon.svg index 74603fe7a..1e97d098d 100644 --- a/assets/images/menu-orders-icon.svg +++ b/assets/images/menu-orders-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/images/menu-translation-icon.svg b/assets/images/menu-translation-icon.svg index e869dedd1..7d034dd68 100644 --- a/assets/images/menu-translation-icon.svg +++ b/assets/images/menu-translation-icon.svg @@ -1,3 +1,3 @@ - - + + diff --git a/cypress/elements/account/left-menu/left-menu-selectors.js b/cypress/elements/account/left-menu/left-menu-selectors.js index fb525ee06..453e686ca 100644 --- a/cypress/elements/account/left-menu/left-menu-selectors.js +++ b/cypress/elements/account/left-menu/left-menu-selectors.js @@ -1,4 +1,4 @@ /* eslint-disable sort-keys */ export const LEFT_MENU_SELECTORS = { - catalog: "[data-test-id='catalogue']" + catalog: "[data-testid='catalogue']" }; diff --git a/cypress/elements/catalog/product-selectors.js b/cypress/elements/catalog/product-selectors.js index 6e9c992aa..aae2d0b9f 100644 --- a/cypress/elements/catalog/product-selectors.js +++ b/cypress/elements/catalog/product-selectors.js @@ -1,6 +1,6 @@ /* eslint-disable sort-keys */ export const PRODUCTS_SELECTORS = { - products: "[data-test='submenu-item-label'][data-test-id='products']", + products: "[href='/dashboard/products?']", createProductBtn: "[data-test='add-product']", productNameInput: "[name='name']", productTypeInput: "[data-test='product-type']", diff --git a/cypress/integration/warehouse.js b/cypress/integration/warehouse.js index 208321164..7ed06c295 100644 --- a/cypress/integration/warehouse.js +++ b/cypress/integration/warehouse.js @@ -7,7 +7,7 @@ describe("Warehouse settings", () => { xit("Warehouse section visible in the configuration", () => { cy.visit("/configuration/") .loginUser() - .get("[data-test-id=warehouses][data-test=settingsSubsection]") + .get("[data-testid=warehouses][data-test=settingsSubsection]") .click(); cy.location("pathname").should("eq", "/warehouses/"); }); diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 4822081e1..134765658 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -2719,7 +2719,7 @@ }, "src_dot_home": { "context": "home section name", - "string": "Dashboard" + "string": "Home" }, "src_dot_home_dot_components_dot_HomeActivityCard_dot_draft": { "string": "Order #{orderId} was placed from draft by {userEmail}" diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index 23d64337a..f46884fd3 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -1,7 +1,11 @@ +import saleorDarkLogoSmall from "@assets/images/logo-dark-small.svg"; +import saleorDarkLogo from "@assets/images/logo-dark.svg"; +import menuArrowIcon from "@assets/images/menu-arrow-icon.svg"; import Avatar from "@material-ui/core/Avatar"; import Chip from "@material-ui/core/Chip"; import ClickAwayListener from "@material-ui/core/ClickAwayListener"; import Grow from "@material-ui/core/Grow"; +import Hidden from "@material-ui/core/Hidden"; import LinearProgress from "@material-ui/core/LinearProgress"; import MenuItem from "@material-ui/core/MenuItem"; import Menu from "@material-ui/core/MenuList"; @@ -10,6 +14,7 @@ import Popper from "@material-ui/core/Popper"; import { makeStyles } from "@material-ui/core/styles"; import { createConfigurationMenu } from "@saleor/configuration"; import useAppState from "@saleor/hooks/useAppState"; +import useLocalStorage from "@saleor/hooks/useLocalStorage"; import useNavigator from "@saleor/hooks/useNavigator"; import useTheme from "@saleor/hooks/useTheme"; import useUser from "@saleor/hooks/useUser"; @@ -17,6 +22,7 @@ import ArrowDropdown from "@saleor/icons/ArrowDropdown"; import { staffMemberDetailsUrl } from "@saleor/staff/urls"; import classNames from "classnames"; import React from "react"; +import SVG from "react-inlinesvg"; import { FormattedMessage, useIntl } from "react-intl"; import useRouter from "use-react-router"; @@ -24,11 +30,12 @@ import Container from "../Container"; import ErrorPage from "../ErrorPage"; import Navigator from "../Navigator"; import NavigatorButton from "../NavigatorButton/NavigatorButton"; -import SideBar from "../SideBar"; import AppActionContext from "./AppActionContext"; import AppHeaderContext from "./AppHeaderContext"; -import { appLoaderHeight } from "./consts"; +import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts"; +import MenuList from "./MenuList"; import createMenuStructure from "./menuStructure"; +import ResponsiveDrawer from "./ResponsiveDrawer"; import ThemeSwitch from "./ThemeSwitch"; const useStyles = makeStyles( @@ -45,12 +52,12 @@ const useStyles = makeStyles( }, appLoader: { height: appLoaderHeight, - marginBottom: theme.spacing(4), + marginBottom: theme.spacing(2), zIndex: 1201 }, appLoaderPlaceholder: { height: appLoaderHeight, - marginBottom: theme.spacing(4) + marginBottom: theme.spacing(2) }, arrow: { marginLeft: theme.spacing(2), @@ -63,7 +70,18 @@ const useStyles = makeStyles( } }, content: { - flex: 1 + [theme.breakpoints.down("sm")]: { + paddingLeft: 0 + }, + paddingLeft: drawerWidthExpanded, + transition: "padding-left 0.5s ease", + width: "100%" + }, + contentToggle: { + [theme.breakpoints.down("sm")]: { + paddingLeft: 0 + }, + paddingLeft: drawerWidth }, darkThemeSwitch: { [theme.breakpoints.down("sm")]: { @@ -91,11 +109,136 @@ const useStyles = makeStyles( height: "auto" } }, + isMenuSmall: { + "& path": { + fill: theme.palette.primary.main + }, + "& span": { + margin: "0 8px" + }, + "& svg": { + marginTop: 8, + transform: "rotate(180deg)" + }, + "&:hover": { + background: "#E6F3F3" + }, + background: theme.palette.background.paper, + border: `solid 1px #EAEAEA`, + borderRadius: "50%", + cursor: "pointer", + height: 32, + position: "absolute", + right: -16, + top: 65, + transition: `background ${theme.transitions.duration.shorter}ms`, + width: 32, + zIndex: 99 + }, + isMenuSmallDark: { + "&:hover": { + background: `linear-gradient(0deg, rgba(25, 195, 190, 0.1), rgba(25, 195, 190, 0.1)), ${theme.palette.background.paper}` + }, + border: `solid 1px #252728`, + transition: `background ${theme.transitions.duration.shorter}ms` + }, + isMenuSmallHide: { + "& svg": { + marginLeft: "3px", + transform: "rotate(0deg)" + } + }, + logo: { + "& svg": { + left: "50%", + position: "absolute", + top: "50%", + transform: "translate(-50%,-50%)" + }, + background: theme.palette.secondary.main, + display: "block", + height: 80, + position: "relative" + }, + logoDark: { + "& path": { + fill: theme.palette.common.white + }, + background: theme.palette.primary.main + }, + logoSmall: { + "& svg": { + margin: 0, + padding: 0, + width: "80px" + } + }, menu: { background: theme.palette.background.paper, height: "100vh", padding: "25px 20px" }, + menuIcon: { + "& span": { + "&:nth-child(1)": { + top: 15 + }, + "&:nth-child(2), &:nth-child(3)": { + top: 20 + }, + "&:nth-child(4)": { + top: 25 + }, + background: theme.palette.secondary.light, + display: "block", + height: 1, + left: "20%", + opacity: 1, + position: "absolute", + transform: "rotate(0deg)", + transition: ".25s ease-in-out", + width: "60%" + }, + [theme.breakpoints.up("md")]: { + display: "none" + }, + [theme.breakpoints.down("sm")]: { + left: 0 + }, + background: theme.palette.background.paper, + borderRadius: "50%", + cursor: "pointer", + height: 42, + left: theme.spacing(), + marginRight: theme.spacing(2), + position: "relative", + transform: "rotate(0deg)", + transition: `${theme.transitions.duration.shorter}ms ease-in-out`, + width: 42 + }, + menuIconDark: { + "& span": { + background: theme.palette.common.white + } + }, + menuIconOpen: { + "& span": { + "&:nth-child(1), &:nth-child(4)": { + left: "50%", + top: 20, + width: 0 + }, + "&:nth-child(2)": { + transform: "rotate(45deg)" + }, + "&:nth-child(3)": { + transform: "rotate(-45deg)" + } + }, + left: 280, + position: "absolute", + zIndex: 1999 + }, menuSmall: { background: theme.palette.background.paper, height: "100vh", @@ -106,14 +249,18 @@ const useStyles = makeStyles( zIndex: 1 }, root: { - [theme.breakpoints.up("md")]: { - display: "flex" - }, width: `100%` }, rotate: { transform: "rotate(180deg)" }, + sideBar: { + [theme.breakpoints.down("sm")]: { + padding: 0 + }, + background: theme.palette.background.paper, + padding: `0 ${theme.spacing(4)}px` + }, spacer: { flex: 1 }, @@ -140,6 +287,7 @@ const useStyles = makeStyles( textAlign: "right" }, view: { + backgroundColor: theme.palette.background.default, flex: 1, flexGrow: 1, marginLeft: 0, @@ -149,7 +297,7 @@ const useStyles = makeStyles( } }, viewContainer: { - minHeight: `calc(100vh - ${theme.spacing(4) + appLoaderHeight + 120}px)` + minHeight: `calc(100vh - ${theme.spacing(2) + appLoaderHeight + 70}px)` } }), { @@ -164,6 +312,8 @@ interface AppLayoutProps { const AppLayout: React.FC = ({ children }) => { const classes = useStyles({}); const { isDark, toggleTheme } = useTheme(); + const [isMenuSmall, setMenuSmall] = useLocalStorage("isMenuSmall", false); + const [isDrawerOpened, setDrawerState] = React.useState(false); const [isMenuOpened, setMenuState] = React.useState(false); const appActionAnchor = React.useRef(); const appHeaderAnchor = React.useRef(); @@ -198,6 +348,17 @@ const AppLayout: React.FC = ({ children }) => { navigate(staffMemberDetailsUrl(user.id)); }; + const handleMenuItemClick = (url: string, event: React.MouseEvent) => { + event.stopPropagation(); + event.preventDefault(); + setDrawerState(false); + navigate(url); + }; + + const handleIsMenuSmall = () => { + setMenuSmall(!isMenuSmall); + }; + const handleErrorBack = () => { navigate("/"); dispatchAppState({ @@ -217,14 +378,49 @@ const AppLayout: React.FC = ({ children }) => {
- -
+
+ setDrawerState(false)} + open={isDrawerOpened} + small={!isMenuSmall} + > +
+ +
+ +
+ +
+
+ +
+
+
{appState.loading ? ( ) : ( @@ -234,6 +430,18 @@ const AppLayout: React.FC = ({ children }) => {
+
setDrawerState(!isDrawerOpened)} + > + + + + +
diff --git a/src/components/AppLayout/MenuList.tsx b/src/components/AppLayout/MenuList.tsx new file mode 100644 index 000000000..05f6fa971 --- /dev/null +++ b/src/components/AppLayout/MenuList.tsx @@ -0,0 +1,369 @@ +import configureIcon from "@assets/images/menu-configure-icon.svg"; +import { makeStyles } from "@material-ui/core/styles"; +import Typography from "@material-ui/core/Typography"; +import { User } from "@saleor/fragments/types/User"; +import useTheme from "@saleor/hooks/useTheme"; +import { sectionNames } from "@saleor/intl"; +import classNames from "classnames"; +import React from "react"; +import SVG from "react-inlinesvg"; +import { FormattedMessage, useIntl } from "react-intl"; +import { matchPath } from "react-router"; + +import { + configurationMenuUrl, + createConfigurationMenu +} from "../../configuration"; +import { createHref } from "../../misc"; +import { orderDraftListUrl, orderListUrl } from "../../orders/urls"; +import MenuNested from "./MenuNested"; +import { IMenuItem } from "./menuStructure"; + +const useStyles = makeStyles( + theme => ({ + menuIcon: { + "& svg": { + height: 32, + width: 32 + }, + display: "inline-block", + position: "relative", + top: 8 + }, + menuIconDark: { + "& path": { + fill: theme.palette.common.white + } + }, + menuIconSmall: { + left: -5 + }, + menuIsActive: { + boxShadow: "0px 0px 12px 1px rgba(0,0,0,0.2)" + }, + menuItemHover: { + "& p": { + fontSize: 14, + transition: "color 0.5s ease, opacity 0.3s ease-out" + }, + "& path": { + transition: "fill 0.5s ease" + }, + "&:hover": { + "& p": { + color: theme.palette.primary.main + }, + "& path": { + fill: theme.palette.primary.main + }, + "&:before": { + borderLeft: `solid 2px ${theme.palette.primary.main}`, + content: "''", + height: 33, + left: -20, + position: "absolute", + top: 8 + }, + color: theme.palette.primary.main + }, + cursor: "pointer", + position: "relative" + }, + menuList: { + display: "flex", + flexDirection: "column", + height: "100%", + marginLeft: theme.spacing(4), + marginTop: theme.spacing(2), + paddingBottom: theme.spacing(3) + }, + menuListItem: { + alignItems: "center", + display: "block", + marginBottom: theme.spacing(5), + paddingLeft: 0, + textDecoration: "none", + transition: theme.transitions.duration.standard + "ms" + }, + menuListItemActive: { + "& $menuListItemText": { + color: theme.palette.primary.main + }, + "& path": { + color: theme.palette.primary.main, + fill: theme.palette.primary.main + } + }, + menuListItemOpen: { + "&:after": { + borderBottom: `10px solid transparent`, + borderLeft: `10px solid ${theme.palette.background.paper}`, + borderTop: `10px solid transparent`, + content: "''", + height: 0, + position: "absolute", + right: -30, + top: 15, + width: 0 + }, + "&:before": { + borderLeft: `solid 2px ${theme.palette.primary.main}`, + content: "''", + height: 33, + left: -20, + position: "absolute", + top: 8 + }, + position: "relative" + }, + menuListItemText: { + "&:hover": { + color: theme.palette.primary.main + }, + bottom: 0, + cursor: "pointer", + fontSize: "1rem", + fontWeight: 500, + left: 30, + opacity: 1, + paddingLeft: 16, + position: "absolute", + textTransform: "uppercase", + transition: "opacity 0.5s ease" + }, + menuListItemTextHide: { + bottom: 0, + left: 30, + opacity: 0, + position: "absolute" + }, + subMenu: { + padding: "0 15px" + }, + subMenuDrawer: { + background: "#000", + cursor: "pointer", + height: "100vh", + left: 0, + opacity: 0.2, + position: "absolute", + top: 0, + width: 0, + zIndex: -2 + }, + subMenuDrawerOpen: { + width: `100vw` + } + }), + { name: "MenuList" } +); + +interface MenuListProps { + className?: string; + menuItems: IMenuItem[]; + isMenuSmall: boolean; + location: string; + user: User; + renderConfigure: boolean; + onMenuItemClick: (url: string, event: React.MouseEvent) => void; +} + +export interface IActiveSubMenu { + isActive: boolean; + label: string | null; +} + +const MenuList: React.FC = props => { + const { + className, + menuItems, + isMenuSmall, + location, + user, + renderConfigure, + onMenuItemClick + } = props; + + const classes = useStyles(props); + + const { isDark } = useTheme(); + const [activeSubMenu, setActiveSubMenu] = React.useState({ + isActive: false, + label: null + }); + const intl = useIntl(); + + const configurationMenu = createConfigurationMenu(intl).map(menu => { + menu.menuItems.map(item => + user.userPermissions.map(perm => perm.code).includes(item.permission) + ); + }); + + const handleSubMenu = itemLabel => { + setActiveSubMenu({ + isActive: + itemLabel === activeSubMenu.label ? !activeSubMenu.isActive : true, + label: itemLabel + }); + }; + + const closeSubMenu = (menuItemUrl, event) => { + setActiveSubMenu({ + isActive: false, + label: null + }); + if (menuItemUrl && event) { + onMenuItemClick(menuItemUrl, event); + event.stopPropagation(); + event.preventDefault(); + } + }; + + return ( +
+ {/* FIXME: this .split("?")[0] looks gross */} + {menuItems.map(menuItem => { + const isActive = (menuItem: IMenuItem) => + location.split("?")[0] === orderDraftListUrl().split("?")[0] && + menuItem.url.split("?")[0] === orderListUrl().split("?")[0] + ? false + : !!matchPath(location.split("?")[0], { + exact: menuItem.url.split("?")[0] === "/", + path: menuItem.url.split("?")[0] + }); + + if ( + menuItem.permission && + !user.userPermissions + .map(perm => perm.code) + .includes(menuItem.permission) + ) { + return null; + } + + if (!menuItem.url) { + const isAnyChildActive = menuItem.children.reduce( + (acc, child) => acc || isActive(child), + false + ); + + return ( +
+
handleSubMenu(menuItem.ariaLabel)} + > + + + {menuItem.label} + +
+ +
closeSubMenu(null, event)} + className={classNames(classes.subMenuDrawer, { + [classes.subMenuDrawerOpen]: activeSubMenu.isActive + })} + /> +
+ ); + } + + return ( + closeSubMenu(menuItem.url, event)} + key={menuItem.label} + data-testid={menuItem.testingContextId} + data-test="menuItemEntry" + > +
+ + + {menuItem.label} + +
+
+ ); + })} + {renderConfigure && configurationMenu.length > 0 && ( + closeSubMenu(configurationMenuUrl, event)} + > +
+ + + + +
+
+ )} +
+ ); +}; + +MenuList.displayName = "MenuList"; +export default MenuList; diff --git a/src/components/AppLayout/MenuNested.tsx b/src/components/AppLayout/MenuNested.tsx new file mode 100644 index 000000000..0a64b1892 --- /dev/null +++ b/src/components/AppLayout/MenuNested.tsx @@ -0,0 +1,194 @@ +import menuArrowIcon from "@assets/images/menu-arrow-icon.svg"; +import Hidden from "@material-ui/core/Hidden"; +import { makeStyles } from "@material-ui/core/styles"; +import Typography from "@material-ui/core/Typography"; +import useTheme from "@saleor/hooks/useTheme"; +import { createHref } from "@saleor/misc"; +import classNames from "classnames"; +import React from "react"; +import SVG from "react-inlinesvg"; + +import { drawerNestedMenuWidth, drawerWidthExpandedMobile } from "./consts"; +import { IActiveSubMenu } from "./MenuList"; +import { IMenuItem } from "./menuStructure"; + +const useStyles = makeStyles( + theme => ({ + menuListNested: { + background: theme.palette.background.paper, + height: "100vh", + position: "absolute", + right: 0, + top: 0, + transition: `right ${theme.transitions.duration.shorter}ms ease`, + width: drawerNestedMenuWidth, + zIndex: -1 + }, + menuListNestedClose: { + "& svg": { + fill: theme.palette.primary.main, + left: 11, + position: "relative", + top: 1 + }, + border: `solid 1px #EAEAEA`, + borderRadius: "100%", + cursor: "pointer", + height: 32, + position: "absolute", + right: 32, + top: 35, + transform: "rotate(180deg)", + width: 32 + }, + menuListNestedCloseDark: { + border: `solid 1px #252728` + }, + menuListNestedHide: { + opacity: 0 + }, + menuListNestedIcon: { + "& path": { + fill: "initial" + }, + "& svg": { height: 32, position: "relative", top: 7, width: 32 } + }, + menuListNestedIconDark: { + "& path": { + fill: theme.palette.common.white + } + }, + menuListNestedItem: { + "&:hover": { + "& p": { + color: theme.palette.primary.main + } + }, + display: "block", + marginBottom: theme.spacing(2), + padding: "0px 30px", + textDecoration: "none" + }, + menuListNestedOpen: { + [theme.breakpoints.down("sm")]: { + right: 0, + width: drawerWidthExpandedMobile, + zIndex: 2 + }, + right: -drawerNestedMenuWidth, + width: drawerNestedMenuWidth, + zIndex: -1 + }, + subHeader: { + borderBottom: "solid 1px #EAEAEA", + margin: "30px", + marginBottom: 39, + paddingBottom: 22 + }, + subHeaderDark: { + borderBottom: "solid 1px #252728" + }, + subHeaderTitle: { + [theme.breakpoints.up("md")]: { + paddingLeft: 0 + }, + display: "inline", + paddingLeft: 10 + } + }), + { name: "MenuNested" } +); + +export interface MenuNestedProps { + activeItem: IActiveSubMenu; + ariaLabel: string; + closeSubMenu: ({ isActive, label }: IActiveSubMenu) => void; + icon: string; + menuItem: IMenuItem; + title: string; + handleSubMenu: (itemLabel: string) => void; + onMenuItemClick: (url: string, event: React.MouseEvent) => void; +} + +const MenuNested: React.FC = props => { + const { + activeItem, + ariaLabel, + + closeSubMenu, + icon, + menuItem, + onMenuItemClick, + title + } = props; + const classes = useStyles(props); + + const menuItems = menuItem.children; + const { isDark } = useTheme(); + const closeMenu = (menuItemUrl, event) => { + onMenuItemClick(menuItemUrl, event); + closeSubMenu({ + isActive: false, + label: null + }); + event.stopPropagation(); + event.preventDefault(); + }; + return ( + <> +
+ + + + +
{title}
+ +
+ closeSubMenu({ + isActive: false, + label: null + }) + } + > + +
+
+
+ {menuItems.map(item => ( + closeMenu(item.url, event)} + key={item.label} + > + {item.label} + + ))} +
+ + ); +}; + +MenuNested.displayName = "MenuNested"; +export default MenuNested; diff --git a/src/components/AppLayout/ResponsiveDrawer.tsx b/src/components/AppLayout/ResponsiveDrawer.tsx new file mode 100644 index 000000000..49baa1e7f --- /dev/null +++ b/src/components/AppLayout/ResponsiveDrawer.tsx @@ -0,0 +1,74 @@ +import Drawer from "@material-ui/core/Drawer"; +import Hidden from "@material-ui/core/Hidden"; +import { makeStyles } from "@material-ui/core/styles"; +import React from "react"; + +import { + drawerWidth, + drawerWidthExpanded, + drawerWidthExpandedMobile +} from "./consts"; + +const useStyles = makeStyles( + theme => ({ + drawerDesktop: { + backgroundColor: theme.palette.background.paper, + border: "none", + height: "100vh", + overflow: "visible", + padding: 0, + position: "fixed" as "fixed", + transition: "width 0.3s ease", + width: drawerWidthExpanded + }, + drawerDesktopSmall: { + overflow: "visible", + transition: "width 0.2s ease", + width: drawerWidth + }, + drawerMobile: { + width: drawerWidthExpandedMobile + } + }), + { name: "ResponsiveDrawer" } +); + +interface ResponsiveDrawerProps { + children?: React.ReactNode; + open: boolean; + small: boolean; + onClose?(); +} + +const ResponsiveDrawer: React.FC = props => { + const { children, onClose, open, small } = props; + + const classes = useStyles(props); + + return ( + <> + + + {children} + + + + + {children} + + + + ); +}; +export default ResponsiveDrawer; diff --git a/src/components/SaveButtonBar/SaveButtonBar.tsx b/src/components/SaveButtonBar/SaveButtonBar.tsx index b7a5b6cf0..adf2bdcdb 100644 --- a/src/components/SaveButtonBar/SaveButtonBar.tsx +++ b/src/components/SaveButtonBar/SaveButtonBar.tsx @@ -5,7 +5,6 @@ import Portal from "@material-ui/core/Portal"; import { makeStyles } from "@material-ui/core/styles"; import useWindowScroll from "@saleor/hooks/useWindowScroll"; import { buttonMessages } from "@saleor/intl"; -import classNames from "classnames"; import React from "react"; import { useIntl } from "react-intl"; @@ -18,21 +17,12 @@ import Container from "../Container"; const useStyles = makeStyles( theme => ({ - applyShadow: { - "&$card": { - boxShadow: "0px 6px 30px rgba(0, 0, 0, 0.16)" - } - }, button: { marginRight: theme.spacing(1) }, cancelButton: { marginRight: theme.spacing(2) }, - card: { - boxShadow: "0px 0px 0px rgba(0, 0, 0, 0.16)", - transition: theme.transitions.duration.shortest + "ms" - }, content: { "&:last-child": { paddingBottom: theme.spacing(2) @@ -89,7 +79,7 @@ export const SaveButtonBar: React.FC = props => { const intl = useIntl(); const scrollPosition = useWindowScroll(); const scrolledToBottom = - scrollPosition.y + window.innerHeight - document.body.scrollHeight >= -5; + scrollPosition.y + window.innerHeight >= document.body.scrollHeight; return ( @@ -98,11 +88,7 @@ export const SaveButtonBar: React.FC = props => {
- + {!!onDelete && ( - {menuItem.children && ( - - setOpen(false)}> - - {menuItem.children.map(subMenuItem => ( - handleClick(event, subMenuItem)} - data-test="submenu-item-label" - data-test-id={subMenuItem.testingContextId} - variant="body2" - > - {subMenuItem.label} - - ))} - - - - )} -
- ); -}; - -MenuItem.displayName = "MenuItem"; -export default MenuItem; diff --git a/src/components/SideBar/SideBar.tsx b/src/components/SideBar/SideBar.tsx deleted file mode 100644 index 04570317e..000000000 --- a/src/components/SideBar/SideBar.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import logoLight from "@assets/images/logo-sidebar-light.svg"; -import configurationIcon from "@assets/images/menu-configure-icon.svg"; -import makeStyles from "@material-ui/core/styles/makeStyles"; -import { configurationMenuUrl } from "@saleor/configuration"; -import { User } from "@saleor/fragments/types/User"; -import useLocalStorage from "@saleor/hooks/useLocalStorage"; -import { UseNavigatorResult } from "@saleor/hooks/useNavigator"; -import { sectionNames } from "@saleor/intl"; -import classNames from "classnames"; -import React from "react"; -import SVG from "react-inlinesvg"; -import { useIntl } from "react-intl"; - -import { IMenuItem } from "../AppLayout/menuStructure"; -import ExpandButton from "./ExpandButton"; -import MenuItem, { menuWidth, shrunkMenuWidth } from "./MenuItem"; -import { isMenuActive } from "./utils"; - -const useStyles = makeStyles( - theme => ({ - expandButton: { - marginLeft: theme.spacing(2) - }, - float: { - position: "fixed" - }, - logo: { - margin: `36px 0 ${theme.spacing(3)}px ${theme.spacing(3)}px` - }, - root: { - transition: "width 0.5s ease", - width: menuWidth, - zIndex: 100 - }, - rootShrink: { - width: shrunkMenuWidth - } - }), - { - name: "SideBar" - } -); - -export interface SideBarProps { - className?: string; - menuItems: IMenuItem[]; - location: string; - user: User; - renderConfigure: boolean; - onMenuItemClick: UseNavigatorResult; -} - -export interface IActiveSubMenu { - isActive: boolean; - label: string | null; -} - -const SideBar: React.FC = ({ - location, - menuItems, - renderConfigure, - user, - onMenuItemClick -}) => { - const classes = useStyles({}); - const [isShrunk, setShrink] = useLocalStorage("isMenuSmall", false); - const intl = useIntl(); - - return ( -
-
-
- -
- {menuItems.map(menuItem => { - const isActive = isMenuActive(location, menuItem); - - if ( - menuItem.permission && - !user.userPermissions - .map(perm => perm.code) - .includes(menuItem.permission) - ) { - return null; - } - - return ( - - ); - })} - {renderConfigure && ( - acc || isMenuActive(location, menuItem), - false - ) - } - isMenuShrunk={isShrunk} - menuItem={{ - ariaLabel: "configure", - icon: configurationIcon, - label: intl.formatMessage(sectionNames.configuration), - testingContextId: "configure", - url: configurationMenuUrl - }} - onClick={onMenuItemClick} - /> - )} - setShrink(!isShrunk)} - /> -
-
- ); -}; - -SideBar.displayName = "SideBar"; -export default SideBar; diff --git a/src/components/SideBar/SubMenu.tsx b/src/components/SideBar/SubMenu.tsx deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/components/SideBar/index.ts b/src/components/SideBar/index.ts deleted file mode 100644 index df08bddc7..000000000 --- a/src/components/SideBar/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./SideBar"; -export { default } from "./SideBar"; diff --git a/src/components/SideBar/utils.ts b/src/components/SideBar/utils.ts deleted file mode 100644 index 06827a7ac..000000000 --- a/src/components/SideBar/utils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { orderDraftListUrl, orderListUrl } from "@saleor/orders/urls"; -import { matchPath } from "react-router"; - -import { IMenuItem } from "../AppLayout/menuStructure"; - -export function isMenuActive(location: string, menuItem: IMenuItem) { - if (menuItem.children) { - return menuItem.children.reduce( - (acc, subMenuItem) => acc || isMenuActive(location, subMenuItem), - false - ); - } - - const activeUrl = location.split("?")[0]; - const menuItemUrl = menuItem.url.split("?")[0]; - - return activeUrl === orderDraftListUrl().split("?")[0] && - menuItemUrl === orderListUrl().split("?")[0] - ? false - : !!matchPath(activeUrl, { - exact: menuItemUrl === "/", - path: menuItemUrl - }); -} diff --git a/src/configuration/ConfigurationPage.tsx b/src/configuration/ConfigurationPage.tsx index 271a08eca..502b9568c 100644 --- a/src/configuration/ConfigurationPage.tsx +++ b/src/configuration/ConfigurationPage.tsx @@ -127,7 +127,7 @@ export const ConfigurationPage: React.FC = props => { onClick={() => onSectionClick(item.url)} key={itemIndex} data-test="settingsSubsection" - data-test-id={item.title.toLowerCase()} + data-testid={item.title.toLowerCase()} >
{item.icon}
diff --git a/src/intl.ts b/src/intl.ts index b0e989e24..6fe6a3e68 100644 --- a/src/intl.ts +++ b/src/intl.ts @@ -196,7 +196,7 @@ export const sectionNames = defineMessages({ description: "draft orders section name" }, home: { - defaultMessage: "Dashboard", + defaultMessage: "Home", description: "home section name" }, navigation: { diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index b06612519..10ad182b8 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -53129,7 +53129,7 @@ exports[`Storyshots Views / Configuration default 1`] = `
= props => { onClick={warehouse ? onRowClick(warehouse.id) : undefined} key={warehouse ? warehouse.id : "skeleton"} data-test="warehouseEntry" - data-test-id={warehouse?.name.toLowerCase().replace(" ", "")} + data-testid={warehouse?.name.toLowerCase().replace(" ", "")} > {maybe(() => warehouse.name, )} From 80c57ae0c08b6feebc7b8196f0b83c4882406090 Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Fri, 25 Sep 2020 17:23:07 +0200 Subject: [PATCH 3/4] Revert "Fix return to previous page on screen size change (#710)" This reverts commit 45d33c392081dc418ef3cc7d2b67d8fda522c458. --- src/components/AppLayout/AppLayout.tsx | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index f46884fd3..bbfbf4475 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -90,24 +90,13 @@ const useStyles = makeStyles( marginRight: theme.spacing(2) }, header: { - display: "grid", - gridTemplateAreas: `"headerAnchor headerToolbar"`, [theme.breakpoints.down("sm")]: { height: 88, marginBottom: 0 }, - marginBottom: theme.spacing(3) - }, - headerAnchor: { - gridArea: "headerAnchor" - }, - headerToolbar: { display: "flex", - gridArea: "headerToolbar", height: 40, - [theme.breakpoints.down("sm")]: { - height: "auto" - } + marginBottom: theme.spacing(3) }, isMenuSmall: { "& path": { From 85b4d13ba2ba3166702f03203a391c7d9940c8d7 Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Fri, 25 Sep 2020 17:27:50 +0200 Subject: [PATCH 4/4] Hide navigator button on mobile devices --- src/components/AppLayout/AppLayout.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/AppLayout/AppLayout.tsx b/src/components/AppLayout/AppLayout.tsx index bbfbf4475..128c20a95 100644 --- a/src/components/AppLayout/AppLayout.tsx +++ b/src/components/AppLayout/AppLayout.tsx @@ -439,12 +439,14 @@ const AppLayout: React.FC = ({ children }) => { checked={isDark} onClick={toggleTheme} /> - setNavigatorVisibility(true)} - /> + + setNavigatorVisibility(true)} + /> +