From 4efce141da2221be57fa7d50303df7d5e20e4136 Mon Sep 17 00:00:00 2001 From: dominik-zeglen Date: Thu, 9 Jul 2020 13:45:01 +0200 Subject: [PATCH] Add weight to variant --- src/misc.ts | 4 ++ .../ProductShipping/ProductShipping.tsx | 65 +++++++++++++++++++ .../components/ProductShipping/index.ts | 0 .../ProductVariantAttributes.tsx | 21 +----- .../ProductVariantCreatePage.tsx | 15 ++++- .../ProductVariantPage/ProductVariantPage.tsx | 15 ++++- src/products/fixtures.ts | 28 ++++++-- src/products/mutations.ts | 4 ++ src/products/queries.ts | 12 ++++ src/products/types/Product.ts | 14 ++++ src/products/types/ProductCreate.ts | 15 +++++ src/products/types/ProductDetails.ts | 14 ++++ src/products/types/ProductImageCreate.ts | 14 ++++ src/products/types/ProductImageUpdate.ts | 14 ++++ src/products/types/ProductUpdate.ts | 14 ++++ src/products/types/ProductVariant.ts | 7 ++ src/products/types/ProductVariantDetails.ts | 7 ++ src/products/types/SimpleProductUpdate.ts | 42 ++++++++++++ src/products/types/VariantCreate.ts | 7 ++ src/products/types/VariantImageAssign.ts | 7 ++ src/products/types/VariantImageUnassign.ts | 7 ++ src/products/types/VariantUpdate.ts | 15 +++++ src/products/views/ProductVariant.tsx | 8 ++- src/products/views/ProductVariantCreate.tsx | 6 +- .../products/ProductVariantCreatePage.tsx | 4 ++ .../stories/products/ProductVariantPage.tsx | 3 + src/utils/errors/product.ts | 31 +++++++++ 27 files changed, 365 insertions(+), 28 deletions(-) create mode 100644 src/products/components/ProductShipping/ProductShipping.tsx create mode 100644 src/products/components/ProductShipping/index.ts diff --git a/src/misc.ts b/src/misc.ts index 4d51f42fa..f4934f862 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -59,6 +59,10 @@ export function decimal(value: string | number) { return value; } +export function weight(value: string) { + return value === "" ? null : parseFloat(value); +} + export const removeDoubleSlashes = (url: string) => url.replace(/([^:]\/)\/+/g, "$1"); diff --git a/src/products/components/ProductShipping/ProductShipping.tsx b/src/products/components/ProductShipping/ProductShipping.tsx new file mode 100644 index 000000000..ef5373ce4 --- /dev/null +++ b/src/products/components/ProductShipping/ProductShipping.tsx @@ -0,0 +1,65 @@ +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import InputAdornment from "@material-ui/core/InputAdornment"; +import TextField from "@material-ui/core/TextField"; +import CardTitle from "@saleor/components/CardTitle"; +import Grid from "@saleor/components/Grid"; +import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors"; +import React from "react"; +import { useIntl } from "react-intl"; +import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment"; + +interface ProductShippingProps { + data: { + weight: string; + }; + disabled: boolean; + errors: ProductErrorFragment[]; + weightUnit: string; + onChange: (event: React.ChangeEvent) => void; +} + +const ProductShipping: React.FC = props => { + const { data, disabled, errors, weightUnit, onChange } = props; + + const intl = useIntl(); + + const formErrors = getFormErrors(["weight"], errors); + + return ( + + + + + {weightUnit} + ), + inputProps: { + min: 0 + } + }} + /> + + + + ); +}; +ProductShipping.displayName = "ProductShipping"; +export default ProductShipping; diff --git a/src/products/components/ProductShipping/index.ts b/src/products/components/ProductShipping/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx b/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx index b32a7ef2d..bad74b2b5 100644 --- a/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx +++ b/src/products/components/ProductVariantAttributes/ProductVariantAttributes.tsx @@ -2,7 +2,7 @@ import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; import Typography from "@material-ui/core/Typography"; import React from "react"; -import { IntlShape, useIntl } from "react-intl"; +import { useIntl } from "react-intl"; import CardTitle from "@saleor/components/CardTitle"; import FormSpacer from "@saleor/components/FormSpacer"; @@ -14,7 +14,7 @@ import Skeleton from "@saleor/components/Skeleton"; import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset"; import { commonMessages } from "@saleor/intl"; import { VariantCreate_productVariantCreate_errors } from "@saleor/products/types/VariantCreate"; -import { ProductErrorCode } from "@saleor/types/globalTypes"; +import { getProductVariantAttributeErrorMessage } from "@saleor/utils/errors/product"; import { ProductVariant_attributes_attribute_values } from "../../types/ProductVariant"; export interface VariantAttributeInputData { @@ -67,19 +67,6 @@ function getAttributeValueChoices( })); } -function translateErrors(intl: IntlShape) { - return { - [ProductErrorCode.REQUIRED]: intl.formatMessage({ - defaultMessage: "All attributes should have value", - description: "product attribute error" - }), - [ProductErrorCode.UNIQUE]: intl.formatMessage({ - defaultMessage: "This variant already exists", - description: "product attribute error" - }) - }; -} - const ProductVariantAttributes: React.FC = ({ attributes, disabled, @@ -88,8 +75,6 @@ const ProductVariantAttributes: React.FC = ({ }) => { const intl = useIntl(); - const translatedErrors = translateErrors(intl); - return ( = ({ .filter(error => error.field === "attributes") .map(error => ( - {translatedErrors[error.code]} + {getProductVariantAttributeErrorMessage(error, intl)} ))} diff --git a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx index f768787db..2e59ea446 100644 --- a/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx +++ b/src/products/components/ProductVariantCreatePage/ProductVariantCreatePage.tsx @@ -18,6 +18,7 @@ import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragm import { SearchWarehouses_search_edges_node } from "@saleor/searches/types/SearchWarehouses"; import { maybe } from "../../../misc"; import { ProductVariantCreateData_product } from "../../types/ProductVariantCreateData"; +import ProductShipping from "../ProductShipping/ProductShipping"; import ProductVariantAttributes, { VariantAttributeInputData } from "../ProductVariantAttributes"; @@ -32,6 +33,7 @@ interface ProductVariantCreatePageFormData { quantity: string; sku: string; trackInventory: boolean; + weight: string; } export interface ProductVariantCreatePageSubmitData @@ -48,6 +50,7 @@ interface ProductVariantCreatePageProps { product: ProductVariantCreateData_product; saveButtonBarState: ConfirmButtonTransitionState; warehouses: SearchWarehouses_search_edges_node[]; + weightUnit: string; onBack: () => void; onSubmit: (data: ProductVariantCreatePageSubmitData) => void; onVariantClick: (variantId: string) => void; @@ -61,6 +64,7 @@ const ProductVariantCreatePage: React.FC = ({ product, saveButtonBarState, warehouses, + weightUnit, onBack, onSubmit, onVariantClick @@ -86,7 +90,8 @@ const ProductVariantCreatePage: React.FC = ({ priceOverride: "", quantity: "0", sku: "", - trackInventory: true + trackInventory: true, + weight: "" }; const handleSubmit = (data: ProductVariantCreatePageFormData) => @@ -137,6 +142,14 @@ const ProductVariantCreatePage: React.FC = ({ onChange={change} /> + + = ({ + defaultWeightUnit, errors, loading, header, @@ -112,7 +116,8 @@ const ProductVariantPage: React.FC = ({ costPrice: maybe(() => variant.costPrice.amount.toString(), ""), priceOverride: maybe(() => variant.priceOverride.amount.toString(), ""), sku: maybe(() => variant.sku, ""), - trackInventory: variant?.trackInventory + trackInventory: variant?.trackInventory, + weight: variant?.weight?.value.toString() || "" }; const handleSubmit = (data: ProductVariantPageFormData) => { @@ -195,6 +200,14 @@ const ProductVariantPage: React.FC = ({ onChange={change} /> + + ({ } } ], - trackInventory: true + trackInventory: true, + weight: { + __typename: "Weight", + unit: "kg", + value: 6 + } }); export const variantImages = (placeholderImage: string) => variant(placeholderImage).images; diff --git a/src/products/mutations.ts b/src/products/mutations.ts index d877e1b1a..80d7cacdb 100644 --- a/src/products/mutations.ts +++ b/src/products/mutations.ts @@ -295,6 +295,7 @@ export const productCreateMutation = gql` $seo: SeoInput $stocks: [StockInput!]! $trackInventory: Boolean! + $weight: WeightScalar ) { productCreate( input: { @@ -312,6 +313,7 @@ export const productCreateMutation = gql` seo: $seo stocks: $stocks trackInventory: $trackInventory + weight: $weight } ) { errors: productErrors { @@ -360,6 +362,7 @@ export const variantUpdateMutation = gql` $sku: String $trackInventory: Boolean! $stocks: [StockInput!]! + $weight: WeightScalar ) { productVariantUpdate( id: $id @@ -369,6 +372,7 @@ export const variantUpdateMutation = gql` priceOverride: $priceOverride sku: $sku trackInventory: $trackInventory + weight: $weight } ) { errors: productErrors { diff --git a/src/products/queries.ts b/src/products/queries.ts index a614f0318..5ae6e21d3 100644 --- a/src/products/queries.ts +++ b/src/products/queries.ts @@ -185,12 +185,20 @@ export const productFragmentDetails = gql` ...StockFragment } trackInventory + weight { + unit + value + } } productType { id name hasVariants } + weight { + unit + value + } } `; @@ -253,6 +261,10 @@ export const fragmentVariant = gql` ...StockFragment } trackInventory + weight { + unit + value + } } `; diff --git a/src/products/types/Product.ts b/src/products/types/Product.ts index a1c8c7696..370fdc3d0 100644 --- a/src/products/types/Product.ts +++ b/src/products/types/Product.ts @@ -163,6 +163,12 @@ export interface Product_variants_stocks { warehouse: Product_variants_stocks_warehouse; } +export interface Product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface Product_variants { __typename: "ProductVariant"; id: string; @@ -172,6 +178,13 @@ export interface Product_variants { margin: number | null; stocks: (Product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: Product_variants_weight | null; +} + +export interface Product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface Product { @@ -195,4 +208,5 @@ export interface Product { pricing: Product_pricing | null; images: (Product_images | null)[] | null; variants: (Product_variants | null)[] | null; + weight: Product_weight | null; } diff --git a/src/products/types/ProductCreate.ts b/src/products/types/ProductCreate.ts index d757729d0..e1d020c3f 100644 --- a/src/products/types/ProductCreate.ts +++ b/src/products/types/ProductCreate.ts @@ -169,6 +169,12 @@ export interface ProductCreate_productCreate_product_variants_stocks { warehouse: ProductCreate_productCreate_product_variants_stocks_warehouse; } +export interface ProductCreate_productCreate_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductCreate_productCreate_product_variants { __typename: "ProductVariant"; id: string; @@ -178,6 +184,13 @@ export interface ProductCreate_productCreate_product_variants { margin: number | null; stocks: (ProductCreate_productCreate_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: ProductCreate_productCreate_product_variants_weight | null; +} + +export interface ProductCreate_productCreate_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface ProductCreate_productCreate_product { @@ -201,6 +214,7 @@ export interface ProductCreate_productCreate_product { pricing: ProductCreate_productCreate_product_pricing | null; images: (ProductCreate_productCreate_product_images | null)[] | null; variants: (ProductCreate_productCreate_product_variants | null)[] | null; + weight: ProductCreate_productCreate_product_weight | null; } export interface ProductCreate_productCreate { @@ -228,4 +242,5 @@ export interface ProductCreateVariables { seo?: SeoInput | null; stocks: StockInput[]; trackInventory: boolean; + weight?: any | null; } diff --git a/src/products/types/ProductDetails.ts b/src/products/types/ProductDetails.ts index 2c5913c5a..86d337d42 100644 --- a/src/products/types/ProductDetails.ts +++ b/src/products/types/ProductDetails.ts @@ -163,6 +163,12 @@ export interface ProductDetails_product_variants_stocks { warehouse: ProductDetails_product_variants_stocks_warehouse; } +export interface ProductDetails_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductDetails_product_variants { __typename: "ProductVariant"; id: string; @@ -172,6 +178,13 @@ export interface ProductDetails_product_variants { margin: number | null; stocks: (ProductDetails_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: ProductDetails_product_variants_weight | null; +} + +export interface ProductDetails_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface ProductDetails_product { @@ -195,6 +208,7 @@ export interface ProductDetails_product { pricing: ProductDetails_product_pricing | null; images: (ProductDetails_product_images | null)[] | null; variants: (ProductDetails_product_variants | null)[] | null; + weight: ProductDetails_product_weight | null; } export interface ProductDetails { diff --git a/src/products/types/ProductImageCreate.ts b/src/products/types/ProductImageCreate.ts index 49cd57bda..6614ea716 100644 --- a/src/products/types/ProductImageCreate.ts +++ b/src/products/types/ProductImageCreate.ts @@ -169,6 +169,12 @@ export interface ProductImageCreate_productImageCreate_product_variants_stocks { warehouse: ProductImageCreate_productImageCreate_product_variants_stocks_warehouse; } +export interface ProductImageCreate_productImageCreate_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductImageCreate_productImageCreate_product_variants { __typename: "ProductVariant"; id: string; @@ -178,6 +184,13 @@ export interface ProductImageCreate_productImageCreate_product_variants { margin: number | null; stocks: (ProductImageCreate_productImageCreate_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: ProductImageCreate_productImageCreate_product_variants_weight | null; +} + +export interface ProductImageCreate_productImageCreate_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface ProductImageCreate_productImageCreate_product { @@ -201,6 +214,7 @@ export interface ProductImageCreate_productImageCreate_product { pricing: ProductImageCreate_productImageCreate_product_pricing | null; images: (ProductImageCreate_productImageCreate_product_images | null)[] | null; variants: (ProductImageCreate_productImageCreate_product_variants | null)[] | null; + weight: ProductImageCreate_productImageCreate_product_weight | null; } export interface ProductImageCreate_productImageCreate { diff --git a/src/products/types/ProductImageUpdate.ts b/src/products/types/ProductImageUpdate.ts index abb5401cb..26adab936 100644 --- a/src/products/types/ProductImageUpdate.ts +++ b/src/products/types/ProductImageUpdate.ts @@ -169,6 +169,12 @@ export interface ProductImageUpdate_productImageUpdate_product_variants_stocks { warehouse: ProductImageUpdate_productImageUpdate_product_variants_stocks_warehouse; } +export interface ProductImageUpdate_productImageUpdate_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductImageUpdate_productImageUpdate_product_variants { __typename: "ProductVariant"; id: string; @@ -178,6 +184,13 @@ export interface ProductImageUpdate_productImageUpdate_product_variants { margin: number | null; stocks: (ProductImageUpdate_productImageUpdate_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: ProductImageUpdate_productImageUpdate_product_variants_weight | null; +} + +export interface ProductImageUpdate_productImageUpdate_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface ProductImageUpdate_productImageUpdate_product { @@ -201,6 +214,7 @@ export interface ProductImageUpdate_productImageUpdate_product { pricing: ProductImageUpdate_productImageUpdate_product_pricing | null; images: (ProductImageUpdate_productImageUpdate_product_images | null)[] | null; variants: (ProductImageUpdate_productImageUpdate_product_variants | null)[] | null; + weight: ProductImageUpdate_productImageUpdate_product_weight | null; } export interface ProductImageUpdate_productImageUpdate { diff --git a/src/products/types/ProductUpdate.ts b/src/products/types/ProductUpdate.ts index 9ea3e5fd8..6a4e68411 100644 --- a/src/products/types/ProductUpdate.ts +++ b/src/products/types/ProductUpdate.ts @@ -169,6 +169,12 @@ export interface ProductUpdate_productUpdate_product_variants_stocks { warehouse: ProductUpdate_productUpdate_product_variants_stocks_warehouse; } +export interface ProductUpdate_productUpdate_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductUpdate_productUpdate_product_variants { __typename: "ProductVariant"; id: string; @@ -178,6 +184,13 @@ export interface ProductUpdate_productUpdate_product_variants { margin: number | null; stocks: (ProductUpdate_productUpdate_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: ProductUpdate_productUpdate_product_variants_weight | null; +} + +export interface ProductUpdate_productUpdate_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface ProductUpdate_productUpdate_product { @@ -201,6 +214,7 @@ export interface ProductUpdate_productUpdate_product { pricing: ProductUpdate_productUpdate_product_pricing | null; images: (ProductUpdate_productUpdate_product_images | null)[] | null; variants: (ProductUpdate_productUpdate_product_variants | null)[] | null; + weight: ProductUpdate_productUpdate_product_weight | null; } export interface ProductUpdate_productUpdate { diff --git a/src/products/types/ProductVariant.ts b/src/products/types/ProductVariant.ts index ec79ea8ed..78926e644 100644 --- a/src/products/types/ProductVariant.ts +++ b/src/products/types/ProductVariant.ts @@ -103,6 +103,12 @@ export interface ProductVariant_stocks { warehouse: ProductVariant_stocks_warehouse; } +export interface ProductVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductVariant { __typename: "ProductVariant"; id: string; @@ -115,4 +121,5 @@ export interface ProductVariant { sku: string; stocks: (ProductVariant_stocks | null)[] | null; trackInventory: boolean; + weight: ProductVariant_weight | null; } diff --git a/src/products/types/ProductVariantDetails.ts b/src/products/types/ProductVariantDetails.ts index 3e7de3718..43a1871e7 100644 --- a/src/products/types/ProductVariantDetails.ts +++ b/src/products/types/ProductVariantDetails.ts @@ -103,6 +103,12 @@ export interface ProductVariantDetails_productVariant_stocks { warehouse: ProductVariantDetails_productVariant_stocks_warehouse; } +export interface ProductVariantDetails_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface ProductVariantDetails_productVariant { __typename: "ProductVariant"; id: string; @@ -115,6 +121,7 @@ export interface ProductVariantDetails_productVariant { sku: string; stocks: (ProductVariantDetails_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: ProductVariantDetails_productVariant_weight | null; } export interface ProductVariantDetails { diff --git a/src/products/types/SimpleProductUpdate.ts b/src/products/types/SimpleProductUpdate.ts index 7e4d34600..c4ace4ad5 100644 --- a/src/products/types/SimpleProductUpdate.ts +++ b/src/products/types/SimpleProductUpdate.ts @@ -169,6 +169,12 @@ export interface SimpleProductUpdate_productUpdate_product_variants_stocks { warehouse: SimpleProductUpdate_productUpdate_product_variants_stocks_warehouse; } +export interface SimpleProductUpdate_productUpdate_product_variants_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface SimpleProductUpdate_productUpdate_product_variants { __typename: "ProductVariant"; id: string; @@ -178,6 +184,13 @@ export interface SimpleProductUpdate_productUpdate_product_variants { margin: number | null; stocks: (SimpleProductUpdate_productUpdate_product_variants_stocks | null)[] | null; trackInventory: boolean; + weight: SimpleProductUpdate_productUpdate_product_variants_weight | null; +} + +export interface SimpleProductUpdate_productUpdate_product_weight { + __typename: "Weight"; + unit: string; + value: number; } export interface SimpleProductUpdate_productUpdate_product { @@ -201,6 +214,7 @@ export interface SimpleProductUpdate_productUpdate_product { pricing: SimpleProductUpdate_productUpdate_product_pricing | null; images: (SimpleProductUpdate_productUpdate_product_images | null)[] | null; variants: (SimpleProductUpdate_productUpdate_product_variants | null)[] | null; + weight: SimpleProductUpdate_productUpdate_product_weight | null; } export interface SimpleProductUpdate_productUpdate { @@ -312,6 +326,12 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_stocks warehouse: SimpleProductUpdate_productVariantUpdate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantUpdate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface SimpleProductUpdate_productVariantUpdate_productVariant { __typename: "ProductVariant"; id: string; @@ -324,6 +344,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant { sku: string; stocks: (SimpleProductUpdate_productVariantUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: SimpleProductUpdate_productVariantUpdate_productVariant_weight | null; } export interface SimpleProductUpdate_productVariantUpdate { @@ -436,6 +457,12 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface SimpleProductUpdate_productVariantStocksCreate_productVariant { __typename: "ProductVariant"; id: string; @@ -448,6 +475,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant { sku: string; stocks: (SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: SimpleProductUpdate_productVariantStocksCreate_productVariant_weight | null; } export interface SimpleProductUpdate_productVariantStocksCreate { @@ -559,6 +587,12 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface SimpleProductUpdate_productVariantStocksDelete_productVariant { __typename: "ProductVariant"; id: string; @@ -571,6 +605,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant { sku: string; stocks: (SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: SimpleProductUpdate_productVariantStocksDelete_productVariant_weight | null; } export interface SimpleProductUpdate_productVariantStocksDelete { @@ -683,6 +718,12 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_s warehouse: SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse; } +export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant { __typename: "ProductVariant"; id: string; @@ -695,6 +736,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant { sku: string; stocks: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight | null; } export interface SimpleProductUpdate_productVariantStocksUpdate { diff --git a/src/products/types/VariantCreate.ts b/src/products/types/VariantCreate.ts index 6d8e19e5c..004894e9b 100644 --- a/src/products/types/VariantCreate.ts +++ b/src/products/types/VariantCreate.ts @@ -111,6 +111,12 @@ export interface VariantCreate_productVariantCreate_productVariant_stocks { warehouse: VariantCreate_productVariantCreate_productVariant_stocks_warehouse; } +export interface VariantCreate_productVariantCreate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface VariantCreate_productVariantCreate_productVariant { __typename: "ProductVariant"; id: string; @@ -123,6 +129,7 @@ export interface VariantCreate_productVariantCreate_productVariant { sku: string; stocks: (VariantCreate_productVariantCreate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: VariantCreate_productVariantCreate_productVariant_weight | null; } export interface VariantCreate_productVariantCreate { diff --git a/src/products/types/VariantImageAssign.ts b/src/products/types/VariantImageAssign.ts index fad6f55d6..ac72c1c4f 100644 --- a/src/products/types/VariantImageAssign.ts +++ b/src/products/types/VariantImageAssign.ts @@ -111,6 +111,12 @@ export interface VariantImageAssign_variantImageAssign_productVariant_stocks { warehouse: VariantImageAssign_variantImageAssign_productVariant_stocks_warehouse; } +export interface VariantImageAssign_variantImageAssign_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface VariantImageAssign_variantImageAssign_productVariant { __typename: "ProductVariant"; id: string; @@ -123,6 +129,7 @@ export interface VariantImageAssign_variantImageAssign_productVariant { sku: string; stocks: (VariantImageAssign_variantImageAssign_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: VariantImageAssign_variantImageAssign_productVariant_weight | null; } export interface VariantImageAssign_variantImageAssign { diff --git a/src/products/types/VariantImageUnassign.ts b/src/products/types/VariantImageUnassign.ts index 51b14b8c0..8d7d870ac 100644 --- a/src/products/types/VariantImageUnassign.ts +++ b/src/products/types/VariantImageUnassign.ts @@ -111,6 +111,12 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant_stocks warehouse: VariantImageUnassign_variantImageUnassign_productVariant_stocks_warehouse; } +export interface VariantImageUnassign_variantImageUnassign_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface VariantImageUnassign_variantImageUnassign_productVariant { __typename: "ProductVariant"; id: string; @@ -123,6 +129,7 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant { sku: string; stocks: (VariantImageUnassign_variantImageUnassign_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: VariantImageUnassign_variantImageUnassign_productVariant_weight | null; } export interface VariantImageUnassign_variantImageUnassign { diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index 4ed244606..b898c17dc 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -111,6 +111,12 @@ export interface VariantUpdate_productVariantUpdate_productVariant_stocks { warehouse: VariantUpdate_productVariantUpdate_productVariant_stocks_warehouse; } +export interface VariantUpdate_productVariantUpdate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface VariantUpdate_productVariantUpdate_productVariant { __typename: "ProductVariant"; id: string; @@ -123,6 +129,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant { sku: string; stocks: (VariantUpdate_productVariantUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: VariantUpdate_productVariantUpdate_productVariant_weight | null; } export interface VariantUpdate_productVariantUpdate { @@ -235,6 +242,12 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_stocks warehouse: VariantUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse; } +export interface VariantUpdate_productVariantStocksUpdate_productVariant_weight { + __typename: "Weight"; + unit: string; + value: number; +} + export interface VariantUpdate_productVariantStocksUpdate_productVariant { __typename: "ProductVariant"; id: string; @@ -247,6 +260,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant { sku: string; stocks: (VariantUpdate_productVariantStocksUpdate_productVariant_stocks | null)[] | null; trackInventory: boolean; + weight: VariantUpdate_productVariantStocksUpdate_productVariant_weight | null; } export interface VariantUpdate_productVariantStocksUpdate { @@ -337,4 +351,5 @@ export interface VariantUpdateVariables { sku?: string | null; trackInventory: boolean; stocks: StockInput[]; + weight?: any | null; } diff --git a/src/products/views/ProductVariant.tsx b/src/products/views/ProductVariant.tsx index 5f9c10584..bb7b10a22 100644 --- a/src/products/views/ProductVariant.tsx +++ b/src/products/views/ProductVariant.tsx @@ -9,7 +9,8 @@ import { commonMessages } from "@saleor/intl"; import NotFoundPage from "@saleor/components/NotFoundPage"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import { useWarehouseList } from "@saleor/warehouses/queries"; -import { decimal } from "../../misc"; +import useShop from "@saleor/hooks/useShop"; +import { decimal, weight } from "../../misc"; import ProductVariantDeleteDialog from "../components/ProductVariantDeleteDialog"; import ProductVariantPage, { ProductVariantPageSubmitData @@ -40,6 +41,7 @@ export const ProductVariant: React.FC = ({ productId, params }) => { + const shop = useShop(); const navigate = useNavigator(); const notify = useNotifier(); const intl = useIntl(); @@ -129,6 +131,7 @@ export const ProductVariant: React.FC = ({ <> = ({ stocks: data.updateStocks.map( mapFormsetStockToStockInput ), - trackInventory: data.trackInventory + trackInventory: data.trackInventory, + weight: weight(data.weight) }) } onVariantClick={variantId => { diff --git a/src/products/views/ProductVariantCreate.tsx b/src/products/views/ProductVariantCreate.tsx index fce437e40..b1545c2f2 100644 --- a/src/products/views/ProductVariantCreate.tsx +++ b/src/products/views/ProductVariantCreate.tsx @@ -8,7 +8,7 @@ import useShop from "@saleor/hooks/useShop"; import NotFoundPage from "@saleor/components/NotFoundPage"; import { commonMessages } from "@saleor/intl"; import { useWarehouseList } from "@saleor/warehouses/queries"; -import { decimal } from "../../misc"; +import { decimal, weight } from "../../misc"; import ProductVariantCreatePage, { ProductVariantCreatePageSubmitData } from "../components/ProductVariantCreatePage"; @@ -82,7 +82,8 @@ export const ProductVariant: React.FC = ({ quantity: parseInt(stock.value, 0), warehouse: stock.id })), - trackInventory: true + trackInventory: true, + weight: weight(formData.weight) } } }); @@ -120,6 +121,7 @@ export const ProductVariant: React.FC = ({ edge => edge.node ) || [] } + weightUnit={shop?.defaultWeightUnit} /> ); diff --git a/src/storybook/stories/products/ProductVariantCreatePage.tsx b/src/storybook/stories/products/ProductVariantCreatePage.tsx index d5ef0ac0b..f15d829ff 100644 --- a/src/storybook/stories/products/ProductVariantCreatePage.tsx +++ b/src/storybook/stories/products/ProductVariantCreatePage.tsx @@ -15,6 +15,7 @@ storiesOf("Views / Products / Create product variant", module) .add("default", () => ( ( ( ( ( ( ( undefined} diff --git a/src/utils/errors/product.ts b/src/utils/errors/product.ts index 0886770ec..01baeec1c 100644 --- a/src/utils/errors/product.ts +++ b/src/utils/errors/product.ts @@ -14,15 +14,26 @@ const messages = defineMessages({ attributeCannotBeAssigned: { defaultMessage: "This attribute cannot be assigned to this product type" }, + attributeRequired: { + defaultMessage: "All attributes should have value", + description: "product attribute error" + }, attributeVariantsDisabled: { defaultMessage: "Variants are disabled in this product type" }, + duplicatedInputItem: { + defaultMessage: "Variant with these attributes already exists" + }, skuUnique: { defaultMessage: "SKUs must be unique", description: "bulk variant create error" }, variantNoDigitalContent: { defaultMessage: "This variant does not have any digital content" + }, + variantUnique: { + defaultMessage: "This variant already exists", + description: "product attribute error" } }); @@ -38,6 +49,8 @@ function getProductErrorMessage( return intl.formatMessage(messages.attributeCannotBeAssigned); case ProductErrorCode.ATTRIBUTE_VARIANTS_DISABLED: return intl.formatMessage(messages.attributeVariantsDisabled); + case ProductErrorCode.DUPLICATED_INPUT_ITEM: + return intl.formatMessage(messages.duplicatedInputItem); case ProductErrorCode.GRAPHQL_ERROR: return intl.formatMessage(commonErrorMessages.graphqlError); case ProductErrorCode.REQUIRED: @@ -54,6 +67,24 @@ function getProductErrorMessage( return undefined; } +export function getProductVariantAttributeErrorMessage( + err: Omit | undefined, + intl: IntlShape +): string { + if (err) { + switch (err.code) { + case ProductErrorCode.REQUIRED: + return intl.formatMessage(messages.attributeRequired); + case ProductErrorCode.UNIQUE: + return intl.formatMessage(messages.variantUnique); + default: + return getProductErrorMessage(err, intl); + } + } + + return undefined; +} + export function getBulkProductErrorMessage( err: BulkProductErrorFragment | undefined, intl: IntlShape