Revert "Use error formatting in product type section"
This commit is contained in:
parent
90e5b317d4
commit
bf92214fc3
47 changed files with 417 additions and 466 deletions
|
@ -10,17 +10,16 @@ import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import SingleSelectField from "@saleor/components/SingleSelectField";
|
import SingleSelectField from "@saleor/components/SingleSelectField";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
import { UserError } from "@saleor/types";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import { getProductErrorMessage, getFormErrors } from "@saleor/utils/errors";
|
import { getFieldError } from "@saleor/utils/errors";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import { AttributePageFormData } from "../AttributePage";
|
import { AttributePageFormData } from "../AttributePage";
|
||||||
import { getAttributeSlugErrorMessage } from "../../errors";
|
|
||||||
|
|
||||||
export interface AttributeDetailsProps {
|
export interface AttributeDetailsProps {
|
||||||
canChangeType: boolean;
|
canChangeType: boolean;
|
||||||
data: AttributePageFormData;
|
data: AttributePageFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,8 +48,6 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const formErrors = getFormErrors(["name", "slug", "inputType"], errors);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -59,21 +56,21 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.name}
|
error={!!getFieldError(errors, "name")}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Default Label",
|
defaultMessage: "Default Label",
|
||||||
description: "attribute's label"
|
description: "attribute's label"
|
||||||
})}
|
})}
|
||||||
name={"name" as keyof AttributePageFormData}
|
name={"name" as keyof AttributePageFormData}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getProductErrorMessage(formErrors.name, intl)}
|
helperText={getFieldError(errors, "name")?.message}
|
||||||
value={data.name}
|
value={data.name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.slug}
|
error={!!getFieldError(errors, "slug")}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Attribute Code",
|
defaultMessage: "Attribute Code",
|
||||||
description: "attribute's slug short code label"
|
description: "attribute's slug short code label"
|
||||||
|
@ -82,7 +79,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
placeholder={slugify(data.name).toLowerCase()}
|
placeholder={slugify(data.name).toLowerCase()}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={
|
helperText={
|
||||||
getAttributeSlugErrorMessage(formErrors.slug, intl) ||
|
getFieldError(errors, "slug")?.message ||
|
||||||
intl.formatMessage({
|
intl.formatMessage({
|
||||||
defaultMessage:
|
defaultMessage:
|
||||||
"This is used internally. Make sure you don’t use spaces",
|
"This is used internally. Make sure you don’t use spaces",
|
||||||
|
@ -96,8 +93,8 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({
|
||||||
<SingleSelectField
|
<SingleSelectField
|
||||||
choices={inputTypeChoices}
|
choices={inputTypeChoices}
|
||||||
disabled={disabled || !canChangeType}
|
disabled={disabled || !canChangeType}
|
||||||
error={!!formErrors.inputType}
|
error={!!getFieldError(errors, "inputType")}
|
||||||
hint={getProductErrorMessage(formErrors.inputType, intl)}
|
hint={getFieldError(errors, "inputType")?.message}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Catalog Input type for Store Owner",
|
defaultMessage: "Catalog Input type for Store Owner",
|
||||||
description: "attribute's editor component"
|
description: "attribute's editor component"
|
||||||
|
|
|
@ -12,9 +12,8 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ReorderAction } from "@saleor/types";
|
import { ReorderAction, UserError } from "@saleor/types";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import {
|
import {
|
||||||
AttributeDetailsFragment,
|
AttributeDetailsFragment,
|
||||||
AttributeDetailsFragment_values
|
AttributeDetailsFragment_values
|
||||||
|
@ -26,7 +25,7 @@ import AttributeValues from "../AttributeValues";
|
||||||
export interface AttributePageProps {
|
export interface AttributePageProps {
|
||||||
attribute: AttributeDetailsFragment | null;
|
attribute: AttributeDetailsFragment | null;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
saveButtonBarState: ConfirmButtonTransitionState;
|
saveButtonBarState: ConfirmButtonTransitionState;
|
||||||
values: AttributeDetailsFragment_values[];
|
values: AttributeDetailsFragment_values[];
|
||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
|
|
|
@ -11,14 +11,14 @@ import ControlledCheckbox from "@saleor/components/ControlledCheckbox";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
import { UserError } from "@saleor/types";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
import { getFieldError } from "@saleor/utils/errors";
|
||||||
import { AttributePageFormData } from "../AttributePage";
|
import { AttributePageFormData } from "../AttributePage";
|
||||||
|
|
||||||
export interface AttributePropertiesProps {
|
export interface AttributePropertiesProps {
|
||||||
data: AttributePageFormData;
|
data: AttributePageFormData;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@ const AttributeProperties: React.FC<AttributePropertiesProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const formErrors = getFormErrors(["storefrontSearchPosition"], errors);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle title={intl.formatMessage(commonMessages.properties)} />
|
<CardTitle title={intl.formatMessage(commonMessages.properties)} />
|
||||||
|
@ -88,12 +86,11 @@ const AttributeProperties: React.FC<AttributePropertiesProps> = ({
|
||||||
{data.filterableInStorefront && (
|
{data.filterableInStorefront && (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.storefrontSearchPosition}
|
error={!!getFieldError(errors, "storefrontSearchPosition")}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getProductErrorMessage(
|
helperText={
|
||||||
formErrors.storefrontSearchPosition,
|
getFieldError(errors, "storefrontSearchPosition")?.message
|
||||||
intl
|
}
|
||||||
)}
|
|
||||||
name={"storefrontSearchPosition" as keyof AttributePageFormData}
|
name={"storefrontSearchPosition" as keyof AttributePageFormData}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Position in faceted navigation",
|
defaultMessage: "Position in faceted navigation",
|
||||||
|
|
|
@ -14,9 +14,8 @@ import Form from "@saleor/components/Form";
|
||||||
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { getFormErrors } from "@saleor/utils/errors";
|
import { UserError } from "@saleor/types";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
import { getFieldError } from "@saleor/utils/errors";
|
||||||
import { getAttributeValueErrorMessage } from "@saleor/attributes/errors";
|
|
||||||
import { AttributeDetails_attribute_values } from "../../types/AttributeDetails";
|
import { AttributeDetails_attribute_values } from "../../types/AttributeDetails";
|
||||||
|
|
||||||
export interface AttributeValueEditDialogFormData {
|
export interface AttributeValueEditDialogFormData {
|
||||||
|
@ -26,7 +25,7 @@ export interface AttributeValueEditDialogProps {
|
||||||
attributeValue: AttributeDetails_attribute_values | null;
|
attributeValue: AttributeDetails_attribute_values | null;
|
||||||
confirmButtonState: ConfirmButtonTransitionState;
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onSubmit: (data: AttributeValueEditDialogFormData) => void;
|
onSubmit: (data: AttributeValueEditDialogFormData) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -46,7 +45,6 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
|
||||||
name: maybe(() => attributeValue.name, "")
|
name: maybe(() => attributeValue.name, "")
|
||||||
};
|
};
|
||||||
const errors = useModalDialogErrors(apiErrors, open);
|
const errors = useModalDialogErrors(apiErrors, open);
|
||||||
const formErrors = getFormErrors(["name"], errors);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
|
<Dialog onClose={onClose} open={open} fullWidth maxWidth="sm">
|
||||||
|
@ -70,12 +68,9 @@ const AttributeValueEditDialog: React.FC<AttributeValueEditDialogProps> = ({
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus
|
autoFocus
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.name}
|
error={!!getFieldError(errors, "name")}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getAttributeValueErrorMessage(
|
helperText={getFieldError(errors, "name")?.message}
|
||||||
formErrors.name,
|
|
||||||
intl
|
|
||||||
)}
|
|
||||||
name={"name" as keyof AttributeValueEditDialogFormData}
|
name={"name" as keyof AttributeValueEditDialogFormData}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Name",
|
defaultMessage: "Name",
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
import { IntlShape, defineMessages } from "react-intl";
|
|
||||||
|
|
||||||
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
|
||||||
import { getProductErrorMessage } from "@saleor/utils/errors";
|
|
||||||
import { ProductErrorFragment } from "./types/ProductErrorFragment";
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
attributeSlugUnique: {
|
|
||||||
defaultMessage: "Attribute with this slug already exists"
|
|
||||||
},
|
|
||||||
attributeValueAlreadyExists: {
|
|
||||||
defaultMessage: "This value already exists within this attribute"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export function getAttributeSlugErrorMessage(
|
|
||||||
err: ProductErrorFragment,
|
|
||||||
intl: IntlShape
|
|
||||||
): string {
|
|
||||||
switch (err?.code) {
|
|
||||||
case ProductErrorCode.UNIQUE:
|
|
||||||
return intl.formatMessage(messages.attributeSlugUnique);
|
|
||||||
default:
|
|
||||||
return getProductErrorMessage(err, intl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAttributeValueErrorMessage(
|
|
||||||
err: ProductErrorFragment,
|
|
||||||
intl: IntlShape
|
|
||||||
): string {
|
|
||||||
switch (err?.code) {
|
|
||||||
case ProductErrorCode.ALREADY_EXISTS:
|
|
||||||
return intl.formatMessage(messages.attributeValueAlreadyExists);
|
|
||||||
default:
|
|
||||||
return getProductErrorMessage(err, intl);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,19 +35,12 @@ import {
|
||||||
AttributeValueUpdateVariables
|
AttributeValueUpdateVariables
|
||||||
} from "./types/AttributeValueUpdate";
|
} from "./types/AttributeValueUpdate";
|
||||||
|
|
||||||
export const productErrorFragment = gql`
|
|
||||||
fragment ProductErrorFragment on ProductError {
|
|
||||||
code
|
|
||||||
field
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const attributeBulkDelete = gql`
|
const attributeBulkDelete = gql`
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeBulkDelete($ids: [ID!]!) {
|
mutation AttributeBulkDelete($ids: [ID!]!) {
|
||||||
attributeBulkDelete(ids: $ids) {
|
attributeBulkDelete(ids: $ids) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,11 +51,11 @@ export const AttributeBulkDeleteMutation = TypedMutation<
|
||||||
>(attributeBulkDelete);
|
>(attributeBulkDelete);
|
||||||
|
|
||||||
const attributeDelete = gql`
|
const attributeDelete = gql`
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeDelete($id: ID!) {
|
mutation AttributeDelete($id: ID!) {
|
||||||
attributeDelete(id: $id) {
|
attributeDelete(id: $id) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,15 +67,15 @@ export const AttributeDeleteMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeUpdateMutation = gql`
|
export const attributeUpdateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeUpdate($id: ID!, $input: AttributeUpdateInput!) {
|
mutation AttributeUpdate($id: ID!, $input: AttributeUpdateInput!) {
|
||||||
attributeUpdate(id: $id, input: $input) {
|
attributeUpdate(id: $id, input: $input) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -93,15 +86,15 @@ export const AttributeUpdateMutation = TypedMutation<
|
||||||
|
|
||||||
const attributeValueDelete = gql`
|
const attributeValueDelete = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeValueDelete($id: ID!) {
|
mutation AttributeValueDelete($id: ID!) {
|
||||||
attributeValueDelete(id: $id) {
|
attributeValueDelete(id: $id) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -112,15 +105,15 @@ export const AttributeValueDeleteMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeValueUpdateMutation = gql`
|
export const attributeValueUpdateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeValueUpdate($id: ID!, $input: AttributeValueCreateInput!) {
|
mutation AttributeValueUpdate($id: ID!, $input: AttributeValueCreateInput!) {
|
||||||
attributeValueUpdate(id: $id, input: $input) {
|
attributeValueUpdate(id: $id, input: $input) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -131,15 +124,15 @@ export const AttributeValueUpdateMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeValueCreateMutation = gql`
|
export const attributeValueCreateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeValueCreate($id: ID!, $input: AttributeValueCreateInput!) {
|
mutation AttributeValueCreate($id: ID!, $input: AttributeValueCreateInput!) {
|
||||||
attributeValueCreate(attribute: $id, input: $input) {
|
attributeValueCreate(attribute: $id, input: $input) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -150,15 +143,15 @@ export const AttributeValueCreateMutation = TypedMutation<
|
||||||
|
|
||||||
export const attributeCreateMutation = gql`
|
export const attributeCreateMutation = gql`
|
||||||
${attributeDetailsFragment}
|
${attributeDetailsFragment}
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeCreate($input: AttributeCreateInput!) {
|
mutation AttributeCreate($input: AttributeCreateInput!) {
|
||||||
attributeCreate(input: $input) {
|
attributeCreate(input: $input) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
...AttributeDetailsFragment
|
...AttributeDetailsFragment
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -168,18 +161,18 @@ export const AttributeCreateMutation = TypedMutation<
|
||||||
>(attributeCreateMutation);
|
>(attributeCreateMutation);
|
||||||
|
|
||||||
const attributeValueReorderMutation = gql`
|
const attributeValueReorderMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
mutation AttributeValueReorder($id: ID!, $move: ReorderInput!) {
|
mutation AttributeValueReorder($id: ID!, $move: ReorderInput!) {
|
||||||
attributeReorderValues(attributeId: $id, moves: [$move]) {
|
attributeReorderValues(attributeId: $id, moves: [$move]) {
|
||||||
|
errors {
|
||||||
|
field
|
||||||
|
message
|
||||||
|
}
|
||||||
attribute {
|
attribute {
|
||||||
id
|
id
|
||||||
values {
|
values {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
errors: productErrors {
|
|
||||||
...ProductErrorFragment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeBulkDelete
|
// GraphQL mutation operation: AttributeBulkDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeBulkDelete_attributeBulkDelete_errors {
|
export interface AttributeBulkDelete_attributeBulkDelete_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeBulkDelete_attributeBulkDelete {
|
export interface AttributeBulkDelete_attributeBulkDelete {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeCreate
|
// GraphQL mutation operation: AttributeCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeCreate_attributeCreate_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate_attribute_values {
|
export interface AttributeCreate_attributeCreate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -31,16 +37,10 @@ export interface AttributeCreate_attributeCreate_attribute {
|
||||||
values: (AttributeCreate_attributeCreate_attribute_values | null)[] | null;
|
values: (AttributeCreate_attributeCreate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeCreate_attributeCreate {
|
export interface AttributeCreate_attributeCreate {
|
||||||
__typename: "AttributeCreate";
|
__typename: "AttributeCreate";
|
||||||
attribute: AttributeCreate_attributeCreate_attribute | null;
|
|
||||||
errors: AttributeCreate_attributeCreate_errors[];
|
errors: AttributeCreate_attributeCreate_errors[];
|
||||||
|
attribute: AttributeCreate_attributeCreate_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeCreate {
|
export interface AttributeCreate {
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeDelete
|
// GraphQL mutation operation: AttributeDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AttributeDelete_attributeDelete_errors {
|
export interface AttributeDelete_attributeDelete_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeDelete_attributeDelete {
|
export interface AttributeDelete_attributeDelete {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeUpdateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeUpdateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeUpdate
|
// GraphQL mutation operation: AttributeUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeUpdate_attributeUpdate_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate_attribute_values {
|
export interface AttributeUpdate_attributeUpdate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -31,16 +37,10 @@ export interface AttributeUpdate_attributeUpdate_attribute {
|
||||||
values: (AttributeUpdate_attributeUpdate_attribute_values | null)[] | null;
|
values: (AttributeUpdate_attributeUpdate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeUpdate_attributeUpdate {
|
export interface AttributeUpdate_attributeUpdate {
|
||||||
__typename: "AttributeUpdate";
|
__typename: "AttributeUpdate";
|
||||||
attribute: AttributeUpdate_attributeUpdate_attribute | null;
|
|
||||||
errors: AttributeUpdate_attributeUpdate_errors[];
|
errors: AttributeUpdate_attributeUpdate_errors[];
|
||||||
|
attribute: AttributeUpdate_attributeUpdate_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeUpdate {
|
export interface AttributeUpdate {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueCreate
|
// GraphQL mutation operation: AttributeValueCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeValueCreate_attributeValueCreate_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate_attribute_values {
|
export interface AttributeValueCreate_attributeValueCreate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -31,16 +37,10 @@ export interface AttributeValueCreate_attributeValueCreate_attribute {
|
||||||
values: (AttributeValueCreate_attributeValueCreate_attribute_values | null)[] | null;
|
values: (AttributeValueCreate_attributeValueCreate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueCreate_attributeValueCreate {
|
export interface AttributeValueCreate_attributeValueCreate {
|
||||||
__typename: "AttributeValueCreate";
|
__typename: "AttributeValueCreate";
|
||||||
attribute: AttributeValueCreate_attributeValueCreate_attribute | null;
|
|
||||||
errors: AttributeValueCreate_attributeValueCreate_errors[];
|
errors: AttributeValueCreate_attributeValueCreate_errors[];
|
||||||
|
attribute: AttributeValueCreate_attributeValueCreate_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueCreate {
|
export interface AttributeValueCreate {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueDelete
|
// GraphQL mutation operation: AttributeValueDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeValueDelete_attributeValueDelete_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete_attribute_values {
|
export interface AttributeValueDelete_attributeValueDelete_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -31,16 +37,10 @@ export interface AttributeValueDelete_attributeValueDelete_attribute {
|
||||||
values: (AttributeValueDelete_attributeValueDelete_attribute_values | null)[] | null;
|
values: (AttributeValueDelete_attributeValueDelete_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueDelete_attributeValueDelete {
|
export interface AttributeValueDelete_attributeValueDelete {
|
||||||
__typename: "AttributeValueDelete";
|
__typename: "AttributeValueDelete";
|
||||||
attribute: AttributeValueDelete_attributeValueDelete_attribute | null;
|
|
||||||
errors: AttributeValueDelete_attributeValueDelete_errors[];
|
errors: AttributeValueDelete_attributeValueDelete_errors[];
|
||||||
|
attribute: AttributeValueDelete_attributeValueDelete_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueDelete {
|
export interface AttributeValueDelete {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ReorderInput, ProductErrorCode } from "./../../types/globalTypes";
|
import { ReorderInput } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueReorder
|
// GraphQL mutation operation: AttributeValueReorder
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeValueReorder_attributeReorderValues_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues_attribute_values {
|
export interface AttributeValueReorder_attributeReorderValues_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -19,16 +25,10 @@ export interface AttributeValueReorder_attributeReorderValues_attribute {
|
||||||
values: (AttributeValueReorder_attributeReorderValues_attribute_values | null)[] | null;
|
values: (AttributeValueReorder_attributeReorderValues_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueReorder_attributeReorderValues {
|
export interface AttributeValueReorder_attributeReorderValues {
|
||||||
__typename: "AttributeReorderValues";
|
__typename: "AttributeReorderValues";
|
||||||
attribute: AttributeValueReorder_attributeReorderValues_attribute | null;
|
|
||||||
errors: AttributeValueReorder_attributeReorderValues_errors[];
|
errors: AttributeValueReorder_attributeReorderValues_errors[];
|
||||||
|
attribute: AttributeValueReorder_attributeReorderValues_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueReorder {
|
export interface AttributeValueReorder {
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeValueCreateInput, AttributeInputTypeEnum, AttributeValueType } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AttributeValueUpdate
|
// GraphQL mutation operation: AttributeValueUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface AttributeValueUpdate_attributeValueUpdate_errors {
|
||||||
|
__typename: "Error";
|
||||||
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate_attribute_values {
|
export interface AttributeValueUpdate_attributeValueUpdate_attribute_values {
|
||||||
__typename: "AttributeValue";
|
__typename: "AttributeValue";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -31,16 +37,10 @@ export interface AttributeValueUpdate_attributeValueUpdate_attribute {
|
||||||
values: (AttributeValueUpdate_attributeValueUpdate_attribute_values | null)[] | null;
|
values: (AttributeValueUpdate_attributeValueUpdate_attribute_values | null)[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate_errors {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttributeValueUpdate_attributeValueUpdate {
|
export interface AttributeValueUpdate_attributeValueUpdate {
|
||||||
__typename: "AttributeValueUpdate";
|
__typename: "AttributeValueUpdate";
|
||||||
attribute: AttributeValueUpdate_attributeValueUpdate_attribute | null;
|
|
||||||
errors: AttributeValueUpdate_attributeValueUpdate_errors[];
|
errors: AttributeValueUpdate_attributeValueUpdate_errors[];
|
||||||
|
attribute: AttributeValueUpdate_attributeValueUpdate_attribute | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AttributeValueUpdate {
|
export interface AttributeValueUpdate {
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
// This file was automatically generated and should not be edited.
|
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// GraphQL fragment: ProductErrorFragment
|
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
export interface ProductErrorFragment {
|
|
||||||
__typename: "ProductError";
|
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@ import slugify from "slugify";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ReorderEvent } from "@saleor/types";
|
import { ReorderEvent, UserError } from "@saleor/types";
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
@ -14,8 +14,6 @@ import {
|
||||||
updateAtIndex
|
updateAtIndex
|
||||||
} from "@saleor/utils/lists";
|
} from "@saleor/utils/lists";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
|
||||||
import AttributePage from "../../components/AttributePage";
|
import AttributePage from "../../components/AttributePage";
|
||||||
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
||||||
import AttributeValueEditDialog, {
|
import AttributeValueEditDialog, {
|
||||||
|
@ -35,12 +33,6 @@ interface AttributeDetailsProps {
|
||||||
params: AttributeAddUrlQueryParams;
|
params: AttributeAddUrlQueryParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
const attributeValueAlreadyExistsError: ProductErrorFragment = {
|
|
||||||
__typename: "ProductError",
|
|
||||||
code: ProductErrorCode.ALREADY_EXISTS,
|
|
||||||
field: "name"
|
|
||||||
};
|
|
||||||
|
|
||||||
function areValuesEqual(
|
function areValuesEqual(
|
||||||
a: AttributeValueEditDialogFormData,
|
a: AttributeValueEditDialogFormData,
|
||||||
b: AttributeValueEditDialogFormData
|
b: AttributeValueEditDialogFormData
|
||||||
|
@ -56,9 +48,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
const [values, setValues] = React.useState<
|
const [values, setValues] = React.useState<
|
||||||
AttributeValueEditDialogFormData[]
|
AttributeValueEditDialogFormData[]
|
||||||
>([]);
|
>([]);
|
||||||
const [valueErrors, setValueErrors] = React.useState<ProductErrorFragment[]>(
|
const [valueErrors, setValueErrors] = React.useState<UserError[]>([]);
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
const id = params.id ? parseInt(params.id, 0) : undefined;
|
const id = params.id ? parseInt(params.id, 0) : undefined;
|
||||||
|
|
||||||
|
@ -67,8 +57,6 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
AttributeAddUrlQueryParams
|
AttributeAddUrlQueryParams
|
||||||
>(navigate, attributeAddUrl, params);
|
>(navigate, attributeAddUrl, params);
|
||||||
|
|
||||||
React.useEffect(() => setValueErrors([]), [params.action]);
|
|
||||||
|
|
||||||
const handleValueDelete = () => {
|
const handleValueDelete = () => {
|
||||||
setValues(remove(values[params.id], values, areValuesEqual));
|
setValues(remove(values[params.id], values, areValuesEqual));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -85,7 +73,20 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
};
|
};
|
||||||
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
|
const handleValueUpdate = (input: AttributeValueEditDialogFormData) => {
|
||||||
if (isSelected(input, values, areValuesEqual)) {
|
if (isSelected(input, values, areValuesEqual)) {
|
||||||
setValueErrors([attributeValueAlreadyExistsError]);
|
setValueErrors([
|
||||||
|
{
|
||||||
|
field: "name",
|
||||||
|
message: intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "A value named {name} already exists",
|
||||||
|
description: "attribute value edit error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: input.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
setValues(updateAtIndex(input, values, id));
|
setValues(updateAtIndex(input, values, id));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -93,7 +94,20 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
};
|
};
|
||||||
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
|
const handleValueCreate = (input: AttributeValueEditDialogFormData) => {
|
||||||
if (isSelected(input, values, areValuesEqual)) {
|
if (isSelected(input, values, areValuesEqual)) {
|
||||||
setValueErrors([attributeValueAlreadyExistsError]);
|
setValueErrors([
|
||||||
|
{
|
||||||
|
field: "name",
|
||||||
|
message: intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "A value named {name} already exists",
|
||||||
|
description: "attribute value edit error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: input.name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
setValues(add(input, values));
|
setValues(add(input, values));
|
||||||
closeModal();
|
closeModal();
|
||||||
|
@ -109,7 +123,10 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
||||||
<AttributePage
|
<AttributePage
|
||||||
attribute={null}
|
attribute={null}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
errors={attributeCreateOpts.data?.attributeCreate.errors || []}
|
errors={maybe(
|
||||||
|
() => attributeCreateOpts.data.attributeCreate.errors,
|
||||||
|
[]
|
||||||
|
)}
|
||||||
onBack={() => navigate(attributeListUrl())}
|
onBack={() => navigate(attributeListUrl())}
|
||||||
onDelete={undefined}
|
onDelete={undefined}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
|
|
@ -8,7 +8,6 @@ import { maybe } from "@saleor/misc";
|
||||||
import { ReorderEvent } from "@saleor/types";
|
import { ReorderEvent } from "@saleor/types";
|
||||||
import { move } from "@saleor/utils/lists";
|
import { move } from "@saleor/utils/lists";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import { getProductErrorMessage } from "@saleor/utils/errors";
|
|
||||||
import AttributeDeleteDialog from "../../components/AttributeDeleteDialog";
|
import AttributeDeleteDialog from "../../components/AttributeDeleteDialog";
|
||||||
import AttributePage from "../../components/AttributePage";
|
import AttributePage from "../../components/AttributePage";
|
||||||
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
import AttributeValueDeleteDialog from "../../components/AttributeValueDeleteDialog";
|
||||||
|
@ -96,10 +95,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
const handleValueReorderMutation = (data: AttributeValueReorder) => {
|
const handleValueReorderMutation = (data: AttributeValueReorder) => {
|
||||||
if (data.attributeReorderValues.errors.length !== 0) {
|
if (data.attributeReorderValues.errors.length !== 0) {
|
||||||
notify({
|
notify({
|
||||||
text: getProductErrorMessage(
|
text: data.attributeReorderValues.errors[0].message
|
||||||
data.attributeReorderValues.errors[0],
|
|
||||||
intl
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -159,10 +155,12 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
<AttributePage
|
<AttributePage
|
||||||
attribute={maybe(() => data.attribute)}
|
attribute={maybe(() => data.attribute)}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={
|
errors={maybe(
|
||||||
attributeUpdateOpts.data
|
() =>
|
||||||
?.attributeUpdate.errors || []
|
attributeUpdateOpts.data
|
||||||
}
|
.attributeUpdate.errors,
|
||||||
|
[]
|
||||||
|
)}
|
||||||
onBack={() =>
|
onBack={() =>
|
||||||
navigate(attributeListUrl())
|
navigate(attributeListUrl())
|
||||||
}
|
}
|
||||||
|
@ -255,10 +253,12 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
attributeValueCreateOpts.status
|
attributeValueCreateOpts.status
|
||||||
}
|
}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={
|
errors={maybe(
|
||||||
attributeValueCreateOpts.data
|
() =>
|
||||||
?.attributeValueCreate.errors || []
|
attributeValueCreateOpts.data
|
||||||
}
|
.attributeValueCreate.errors,
|
||||||
|
[]
|
||||||
|
)}
|
||||||
open={params.action === "add-value"}
|
open={params.action === "add-value"}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
@ -280,10 +280,12 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ id, params }) => {
|
||||||
attributeValueUpdateOpts.status
|
attributeValueUpdateOpts.status
|
||||||
}
|
}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={
|
errors={maybe(
|
||||||
attributeValueUpdateOpts.data
|
() =>
|
||||||
?.attributeValueUpdate.errors || []
|
attributeValueUpdateOpts.data
|
||||||
}
|
.attributeValueUpdate.errors,
|
||||||
|
[]
|
||||||
|
)}
|
||||||
open={params.action === "edit-value"}
|
open={params.action === "edit-value"}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={input =>
|
onSubmit={input =>
|
||||||
|
|
|
@ -30,8 +30,6 @@ import useSearchQuery from "@saleor/hooks/useSearchQuery";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { maybe, renderCollection } from "@saleor/misc";
|
import { maybe, renderCollection } from "@saleor/misc";
|
||||||
import { FetchMoreProps } from "@saleor/types";
|
import { FetchMoreProps } from "@saleor/types";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import { getProductErrorMessage } from "@saleor/utils/errors";
|
|
||||||
import { SearchAttributes_productType_availableAttributes_edges_node } from "../../hooks/useAvailableAttributeSearch/types/SearchAttributes";
|
import { SearchAttributes_productType_availableAttributes_edges_node } from "../../hooks/useAvailableAttributeSearch/types/SearchAttributes";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
|
@ -63,7 +61,7 @@ const useStyles = makeStyles(
|
||||||
|
|
||||||
export interface AssignAttributeDialogProps extends FetchMoreProps {
|
export interface AssignAttributeDialogProps extends FetchMoreProps {
|
||||||
confirmButtonState: ConfirmButtonTransitionState;
|
confirmButtonState: ConfirmButtonTransitionState;
|
||||||
errors: ProductErrorFragment[];
|
errors: string[];
|
||||||
open: boolean;
|
open: boolean;
|
||||||
attributes: SearchAttributes_productType_availableAttributes_edges_node[];
|
attributes: SearchAttributes_productType_availableAttributes_edges_node[];
|
||||||
selected: string[];
|
selected: string[];
|
||||||
|
@ -190,7 +188,7 @@ const AssignAttributeDialog: React.FC<AssignAttributeDialogProps> = ({
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
{errors.map((error, errorIndex) => (
|
{errors.map((error, errorIndex) => (
|
||||||
<DialogContentText color="error" key={errorIndex}>
|
<DialogContentText color="error" key={errorIndex}>
|
||||||
{getProductErrorMessage(error, intl)}
|
{error}
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
))}
|
))}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
import Button from "@material-ui/core/Button";
|
||||||
|
import Dialog from "@material-ui/core/Dialog";
|
||||||
|
import DialogActions from "@material-ui/core/DialogActions";
|
||||||
|
import DialogContent from "@material-ui/core/DialogContent";
|
||||||
|
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||||
|
import TextField from "@material-ui/core/TextField";
|
||||||
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import Form from "@saleor/components/Form";
|
||||||
|
import { FormSpacer } from "@saleor/components/FormSpacer";
|
||||||
|
import ListField from "@saleor/components/ListField";
|
||||||
|
import { buttonMessages } from "@saleor/intl";
|
||||||
|
import { UserError } from "@saleor/types";
|
||||||
|
import { getFieldError } from "@saleor/utils/errors";
|
||||||
|
|
||||||
|
export interface FormData {
|
||||||
|
name: string;
|
||||||
|
values: Array<{
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ProductTypeAttributeEditDialogProps {
|
||||||
|
disabled: boolean;
|
||||||
|
errors: UserError[];
|
||||||
|
name: string;
|
||||||
|
opened: boolean;
|
||||||
|
title: string;
|
||||||
|
values: Array<{
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
}>;
|
||||||
|
onClose: () => void;
|
||||||
|
onConfirm: (data: FormData) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductTypeAttributeEditDialog: React.FC<ProductTypeAttributeEditDialogProps> = ({
|
||||||
|
disabled,
|
||||||
|
errors,
|
||||||
|
name,
|
||||||
|
opened,
|
||||||
|
title,
|
||||||
|
values,
|
||||||
|
onClose,
|
||||||
|
onConfirm
|
||||||
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const initialForm: FormData = {
|
||||||
|
name: name || "",
|
||||||
|
values: values || []
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Dialog onClose={onClose} open={opened}>
|
||||||
|
<Form initial={initialForm} onSubmit={onConfirm}>
|
||||||
|
{({ change, data }) => (
|
||||||
|
<>
|
||||||
|
<DialogTitle>{title}</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField
|
||||||
|
disabled={disabled}
|
||||||
|
error={!!getFieldError(errors, "name")}
|
||||||
|
fullWidth
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Attribute name"
|
||||||
|
})}
|
||||||
|
helperText={getFieldError(errors, "name")?.message}
|
||||||
|
name="name"
|
||||||
|
value={data.name}
|
||||||
|
onChange={change}
|
||||||
|
/>
|
||||||
|
<FormSpacer />
|
||||||
|
<ListField
|
||||||
|
autoComplete="off"
|
||||||
|
disabled={disabled}
|
||||||
|
error={
|
||||||
|
!!getFieldError(errors, "values") ||
|
||||||
|
!!getFieldError(errors, "addValues") ||
|
||||||
|
!!getFieldError(errors, "removeValues")
|
||||||
|
}
|
||||||
|
fullWidth
|
||||||
|
name="values"
|
||||||
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Attribute values"
|
||||||
|
})}
|
||||||
|
helperText={
|
||||||
|
getFieldError(errors, "values") ||
|
||||||
|
getFieldError(errors, "addValues") ||
|
||||||
|
getFieldError(errors, "removeValues")
|
||||||
|
}
|
||||||
|
values={data.values}
|
||||||
|
onChange={change}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={onClose}>
|
||||||
|
<FormattedMessage {...buttonMessages.back} />
|
||||||
|
</Button>
|
||||||
|
<Button color="primary" variant="contained" type="submit">
|
||||||
|
<FormattedMessage {...buttonMessages.confirm} />
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
ProductTypeAttributeEditDialog.displayName = "ProductTypeAttributeEditDialog";
|
||||||
|
export default ProductTypeAttributeEditDialog;
|
|
@ -0,0 +1,2 @@
|
||||||
|
export { default } from "./ProductTypeAttributeEditDialog";
|
||||||
|
export * from "./ProductTypeAttributeEditDialog";
|
|
@ -13,8 +13,8 @@ import { ChangeEvent, FormChange } from "@saleor/hooks/useForm";
|
||||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { ProductTypeDetails_taxTypes } from "@saleor/productTypes/types/ProductTypeDetails";
|
import { ProductTypeDetails_taxTypes } from "@saleor/productTypes/types/ProductTypeDetails";
|
||||||
|
import { UserError } from "@saleor/types";
|
||||||
import { WeightUnitsEnum } from "@saleor/types/globalTypes";
|
import { WeightUnitsEnum } from "@saleor/types/globalTypes";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import ProductTypeDetails from "../ProductTypeDetails/ProductTypeDetails";
|
import ProductTypeDetails from "../ProductTypeDetails/ProductTypeDetails";
|
||||||
import ProductTypeShipping from "../ProductTypeShipping/ProductTypeShipping";
|
import ProductTypeShipping from "../ProductTypeShipping/ProductTypeShipping";
|
||||||
import ProductTypeTaxes from "../ProductTypeTaxes/ProductTypeTaxes";
|
import ProductTypeTaxes from "../ProductTypeTaxes/ProductTypeTaxes";
|
||||||
|
@ -27,7 +27,7 @@ export interface ProductTypeForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeCreatePageProps {
|
export interface ProductTypeCreatePageProps {
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
defaultWeightUnit: WeightUnitsEnum;
|
defaultWeightUnit: WeightUnitsEnum;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
pageTitle: string;
|
pageTitle: string;
|
||||||
|
@ -106,7 +106,6 @@ const ProductTypeCreatePage: React.FC<ProductTypeCreatePageProps> = ({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
data={data}
|
data={data}
|
||||||
defaultWeightUnit={defaultWeightUnit}
|
defaultWeightUnit={defaultWeightUnit}
|
||||||
errors={errors}
|
|
||||||
onChange={change}
|
onChange={change}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { commonMessages } from "@saleor/intl";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
import { UserError } from "@saleor/types";
|
||||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
import { getFieldError } from "@saleor/utils/errors";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
{
|
{
|
||||||
|
@ -24,17 +24,15 @@ interface ProductTypeDetailsProps {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductTypeDetails: React.FC<ProductTypeDetailsProps> = props => {
|
const ProductTypeDetails: React.FC<ProductTypeDetailsProps> = props => {
|
||||||
const { data, disabled, errors, onChange } = props;
|
const { data, disabled, errors, onChange } = props;
|
||||||
|
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
|
||||||
|
|
||||||
const formErrors = getFormErrors(["name"], errors);
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={classes.root}>
|
<Card className={classes.root}>
|
||||||
|
@ -44,9 +42,9 @@ const ProductTypeDetails: React.FC<ProductTypeDetailsProps> = props => {
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.name}
|
error={!!getFieldError(errors, "name")}
|
||||||
fullWidth
|
fullWidth
|
||||||
helperText={getProductErrorMessage(formErrors.name, intl)}
|
helperText={getFieldError(errors, "name")?.message}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Product Type Name"
|
defaultMessage: "Product Type Name"
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -14,9 +14,8 @@ import { ChangeEvent, FormChange } from "@saleor/hooks/useForm";
|
||||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { maybe } from "@saleor/misc";
|
import { maybe } from "@saleor/misc";
|
||||||
import { ListActions, ReorderEvent } from "@saleor/types";
|
import { ListActions, ReorderEvent, UserError } from "@saleor/types";
|
||||||
import { AttributeTypeEnum, WeightUnitsEnum } from "@saleor/types/globalTypes";
|
import { AttributeTypeEnum, WeightUnitsEnum } from "@saleor/types/globalTypes";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import {
|
import {
|
||||||
ProductTypeDetails_productType,
|
ProductTypeDetails_productType,
|
||||||
ProductTypeDetails_taxTypes
|
ProductTypeDetails_taxTypes
|
||||||
|
@ -42,7 +41,7 @@ export interface ProductTypeForm {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeDetailsPageProps {
|
export interface ProductTypeDetailsPageProps {
|
||||||
errors: ProductErrorFragment[];
|
errors: UserError[];
|
||||||
productType: ProductTypeDetails_productType;
|
productType: ProductTypeDetails_productType;
|
||||||
defaultWeightUnit: WeightUnitsEnum;
|
defaultWeightUnit: WeightUnitsEnum;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
@ -201,7 +200,6 @@ const ProductTypeDetailsPage: React.FC<ProductTypeDetailsPageProps> = ({
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
data={data}
|
data={data}
|
||||||
defaultWeightUnit={defaultWeightUnit}
|
defaultWeightUnit={defaultWeightUnit}
|
||||||
errors={errors}
|
|
||||||
onChange={change}
|
onChange={change}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,8 +6,6 @@ import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import { getFormErrors, getProductErrorMessage } from "@saleor/utils/errors";
|
|
||||||
import { WeightUnitsEnum } from "../../../types/globalTypes";
|
import { WeightUnitsEnum } from "../../../types/globalTypes";
|
||||||
|
|
||||||
interface ProductTypeShippingProps {
|
interface ProductTypeShippingProps {
|
||||||
|
@ -17,7 +15,6 @@ interface ProductTypeShippingProps {
|
||||||
};
|
};
|
||||||
defaultWeightUnit: WeightUnitsEnum;
|
defaultWeightUnit: WeightUnitsEnum;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
errors: ProductErrorFragment[];
|
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +22,10 @@ const ProductTypeShipping: React.FC<ProductTypeShippingProps> = ({
|
||||||
data,
|
data,
|
||||||
defaultWeightUnit,
|
defaultWeightUnit,
|
||||||
disabled,
|
disabled,
|
||||||
errors,
|
|
||||||
onChange
|
onChange
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const formErrors = getFormErrors(["weight"], errors);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
|
@ -54,19 +48,15 @@ const ProductTypeShipping: React.FC<ProductTypeShippingProps> = ({
|
||||||
{data.isShippingRequired && (
|
{data.isShippingRequired && (
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.weight}
|
|
||||||
InputProps={{ endAdornment: defaultWeightUnit }}
|
InputProps={{ endAdornment: defaultWeightUnit }}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
defaultMessage: "Weight"
|
defaultMessage: "Weight"
|
||||||
})}
|
})}
|
||||||
name="weight"
|
name="weight"
|
||||||
helperText={
|
helperText={intl.formatMessage({
|
||||||
getProductErrorMessage(formErrors.weight, intl) ||
|
defaultMessage:
|
||||||
intl.formatMessage({
|
"Used to calculate rates for shipping for products of this product type, when specific weight is not given"
|
||||||
defaultMessage:
|
})}
|
||||||
"Used to calculate rates for shipping for products of this product type, when specific weight is not given"
|
|
||||||
})
|
|
||||||
}
|
|
||||||
type="number"
|
type="number"
|
||||||
value={data.weight}
|
value={data.weight}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import gql from "graphql-tag";
|
import gql from "graphql-tag";
|
||||||
|
|
||||||
import { productErrorFragment } from "@saleor/attributes/mutations";
|
|
||||||
import { TypedMutation } from "../mutations";
|
import { TypedMutation } from "../mutations";
|
||||||
import { productTypeDetailsFragment } from "./queries";
|
import { productTypeDetailsFragment } from "./queries";
|
||||||
import {
|
import {
|
||||||
|
@ -33,11 +32,11 @@ import {
|
||||||
} from "./types/UnassignAttribute";
|
} from "./types/UnassignAttribute";
|
||||||
|
|
||||||
export const productTypeDeleteMutation = gql`
|
export const productTypeDeleteMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
mutation ProductTypeDelete($id: ID!) {
|
mutation ProductTypeDelete($id: ID!) {
|
||||||
productTypeDelete(id: $id) {
|
productTypeDelete(id: $id) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
id
|
id
|
||||||
|
@ -51,11 +50,11 @@ export const TypedProductTypeDeleteMutation = TypedMutation<
|
||||||
>(productTypeDeleteMutation);
|
>(productTypeDeleteMutation);
|
||||||
|
|
||||||
export const productTypeBulkDeleteMutation = gql`
|
export const productTypeBulkDeleteMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
mutation ProductTypeBulkDelete($ids: [ID]!) {
|
mutation ProductTypeBulkDelete($ids: [ID]!) {
|
||||||
productTypeBulkDelete(ids: $ids) {
|
productTypeBulkDelete(ids: $ids) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,12 +65,12 @@ export const TypedProductTypeBulkDeleteMutation = TypedMutation<
|
||||||
>(productTypeBulkDeleteMutation);
|
>(productTypeBulkDeleteMutation);
|
||||||
|
|
||||||
export const productTypeUpdateMutation = gql`
|
export const productTypeUpdateMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
${productTypeDetailsFragment}
|
${productTypeDetailsFragment}
|
||||||
mutation ProductTypeUpdate($id: ID!, $input: ProductTypeInput!) {
|
mutation ProductTypeUpdate($id: ID!, $input: ProductTypeInput!) {
|
||||||
productTypeUpdate(id: $id, input: $input) {
|
productTypeUpdate(id: $id, input: $input) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
...ProductTypeDetailsFragment
|
...ProductTypeDetailsFragment
|
||||||
|
@ -85,12 +84,12 @@ export const TypedProductTypeUpdateMutation = TypedMutation<
|
||||||
>(productTypeUpdateMutation);
|
>(productTypeUpdateMutation);
|
||||||
|
|
||||||
export const assignAttributeMutation = gql`
|
export const assignAttributeMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
${productTypeDetailsFragment}
|
${productTypeDetailsFragment}
|
||||||
mutation AssignAttribute($id: ID!, $operations: [AttributeAssignInput!]!) {
|
mutation AssignAttribute($id: ID!, $operations: [AttributeAssignInput!]!) {
|
||||||
attributeAssign(productTypeId: $id, operations: $operations) {
|
attributeAssign(productTypeId: $id, operations: $operations) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
...ProductTypeDetailsFragment
|
...ProductTypeDetailsFragment
|
||||||
|
@ -104,12 +103,12 @@ export const TypedAssignAttributeMutation = TypedMutation<
|
||||||
>(assignAttributeMutation);
|
>(assignAttributeMutation);
|
||||||
|
|
||||||
export const unassignAttributeMutation = gql`
|
export const unassignAttributeMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
${productTypeDetailsFragment}
|
${productTypeDetailsFragment}
|
||||||
mutation UnassignAttribute($id: ID!, $ids: [ID]!) {
|
mutation UnassignAttribute($id: ID!, $ids: [ID]!) {
|
||||||
attributeUnassign(productTypeId: $id, attributeIds: $ids) {
|
attributeUnassign(productTypeId: $id, attributeIds: $ids) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
...ProductTypeDetailsFragment
|
...ProductTypeDetailsFragment
|
||||||
|
@ -123,12 +122,12 @@ export const TypedUnassignAttributeMutation = TypedMutation<
|
||||||
>(unassignAttributeMutation);
|
>(unassignAttributeMutation);
|
||||||
|
|
||||||
export const productTypeCreateMutation = gql`
|
export const productTypeCreateMutation = gql`
|
||||||
${productErrorFragment}
|
|
||||||
${productTypeDetailsFragment}
|
${productTypeDetailsFragment}
|
||||||
mutation ProductTypeCreate($input: ProductTypeInput!) {
|
mutation ProductTypeCreate($input: ProductTypeInput!) {
|
||||||
productTypeCreate(input: $input) {
|
productTypeCreate(input: $input) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
...ProductTypeDetailsFragment
|
...ProductTypeDetailsFragment
|
||||||
|
@ -142,7 +141,6 @@ export const TypedProductTypeCreateMutation = TypedMutation<
|
||||||
>(productTypeCreateMutation);
|
>(productTypeCreateMutation);
|
||||||
|
|
||||||
const productTypeAttributeReorder = gql`
|
const productTypeAttributeReorder = gql`
|
||||||
${productErrorFragment}
|
|
||||||
${productTypeDetailsFragment}
|
${productTypeDetailsFragment}
|
||||||
mutation ProductTypeAttributeReorder(
|
mutation ProductTypeAttributeReorder(
|
||||||
$move: ReorderInput!
|
$move: ReorderInput!
|
||||||
|
@ -154,8 +152,9 @@ const productTypeAttributeReorder = gql`
|
||||||
productTypeId: $productTypeId
|
productTypeId: $productTypeId
|
||||||
type: $type
|
type: $type
|
||||||
) {
|
) {
|
||||||
errors: productErrors {
|
errors {
|
||||||
...ProductErrorFragment
|
field
|
||||||
|
message
|
||||||
}
|
}
|
||||||
productType {
|
productType {
|
||||||
...ProductTypeDetailsFragment
|
...ProductTypeDetailsFragment
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeAssignInput, ProductErrorCode } from "./../../types/globalTypes";
|
import { AttributeAssignInput } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AssignAttribute
|
// GraphQL mutation operation: AssignAttribute
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface AssignAttribute_attributeAssign_errors {
|
export interface AssignAttribute_attributeAssign_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AssignAttribute_attributeAssign_productType_taxType {
|
export interface AssignAttribute_attributeAssign_productType_taxType {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ReorderInput, AttributeTypeEnum, ProductErrorCode } from "./../../types/globalTypes";
|
import { ReorderInput, AttributeTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeAttributeReorder
|
// GraphQL mutation operation: ProductTypeAttributeReorder
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_errors {
|
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_taxType {
|
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_taxType {
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeBulkDelete
|
// GraphQL mutation operation: ProductTypeBulkDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ProductTypeBulkDelete_productTypeBulkDelete_errors {
|
export interface ProductTypeBulkDelete_productTypeBulkDelete_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeBulkDelete_productTypeBulkDelete {
|
export interface ProductTypeBulkDelete_productTypeBulkDelete {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductTypeInput, ProductErrorCode } from "./../../types/globalTypes";
|
import { ProductTypeInput } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeCreate
|
// GraphQL mutation operation: ProductTypeCreate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ProductTypeCreate_productTypeCreate_errors {
|
export interface ProductTypeCreate_productTypeCreate_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeCreate_productTypeCreate_productType_taxType {
|
export interface ProductTypeCreate_productTypeCreate_productType_taxType {
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeDelete
|
// GraphQL mutation operation: ProductTypeDelete
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ProductTypeDelete_productTypeDelete_errors {
|
export interface ProductTypeDelete_productTypeDelete_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeDelete_productTypeDelete_productType {
|
export interface ProductTypeDelete_productTypeDelete_productType {
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductTypeInput, ProductErrorCode } from "./../../types/globalTypes";
|
import { ProductTypeInput } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeUpdate
|
// GraphQL mutation operation: ProductTypeUpdate
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface ProductTypeUpdate_productTypeUpdate_errors {
|
export interface ProductTypeUpdate_productTypeUpdate_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductTypeUpdate_productTypeUpdate_productType_taxType {
|
export interface ProductTypeUpdate_productTypeUpdate_productType_taxType {
|
||||||
|
|
|
@ -2,16 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UnassignAttribute
|
// GraphQL mutation operation: UnassignAttribute
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface UnassignAttribute_attributeUnassign_errors {
|
export interface UnassignAttribute_attributeUnassign_errors {
|
||||||
__typename: "ProductError";
|
__typename: "Error";
|
||||||
code: ProductErrorCode;
|
|
||||||
field: string | null;
|
field: string | null;
|
||||||
|
message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UnassignAttribute_attributeUnassign_productType_taxType {
|
export interface UnassignAttribute_attributeUnassign_productType_taxType {
|
||||||
|
|
|
@ -57,9 +57,10 @@ export const ProductTypeCreate: React.FC = () => {
|
||||||
<ProductTypeCreatePage
|
<ProductTypeCreatePage
|
||||||
defaultWeightUnit={maybe(() => data.shop.defaultWeightUnit)}
|
defaultWeightUnit={maybe(() => data.shop.defaultWeightUnit)}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
errors={
|
errors={maybe(
|
||||||
createProductTypeOpts.data?.productTypeCreate.errors || []
|
() => createProductTypeOpts.data.productTypeCreate.errors,
|
||||||
}
|
[]
|
||||||
|
)}
|
||||||
pageTitle={intl.formatMessage({
|
pageTitle={intl.formatMessage({
|
||||||
defaultMessage: "Create Product Type",
|
defaultMessage: "Create Product Type",
|
||||||
description: "header",
|
description: "header",
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
import { UserError } from "../../../types";
|
||||||
|
|
||||||
interface ProductTypeUpdateErrorsState {
|
interface ProductTypeUpdateErrorsState {
|
||||||
addAttributeErrors: ProductErrorFragment[];
|
addAttributeErrors: UserError[];
|
||||||
editAttributeErrors: ProductErrorFragment[];
|
editAttributeErrors: UserError[];
|
||||||
formErrors: ProductErrorFragment[];
|
formErrors: UserError[];
|
||||||
}
|
}
|
||||||
interface ProductTypeUpdateErrorsProps {
|
interface ProductTypeUpdateErrorsProps {
|
||||||
children: (props: {
|
children: (props: {
|
||||||
errors: ProductTypeUpdateErrorsState;
|
errors: ProductTypeUpdateErrorsState;
|
||||||
set: {
|
set: {
|
||||||
addAttributeErrors: (errors: ProductErrorFragment[]) => void;
|
addAttributeErrors: (errors: UserError[]) => void;
|
||||||
editAttributeErrors: (errors: ProductErrorFragment[]) => void;
|
editAttributeErrors: (errors: UserError[]) => void;
|
||||||
formErrors: (errors: ProductErrorFragment[]) => void;
|
formErrors: (errors: UserError[]) => void;
|
||||||
};
|
};
|
||||||
}) => React.ReactNode;
|
}) => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
@ -32,12 +32,11 @@ export class ProductTypeUpdateErrors extends React.Component<
|
||||||
return this.props.children({
|
return this.props.children({
|
||||||
errors: this.state,
|
errors: this.state,
|
||||||
set: {
|
set: {
|
||||||
addAttributeErrors: (addAttributeErrors: ProductErrorFragment[]) =>
|
addAttributeErrors: (addAttributeErrors: UserError[]) =>
|
||||||
this.setState({ addAttributeErrors }),
|
this.setState({ addAttributeErrors }),
|
||||||
editAttributeErrors: (editAttributeErrors: ProductErrorFragment[]) =>
|
editAttributeErrors: (editAttributeErrors: UserError[]) =>
|
||||||
this.setState({ editAttributeErrors }),
|
this.setState({ editAttributeErrors }),
|
||||||
formErrors: (formErrors: ProductErrorFragment[]) =>
|
formErrors: (formErrors: UserError[]) => this.setState({ formErrors })
|
||||||
this.setState({ formErrors })
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -319,10 +319,13 @@ export const ProductTypeUpdate: React.FC<ProductTypeUpdateProps> = ({
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
confirmButtonState={assignAttribute.opts.status}
|
confirmButtonState={assignAttribute.opts.status}
|
||||||
errors={
|
errors={maybe(
|
||||||
assignAttribute.opts.data?.attributeAssign
|
() =>
|
||||||
.errors || []
|
assignAttribute.opts.data.attributeAssign.errors.map(
|
||||||
}
|
err => err.message
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
)}
|
||||||
loading={result.loading}
|
loading={result.loading}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={handleAssignAttribute}
|
onSubmit={handleAssignAttribute}
|
||||||
|
|
|
@ -10012,7 +10012,7 @@ exports[`Storyshots Views / Attributes / Attribute details form errors 1`] = `
|
||||||
<p
|
<p
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
||||||
>
|
>
|
||||||
This field is required
|
Generic form error
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -10056,7 +10056,7 @@ exports[`Storyshots Views / Attributes / Attribute details form errors 1`] = `
|
||||||
<p
|
<p
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
||||||
>
|
>
|
||||||
This field is required
|
Generic form error
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -10465,7 +10465,7 @@ exports[`Storyshots Views / Attributes / Attribute details form errors 1`] = `
|
||||||
<p
|
<p
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
||||||
>
|
>
|
||||||
API error
|
Generic form error
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -84010,7 +84010,7 @@ exports[`Storyshots Views / Product types / Create product type form errors 1`]
|
||||||
<p
|
<p
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
|
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id"
|
||||||
>
|
>
|
||||||
Unknown error
|
Generic form error
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -85147,7 +85147,7 @@ exports[`Storyshots Views / Product types / Product type details form errors 1`]
|
||||||
<p
|
<p
|
||||||
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
class="MuiFormHelperText-root-id MuiFormHelperText-contained-id MuiFormHelperText-error-id MuiFormHelperText-filled-id"
|
||||||
>
|
>
|
||||||
Unknown error
|
Generic form error
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,10 +5,8 @@ import AttributePage, {
|
||||||
AttributePageProps
|
AttributePageProps
|
||||||
} from "@saleor/attributes/components/AttributePage";
|
} from "@saleor/attributes/components/AttributePage";
|
||||||
import { attribute } from "@saleor/attributes/fixtures";
|
import { attribute } from "@saleor/attributes/fixtures";
|
||||||
import {
|
import { formError } from "@saleor/storybook/misc";
|
||||||
AttributeInputTypeEnum,
|
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
||||||
ProductErrorCode
|
|
||||||
} from "@saleor/types/globalTypes";
|
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
|
||||||
const props: AttributePageProps = {
|
const props: AttributePageProps = {
|
||||||
|
@ -41,23 +39,7 @@ storiesOf("Views / Attributes / Attribute details", module)
|
||||||
.add("form errors", () => (
|
.add("form errors", () => (
|
||||||
<AttributePage
|
<AttributePage
|
||||||
{...props}
|
{...props}
|
||||||
errors={[
|
errors={["name", "slug", "storefrontSearchPosition"].map(formError)}
|
||||||
{
|
|
||||||
code: ProductErrorCode.REQUIRED,
|
|
||||||
field: "name"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: ProductErrorCode.REQUIRED,
|
|
||||||
field: "slug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
code: ProductErrorCode.GRAPHQL_ERROR,
|
|
||||||
field: "storefrontSearchPosition"
|
|
||||||
}
|
|
||||||
].map(err => ({
|
|
||||||
__typename: "ProductError",
|
|
||||||
...err
|
|
||||||
}))}
|
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
.add("multiple select input", () => (
|
.add("multiple select input", () => (
|
||||||
|
|
|
@ -2,10 +2,8 @@ import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { attribute } from "@saleor/attributes/fixtures";
|
import { attribute } from "@saleor/attributes/fixtures";
|
||||||
import {
|
import { formError } from "@saleor/storybook/misc";
|
||||||
AttributeValueType,
|
import { AttributeValueType } from "@saleor/types/globalTypes";
|
||||||
ProductErrorCode
|
|
||||||
} from "@saleor/types/globalTypes";
|
|
||||||
import AttributeValueEditDialog, {
|
import AttributeValueEditDialog, {
|
||||||
AttributeValueEditDialogProps
|
AttributeValueEditDialogProps
|
||||||
} from "../../../attributes/components/AttributeValueEditDialog";
|
} from "../../../attributes/components/AttributeValueEditDialog";
|
||||||
|
@ -28,14 +26,5 @@ storiesOf("Attributes / Attribute value edit", module)
|
||||||
.addDecorator(Decorator)
|
.addDecorator(Decorator)
|
||||||
.add("default", () => <AttributeValueEditDialog {...props} />)
|
.add("default", () => <AttributeValueEditDialog {...props} />)
|
||||||
.add("form errors", () => (
|
.add("form errors", () => (
|
||||||
<AttributeValueEditDialog
|
<AttributeValueEditDialog {...props} errors={[formError("name")]} />
|
||||||
{...props}
|
|
||||||
errors={[
|
|
||||||
{
|
|
||||||
__typename: "ProductError",
|
|
||||||
code: ProductErrorCode.ALREADY_EXISTS,
|
|
||||||
field: "name"
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
));
|
));
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { fetchMoreProps } from "@saleor/fixtures";
|
||||||
import AssignAttributeDialog, {
|
import AssignAttributeDialog, {
|
||||||
AssignAttributeDialogProps
|
AssignAttributeDialogProps
|
||||||
} from "@saleor/productTypes/components/AssignAttributeDialog";
|
} from "@saleor/productTypes/components/AssignAttributeDialog";
|
||||||
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
import { formError } from "@saleor/storybook/misc";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
|
||||||
const props: AssignAttributeDialogProps = {
|
const props: AssignAttributeDialogProps = {
|
||||||
|
@ -30,14 +30,5 @@ storiesOf("Generics / Assign attributes dialog", module)
|
||||||
<AssignAttributeDialog {...props} attributes={undefined} loading={true} />
|
<AssignAttributeDialog {...props} attributes={undefined} loading={true} />
|
||||||
))
|
))
|
||||||
.add("errors", () => (
|
.add("errors", () => (
|
||||||
<AssignAttributeDialog
|
<AssignAttributeDialog {...props} errors={[formError("").message]} />
|
||||||
{...props}
|
|
||||||
errors={[
|
|
||||||
{
|
|
||||||
__typename: "ProductError" as "ProductError",
|
|
||||||
code: ProductErrorCode.INVALID,
|
|
||||||
field: null
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
));
|
));
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import { formError } from "@saleor/storybook/misc";
|
||||||
|
import ProductTypeAttributeEditDialog, {
|
||||||
|
ProductTypeAttributeEditDialogProps
|
||||||
|
} from "../../../productTypes/components/ProductTypeAttributeEditDialog";
|
||||||
|
import { attributes } from "../../../productTypes/fixtures";
|
||||||
|
import Decorator from "../../Decorator";
|
||||||
|
|
||||||
|
const attribute = attributes[0];
|
||||||
|
|
||||||
|
const props: ProductTypeAttributeEditDialogProps = {
|
||||||
|
disabled: false,
|
||||||
|
errors: [],
|
||||||
|
name: attribute.name,
|
||||||
|
onClose: () => undefined,
|
||||||
|
onConfirm: () => undefined,
|
||||||
|
opened: true,
|
||||||
|
title: "Add Attribute",
|
||||||
|
values: attribute.values.map(value => ({
|
||||||
|
label: value.name,
|
||||||
|
value: value.id
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
storiesOf("Product types / Edit attribute", module)
|
||||||
|
.addDecorator(Decorator)
|
||||||
|
.add("default", () => <ProductTypeAttributeEditDialog {...props} />)
|
||||||
|
.add("loading", () => (
|
||||||
|
<ProductTypeAttributeEditDialog {...props} disabled={true} />
|
||||||
|
))
|
||||||
|
.add("form errors", () => (
|
||||||
|
<ProductTypeAttributeEditDialog
|
||||||
|
{...props}
|
||||||
|
errors={["name", "values"].map(field => formError(field))}
|
||||||
|
/>
|
||||||
|
));
|
|
@ -2,11 +2,12 @@ import { Omit } from "@material-ui/core";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
import { formError } from "@saleor/storybook/misc";
|
||||||
import ProductTypeCreatePage, {
|
import ProductTypeCreatePage, {
|
||||||
ProductTypeCreatePageProps,
|
ProductTypeCreatePageProps,
|
||||||
ProductTypeForm
|
ProductTypeForm
|
||||||
} from "../../../productTypes/components/ProductTypeCreatePage";
|
} from "../../../productTypes/components/ProductTypeCreatePage";
|
||||||
import { WeightUnitsEnum, ProductErrorCode } from "../../../types/globalTypes";
|
import { WeightUnitsEnum } from "../../../types/globalTypes";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
|
||||||
const props: Omit<ProductTypeCreatePageProps, "classes"> = {
|
const props: Omit<ProductTypeCreatePageProps, "classes"> = {
|
||||||
|
@ -29,10 +30,6 @@ storiesOf("Views / Product types / Create product type", module)
|
||||||
.add("form errors", () => (
|
.add("form errors", () => (
|
||||||
<ProductTypeCreatePage
|
<ProductTypeCreatePage
|
||||||
{...props}
|
{...props}
|
||||||
errors={(["name"] as Array<keyof ProductTypeForm>).map(field => ({
|
errors={(["name"] as Array<keyof ProductTypeForm>).map(formError)}
|
||||||
__typename: "ProductError",
|
|
||||||
code: ProductErrorCode.INVALID,
|
|
||||||
field
|
|
||||||
}))}
|
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
@ -3,12 +3,13 @@ import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { listActionsProps } from "@saleor/fixtures";
|
import { listActionsProps } from "@saleor/fixtures";
|
||||||
|
import { formError } from "@saleor/storybook/misc";
|
||||||
import ProductTypeDetailsPage, {
|
import ProductTypeDetailsPage, {
|
||||||
ProductTypeDetailsPageProps,
|
ProductTypeDetailsPageProps,
|
||||||
ProductTypeForm
|
ProductTypeForm
|
||||||
} from "../../../productTypes/components/ProductTypeDetailsPage";
|
} from "../../../productTypes/components/ProductTypeDetailsPage";
|
||||||
import { productType } from "../../../productTypes/fixtures";
|
import { productType } from "../../../productTypes/fixtures";
|
||||||
import { WeightUnitsEnum, ProductErrorCode } from "../../../types/globalTypes";
|
import { WeightUnitsEnum } from "../../../types/globalTypes";
|
||||||
import Decorator from "../../Decorator";
|
import Decorator from "../../Decorator";
|
||||||
|
|
||||||
const props: Omit<ProductTypeDetailsPageProps, "classes"> = {
|
const props: Omit<ProductTypeDetailsPageProps, "classes"> = {
|
||||||
|
@ -54,12 +55,6 @@ storiesOf("Views / Product types / Product type details", module)
|
||||||
.add("form errors", () => (
|
.add("form errors", () => (
|
||||||
<ProductTypeDetailsPage
|
<ProductTypeDetailsPage
|
||||||
{...props}
|
{...props}
|
||||||
errors={(["name", "weight"] as Array<keyof ProductTypeForm>).map(
|
errors={(["name"] as Array<keyof ProductTypeForm>).map(formError)}
|
||||||
field => ({
|
|
||||||
__typename: "ProductError",
|
|
||||||
code: ProductErrorCode.INVALID,
|
|
||||||
field
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelec
|
||||||
|
|
||||||
export interface UserError {
|
export interface UserError {
|
||||||
field: string | null;
|
field: string | null;
|
||||||
message?: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DialogProps {
|
export interface DialogProps {
|
||||||
|
|
11
src/utils/errors.ts
Normal file
11
src/utils/errors.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { UserError } from "@saleor/types";
|
||||||
|
|
||||||
|
export function getFieldError(errors: UserError[], field: string): UserError {
|
||||||
|
return errors.find(err => err.field === field);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getErrors(errors: UserError[]): string[] {
|
||||||
|
return errors
|
||||||
|
.filter(err => ["", null].includes(err.field))
|
||||||
|
.map(err => err.message);
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
import { defineMessages } from "react-intl";
|
|
||||||
|
|
||||||
const commonErrorMessages = defineMessages({
|
|
||||||
graphqlError: {
|
|
||||||
defaultMessage: "API error"
|
|
||||||
},
|
|
||||||
unknownError: {
|
|
||||||
defaultMessage: "Unknown error"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default commonErrorMessages;
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { UserError } from "@saleor/types";
|
|
||||||
|
|
||||||
export function getFieldError<T extends UserError>(
|
|
||||||
errors: T[],
|
|
||||||
field: string
|
|
||||||
): T {
|
|
||||||
return errors.find(err => err.field === field);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getErrors(errors: UserError[]): string[] {
|
|
||||||
return errors
|
|
||||||
.filter(err => ["", null].includes(err.field))
|
|
||||||
.map(err => err.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFormErrors<TField extends string, TError extends UserError>(
|
|
||||||
fields: TField[],
|
|
||||||
errors: TError[]
|
|
||||||
): Record<TField, TError> {
|
|
||||||
return fields.reduce((errs, field) => {
|
|
||||||
errs[field] = getFieldError(errors, field);
|
|
||||||
return errs;
|
|
||||||
}, ({} as unknown) as Record<TField, TError>);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { default as getProductErrorMessage } from "./product";
|
|
|
@ -1,50 +0,0 @@
|
||||||
import { IntlShape, defineMessages } from "react-intl";
|
|
||||||
|
|
||||||
import { ProductErrorFragment } from "@saleor/attributes/types/ProductErrorFragment";
|
|
||||||
import { ProductErrorCode } from "@saleor/types/globalTypes";
|
|
||||||
import { commonMessages } from "@saleor/intl";
|
|
||||||
import commonErrorMessages from "./common";
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
attributeAlreadyAssigned: {
|
|
||||||
defaultMessage:
|
|
||||||
"This attribute has already been assigned to this product type"
|
|
||||||
},
|
|
||||||
attributeCannotBeAssigned: {
|
|
||||||
defaultMessage: "This attribute cannot be assigned to this product type"
|
|
||||||
},
|
|
||||||
attributeVariantsDisabled: {
|
|
||||||
defaultMessage: "Variants are disabled in this product type"
|
|
||||||
},
|
|
||||||
variantNoDigitalContent: {
|
|
||||||
defaultMessage: "This variant does not have any digital content"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function getProductErrorMessage(
|
|
||||||
err: ProductErrorFragment,
|
|
||||||
intl: IntlShape
|
|
||||||
): string {
|
|
||||||
if (err) {
|
|
||||||
switch (err.code) {
|
|
||||||
case ProductErrorCode.ATTRIBUTE_ALREADY_ASSIGNED:
|
|
||||||
return intl.formatMessage(messages.attributeAlreadyAssigned);
|
|
||||||
case ProductErrorCode.ATTRIBUTE_CANNOT_BE_ASSIGNED:
|
|
||||||
return intl.formatMessage(messages.attributeCannotBeAssigned);
|
|
||||||
case ProductErrorCode.ATTRIBUTE_VARIANTS_DISABLED:
|
|
||||||
return intl.formatMessage(messages.attributeVariantsDisabled);
|
|
||||||
case ProductErrorCode.GRAPHQL_ERROR:
|
|
||||||
return intl.formatMessage(commonErrorMessages.graphqlError);
|
|
||||||
case ProductErrorCode.REQUIRED:
|
|
||||||
return intl.formatMessage(commonMessages.requiredField);
|
|
||||||
case ProductErrorCode.VARIANT_NO_DIGITAL_CONTENT:
|
|
||||||
return intl.formatMessage(messages.variantNoDigitalContent);
|
|
||||||
default:
|
|
||||||
return intl.formatMessage(commonErrorMessages.unknownError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getProductErrorMessage;
|
|
Loading…
Reference in a new issue