diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 3183cd510..60e8cc9cd 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -5388,6 +5388,9 @@ "src_dot_shipping_dot_components_dot_ShippingMethodProducts_dot_4190792473": { "string": "Actions" }, + "src_dot_shipping_dot_components_dot_ShippingRateInfo_dot_579967655": { + "string": "Shipping rate name" + }, "src_dot_shipping_dot_components_dot_ShippingRateZipCodeRangeRemoveDialog_dot_1083561409": { "string": "Are you sure you want to remove this ZIP-code rule?" }, @@ -5438,33 +5441,47 @@ "src_dot_shipping_dot_components_dot_ShippingZoneCountriesAssignDialog_dot_3510295703": { "string": "Search Countries" }, - "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_2364051773": { - "string": "Currently, there are no countries assigned to this shipping zone" - }, - "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_3109712047": { + "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_countries": { + "context": "country list header", "string": "Countries" }, - "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_4049462680": { - "context": "header", + "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_createZone": { + "context": "section header", "string": "Create New Shipping Zone" }, - "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_4270729636": { + "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_defaultZone": { "string": "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" }, - "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_1325966144": { - "string": "Shipping" - }, - "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_2364051773": { + "src_dot_shipping_dot_components_dot_ShippingZoneCreatePage_dot_noCountriesAssigned": { "string": "Currently, there are no countries assigned to this shipping zone" }, - "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_3109712047": { + "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_countries": { + "context": "country list header", "string": "Countries" }, - "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_4270729636": { + "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_defaultZone": { "string": "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" }, - "src_dot_shipping_dot_components_dot_ShippingZoneInfo_dot_579967655": { - "string": "Shipping rate name" + "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_noCountriesAssigned": { + "string": "Currently, there are no countries assigned to this shipping zone" + }, + "src_dot_shipping_dot_components_dot_ShippingZoneDetailsPage_dot_shipping": { + "context": "shipping section header", + "string": "Shipping" + }, + "src_dot_shipping_dot_components_dot_ShippingZoneInfo_dot_1470703814": { + "context": "field placeholder", + "string": "Description of a shipping zone." + }, + "src_dot_shipping_dot_components_dot_ShippingZoneInfo_dot_1560416099": { + "string": "Shipping zone name" + }, + "src_dot_shipping_dot_components_dot_ShippingZoneInfo_dot_3374163063": { + "string": "Description" + }, + "src_dot_shipping_dot_components_dot_ShippingZoneInfo_dot_3877274856": { + "context": "character limit", + "string": "{numberOfCharacters} of {maxCharacters} characters" }, "src_dot_shipping_dot_components_dot_ShippingZoneRatesCreatePage_dot_1161979494": { "context": "page title", diff --git a/schema.graphql b/schema.graphql index aa914316b..0bdaec696 100644 --- a/schema.graphql +++ b/schema.graphql @@ -4782,6 +4782,7 @@ type ShippingZone implements Node & ObjectWithMetadata { countries: [CountryDisplay] shippingMethods: [ShippingMethod] warehouses: [Warehouse] + description: String } type ShippingZoneBulkDelete { @@ -4809,6 +4810,7 @@ type ShippingZoneCreate { input ShippingZoneCreateInput { name: String + description: String countries: [String] default: Boolean addWarehouses: [ID] @@ -4828,6 +4830,7 @@ type ShippingZoneUpdate { input ShippingZoneUpdateInput { name: String + description: String countries: [String] default: Boolean addWarehouses: [ID] diff --git a/src/fragments/shipping.ts b/src/fragments/shipping.ts index 25a89d06c..bf19fe7d9 100644 --- a/src/fragments/shipping.ts +++ b/src/fragments/shipping.ts @@ -13,6 +13,7 @@ export const shippingZoneFragment = gql` country } name + description } `; diff --git a/src/fragments/types/ShippingZoneDetailsFragment.ts b/src/fragments/types/ShippingZoneDetailsFragment.ts index da530e989..961b71048 100644 --- a/src/fragments/types/ShippingZoneDetailsFragment.ts +++ b/src/fragments/types/ShippingZoneDetailsFragment.ts @@ -117,6 +117,7 @@ export interface ShippingZoneDetailsFragment { id: string; countries: (ShippingZoneDetailsFragment_countries | null)[] | null; name: string; + description: string | null; default: boolean; shippingMethods: (ShippingZoneDetailsFragment_shippingMethods | null)[] | null; warehouses: (ShippingZoneDetailsFragment_warehouses | null)[] | null; diff --git a/src/fragments/types/ShippingZoneFragment.ts b/src/fragments/types/ShippingZoneFragment.ts index ddbf30da6..2aa596c72 100644 --- a/src/fragments/types/ShippingZoneFragment.ts +++ b/src/fragments/types/ShippingZoneFragment.ts @@ -31,4 +31,5 @@ export interface ShippingZoneFragment { id: string; countries: (ShippingZoneFragment_countries | null)[] | null; name: string; + description: string | null; } diff --git a/src/shipping/components/ShippingRateInfo/ShippingRateInfo.tsx b/src/shipping/components/ShippingRateInfo/ShippingRateInfo.tsx new file mode 100644 index 000000000..b66937bee --- /dev/null +++ b/src/shipping/components/ShippingRateInfo/ShippingRateInfo.tsx @@ -0,0 +1,52 @@ +import Card from "@material-ui/core/Card"; +import CardContent from "@material-ui/core/CardContent"; +import TextField from "@material-ui/core/TextField"; +import CardTitle from "@saleor/components/CardTitle"; +import { ShippingErrorFragment } from "@saleor/fragments/types/ShippingErrorFragment"; +import { commonMessages } from "@saleor/intl"; +import { getFormErrors } from "@saleor/utils/errors"; +import getShippingErrorMessage from "@saleor/utils/errors/shipping"; +import React from "react"; +import { useIntl } from "react-intl"; + +export interface ShippingRateInfoProps { + data: Record<"name", string>; + disabled: boolean; + errors: ShippingErrorFragment[]; + onChange: (event: React.ChangeEvent) => void; +} + +const ShippingRateInfo: React.FC = ({ + data, + disabled, + errors, + onChange +}) => { + const intl = useIntl(); + + const formErrors = getFormErrors(["name"], errors); + + return ( + + + + + + + ); +}; +ShippingRateInfo.displayName = "ShippingRateInfo"; +export default ShippingRateInfo; diff --git a/src/shipping/components/ShippingRateInfo/index.ts b/src/shipping/components/ShippingRateInfo/index.ts new file mode 100644 index 000000000..8002507b2 --- /dev/null +++ b/src/shipping/components/ShippingRateInfo/index.ts @@ -0,0 +1,2 @@ +export { default } from "./ShippingRateInfo"; +export * from "./ShippingRateInfo"; diff --git a/src/shipping/components/ShippingZoneCreatePage/ShippingZoneCreatePage.tsx b/src/shipping/components/ShippingZoneCreatePage/ShippingZoneCreatePage.tsx index a357ef81d..c221a5c1c 100644 --- a/src/shipping/components/ShippingZoneCreatePage/ShippingZoneCreatePage.tsx +++ b/src/shipping/components/ShippingZoneCreatePage/ShippingZoneCreatePage.tsx @@ -11,7 +11,7 @@ import { CountryFragment } from "@saleor/fragments/types/CountryFragment"; import { ShippingErrorFragment } from "@saleor/fragments/types/ShippingErrorFragment"; import { sectionNames } from "@saleor/intl"; import React from "react"; -import { useIntl } from "react-intl"; +import { defineMessages, useIntl } from "react-intl"; import ShippingZoneCountriesAssignDialog from "../ShippingZoneCountriesAssignDialog"; import ShippingZoneInfo from "../ShippingZoneInfo"; @@ -19,9 +19,29 @@ import ShippingZoneInfo from "../ShippingZoneInfo"; export interface FormData { countries: string[]; default: boolean; + description: string; name: string; } +const messages = defineMessages({ + countries: { + defaultMessage: "Countries", + description: "country list header" + }, + createZone: { + defaultMessage: "Create New Shipping Zone", + description: "section header" + }, + defaultZone: { + defaultMessage: + "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" + }, + noCountriesAssigned: { + defaultMessage: + "Currently, there are no countries assigned to this shipping zone" + } +}); + export interface ShippingZoneCreatePageProps { countries: CountryFragment[]; disabled: boolean; @@ -46,6 +66,7 @@ const ShippingZoneCreatePage: React.FC = ({ const initialForm: FormData = { countries: [], default: false, + description: "", name: "" }; @@ -57,12 +78,7 @@ const ShippingZoneCreatePage: React.FC = ({ {intl.formatMessage(sectionNames.shipping)} - +
= ({ disabled={disabled} emptyText={ data.default - ? intl.formatMessage({ - defaultMessage: - "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" - }) - : intl.formatMessage({ - defaultMessage: - "Currently, there are no countries assigned to this shipping zone" - }) + ? intl.formatMessage(messages.defaultZone) + : intl.formatMessage(messages.noCountriesAssigned) } onCountryAssign={toggleModal} onCountryUnassign={countryCode => @@ -99,9 +109,7 @@ const ShippingZoneCreatePage: React.FC = ({ } } as any) } - title={intl.formatMessage({ - defaultMessage: "Countries" - })} + title={intl.formatMessage(messages.countries)} />
diff --git a/src/shipping/components/ShippingZoneDetailsPage/ShippingZoneDetailsPage.tsx b/src/shipping/components/ShippingZoneDetailsPage/ShippingZoneDetailsPage.tsx index 204ee2bdb..0c7a55b0e 100644 --- a/src/shipping/components/ShippingZoneDetailsPage/ShippingZoneDetailsPage.tsx +++ b/src/shipping/components/ShippingZoneDetailsPage/ShippingZoneDetailsPage.tsx @@ -22,7 +22,7 @@ import createMultiAutocompleteSelectHandler from "@saleor/utils/handlers/multiAu import { mapMetadataItemToInput } from "@saleor/utils/maps"; import useMetadataChangeTrigger from "@saleor/utils/metadata/useMetadataChangeTrigger"; import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; +import { defineMessages, FormattedMessage, useIntl } from "react-intl"; import { getStringOrPlaceholder } from "../../../misc"; import { ChannelProps, FetchMoreProps, SearchProps } from "../../../types"; @@ -33,9 +33,29 @@ import ShippingZoneWarehouses from "../ShippingZoneWarehouses"; export interface FormData extends MetadataFormData { name: string; + description: string; warehouses: string[]; } +const messages = defineMessages({ + countries: { + defaultMessage: "Countries", + description: "country list header" + }, + defaultZone: { + defaultMessage: + "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" + }, + noCountriesAssigned: { + defaultMessage: + "Currently, there are no countries assigned to this shipping zone" + }, + shipping: { + defaultMessage: "Shipping", + description: "shipping section header" + } +}); + export interface ShippingZoneDetailsPageProps extends FetchMoreProps, SearchProps, @@ -93,6 +113,7 @@ const ShippingZoneDetailsPage: React.FC = ({ const intl = useIntl(); const initialForm: FormData = { + description: shippingZone?.description || "", metadata: shippingZone?.metadata.map(mapMetadataItemToInput), name: shippingZone?.name || "", privateMetadata: shippingZone?.privateMetadata.map(mapMetadataItemToInput), @@ -128,7 +149,7 @@ const ShippingZoneDetailsPage: React.FC = ({ return ( - + @@ -147,20 +168,12 @@ const ShippingZoneDetailsPage: React.FC = ({ shippingZone?.default === undefined ? undefined : shippingZone.default - ? intl.formatMessage({ - defaultMessage: - "This is default shipping zone, which means that it covers all of the countries which are not assigned to other shipping zones" - }) - : intl.formatMessage({ - defaultMessage: - "Currently, there are no countries assigned to this shipping zone" - }) + ? intl.formatMessage(messages.defaultZone) + : intl.formatMessage(messages.noCountriesAssigned) )} onCountryAssign={onCountryAdd} onCountryUnassign={onCountryRemove} - title={intl.formatMessage({ - defaultMessage: "Countries" - })} + title={intl.formatMessage(messages.countries)} /> ; + data: Record<"name" | "description", string>; disabled: boolean; errors: ShippingErrorFragment[]; onChange: (event: React.ChangeEvent) => void; } +const useStyles = makeStyles( + { + label: { + flex: 1 + }, + labelContainer: { + "& span": { + paddingRight: 30 + }, + display: "flex" + } + }, + { name: "ShippingZoneCreatePage" } +); + +const MAX_DESCRIPTION_LENGTH = 300; + const ShippingZoneInfo: React.FC = ({ data, disabled, @@ -23,6 +42,7 @@ const ShippingZoneInfo: React.FC = ({ onChange }) => { const intl = useIntl(); + const classes = useStyles({}); const formErrors = getFormErrors(["name"], errors); @@ -38,12 +58,51 @@ const ShippingZoneInfo: React.FC = ({ fullWidth helperText={getShippingErrorMessage(formErrors.name, intl)} label={intl.formatMessage({ - defaultMessage: "Shipping rate name" + defaultMessage: "Shipping zone name" })} name="name" value={data.name} onChange={onChange} /> + + MAX_DESCRIPTION_LENGTH} + name={"description"} + label={ +
+
+ +
+ {data.description?.length > 0 && ( + + + + )} +
+ } + InputProps={{ + inputProps: { + maxLength: MAX_DESCRIPTION_LENGTH + } + }} + value={data.description} + onChange={onChange} + disabled={disabled} + fullWidth + multiline + placeholder={intl.formatMessage({ + defaultMessage: "Description of a shipping zone.", + description: "field placeholder" + })} + rows={10} + /> ); diff --git a/src/shipping/components/ShippingZoneRates/ShippingZoneRates.tsx b/src/shipping/components/ShippingZoneRates/ShippingZoneRates.tsx index a11037b6c..623fbbad5 100644 --- a/src/shipping/components/ShippingZoneRates/ShippingZoneRates.tsx +++ b/src/shipping/components/ShippingZoneRates/ShippingZoneRates.tsx @@ -37,15 +37,15 @@ const useStyles = makeStyles( paddingRight: 24, width: ICONBUTTON_SIZE + theme.spacing(0.5) }, + buttonColumn: { + padding: "4px 0", + width: "62px" + }, nameColumn: { width: "auto" }, valueColumn: { width: "auto" - }, - buttonColumn: { - width: "62px", - padding: "4px 0" } }), { name: "ShippingZoneRates" } diff --git a/src/shipping/components/ShippingZoneRatesCreatePage/ShippingZoneRatesCreatePage.tsx b/src/shipping/components/ShippingZoneRatesCreatePage/ShippingZoneRatesCreatePage.tsx index c390d76e1..952c9c421 100644 --- a/src/shipping/components/ShippingZoneRatesCreatePage/ShippingZoneRatesCreatePage.tsx +++ b/src/shipping/components/ShippingZoneRatesCreatePage/ShippingZoneRatesCreatePage.tsx @@ -15,7 +15,7 @@ import { validatePrice } from "@saleor/products/utils/validation"; import OrderValue from "@saleor/shipping/components/OrderValue"; import OrderWeight from "@saleor/shipping/components/OrderWeight"; import PricingCard from "@saleor/shipping/components/PricingCard"; -import ShippingZoneInfo from "@saleor/shipping/components/ShippingZoneInfo"; +import ShippingRateInfo from "@saleor/shipping/components/ShippingRateInfo"; import { createChannelsChangeHandler } from "@saleor/shipping/handlers"; import { ShippingMethodTypeEnum } from "@saleor/types/globalTypes"; import React from "react"; @@ -116,7 +116,7 @@ export const ShippingZoneRatesCreatePage: React.FC
- = ({
- = ({ id, input: { addWarehouses: warehouseDiff.added, + description: submitData.description, name: submitData.name, removeWarehouses: warehouseDiff.removed } diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index 545e9b98f..86a89a84b 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -202858,7 +202858,7 @@ exports[`Storyshots Views / Shipping / Create shipping zone default 1`] = ` class="MuiFormLabel-root-id MuiInputLabel-root-id MuiInputLabel-formControl-id MuiInputLabel-animated-id MuiInputLabel-outlined-id" data-shrink="false" > - Shipping rate name + Shipping zone name
+
+
+ +
+ + +
+
- Shipping rate name + Shipping zone name
+
+
+ +
+ + +
+
- Shipping rate name + Shipping zone name
+
+
+ +
+