Display attribute errors in product view
This commit is contained in:
parent
bf295e4dce
commit
369fd09853
4 changed files with 81 additions and 60 deletions
|
@ -10,6 +10,7 @@ import { ProductErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
export interface ProductErrorFragment {
|
export interface ProductErrorFragment {
|
||||||
__typename: "ProductError";
|
__typename: "ProductError";
|
||||||
|
attributeId: string | null;
|
||||||
code: ProductErrorCode;
|
code: ProductErrorCode;
|
||||||
field: string | null;
|
field: string | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,12 @@ import MultiAutocompleteSelectField, {
|
||||||
import SingleAutocompleteSelectField, {
|
import SingleAutocompleteSelectField, {
|
||||||
SingleAutocompleteChoiceType
|
SingleAutocompleteChoiceType
|
||||||
} from "@saleor/components/SingleAutocompleteSelectField";
|
} from "@saleor/components/SingleAutocompleteSelectField";
|
||||||
|
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
|
||||||
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
|
import { FormsetAtomicData, FormsetChange } from "@saleor/hooks/useFormset";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ProductDetails_product_attributes_attribute_values } from "@saleor/products/types/ProductDetails";
|
import { ProductDetails_product_attributes_attribute_values } from "@saleor/products/types/ProductDetails";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
|
import { getProductErrorMessage } from "@saleor/utils/errors";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
@ -33,6 +35,7 @@ export type ProductAttributeInput = FormsetAtomicData<
|
||||||
export interface ProductAttributesProps {
|
export interface ProductAttributesProps {
|
||||||
attributes: ProductAttributeInput[];
|
attributes: ProductAttributeInput[];
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
errors: ProductErrorFragment[];
|
||||||
onChange: FormsetChange;
|
onChange: FormsetChange;
|
||||||
onMultiChange: FormsetChange;
|
onMultiChange: FormsetChange;
|
||||||
}
|
}
|
||||||
|
@ -125,6 +128,7 @@ function getSingleChoices(
|
||||||
const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
||||||
attributes,
|
attributes,
|
||||||
disabled,
|
disabled,
|
||||||
|
errors,
|
||||||
onChange,
|
onChange,
|
||||||
onMultiChange
|
onMultiChange
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -169,7 +173,12 @@ const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
||||||
{expanded && attributes.length > 0 && (
|
{expanded && attributes.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<Hr />
|
<Hr />
|
||||||
{attributes.map((attribute, attributeIndex) => (
|
{attributes.map((attribute, attributeIndex) => {
|
||||||
|
const error = errors.find(
|
||||||
|
err => err.attributeId === attribute.id
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
<React.Fragment key={attribute.id}>
|
<React.Fragment key={attribute.id}>
|
||||||
{attributeIndex > 0 && <Hr />}
|
{attributeIndex > 0 && <Hr />}
|
||||||
<Grid className={classes.attributeSection} variant="uniform">
|
<Grid className={classes.attributeSection} variant="uniform">
|
||||||
|
@ -193,6 +202,8 @@ const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
||||||
attribute.value[0]
|
attribute.value[0]
|
||||||
)}
|
)}
|
||||||
emptyOption
|
emptyOption
|
||||||
|
error={!!error}
|
||||||
|
helperText={getProductErrorMessage(error, intl)}
|
||||||
name={`attribute:${attribute.label}`}
|
name={`attribute:${attribute.label}`}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Value",
|
defaultMessage: "Value",
|
||||||
|
@ -208,6 +219,8 @@ const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
||||||
<MultiAutocompleteSelectField
|
<MultiAutocompleteSelectField
|
||||||
choices={getMultiChoices(attribute.data.values)}
|
choices={getMultiChoices(attribute.data.values)}
|
||||||
displayValues={getMultiDisplayValue(attribute)}
|
displayValues={getMultiDisplayValue(attribute)}
|
||||||
|
error={!!error}
|
||||||
|
helperText={getProductErrorMessage(error, intl)}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Values",
|
defaultMessage: "Values",
|
||||||
description: "attribute values"
|
description: "attribute values"
|
||||||
|
@ -223,7 +236,8 @@ const ProductAttributes: React.FC<ProductAttributesProps> = ({
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
|
@ -296,6 +296,7 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
{attributes.length > 0 && (
|
{attributes.length > 0 && (
|
||||||
<ProductAttributes
|
<ProductAttributes
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
|
errors={errors}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={handleAttributeChange}
|
onChange={handleAttributeChange}
|
||||||
onMultiChange={handleAttributeMultiChange}
|
onMultiChange={handleAttributeMultiChange}
|
||||||
|
|
|
@ -137,6 +137,7 @@ storiesOf("Views / Products / Product edit", module)
|
||||||
<ProductUpdatePage
|
<ProductUpdatePage
|
||||||
{...props}
|
{...props}
|
||||||
errors={([
|
errors={([
|
||||||
|
"attributes",
|
||||||
"basePrice",
|
"basePrice",
|
||||||
"category",
|
"category",
|
||||||
"chargeTaxes",
|
"chargeTaxes",
|
||||||
|
@ -148,10 +149,14 @@ storiesOf("Views / Products / Product edit", module)
|
||||||
"seoTitle",
|
"seoTitle",
|
||||||
"sku",
|
"sku",
|
||||||
"stockQuantity"
|
"stockQuantity"
|
||||||
] as Array<keyof ProductUpdatePageFormData>).map(field => ({
|
] as Array<keyof ProductUpdatePageFormData | "attributes">).map(
|
||||||
|
field => ({
|
||||||
__typename: "ProductError",
|
__typename: "ProductError",
|
||||||
|
attributeId:
|
||||||
|
field === "attributes" ? product.attributes[0].attribute.id : null,
|
||||||
code: ProductErrorCode.INVALID,
|
code: ProductErrorCode.INVALID,
|
||||||
field
|
field
|
||||||
}))}
|
})
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
Loading…
Reference in a new issue