Implement dropdown for province/country area selection based on allowedFields from the API (#2833)
* Dropdown for province / country area * Remove unused ref * Implementation for settings and warehouses * Disable autocomplete
This commit is contained in:
parent
3669f45061
commit
6db5dfa94a
16 changed files with 312 additions and 63 deletions
|
@ -13,6 +13,7 @@ import FormSpacer from "../FormSpacer";
|
||||||
import SingleAutocompleteSelectField, {
|
import SingleAutocompleteSelectField, {
|
||||||
SingleAutocompleteChoiceType,
|
SingleAutocompleteChoiceType,
|
||||||
} from "../SingleAutocompleteSelectField";
|
} from "../SingleAutocompleteSelectField";
|
||||||
|
import { useAddressValidation } from "./useAddressValidation";
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
|
@ -46,6 +47,24 @@ function getErrorMessage(
|
||||||
return getOrderErrorMessage(err, intl);
|
return getOrderErrorMessage(err, intl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PossibleFormFields = {
|
||||||
|
CITY: "city",
|
||||||
|
CITY_AREA: "cityArea",
|
||||||
|
COUNTRY: "country",
|
||||||
|
COUNTRY_AREA: "countryArea",
|
||||||
|
FIRST_NAME: "firstName",
|
||||||
|
LAST_NAME: "lastName",
|
||||||
|
COMPANY_NAME: "companyName",
|
||||||
|
PHONE: "phone",
|
||||||
|
POSTAL_CODE: "postalCode",
|
||||||
|
STREET_ADDRESS_1: "streetAddress1",
|
||||||
|
STREET_ADDRESS_2: "streetAddress2",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
const formFields: Array<keyof AddressTypeInput> = Object.values(
|
||||||
|
PossibleFormFields,
|
||||||
|
);
|
||||||
|
|
||||||
const AddressEdit: React.FC<AddressEditProps> = props => {
|
const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
const {
|
const {
|
||||||
countries,
|
countries,
|
||||||
|
@ -56,23 +75,9 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
onChange,
|
onChange,
|
||||||
onCountryChange,
|
onCountryChange,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const { areas, isFieldAllowed } = useAddressValidation(data.country);
|
||||||
const formFields: Array<keyof AddressTypeInput> = [
|
|
||||||
"city",
|
|
||||||
"cityArea",
|
|
||||||
"country",
|
|
||||||
"countryArea",
|
|
||||||
"firstName",
|
|
||||||
"lastName",
|
|
||||||
"companyName",
|
|
||||||
"phone",
|
|
||||||
"postalCode",
|
|
||||||
"streetAddress1",
|
|
||||||
"streetAddress2",
|
|
||||||
];
|
|
||||||
|
|
||||||
const formErrors = getFormErrors<
|
const formErrors = getFormErrors<
|
||||||
keyof AddressTypeInput,
|
keyof AddressTypeInput,
|
||||||
|
@ -219,7 +224,6 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<TextField
|
<TextField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!formErrors.postalCode}
|
error={!!formErrors.postalCode}
|
||||||
helperText={getErrorMessage(formErrors.postalCode, intl)}
|
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id: "oYGfnY",
|
id: "oYGfnY",
|
||||||
defaultMessage: "ZIP / Postal code",
|
defaultMessage: "ZIP / Postal code",
|
||||||
|
@ -241,6 +245,7 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
<div>
|
<div>
|
||||||
<SingleAutocompleteSelectField
|
<SingleAutocompleteSelectField
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
autocomplete="new-password"
|
||||||
data-test-id="address-edit-country-select-field"
|
data-test-id="address-edit-country-select-field"
|
||||||
displayValue={countryDisplayValue}
|
displayValue={countryDisplayValue}
|
||||||
error={!!formErrors.country}
|
error={!!formErrors.country}
|
||||||
|
@ -259,23 +264,27 @@ const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
{isFieldAllowed(PossibleFormFields.COUNTRY_AREA) && (
|
||||||
disabled={disabled}
|
<SingleAutocompleteSelectField
|
||||||
error={!!formErrors.countryArea}
|
disabled={disabled}
|
||||||
helperText={getErrorMessage(formErrors.countryArea, intl)}
|
autocomplete="new-password"
|
||||||
label={intl.formatMessage({
|
data-test-id="address-edit-country-area-field"
|
||||||
id: "AuwpCm",
|
displayValue={data.countryArea}
|
||||||
defaultMessage: "Country area",
|
error={!!formErrors.countryArea}
|
||||||
})}
|
helperText={getErrorMessage(formErrors.countryArea, intl)}
|
||||||
name="countryArea"
|
label={intl.formatMessage({
|
||||||
onChange={onChange}
|
id: "AuwpCm",
|
||||||
value={data.countryArea}
|
defaultMessage: "Country area",
|
||||||
fullWidth
|
})}
|
||||||
InputProps={{
|
name="countryArea"
|
||||||
autoComplete: "new-password",
|
onChange={onChange}
|
||||||
spellCheck: false,
|
value={data.countryArea}
|
||||||
}}
|
choices={areas}
|
||||||
/>
|
InputProps={{
|
||||||
|
spellCheck: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
20
src/components/AddressEdit/createCountryHandler.test.ts
Normal file
20
src/components/AddressEdit/createCountryHandler.test.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { ChangeEvent } from "react";
|
||||||
|
|
||||||
|
import { createCountryHandler } from "./createCountryHandler";
|
||||||
|
|
||||||
|
describe("createCountryHandler", () => {
|
||||||
|
it("calls original country handler and restets the country area field", () => {
|
||||||
|
// Arrange
|
||||||
|
const originalCountryHandler = jest.fn();
|
||||||
|
const setFn = jest.fn();
|
||||||
|
const exampleEvent = { target: "some event" } as ChangeEvent<any>;
|
||||||
|
const newHandler = createCountryHandler(originalCountryHandler, setFn);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
newHandler(exampleEvent);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(originalCountryHandler).toBeCalledWith(exampleEvent);
|
||||||
|
expect(setFn).toBeCalledWith({ countryArea: "" });
|
||||||
|
});
|
||||||
|
});
|
11
src/components/AddressEdit/createCountryHandler.ts
Normal file
11
src/components/AddressEdit/createCountryHandler.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { AddressTypeInput } from "@saleor/customers/types";
|
||||||
|
import { FormChange } from "@saleor/hooks/useForm";
|
||||||
|
import { ChangeEvent } from "react";
|
||||||
|
|
||||||
|
export const createCountryHandler = (
|
||||||
|
currentHandler: FormChange,
|
||||||
|
set: (dataSet: Partial<AddressTypeInput>) => void,
|
||||||
|
) => (event: ChangeEvent<any>) => {
|
||||||
|
currentHandler(event);
|
||||||
|
set({ countryArea: "" });
|
||||||
|
};
|
13
src/components/AddressEdit/queries.ts
Normal file
13
src/components/AddressEdit/queries.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { gql } from "@apollo/client";
|
||||||
|
|
||||||
|
export const addressValidationQuery = gql`
|
||||||
|
query addressValidationRules($countryCode: CountryCode!) {
|
||||||
|
addressValidationRules(countryCode: $countryCode) {
|
||||||
|
countryAreaChoices {
|
||||||
|
raw
|
||||||
|
verbose
|
||||||
|
}
|
||||||
|
allowedFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
65
src/components/AddressEdit/useAddressValidation.test.ts
Normal file
65
src/components/AddressEdit/useAddressValidation.test.ts
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import { useAddressValidationRulesQuery } from "@saleor/graphql";
|
||||||
|
import { renderHook } from "@testing-library/react-hooks";
|
||||||
|
|
||||||
|
import { useAddressValidation } from "./useAddressValidation";
|
||||||
|
|
||||||
|
jest.mock("@saleor/graphql", () => ({
|
||||||
|
CountryCode: jest.requireActual("@saleor/graphql").CountryCode,
|
||||||
|
useAddressValidationRulesQuery: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("useAddressValidation", () => {
|
||||||
|
it("skips loading validation rules when country is not provided", () => {
|
||||||
|
// Arrange
|
||||||
|
(useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
|
||||||
|
data: null,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
// Act
|
||||||
|
const {
|
||||||
|
result: { current },
|
||||||
|
} = renderHook(() => useAddressValidation());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(current.areas).toEqual([]);
|
||||||
|
expect(current.loading).toBeFalsy();
|
||||||
|
expect(useAddressValidationRulesQuery).toBeCalledWith({
|
||||||
|
skip: true,
|
||||||
|
variables: { countryCode: undefined },
|
||||||
|
});
|
||||||
|
expect(current.isFieldAllowed("country")).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("loads validation rules when country is provided", () => {
|
||||||
|
// Arrange
|
||||||
|
(useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
|
||||||
|
data: {
|
||||||
|
addressValidationRules: {
|
||||||
|
countryAreaChoices: [
|
||||||
|
{ raw: "AL", verbose: "Alabama" },
|
||||||
|
{ raw: "AN", verbose: "Ancona" },
|
||||||
|
],
|
||||||
|
allowedFields: ["country"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
// Act
|
||||||
|
const {
|
||||||
|
result: { current },
|
||||||
|
} = renderHook(() => useAddressValidation("US"));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(current.areas).toEqual([
|
||||||
|
{ label: "Alabama", value: "Alabama" },
|
||||||
|
{ label: "Ancona", value: "Ancona" },
|
||||||
|
]);
|
||||||
|
expect(current.loading).toBeFalsy();
|
||||||
|
expect(useAddressValidationRulesQuery).toBeCalledWith({
|
||||||
|
skip: false,
|
||||||
|
variables: { countryCode: "US" },
|
||||||
|
});
|
||||||
|
expect(current.isFieldAllowed("country")).toBeTruthy();
|
||||||
|
expect(current.isFieldAllowed("countryArea")).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
58
src/components/AddressEdit/useAddressValidation.ts
Normal file
58
src/components/AddressEdit/useAddressValidation.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
import {
|
||||||
|
AddressValidationRulesQuery,
|
||||||
|
CountryCode,
|
||||||
|
useAddressValidationRulesQuery,
|
||||||
|
} from "@saleor/graphql";
|
||||||
|
import { ChoiceValue } from "@saleor/sdk/dist/apollo/types";
|
||||||
|
|
||||||
|
const prepareChoices = (values: ChoiceValue[]) =>
|
||||||
|
values.map(v => ({
|
||||||
|
label: v.verbose,
|
||||||
|
value: v.verbose,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const selectRules = (data: AddressValidationRulesQuery) =>
|
||||||
|
data
|
||||||
|
? data.addressValidationRules
|
||||||
|
: { countryAreaChoices: [], allowedFields: [] };
|
||||||
|
|
||||||
|
const useValidationRules = (country?: string) => {
|
||||||
|
const countryCode = CountryCode[country];
|
||||||
|
const { data, loading } = useAddressValidationRulesQuery({
|
||||||
|
variables: { countryCode },
|
||||||
|
skip: !countryCode,
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data, loading };
|
||||||
|
};
|
||||||
|
|
||||||
|
const useAreas = (data: AddressValidationRulesQuery) => {
|
||||||
|
const rawChoices = selectRules(data).countryAreaChoices;
|
||||||
|
const choices = prepareChoices(rawChoices);
|
||||||
|
|
||||||
|
return choices;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useAllowedFields = (data: AddressValidationRulesQuery) => {
|
||||||
|
const isAllowed = (fieldName: string) => {
|
||||||
|
if (!data) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectRules(data).allowedFields.includes(fieldName);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { isAllowed };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useAddressValidation = (country?: string) => {
|
||||||
|
const { data, loading } = useValidationRules(country);
|
||||||
|
const areas = useAreas(data);
|
||||||
|
const { isAllowed } = useAllowedFields(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
areas,
|
||||||
|
isFieldAllowed: isAllowed,
|
||||||
|
loading,
|
||||||
|
};
|
||||||
|
};
|
|
@ -19,6 +19,8 @@ import getWarehouseErrorMessage from "@saleor/utils/errors/warehouse";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { IntlShape, useIntl } from "react-intl";
|
import { IntlShape, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
import { useAddressValidation } from "../AddressEdit/useAddressValidation";
|
||||||
|
|
||||||
export interface CompanyAddressFormProps {
|
export interface CompanyAddressFormProps {
|
||||||
countries: SingleAutocompleteChoiceType[];
|
countries: SingleAutocompleteChoiceType[];
|
||||||
data: AddressTypeInput;
|
data: AddressTypeInput;
|
||||||
|
@ -62,7 +64,7 @@ const CompanyAddressForm: React.FC<CompanyAddressFormProps> = props => {
|
||||||
onChange,
|
onChange,
|
||||||
onCountryChange,
|
onCountryChange,
|
||||||
} = props;
|
} = props;
|
||||||
|
const { areas, isFieldAllowed } = useAddressValidation(data.country);
|
||||||
const classes = useStyles(props);
|
const classes = useStyles(props);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
@ -176,6 +178,7 @@ const CompanyAddressForm: React.FC<CompanyAddressFormProps> = props => {
|
||||||
<SingleAutocompleteSelectField
|
<SingleAutocompleteSelectField
|
||||||
data-test-id="address-edit-country-select-field"
|
data-test-id="address-edit-country-select-field"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
autocomplete="new-password"
|
||||||
displayValue={displayCountry}
|
displayValue={displayCountry}
|
||||||
error={!!formErrors.country}
|
error={!!formErrors.country}
|
||||||
helperText={getErrorMessage(formErrors.country, intl)}
|
helperText={getErrorMessage(formErrors.country, intl)}
|
||||||
|
@ -189,25 +192,30 @@ const CompanyAddressForm: React.FC<CompanyAddressFormProps> = props => {
|
||||||
choices={countries}
|
choices={countries}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
spellCheck: false,
|
spellCheck: false,
|
||||||
|
autoComplete: "new-password",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<TextField
|
{isFieldAllowed("countryArea") && (
|
||||||
disabled={disabled}
|
<SingleAutocompleteSelectField
|
||||||
error={!!formErrors.countryArea}
|
disabled={disabled}
|
||||||
helperText={getErrorMessage(formErrors.countryArea, intl)}
|
autocomplete="new-password"
|
||||||
label={intl.formatMessage({
|
data-test-id="address-edit-country-area-field"
|
||||||
id: "AuwpCm",
|
displayValue={data.countryArea}
|
||||||
defaultMessage: "Country area",
|
error={!!formErrors.countryArea}
|
||||||
})}
|
helperText={getErrorMessage(formErrors.countryArea, intl)}
|
||||||
name={"countryArea" as keyof AddressTypeInput}
|
label={intl.formatMessage({
|
||||||
onChange={onChange}
|
id: "AuwpCm",
|
||||||
value={data.countryArea}
|
defaultMessage: "Country area",
|
||||||
fullWidth
|
})}
|
||||||
InputProps={{
|
name="countryArea"
|
||||||
autoComplete: "address-level1",
|
onChange={onChange}
|
||||||
spellCheck: false,
|
value={data.countryArea}
|
||||||
}}
|
choices={areas}
|
||||||
/>
|
InputProps={{
|
||||||
|
spellCheck: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
<FormSpacer />
|
<FormSpacer />
|
||||||
<TextField
|
<TextField
|
||||||
|
|
|
@ -37,6 +37,7 @@ export interface SingleAutocompleteSelectFieldProps
|
||||||
helperText?: string;
|
helperText?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
InputProps?: InputProps;
|
InputProps?: InputProps;
|
||||||
|
autocomplete?: string,
|
||||||
fetchChoices?: (value: string) => void;
|
fetchChoices?: (value: string) => void;
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
fetchOnFocus?: boolean;
|
fetchOnFocus?: boolean;
|
||||||
|
@ -65,6 +66,7 @@ const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectF
|
||||||
label,
|
label,
|
||||||
loading,
|
loading,
|
||||||
name,
|
name,
|
||||||
|
autocomplete,
|
||||||
placeholder,
|
placeholder,
|
||||||
value,
|
value,
|
||||||
InputProps,
|
InputProps,
|
||||||
|
@ -229,6 +231,7 @@ const SingleAutocompleteSelectFieldComponent: React.FC<SingleAutocompleteSelectF
|
||||||
inputProps={{
|
inputProps={{
|
||||||
...(getInputProps({
|
...(getInputProps({
|
||||||
placeholder,
|
placeholder,
|
||||||
|
autocomplete,
|
||||||
onClick: handleToggleMenu,
|
onClick: handleToggleMenu,
|
||||||
}) as OutlinedInputProps["inputProps"]),
|
}) as OutlinedInputProps["inputProps"]),
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import AddressEdit from "@saleor/components/AddressEdit";
|
import AddressEdit from "@saleor/components/AddressEdit";
|
||||||
|
import { createCountryHandler } from "@saleor/components/AddressEdit/createCountryHandler";
|
||||||
import BackButton from "@saleor/components/BackButton";
|
import BackButton from "@saleor/components/BackButton";
|
||||||
import ConfirmButton from "@saleor/components/ConfirmButton";
|
import ConfirmButton from "@saleor/components/ConfirmButton";
|
||||||
import Form from "@saleor/components/Form";
|
import Form from "@saleor/components/Form";
|
||||||
|
@ -94,13 +95,15 @@ const CustomerAddressDialog: React.FC<CustomerAddressDialogProps> = ({
|
||||||
maxWidth="sm"
|
maxWidth="sm"
|
||||||
>
|
>
|
||||||
<Form initial={initialForm} onSubmit={handleSubmit}>
|
<Form initial={initialForm} onSubmit={handleSubmit}>
|
||||||
{({ change, data }) => {
|
{({ change, set, data }) => {
|
||||||
const handleCountrySelect = createSingleAutocompleteSelectHandler(
|
const countrySelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setCountryDisplayName,
|
setCountryDisplayName,
|
||||||
countryChoices,
|
countryChoices,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleCountrySelect = createCountryHandler(countrySelect, set);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DialogTitle>
|
<DialogTitle>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { createCountryHandler } from "@saleor/components/AddressEdit/createCountryHandler";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import { CardSpacer } from "@saleor/components/CardSpacer";
|
import { CardSpacer } from "@saleor/components/CardSpacer";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
|
@ -143,13 +144,15 @@ const CustomerCreatePage: React.FC<CustomerCreatePageProps> = ({
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{({ change, data, isSaveDisabled, submit }) => {
|
{({ change, set, data, isSaveDisabled, submit }) => {
|
||||||
const handleCountrySelect = createSingleAutocompleteSelectHandler(
|
const countrySelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setCountryDisplayName,
|
setCountryDisplayName,
|
||||||
countryChoices,
|
countryChoices,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleCountrySelect = createCountryHandler(countrySelect, set);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={customerListUrl()}>
|
<Backlink href={customerListUrl()}>
|
||||||
|
|
|
@ -5039,6 +5039,45 @@ export function useCollectionDetailsLazyQuery(baseOptions?: ApolloReactHooks.Laz
|
||||||
export type CollectionDetailsQueryHookResult = ReturnType<typeof useCollectionDetailsQuery>;
|
export type CollectionDetailsQueryHookResult = ReturnType<typeof useCollectionDetailsQuery>;
|
||||||
export type CollectionDetailsLazyQueryHookResult = ReturnType<typeof useCollectionDetailsLazyQuery>;
|
export type CollectionDetailsLazyQueryHookResult = ReturnType<typeof useCollectionDetailsLazyQuery>;
|
||||||
export type CollectionDetailsQueryResult = Apollo.QueryResult<Types.CollectionDetailsQuery, Types.CollectionDetailsQueryVariables>;
|
export type CollectionDetailsQueryResult = Apollo.QueryResult<Types.CollectionDetailsQuery, Types.CollectionDetailsQueryVariables>;
|
||||||
|
export const AddressValidationRulesDocument = gql`
|
||||||
|
query addressValidationRules($countryCode: CountryCode!) {
|
||||||
|
addressValidationRules(countryCode: $countryCode) {
|
||||||
|
countryAreaChoices {
|
||||||
|
raw
|
||||||
|
verbose
|
||||||
|
}
|
||||||
|
allowedFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useAddressValidationRulesQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useAddressValidationRulesQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useAddressValidationRulesQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useAddressValidationRulesQuery({
|
||||||
|
* variables: {
|
||||||
|
* countryCode: // value for 'countryCode'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useAddressValidationRulesQuery(baseOptions: ApolloReactHooks.QueryHookOptions<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useQuery<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>(AddressValidationRulesDocument, options);
|
||||||
|
}
|
||||||
|
export function useAddressValidationRulesLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return ApolloReactHooks.useLazyQuery<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>(AddressValidationRulesDocument, options);
|
||||||
|
}
|
||||||
|
export type AddressValidationRulesQueryHookResult = ReturnType<typeof useAddressValidationRulesQuery>;
|
||||||
|
export type AddressValidationRulesLazyQueryHookResult = ReturnType<typeof useAddressValidationRulesLazyQuery>;
|
||||||
|
export type AddressValidationRulesQueryResult = Apollo.QueryResult<Types.AddressValidationRulesQuery, Types.AddressValidationRulesQueryVariables>;
|
||||||
export const CheckIfOrderExistsDocument = gql`
|
export const CheckIfOrderExistsDocument = gql`
|
||||||
query CheckIfOrderExists($id: ID!) {
|
query CheckIfOrderExists($id: ID!) {
|
||||||
order(id: $id) {
|
order(id: $id) {
|
||||||
|
|
|
@ -6670,6 +6670,13 @@ export type CollectionDetailsQueryVariables = Exact<{
|
||||||
|
|
||||||
export type CollectionDetailsQuery = { __typename: 'Query', collection: { __typename: 'Collection', slug: string, description: any | null, seoDescription: string | null, seoTitle: string | null, id: string, name: string, products: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, backgroundImage: { __typename: 'Image', alt: string | null, url: string } | null, channelListings: Array<{ __typename: 'CollectionChannelListing', isPublished: boolean, publicationDate: any | null, channel: { __typename: 'Channel', id: string, name: string } }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null };
|
export type CollectionDetailsQuery = { __typename: 'Query', collection: { __typename: 'Collection', slug: string, description: any | null, seoDescription: string | null, seoTitle: string | null, id: string, name: string, products: { __typename: 'ProductCountableConnection', edges: Array<{ __typename: 'ProductCountableEdge', node: { __typename: 'Product', id: string, name: string, productType: { __typename: 'ProductType', id: string, name: string }, thumbnail: { __typename: 'Image', url: string } | null, channelListings: Array<{ __typename: 'ProductChannelListing', isPublished: boolean, publicationDate: any | null, isAvailableForPurchase: boolean | null, availableForPurchase: any | null, visibleInListings: boolean, channel: { __typename: 'Channel', id: string, name: string, currencyCode: string } }> | null } }>, pageInfo: { __typename: 'PageInfo', endCursor: string | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string | null } } | null, backgroundImage: { __typename: 'Image', alt: string | null, url: string } | null, channelListings: Array<{ __typename: 'CollectionChannelListing', isPublished: boolean, publicationDate: any | null, channel: { __typename: 'Channel', id: string, name: string } }> | null, metadata: Array<{ __typename: 'MetadataItem', key: string, value: string }>, privateMetadata: Array<{ __typename: 'MetadataItem', key: string, value: string }> } | null };
|
||||||
|
|
||||||
|
export type AddressValidationRulesQueryVariables = Exact<{
|
||||||
|
countryCode: CountryCode;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type AddressValidationRulesQuery = { __typename: 'Query', addressValidationRules: { __typename: 'AddressValidationData', allowedFields: Array<string>, countryAreaChoices: Array<{ __typename: 'ChoiceValue', raw: string | null, verbose: string | null }> } | null };
|
||||||
|
|
||||||
export type CheckIfOrderExistsQueryVariables = Exact<{
|
export type CheckIfOrderExistsQueryVariables = Exact<{
|
||||||
id: Scalars['ID'];
|
id: Scalars['ID'];
|
||||||
}>;
|
}>;
|
||||||
|
|
|
@ -145,6 +145,7 @@ function useOrderCustomerAddressesEditForm(
|
||||||
value: {
|
value: {
|
||||||
...formData.shippingAddress,
|
...formData.shippingAddress,
|
||||||
[event.target.name]: event.target.value,
|
[event.target.name]: event.target.value,
|
||||||
|
countryArea: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
@ -159,6 +160,7 @@ function useOrderCustomerAddressesEditForm(
|
||||||
value: {
|
value: {
|
||||||
...formData.billingAddress,
|
...formData.billingAddress,
|
||||||
[event.target.name]: event.target.value,
|
[event.target.name]: event.target.value,
|
||||||
|
countryArea: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { createCountryHandler } from "@saleor/components/AddressEdit/createCountryHandler";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
|
@ -126,14 +127,16 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
|
||||||
confirmLeave
|
confirmLeave
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{({ change, data, isSaveDisabled, submit }) => {
|
{({ change, data, set, isSaveDisabled, submit }) => {
|
||||||
const countryChoices = mapCountriesToChoices(shop?.countries || []);
|
const countryChoices = mapCountriesToChoices(shop?.countries || []);
|
||||||
const handleCountryChange = createSingleAutocompleteSelectHandler(
|
const countrySelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setDisplayCountry,
|
setDisplayCountry,
|
||||||
countryChoices,
|
countryChoices,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleCountrySelect = createCountryHandler(countrySelect, set);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={configurationMenuUrl}>
|
<Backlink href={configurationMenuUrl}>
|
||||||
|
@ -175,7 +178,7 @@ const SiteSettingsPage: React.FC<SiteSettingsPageProps> = props => {
|
||||||
description: "section header",
|
description: "section header",
|
||||||
})}
|
})}
|
||||||
onChange={change}
|
onChange={change}
|
||||||
onCountryChange={handleCountryChange}
|
onCountryChange={handleCountrySelect}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Savebar
|
<Savebar
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { createCountryHandler } from "@saleor/components/AddressEdit/createCountryHandler";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import CardSpacer from "@saleor/components/CardSpacer";
|
import CardSpacer from "@saleor/components/CardSpacer";
|
||||||
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
||||||
|
@ -67,14 +68,16 @@ const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form confirmLeave initial={initialForm} onSubmit={handleSubmit}>
|
<Form confirmLeave initial={initialForm} onSubmit={handleSubmit}>
|
||||||
{({ change, data, submit }) => {
|
{({ change, data, set, submit }) => {
|
||||||
const countryChoices = mapCountriesToChoices(countries);
|
const countryChoices = mapCountriesToChoices(countries);
|
||||||
const handleCountryChange = createSingleAutocompleteSelectHandler(
|
const countrySelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setDisplayCountry,
|
setDisplayCountry,
|
||||||
countryChoices,
|
countryChoices,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleCountrySelect = createCountryHandler(countrySelect, set);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Backlink href={warehouseListUrl()}>
|
<Backlink href={warehouseListUrl()}>
|
||||||
|
@ -108,7 +111,7 @@ const WarehouseCreatePage: React.FC<WarehouseCreatePageProps> = ({
|
||||||
description: "warehouse",
|
description: "warehouse",
|
||||||
})}
|
})}
|
||||||
onChange={change}
|
onChange={change}
|
||||||
onCountryChange={handleCountryChange}
|
onCountryChange={handleCountrySelect}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { createCountryHandler } from "@saleor/components/AddressEdit/createCountryHandler";
|
||||||
import { Backlink } from "@saleor/components/Backlink";
|
import { Backlink } from "@saleor/components/Backlink";
|
||||||
import CardSpacer from "@saleor/components/CardSpacer";
|
import CardSpacer from "@saleor/components/CardSpacer";
|
||||||
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
import CompanyAddressInput from "@saleor/components/CompanyAddressInput";
|
||||||
|
@ -93,11 +94,12 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
|
||||||
>
|
>
|
||||||
{({ change, data, isSaveDisabled, submit, set }) => {
|
{({ change, data, isSaveDisabled, submit, set }) => {
|
||||||
const countryChoices = mapCountriesToChoices(countries);
|
const countryChoices = mapCountriesToChoices(countries);
|
||||||
const handleCountryChange = createSingleAutocompleteSelectHandler(
|
const countrySelect = createSingleAutocompleteSelectHandler(
|
||||||
change,
|
change,
|
||||||
setDisplayCountry,
|
setDisplayCountry,
|
||||||
countryChoices,
|
countryChoices,
|
||||||
);
|
);
|
||||||
|
const handleCountrySelect = createCountryHandler(countrySelect, set);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
@ -126,7 +128,7 @@ const WarehouseDetailsPage: React.FC<WarehouseDetailsPageProps> = ({
|
||||||
description: "warehouse",
|
description: "warehouse",
|
||||||
})}
|
})}
|
||||||
onChange={change}
|
onChange={change}
|
||||||
onCountryChange={handleCountryChange}
|
onCountryChange={handleCountrySelect}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
Loading…
Reference in a new issue