Merge pull request #1309 from mirumee/fix-gift-cards-currencies-select
Fix gift cards currencies select and some minor bugs
This commit is contained in:
commit
12e4ff35ca
9 changed files with 136 additions and 34 deletions
|
@ -28,7 +28,7 @@ export const useAuth = () => {
|
||||||
const isAuthenticated = !!user.user;
|
const isAuthenticated = !!user.user;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasToken: !!getTokens(),
|
hasToken: !!getTokens().auth,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
tokenAuthLoading: user.tokenAuthLoading,
|
tokenAuthLoading: user.tokenAuthLoading,
|
||||||
tokenVerifyLoading: user.tokenVerifyLoading,
|
tokenVerifyLoading: user.tokenVerifyLoading,
|
||||||
|
|
|
@ -50,30 +50,33 @@ function createMenuStructure(intl: IntlShape, user: User): SidebarMenuItem[] {
|
||||||
ariaLabel: "products",
|
ariaLabel: "products",
|
||||||
label: intl.formatMessage(sectionNames.products),
|
label: intl.formatMessage(sectionNames.products),
|
||||||
id: "products",
|
id: "products",
|
||||||
url: productListUrl()
|
url: productListUrl(),
|
||||||
|
permissions: [PermissionEnum.MANAGE_PRODUCTS]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ariaLabel: "categories",
|
ariaLabel: "categories",
|
||||||
label: intl.formatMessage(sectionNames.categories),
|
label: intl.formatMessage(sectionNames.categories),
|
||||||
id: "categories",
|
id: "categories",
|
||||||
url: categoryListUrl()
|
url: categoryListUrl(),
|
||||||
|
permissions: [PermissionEnum.MANAGE_PRODUCTS]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ariaLabel: "collections",
|
ariaLabel: "collections",
|
||||||
label: intl.formatMessage(sectionNames.collections),
|
label: intl.formatMessage(sectionNames.collections),
|
||||||
id: "collections",
|
id: "collections",
|
||||||
url: collectionListUrl()
|
url: collectionListUrl(),
|
||||||
|
permissions: [PermissionEnum.MANAGE_PRODUCTS]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ariaLabel: "giftCards",
|
ariaLabel: "giftCards",
|
||||||
label: intl.formatMessage(sectionNames.giftCards),
|
label: intl.formatMessage(sectionNames.giftCards),
|
||||||
id: "giftCards",
|
id: "giftCards",
|
||||||
url: giftCardsListUrl()
|
url: giftCardsListUrl(),
|
||||||
|
permissions: [PermissionEnum.MANAGE_GIFT_CARD]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
iconSrc: catalogIcon,
|
iconSrc: catalogIcon,
|
||||||
label: intl.formatMessage(commonMessages.catalog),
|
label: intl.formatMessage(commonMessages.catalog),
|
||||||
permissions: [PermissionEnum.MANAGE_PRODUCTS],
|
|
||||||
id: "catalogue"
|
id: "catalogue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -160,12 +163,30 @@ function createMenuStructure(intl: IntlShape, user: User): SidebarMenuItem[] {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
return menuItems.filter(
|
const isMenuItemPermitted = (menuItem: FilterableMenuItem) =>
|
||||||
menuItem =>
|
!menuItem.permissions ||
|
||||||
!menuItem.permissions ||
|
(user?.userPermissions || []).some(permission =>
|
||||||
(user?.userPermissions || []).some(permission =>
|
menuItem.permissions.includes(permission.code)
|
||||||
menuItem.permissions.includes(permission.code)
|
);
|
||||||
)
|
|
||||||
|
const getFilteredMenuItems = (menuItems: FilterableMenuItem[]) =>
|
||||||
|
menuItems.filter(isMenuItemPermitted);
|
||||||
|
|
||||||
|
return menuItems.reduce(
|
||||||
|
(resultItems: FilterableMenuItem[], menuItem: FilterableMenuItem) => {
|
||||||
|
const { children } = menuItem;
|
||||||
|
|
||||||
|
if (!isMenuItemPermitted(menuItem)) {
|
||||||
|
return resultItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredChildren = children
|
||||||
|
? getFilteredMenuItems(children)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return [...resultItems, { ...menuItem, children: filteredChildren }];
|
||||||
|
},
|
||||||
|
[] as FilterableMenuItem[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ const Skeleton: React.FC<SkeletonProps> = props => {
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
|
|
||||||
return children ? (
|
return children ? (
|
||||||
(children as React.ReactElement)
|
<>{children}</>
|
||||||
) : (
|
) : (
|
||||||
<span
|
<span
|
||||||
data-test-id="skeleton"
|
data-test-id="skeleton"
|
||||||
|
|
39
src/giftCards/GiftCardCreateDialog/ContentWithProgress.tsx
Normal file
39
src/giftCards/GiftCardCreateDialog/ContentWithProgress.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { CircularProgress } from "@material-ui/core";
|
||||||
|
import { makeStyles } from "@saleor/macaw-ui";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
interface ContentWithProgressProps {
|
||||||
|
containerClassName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useStyles = makeStyles(
|
||||||
|
theme => ({
|
||||||
|
container: {
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
padding: theme.spacing
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{ name: "ContentWithProgress" }
|
||||||
|
);
|
||||||
|
|
||||||
|
const ContentWithProgress: React.FC<ContentWithProgressProps> = ({
|
||||||
|
containerClassName,
|
||||||
|
children
|
||||||
|
}) => {
|
||||||
|
const classes = useStyles({});
|
||||||
|
|
||||||
|
return children ? (
|
||||||
|
<>{children}</>
|
||||||
|
) : (
|
||||||
|
<div className={classNames(classes.container, containerClassName)}>
|
||||||
|
<CircularProgress />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ContentWithProgress;
|
|
@ -6,12 +6,14 @@ import commonErrorMessages from "@saleor/utils/errors/common";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import ContentWithProgress from "./ContentWithProgress";
|
||||||
import GiftCardCreateDialogCodeContent from "./GiftCardCreateDialogCodeContent";
|
import GiftCardCreateDialogCodeContent from "./GiftCardCreateDialogCodeContent";
|
||||||
import GiftCardCreateDialogForm, {
|
import GiftCardCreateDialogForm, {
|
||||||
GiftCardCreateFormData
|
GiftCardCreateFormData
|
||||||
} from "./GiftCardCreateDialogForm";
|
} from "./GiftCardCreateDialogForm";
|
||||||
import { giftCardCreateDialogMessages as messages } from "./messages";
|
import { giftCardCreateDialogMessages as messages } from "./messages";
|
||||||
import { useGiftCardCreateMutation } from "./mutations";
|
import { useGiftCardCreateMutation } from "./mutations";
|
||||||
|
import { useChannelCurrencies } from "./queries";
|
||||||
import { GiftCardCreate } from "./types/GiftCardCreate";
|
import { GiftCardCreate } from "./types/GiftCardCreate";
|
||||||
import { getGiftCardExpirySettingsInputData } from "./utils";
|
import { getGiftCardExpirySettingsInputData } from "./utils";
|
||||||
|
|
||||||
|
@ -27,6 +29,11 @@ const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: channelCurrenciesData,
|
||||||
|
loading: loadingChannelCurrencies
|
||||||
|
} = useChannelCurrencies({});
|
||||||
|
|
||||||
const [cardCode, setCardCode] = useState(null);
|
const [cardCode, setCardCode] = useState(null);
|
||||||
|
|
||||||
const onCompleted = (data: GiftCardCreate) => {
|
const onCompleted = (data: GiftCardCreate) => {
|
||||||
|
@ -94,19 +101,23 @@ const GiftCardCreateDialog: React.FC<GiftCardCreateDialogProps> = ({
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} maxWidth="sm">
|
<Dialog open={open} maxWidth="sm">
|
||||||
<DialogTitle>{intl.formatMessage(messages.title)}</DialogTitle>
|
<DialogTitle>{intl.formatMessage(messages.title)}</DialogTitle>
|
||||||
{cardCode ? (
|
<ContentWithProgress>
|
||||||
<GiftCardCreateDialogCodeContent
|
{!loadingChannelCurrencies &&
|
||||||
cardCode={cardCode}
|
(cardCode ? (
|
||||||
onClose={handleClose}
|
<GiftCardCreateDialogCodeContent
|
||||||
/>
|
cardCode={cardCode}
|
||||||
) : (
|
onClose={handleClose}
|
||||||
<GiftCardCreateDialogForm
|
/>
|
||||||
opts={createGiftCardOpts}
|
) : (
|
||||||
onClose={handleClose}
|
<GiftCardCreateDialogForm
|
||||||
apiErrors={createGiftCardOpts?.data?.giftCardCreate?.errors}
|
channelCurrencies={channelCurrenciesData?.shop?.channelCurrencies}
|
||||||
onSubmit={handleSubmit}
|
opts={createGiftCardOpts}
|
||||||
/>
|
onClose={handleClose}
|
||||||
)}
|
apiErrors={createGiftCardOpts?.data?.giftCardCreate?.errors}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ContentWithProgress>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,6 @@ import { GiftCardError } from "@saleor/fragments/types/GiftCardError";
|
||||||
import GiftCardExpirySelect from "@saleor/giftCards/components/GiftCardExpirySelect";
|
import GiftCardExpirySelect from "@saleor/giftCards/components/GiftCardExpirySelect";
|
||||||
import GiftCardTagInput from "@saleor/giftCards/components/GiftCardTagInput";
|
import GiftCardTagInput from "@saleor/giftCards/components/GiftCardTagInput";
|
||||||
import useForm from "@saleor/hooks/useForm";
|
import useForm from "@saleor/hooks/useForm";
|
||||||
import useShop from "@saleor/hooks/useShop";
|
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
import { ConfirmButtonTransitionState } from "@saleor/macaw-ui";
|
||||||
import Label from "@saleor/orders/components/OrderHistory/Label";
|
import Label from "@saleor/orders/components/OrderHistory/Label";
|
||||||
|
@ -49,20 +48,20 @@ interface GiftCardCreateDialogFormProps {
|
||||||
apiErrors: GiftCardError[];
|
apiErrors: GiftCardError[];
|
||||||
onSubmit: (data: GiftCardCreateFormData) => void;
|
onSubmit: (data: GiftCardCreateFormData) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
channelCurrencies: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
opts,
|
opts,
|
||||||
onClose,
|
onClose,
|
||||||
apiErrors
|
apiErrors,
|
||||||
|
channelCurrencies
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const shop = useShop();
|
|
||||||
|
|
||||||
// TEMP
|
const initialCurrency = channelCurrencies[0];
|
||||||
const initialCurrency = shop?.channelCurrencies?.[0];
|
|
||||||
|
|
||||||
const [selectedCustomer, setSelectedCustomer] = useState<
|
const [selectedCustomer, setSelectedCustomer] = useState<
|
||||||
GiftCardCreateFormCustomer
|
GiftCardCreateFormCustomer
|
||||||
|
@ -105,7 +104,7 @@ const GiftCardCreateDialogForm: React.FC<GiftCardCreateDialogFormProps> = ({
|
||||||
isError={!!formErrors?.balance}
|
isError={!!formErrors?.balance}
|
||||||
helperText={getGiftCardErrorMessage(formErrors?.balance, intl)}
|
helperText={getGiftCardErrorMessage(formErrors?.balance, intl)}
|
||||||
change={change}
|
change={change}
|
||||||
choices={mapSingleValueNodeToChoice(shop?.channelCurrencies)}
|
choices={mapSingleValueNodeToChoice(channelCurrencies)}
|
||||||
containerClassName={classes.balanceContainer}
|
containerClassName={classes.balanceContainer}
|
||||||
textFieldProps={{
|
textFieldProps={{
|
||||||
type: "number",
|
type: "number",
|
||||||
|
|
15
src/giftCards/GiftCardCreateDialog/queries.ts
Normal file
15
src/giftCards/GiftCardCreateDialog/queries.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import makeQuery from "@saleor/hooks/makeQuery";
|
||||||
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
|
import { ChannelCurrencies } from "./types/ChannelCurrencies";
|
||||||
|
|
||||||
|
const channelCurrencies = gql`
|
||||||
|
query ChannelCurrencies {
|
||||||
|
shop {
|
||||||
|
channelCurrencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const useChannelCurrencies = makeQuery<ChannelCurrencies, {}>(
|
||||||
|
channelCurrencies
|
||||||
|
);
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: ChannelCurrencies
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface ChannelCurrencies_shop {
|
||||||
|
__typename: "Shop";
|
||||||
|
channelCurrencies: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChannelCurrencies {
|
||||||
|
shop: ChannelCurrencies_shop;
|
||||||
|
}
|
|
@ -144,6 +144,7 @@ const Routes: React.FC = () => {
|
||||||
tokenVerifyLoading,
|
tokenVerifyLoading,
|
||||||
user
|
user
|
||||||
} = useAuth();
|
} = useAuth();
|
||||||
|
|
||||||
const { channel } = useAppChannel(false);
|
const { channel } = useAppChannel(false);
|
||||||
|
|
||||||
const channelLoaded = typeof channel !== "undefined";
|
const channelLoaded = typeof channel !== "undefined";
|
||||||
|
@ -193,8 +194,7 @@ const Routes: React.FC = () => {
|
||||||
component={CustomerSection}
|
component={CustomerSection}
|
||||||
/>
|
/>
|
||||||
<SectionRoute
|
<SectionRoute
|
||||||
/* add after backend adds the permission to schema */
|
permissions={[PermissionEnum.MANAGE_GIFT_CARD]}
|
||||||
// permissions={[]}
|
|
||||||
path={giftCardsSectionUrlName}
|
path={giftCardsSectionUrlName}
|
||||||
component={GiftCardSection}
|
component={GiftCardSection}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue