Merge pull request #713 from mirumee/fix/no-warehouses-in-variant-creator
Add no warehouses info when working with stock quantities
This commit is contained in:
commit
46cadf0c48
18 changed files with 5374 additions and 279 deletions
|
@ -40,6 +40,8 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Update schema with PositiveDecimal type - #695 by @AlicjaSzu
|
- Update schema with PositiveDecimal type - #695 by @AlicjaSzu
|
||||||
- Add error info when fetching taxes - #701 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
|
- Fix return to previous page on screen size change - #710 by @orzechdev
|
||||||
|
- Fix updating order details on address change #711 - by @orzechdev
|
||||||
|
- Add no warehouses info when working with stock quantities #713 - by @orzechdev
|
||||||
- Add variants reordering possibility - #716 by @orzechdev
|
- Add variants reordering possibility - #716 by @orzechdev
|
||||||
- Fix avatar change button - #719 by @orzechdev
|
- Fix avatar change button - #719 by @orzechdev
|
||||||
- Add slug field to product, collection, category & page details (update and create) - #720 by @mmarkusik
|
- Add slug field to product, collection, category & page details (update and create) - #720 by @mmarkusik
|
||||||
|
@ -104,7 +106,6 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Update product stock management to newest design - #515 by @dominik-zeglen
|
- Update product stock management to newest design - #515 by @dominik-zeglen
|
||||||
- Handle untracked products - #523 by @dominik-zeglen
|
- Handle untracked products - #523 by @dominik-zeglen
|
||||||
- Display correct error if there were no graphql errors - #525 by @dominik-zeglen
|
- Display correct error if there were no graphql errors - #525 by @dominik-zeglen
|
||||||
- Fix updating order details on address change #711 - by @orzechdev
|
|
||||||
|
|
||||||
## 2.0.0
|
## 2.0.0
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,10 @@
|
||||||
"context": "variant stock, header",
|
"context": "variant stock, header",
|
||||||
"string": "Stock"
|
"string": "Stock"
|
||||||
},
|
},
|
||||||
|
"productVariantCreatorWarehouseSectionDescription": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "There are no warehouses set up for your store. You can configure variants without providing stock quantities."
|
||||||
|
},
|
||||||
"productVariantCreatorWarehouseSectionHeader": {
|
"productVariantCreatorWarehouseSectionHeader": {
|
||||||
"context": "header",
|
"context": "header",
|
||||||
"string": "Warehouses"
|
"string": "Warehouses"
|
||||||
|
@ -310,6 +314,14 @@
|
||||||
"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 <a>configure a warehouse</a>"
|
||||||
|
},
|
||||||
|
"productWarehouseSectionDescription": {
|
||||||
|
"context": "no warehouses info",
|
||||||
|
"string": "There are no warehouses set up for your store. To add stock quantity to the product please <a>configure a warehouse</a>"
|
||||||
|
},
|
||||||
"saleDetailsPageCategoriesQuantity": {
|
"saleDetailsPageCategoriesQuantity": {
|
||||||
"context": "number of categories",
|
"context": "number of categories",
|
||||||
"string": "Categories ({quantity})"
|
"string": "Categories ({quantity})"
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +125,8 @@ export const ProductCreatePage: React.FC<ProductCreatePageProps> = ({
|
||||||
onBack,
|
onBack,
|
||||||
fetchProductTypes,
|
fetchProductTypes,
|
||||||
weightUnit,
|
weightUnit,
|
||||||
onSubmit
|
onSubmit,
|
||||||
|
onWarehouseConfigure
|
||||||
}: ProductCreatePageProps) => {
|
}: ProductCreatePageProps) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const localizeDate = useDateLocalize();
|
const localizeDate = useDateLocalize();
|
||||||
|
@ -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,143 @@ const ProductStocks: React.FC<ProductStocksProps> = ({
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Typography>
|
</Typography>
|
||||||
</CardContent>
|
{!warehouses.length && (
|
||||||
<Table>
|
<Typography color="textSecondary" className={classes.noWarehouseInfo}>
|
||||||
<TableHead>
|
{hasVariants ? (
|
||||||
<TableRow>
|
<>
|
||||||
<TableCell className={classes.colName}>
|
<FormattedMessage
|
||||||
<FormattedMessage
|
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the variant please <a>configure a warehouse</a>"
|
||||||
defaultMessage="Warehouse Name"
|
description="no warehouses info"
|
||||||
description="tabel column header"
|
id="productVariantWarehouseSectionDescription"
|
||||||
/>
|
values={{
|
||||||
</TableCell>
|
a: chunks => (
|
||||||
<TableCell className={classes.colQuantity}>
|
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||||
<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}
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="There are no warehouses set up for your store. To add stock quantity to the product please <a>configure a warehouse</a>"
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productWarehouseSectionDescription"
|
||||||
|
values={{
|
||||||
|
a: chunks => (
|
||||||
|
<Link onClick={onWarehouseConfigure}>{chunks}</Link>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</CardContent>
|
||||||
|
{warehouses.length > 0 && (
|
||||||
|
<Table>
|
||||||
|
<TableHead>
|
||||||
|
<TableRow>
|
||||||
|
<TableCell className={classes.colName}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Warehouse Name"
|
||||||
|
description="tabel column header"
|
||||||
/>
|
/>
|
||||||
</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} />
|
||||||
|
|
|
@ -140,6 +140,17 @@ storiesOf(
|
||||||
step={ProductVariantCreatorStep.prices}
|
step={ProductVariantCreatorStep.prices}
|
||||||
warehouses={[props.warehouses[0]]}
|
warehouses={[props.warehouses[0]]}
|
||||||
/>
|
/>
|
||||||
|
))
|
||||||
|
.add("ship when no warehouses", () => (
|
||||||
|
<ProductVariantCreatorContent
|
||||||
|
{...props}
|
||||||
|
data={{
|
||||||
|
...data,
|
||||||
|
warehouses: []
|
||||||
|
}}
|
||||||
|
step={ProductVariantCreatorStep.prices}
|
||||||
|
warehouses={[]}
|
||||||
|
/>
|
||||||
));
|
));
|
||||||
|
|
||||||
storiesOf("Views / Products / Create multiple variants / summary", module)
|
storiesOf("Views / Products / Create multiple variants / summary", module)
|
||||||
|
|
|
@ -123,192 +123,206 @@ const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = pr
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{warehouses.length > 1 && (
|
{!warehouses.length ? (
|
||||||
|
<Typography color="textSecondary">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="There are no warehouses set up for your store. You can configure variants without providing stock quantities."
|
||||||
|
description="no warehouses info"
|
||||||
|
id="productVariantCreatorWarehouseSectionDescription"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
<>
|
<>
|
||||||
<Typography className={classes.warehouseHeader} variant="h5">
|
{warehouses.length > 1 && (
|
||||||
<FormattedMessage
|
<>
|
||||||
defaultMessage="Warehouses"
|
<Typography className={classes.warehouseHeader} variant="h5">
|
||||||
description="header"
|
<FormattedMessage
|
||||||
id="productVariantCreatorWarehouseSectionHeader"
|
defaultMessage="Warehouses"
|
||||||
/>
|
description="header"
|
||||||
</Typography>
|
id="productVariantCreatorWarehouseSectionHeader"
|
||||||
<Typography className={classes.warehouseSubheader}>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Based on your selections we will create {numberOfProducts} products. Use this step to customize price and stocks for your new products"
|
|
||||||
values={{
|
|
||||||
numberOfProducts: data.attributes.reduce(
|
|
||||||
(acc, attr) => acc + attr.values.length,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
<div className={classes.warehouseContainer}>
|
|
||||||
{warehouses.map(warehouse => (
|
|
||||||
<ControlledCheckbox
|
|
||||||
checked={isSelected(
|
|
||||||
warehouse.id,
|
|
||||||
data.warehouses,
|
|
||||||
(a, b) => a === b
|
|
||||||
)}
|
|
||||||
name={`warehouse:${warehouse.id}`}
|
|
||||||
label={warehouse.name}
|
|
||||||
onChange={() => onWarehouseToggle(warehouse.id)}
|
|
||||||
key={warehouse.id}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<CardSpacer />
|
|
||||||
<Hr />
|
|
||||||
<CardSpacer />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<Typography className={classes.stockHeader} variant="h5">
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="Stock"
|
|
||||||
description="variant stock, header"
|
|
||||||
id="productVariantCreatorStockSectionHeader"
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
<RadioGroup value={data.stock.mode}>
|
|
||||||
<FormControlLabel
|
|
||||||
value="all"
|
|
||||||
control={<Radio color="primary" />}
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Apply single stock to all SKUs"
|
|
||||||
})}
|
|
||||||
onChange={() => onApplyToAllChange("all")}
|
|
||||||
/>
|
|
||||||
{data.stock.mode === "all" && (
|
|
||||||
<div className={classes.stockContainer}>
|
|
||||||
{data.warehouses.map((warehouseId, warehouseIndex) => (
|
|
||||||
<div key={warehouseId}>
|
|
||||||
<Typography className={classes.warehouseName}>
|
|
||||||
{
|
|
||||||
warehouses.find(warehouse => warehouse.id === warehouseId)
|
|
||||||
.name
|
|
||||||
}
|
|
||||||
</Typography>
|
|
||||||
<TextField
|
|
||||||
fullWidth
|
|
||||||
inputProps={{
|
|
||||||
min: 0,
|
|
||||||
type: "number"
|
|
||||||
}}
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Stock",
|
|
||||||
id: "productVariantCreatePricesStockInputLabel"
|
|
||||||
})}
|
|
||||||
value={data.stock.value[warehouseIndex]}
|
|
||||||
onChange={event =>
|
|
||||||
onApplyToAllStockChange(
|
|
||||||
parseInt(event.target.value, 10),
|
|
||||||
warehouseIndex
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
|
</Typography>
|
||||||
|
<Typography className={classes.warehouseSubheader}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Based on your selections we will create {numberOfProducts} products. Use this step to customize price and stocks for your new products"
|
||||||
|
values={{
|
||||||
|
numberOfProducts: data.attributes.reduce(
|
||||||
|
(acc, attr) => acc + attr.values.length,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
<div className={classes.warehouseContainer}>
|
||||||
|
{warehouses.map(warehouse => (
|
||||||
|
<ControlledCheckbox
|
||||||
|
checked={isSelected(
|
||||||
|
warehouse.id,
|
||||||
|
data.warehouses,
|
||||||
|
(a, b) => a === b
|
||||||
|
)}
|
||||||
|
name={`warehouse:${warehouse.id}`}
|
||||||
|
label={warehouse.name}
|
||||||
|
onChange={() => onWarehouseToggle(warehouse.id)}
|
||||||
|
key={warehouse.id}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
<CardSpacer />
|
||||||
</div>
|
<Hr />
|
||||||
)}
|
<CardSpacer />
|
||||||
<FormSpacer />
|
</>
|
||||||
<FormControlLabel
|
)}
|
||||||
value="attribute"
|
<Typography className={classes.stockHeader} variant="h5">
|
||||||
control={<Radio color="primary" />}
|
<FormattedMessage
|
||||||
label={intl.formatMessage({
|
defaultMessage="Stock"
|
||||||
defaultMessage: "Apply unique stock by attribute to each SKU"
|
description="variant stock, header"
|
||||||
})}
|
id="productVariantCreatorStockSectionHeader"
|
||||||
onChange={() => onApplyToAllChange("attribute")}
|
|
||||||
/>
|
|
||||||
{data.stock.mode === "attribute" && (
|
|
||||||
<>
|
|
||||||
<FormSpacer />
|
|
||||||
<SingleSelectField
|
|
||||||
className={classes.shortInput}
|
|
||||||
choices={attributeChoices}
|
|
||||||
label={intl.formatMessage({
|
|
||||||
defaultMessage: "Select Attribute",
|
|
||||||
description: "variant attribute"
|
|
||||||
})}
|
|
||||||
value={data.stock.attribute}
|
|
||||||
onChange={event => onAttributeSelect(event.target.value)}
|
|
||||||
/>
|
/>
|
||||||
{stockAttributeValues && (
|
</Typography>
|
||||||
<>
|
<RadioGroup value={data.stock.mode}>
|
||||||
<Hr className={classes.hrAttribute} />
|
<FormControlLabel
|
||||||
<FormSpacer />
|
value="all"
|
||||||
<div className={classes.attributeStockScroll}>
|
control={<Radio color="primary" />}
|
||||||
<div className={classes.attributeStockContainer}>
|
label={intl.formatMessage({
|
||||||
<div />
|
defaultMessage: "Apply single stock to all SKUs"
|
||||||
{data.stock.attribute &&
|
})}
|
||||||
data.warehouses.map(warehouseId => (
|
onChange={() => onApplyToAllChange("all")}
|
||||||
<Typography
|
/>
|
||||||
className={classes.warehouseName}
|
{data.stock.mode === "all" && (
|
||||||
key={warehouseId}
|
<div className={classes.stockContainer}>
|
||||||
>
|
{data.warehouses.map((warehouseId, warehouseIndex) => (
|
||||||
{
|
<div key={warehouseId}>
|
||||||
warehouses.find(
|
<Typography className={classes.warehouseName}>
|
||||||
warehouse => warehouse.id === warehouseId
|
{
|
||||||
).name
|
warehouses.find(
|
||||||
}
|
warehouse => warehouse.id === warehouseId
|
||||||
</Typography>
|
).name
|
||||||
))}
|
}
|
||||||
{stockAttributeValues.map(attributeValue => (
|
</Typography>
|
||||||
<React.Fragment key={attributeValue.id}>
|
<TextField
|
||||||
<Typography>{attributeValue.name}</Typography>
|
fullWidth
|
||||||
{data.warehouses.map(
|
inputProps={{
|
||||||
(warehouseId, warehouseIndex) => (
|
min: 0,
|
||||||
<TextField
|
type: "number"
|
||||||
fullWidth
|
}}
|
||||||
inputProps={{
|
label={intl.formatMessage({
|
||||||
min: 0,
|
defaultMessage: "Stock",
|
||||||
type: "number"
|
id: "productVariantCreatePricesStockInputLabel"
|
||||||
}}
|
})}
|
||||||
label={intl.formatMessage({
|
value={data.stock.value[warehouseIndex]}
|
||||||
defaultMessage: "Stock",
|
onChange={event =>
|
||||||
id:
|
onApplyToAllStockChange(
|
||||||
"productVariantCreatePricesStockInputLabel"
|
parseInt(event.target.value, 10),
|
||||||
})}
|
warehouseIndex
|
||||||
value={
|
)
|
||||||
data.stock.values.find(
|
}
|
||||||
value => value.slug === attributeValue.slug
|
/>
|
||||||
).value[warehouseIndex]
|
|
||||||
}
|
|
||||||
onChange={event =>
|
|
||||||
onAttributeValueChange(
|
|
||||||
attributeValue.slug,
|
|
||||||
parseInt(event.target.value, 10),
|
|
||||||
warehouseIndex
|
|
||||||
)
|
|
||||||
}
|
|
||||||
key={warehouseId}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<FormSpacer />
|
||||||
|
<FormControlLabel
|
||||||
|
value="attribute"
|
||||||
|
control={<Radio color="primary" />}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Apply unique stock by attribute to each SKU"
|
||||||
|
})}
|
||||||
|
onChange={() => onApplyToAllChange("attribute")}
|
||||||
|
/>
|
||||||
|
{data.stock.mode === "attribute" && (
|
||||||
|
<>
|
||||||
|
<FormSpacer />
|
||||||
|
<SingleSelectField
|
||||||
|
className={classes.shortInput}
|
||||||
|
choices={attributeChoices}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Select Attribute",
|
||||||
|
description: "variant attribute"
|
||||||
|
})}
|
||||||
|
value={data.stock.attribute}
|
||||||
|
onChange={event => onAttributeSelect(event.target.value)}
|
||||||
|
/>
|
||||||
|
{stockAttributeValues && (
|
||||||
|
<>
|
||||||
|
<Hr className={classes.hrAttribute} />
|
||||||
|
<FormSpacer />
|
||||||
|
<div className={classes.attributeStockScroll}>
|
||||||
|
<div className={classes.attributeStockContainer}>
|
||||||
|
<div />
|
||||||
|
{data.stock.attribute &&
|
||||||
|
data.warehouses.map(warehouseId => (
|
||||||
|
<Typography
|
||||||
|
className={classes.warehouseName}
|
||||||
|
key={warehouseId}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
warehouses.find(
|
||||||
|
warehouse => warehouse.id === warehouseId
|
||||||
|
).name
|
||||||
|
}
|
||||||
|
</Typography>
|
||||||
|
))}
|
||||||
|
{stockAttributeValues.map(attributeValue => (
|
||||||
|
<React.Fragment key={attributeValue.id}>
|
||||||
|
<Typography>{attributeValue.name}</Typography>
|
||||||
|
{data.warehouses.map(
|
||||||
|
(warehouseId, warehouseIndex) => (
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
inputProps={{
|
||||||
|
min: 0,
|
||||||
|
type: "number"
|
||||||
|
}}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Stock",
|
||||||
|
id:
|
||||||
|
"productVariantCreatePricesStockInputLabel"
|
||||||
|
})}
|
||||||
|
value={
|
||||||
|
data.stock.values.find(
|
||||||
|
value =>
|
||||||
|
value.slug === attributeValue.slug
|
||||||
|
).value[warehouseIndex]
|
||||||
|
}
|
||||||
|
onChange={event =>
|
||||||
|
onAttributeValueChange(
|
||||||
|
attributeValue.slug,
|
||||||
|
parseInt(event.target.value, 10),
|
||||||
|
warehouseIndex
|
||||||
|
)
|
||||||
|
}
|
||||||
|
key={warehouseId}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{data.stock.mode === "attribute" && !!data.stock.attribute && (
|
||||||
|
<>
|
||||||
|
<FormSpacer />
|
||||||
|
<Hr />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{data.stock.mode === "attribute" && !!data.stock.attribute && (
|
|
||||||
<>
|
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<Hr />
|
<FormControlLabel
|
||||||
</>
|
value="skip"
|
||||||
)}
|
control={<Radio color="primary" />}
|
||||||
<FormSpacer />
|
label={intl.formatMessage({
|
||||||
<FormControlLabel
|
defaultMessage: "Skip stock for now"
|
||||||
value="skip"
|
})}
|
||||||
control={<Radio color="primary" />}
|
onChange={() => onApplyToAllChange("skip")}
|
||||||
label={intl.formatMessage({
|
/>
|
||||||
defaultMessage: "Skip stock for now"
|
</RadioGroup>
|
||||||
})}
|
</>
|
||||||
onChange={() => onApplyToAllChange("skip")}
|
)}
|
||||||
/>
|
|
||||||
</RadioGroup>
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
|
@ -14,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 { warehouseAddPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -180,6 +181,7 @@ export const ProductCreateView: React.FC = () => {
|
||||||
)}
|
)}
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
onWarehouseConfigure={() => navigate(warehouseAddPath)}
|
||||||
saveButtonBarState={productCreateOpts.status}
|
saveButtonBarState={productCreateOpts.status}
|
||||||
fetchMoreCategories={{
|
fetchMoreCategories={{
|
||||||
hasMore: searchCategoryOpts.data?.search.pageInfo.hasNextPage,
|
hasMore: searchCategoryOpts.data?.search.pageInfo.hasNextPage,
|
||||||
|
|
|
@ -33,6 +33,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 { warehouseAddPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -304,6 +305,7 @@ export const ProductUpdate: React.FC<ProductUpdateProps> = ({ id, params }) => {
|
||||||
onDelete={() => openModal("remove")}
|
onDelete={() => openModal("remove")}
|
||||||
onImageReorder={handleImageReorder}
|
onImageReorder={handleImageReorder}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
onWarehouseConfigure={() => navigate(warehouseAddPath)}
|
||||||
onVariantAdd={handleVariantAdd}
|
onVariantAdd={handleVariantAdd}
|
||||||
onVariantsAdd={() => navigate(productVariantCreatorUrl(id))}
|
onVariantsAdd={() => navigate(productVariantCreatorUrl(id))}
|
||||||
onVariantShow={variantId => () =>
|
onVariantShow={variantId => () =>
|
||||||
|
|
|
@ -13,6 +13,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 { warehouseAddPath } 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";
|
||||||
|
|
||||||
|
@ -215,6 +216,7 @@ export const ProductVariant: React.FC<ProductUpdateProps> = ({
|
||||||
onDelete={() => openModal("remove")}
|
onDelete={() => openModal("remove")}
|
||||||
onImageSelect={handleImageSelect}
|
onImageSelect={handleImageSelect}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
|
onWarehouseConfigure={() => navigate(warehouseAddPath)}
|
||||||
onVariantClick={variantId => {
|
onVariantClick={variantId => {
|
||||||
navigate(productVariantEditUrl(productId, variantId));
|
navigate(productVariantEditUrl(productId, variantId));
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -10,6 +10,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 { warehouseAddPath } from "@saleor/warehouses/urls";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -142,6 +143,7 @@ export const ProductVariant: React.FC<ProductVariantCreateProps> = ({
|
||||||
onBack={handleBack}
|
onBack={handleBack}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onVariantClick={handleVariantClick}
|
onVariantClick={handleVariantClick}
|
||||||
|
onWarehouseConfigure={() => navigate(warehouseAddPath)}
|
||||||
onVariantReorder={handleVariantReorder}
|
onVariantReorder={handleVariantReorder}
|
||||||
saveButtonBarState={variantCreateResult.status}
|
saveButtonBarState={variantCreateResult.status}
|
||||||
warehouses={
|
warehouses={
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,7 @@ storiesOf("Views / Products / Create product", module)
|
||||||
onSubmit={() => undefined}
|
onSubmit={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
/>
|
/>
|
||||||
|
@ -58,6 +59,7 @@ storiesOf("Views / Products / Create product", module)
|
||||||
onSubmit={() => undefined}
|
onSubmit={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={undefined}
|
warehouses={undefined}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
/>
|
/>
|
||||||
|
@ -87,6 +89,7 @@ storiesOf("Views / Products / Create product", module)
|
||||||
onSubmit={() => undefined}
|
onSubmit={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
taxTypes={taxTypes}
|
taxTypes={taxTypes}
|
||||||
weightUnit="kg"
|
weightUnit="kg"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -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",
|
||||||
|
@ -104,6 +105,25 @@ storiesOf("Views / Products / Product edit", module)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
.add("no stock, no variants and no warehouses", () => (
|
||||||
|
<ProductUpdatePage
|
||||||
|
{...props}
|
||||||
|
warehouses={[]}
|
||||||
|
product={{
|
||||||
|
...product,
|
||||||
|
productType: {
|
||||||
|
...product.productType,
|
||||||
|
hasVariants: false
|
||||||
|
},
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
...product.variants[0],
|
||||||
|
stocks: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))
|
||||||
.add("no product attributes", () => (
|
.add("no product attributes", () => (
|
||||||
<ProductUpdatePage
|
<ProductUpdatePage
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
@ -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,23 @@ storiesOf("Views / Products / Create product variant", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
.add("no warehouses", () => (
|
||||||
|
<ProductVariantCreatePage
|
||||||
|
currencySymbol="USD"
|
||||||
|
weightUnit="kg"
|
||||||
|
disabled={false}
|
||||||
|
errors={[]}
|
||||||
|
header="Add variant"
|
||||||
|
product={product}
|
||||||
|
onBack={() => undefined}
|
||||||
|
onSubmit={() => undefined}
|
||||||
|
onVariantClick={undefined}
|
||||||
|
onVariantReorder={() => undefined}
|
||||||
|
saveButtonBarState="default"
|
||||||
|
warehouses={[]}
|
||||||
|
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,26 @@ storiesOf("Views / Products / Product variant details", module)
|
||||||
onVariantReorder={() => undefined}
|
onVariantReorder={() => undefined}
|
||||||
saveButtonBarState="default"
|
saveButtonBarState="default"
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
.add("no warehouses", () => (
|
||||||
|
<ProductVariantPage
|
||||||
|
defaultWeightUnit="kg"
|
||||||
|
header={variant.name || variant.sku}
|
||||||
|
errors={[]}
|
||||||
|
variant={variant}
|
||||||
|
onAdd={() => undefined}
|
||||||
|
onBack={() => undefined}
|
||||||
|
onDelete={undefined}
|
||||||
|
onSetDefaultVariant={() => undefined}
|
||||||
|
onImageSelect={() => undefined}
|
||||||
|
onSubmit={() => undefined}
|
||||||
|
onVariantClick={() => undefined}
|
||||||
|
onVariantReorder={() => undefined}
|
||||||
|
saveButtonBarState="default"
|
||||||
|
warehouses={[]}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("attribute errors", () => (
|
.add("attribute errors", () => (
|
||||||
|
@ -82,5 +103,6 @@ storiesOf("Views / Products / Product variant details", module)
|
||||||
...error
|
...error
|
||||||
}))}
|
}))}
|
||||||
warehouses={warehouseList}
|
warehouses={warehouseList}
|
||||||
|
onWarehouseConfigure={() => undefined}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in a new issue