Handle attribute errors in product views
This commit is contained in:
parent
369fd09853
commit
ee1ecff1f8
6 changed files with 51 additions and 26 deletions
|
@ -8,10 +8,10 @@ import SingleAutocompleteSelectField, {
|
|||
SingleAutocompleteChoiceType
|
||||
} from "@saleor/components/SingleAutocompleteSelectField";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||
import { ProductVariant_attributes_attribute_values } from "@saleor/fragments/types/ProductVariant";
|
||||
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
|
||||
import { commonMessages } from "@saleor/intl";
|
||||
import { VariantCreate_productVariantCreate_errors } from "@saleor/products/types/VariantCreate";
|
||||
import { getProductVariantAttributeErrorMessage } from "@saleor/utils/errors/product";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
@ -27,7 +27,7 @@ export type VariantAttributeInput = FormsetAtomicData<
|
|||
interface ProductVariantAttributesProps {
|
||||
attributes: VariantAttributeInput[];
|
||||
disabled: boolean;
|
||||
errors: VariantCreate_productVariantCreate_errors[];
|
||||
errors: ProductErrorFragment[];
|
||||
onChange: FormsetChange<VariantAttributeInputData>;
|
||||
}
|
||||
|
||||
|
@ -84,31 +84,46 @@ const ProductVariantAttributes: React.FC<ProductVariantAttributesProps> = ({
|
|||
{attributes === undefined ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
attributes.map(attribute => (
|
||||
<SingleAutocompleteSelectField
|
||||
key={attribute.id}
|
||||
disabled={disabled}
|
||||
displayValue={getAttributeDisplayValue(
|
||||
attribute.id,
|
||||
attribute.value,
|
||||
attributes
|
||||
)}
|
||||
label={attribute.label}
|
||||
name={`attribute:${attribute.id}`}
|
||||
onChange={event => onChange(attribute.id, event.target.value)}
|
||||
value={getAttributeValue(attribute.id, attributes)}
|
||||
choices={getAttributeValueChoices(attribute.id, attributes)}
|
||||
allowCustomValues
|
||||
data-test="variant-attribute-input"
|
||||
/>
|
||||
))
|
||||
attributes.map(attribute => {
|
||||
const error = errors.find(
|
||||
err => err.attributeId === attribute.id
|
||||
);
|
||||
|
||||
return (
|
||||
<SingleAutocompleteSelectField
|
||||
key={attribute.id}
|
||||
disabled={disabled}
|
||||
displayValue={getAttributeDisplayValue(
|
||||
attribute.id,
|
||||
attribute.value,
|
||||
attributes
|
||||
)}
|
||||
emptyOption
|
||||
error={!!error}
|
||||
helperText={getProductVariantAttributeErrorMessage(
|
||||
error,
|
||||
intl
|
||||
)}
|
||||
label={attribute.label}
|
||||
name={`attribute:${attribute.id}`}
|
||||
onChange={event => onChange(attribute.id, event.target.value)}
|
||||
value={getAttributeValue(attribute.id, attributes)}
|
||||
choices={getAttributeValueChoices(attribute.id, attributes)}
|
||||
allowCustomValues
|
||||
data-test="variant-attribute-input"
|
||||
/>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</Grid>
|
||||
{errors.length > 0 && (
|
||||
<>
|
||||
<FormSpacer />
|
||||
{errors
|
||||
.filter(error => error.field === "attributes")
|
||||
.filter(
|
||||
error =>
|
||||
error.field === "attributes" && error.attributeId === null
|
||||
)
|
||||
.map(error => (
|
||||
<Typography color="error" key={error.code}>
|
||||
{getProductVariantAttributeErrorMessage(error, intl)}
|
||||
|
|
|
@ -28,6 +28,9 @@ const useStyles = makeStyles(
|
|||
colName: {
|
||||
paddingLeft: 0
|
||||
},
|
||||
firstVariant: {
|
||||
width: 88
|
||||
},
|
||||
link: {
|
||||
cursor: "pointer"
|
||||
},
|
||||
|
@ -126,7 +129,10 @@ const ProductVariantNavigation: React.FC<ProductVariantNavigationProps> = props
|
|||
className={classNames(
|
||||
classes.colAvatar,
|
||||
classes.tabActive,
|
||||
classes.noHandle
|
||||
classes.noHandle,
|
||||
{
|
||||
[classes.firstVariant]: variants.length === 0
|
||||
}
|
||||
)}
|
||||
thumbnail={null}
|
||||
colSpan={2}
|
||||
|
|
|
@ -8,13 +8,13 @@ import { MetadataFormData } from "@saleor/components/Metadata";
|
|||
import Metadata from "@saleor/components/Metadata/Metadata";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||
import { ProductVariant } from "@saleor/fragments/types/ProductVariant";
|
||||
import { WarehouseFragment } from "@saleor/fragments/types/WarehouseFragment";
|
||||
import useFormset, {
|
||||
FormsetChange,
|
||||
FormsetData
|
||||
} from "@saleor/hooks/useFormset";
|
||||
import { VariantUpdate_productVariantUpdate_errors } from "@saleor/products/types/VariantUpdate";
|
||||
import {
|
||||
getAttributeInputFromVariant,
|
||||
getStockInputFromVariant
|
||||
|
@ -56,7 +56,7 @@ export interface ProductVariantPageSubmitData
|
|||
interface ProductVariantPageProps {
|
||||
defaultWeightUnit: string;
|
||||
variant?: ProductVariant;
|
||||
errors: VariantUpdate_productVariantUpdate_errors[];
|
||||
errors: ProductErrorFragment[];
|
||||
saveButtonBarState: ConfirmButtonTransitionState;
|
||||
loading?: boolean;
|
||||
placeholderImage?: string;
|
||||
|
|
|
@ -36,14 +36,17 @@ storiesOf("Views / Products / Create product variant", module)
|
|||
disabled={false}
|
||||
errors={[
|
||||
{
|
||||
attributeId: product.productType.variantAttributes[0].id,
|
||||
code: ProductErrorCode.REQUIRED,
|
||||
field: "attributes"
|
||||
},
|
||||
{
|
||||
attributeId: null,
|
||||
code: ProductErrorCode.UNIQUE,
|
||||
field: "attributes"
|
||||
},
|
||||
{
|
||||
attributeId: null,
|
||||
code: ProductErrorCode.ALREADY_EXISTS,
|
||||
field: "sku"
|
||||
}
|
||||
|
|
|
@ -86,14 +86,17 @@ storiesOf("Views / Products / Product variant details", module)
|
|||
saveButtonBarState="default"
|
||||
errors={[
|
||||
{
|
||||
attributeId: variant.attributes[0].attribute.id,
|
||||
code: ProductErrorCode.REQUIRED,
|
||||
field: "attributes"
|
||||
},
|
||||
{
|
||||
attributeId: null,
|
||||
code: ProductErrorCode.UNIQUE,
|
||||
field: "attributes"
|
||||
},
|
||||
{
|
||||
attributeId: null,
|
||||
code: ProductErrorCode.ALREADY_EXISTS,
|
||||
field: "sku"
|
||||
}
|
||||
|
|
|
@ -83,8 +83,6 @@ export function getProductVariantAttributeErrorMessage(
|
|||
): string {
|
||||
if (err) {
|
||||
switch (err.code) {
|
||||
case ProductErrorCode.REQUIRED:
|
||||
return intl.formatMessage(messages.attributeRequired);
|
||||
case ProductErrorCode.UNIQUE:
|
||||
return intl.formatMessage(messages.variantUnique);
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue