diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c9489724..d00be6b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ All notable, unreleased changes to this project will be documented in this file. - Change plural form of "informations" to "information" strings across the app #722 by @mmarkusik - Fix misaligned rich text draft controls - #725 by @orzechdev - Allow taxes to be configured per product - #728 by @dominik-zeglen +- Add default variant indicator for variant nav - #741 by @krzysztofwolski - Fix style of product type attributes empty table - #744 by @orzechdev - Fix order draft back button redirect - #753 by @orzechdev diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 435914cf8..13fb9f884 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -4516,6 +4516,10 @@ "context": "button", "string": "Choose photos" }, + "src_dot_products_dot_components_dot_ProductVariantNavigation_dot_1222345317": { + "context": "default product variant indicator", + "string": "Default" + }, "src_dot_products_dot_components_dot_ProductVariantNavigation_dot_2153006789": { "context": "section header", "string": "Variants" @@ -4550,14 +4554,14 @@ "context": "product variant inventory", "string": "Unavailable" }, - "src_dot_products_dot_components_dot_ProductVariants_dot_1120495519": { - "context": "default variant label", - "string": "default" - }, "src_dot_products_dot_components_dot_ProductVariants_dot_1134347598": { "context": "product variant price", "string": "Price" }, + "src_dot_products_dot_components_dot_ProductVariants_dot_1222345317": { + "context": "default product variant indicator", + "string": "Default" + }, "src_dot_products_dot_components_dot_ProductVariants_dot_1252282784": { "context": "product variant inventory", "string": "{stockQuantity,plural,one{{stockQuantity} available} other{{stockQuantity} available}}" diff --git a/src/fragments/products.ts b/src/fragments/products.ts index b0d729069..33e0fbc33 100644 --- a/src/fragments/products.ts +++ b/src/fragments/products.ts @@ -253,6 +253,9 @@ export const fragmentVariant = gql` url } } + defaultVariant { + id + } } sku stocks { diff --git a/src/fragments/types/ProductVariant.ts b/src/fragments/types/ProductVariant.ts index 928e068c8..9cc5da325 100644 --- a/src/fragments/types/ProductVariant.ts +++ b/src/fragments/types/ProductVariant.ts @@ -99,6 +99,11 @@ export interface ProductVariant_product_variants { images: (ProductVariant_product_variants_images | null)[] | null; } +export interface ProductVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface ProductVariant_product { __typename: "Product"; id: string; diff --git a/src/products/components/ProductVariantNavigation/ProductVariantNavigation.tsx b/src/products/components/ProductVariantNavigation/ProductVariantNavigation.tsx index 6d9214d22..bcb573dad 100644 --- a/src/products/components/ProductVariantNavigation/ProductVariantNavigation.tsx +++ b/src/products/components/ProductVariantNavigation/ProductVariantNavigation.tsx @@ -1,6 +1,7 @@ import Button from "@material-ui/core/Button"; import Card from "@material-ui/core/Card"; import { makeStyles } from "@material-ui/core/styles"; +import { fade } from "@material-ui/core/styles/colorManipulator"; import TableCell from "@material-ui/core/TableCell"; import TableRow from "@material-ui/core/TableRow"; import CardTitle from "@saleor/components/CardTitle"; @@ -16,7 +17,7 @@ import classNames from "classnames"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; -import { maybe, renderCollection } from "../../../misc"; +import { renderCollection } from "../../../misc"; import { ProductVariantCreateData_product_variants } from "../../types/ProductVariantCreateData"; import { ProductVariantDetails_productVariant } from "../../types/ProductVariantDetails"; @@ -28,6 +29,10 @@ const useStyles = makeStyles( colName: { paddingLeft: 0 }, + defaultVariant: { + color: fade(theme.palette.text.secondary, 0.6), + display: "block" + }, firstVariant: { width: 88 }, @@ -57,6 +62,7 @@ const useStyles = makeStyles( interface ProductVariantNavigationProps { current?: string; + defaultVariantId?: string; fallbackThumbnail: string; variants: | ProductVariantDetails_productVariant[] @@ -69,6 +75,7 @@ interface ProductVariantNavigationProps { const ProductVariantNavigation: React.FC = props => { const { current, + defaultVariantId, fallbackThumbnail, variants, onAdd, @@ -89,28 +96,37 @@ const ProductVariantNavigation: React.FC = props /> - {renderCollection(variants, (variant, variantIndex) => ( - onRowClick(variant.id) : undefined} - > - variant.images[0].url, - fallbackThumbnail - )} - /> - - {variant ? variant.name || variant.sku : } - - - ))} + {renderCollection(variants, (variant, variantIndex) => { + const isDefault = variant && variant.id === defaultVariantId; + const isActive = variant && variant.id === current; + return ( + onRowClick(variant.id) : undefined} + > + + + {variant ? variant.name || variant.sku : } + {isDefault && ( + + {intl.formatMessage({ + defaultMessage: "Default", + description: "default product variant indicator" + })} + + )} + + + ); + })} {onAdd ? ( diff --git a/src/products/components/ProductVariantPage/ProductVariantPage.tsx b/src/products/components/ProductVariantPage/ProductVariantPage.tsx index 3e19efa9e..777fcd907 100644 --- a/src/products/components/ProductVariantPage/ProductVariantPage.tsx +++ b/src/products/components/ProductVariantPage/ProductVariantPage.tsx @@ -15,6 +15,7 @@ import useFormset, { FormsetChange, FormsetData } from "@saleor/hooks/useFormset"; +import { VariantUpdate_productVariantUpdate_errors } from "@saleor/products/types/VariantUpdate"; import { getAttributeInputFromVariant, getStockInputFromVariant @@ -54,13 +55,16 @@ export interface ProductVariantPageSubmitData } interface ProductVariantPageProps { + defaultVariantId?: string; defaultWeightUnit: string; - variant?: ProductVariant; - errors: ProductErrorWithAttributesFragment[]; - saveButtonBarState: ConfirmButtonTransitionState; + errors: + | ProductErrorWithAttributesFragment[] + | VariantUpdate_productVariantUpdate_errors[]; + header: string; loading?: boolean; placeholderImage?: string; - header: string; + saveButtonBarState: ConfirmButtonTransitionState; + variant?: ProductVariant; warehouses: WarehouseFragment[]; onVariantReorder: ReorderAction; onAdd(); @@ -74,10 +78,11 @@ interface ProductVariantPageProps { } const ProductVariantPage: React.FC = ({ + defaultVariantId, defaultWeightUnit, errors, - loading, header, + loading, placeholderImage, saveButtonBarState, variant, @@ -171,7 +176,7 @@ const ProductVariantPage: React.FC = ({ {maybe(() => variant.product.name)} - {variant?.product?.defaultVariant.id !== variant?.id && ( + {variant?.product?.defaultVariant?.id !== variant?.id && ( @@ -192,6 +197,7 @@ const ProductVariantPage: React.FC = ({
variant.product.thumbnail.url )} diff --git a/src/products/components/ProductVariants/ProductVariants.tsx b/src/products/components/ProductVariants/ProductVariants.tsx index 7e12fd64b..cb533e8a1 100644 --- a/src/products/components/ProductVariants/ProductVariants.tsx +++ b/src/products/components/ProductVariants/ProductVariants.tsx @@ -355,8 +355,8 @@ export const ProductVariants: React.FC = props => { {isDefault && ( {intl.formatMessage({ - defaultMessage: "default", - description: "default variant label" + defaultMessage: "Default", + description: "default product variant indicator" })} )} @@ -399,7 +399,7 @@ export const ProductVariants: React.FC = props => { data-test="actions" onClick={e => e.stopPropagation()} > - {variant?.id !== product?.defaultVariant.id && ( + {variant?.id !== product?.defaultVariant?.id && ( onSetDefaultVariant(variant)} /> diff --git a/src/products/types/ProductVariantDetails.ts b/src/products/types/ProductVariantDetails.ts index 7227a7405..4eaf125a4 100644 --- a/src/products/types/ProductVariantDetails.ts +++ b/src/products/types/ProductVariantDetails.ts @@ -99,14 +99,19 @@ export interface ProductVariantDetails_productVariant_product_variants { images: (ProductVariantDetails_productVariant_product_variants_images | null)[] | null; } +export interface ProductVariantDetails_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface ProductVariantDetails_productVariant_product { __typename: "Product"; id: string; - defaultVariant: ProductVariantDetails_productVariant_product_defaultVariant | null; images: (ProductVariantDetails_productVariant_product_images | null)[] | null; name: string; thumbnail: ProductVariantDetails_productVariant_product_thumbnail | null; variants: (ProductVariantDetails_productVariant_product_variants | null)[] | null; + defaultVariant: ProductVariantDetails_productVariant_product_defaultVariant | null; } export interface ProductVariantDetails_productVariant_stocks_warehouse { diff --git a/src/products/types/SimpleProductUpdate.ts b/src/products/types/SimpleProductUpdate.ts index b0c1a04d3..13ba1db76 100644 --- a/src/products/types/SimpleProductUpdate.ts +++ b/src/products/types/SimpleProductUpdate.ts @@ -346,14 +346,19 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_product images: (SimpleProductUpdate_productVariantUpdate_productVariant_product_variants_images | null)[] | null; } +export interface SimpleProductUpdate_productVariantUpdate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface SimpleProductUpdate_productVariantUpdate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: SimpleProductUpdate_productVariantUpdate_productVariant_product_defaultVariant | null; images: (SimpleProductUpdate_productVariantUpdate_productVariant_product_images | null)[] | null; name: string; thumbnail: SimpleProductUpdate_productVariantUpdate_productVariant_product_thumbnail | null; variants: (SimpleProductUpdate_productVariantUpdate_productVariant_product_variants | null)[] | null; + defaultVariant: SimpleProductUpdate_productVariantUpdate_productVariant_product_defaultVariant | null; } export interface SimpleProductUpdate_productVariantUpdate_productVariant_stocks_warehouse { @@ -497,14 +502,19 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_p images: (SimpleProductUpdate_productVariantStocksCreate_productVariant_product_variants_images | null)[] | null; } +export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: SimpleProductUpdate_productVariantStocksCreate_productVariant_product_defaultVariant | null; images: (SimpleProductUpdate_productVariantStocksCreate_productVariant_product_images | null)[] | null; name: string; thumbnail: SimpleProductUpdate_productVariantStocksCreate_productVariant_product_thumbnail | null; variants: (SimpleProductUpdate_productVariantStocksCreate_productVariant_product_variants | null)[] | null; + defaultVariant: SimpleProductUpdate_productVariantStocksCreate_productVariant_product_defaultVariant | null; } export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_stocks_warehouse { @@ -647,14 +657,19 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_p images: (SimpleProductUpdate_productVariantStocksDelete_productVariant_product_variants_images | null)[] | null; } +export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_product { __typename: "Product"; id: string; - defaultVariant: SimpleProductUpdate_productVariantStocksDelete_productVariant_product_defaultVariant | null; images: (SimpleProductUpdate_productVariantStocksDelete_productVariant_product_images | null)[] | null; name: string; thumbnail: SimpleProductUpdate_productVariantStocksDelete_productVariant_product_thumbnail | null; variants: (SimpleProductUpdate_productVariantStocksDelete_productVariant_product_variants | null)[] | null; + defaultVariant: SimpleProductUpdate_productVariantStocksDelete_productVariant_product_defaultVariant | null; } export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_stocks_warehouse { @@ -798,14 +813,19 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_p images: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_variants_images | null)[] | null; } +export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant | null; images: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_images | null)[] | null; name: string; thumbnail: SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_thumbnail | null; variants: (SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_variants | null)[] | null; + defaultVariant: SimpleProductUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant | null; } export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse { diff --git a/src/products/types/VariantCreate.ts b/src/products/types/VariantCreate.ts index be28216f6..ad340028e 100644 --- a/src/products/types/VariantCreate.ts +++ b/src/products/types/VariantCreate.ts @@ -106,14 +106,19 @@ export interface VariantCreate_productVariantCreate_productVariant_product_varia images: (VariantCreate_productVariantCreate_productVariant_product_variants_images | null)[] | null; } +export interface VariantCreate_productVariantCreate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface VariantCreate_productVariantCreate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: VariantCreate_productVariantCreate_productVariant_product_defaultVariant | null; images: (VariantCreate_productVariantCreate_productVariant_product_images | null)[] | null; name: string; thumbnail: VariantCreate_productVariantCreate_productVariant_product_thumbnail | null; variants: (VariantCreate_productVariantCreate_productVariant_product_variants | null)[] | null; + defaultVariant: VariantCreate_productVariantCreate_productVariant_product_defaultVariant | null; } export interface VariantCreate_productVariantCreate_productVariant_stocks_warehouse { diff --git a/src/products/types/VariantImageAssign.ts b/src/products/types/VariantImageAssign.ts index 5dcf48722..871c1bf99 100644 --- a/src/products/types/VariantImageAssign.ts +++ b/src/products/types/VariantImageAssign.ts @@ -105,14 +105,19 @@ export interface VariantImageAssign_variantImageAssign_productVariant_product_va images: (VariantImageAssign_variantImageAssign_productVariant_product_variants_images | null)[] | null; } +export interface VariantImageAssign_variantImageAssign_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface VariantImageAssign_variantImageAssign_productVariant_product { __typename: "Product"; id: string; - defaultVariant: VariantImageAssign_variantImageAssign_productVariant_product_defaultVariant | null; images: (VariantImageAssign_variantImageAssign_productVariant_product_images | null)[] | null; name: string; thumbnail: VariantImageAssign_variantImageAssign_productVariant_product_thumbnail | null; variants: (VariantImageAssign_variantImageAssign_productVariant_product_variants | null)[] | null; + defaultVariant: VariantImageAssign_variantImageAssign_productVariant_product_defaultVariant | null; } export interface VariantImageAssign_variantImageAssign_productVariant_stocks_warehouse { diff --git a/src/products/types/VariantImageUnassign.ts b/src/products/types/VariantImageUnassign.ts index 347b3f992..719b9e8a6 100644 --- a/src/products/types/VariantImageUnassign.ts +++ b/src/products/types/VariantImageUnassign.ts @@ -105,14 +105,19 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant_produc images: (VariantImageUnassign_variantImageUnassign_productVariant_product_variants_images | null)[] | null; } +export interface VariantImageUnassign_variantImageUnassign_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface VariantImageUnassign_variantImageUnassign_productVariant_product { __typename: "Product"; id: string; - defaultVariant: VariantImageUnassign_variantImageUnassign_productVariant_product_defaultVariant | null; images: (VariantImageUnassign_variantImageUnassign_productVariant_product_images | null)[] | null; name: string; thumbnail: VariantImageUnassign_variantImageUnassign_productVariant_product_thumbnail | null; variants: (VariantImageUnassign_variantImageUnassign_productVariant_product_variants | null)[] | null; + defaultVariant: VariantImageUnassign_variantImageUnassign_productVariant_product_defaultVariant | null; } export interface VariantImageUnassign_variantImageUnassign_productVariant_stocks_warehouse { diff --git a/src/products/types/VariantUpdate.ts b/src/products/types/VariantUpdate.ts index 7bb411da3..88d3548e4 100644 --- a/src/products/types/VariantUpdate.ts +++ b/src/products/types/VariantUpdate.ts @@ -106,14 +106,19 @@ export interface VariantUpdate_productVariantUpdate_productVariant_product_varia images: (VariantUpdate_productVariantUpdate_productVariant_product_variants_images | null)[] | null; } +export interface VariantUpdate_productVariantUpdate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface VariantUpdate_productVariantUpdate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: VariantUpdate_productVariantUpdate_productVariant_product_defaultVariant | null; images: (VariantUpdate_productVariantUpdate_productVariant_product_images | null)[] | null; name: string; thumbnail: VariantUpdate_productVariantUpdate_productVariant_product_thumbnail | null; variants: (VariantUpdate_productVariantUpdate_productVariant_product_variants | null)[] | null; + defaultVariant: VariantUpdate_productVariantUpdate_productVariant_product_defaultVariant | null; } export interface VariantUpdate_productVariantUpdate_productVariant_stocks_warehouse { @@ -257,14 +262,19 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_product images: (VariantUpdate_productVariantStocksUpdate_productVariant_product_variants_images | null)[] | null; } +export interface VariantUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant { + __typename: "ProductVariant"; + id: string; +} + export interface VariantUpdate_productVariantStocksUpdate_productVariant_product { __typename: "Product"; id: string; - defaultVariant: VariantUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant | null; images: (VariantUpdate_productVariantStocksUpdate_productVariant_product_images | null)[] | null; name: string; thumbnail: VariantUpdate_productVariantStocksUpdate_productVariant_product_thumbnail | null; variants: (VariantUpdate_productVariantStocksUpdate_productVariant_product_variants | null)[] | null; + defaultVariant: VariantUpdate_productVariantStocksUpdate_productVariant_product_defaultVariant | null; } export interface VariantUpdate_productVariantStocksUpdate_productVariant_stocks_warehouse { diff --git a/src/products/views/ProductVariant.tsx b/src/products/views/ProductVariant.tsx index 2de88694b..7b99e3ba3 100644 --- a/src/products/views/ProductVariant.tsx +++ b/src/products/views/ProductVariant.tsx @@ -201,6 +201,7 @@ export const ProductVariant: React.FC = ({ - default + Default - default + Default - default + Default - default + Default