Add no warehouses info in variant and product details
This commit is contained in:
parent
4cb5a1114c
commit
6065c5ded6
22 changed files with 370 additions and 120 deletions
|
@ -304,7 +304,7 @@
|
||||||
},
|
},
|
||||||
"productVariantCreatorWarehouseSectionDescription": {
|
"productVariantCreatorWarehouseSectionDescription": {
|
||||||
"context": "no warehouses info",
|
"context": "no warehouses info",
|
||||||
"string": "There are no warehouses set up for your store. You can configure your variants without providing stock quantites."
|
"string": "There are no warehouses set up for your store. You can configure variants without providing stock quantities."
|
||||||
},
|
},
|
||||||
"productVariantCreatorWarehouseSectionHeader": {
|
"productVariantCreatorWarehouseSectionHeader": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
|
@ -314,6 +314,22 @@
|
||||||
"context": "optional field",
|
"context": "optional field",
|
||||||
"string": "Optional"
|
"string": "Optional"
|
||||||
},
|
},
|
||||||
|
"productVariantWarehouseSectionDescription": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "There are no warehouses set up for your store. To add stock quantity to the variant please"
|
||||||
|
},
|
||||||
|
"productVariantWarehouseSectionDescriptionLink": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "configure a warehouse"
|
||||||
|
},
|
||||||
|
"productWarehouseSectionDescription": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "There are no warehouses set up for your store. To add stock quantity to the product please"
|
||||||
|
},
|
||||||
|
"productWarehouseSectionDescriptionLink": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "configure a warehouse"
|
||||||
|
},
|
||||||
"saleDetailsPageCategoriesQuantity": {
|
"saleDetailsPageCategoriesQuantity": {
|
||||||
"context": "number of categories",
|
"context": "number of categories",
|
||||||
"string": "Categories ({quantity})"
|
"string": "Categories ({quantity})"
|
||||||
|
@ -1577,6 +1593,10 @@
|
||||||
"context": "button",
|
"context": "button",
|
||||||
"string": "{languageName} - {languageCode}"
|
"string": "{languageName} - {languageCode}"
|
||||||
},
|
},
|
||||||
|
"src_dot_components_dot_LeaveScreenDialog_dot_3281163715": {
|
||||||
|
"context": "leaving screen warning message",
|
||||||
|
"string": "You're leaving this screen. Do you want to save previously made changes?"
|
||||||
|
},
|
||||||
"src_dot_components_dot_ListField_dot_3099331554": {
|
"src_dot_components_dot_ListField_dot_3099331554": {
|
||||||
"context": "button",
|
"context": "button",
|
||||||
"string": "Add"
|
"string": "Add"
|
||||||
|
|
|
@ -211,7 +211,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={updateResult.data?.categoryUpdate.errors || []}
|
errors={updateResult.data?.categoryUpdate.errors || []}
|
||||||
onAddCategory={() => navigate(categoryAddUrl(id))}
|
onAddCategory={() => navigate(categoryAddUrl(id))}
|
||||||
onAddProduct={() => navigate(productAddUrl)}
|
onAddProduct={() => navigate(productAddUrl())}
|
||||||
onBack={() =>
|
onBack={() =>
|
||||||
navigate(
|
navigate(
|
||||||
maybe(() => categoryUrl(data.category.parent.id), categoryListUrl())
|
maybe(() => categoryUrl(data.category.parent.id), categoryListUrl())
|
||||||
|
|
54
src/components/LeaveScreenDialog/LeaveScreenDialog.tsx
Normal file
54
src/components/LeaveScreenDialog/LeaveScreenDialog.tsx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Dialog from "@material-ui/core/Dialog";
|
||||||
|
import DialogActions from "@material-ui/core/DialogActions";
|
||||||
|
import DialogContent from "@material-ui/core/DialogContent";
|
||||||
|
import { buttonMessages } from "@saleor/intl";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
|
import ConfirmButton, { ConfirmButtonTransitionState } from "../ConfirmButton";
|
||||||
|
import Form from "../Form";
|
||||||
|
|
||||||
|
export interface LeaveScreenDialogProps {
|
||||||
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
|
open: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onSubmit: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LeaveScreenDialog: React.FC<LeaveScreenDialogProps> = ({
|
||||||
|
confirmButtonState,
|
||||||
|
onClose,
|
||||||
|
onSubmit,
|
||||||
|
open
|
||||||
|
}) => (
|
||||||
|
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
|
||||||
|
<Form onSubmit={onSubmit}>
|
||||||
|
{({ submit }) => (
|
||||||
|
<>
|
||||||
|
<DialogContent>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="You're leaving this screen. Do you want to save previously made changes?"
|
||||||
|
description="leaving screen warning message"
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={onClose}>
|
||||||
|
<FormattedMessage {...buttonMessages.cancel} />
|
||||||
|
</Button>
|
||||||
|
<ConfirmButton
|
||||||
|
transitionState={confirmButtonState}
|
||||||
|
color="primary"
|
||||||
|
variant="contained"
|
||||||
|
onClick={submit}
|
||||||
|
>
|
||||||
|
<FormattedMessage {...buttonMessages.save} />
|
||||||
|
</ConfirmButton>
|
||||||
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
LeaveScreenDialog.displayName = "LeaveScreenDialog";
|
||||||
|
export default LeaveScreenDialog;
|
2
src/components/LeaveScreenDialog/index.ts
Normal file
2
src/components/LeaveScreenDialog/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./LeaveScreenDialog";
|
||||||
|
export * from "./LeaveScreenDialog";
|
|
@ -46,7 +46,7 @@ export function searchInCommands(
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.createProduct),
|
label: intl.formatMessage(messages.createProduct),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
navigate(productAddUrl);
|
navigate(productAddUrl());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -101,6 +101,7 @@ interface ProductCreatePageProps {
|
||||||
fetchCategories: (data: string) => void;
|
fetchCategories: (data: string) => void;
|
||||||
fetchCollections: (data: string) => void;
|
fetchCollections: (data: string) => void;
|
||||||
fetchProductTypes: (data: string) => void;
|
fetchProductTypes: (data: string) => void;
|
||||||
|
onWarehouseConfigure: () => void;
|
||||||
onBack?();
|
onBack?();
|
||||||
onSubmit?(data: ProductCreatePageSubmitData);
|
onSubmit?(data: ProductCreatePageSubmitData);
|
||||||
}
|
}
|
||||||
|
@ -122,6 +123,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
||||||
warehouses,
|
warehouses,
|
||||||
taxTypes,
|
taxTypes,
|
||||||
onBack,
|
onBack,
|
||||||
|
onWarehouseConfigure,
|
||||||
fetchProductTypes,
|
fetchProductTypes,
|
||||||
weightUnit,
|
weightUnit,
|
||||||
onSubmit
|
onSubmit
|
||||||
|
@ -297,6 +299,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
||||||
<ProductStocks
|
<ProductStocks
|
||||||
data={data}
|
data={data}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
hasVariants={false}
|
||||||
onFormDataChange={change}
|
onFormDataChange={change}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
stocks={stocks}
|
stocks={stocks}
|
||||||
|
@ -320,6 +323,7 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
||||||
triggerChange();
|
triggerChange();
|
||||||
removeStock(id);
|
removeStock(id);
|
||||||
}}
|
}}
|
||||||
|
onWarehouseConfigure={onWarehouseConfigure}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -21,6 +21,7 @@ import CardTitle from "@saleor/components/CardTitle";
|
||||||
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
|
import Link from "@saleor/components/Link";
|
||||||
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||||
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
|
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
@ -41,12 +42,14 @@ export interface ProductStocksProps {
|
||||||
data: ProductStockFormData;
|
data: ProductStockFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: ProductErrorFragment[];
|
||||||
|
hasVariants: boolean;
|
||||||
stocks: ProductStockInput[];
|
stocks: ProductStockInput[];
|
||||||
warehouses: WarehouseFragment[];
|
warehouses: WarehouseFragment[];
|
||||||
onChange: FormsetChange;
|
onChange: FormsetChange;
|
||||||
onFormDataChange: FormChange;
|
onFormDataChange: FormChange;
|
||||||
onWarehouseStockAdd: (warehouseId: string) => void;
|
onWarehouseStockAdd: (warehouseId: string) => void;
|
||||||
onWarehouseStockDelete: (warehouseId: string) => void;
|
onWarehouseStockDelete: (warehouseId: string) => void;
|
||||||
|
onWarehouseConfigure: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -75,6 +78,9 @@ const useStyles = makeStyles(
|
||||||
marginBottom: theme.spacing(2)
|
marginBottom: theme.spacing(2)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
noWarehouseInfo: {
|
||||||
|
marginTop: theme.spacing()
|
||||||
|
},
|
||||||
paper: {
|
paper: {
|
||||||
padding: theme.spacing(2)
|
padding: theme.spacing(2)
|
||||||
},
|
},
|
||||||
|
@ -105,13 +111,15 @@ const useStyles = makeStyles(
|
||||||
const ProductStocks: React.FC<ProductStocksProps> = ({
|
const ProductStocks: React.FC<ProductStocksProps> = ({
|
||||||
data,
|
data,
|
||||||
disabled,
|
disabled,
|
||||||
|
hasVariants,
|
||||||
errors,
|
errors,
|
||||||
stocks,
|
stocks,
|
||||||
warehouses,
|
warehouses,
|
||||||
onChange,
|
onChange,
|
||||||
onFormDataChange,
|
onFormDataChange,
|
||||||
onWarehouseStockAdd,
|
onWarehouseStockAdd,
|
||||||
onWarehouseStockDelete
|
onWarehouseStockDelete,
|
||||||
|
onWarehouseConfigure
|
||||||
}) => {
|
}) => {
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -178,108 +186,147 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
{!warehouses.length && (
|
||||||
|
<Typography color="textSecondary" className={classes.noWarehouseInfo}>
|
||||||
|
{hasVariants ? (
|
||||||
|
<>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the variant please"
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productVariantWarehouseSectionDescription"
|
||||||
|
/>{" "}
|
||||||
|
<Link onClick={onWarehouseConfigure}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="configure a warehouse"
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productVariantWarehouseSectionDescriptionLink"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the product please"
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productWarehouseSectionDescription"
|
||||||
|
/>{" "}
|
||||||
|
<Link onClick={onWarehouseConfigure}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="configure a warehouse"
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productWarehouseSectionDescriptionLink"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
<Table>
|
{warehouses.length > 0 && (
|
||||||
<TableHead>
|
<Table>
|
||||||
<TableRow>
|
<TableHead>
|
||||||
<TableCell className={classes.colName}>
|
<TableRow>
|
||||||
<FormattedMessage
|
<TableCell className={classes.colName}>
|
||||||
defaultMessage="Warehouse Name"
|
<FormattedMessage
|
||||||
description="tabel column header"
|
defaultMessage="Warehouse Name"
|
||||||
/>
|
description="tabel column header"
|
||||||
</TableCell>
|
|
||||||
<TableCell className={classes.colQuantity}>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Quantity Available"
|
|
||||||
description="tabel column header"
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className={classes.colAction} />
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<TableBody>
|
|
||||||
{renderCollection(stocks, stock => (
|
|
||||||
<TableRow key={stock.id}>
|
|
||||||
<TableCell className={classes.colName}>{stock.label}</TableCell>
|
|
||||||
<TableCell className={classes.colQuantity}>
|
|
||||||
<TextField
|
|
||||||
className={classes.inputComponent}
|
|
||||||
disabled={disabled}
|
|
||||||
fullWidth
|
|
||||||
inputProps={{
|
|
||||||
className: classes.input,
|
|
||||||
min: 0,
|
|
||||||
type: "number"
|
|
||||||
}}
|
|
||||||
onChange={event => onChange(stock.id, event.target.value)}
|
|
||||||
value={stock.value}
|
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={classes.colAction}>
|
<TableCell className={classes.colQuantity}>
|
||||||
<IconButton
|
<FormattedMessage
|
||||||
color="primary"
|
defaultMessage="Quantity Available"
|
||||||
onClick={() => onWarehouseStockDelete(stock.id)}
|
description="tabel column header"
|
||||||
>
|
/>
|
||||||
<DeleteIcon />
|
|
||||||
</IconButton>
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className={classes.colAction} />
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
</TableHead>
|
||||||
{warehousesToAssign.length > 0 && (
|
<TableBody>
|
||||||
<TableRow>
|
{renderCollection(stocks, stock => (
|
||||||
<TableCell colSpan={2}>
|
<TableRow key={stock.id}>
|
||||||
<Typography variant="body2">
|
<TableCell className={classes.colName}>{stock.label}</TableCell>
|
||||||
<FormattedMessage
|
<TableCell className={classes.colQuantity}>
|
||||||
defaultMessage="Assign Warehouse"
|
<TextField
|
||||||
description="button"
|
className={classes.inputComponent}
|
||||||
|
disabled={disabled}
|
||||||
|
fullWidth
|
||||||
|
inputProps={{
|
||||||
|
className: classes.input,
|
||||||
|
min: 0,
|
||||||
|
type: "number"
|
||||||
|
}}
|
||||||
|
onChange={event => onChange(stock.id, event.target.value)}
|
||||||
|
value={stock.value}
|
||||||
/>
|
/>
|
||||||
</Typography>
|
</TableCell>
|
||||||
</TableCell>
|
<TableCell className={classes.colAction}>
|
||||||
<TableCell className={classes.colAction}>
|
<IconButton
|
||||||
<ClickAwayListener onClickAway={() => setExpansionState(false)}>
|
color="primary"
|
||||||
<div ref={anchor}>
|
onClick={() => onWarehouseStockDelete(stock.id)}
|
||||||
<IconButton
|
>
|
||||||
color="primary"
|
<DeleteIcon />
|
||||||
onClick={() => setExpansionState(!isExpanded)}
|
</IconButton>
|
||||||
>
|
</TableCell>
|
||||||
<AddIcon />
|
</TableRow>
|
||||||
</IconButton>
|
))}
|
||||||
<Popper
|
{warehousesToAssign.length > 0 && (
|
||||||
className={classes.popper}
|
<TableRow>
|
||||||
open={isExpanded}
|
<TableCell colSpan={2}>
|
||||||
anchorEl={anchor.current}
|
<Typography variant="body2">
|
||||||
transition
|
<FormattedMessage
|
||||||
placement="top-end"
|
defaultMessage="Assign Warehouse"
|
||||||
>
|
description="button"
|
||||||
{({ TransitionProps }) => (
|
/>
|
||||||
<Grow
|
</Typography>
|
||||||
{...TransitionProps}
|
</TableCell>
|
||||||
style={{
|
<TableCell className={classes.colAction}>
|
||||||
transformOrigin: "right top"
|
<ClickAwayListener
|
||||||
}}
|
onClickAway={() => setExpansionState(false)}
|
||||||
>
|
>
|
||||||
<Paper className={classes.paper}>
|
<div ref={anchor}>
|
||||||
{warehousesToAssign.map(warehouse => (
|
<IconButton
|
||||||
<MenuItem
|
color="primary"
|
||||||
className={classes.menuItem}
|
onClick={() => setExpansionState(!isExpanded)}
|
||||||
onClick={() =>
|
>
|
||||||
onWarehouseStockAdd(warehouse.id)
|
<AddIcon />
|
||||||
}
|
</IconButton>
|
||||||
>
|
<Popper
|
||||||
{warehouse.name}
|
className={classes.popper}
|
||||||
</MenuItem>
|
open={isExpanded}
|
||||||
))}
|
anchorEl={anchor.current}
|
||||||
</Paper>
|
transition
|
||||||
</Grow>
|
placement="top-end"
|
||||||
)}
|
>
|
||||||
</Popper>
|
{({ TransitionProps }) => (
|
||||||
</div>
|
<Grow
|
||||||
</ClickAwayListener>
|
{...TransitionProps}
|
||||||
</TableCell>
|
style={{
|
||||||
</TableRow>
|
transformOrigin: "right top"
|
||||||
)}
|
}}
|
||||||
</TableBody>
|
>
|
||||||
</Table>
|
<Paper className={classes.paper}>
|
||||||
|
{warehousesToAssign.map(warehouse => (
|
||||||
|
<MenuItem
|
||||||
|
className={classes.menuItem}
|
||||||
|
onClick={() =>
|
||||||
|
onWarehouseStockAdd(warehouse.id)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{warehouse.name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Paper>
|
||||||
|
</Grow>
|
||||||
|
)}
|
||||||
|
</Popper>
|
||||||
|
</div>
|
||||||
|
</ClickAwayListener>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -87,6 +87,7 @@ export interface ProductUpdatePageProps extends ListActions {
|
||||||
onSubmit?(data: ProductUpdatePageSubmitData);
|
onSubmit?(data: ProductUpdatePageSubmitData);
|
||||||
onVariantAdd?();
|
onVariantAdd?();
|
||||||
onSetDefaultVariant();
|
onSetDefaultVariant();
|
||||||
|
onWarehouseConfigure();
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductUpdatePageSubmitData extends ProductUpdatePageFormData {
|
export interface ProductUpdatePageSubmitData extends ProductUpdatePageFormData {
|
||||||
|
@ -128,6 +129,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
onSetDefaultVariant,
|
onSetDefaultVariant,
|
||||||
onVariantShow,
|
onVariantShow,
|
||||||
onVariantReorder,
|
onVariantReorder,
|
||||||
|
onWarehouseConfigure,
|
||||||
isChecked,
|
isChecked,
|
||||||
selected,
|
selected,
|
||||||
toggle,
|
toggle,
|
||||||
|
@ -346,6 +348,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
<ProductStocks
|
<ProductStocks
|
||||||
data={data}
|
data={data}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
hasVariants={false}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
stocks={stocks}
|
stocks={stocks}
|
||||||
warehouses={warehouses}
|
warehouses={warehouses}
|
||||||
|
@ -369,6 +372,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
triggerChange();
|
triggerChange();
|
||||||
removeStock(id);
|
removeStock(id);
|
||||||
}}
|
}}
|
||||||
|
onWarehouseConfigure={onWarehouseConfigure}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -58,6 +58,7 @@ interface ProductVariantCreatePageProps {
|
||||||
onSubmit: (data: ProductVariantCreatePageSubmitData) => void;
|
onSubmit: (data: ProductVariantCreatePageSubmitData) => void;
|
||||||
onVariantClick: (variantId: string) => void;
|
onVariantClick: (variantId: string) => void;
|
||||||
onVariantReorder: ReorderAction;
|
onVariantReorder: ReorderAction;
|
||||||
|
onWarehouseConfigure: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
|
@ -72,7 +73,8 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
onBack,
|
onBack,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onVariantClick,
|
onVariantClick,
|
||||||
onVariantReorder
|
onVariantReorder,
|
||||||
|
onWarehouseConfigure
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const attributeInput = React.useMemo(
|
const attributeInput = React.useMemo(
|
||||||
|
@ -165,6 +167,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
<ProductStocks
|
<ProductStocks
|
||||||
data={data}
|
data={data}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
hasVariants={true}
|
||||||
onFormDataChange={change}
|
onFormDataChange={change}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
stocks={stocks}
|
stocks={stocks}
|
||||||
|
@ -187,6 +190,7 @@ const ProductVariantCreatePage: React.FC<ProductVariantCreatePageProps> = ({
|
||||||
triggerChange();
|
triggerChange();
|
||||||
removeStock(id);
|
removeStock(id);
|
||||||
}}
|
}}
|
||||||
|
onWarehouseConfigure={onWarehouseConfigure}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<Metadata data={data} onChange={changeMetadata} />
|
<Metadata data={data} onChange={changeMetadata} />
|
||||||
|
|
|
@ -126,7 +126,7 @@ const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = pr
|
||||||
{!warehouses.length ? (
|
{!warehouses.length ? (
|
||||||
<Typography color="textSecondary">
|
<Typography color="textSecondary">
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
defaultMessage="There are no warehouses set up for your store. You can configure your variants without providing stock quantites."
|
defaultMessage="There are no warehouses set up for your store. You can configure variants without providing stock quantities."
|
||||||
description="no warehouses info"
|
description="no warehouses info"
|
||||||
id="productVariantCreatorWarehouseSectionDescription"
|
id="productVariantCreatorWarehouseSectionDescription"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -70,6 +70,7 @@ interface ProductVariantPageProps {
|
||||||
onImageSelect(id: string);
|
onImageSelect(id: string);
|
||||||
onVariantClick(variantId: string);
|
onVariantClick(variantId: string);
|
||||||
onSetDefaultVariant();
|
onSetDefaultVariant();
|
||||||
|
onWarehouseConfigure();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
|
@ -88,7 +89,8 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onVariantClick,
|
onVariantClick,
|
||||||
onVariantReorder,
|
onVariantReorder,
|
||||||
onSetDefaultVariant
|
onSetDefaultVariant,
|
||||||
|
onWarehouseConfigure
|
||||||
}) => {
|
}) => {
|
||||||
const attributeInput = React.useMemo(
|
const attributeInput = React.useMemo(
|
||||||
() => getAttributeInputFromVariant(variant),
|
() => getAttributeInputFromVariant(variant),
|
||||||
|
@ -240,6 +242,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
<ProductStocks
|
<ProductStocks
|
||||||
data={data}
|
data={data}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
|
hasVariants={true}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
stocks={stocks}
|
stocks={stocks}
|
||||||
warehouses={warehouses}
|
warehouses={warehouses}
|
||||||
|
@ -263,6 +266,7 @@ const ProductVariantPage: React.FC<ProductVariantPageProps> = ({
|
||||||
triggerChange();
|
triggerChange();
|
||||||
removeStock(id);
|
removeStock(id);
|
||||||
}}
|
}}
|
||||||
|
onWarehouseConfigure={onWarehouseConfigure}
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<Metadata data={data} onChange={changeMetadata} />
|
<Metadata data={data} onChange={changeMetadata} />
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { Route, RouteComponentProps, Switch } from "react-router-dom";
|
||||||
import { WindowTitle } from "../components/WindowTitle";
|
import { WindowTitle } from "../components/WindowTitle";
|
||||||
import {
|
import {
|
||||||
productAddPath,
|
productAddPath,
|
||||||
|
ProductAddUrlQueryParams,
|
||||||
productImagePath,
|
productImagePath,
|
||||||
ProductImageUrlQueryParams,
|
ProductImageUrlQueryParams,
|
||||||
productListPath,
|
productListPath,
|
||||||
|
@ -17,11 +18,12 @@ import {
|
||||||
productPath,
|
productPath,
|
||||||
ProductUrlQueryParams,
|
ProductUrlQueryParams,
|
||||||
productVariantAddPath,
|
productVariantAddPath,
|
||||||
|
ProductVariantAddUrlQueryParams,
|
||||||
productVariantCreatorPath,
|
productVariantCreatorPath,
|
||||||
productVariantEditPath,
|
productVariantEditPath,
|
||||||
ProductVariantEditUrlQueryParams
|
ProductVariantEditUrlQueryParams
|
||||||
} from "./urls";
|
} from "./urls";
|
||||||
import ProductCreate from "./views/ProductCreate";
|
import ProductCreateComponent from "./views/ProductCreate";
|
||||||
import ProductImageComponent from "./views/ProductImage";
|
import ProductImageComponent from "./views/ProductImage";
|
||||||
import ProductListComponent from "./views/ProductList";
|
import ProductListComponent from "./views/ProductList";
|
||||||
import ProductUpdateComponent from "./views/ProductUpdate";
|
import ProductUpdateComponent from "./views/ProductUpdate";
|
||||||
|
@ -45,6 +47,13 @@ const ProductList: React.FC<RouteComponentProps<any>> = ({ location }) => {
|
||||||
return <ProductListComponent params={params} />;
|
return <ProductListComponent params={params} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ProductCreate: React.FC<RouteComponentProps> = () => {
|
||||||
|
const qs = parseQs(location.search.substr(1));
|
||||||
|
const params: ProductAddUrlQueryParams = qs;
|
||||||
|
|
||||||
|
return <ProductCreateComponent params={params} />;
|
||||||
|
};
|
||||||
|
|
||||||
const ProductUpdate: React.FC<RouteComponentProps<any>> = ({ match }) => {
|
const ProductUpdate: React.FC<RouteComponentProps<any>> = ({ match }) => {
|
||||||
const qs = parseQs(location.search.substr(1));
|
const qs = parseQs(location.search.substr(1));
|
||||||
const params: ProductUrlQueryParams = qs;
|
const params: ProductUrlQueryParams = qs;
|
||||||
|
@ -91,11 +100,17 @@ const ProductImage: React.FC<RouteComponentProps<any>> = ({
|
||||||
|
|
||||||
const ProductVariantCreate: React.FC<RouteComponentProps<any>> = ({
|
const ProductVariantCreate: React.FC<RouteComponentProps<any>> = ({
|
||||||
match
|
match
|
||||||
}) => (
|
}) => {
|
||||||
<ProductVariantCreateComponent
|
const qs = parseQs(location.search.substr(1));
|
||||||
productId={decodeURIComponent(match.params.id)}
|
const params: ProductVariantAddUrlQueryParams = qs;
|
||||||
/>
|
|
||||||
);
|
return (
|
||||||
|
<ProductVariantCreateComponent
|
||||||
|
productId={decodeURIComponent(match.params.id)}
|
||||||
|
params={params}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const ProductVariantCreator: React.FC<RouteComponentProps<{
|
const ProductVariantCreator: React.FC<RouteComponentProps<{
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -16,7 +16,10 @@ import { stringifyQs } from "../utils/urls";
|
||||||
const productSection = "/products/";
|
const productSection = "/products/";
|
||||||
|
|
||||||
export const productAddPath = urlJoin(productSection, "add");
|
export const productAddPath = urlJoin(productSection, "add");
|
||||||
export const productAddUrl = productAddPath;
|
export type ProductAddUrlDialog = "leave-screen";
|
||||||
|
export type ProductAddUrlQueryParams = Dialog<ProductAddUrlDialog>;
|
||||||
|
export const productAddUrl = (params?: ProductAddUrlQueryParams) =>
|
||||||
|
productAddPath + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const productListPath = productSection;
|
export const productListPath = productSection;
|
||||||
export type ProductListUrlDialog =
|
export type ProductListUrlDialog =
|
||||||
|
@ -66,14 +69,14 @@ export const productListUrl = (params?: ProductListUrlQueryParams): string =>
|
||||||
productListPath + "?" + stringifyQs(params);
|
productListPath + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const productPath = (id: string) => urlJoin(productSection + id);
|
export const productPath = (id: string) => urlJoin(productSection + id);
|
||||||
export type ProductUrlDialog = "remove" | "remove-variants";
|
export type ProductUrlDialog = "remove" | "remove-variants" | "leave-screen";
|
||||||
export type ProductUrlQueryParams = BulkAction & Dialog<ProductUrlDialog>;
|
export type ProductUrlQueryParams = BulkAction & Dialog<ProductUrlDialog>;
|
||||||
export const productUrl = (id: string, params?: ProductUrlQueryParams) =>
|
export const productUrl = (id: string, params?: ProductUrlQueryParams) =>
|
||||||
productPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
productPath(encodeURIComponent(id)) + "?" + stringifyQs(params);
|
||||||
|
|
||||||
export const productVariantEditPath = (productId: string, variantId: string) =>
|
export const productVariantEditPath = (productId: string, variantId: string) =>
|
||||||
urlJoin(productSection, productId, "variant", variantId);
|
urlJoin(productSection, productId, "variant", variantId);
|
||||||
export type ProductVariantEditUrlDialog = "remove";
|
export type ProductVariantEditUrlDialog = "remove" | "leave-screen";
|
||||||
export type ProductVariantEditUrlQueryParams = Dialog<
|
export type ProductVariantEditUrlQueryParams = Dialog<
|
||||||
ProductVariantEditUrlDialog
|
ProductVariantEditUrlDialog
|
||||||
>;
|
>;
|
||||||
|
@ -96,8 +99,17 @@ export const productVariantCreatorUrl = (productId: string) =>
|
||||||
|
|
||||||
export const productVariantAddPath = (productId: string) =>
|
export const productVariantAddPath = (productId: string) =>
|
||||||
urlJoin(productSection, productId, "variant/add");
|
urlJoin(productSection, productId, "variant/add");
|
||||||
export const productVariantAddUrl = (productId: string): string =>
|
export type ProductVariantAddUrlDialog = "leave-screen";
|
||||||
productVariantAddPath(encodeURIComponent(productId));
|
export type ProductVariantAddUrlQueryParams = Dialog<
|
||||||
|
ProductVariantAddUrlDialog
|
||||||
|
>;
|
||||||
|
export const productVariantAddUrl = (
|
||||||
|
productId: string,
|
||||||
|
params?: ProductVariantAddUrlQueryParams
|
||||||
|
): string =>
|
||||||
|
productVariantAddPath(encodeURIComponent(productId)) +
|
||||||
|
"?" +
|
||||||
|
stringifyQs(params);
|
||||||
|
|
||||||
export const productImagePath = (productId: string, imageId: string) =>
|
export const productImagePath = (productId: string, imageId: string) =>
|
||||||
urlJoin(productSection, productId, "image", imageId);
|
urlJoin(productSection, productId, "image", imageId);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
@ -8,12 +9,14 @@ import useCategorySearch from "@saleor/searches/useCategorySearch";
|
||||||
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
|
import useCollectionSearch from "@saleor/searches/useCollectionSearch";
|
||||||
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
|
import useProductTypeSearch from "@saleor/searches/useProductTypeSearch";
|
||||||
import { useTaxTypeList } from "@saleor/taxes/queries";
|
import { useTaxTypeList } from "@saleor/taxes/queries";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
||||||
import {
|
import {
|
||||||
useMetadataUpdate,
|
useMetadataUpdate,
|
||||||
usePrivateMetadataUpdate
|
usePrivateMetadataUpdate
|
||||||
} from "@saleor/utils/metadata/updateMetadata";
|
} from "@saleor/utils/metadata/updateMetadata";
|
||||||
import { useWarehouseList } from "@saleor/warehouses/queries";
|
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||||
|
import { warehouseListPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -25,9 +28,22 @@ import {
|
||||||
useProductCreateMutation,
|
useProductCreateMutation,
|
||||||
useProductSetAvailabilityForPurchase
|
useProductSetAvailabilityForPurchase
|
||||||
} from "../mutations";
|
} from "../mutations";
|
||||||
import { productListUrl, productUrl } from "../urls";
|
import {
|
||||||
|
productAddUrl,
|
||||||
|
ProductAddUrlDialog,
|
||||||
|
ProductAddUrlQueryParams,
|
||||||
|
productListUrl,
|
||||||
|
productUrl
|
||||||
|
} from "../urls";
|
||||||
|
|
||||||
export const ProductCreateView: React.FC = () => {
|
interface ProductCreateViewProps {
|
||||||
|
params: ProductAddUrlQueryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ProductCreateView: React.FC<ProductCreateViewProps> = ({
|
||||||
|
params
|
||||||
|
}) => {
|
||||||
|
const { action } = params;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const shop = useShop();
|
const shop = useShop();
|
||||||
|
@ -90,6 +106,11 @@ export const ProductCreateView: React.FC = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
|
ProductAddUrlDialog,
|
||||||
|
ProductAddUrlQueryParams
|
||||||
|
>(navigate, productAddUrl, params);
|
||||||
|
|
||||||
const handleCreate = async (formData: ProductCreatePageSubmitData) => {
|
const handleCreate = async (formData: ProductCreatePageSubmitData) => {
|
||||||
const result = await productCreate({
|
const result = await productCreate({
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -196,12 +217,19 @@ export const ProductCreateView: React.FC = () => {
|
||||||
loading: searchProductTypesOpts.loading,
|
loading: searchProductTypesOpts.loading,
|
||||||
onFetchMore: loadMoreProductTypes
|
onFetchMore: loadMoreProductTypes
|
||||||
}}
|
}}
|
||||||
|
onWarehouseConfigure={() => openModal("leave-screen")}
|
||||||
warehouses={
|
warehouses={
|
||||||
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
||||||
}
|
}
|
||||||
taxTypes={taxTypes.data?.taxTypes || []}
|
taxTypes={taxTypes.data?.taxTypes || []}
|
||||||
weightUnit={shop?.defaultWeightUnit}
|
weightUnit={shop?.defaultWeightUnit}
|
||||||
/>
|
/>
|
||||||
|
<LeaveScreenDialog
|
||||||
|
onSubmit={() => navigate(warehouseListPath)}
|
||||||
|
onClose={closeModal}
|
||||||
|
open={action === "leave-screen"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -344,7 +344,7 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
() => attributes.data.availableInGrid.pageInfo.hasNextPage,
|
() => attributes.data.availableInGrid.pageInfo.hasNextPage,
|
||||||
false
|
false
|
||||||
)}
|
)}
|
||||||
onAdd={() => navigate(productAddUrl)}
|
onAdd={() => navigate(productAddUrl())}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
products={maybe(() => data.products.edges.map(edge => edge.node))}
|
products={maybe(() => data.products.edges.map(edge => edge.node))}
|
||||||
onFetchMore={() =>
|
onFetchMore={() =>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import ActionDialog from "@saleor/components/ActionDialog";
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
|
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
|
||||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||||
|
@ -33,6 +34,7 @@ import {
|
||||||
usePrivateMetadataUpdate
|
usePrivateMetadataUpdate
|
||||||
} from "@saleor/utils/metadata/updateMetadata";
|
} from "@saleor/utils/metadata/updateMetadata";
|
||||||
import { useWarehouseList } from "@saleor/warehouses/queries";
|
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||||
|
import { warehouseListPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -64,6 +66,7 @@ interface ProductUpdateProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
|
export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
|
||||||
|
const { action } = params;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
|
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
|
||||||
|
@ -312,6 +315,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
|
||||||
onImageUpload={handleImageUpload}
|
onImageUpload={handleImageUpload}
|
||||||
onImageEdit={handleImageEdit}
|
onImageEdit={handleImageEdit}
|
||||||
onImageDelete={handleImageDelete}
|
onImageDelete={handleImageDelete}
|
||||||
|
onWarehouseConfigure={() => openModal("leave-screen")}
|
||||||
toolbar={
|
toolbar={
|
||||||
<IconButton
|
<IconButton
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -392,6 +396,12 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
|
||||||
/>
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
|
<LeaveScreenDialog
|
||||||
|
onSubmit={() => navigate(warehouseListPath)}
|
||||||
|
onClose={closeModal}
|
||||||
|
open={action === "leave-screen"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import placeholderImg from "@assets/images/placeholder255x255.png";
|
import placeholderImg from "@assets/images/placeholder255x255.png";
|
||||||
|
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
|
||||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
|
@ -13,6 +14,7 @@ import {
|
||||||
usePrivateMetadataUpdate
|
usePrivateMetadataUpdate
|
||||||
} from "@saleor/utils/metadata/updateMetadata";
|
} from "@saleor/utils/metadata/updateMetadata";
|
||||||
import { useWarehouseList } from "@saleor/warehouses/queries";
|
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||||
|
import { warehouseListPath } from "@saleor/warehouses/urls";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -51,6 +53,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
productId,
|
productId,
|
||||||
params
|
params
|
||||||
}) => {
|
}) => {
|
||||||
|
const { action } = params;
|
||||||
const shop = useShop();
|
const shop = useShop();
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
|
@ -78,7 +81,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
const [updateMetadata] = useMetadataUpdate({});
|
const [updateMetadata] = useMetadataUpdate({});
|
||||||
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
|
const [updatePrivateMetadata] = usePrivateMetadataUpdate({});
|
||||||
|
|
||||||
const [openModal] = createDialogActionHandlers<
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
ProductVariantEditUrlDialog,
|
ProductVariantEditUrlDialog,
|
||||||
ProductVariantEditUrlQueryParams
|
ProductVariantEditUrlQueryParams
|
||||||
>(
|
>(
|
||||||
|
@ -220,6 +223,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
navigate(productVariantEditUrl(productId, variantId));
|
navigate(productVariantEditUrl(productId, variantId));
|
||||||
}}
|
}}
|
||||||
onVariantReorder={handleVariantReorder}
|
onVariantReorder={handleVariantReorder}
|
||||||
|
onWarehouseConfigure={() => openModal("leave-screen")}
|
||||||
/>
|
/>
|
||||||
<ProductVariantDeleteDialog
|
<ProductVariantDeleteDialog
|
||||||
confirmButtonState={deleteVariantOpts.status}
|
confirmButtonState={deleteVariantOpts.status}
|
||||||
|
@ -234,6 +238,12 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
open={params.action === "remove"}
|
open={params.action === "remove"}
|
||||||
name={data?.productVariant?.name}
|
name={data?.productVariant?.name}
|
||||||
/>
|
/>
|
||||||
|
<LeaveScreenDialog
|
||||||
|
onSubmit={() => navigate(warehouseListPath)}
|
||||||
|
onClose={closeModal}
|
||||||
|
open={action === "leave-screen"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
|
import LeaveScreenDialog from "@saleor/components/LeaveScreenDialog";
|
||||||
import NotFoundPage from "@saleor/components/NotFoundPage";
|
import NotFoundPage from "@saleor/components/NotFoundPage";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import useShop from "@saleor/hooks/useShop";
|
import useShop from "@saleor/hooks/useShop";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler";
|
||||||
import {
|
import {
|
||||||
useMetadataUpdate,
|
useMetadataUpdate,
|
||||||
usePrivateMetadataUpdate
|
usePrivateMetadataUpdate
|
||||||
} from "@saleor/utils/metadata/updateMetadata";
|
} from "@saleor/utils/metadata/updateMetadata";
|
||||||
import { useWarehouseList } from "@saleor/warehouses/queries";
|
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||||
|
import { warehouseListPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -22,16 +25,26 @@ import {
|
||||||
useVariantCreateMutation
|
useVariantCreateMutation
|
||||||
} from "../mutations";
|
} from "../mutations";
|
||||||
import { useProductVariantCreateQuery } from "../queries";
|
import { useProductVariantCreateQuery } from "../queries";
|
||||||
import { productListUrl, productUrl, productVariantEditUrl } from "../urls";
|
import {
|
||||||
|
productListUrl,
|
||||||
|
productUrl,
|
||||||
|
productVariantAddUrl,
|
||||||
|
ProductVariantAddUrlDialog,
|
||||||
|
ProductVariantAddUrlQueryParams,
|
||||||
|
productVariantEditUrl
|
||||||
|
} from "../urls";
|
||||||
import { createVariantReorderHandler } from "./ProductUpdate/handlers";
|
import { createVariantReorderHandler } from "./ProductUpdate/handlers";
|
||||||
|
|
||||||
interface ProductVariantCreateProps {
|
interface ProductVariantCreateProps {
|
||||||
productId: string;
|
productId: string;
|
||||||
|
params: ProductVariantAddUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
|
export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
|
||||||
productId
|
productId,
|
||||||
|
params
|
||||||
}) => {
|
}) => {
|
||||||
|
const { action } = params;
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
const shop = useShop();
|
const shop = useShop();
|
||||||
|
@ -82,6 +95,11 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
|
||||||
reorderProductVariants({ variables })
|
reorderProductVariants({ variables })
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [openModal, closeModal] = createDialogActionHandlers<
|
||||||
|
ProductVariantAddUrlDialog,
|
||||||
|
ProductVariantAddUrlQueryParams
|
||||||
|
>(navigate, params => productVariantAddUrl(productId, params), params);
|
||||||
|
|
||||||
const handleBack = () => navigate(productUrl(productId));
|
const handleBack = () => navigate(productUrl(productId));
|
||||||
const handleCreate = async (formData: ProductVariantCreatePageSubmitData) => {
|
const handleCreate = async (formData: ProductVariantCreatePageSubmitData) => {
|
||||||
const result = await variantCreate({
|
const result = await variantCreate({
|
||||||
|
@ -143,12 +161,19 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onVariantClick={handleVariantClick}
|
onVariantClick={handleVariantClick}
|
||||||
onVariantReorder={handleVariantReorder}
|
onVariantReorder={handleVariantReorder}
|
||||||
|
onWarehouseConfigure={() => openModal("leave-screen")}
|
||||||
saveButtonBarState={variantCreateResult.status}
|
saveButtonBarState={variantCreateResult.status}
|
||||||
warehouses={
|
warehouses={
|
||||||
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
warehouses.data?.warehouses.edges.map(edge => edge.node) || []
|
||||||
}
|
}
|
||||||
weightUnit={shop?.defaultWeightUnit}
|
weightUnit={shop?.defaultWeightUnit}
|
||||||
/>
|
/>
|
||||||
|
<LeaveScreenDialog
|
||||||
|
onSubmit={() => navigate(warehouseListPath)}
|
||||||
|
onClose={closeModal}
|
||||||
|
open={action === "leave-screen"}
|
||||||
|
confirmButtonState="default"
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,7 @@ storiesOf("Views / Products / Create product", module)
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("When loading", () => (
|
.add("When loading", () => (
|
||||||
|
@ -60,6 +61,7 @@ storiesOf("Views / Products / Create product", module)
|
||||||
warehouses={undefined}
|
warehouses={undefined}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("form errors", () => (
|
.add("form errors", () => (
|
||||||
|
@ -89,5 +91,6 @@ storiesOf("Views / Products / Create product", module)
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
@ -39,6 +39,7 @@ const props: ProductUpdatePageProps = {
|
||||||
onVariantReorder: () => undefined,
|
onVariantReorder: () => undefined,
|
||||||
onVariantShow: () => undefined,
|
onVariantShow: () => undefined,
|
||||||
onVariantsAdd: () => undefined,
|
onVariantsAdd: () => undefined,
|
||||||
|
onWarehouseConfigure: () => undefined,
|
||||||
placeholderImage,
|
placeholderImage,
|
||||||
product,
|
product,
|
||||||
saveButtonBarState: "default",
|
saveButtonBarState: "default",
|
||||||
|
|
|
@ -26,6 +26,7 @@ storiesOf("Views / Products / Create product variant", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("with errors", () => (
|
.add("with errors", () => (
|
||||||
|
@ -58,6 +59,7 @@ storiesOf("Views / Products / Create product variant", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("when loading data", () => (
|
.add("when loading data", () => (
|
||||||
|
@ -74,6 +76,7 @@ storiesOf("Views / Products / Create product variant", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("add first variant", () => (
|
.add("add first variant", () => (
|
||||||
|
@ -93,5 +96,6 @@ storiesOf("Views / Products / Create product variant", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
@ -28,6 +28,7 @@ storiesOf("Views / Products / Product variant details", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("when loading data", () => (
|
.add("when loading data", () => (
|
||||||
|
@ -47,6 +48,7 @@ storiesOf("Views / Products / Product variant details", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("attribute errors", () => (
|
.add("attribute errors", () => (
|
||||||
|
@ -82,5 +84,6 @@ storiesOf("Views / Products / Product variant details", module)
|
||||||
...error
|
...error
|
||||||
}))}
|
}))}
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in a new issue