Remove double submenus from the sidebar (#3218)

This commit is contained in:
Paweł Chyła 2023-02-28 13:15:25 +01:00 committed by GitHub
parent 67c674126a
commit c5a25f9cb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 176 additions and 199 deletions

View file

@ -39,6 +39,10 @@
"context": "tax class for a product type",
"string": "Tax class"
},
"+MJW+8": {
"context": "button",
"string": "Create Discount"
},
"+NUzaQ": {
"context": "check to mark this account as active",
"string": "User account active"
@ -562,10 +566,6 @@
"context": "CreateVariantTitle manage",
"string": "Manage"
},
"2E1xZ0": {
"context": "page header",
"string": "Create Sale"
},
"2FQsYj": {
"context": "button",
"string": "Clear"
@ -1542,10 +1542,6 @@
"context": "dialog content",
"string": "{counter,plural,one{Are you sure you want to unassign this product?} other{Are you sure you want to unassign {displayQuantity} products?}}"
},
"AHRDWt": {
"context": "button",
"string": "Create page"
},
"AJgl5u": {
"context": "gift card product message",
"string": "gift card product"
@ -2001,6 +1997,10 @@
"DO8+uV": {
"string": "Product created"
},
"DOVEZF": {
"context": "button",
"string": "Create content"
},
"DOkfyZ": {
"string": "Insufficient permissions"
},
@ -2260,6 +2260,10 @@
"context": "option title",
"string": "Prioritize warehouses by sorting order"
},
"FWbv/u": {
"context": "page header",
"string": "Create Discount"
},
"FYfoiF": {
"context": "section name",
"string": "Allocation strategy"
@ -2812,10 +2816,6 @@
"context": "option",
"string": "Export stock for all warehouses"
},
"JHfbXR": {
"context": "button",
"string": "Create Sale"
},
"JI2Xwp": {
"context": "dialog title",
"string": "Delete attribute"
@ -3198,9 +3198,6 @@
"context": "activate",
"string": "Activate"
},
"MSD3A/": {
"string": "Search Sale"
},
"MSItJD": {
"string": "You are about to leave the Dashboard. Do you want to continue?"
},
@ -3359,6 +3356,10 @@
"context": "gift card bulk create success dialog content",
"string": "We have issued all of your requested gift cards. You can download the list of new gift cards using the button below."
},
"NelCIl": {
"context": "content section name",
"string": "Content"
},
"Nfh9QM": {
"context": "checkbox gift cards label description",
"string": "when activated non-shippable gift cards will be automatically set as fulfilled and sent to customer"
@ -4274,10 +4275,6 @@
"context": "filters error messages unknown error",
"string": "Unknown error occurred"
},
"UW1fLs": {
"context": "search pages placeholder",
"string": "Search Pages"
},
"UaYJJ8": {
"string": "Are you sure you want to delete {name} search tab?"
},
@ -4921,10 +4918,6 @@
"context": "time during voucher is active, header",
"string": "Active Dates"
},
"Yjhgle": {
"context": "tab name",
"string": "All Sales"
},
"YkOzse": {
"context": "used warehouses counter",
"string": "{count}/{max} warehouses used"
@ -5372,6 +5365,10 @@
"c8nvms": {
"string": "Sales"
},
"c8zJID": {
"context": "tab name",
"string": "All Discounts"
},
"cBHRxx": {
"context": "button",
"string": "Assign Warehouse"
@ -6457,6 +6454,9 @@
"context": "save filter tab, header",
"string": "Save Custom Search"
},
"lit2zF": {
"string": "Search Discounts"
},
"ll2dE6": {
"context": "PageTypeDeleteWarningDialog multiple assigned items description",
"string": "Are you sure you want to delete selected page types? If you remove them you wont be able to assign them to created pages."
@ -6677,6 +6677,10 @@
"context": "error message",
"string": "Not enough items to fulfill"
},
"nP8iex": {
"context": "search content placeholder",
"string": "Search Content"
},
"nRiOg+": {
"string": "Sorry, the page was not found"
},

14
package-lock.json generated
View file

@ -26,7 +26,7 @@
"@material-ui/lab": "^4.0.0-alpha.61",
"@material-ui/styles": "^4.11.4",
"@reach/auto-id": "^0.16.0",
"@saleor/macaw-ui": "^0.8.0-pre.31",
"@saleor/macaw-ui": "^0.8.0-pre.33",
"@saleor/sdk": "^0.4.4",
"@sentry/react": "^6.0.0",
"@types/faker": "^5.1.6",
@ -6587,9 +6587,9 @@
}
},
"node_modules/@saleor/macaw-ui": {
"version": "0.8.0-pre.31",
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.31.tgz",
"integrity": "sha512-6BtXjF0snDFoj7c9mB2FeHnBPKoN1j0ZJnumqiGvdtzlESz4cgBhMZsbDk8BTQU5+C52PC+FWObDiKC73yjQJQ==",
"version": "0.8.0-pre.33",
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.33.tgz",
"integrity": "sha512-1ePo+aPJQWox8DJ4JM7QPEtfuz7x6F7jKA772sQgCoHP6t2IHsHnVBxAFaUZRFCR6xlW78WQLTVkLGiFYpbkPg==",
"dependencies": {
"@floating-ui/react-dom-interactions": "^0.5.0",
"clsx": "^1.1.1",
@ -39343,9 +39343,9 @@
}
},
"@saleor/macaw-ui": {
"version": "0.8.0-pre.31",
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.31.tgz",
"integrity": "sha512-6BtXjF0snDFoj7c9mB2FeHnBPKoN1j0ZJnumqiGvdtzlESz4cgBhMZsbDk8BTQU5+C52PC+FWObDiKC73yjQJQ==",
"version": "0.8.0-pre.33",
"resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-0.8.0-pre.33.tgz",
"integrity": "sha512-1ePo+aPJQWox8DJ4JM7QPEtfuz7x6F7jKA772sQgCoHP6t2IHsHnVBxAFaUZRFCR6xlW78WQLTVkLGiFYpbkPg==",
"requires": {
"@floating-ui/react-dom-interactions": "^0.5.0",
"clsx": "^1.1.1",

View file

@ -33,7 +33,7 @@
"@material-ui/lab": "^4.0.0-alpha.61",
"@material-ui/styles": "^4.11.4",
"@reach/auto-id": "^0.16.0",
"@saleor/macaw-ui": "^0.8.0-pre.31",
"@saleor/macaw-ui": "^0.8.0-pre.33",
"@saleor/sdk": "^0.4.4",
"@sentry/react": "^6.0.0",
"@types/faker": "^5.1.6",

View file

@ -71,7 +71,7 @@ function searchInViews(
url: orderListUrl(),
},
{
label: intl.formatMessage(sectionNames.pages),
label: intl.formatMessage(sectionNames.content),
url: pageListUrl(),
},
{

View file

@ -1,22 +1,39 @@
import { Box, List, Text } from "@saleor/macaw-ui/next";
import { Box, List, sprinkles, Text } from "@saleor/macaw-ui/next";
import React from "react";
import { Link } from "react-router-dom";
import { MenuItem } from "./Item";
import { SidebarMenuItem } from "./types";
import { isMenuActive } from "./utils";
interface Props {
menuItem: SidebarMenuItem;
}
export const ItemGroup: React.FC<Props> = ({ menuItem }) => (
<List.ItemGroup>
export const ItemGroup: React.FC<Props> = ({ menuItem }) => {
const hasSubmenuActive = menuItem?.children.some(item =>
isMenuActive(location.pathname, item),
);
const isActive =
isMenuActive(location.pathname, menuItem) && !hasSubmenuActive;
const isExpanded = isActive || hasSubmenuActive;
return (
<List.ItemGroup defaultExpanded={isExpanded}>
<List.ItemGroup.Trigger
paddingX={5}
paddingY={4}
borderRadius={3}
size="small"
active={isActive}
justifyContent="space-between"
data-test-id={`menu-item-label-${menuItem.id}`}
>
<Link
to={menuItem?.url ?? ""}
className={sprinkles({
width: "100%",
})}
>
<Box display="flex" alignItems="center" gap={6}>
{menuItem.icon}
@ -24,6 +41,7 @@ export const ItemGroup: React.FC<Props> = ({ menuItem }) => (
{menuItem.label}
</Text>
</Box>
</Link>
</List.ItemGroup.Trigger>
<List.ItemGroup.Content>
<Box
@ -45,3 +63,4 @@ export const ItemGroup: React.FC<Props> = ({ menuItem }) => (
</List.ItemGroup.Content>
</List.ItemGroup>
);
};

View file

@ -107,13 +107,6 @@ export function useMenuStructure() {
},
{
children: [
{
label: intl.formatMessage(sectionNames.products),
id: "products",
url: productListUrl(),
permissions: [PermissionEnum.MANAGE_PRODUCTS],
type: "item",
},
{
label: intl.formatMessage(sectionNames.categories),
id: "categories",
@ -141,6 +134,7 @@ export function useMenuStructure() {
),
],
icon: <ProductsIcons {...iconSettings} />,
url: productListUrl(),
label: intl.formatMessage(commonMessages.products),
permissions: [
PermissionEnum.MANAGE_GIFT_CARD,
@ -149,19 +143,8 @@ export function useMenuStructure() {
id: "products",
type: "itemGroup",
},
{
id: "divider-1",
type: "divider",
},
{
children: [
{
label: intl.formatMessage(sectionNames.orders),
permissions: [PermissionEnum.MANAGE_ORDERS],
id: "orders",
url: orderListUrl(),
type: "item",
},
{
label: intl.formatMessage(commonMessages.drafts),
permissions: [PermissionEnum.MANAGE_ORDERS],
@ -178,6 +161,7 @@ export function useMenuStructure() {
label: intl.formatMessage(sectionNames.orders),
permissions: [PermissionEnum.MANAGE_ORDERS],
id: "orders",
url: orderListUrl(),
type: "itemGroup",
},
{
@ -201,15 +185,8 @@ export function useMenuStructure() {
url: customerListUrl(),
type: !isEmpty(extensions.NAVIGATION_CUSTOMERS) ? "itemGroup" : "item",
},
{
children: [
{
label: intl.formatMessage(sectionNames.sales),
id: "sales",
url: saleListUrl(),
type: "item",
},
{
label: intl.formatMessage(sectionNames.vouchers),
id: "vouchers",
@ -224,44 +201,26 @@ export function useMenuStructure() {
icon: <VouchersIcon {...iconSettings} />,
label: intl.formatMessage(commonMessages.discounts),
permissions: [PermissionEnum.MANAGE_DISCOUNTS],
url: saleListUrl(),
id: "discounts",
type: "itemGroup",
},
{
id: "divider-2",
type: "divider",
},
{
children: !isEmpty(extensions.NAVIGATION_PAGES) && [
{
label: intl.formatMessage(sectionNames.pages),
permissions: [PermissionEnum.MANAGE_PAGES],
id: "pages",
url: pageListPath,
type: "item",
},
...mapToExtensionsItems(
extensions.NAVIGATION_PAGES,
appExtensionsHeaderItem,
),
],
icon: <StorefrontIcon {...iconSettings} />,
label: intl.formatMessage(sectionNames.pages),
label: intl.formatMessage(sectionNames.content),
permissions: [PermissionEnum.MANAGE_PAGES],
id: "pages",
url: pageListPath,
type: !isEmpty(extensions.NAVIGATION_PAGES) ? "itemGroup" : "item",
},
getAppSection(),
{
children: !isEmpty(extensions.NAVIGATION_TRANSLATIONS) && [
{
label: intl.formatMessage(sectionNames.translations),
permissions: [PermissionEnum.MANAGE_TRANSLATIONS],
id: "translations",
url: languageListUrl,
type: "item",
},
...mapToExtensionsItems(
extensions.NAVIGATION_TRANSLATIONS,
appExtensionsHeaderItem,
@ -274,10 +233,7 @@ export function useMenuStructure() {
url: languageListUrl,
type: !isEmpty(extensions.NAVIGATION_TRANSLATIONS) ? "itemGroup" : "item",
},
{
id: "divider-3",
type: "divider",
},
getAppSection(),
{
icon: <ConfigurationIcon {...iconSettings} />,
label: intl.formatMessage(sectionNames.configuration),

View file

@ -31,7 +31,7 @@ export function isMenuActive(location: string, menuItem: SidebarMenuItem) {
return false;
}
const activeUrl = location.split("?")[0];
const activeUrl = getPureUrl(location.split("?")[0]);
const menuItemUrl = menuItem.url.split("?")[0];
if (isMenuItemExtension(menuItem)) {
@ -51,6 +51,14 @@ export function isMenuActive(location: string, menuItem: SidebarMenuItem) {
});
}
const getPureUrl = (url: string) => {
if (url.includes("/dashboard")) {
return url.split("/dashboard")[1];
}
return url;
};
const isMenuItemExtension = (menuItem: SidebarMenuItem) =>
menuItem.id.startsWith("extension-");

View file

@ -103,8 +103,8 @@ const SaleCreatePage: React.FC<SaleCreatePageProps> = ({
<DetailPageLayout>
<TopNav
title={intl.formatMessage({
id: "2E1xZ0",
defaultMessage: "Create Sale",
id: "FWbv/u",
defaultMessage: "Create Discount",
description: "page header",
})}
/>

View file

@ -5,7 +5,7 @@ import FilterBar from "@dashboard/components/FilterBar";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { saleAddUrl, SaleListUrlSortField } from "@dashboard/discounts/urls";
import { SaleFragment } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { commonMessages } from "@dashboard/intl";
import {
ChannelProps,
FilterPageProps,
@ -55,15 +55,15 @@ const SaleListPage: React.FC<SaleListPageProps> = ({
return (
<ListPageLayout>
<TopNav title={intl.formatMessage(sectionNames.sales)}>
<TopNav title={intl.formatMessage(commonMessages.discounts)}>
<Button
href={saleAddUrl()}
variant="primary"
data-test-id="create-sale"
>
<FormattedMessage
id="JHfbXR"
defaultMessage="Create Sale"
id="+MJW+8"
defaultMessage="Create Discount"
description="button"
/>
</Button>
@ -71,16 +71,16 @@ const SaleListPage: React.FC<SaleListPageProps> = ({
<Card>
<FilterBar
allTabLabel={intl.formatMessage({
id: "Yjhgle",
defaultMessage: "All Sales",
id: "c8zJID",
defaultMessage: "All Discounts",
description: "tab name",
})}
currentTab={currentTab}
filterStructure={structure}
initialSearch={initialSearch}
searchPlaceholder={intl.formatMessage({
id: "MSD3A/",
defaultMessage: "Search Sale",
id: "lit2zF",
defaultMessage: "Search Discounts",
})}
tabs={tabs}
onAll={onAll}

View file

@ -20,7 +20,7 @@ import {
import useChannels from "@dashboard/hooks/useChannels";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { sectionNames } from "@dashboard/intl";
import { commonMessages } from "@dashboard/intl";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import createMetadataCreateHandler from "@dashboard/utils/handlers/metadataCreateHandler";
import React from "react";
@ -46,9 +46,8 @@ export const SaleCreateView: React.FC<SaleCreateProps> = ({ params }) => {
>(navigate, params => saleAddUrl(params), params);
const { availableChannels } = useAppChannel(false);
const allChannels: ChannelSaleFormData[] = createSortedSaleData(
availableChannels,
);
const allChannels: ChannelSaleFormData[] =
createSortedSaleData(availableChannels);
const {
channelListElements,
@ -68,10 +67,8 @@ export const SaleCreateView: React.FC<SaleCreateProps> = ({ params }) => {
{ formId: SALE_CREATE_FORM_ID },
);
const [
updateChannels,
updateChannelsOpts,
] = useSaleChannelListingUpdateMutation({});
const [updateChannels, updateChannelsOpts] =
useSaleChannelListingUpdateMutation({});
const [saleCreate, saleCreateOpts] = useSaleCreateMutation({
onCompleted: data => {
@ -100,7 +97,7 @@ export const SaleCreateView: React.FC<SaleCreateProps> = ({ params }) => {
return (
<>
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />
<WindowTitle title={intl.formatMessage(commonMessages.discounts)} />
{!!allChannels?.length && (
<ChannelsAvailabilityDialog
isSelected={isChannelSelected}

View file

@ -42,7 +42,7 @@ import useLocalStorage from "@dashboard/hooks/useLocalStorage";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
import { PaginatorContext } from "@dashboard/hooks/usePaginator";
import { commonMessages, sectionNames } from "@dashboard/intl";
import { commonMessages } from "@dashboard/intl";
import { maybe } from "@dashboard/misc";
import useCategorySearch from "@dashboard/searches/useCategorySearch";
import useCollectionSearch from "@dashboard/searches/useCollectionSearch";
@ -136,10 +136,8 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
SaleUrlQueryParams
>(navigate, params => saleUrl(id, params), params);
const allChannels: ChannelSaleData[] = createChannelsDataWithSaleDiscountPrice(
data?.sale,
availableChannels,
);
const allChannels: ChannelSaleData[] =
createChannelsDataWithSaleDiscountPrice(data?.sale, availableChannels);
const saleChannelsChoices = createSortedChannelsDataFromSale(data?.sale);
const {
@ -188,10 +186,8 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
},
});
const [
saleCataloguesAdd,
saleCataloguesAddOpts,
] = useSaleCataloguesAddMutation({
const [saleCataloguesAdd, saleCataloguesAddOpts] =
useSaleCataloguesAddMutation({
onCompleted: data => {
if (data.saleCataloguesAdd.errors.length === 0) {
notifySaved();
@ -200,10 +196,8 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
},
});
const [
saleCataloguesRemove,
saleCataloguesRemoveOpts,
] = useSaleCataloguesRemoveMutation({
const [saleCataloguesRemove, saleCataloguesRemoveOpts] =
useSaleCataloguesRemoveMutation({
onCompleted: data => {
if (data.saleCataloguesRemove.errors.length === 0) {
notifySaved();
@ -298,7 +292,7 @@ export const SaleDetails: React.FC<SaleDetailsProps> = ({ id, params }) => {
return (
<PaginatorContext.Provider value={{ ...pageInfo, ...paginationValues }}>
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />
<WindowTitle title={intl.formatMessage(commonMessages.discounts)} />
{!!allChannels?.length && (
<ChannelsAvailabilityDialog
isSelected={isChannelSelected}

View file

@ -18,7 +18,7 @@ import usePaginator, {
createPaginationState,
PaginatorContext,
} from "@dashboard/hooks/usePaginator";
import { commonMessages, sectionNames } from "@dashboard/intl";
import { commonMessages } from "@dashboard/intl";
import { maybe } from "@dashboard/misc";
import { ListViews } from "@dashboard/types";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
@ -98,11 +98,8 @@ export const SaleList: React.FC<SaleListProps> = ({ params }) => {
const currentTab = getFiltersCurrentTab(params, tabs);
const [
changeFilters,
resetFilters,
handleSearchChange,
] = createFilterHandlers({
const [changeFilters, resetFilters, handleSearchChange] =
createFilterHandlers({
cleanupFn: reset,
createUrl: saleListUrl,
getFilterQueryParam,
@ -175,7 +172,7 @@ export const SaleList: React.FC<SaleListProps> = ({ params }) => {
return (
<PaginatorContext.Provider value={paginationValues}>
<WindowTitle title={intl.formatMessage(sectionNames.sales)} />
<WindowTitle title={intl.formatMessage(commonMessages.discounts)} />
<SaleListPage
currentTab={currentTab}
filterOpts={getFilterOpts(params, channelOpts)}

View file

@ -455,6 +455,11 @@ export const sectionNames = defineMessages({
defaultMessage: "Pages",
description: "pages section name",
},
content: {
id: "NelCIl",
defaultMessage: "Content",
description: "content section name",
},
permissionGroups: {
id: "DNTxWr",
defaultMessage: "Permission Groups",

View file

@ -39,11 +39,11 @@ const PageListPage: React.FC<PageListPageProps> = ({
return (
<>
<TopNav title={intl.formatMessage(sectionNames.pages)}>
<TopNav title={intl.formatMessage(sectionNames.content)}>
<Button onClick={onAdd} variant="primary" data-test-id="create-page">
<FormattedMessage
id="AHRDWt"
defaultMessage="Create page"
id="DOVEZF"
defaultMessage="Create content"
description="button"
/>
</Button>

View file

@ -63,11 +63,8 @@ const PageListSearchAndFilters: React.FC<PageListSearchAndFiltersProps> = ({
},
});
const [
changeFilters,
resetFilters,
handleSearchChange,
] = createFilterHandlers({
const [changeFilters, resetFilters, handleSearchChange] =
createFilterHandlers({
createUrl: pageListUrl,
getFilterQueryParam,
navigate,
@ -111,7 +108,7 @@ const PageListSearchAndFilters: React.FC<PageListSearchAndFiltersProps> = ({
onFilterChange={changeFilters}
onSearchChange={handleSearchChange}
searchPlaceholder={intl.formatMessage(messages.searchPlaceholder)}
allTabLabel={"All Pages"}
allTabLabel={"All Content"}
tabs={tabs.map(({ name }) => name)}
currentTab={currentTab}
onTabDelete={handleTabDelete}

View file

@ -2,8 +2,8 @@ import { defineMessages } from "react-intl";
export const pagesListSearchAndFiltersMessages = defineMessages({
searchPlaceholder: {
id: "UW1fLs",
defaultMessage: "Search Pages",
description: "search pages placeholder",
id: "nP8iex",
defaultMessage: "Search Content",
description: "search content placeholder",
},
});

View file

@ -58,7 +58,7 @@ const Component = () => {
return (
<>
<WindowTitle title={intl.formatMessage(sectionNames.pages)} />
<WindowTitle title={intl.formatMessage(sectionNames.content)} />
<Switch>
<Route exact path={pageListPath} component={PageList} />
<Route exact path={pageCreatePath} component={PageCreate} />