From 688fc83f558ecc261c288837abab5894a6613938 Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Mon, 6 Apr 2020 16:32:39 +0200 Subject: [PATCH] Split components into pricing and stock sections --- .../ProductVariantCreatorContent.tsx | 28 +- .../ProductVariantCreatorPriceAndSku.tsx | 65 ++++ .../ProductVariantCreatorPrices.tsx | 358 ++++++------------ .../ProductVariantCreatorStock.tsx | 174 +++++++++ .../ProductVariantCreator.tsx | 2 +- 5 files changed, 369 insertions(+), 258 deletions(-) create mode 100644 src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx create mode 100644 src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx index 04db35746..4f2449507 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorContent.tsx @@ -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 /> )} {step === ProductVariantCreatorStep.prices && ( - + onApplyToAllChange={(all, type) => dispatchFormDataAction({ applyPriceOrStockToAll: { all @@ -75,17 +75,16 @@ const ProductVariantCreatorContent: React.FC : ProductVariantCreateReducerActionType.applyStockToAll }) } - // TODO: Stock change is not fixed in this PR so we won't include it here - onApplyToAllChange={(price, type) => - dispatchFormDataAction( - type === "price" && { - changeApplyPriceToAllValue: { - price - }, - type: - ProductVariantCreateReducerActionType.changeApplyPriceToAllValue - } - ) + onApplyToAllPriceOrStockChange={(value, type) => + dispatchFormDataAction({ + changeApplyPriceToAllValue: { + price: value + }, + type: + type === "price" + ? ProductVariantCreateReducerActionType.applyPriceToAll + : ProductVariantCreateReducerActionType.applyStockToAll + }) } onAttributeSelect={(attributeId, type) => dispatchFormDataAction({ @@ -98,7 +97,6 @@ const ProductVariantCreatorContent: React.FC : 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" && { diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx new file mode 100644 index 000000000..238338399 --- /dev/null +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPriceAndSku.tsx @@ -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 = ({ + attributes, + currencySymbol, + data, + onApplyToAllPriceOrStockChange, + onApplyToAllChange, + onAttributeSelect, + onAttributeValueChange +}) => ( + <> + onApplyToAllChange(value, "price")} + onApplyToAllPriceChange={value => + onApplyToAllPriceOrStockChange(value, "price") + } + onAttributeSelect={id => onAttributeSelect(id, "price")} + onAttributeValueChange={(id, value) => + onAttributeValueChange(id, value, "price") + } + /> + + 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; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx index 188c8278c..0e0af5ec2 100644 --- a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorPrices.tsx @@ -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 = props => { @@ -58,8 +52,8 @@ const ProductVariantCreatorPrices: React.FC = attributes, currencySymbol, data, - onApplyPriceOrStockChange, onApplyToAllChange, + onApplyToAllPriceChange, onAttributeSelect, onAttributeValueChange } = props; @@ -71,240 +65,120 @@ const ProductVariantCreatorPrices: React.FC = value: attribute.id })); const priceAttributeValues = getPriceAttributeValues(data, attributes); - const stockAttributeValues = getStockAttributeValues(data, attributes); return ( - <> - - - - - } - label={intl.formatMessage({ - defaultMessage: "Apply single price to all SKUs" - })} - onChange={() => onApplyPriceOrStockChange(true, "price")} - /> + + + + + } + label={intl.formatMessage({ + defaultMessage: "Apply single price to all SKUs" + })} + onChange={() => onApplyToAllChange(true)} + /> + + onApplyToAllPriceChange(event.target.value)} + /> + + } + label={intl.formatMessage({ + defaultMessage: "Apply unique prices by attribute to each SKU" + })} + onChange={() => onApplyToAllChange(false)} + /> + + {!data.price.all && ( + <> - - onApplyToAllChange(event.target.value, "price") - } - /> - - } - label={intl.formatMessage({ - defaultMessage: "Apply unique prices by attribute to each SKU" - })} - onChange={() => onApplyPriceOrStockChange(false, "price")} - /> - - {!data.price.all && ( - <> - - -
- - - -
-
- - onAttributeSelect(event.target.value, "price") - } + +
+ + -
-
- {priceAttributeValues && - priceAttributeValues.map(attributeValue => ( - -
- - -
- {attributeValue.name} -
-
- value.slug === attributeValue.slug - ).value - } - onChange={event => - onAttributeValueChange( - attributeValue.slug, - event.target.value, - "price" - ) - } - /> -
-
-
- ))} - - )} - - - - - - - - } - label={intl.formatMessage({ - defaultMessage: "Apply single stock to all SKUs" - })} - onChange={() => onApplyPriceOrStockChange(true, "stock")} - /> - - - onApplyToAllChange(event.target.value, "stock") - } - /> - - } - label={intl.formatMessage({ - defaultMessage: "Apply unique stock by attribute to each SKU" - })} - onChange={() => onApplyPriceOrStockChange(false, "stock")} - /> - - {!data.stock.all && ( - <> - - -
- - - -
-
- - onAttributeSelect(event.target.value, "stock") - } - /> -
-
- {stockAttributeValues && - stockAttributeValues.map(attributeValue => ( - -
- - -
- {attributeValue.name} -
-
- value.slug === attributeValue.slug - ).value - } - onChange={event => - onAttributeValueChange( - attributeValue.slug, - event.target.value, - "stock" - ) - } - /> -
-
-
- ))} - - )} -
-
- + +
+
+ onAttributeSelect(event.target.value)} + /> +
+
+ {priceAttributeValues && + priceAttributeValues.map(attributeValue => ( + +
+ + +
+ {attributeValue.name} +
+
+ value.slug === attributeValue.slug + ).value + } + onChange={event => + onAttributeValueChange( + attributeValue.slug, + event.target.value + ) + } + /> +
+
+
+ ))} + + )} +
+
); }; diff --git a/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx new file mode 100644 index 000000000..2b33e5f84 --- /dev/null +++ b/src/products/components/ProductVariantCreatorPage/ProductVariantCreatorStock.tsx @@ -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 = 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 ( + + + + + } + label={intl.formatMessage({ + defaultMessage: "Apply single stock to all SKUs" + })} + onChange={() => onApplyToAllChange(true)} + /> + + onApplyToAllStockChange(event.target.value)} + /> + + } + label={intl.formatMessage({ + defaultMessage: "Apply unique stock by attribute to each SKU" + })} + onChange={() => onApplyToAllChange(false)} + /> + + {!data.stock.all && ( + <> + + +
+ + + +
+
+ +
+
+ {stockAttributeValues && + stockAttributeValues.map(attributeValue => ( + +
+ + +
+ {attributeValue.name} +
+
+ value.slug === attributeValue.slug + ).value + } + onChange={event => + onAttributeValueChange( + attributeValue.slug, + event.target.value + ) + } + /> +
+
+
+ ))} + + )} +
+
+ ); +}; + +ProductVariantCreatorStock.displayName = "ProductVariantCreatorStock"; +export default ProductVariantCreatorStock; diff --git a/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx b/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx index 24b599a32..b6854c310 100644 --- a/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx +++ b/src/products/views/ProductVariantCreator/ProductVariantCreator.tsx @@ -63,7 +63,7 @@ const ProductVariantCreator: React.FC = ({ variables: { id, inputs } }) } - warehouses={data?.warehouses.edges.map(edge => edge.node)} + warehouses={data?.warehouses.edges.map(edge => edge.node) || []} /> );