Split components into pricing and stock sections

This commit is contained in:
dominik-zeglen 2020-04-06 16:32:39 +02:00
parent 1b7eac3596
commit 688fc83f55
5 changed files with 369 additions and 258 deletions

View file

@ -5,7 +5,7 @@ import { ProductVariantBulkCreate_productVariantBulkCreate_errors } from "@saleo
import { isSelected } from "@saleor/utils/lists";
import { WarehouseFragment } from "@saleor/warehouses/types/WarehouseFragment";
import { ProductVariantCreateFormData } from "./form";
import ProductVariantCreatePrices from "./ProductVariantCreatorPrices";
import ProductVariantCreatePriceAndSku from "./ProductVariantCreatorPriceAndSku";
import ProductVariantCreateSummary from "./ProductVariantCreatorSummary";
import ProductVariantCreateValues from "./ProductVariantCreatorValues";
import {
@ -60,11 +60,11 @@ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps>
/>
)}
{step === ProductVariantCreatorStep.prices && (
<ProductVariantCreatePrices
<ProductVariantCreatePriceAndSku
attributes={selectedAttributes}
currencySymbol={currencySymbol}
data={data}
onApplyPriceOrStockChange={(all, type) =>
onApplyToAllChange={(all, type) =>
dispatchFormDataAction({
applyPriceOrStockToAll: {
all
@ -75,17 +75,16 @@ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps>
: ProductVariantCreateReducerActionType.applyStockToAll
})
}
// TODO: Stock change is not fixed in this PR so we won't include it here
onApplyToAllChange={(price, type) =>
dispatchFormDataAction(
type === "price" && {
onApplyToAllPriceOrStockChange={(value, type) =>
dispatchFormDataAction({
changeApplyPriceToAllValue: {
price
price: value
},
type:
ProductVariantCreateReducerActionType.changeApplyPriceToAllValue
}
)
type === "price"
? ProductVariantCreateReducerActionType.applyPriceToAll
: ProductVariantCreateReducerActionType.applyStockToAll
})
}
onAttributeSelect={(attributeId, type) =>
dispatchFormDataAction({
@ -98,7 +97,6 @@ const ProductVariantCreatorContent: React.FC<ProductVariantCreatorContentProps>
: ProductVariantCreateReducerActionType.changeApplyStockToAttributeId
})
}
// TODO: Stock change is not fixed in this PR so we won't include it here
onAttributeValueChange={(valueId, price, type) =>
dispatchFormDataAction(
type === "price" && {

View file

@ -0,0 +1,65 @@
import React from "react";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import CardSpacer from "@saleor/components/CardSpacer";
import { ProductVariantCreateFormData } from "./form";
import ProductVariantCreatorPrices from "./ProductVariantCreatorPrices";
import ProductVariantCreatorStock from "./ProductVariantCreatorStock";
export type PriceOrStock = "price" | "stock";
export interface ProductVariantCreatorPriceAndSkuProps {
attributes: ProductDetails_product_productType_variantAttributes[];
currencySymbol: string;
data: ProductVariantCreateFormData;
onApplyToAllChange: (applyToAll: boolean, type: PriceOrStock) => void;
onApplyToAllPriceOrStockChange: (value: string, type: PriceOrStock) => void;
onAttributeSelect: (id: string, type: PriceOrStock) => void;
onAttributeValueChange: (
id: string,
value: string,
type: PriceOrStock
) => void;
}
const ProductVariantCreatorPriceAndSku: React.FC<ProductVariantCreatorPriceAndSkuProps> = ({
attributes,
currencySymbol,
data,
onApplyToAllPriceOrStockChange,
onApplyToAllChange,
onAttributeSelect,
onAttributeValueChange
}) => (
<>
<ProductVariantCreatorPrices
attributes={attributes}
currencySymbol={currencySymbol}
data={data}
onApplyToAllChange={value => onApplyToAllChange(value, "price")}
onApplyToAllPriceChange={value =>
onApplyToAllPriceOrStockChange(value, "price")
}
onAttributeSelect={id => onAttributeSelect(id, "price")}
onAttributeValueChange={(id, value) =>
onAttributeValueChange(id, value, "price")
}
/>
<CardSpacer />
<ProductVariantCreatorStock
attributes={attributes}
data={data}
onApplyToAllChange={value => onApplyToAllChange(value, "stock")}
onApplyToAllStockChange={value =>
onApplyToAllPriceOrStockChange(value, "stock")
}
onAttributeSelect={id => onAttributeSelect(id, "stock")}
onAttributeValueChange={(id, value) =>
onAttributeValueChange(id, value, "stock")
}
/>
</>
);
ProductVariantCreatorPriceAndSku.displayName =
"ProductVariantCreatorPriceAndSku";
export default ProductVariantCreatorPriceAndSku;

View file

@ -15,9 +15,8 @@ import Hr from "@saleor/components/Hr";
import SingleSelectField from "@saleor/components/SingleSelectField";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import CardTitle from "@saleor/components/CardTitle";
import CardSpacer from "@saleor/components/CardSpacer";
import { ProductVariantCreateFormData } from "./form";
import { getPriceAttributeValues, getStockAttributeValues } from "./utils";
import { getPriceAttributeValues } from "./utils";
const useStyles = makeStyles(
theme => ({
@ -38,19 +37,14 @@ const useStyles = makeStyles(
{ name: "ProductVariantCreatorPrices" }
);
export type PriceOrStock = "price" | "stock";
export interface ProductVariantCreatorPricesProps {
attributes: ProductDetails_product_productType_variantAttributes[];
currencySymbol: string;
data: ProductVariantCreateFormData;
onApplyPriceOrStockChange: (applyToAll: boolean, type: PriceOrStock) => void;
onApplyToAllChange: (value: string, type: PriceOrStock) => void;
onAttributeSelect: (id: string, type: PriceOrStock) => void;
onAttributeValueChange: (
id: string,
value: string,
type: PriceOrStock
) => void;
onApplyToAllChange: (applyToAll: boolean) => void;
onApplyToAllPriceChange: (value: string) => void;
onAttributeSelect: (id: string) => void;
onAttributeValueChange: (id: string, value: string) => void;
}
const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> = props => {
@ -58,8 +52,8 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
attributes,
currencySymbol,
data,
onApplyPriceOrStockChange,
onApplyToAllChange,
onApplyToAllPriceChange,
onAttributeSelect,
onAttributeValueChange
} = props;
@ -71,10 +65,8 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
value: attribute.id
}));
const priceAttributeValues = getPriceAttributeValues(data, attributes);
const stockAttributeValues = getStockAttributeValues(data, attributes);
return (
<>
<Card>
<CardTitle
title={intl.formatMessage({
@ -83,16 +75,14 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
})}
/>
<CardContent>
<RadioGroup
value={data.price.all ? "applyToAll" : "applyToAttribute"}
>
<RadioGroup value={data.price.all ? "applyToAll" : "applyToAttribute"}>
<FormControlLabel
value="applyToAll"
control={<Radio color="primary" />}
label={intl.formatMessage({
defaultMessage: "Apply single price to all SKUs"
})}
onChange={() => onApplyPriceOrStockChange(true, "price")}
onChange={() => onApplyToAllChange(true)}
/>
<FormSpacer />
<TextField
@ -109,9 +99,7 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
id: "productVariantCreatePricesPriceInputLabel"
})}
value={data.price.value}
onChange={event =>
onApplyToAllChange(event.target.value, "price")
}
onChange={event => onApplyToAllPriceChange(event.target.value)}
/>
<FormSpacer />
<FormControlLabel
@ -120,7 +108,7 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
label={intl.formatMessage({
defaultMessage: "Apply unique prices by attribute to each SKU"
})}
onChange={() => onApplyPriceOrStockChange(false, "price")}
onChange={() => onApplyToAllChange(false)}
/>
</RadioGroup>
{!data.price.all && (
@ -143,9 +131,7 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
description: "variant attribute"
})}
value={data.price.attribute}
onChange={event =>
onAttributeSelect(event.target.value, "price")
}
onChange={event => onAttributeSelect(event.target.value)}
/>
</div>
</Grid>
@ -181,8 +167,7 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
onChange={event =>
onAttributeValueChange(
attributeValue.slug,
event.target.value,
"price"
event.target.value
)
}
/>
@ -194,117 +179,6 @@ const ProductVariantCreatorPrices: React.FC<ProductVariantCreatorPricesProps> =
)}
</CardContent>
</Card>
<CardSpacer />
<Card>
<CardTitle
title={intl.formatMessage({
defaultMessage: "Stock",
description: "variant stock, header"
})}
/>
<CardContent>
<RadioGroup
value={data.stock.all ? "applyToAll" : "applyToAttribute"}
>
<FormControlLabel
value="applyToAll"
control={<Radio color="primary" />}
label={intl.formatMessage({
defaultMessage: "Apply single stock to all SKUs"
})}
onChange={() => onApplyPriceOrStockChange(true, "stock")}
/>
<FormSpacer />
<TextField
className={classes.shortInput}
inputProps={{
min: 0,
type: "number"
}}
label={intl.formatMessage({
defaultMessage: "Stock",
id: "productVariantCreatePricesStockInputLabel"
})}
value={data.stock.value}
onChange={event =>
onApplyToAllChange(event.target.value, "stock")
}
/>
<FormSpacer />
<FormControlLabel
value="applyToAttribute"
control={<Radio color="primary" />}
label={intl.formatMessage({
defaultMessage: "Apply unique stock by attribute to each SKU"
})}
onChange={() => onApplyPriceOrStockChange(false, "stock")}
/>
</RadioGroup>
{!data.stock.all && (
<>
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>
<FormattedMessage
defaultMessage="Choose attribute"
description="variant attribute"
/>
</Typography>
</div>
<div>
<SingleSelectField
choices={attributeChoices}
label={intl.formatMessage({
defaultMessage: "Attribute",
description: "variant attribute"
})}
value={data.stock.attribute}
onChange={event =>
onAttributeSelect(event.target.value, "stock")
}
/>
</div>
</Grid>
{stockAttributeValues &&
stockAttributeValues.map(attributeValue => (
<React.Fragment key={attributeValue.id}>
<Hr className={classes.hrAttribute} />
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>{attributeValue.name}</Typography>
</div>
<div>
<TextField
label={intl.formatMessage({
defaultMessage: "Stock",
description: "variant stock",
id: "productVariantCreatePricesSetStockPlaceholder"
})}
fullWidth
value={
data.stock.values.find(
value => value.slug === attributeValue.slug
).value
}
onChange={event =>
onAttributeValueChange(
attributeValue.slug,
event.target.value,
"stock"
)
}
/>
</div>
</Grid>
</React.Fragment>
))}
</>
)}
</CardContent>
</Card>
</>
);
};

View file

@ -0,0 +1,174 @@
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import Radio from "@material-ui/core/Radio";
import RadioGroup from "@material-ui/core/RadioGroup";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import FormSpacer from "@saleor/components/FormSpacer";
import Grid from "@saleor/components/Grid";
import Hr from "@saleor/components/Hr";
import SingleSelectField from "@saleor/components/SingleSelectField";
import { ProductDetails_product_productType_variantAttributes } from "@saleor/products/types/ProductDetails";
import CardTitle from "@saleor/components/CardTitle";
import { ProductVariantCreateFormData } from "./form";
import { getStockAttributeValues } from "./utils";
const useStyles = makeStyles(
theme => ({
hr: {
marginBottom: theme.spacing(),
marginTop: theme.spacing(0.5)
},
hrAttribute: {
marginTop: theme.spacing(2)
},
label: {
alignSelf: "center"
},
shortInput: {
width: "33%"
}
}),
{ name: "ProductVariantCreatorStock" }
);
export interface ProductVariantCreatorStockProps {
attributes: ProductDetails_product_productType_variantAttributes[];
data: ProductVariantCreateFormData;
onApplyToAllChange: (applyToAll: boolean) => void;
onApplyToAllStockChange: (value: string) => void;
onAttributeSelect: (id: string) => void;
onAttributeValueChange: (id: string, value: string) => void;
}
const ProductVariantCreatorStock: React.FC<ProductVariantCreatorStockProps> = props => {
const {
attributes,
data,
onApplyToAllChange,
onApplyToAllStockChange,
onAttributeSelect,
onAttributeValueChange
} = props;
const classes = useStyles(props);
const intl = useIntl();
const attributeChoices = attributes.map(attribute => ({
label: attribute.name,
value: attribute.id
}));
const stockAttributeValues = getStockAttributeValues(data, attributes);
return (
<Card>
<CardTitle
title={intl.formatMessage({
defaultMessage: "Stock and Warehousing",
description: "variant stock, header"
})}
/>
<CardContent>
<RadioGroup value={data.stock.all ? "applyToAll" : "applyToAttribute"}>
<FormControlLabel
value="applyToAll"
control={<Radio color="primary" />}
label={intl.formatMessage({
defaultMessage: "Apply single stock to all SKUs"
})}
onChange={() => onApplyToAllChange(true)}
/>
<FormSpacer />
<TextField
className={classes.shortInput}
inputProps={{
min: 0,
type: "number"
}}
label={intl.formatMessage({
defaultMessage: "Stock",
id: "productVariantCreatePricesStockInputLabel"
})}
value={data.stock.value}
onChange={event => onApplyToAllStockChange(event.target.value)}
/>
<FormSpacer />
<FormControlLabel
value="applyToAttribute"
control={<Radio color="primary" />}
label={intl.formatMessage({
defaultMessage: "Apply unique stock by attribute to each SKU"
})}
onChange={() => onApplyToAllChange(false)}
/>
</RadioGroup>
{!data.stock.all && (
<>
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>
<FormattedMessage
defaultMessage="Choose attribute"
description="variant attribute"
/>
</Typography>
</div>
<div>
<SingleSelectField
choices={attributeChoices}
label={intl.formatMessage({
defaultMessage: "Attribute",
description: "variant attribute"
})}
value={data.stock.attribute}
onChange={onAttributeSelect}
/>
</div>
</Grid>
{stockAttributeValues &&
stockAttributeValues.map(attributeValue => (
<React.Fragment key={attributeValue.id}>
<Hr className={classes.hrAttribute} />
<FormSpacer />
<Grid variant="uniform">
<div className={classes.label}>
<Typography>{attributeValue.name}</Typography>
</div>
<div>
<TextField
label={intl.formatMessage({
defaultMessage: "Stock",
description: "variant stock",
id: "productVariantCreatePricesSetStockPlaceholder"
})}
fullWidth
value={
data.stock.values.find(
value => value.slug === attributeValue.slug
).value
}
onChange={event =>
onAttributeValueChange(
attributeValue.slug,
event.target.value
)
}
/>
</div>
</Grid>
</React.Fragment>
))}
</>
)}
</CardContent>
</Card>
);
};
ProductVariantCreatorStock.displayName = "ProductVariantCreatorStock";
export default ProductVariantCreatorStock;

View file

@ -63,7 +63,7 @@ const ProductVariantCreator: React.FC<ProductVariantCreatorProps> = ({
variables: { id, inputs }
})
}
warehouses={data?.warehouses.edges.map(edge => edge.node)}
warehouses={data?.warehouses.edges.map(edge => edge.node) || []}
/>
</>
);