From 8b0fe986b28486bee000d183fe4fa15a07e8288f Mon Sep 17 00:00:00 2001 From: Dawid Tarasiuk Date: Tue, 12 Jan 2021 12:11:15 +0100 Subject: [PATCH] 1425 - Support reference type attribute on attribute details page (#918) * Support reference type attribute on attribute details page * Trigger CI * Prevent changing attribute entity type during attribute update * Refactor attribute details components --- locale/defaultMessages.json | 121 ++-- .../AttributeDetails/AttributeDetails.tsx | 173 ++++-- .../AttributePage/AttributePage.tsx | 9 +- .../AttributeProperties.tsx | 165 +++--- src/attributes/fixtures.ts | 1 + src/attributes/types/AttributeCreate.ts | 3 +- src/attributes/types/AttributeDetails.ts | 3 +- src/attributes/types/AttributeUpdate.ts | 3 +- src/attributes/types/AttributeValueCreate.ts | 3 +- src/attributes/types/AttributeValueDelete.ts | 3 +- src/attributes/types/AttributeValueUpdate.ts | 3 +- src/attributes/utils/data.ts | 45 ++ .../views/AttributeCreate/AttributeCreate.tsx | 38 +- .../AttributeDetails/AttributeDetails.tsx | 1 + src/fragments/attributes.ts | 2 + .../types/AttributeDetailsFragment.ts | 3 +- .../__snapshots__/Stories.test.ts.snap | 554 +++++++++--------- 17 files changed, 650 insertions(+), 480 deletions(-) diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 57c44198f..ff4677d0d 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -733,37 +733,49 @@ "context": "dialog content", "string": "Are you sure you want to delete {attributeName}?" }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_1005562666": { - "context": "attribute's editor component", - "string": "Catalog Input type for Store Owner" + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_attributeLabel": { + "context": "attribute's label", + "string": "Default Label" }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_1336738461": { - "context": "product attribute type", - "string": "Dropdown" - }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_1376373679": { - "context": "file attribute type", - "string": "File" - }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_2592224946": { - "context": "check to require attribute to have value", - "string": "Value Required" - }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_3334509011": { - "context": "product attribute type", - "string": "Multiple Select" - }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_3605174225": { + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_attributeSlug": { "context": "attribute's slug short code label", "string": "Attribute Code" }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_4107478955": { + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_attributeSlugHelperText": { "context": "attribute slug input field helper text", "string": "This is used internally. Make sure you don’t use spaces" }, - "src_dot_attributes_dot_components_dot_AttributeDetails_dot_691600601": { - "context": "attribute's label", - "string": "Default Label" + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_dropdown": { + "context": "product attribute type", + "string": "Dropdown" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_entityType": { + "context": "attribute's editor component entity", + "string": "Entity" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_file": { + "context": "file attribute type", + "string": "File" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_inputType": { + "context": "attribute's editor component", + "string": "Catalog Input type for Store Owner" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_multiselect": { + "context": "product attribute type", + "string": "Multiple Select" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_page": { + "context": "page attribute entity type", + "string": "Pages" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_references": { + "context": "references attribute type", + "string": "References" + }, + "src_dot_attributes_dot_components_dot_AttributeDetails_dot_valueRequired": { + "context": "check to require attribute to have value", + "string": "Value Required" }, "src_dot_attributes_dot_components_dot_AttributeListPage_dot_2417065806": { "context": "tab name", @@ -844,43 +856,46 @@ "context": "page title", "string": "Create New Attribute" }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_1318123158": { - "context": "attribute is filterable in storefront", - "string": "Use in Faceted Navigation" - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_1877630205": { - "context": "attribute properties regarding storefront", - "string": "Storefront Properties" - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_26409543": { - "context": "attribute properties regarding dashboard", - "string": "Dashboard Properties" - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_3135366329": { - "context": "attribute visibility in storefront", - "string": "Public" - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_3590282519": { - "context": "attribute position in storefront filters", - "string": "Position in faceted navigation" - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_3758203740": { - "string": "If enabled, attribute will be accessible to customers." - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_4048785456": { - "string": "If enabled this attribute can be used as a column in product table." - }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_673770329": { + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_availableInGrid": { "context": "add attribute as column in product list table", "string": "Add to Column Options" }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_714335445": { + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_availableInGridCaption": { + "context": "caption", + "string": "If enabled this attribute can be used as a column in product table." + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_dashboardPropertiesTitle": { + "context": "attribute properties regarding dashboard", + "string": "Dashboard Properties" + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_filterableInDashboard": { "context": "use attribute in filtering", "string": "Use in Filtering" }, - "src_dot_attributes_dot_components_dot_AttributeProperties_dot_787251583": { + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_filterableInDashboardCaption": { + "context": "caption", "string": "If enabled, you’ll be able to use this attribute to filter products in product list." }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_filterableInStorefront": { + "context": "attribute is filterable in storefront", + "string": "Use in Faceted Navigation" + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_storefrontPropertiesTitle": { + "context": "attribute properties regarding storefront", + "string": "Storefront Properties" + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_storefrontSearchPosition": { + "context": "attribute position in storefront filters", + "string": "Position in faceted navigation" + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_visibleInStorefront": { + "context": "attribute visibility in storefront", + "string": "Public" + }, + "src_dot_attributes_dot_components_dot_AttributeProperties_dot_visibleInStorefrontCaption": { + "context": "caption", + "string": "If enabled, attribute will be accessible to customers." + }, "src_dot_attributes_dot_components_dot_AttributeValueDeleteDialog_dot_1326420604": { "context": "delete attribute value", "string": "Are you sure you want to delete \"{name}\" value?" diff --git a/src/attributes/components/AttributeDetails/AttributeDetails.tsx b/src/attributes/components/AttributeDetails/AttributeDetails.tsx index 8ad3451d0..1138547ff 100644 --- a/src/attributes/components/AttributeDetails/AttributeDetails.tsx +++ b/src/attributes/components/AttributeDetails/AttributeDetails.tsx @@ -1,5 +1,6 @@ import Card from "@material-ui/core/Card"; import CardContent from "@material-ui/core/CardContent"; +import { makeStyles } from "@material-ui/core/styles"; import TextField from "@material-ui/core/TextField"; import CardTitle from "@saleor/components/CardTitle"; import ControlledCheckbox from "@saleor/components/ControlledCheckbox"; @@ -7,16 +8,86 @@ import FormSpacer from "@saleor/components/FormSpacer"; import SingleSelectField from "@saleor/components/SingleSelectField"; import { AttributeErrorFragment } from "@saleor/fragments/types/AttributeErrorFragment"; import { commonMessages } from "@saleor/intl"; -import { AttributeInputTypeEnum } from "@saleor/types/globalTypes"; +import { + AttributeEntityTypeEnum, + AttributeInputTypeEnum +} from "@saleor/types/globalTypes"; import { getFormErrors } from "@saleor/utils/errors"; import getAttributeErrorMessage from "@saleor/utils/errors/attribute"; import React from "react"; -import { useIntl } from "react-intl"; +import { defineMessages, useIntl } from "react-intl"; import slugify from "slugify"; import { getAttributeSlugErrorMessage } from "../../errors"; import { AttributePageFormData } from "../AttributePage"; +const messages = defineMessages({ + attributeLabel: { + defaultMessage: "Default Label", + description: "attribute's label" + }, + attributeSlug: { + defaultMessage: "Attribute Code", + description: "attribute's slug short code label" + }, + attributeSlugHelperText: { + defaultMessage: "This is used internally. Make sure you don’t use spaces", + description: "attribute slug input field helper text" + }, + entityType: { + defaultMessage: "Entity", + description: "attribute's editor component entity" + }, + inputType: { + defaultMessage: "Catalog Input type for Store Owner", + description: "attribute's editor component" + }, + valueRequired: { + defaultMessage: "Value Required", + description: "check to require attribute to have value" + } +}); + +const inputTypeMessages = defineMessages({ + dropdown: { + defaultMessage: "Dropdown", + description: "product attribute type" + }, + file: { + defaultMessage: "File", + description: "file attribute type" + }, + multiselect: { + defaultMessage: "Multiple Select", + description: "product attribute type" + }, + references: { + defaultMessage: "References", + description: "references attribute type" + } +}); + +const entityTypeMessages = defineMessages({ + page: { + defaultMessage: "Pages", + description: "page attribute entity type" + } +}); + +const useStyles = makeStyles( + theme => ({ + inputTypeSection: { + columnGap: theme.spacing(2) + "px", + display: "flex", + [theme.breakpoints.down("md")]: { + flexFlow: "wrap", + rowGap: theme.spacing(3) + "px" + } + } + }), + { name: "AttributeDetails" } +); + export interface AttributeDetailsProps { canChangeType: boolean; data: AttributePageFormData; @@ -25,39 +96,39 @@ export interface AttributeDetailsProps { onChange: (event: React.ChangeEvent) => void; } -const AttributeDetails: React.FC = ({ - canChangeType, - data, - disabled, - errors, - onChange -}) => { +const AttributeDetails: React.FC = props => { + const { canChangeType, data, disabled, errors, onChange } = props; + const classes = useStyles(props); const intl = useIntl(); const inputTypeChoices = [ { - label: intl.formatMessage({ - defaultMessage: "Dropdown", - description: "product attribute type" - }), + label: intl.formatMessage(inputTypeMessages.dropdown), value: AttributeInputTypeEnum.DROPDOWN }, { - label: intl.formatMessage({ - defaultMessage: "Multiple Select", - description: "product attribute type" - }), + label: intl.formatMessage(inputTypeMessages.multiselect), value: AttributeInputTypeEnum.MULTISELECT }, { - label: intl.formatMessage({ - defaultMessage: "File", - description: "file attribute type" - }), + label: intl.formatMessage(inputTypeMessages.file), value: AttributeInputTypeEnum.FILE + }, + { + label: intl.formatMessage(inputTypeMessages.references), + value: AttributeInputTypeEnum.REFERENCE + } + ]; + const entityTypeChoices = [ + { + label: intl.formatMessage(entityTypeMessages.page), + value: AttributeEntityTypeEnum.PAGE } ]; - const formErrors = getFormErrors(["name", "slug", "inputType"], errors); + const formErrors = getFormErrors( + ["name", "slug", "inputType", "entityType"], + errors + ); return ( @@ -68,10 +139,7 @@ const AttributeDetails: React.FC = ({ = ({ - +
+ + {data.inputType === AttributeInputTypeEnum.REFERENCE && ( + + )} +
= ({ attribute === null ? { availableInGrid: true, + entityType: null, filterableInDashboard: true, filterableInStorefront: true, inputType: AttributeInputTypeEnum.DROPDOWN, @@ -98,6 +102,7 @@ const AttributePage: React.FC = ({ } : { availableInGrid: maybe(() => attribute.availableInGrid, true), + entityType: attribute?.entityType ?? null, filterableInDashboard: maybe( () => attribute.filterableInDashboard, true @@ -172,7 +177,9 @@ const AttributePage: React.FC = ({ errors={errors} onChange={change} /> - {data.inputType !== AttributeInputTypeEnum.FILE && ( + {ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes( + data.inputType + ) && ( <> = ({ const formErrors = getFormErrors(["storefrontSearchPosition"], errors); + const dashboardProperties = ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes( + data.inputType + ); + + const storefrontFacetedNavigationProperties = + ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes(data.inputType) && + data.type === AttributeTypeEnum.PRODUCT_TYPE; + return ( @@ -74,61 +125,48 @@ const AttributeProperties: React.FC = ({ /> */} - +
- {data.inputType !== AttributeInputTypeEnum.FILE && - data.type === AttributeTypeEnum.PRODUCT_TYPE && ( - <> - - {data.filterableInStorefront && ( - <> - - - - )} - - )} + {storefrontFacetedNavigationProperties && ( + <> + + {data.filterableInStorefront && ( + <> + + + + )} + + )} - + - + } @@ -136,14 +174,11 @@ const AttributeProperties: React.FC = ({ onChange={onChange} disabled={disabled} /> - {data.inputType !== AttributeInputTypeEnum.FILE && ( + {dashboardProperties && ( <> - +
@@ -151,12 +186,11 @@ const AttributeProperties: React.FC = ({ name={"filterableInDashboard" as keyof FormData} label={ <> - + - + } @@ -169,12 +203,9 @@ const AttributeProperties: React.FC = ({ name={"availableInGrid" as keyof FormData} label={ <> - + - + } diff --git a/src/attributes/fixtures.ts b/src/attributes/fixtures.ts index 160d45919..ff10cea3b 100644 --- a/src/attributes/fixtures.ts +++ b/src/attributes/fixtures.ts @@ -10,6 +10,7 @@ import { AttributeList_attributes_edges_node } from "./types/AttributeList"; export const attribute: AttributeDetailsFragment = { __typename: "Attribute" as "Attribute", availableInGrid: true, + entityType: null, filterableInDashboard: false, filterableInStorefront: true, id: "UHJvZHVjdEF0dHJpYnV0ZTo5", diff --git a/src/attributes/types/AttributeCreate.ts b/src/attributes/types/AttributeCreate.ts index 0e63aa68b..2e97f1264 100644 --- a/src/attributes/types/AttributeCreate.ts +++ b/src/attributes/types/AttributeCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; +import { AttributeCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: AttributeCreate @@ -47,6 +47,7 @@ export interface AttributeCreate_attributeCreate_attribute { privateMetadata: (AttributeCreate_attributeCreate_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeCreate_attributeCreate_attribute_values | null)[] | null; diff --git a/src/attributes/types/AttributeDetails.ts b/src/attributes/types/AttributeDetails.ts index 54d682d16..e5605d8fb 100644 --- a/src/attributes/types/AttributeDetails.ts +++ b/src/attributes/types/AttributeDetails.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeTypeEnum, AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL query operation: AttributeDetails @@ -47,6 +47,7 @@ export interface AttributeDetails_attribute { privateMetadata: (AttributeDetails_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeDetails_attribute_values | null)[] | null; diff --git a/src/attributes/types/AttributeUpdate.ts b/src/attributes/types/AttributeUpdate.ts index 162d99f69..e4d0f1124 100644 --- a/src/attributes/types/AttributeUpdate.ts +++ b/src/attributes/types/AttributeUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeUpdateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; +import { AttributeUpdateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: AttributeUpdate @@ -47,6 +47,7 @@ export interface AttributeUpdate_attributeUpdate_attribute { privateMetadata: (AttributeUpdate_attributeUpdate_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeUpdate_attributeUpdate_attribute_values | null)[] | null; diff --git a/src/attributes/types/AttributeValueCreate.ts b/src/attributes/types/AttributeValueCreate.ts index 4c2bb316b..25b3a12d8 100644 --- a/src/attributes/types/AttributeValueCreate.ts +++ b/src/attributes/types/AttributeValueCreate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; +import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: AttributeValueCreate @@ -47,6 +47,7 @@ export interface AttributeValueCreate_attributeValueCreate_attribute { privateMetadata: (AttributeValueCreate_attributeValueCreate_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeValueCreate_attributeValueCreate_attribute_values | null)[] | null; diff --git a/src/attributes/types/AttributeValueDelete.ts b/src/attributes/types/AttributeValueDelete.ts index db63e0752..a649a5fb2 100644 --- a/src/attributes/types/AttributeValueDelete.ts +++ b/src/attributes/types/AttributeValueDelete.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; +import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: AttributeValueDelete @@ -47,6 +47,7 @@ export interface AttributeValueDelete_attributeValueDelete_attribute { privateMetadata: (AttributeValueDelete_attributeValueDelete_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeValueDelete_attributeValueDelete_attribute_values | null)[] | null; diff --git a/src/attributes/types/AttributeValueUpdate.ts b/src/attributes/types/AttributeValueUpdate.ts index da64a2a40..80ec5ec4d 100644 --- a/src/attributes/types/AttributeValueUpdate.ts +++ b/src/attributes/types/AttributeValueUpdate.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; +import { AttributeValueCreateInput, AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum, AttributeErrorCode } from "./../../types/globalTypes"; // ==================================================== // GraphQL mutation operation: AttributeValueUpdate @@ -47,6 +47,7 @@ export interface AttributeValueUpdate_attributeValueUpdate_attribute { privateMetadata: (AttributeValueUpdate_attributeValueUpdate_attribute_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeValueUpdate_attributeValueUpdate_attribute_values | null)[] | null; diff --git a/src/attributes/utils/data.ts b/src/attributes/utils/data.ts index 4cccbcd2a..ee2a64f86 100644 --- a/src/attributes/utils/data.ts +++ b/src/attributes/utils/data.ts @@ -10,8 +10,53 @@ import { } from "@saleor/types/globalTypes"; import { MutationFetchResult } from "react-apollo"; +import { AttributePageFormData } from "../components/AttributePage"; +import { AttributeValueEditDialogFormData } from "../components/AttributeValueEditDialog"; import { AttributeValueDelete } from "../types/AttributeValueDelete"; +export const ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES = [ + AttributeInputTypeEnum.DROPDOWN, + AttributeInputTypeEnum.MULTISELECT +]; + +function getSimpleAttributeData( + data: AttributePageFormData, + values: AttributeValueEditDialogFormData[] +) { + return { + ...data, + metadata: undefined, + privateMetadata: undefined, + storefrontSearchPosition: parseInt(data.storefrontSearchPosition, 10), + values: values.map(value => ({ + name: value.name + })) + }; +} + +function getFileOrReferenceAttributeData( + data: AttributePageFormData, + values: AttributeValueEditDialogFormData[] +) { + return { + ...getSimpleAttributeData(data, values), + availableInGrid: undefined, + filterableInDashboard: undefined, + filterableInStorefront: undefined + }; +} + +export function getAttributeData( + data: AttributePageFormData, + values: AttributeValueEditDialogFormData[] +) { + if (ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES.includes(data.inputType)) { + return getSimpleAttributeData(data, values); + } else { + return getFileOrReferenceAttributeData(data, values); + } +} + export const isFileValueUnused = ( attributesWithNewFileValue: FormsetData, existingAttribute: diff --git a/src/attributes/views/AttributeCreate/AttributeCreate.tsx b/src/attributes/views/AttributeCreate/AttributeCreate.tsx index 7fe4e48f0..3dc6bd039 100644 --- a/src/attributes/views/AttributeCreate/AttributeCreate.tsx +++ b/src/attributes/views/AttributeCreate/AttributeCreate.tsx @@ -1,12 +1,10 @@ +import { getAttributeData } from "@saleor/attributes/utils/data"; import { AttributeErrorFragment } from "@saleor/fragments/types/AttributeErrorFragment"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import { getStringOrPlaceholder } from "@saleor/misc"; import { ReorderEvent } from "@saleor/types"; -import { - AttributeErrorCode, - AttributeInputTypeEnum -} from "@saleor/types/globalTypes"; +import { AttributeErrorCode } from "@saleor/types/globalTypes"; import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers"; import createMetadataCreateHandler from "@saleor/utils/handlers/metadataCreateHandler"; import { @@ -57,33 +55,6 @@ function areValuesEqual( return a.name === b.name; } -function getSimpleAttributeData( - data: AttributePageFormData, - values: AttributeValueEditDialogFormData[] -) { - return { - ...data, - metadata: undefined, - privateMetadata: undefined, - storefrontSearchPosition: parseInt(data.storefrontSearchPosition, 10), - values: values.map(value => ({ - name: value.name - })) - }; -} - -function getFileAttributeData( - data: AttributePageFormData, - values: AttributeValueEditDialogFormData[] -) { - return { - ...getSimpleAttributeData(data, values), - availableInGrid: undefined, - filterableInDashboard: undefined, - filterableInStorefront: undefined - }; -} - const AttributeDetails: React.FC = ({ params }) => { const navigate = useNavigator(); const notify = useNotifier(); @@ -145,10 +116,7 @@ const AttributeDetails: React.FC = ({ params }) => { setValues(move(values[oldIndex], values, areValuesEqual, newIndex)); const handleCreate = async (data: AttributePageFormData) => { - const input = - data.inputType === AttributeInputTypeEnum.FILE - ? getFileAttributeData(data, values) - : getSimpleAttributeData(data, values); + const input = getAttributeData(data, values); const result = await attributeCreate({ variables: { diff --git a/src/attributes/views/AttributeDetails/AttributeDetails.tsx b/src/attributes/views/AttributeDetails/AttributeDetails.tsx index acfc3deb3..02dc810d9 100644 --- a/src/attributes/views/AttributeDetails/AttributeDetails.tsx +++ b/src/attributes/views/AttributeDetails/AttributeDetails.tsx @@ -178,6 +178,7 @@ const AttributeDetails: React.FC = ({ id, params }) => { const handleUpdate = async (data: AttributePageFormData) => { const input = { ...data, + entityType: undefined, inputType: undefined, metadata: undefined, privateMetadata: undefined, diff --git a/src/fragments/attributes.ts b/src/fragments/attributes.ts index 76e6c2504..1ba2d436f 100644 --- a/src/fragments/attributes.ts +++ b/src/fragments/attributes.ts @@ -12,6 +12,7 @@ export const attributeValueFragment = gql` file { ...FileFragment } + reference } `; @@ -36,6 +37,7 @@ export const attributeDetailsFragment = gql` ...MetadataFragment availableInGrid inputType + entityType storefrontSearchPosition valueRequired values { diff --git a/src/fragments/types/AttributeDetailsFragment.ts b/src/fragments/types/AttributeDetailsFragment.ts index de9a0d902..3cf67ce3b 100644 --- a/src/fragments/types/AttributeDetailsFragment.ts +++ b/src/fragments/types/AttributeDetailsFragment.ts @@ -2,7 +2,7 @@ /* eslint-disable */ // This file was automatically generated and should not be edited. -import { AttributeTypeEnum, AttributeInputTypeEnum } from "./../../types/globalTypes"; +import { AttributeTypeEnum, AttributeInputTypeEnum, AttributeEntityTypeEnum } from "./../../types/globalTypes"; // ==================================================== // GraphQL fragment: AttributeDetailsFragment @@ -47,6 +47,7 @@ export interface AttributeDetailsFragment { privateMetadata: (AttributeDetailsFragment_privateMetadata | null)[]; availableInGrid: boolean; inputType: AttributeInputTypeEnum | null; + entityType: AttributeEntityTypeEnum | null; storefrontSearchPosition: number; valueRequired: boolean; values: (AttributeDetailsFragment_values | null)[] | null; diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index eb5bd3e4c..04b6cbf60 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -28404,57 +28404,61 @@ exports[`Storyshots Views / Attributes / Attribute details create 1`] = ` class="FormSpacer-spacer-id" />
-
+
- Dropdown -
- - - + Dropdown +
+ + + +
-
+
- Dropdown -
- - - + Dropdown +
+ + + +
-
+
- Dropdown -
- - - + Dropdown +
+ + + +
-
+
- Dropdown -
- - - + Dropdown +
+ + + +
-
+
- Multiple Select -
- - - + Multiple Select +
+ + + +
-
+
- Dropdown -
- - - + Dropdown +
+ + + +