refactor after review

This commit is contained in:
Magdalena Markusik 2020-09-25 15:27:57 +02:00
parent c0d02d6943
commit cc166f463c
2 changed files with 29 additions and 42 deletions

View file

@ -6,12 +6,11 @@ import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography"; import Typography from "@material-ui/core/Typography";
import { PageErrorFragment } from "@saleor/fragments/types/PageErrorFragment"; import { PageErrorFragment } from "@saleor/fragments/types/PageErrorFragment";
import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment"; import { ProductErrorFragment } from "@saleor/fragments/types/ProductErrorFragment";
import { PageErrorCode, ProductErrorCode } from "@saleor/types/globalTypes"; import { getFieldError, getProductErrorMessage } from "@saleor/utils/errors";
import { getProductErrorMessage } from "@saleor/utils/errors";
import getPageErrorMessage from "@saleor/utils/errors/page"; import getPageErrorMessage from "@saleor/utils/errors/page";
import classNames from "classnames"; import classNames from "classnames";
import React from "react"; import React from "react";
import { FormattedMessage, useIntl } from "react-intl"; import { defineMessages, FormattedMessage, useIntl } from "react-intl";
import slugify from "slugify"; import slugify from "slugify";
import CardTitle from "../CardTitle"; import CardTitle from "../CardTitle";
@ -23,16 +22,7 @@ enum SeoField {
description = "seoDescription" description = "seoDescription"
} }
const DEFAULT_INPUT_MESSAGE = const SLUG_REGEX = /^[a-zA-Z0-9\-\_]+$/;
"If empty, the preview shows what will be autogenerated.";
interface Error {
__typename: "ProductError" | "PageError";
field: string | null;
code: ProductErrorCode | PageErrorCode;
}
const SLUG_REGEX = /^[a-z0-9]+(?:[\-a-z0-9]+)*$/;
const useStyles = makeStyles( const useStyles = makeStyles(
theme => ({ theme => ({
@ -88,7 +78,7 @@ interface SeoFormProps {
description?: string; description?: string;
descriptionPlaceholder: string; descriptionPlaceholder: string;
disabled?: boolean; disabled?: boolean;
errors?: ProductErrorFragment[] | PageErrorFragment[]; errors?: Array<PageErrorFragment | ProductErrorFragment>;
loading?: boolean; loading?: boolean;
helperText?: string; helperText?: string;
isCreating?: boolean; isCreating?: boolean;
@ -105,7 +95,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
description, description,
descriptionPlaceholder, descriptionPlaceholder,
disabled, disabled,
errors, errors = [],
helperText, helperText,
isCreating = false, isCreating = false,
loading, loading,
@ -125,33 +115,27 @@ const SeoForm: React.FC<SeoFormProps> = props => {
const shouldDisplayHelperText = helperText && !expanded; const shouldDisplayHelperText = helperText && !expanded;
const getFilteredErrors = () => const { seoFieldMessage } = defineMessages({
(errors as Error[])?.filter(({ field }) => seoFieldMessage: {
Object.keys(SeoField).includes(field) defaultMessage: "If empty, the preview shows what will be autogenerated."
) || []; }
});
const getError = (fieldName: SeoField) => const getSlugHelperMessage = () => {
getFilteredErrors().find(({ field }) => fieldName === field); const error = !!getError(SeoField.slug);
const isError = (fieldName: SeoField) => !!getError(fieldName);
const getSlugHelperText = () => {
const error = isError(SeoField.slug);
if (isCreating && !error) { if (isCreating && !error) {
return intl.formatMessage({ return intl.formatMessage(seoFieldMessage);
defaultMessage: DEFAULT_INPUT_MESSAGE
});
} }
if (error) { if (error) {
return getSlugErrorText(); return getSlugErrorMessage();
} }
return ""; return "";
}; };
const getSlugErrorText = () => { const getSlugErrorMessage = () => {
const error = getError(SeoField.slug); const error = getError(SeoField.slug);
const { __typename: type } = error; const { __typename: type } = error;
@ -163,11 +147,13 @@ const SeoForm: React.FC<SeoFormProps> = props => {
const handleSlugChange = event => { const handleSlugChange = event => {
const { value } = event.target; const { value } = event.target;
if (value === "" || !!value.match(SLUG_REGEX)) { if (value === "" || SLUG_REGEX.test(value)) {
onChange(event); onChange(event);
} }
}; };
const getError = fieldName => getFieldError(errors, fieldName);
return ( return (
<Card> <Card>
<CardTitle <CardTitle
@ -194,7 +180,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
{expanded && ( {expanded && (
<div className={classes.container}> <div className={classes.container}>
<TextField <TextField
error={isError(SeoField.slug)} error={!!getError(SeoField.slug)}
name={SeoField.slug} name={SeoField.slug}
label={ label={
<div className={classes.labelContainer}> <div className={classes.labelContainer}>
@ -215,7 +201,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
)} )}
</div> </div>
} }
helperText={getSlugHelperText()} helperText={getSlugHelperMessage()}
value={slug?.slice(0, 69)} value={slug?.slice(0, 69)}
disabled={loading || disabled} disabled={loading || disabled}
placeholder={slug || slugify(slugPlaceholder, { lower: true })} placeholder={slug || slugify(slugPlaceholder, { lower: true })}
@ -225,7 +211,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
<FormSpacer /> <FormSpacer />
<TextField <TextField
name={SeoField.title} name={SeoField.title}
error={isError(SeoField.title)} error={!!getError(SeoField.title)}
label={ label={
<div className={classes.labelContainer}> <div className={classes.labelContainer}>
<div className={classes.label}> <div className={classes.label}>
@ -245,9 +231,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
)} )}
</div> </div>
} }
helperText={intl.formatMessage({ helperText={intl.formatMessage(seoFieldMessage)}
defaultMessage: DEFAULT_INPUT_MESSAGE
})}
value={title?.slice(0, 69)} value={title?.slice(0, 69)}
disabled={loading || disabled} disabled={loading || disabled}
placeholder={titlePlaceholder} placeholder={titlePlaceholder}
@ -256,7 +240,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
/> />
<FormSpacer /> <FormSpacer />
<TextField <TextField
error={isError(SeoField.description)} error={!!getError(SeoField.description)}
name={SeoField.description} name={SeoField.description}
label={ label={
<div className={classes.labelContainer}> <div className={classes.labelContainer}>
@ -277,9 +261,7 @@ const SeoForm: React.FC<SeoFormProps> = props => {
)} )}
</div> </div>
} }
helperText={intl.formatMessage({ helperText={intl.formatMessage(seoFieldMessage)}
defaultMessage: DEFAULT_INPUT_MESSAGE
})}
value={description?.slice(0, 299)} value={description?.slice(0, 299)}
onChange={onChange} onChange={onChange}
disabled={loading || disabled} disabled={loading || disabled}

View file

@ -24,6 +24,9 @@ const messages = defineMessages({
duplicatedInputItem: { duplicatedInputItem: {
defaultMessage: "Variant with these attributes already exists" defaultMessage: "Variant with these attributes already exists"
}, },
nameAlreadyTaken: {
defaultMessage: "This name is already taken. Please provide another."
},
skuUnique: { skuUnique: {
defaultMessage: "SKUs must be unique", defaultMessage: "SKUs must be unique",
description: "bulk variant create error" description: "bulk variant create error"
@ -59,6 +62,8 @@ function getProductErrorMessage(
return intl.formatMessage(messages.variantNoDigitalContent); return intl.formatMessage(messages.variantNoDigitalContent);
case ProductErrorCode.INVALID: case ProductErrorCode.INVALID:
return intl.formatMessage(commonErrorMessages.invalid); return intl.formatMessage(commonErrorMessages.invalid);
case ProductErrorCode.UNIQUE:
return intl.formatMessage(messages.nameAlreadyTaken);
default: default:
return intl.formatMessage(commonErrorMessages.unknownError); return intl.formatMessage(commonErrorMessages.unknownError);
} }