diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index e20665750..dabe7460f 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -4238,14 +4238,6 @@ "context": "section header", "string": "Sales channel" }, - "src_dot_orders_dot_components_dot_OrderAddressEditDialog_dot_3278396777": { - "context": "dialog header", - "string": "Edit Shipping Address" - }, - "src_dot_orders_dot_components_dot_OrderAddressEditDialog_dot_3982060155": { - "context": "dialog header", - "string": "Edit Billing Address" - }, "src_dot_orders_dot_components_dot_OrderBulkCancelDialog_dot_1528036340": { "context": "dialog header", "string": "Cancel Orders" @@ -4267,9 +4259,13 @@ "context": "section header", "string": "Sales channel" }, - "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_billingAddressDescription": { + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_addressChangeDescription": { "context": "dialog content", - "string": "Add a new address:" + "string": "Select method you want to use to change address" + }, + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_billingChangeTitle": { + "context": "dialog header", + "string": "Change customer billing address" }, "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_billingSameAsShipping": { "context": "checkbox label", @@ -4283,37 +4279,50 @@ "context": "address type", "string": "Use one of customer addresses" }, - "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_customerBillingAddressDescription": { + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_customerChangeBillingDescription": { "context": "dialog content", "string": "Select one of customer addresses or add a new address:" }, - "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_customerShippingAddressDescription": { + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_customerChangeDescription": { "context": "dialog content", "string": "Which address would you like to use as shipping address for selected customer:" }, + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_customerChangeTitle": { + "context": "dialog header", + "string": "Change address for order" + }, "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_newAddress": { "context": "address type", "string": "Add new address" }, + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_noAddressBillingDescription": { + "context": "dialog content", + "string": "Add a new address:" + }, + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_noAddressDescription": { + "context": "dialog content", + "string": "This customer doesn't have any addresses in the address book. Provide address for order:" + }, "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_noResultsFound": { + "context": "info when addresses search is unsuccessful", "string": "No results found" }, "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_searchInfo": { "context": "modal information under title", "string": "Select an address you want to use from the list below" }, - "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_shippingAddressDescription": { - "context": "dialog content", - "string": "This customer doesn’t have any shipping addresses. Provide address for order:" + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_shippingChangeTitle": { + "context": "dialog header", + "string": "Change customer shipping address" + }, + "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_shippingSameAsBilling": { + "context": "checkbox label", + "string": "Set the same for shipping address" }, "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_shippingTitle": { "context": "search modal shipping title", "string": "Shipping address" }, - "src_dot_orders_dot_components_dot_OrderCustomerAddressesEditDialog_dot_title": { - "context": "dialog header", - "string": "Change address for order" - }, "src_dot_orders_dot_components_dot_OrderCustomerChangeDialog_dot_changeAddress": { "context": "option label", "string": "Change address" diff --git a/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx b/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx index 260886aac..80bde7dc1 100644 --- a/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx +++ b/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx @@ -27,7 +27,7 @@ const CustomerAddressChoiceCard: React.FC = prop diff --git a/src/customers/components/CustomerAddressChoiceCard/styles.ts b/src/customers/components/CustomerAddressChoiceCard/styles.ts index 74ab1ede7..846e5df64 100644 --- a/src/customers/components/CustomerAddressChoiceCard/styles.ts +++ b/src/customers/components/CustomerAddressChoiceCard/styles.ts @@ -3,12 +3,14 @@ import { makeStyles } from "@saleor/macaw-ui"; export const useStyles = makeStyles( theme => ({ card: { - padding: "1px" + padding: "1px", + borderColor: theme.palette.saleor.main[5], + borderStyle: "solid", + borderWidth: "2px" }, cardSelected: { borderColor: theme.palette.primary.main, - borderWidth: "2px", - padding: "0" + cursor: "pointer" }, cardContent: { display: "flex", @@ -19,7 +21,7 @@ export const useStyles = makeStyles( selectableCard: { "&:hover": { cursor: "pointer", - borderColor: theme.palette.primary.main + borderColor: theme.palette.saleor.active[3] } }, selectedLabel: { diff --git a/src/orders/components/OrderAddressEditDialog/OrderAddressEditDialog.tsx b/src/orders/components/OrderAddressEditDialog/OrderAddressEditDialog.tsx deleted file mode 100644 index fa53ae264..000000000 --- a/src/orders/components/OrderAddressEditDialog/OrderAddressEditDialog.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import { - Dialog, - DialogActions, - DialogContent, - DialogTitle -} from "@material-ui/core"; -import AddressEdit from "@saleor/components/AddressEdit"; -import BackButton from "@saleor/components/BackButton"; -import ConfirmButton from "@saleor/components/ConfirmButton"; -import Form from "@saleor/components/Form"; -import { ShopInfo_shop_countries } from "@saleor/components/Shop/types/ShopInfo"; -import { AddressTypeInput } from "@saleor/customers/types"; -import { OrderErrorFragment } from "@saleor/fragments/types/OrderErrorFragment"; -import useAddressValidation from "@saleor/hooks/useAddressValidation"; -import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors"; -import useStateFromProps from "@saleor/hooks/useStateFromProps"; -import { buttonMessages } from "@saleor/intl"; -import { ConfirmButtonTransitionState, makeStyles } from "@saleor/macaw-ui"; -import { AddressInput } from "@saleor/types/globalTypes"; -import createSingleAutocompleteSelectHandler from "@saleor/utils/handlers/singleAutocompleteSelectChangeHandler"; -import { mapCountriesToChoices } from "@saleor/utils/maps"; -import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; - -const useStyles = makeStyles( - { - overflow: { - overflowY: "visible" - } - }, - { name: "OrderAddressEditDialog" } -); - -interface OrderAddressEditDialogProps { - confirmButtonState: ConfirmButtonTransitionState; - address: AddressTypeInput; - open: boolean; - errors: OrderErrorFragment[]; - variant: "billing" | "shipping" | string; - countries?: ShopInfo_shop_countries[]; - onClose(); - onConfirm(data: AddressInput); -} - -const OrderAddressEditDialog: React.FC = props => { - const { - address, - confirmButtonState, - open, - errors = [], - variant, - countries = [], - onClose, - onConfirm - } = props; - - const classes = useStyles(props); - const intl = useIntl(); - const [countryDisplayName, setCountryDisplayName] = useStateFromProps( - countries.find(country => address?.country === country.code)?.country - ); - const { - errors: validationErrors, - submit: handleSubmit - } = useAddressValidation(onConfirm); - const dialogErrors = useModalDialogErrors( - [...errors, ...validationErrors], - open - ); - - const countryChoices = mapCountriesToChoices(countries); - - return ( - -
- {({ change, data }) => { - const handleCountrySelect = createSingleAutocompleteSelectHandler( - change, - setCountryDisplayName, - countryChoices - ); - - return ( - <> - - {variant === "billing" - ? intl.formatMessage({ - defaultMessage: "Edit Billing Address", - description: "dialog header" - }) - : intl.formatMessage({ - defaultMessage: "Edit Shipping Address", - description: "dialog header" - })} - - - - - - - - - - - - ); - }} -
-
- ); -}; - -OrderAddressEditDialog.displayName = "OrderAddressEditDialog"; -export default OrderAddressEditDialog; diff --git a/src/orders/components/OrderAddressEditDialog/index.ts b/src/orders/components/OrderAddressEditDialog/index.ts deleted file mode 100644 index 5ae253bf8..000000000 --- a/src/orders/components/OrderAddressEditDialog/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./OrderAddressEditDialog"; -export * from "./OrderAddressEditDialog"; diff --git a/src/orders/components/OrderAddressFields/OrderAddressFields.tsx b/src/orders/components/OrderAddressFields/OrderAddressFields.tsx new file mode 100644 index 000000000..ffe8f2776 --- /dev/null +++ b/src/orders/components/OrderAddressFields/OrderAddressFields.tsx @@ -0,0 +1,89 @@ +import { CustomerAddresses_user } from "@saleor/customers/types/CustomerAddresses"; +import { OrderErrorFragment } from "@saleor/fragments/types/OrderErrorFragment"; +import { SubmitPromise } from "@saleor/hooks/useForm"; +import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; +import { transformAddressToForm } from "@saleor/misc"; +import { + OrderDetails_order_billingAddress, + OrderDetails_order_shippingAddress, + OrderDetails_shop_countries +} from "@saleor/orders/types/OrderDetails"; +import React from "react"; + +import OrderCustomerAddressesEditDialog, { + OrderCustomerAddressesEditDialogProps +} from "../OrderCustomerAddressesEditDialog"; +import { + AddressEditDialogVariant, + OrderCustomerAddressesEditDialogOutput +} from "../OrderCustomerAddressesEditDialog/types"; + +interface OrderAddressFieldsProps { + action: string; + isDraft: boolean; + customerAddressesLoading: boolean; + customer: CustomerAddresses_user; + countries: OrderDetails_shop_countries[]; + onClose: () => void; + onConfirm: (data: OrderCustomerAddressesEditDialogOutput) => SubmitPromise; + confirmButtonState: ConfirmButtonTransitionState; + errors: OrderErrorFragment[]; + orderShippingAddress: OrderDetails_order_shippingAddress; + orderBillingAddress: OrderDetails_order_billingAddress; +} + +const OrderAddressFields: React.FC = ({ + action, + isDraft, + customerAddressesLoading, + customer, + countries, + onClose, + onConfirm, + confirmButtonState, + errors, + orderShippingAddress, + orderBillingAddress +}) => { + const addressFieldCommonProps: Omit< + OrderCustomerAddressesEditDialogProps, + "open" | "variant" + > = { + loading: customerAddressesLoading, + confirmButtonState, + countries, + errors, + orderShippingAddress: transformAddressToForm(orderShippingAddress), + orderBillingAddress: transformAddressToForm(orderBillingAddress), + customerAddresses: customer?.addresses, + defaultShippingAddress: customer?.defaultShippingAddress, + defaultBillingAddress: customer?.defaultBillingAddress, + onClose, + onConfirm + }; + + return ( + <> + {isDraft && ( + + )} + + + + + ); +}; + +export default OrderAddressFields; diff --git a/src/orders/components/OrderAddressFields/index.ts b/src/orders/components/OrderAddressFields/index.ts new file mode 100644 index 000000000..da20b629e --- /dev/null +++ b/src/orders/components/OrderAddressFields/index.ts @@ -0,0 +1,2 @@ +export { default } from "./OrderAddressFields"; +export * from "./OrderAddressFields"; diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressEdit.tsx b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressEdit.tsx index dd4fd98d6..2c0d21e36 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressEdit.tsx +++ b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressEdit.tsx @@ -32,6 +32,7 @@ export interface OrderCustomerAddressEditProps { onChangeFormAddress: (event: React.ChangeEvent) => void; onChangeFormAddressCountry: (event: React.ChangeEvent) => void; onEdit?: () => void; + showCard?: boolean; } const OrderCustomerAddressEdit: React.FC = props => { @@ -48,7 +49,8 @@ const OrderCustomerAddressEdit: React.FC = props formErrors, onChangeFormAddress, onChangeFormAddressCountry, - onEdit + onEdit, + showCard = true } = props; const classes = useStyles(props); @@ -90,17 +92,20 @@ const OrderCustomerAddressEdit: React.FC = props label={intl.formatMessage(addressEditMessages.customerAddress)} className={classes.optionLabel} /> - {addressInputOption === AddressInputOptionEnum.CUSTOMER_ADDRESS && ( - <> - - - - - )} + {addressInputOption === AddressInputOptionEnum.CUSTOMER_ADDRESS && + showCard && ( + <> + + + + + )} = props className={classes.optionLabel} /> {addressInputOption === AddressInputOptionEnum.NEW_ADDRESS && ( - <> - - - + )} ); diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesEditDialog.stories.tsx b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesEditDialog.stories.tsx index 3a69544b2..2fdfb20cb 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesEditDialog.stories.tsx +++ b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesEditDialog.stories.tsx @@ -5,25 +5,47 @@ import React from "react"; import { countries, order as orderFixture } from "../../fixtures"; import OrderCustomerAddressesEditDialog, { OrderCustomerAddressesEditDialogProps -} from "./OrderCustomerAddressesEditDialog"; +} from "."; +import { AddressEditDialogVariant } from "./types"; const order = orderFixture(""); const props: OrderCustomerAddressesEditDialogProps = { confirmButtonState: "default", + variant: AddressEditDialogVariant.CHANGE_CUSTOMER, loading: false, onClose: () => undefined, onConfirm: () => undefined, open: true, - errors: undefined + errors: undefined, + countries }; -storiesOf("Orders / OrderCustomerAddressesEditDialog", module) +storiesOf("Orders / Changing address in order", module) .addDecorator(Decorator) - .add("default", () => ( + .add("address change when customer is changed", () => ( + )) + .add("shipping address change", () => ( + + )) + .add("billing address change", () => ( + )) .add("no customer addresses", () => ( - + )) .add("loading", () => ( ; + onConfirm( + data: Partial + ): SubmitPromise; } const defaultSearchState: OrderCustomerSearchAddressState = { @@ -69,6 +72,7 @@ const defaultSearchState: OrderCustomerSearchAddressState = { const OrderCustomerAddressesEditDialog: React.FC = props => { const { open, + variant, loading, confirmButtonState, errors = [], @@ -77,11 +81,17 @@ const OrderCustomerAddressesEditDialog: React.FC address, AddressTypeEnum.BILLING); + const dialogErrors = useModalDialogErrors( [...errors, ...shippingValidationErrors, ...billingValidationErrors], open ); + const continueToSearchAddressesState = ( + data: OrderCustomerAddressesEditFormData + ): boolean => { + if (hasCustomerChanged || addressSearchState.open) { + return false; + } + if (!customerAddresses.length) { + return false; + } + if (variant === AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS) { + return ( + data.shippingAddressInputOption === + AddressInputOptionEnum.CUSTOMER_ADDRESS + ); + } + return ( + data.billingAddressInputOption === AddressInputOptionEnum.CUSTOMER_ADDRESS + ); + }; + const getCustomerAddress = ( selectedCustomerAddressID: string ): AddressInput => @@ -110,30 +141,75 @@ const OrderCustomerAddressesEditDialog: React.FC 0 && data.billingAddressInputOption === AddressInputOptionEnum.CUSTOMER_ADDRESS ? getCustomerAddress(data.customerBillingAddress.id) : handleBillingSubmit(data.billingAddress); + if (variant === AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS) { + return { + shippingAddress, + ...(data.cloneAddress && { billingAddress: shippingAddress }) + }; + } + if (variant === AddressEditDialogVariant.CHANGE_BILLING_ADDRESS) { + return { + ...(data.cloneAddress && { shippingAddress: billingAddress }), + billingAddress + }; + } return { shippingAddress, - billingAddress + billingAddress: data.cloneAddress ? shippingAddress : billingAddress }; }; - const handleSubmit = (data: OrderCustomerAddressesEditFormData) => { - const adressesInput = handleAddressesSubmit(data); + const getDialogTitle = (): MessageDescriptor => { + if (addressSearchState.open) { + if (variant === AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS) { + return dialogMessages.shippingTitle; + } + if (variant === AddressEditDialogVariant.CHANGE_BILLING_ADDRESS) { + return dialogMessages.billingTitle; + } + } + if (variant === AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS) { + return dialogMessages.shippingChangeTitle; + } + if (variant === AddressEditDialogVariant.CHANGE_BILLING_ADDRESS) { + return dialogMessages.billingChangeTitle; + } + return dialogMessages.customerChangeTitle; + }; + const getDialogDescription = (): MessageDescriptor => { + if (customerAddresses.length === 0) { + return dialogMessages.noAddressDescription; + } + if (variant === AddressEditDialogVariant.CHANGE_CUSTOMER) { + return dialogMessages.customerChangeDescription; + } + return dialogMessages.addressChangeDescription; + }; - if (adressesInput.shippingAddress && adressesInput.billingAddress) { - onConfirm(adressesInput as OrderCustomerAddressesEditDialogOutput); + const handleContinue = (data: OrderCustomerAddressesEditFormData) => { + if (continueToSearchAddressesState(data)) { + setAddressSearchState({ + open: true, + type: + variant === AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS + ? AddressTypeEnum.SHIPPING + : AddressTypeEnum.BILLING + }); + return; + } + handleSubmit(data); + }; + const handleSubmit = async (data: OrderCustomerAddressesEditFormData) => { + const addressesInput = handleAddressesSubmit(data); + if (addressesInput) { + await onConfirm(addressesInput as OrderCustomerAddressesEditDialogOutput); + setAddressSearchState(defaultSearchState); } return Promise.resolve([ @@ -157,175 +233,230 @@ const OrderCustomerAddressesEditDialog: React.FC { + onClose(); + setAddressSearchState(defaultSearchState); + }; + return ( - { - setAddressSearchState(defaultSearchState); - onClose(); - }} - open={open} - fullWidth - > + + + + - {({ change, data, handlers }) => ( - <> - {addressSearchState.open ? ( - - handlers.changeCustomerAddress( - customerAddress, - "customerShippingAddress" - ) - } - onChangeCustomerBillingAddress={customerAddress => - handlers.changeCustomerAddress( - customerAddress, - "customerBillingAddress" - ) - } - exitSearch={() => setAddressSearchState(defaultSearchState)} - /> - ) : ( - <> - - - - - - {customerAddresses.length > 0 ? ( - - ) : ( - - )} - - - error.addressType === AddressTypeEnum.SHIPPING - )} - onChangeFormAddress={event => - handlers.changeFormAddress(event, "shippingAddress") - } - onChangeFormAddressCountry={handlers.selectShippingCountry} - onEdit={() => - setAddressSearchState({ - open: true, - type: AddressTypeEnum.SHIPPING - }) - } - /> - - - - - change({ - target: { - name: "billingSameAsShipping", - value: !data.billingSameAsShipping - } - }) - } - data-test="billingSameAsShipping" - /> - } - label={intl.formatMessage( - dialogMessages.billingSameAsShipping - )} - /> - {!data.billingSameAsShipping && ( - <> - - - {customerAddresses.length > 0 ? ( - - ) : ( - + {({ change, data, handlers }) => { + const shippingAddressEditProps = getAddressEditProps( + "shipping", + data, + handlers, + change, + dialogErrors, + setAddressSearchState, + addressEditCommonProps + ); + const billingAddressEditProps = getAddressEditProps( + "billing", + data, + handlers, + change, + dialogErrors, + setAddressSearchState, + addressEditCommonProps + ); + return ( + <> + {addressSearchState.open ? ( + + handlers.changeCustomerAddress( + customerAddress, + "customerShippingAddress" + ) + } + onChangeCustomerBillingAddress={customerAddress => + handlers.changeCustomerAddress( + customerAddress, + "customerBillingAddress" + ) + } + exitSearch={() => setAddressSearchState(defaultSearchState)} + /> + ) : ( + <> + + + + + + {hasCustomerChanged && ( + <> + + + + + + change({ + target: { + name: "cloneAddress", + value: !data.cloneAddress + } + }) + } + data-test="billingSameAsShipping" + /> + } + label={intl.formatMessage( + dialogMessages.billingSameAsShipping + )} + /> + {!data.cloneAddress && ( + <> + + + {customerAddresses.length > 0 ? ( + + ) : ( + + )} + + + + )} - - - error.addressType === AddressTypeEnum.BILLING + + )} + {variant === + AddressEditDialogVariant.CHANGE_SHIPPING_ADDRESS && ( + <> + + {data.shippingAddressInputOption === + AddressInputOptionEnum.NEW_ADDRESS && ( + <> + + + + change({ + target: { + name: "cloneAddress", + value: !data.cloneAddress + } + }) + } + data-test="billingSameAsShipping" + /> + } + label={intl.formatMessage( + dialogMessages.billingSameAsShipping + )} + /> + )} - onChangeFormAddress={event => - handlers.changeFormAddress(event, "billingAddress") - } - onChangeFormAddressCountry={ - handlers.selectBillingCountry - } - onEdit={() => - setAddressSearchState({ - open: true, - type: AddressTypeEnum.BILLING - }) - } + + )} + {variant === + AddressEditDialogVariant.CHANGE_BILLING_ADDRESS && ( + <> + + {data.shippingAddressInputOption === + AddressInputOptionEnum.NEW_ADDRESS && ( + <> + + + + change({ + target: { + name: "cloneAddress", + value: !data.cloneAddress + } + }) + } + data-test="billingSameAsShipping" + /> + } + label={intl.formatMessage( + dialogMessages.shippingSameAsBilling + )} + /> + + )} + + )} + + + + - - )} - - - - - - - - )} - - )} + + + + )} + + ); + }} ); diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesSearch.tsx b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesSearch.tsx index c206796f5..16036f166 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesSearch.tsx +++ b/src/orders/components/OrderCustomerAddressesEditDialog/OrderCustomerAddressesSearch.tsx @@ -1,29 +1,38 @@ import { - Button, + Checkbox, DialogActions, DialogContent, - DialogTitle, + FormControlLabel, InputAdornment, TextField } from "@material-ui/core"; -import CardSpacer from "@saleor/components/CardSpacer"; +import VerticalSpacer from "@saleor/apps/components/VerticalSpacer"; import { ConfirmButton } from "@saleor/components/ConfirmButton"; import CustomerAddressChoiceCard from "@saleor/customers/components/CustomerAddressChoiceCard"; import { CustomerAddresses_user_addresses } from "@saleor/customers/types/CustomerAddresses"; +import { FormChange } from "@saleor/hooks/useForm"; import { buttonMessages } from "@saleor/intl"; -import { SearchIcon } from "@saleor/macaw-ui"; +import { + Button, + ConfirmButtonTransitionState, + SearchIcon +} from "@saleor/macaw-ui"; import { AddressTypeEnum } from "@saleor/types/globalTypes"; import React from "react"; import { FormattedMessage, useIntl } from "react-intl"; import { getById } from "../OrderReturnPage/utils"; -import { addressSearchMessages as messages } from "./messages"; +import { dialogMessages as messages } from "./messages"; import { useStyles } from "./styles"; import { parseQuery, stringifyAddress } from "./utils"; export interface OrderCustomerAddressesSearchProps { type: AddressTypeEnum; - selectedCustomerAddressId?: string; + cloneAddress: boolean; + formChange: FormChange; + openFromCustomerChange: boolean; + transitionState: ConfirmButtonTransitionState; + selectedCustomerAddressId: string; customerAddresses: CustomerAddresses_user_addresses[]; onChangeCustomerShippingAddress: ( customerAddress: CustomerAddresses_user_addresses @@ -37,6 +46,10 @@ export interface OrderCustomerAddressesSearchProps { const OrderCustomerAddressesSearch: React.FC = props => { const { type, + cloneAddress, + formChange, + transitionState, + openFromCustomerChange, selectedCustomerAddressId, customerAddresses, onChangeCustomerShippingAddress, @@ -63,7 +76,9 @@ const OrderCustomerAddressesSearch: React.FC } else { onChangeCustomerBillingAddress(temporarySelectedAddress); } - exitSearch(); + if (openFromCustomerChange) { + exitSearch(); + } }; const handleChange = (e: React.ChangeEvent) => { @@ -78,16 +93,9 @@ const OrderCustomerAddressesSearch: React.FC return ( <> - - {type === AddressTypeEnum.SHIPPING ? ( - - ) : ( - - )} - {intl.formatMessage(messages.searchInfo)} - + }} inputProps={{ className: classes.searchInput }} /> - +
{filteredCustomerAddresses.length === 0 ? intl.formatMessage(messages.noResultsFound) @@ -114,18 +122,42 @@ const OrderCustomerAddressesSearch: React.FC onSelect={() => setTemporarySelectedAddress(address)} address={address} /> - + ))}
+ {!openFromCustomerChange && filteredCustomerAddresses.length !== 0 && ( + + formChange({ + target: { + name: "cloneAddress", + value: !cloneAddress + } + }) + } + /> + } + label={intl.formatMessage( + type === AddressTypeEnum.SHIPPING + ? messages.billingSameAsShipping + : messages.shippingSameAsBilling + )} + /> + )}
- diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/form.tsx b/src/orders/components/OrderCustomerAddressesEditDialog/form.tsx index b5081b168..c8c0c1ec3 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/form.tsx +++ b/src/orders/components/OrderCustomerAddressesEditDialog/form.tsx @@ -1,4 +1,5 @@ import { useExitFormDialog } from "@saleor/components/Form/useExitFormDialog"; +import { ShopInfo_shop_countries } from "@saleor/components/Shop/types/ShopInfo"; import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField"; import { AddressTypeInput } from "@saleor/customers/types"; import { @@ -21,7 +22,7 @@ export enum AddressInputOptionEnum { } export interface OrderCustomerAddressesEditFormData { - billingSameAsShipping: boolean; + cloneAddress: boolean; shippingAddressInputOption: AddressInputOptionEnum; billingAddressInputOption: AddressInputOptionEnum; customerShippingAddress: CustomerAddresses_user_defaultShippingAddress; @@ -59,42 +60,46 @@ interface UseOrderCustomerAddressesEditFormResult interface UseOrderCustomerAddressesEditFormOpts { countryChoices: SingleAutocompleteChoiceType[]; + countries: ShopInfo_shop_countries[]; defaultShippingAddress: CustomerAddresses_user_defaultShippingAddress; defaultBillingAddress: CustomerAddresses_user_defaultBillingAddress; + defaultCloneAddress: boolean; } export interface OrderCustomerAddressesEditFormProps extends UseOrderCustomerAddressesEditFormOpts { children: (props: UseOrderCustomerAddressesEditFormResult) => React.ReactNode; initial?: Partial; - onSubmit: (data: OrderCustomerAddressesEditData) => SubmitPromise; + onSubmit: (data: OrderCustomerAddressesEditData) => void; } -const initialAddress: AddressTypeInput = { - city: "", - country: "", - phone: "", - postalCode: "", - streetAddress1: "" -}; - -const getDefaultInitialFormData = ( - opts: UseOrderCustomerAddressesEditFormOpts -): OrderCustomerAddressesEditFormData => ({ - billingSameAsShipping: true, - shippingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, - billingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, - customerShippingAddress: opts.defaultShippingAddress, - customerBillingAddress: opts.defaultBillingAddress, - shippingAddress: initialAddress, - billingAddress: initialAddress -}); - function useOrderCustomerAddressesEditForm( - initial: Partial, - onSubmit: (data: OrderCustomerAddressesEditData) => SubmitPromise, + providedInitialFormData: Partial, + onSubmit: (data: OrderCustomerAddressesEditData) => void, opts: UseOrderCustomerAddressesEditFormOpts ): UseOrderCustomerAddressesEditFormResult { + const emptyAddress: AddressTypeInput = { + city: "", + country: "", + phone: "", + postalCode: "", + streetAddress1: "" + }; + const defaultInitialFormData: OrderCustomerAddressesEditFormData = { + cloneAddress: opts.defaultCloneAddress, + shippingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, + billingAddressInputOption: AddressInputOptionEnum.CUSTOMER_ADDRESS, + customerShippingAddress: opts.defaultShippingAddress, + customerBillingAddress: opts.defaultBillingAddress, + shippingAddress: emptyAddress, + billingAddress: emptyAddress + }; + + const initialData = { + ...defaultInitialFormData, + ...providedInitialFormData + }; + const { handleChange, hasChanged, @@ -102,17 +107,20 @@ function useOrderCustomerAddressesEditForm( data: formData, setChanged } = useForm({ - ...initial, - ...getDefaultInitialFormData(opts) + ...initialData }); const { setExitDialogSubmitRef } = useExitFormDialog(); const [shippingCountryDisplayName, setShippingCountryDisplayName] = useState( - "" + opts.countries.find( + country => initialData.shippingAddress.country === country.code + )?.country ); const [billingCountryDisplayName, setBillingCountryDisplayName] = useState( - "" + opts.countries.find( + country => initialData.billingAddress.country === country.code + )?.country ); const handleFormAddressChange = ( diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/messages.ts b/src/orders/components/OrderCustomerAddressesEditDialog/messages.ts index c1f974b50..862704653 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/messages.ts +++ b/src/orders/components/OrderCustomerAddressesEditDialog/messages.ts @@ -1,46 +1,48 @@ import { defineMessages } from "react-intl"; export const dialogMessages = defineMessages({ - title: { + customerChangeTitle: { defaultMessage: "Change address for order", description: "dialog header" }, + shippingChangeTitle: { + defaultMessage: "Change customer shipping address", + description: "dialog header" + }, + billingChangeTitle: { + defaultMessage: "Change customer billing address", + description: "dialog header" + }, billingSameAsShipping: { defaultMessage: "Set the same for billing address", description: "checkbox label" }, - shippingAddressDescription: { + shippingSameAsBilling: { + defaultMessage: "Set the same for shipping address", + description: "checkbox label" + }, + addressChangeDescription: { + defaultMessage: "Select method you want to use to change address", + description: "dialog content" + }, + noAddressDescription: { defaultMessage: - "This customer doesn’t have any shipping addresses. Provide address for order:", + "This customer doesn't have any addresses in the address book. Provide address for order:", description: "dialog content" }, - billingAddressDescription: { - defaultMessage: "Add a new address:", - description: "dialog content" - }, - customerShippingAddressDescription: { + customerChangeDescription: { defaultMessage: "Which address would you like to use as shipping address for selected customer:", description: "dialog content" }, - customerBillingAddressDescription: { + customerChangeBillingDescription: { defaultMessage: "Select one of customer addresses or add a new address:", description: "dialog content" - } -}); - -export const addressEditMessages = defineMessages({ - customerAddress: { - defaultMessage: "Use one of customer addresses", - description: "address type" }, - newAddress: { - defaultMessage: "Add new address", - description: "address type" - } -}); - -export const addressSearchMessages = defineMessages({ + noAddressBillingDescription: { + defaultMessage: "Add a new address:", + description: "dialog content" + }, shippingTitle: { defaultMessage: "Shipping address", description: "search modal shipping title" @@ -54,6 +56,18 @@ export const addressSearchMessages = defineMessages({ description: "modal information under title" }, noResultsFound: { - defaultMessage: "No results found" + defaultMessage: "No results found", + description: "info when addresses search is unsuccessful" + } +}); + +export const addressEditMessages = defineMessages({ + customerAddress: { + defaultMessage: "Use one of customer addresses", + description: "address type" + }, + newAddress: { + defaultMessage: "Add new address", + description: "address type" } }); diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/styles.ts b/src/orders/components/OrderCustomerAddressesEditDialog/styles.ts index ed42b3149..18efa7786 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/styles.ts +++ b/src/orders/components/OrderCustomerAddressesEditDialog/styles.ts @@ -2,10 +2,12 @@ import { makeStyles } from "@saleor/macaw-ui"; export const useStyles = makeStyles( theme => ({ - scrollableContent: { + dialogContent: { maxHeight: `calc(100vh - 250px)`, overflowY: "scroll", - overflowX: "hidden" + overflowX: "hidden", + padding: "24px", + margin: 0 }, scrollableWrapper: { maxHeight: 400, @@ -17,9 +19,6 @@ export const useStyles = makeStyles( optionLabel: { display: "block" }, - overflow: { - overflowY: "visible" - }, searchInput: { paddingTop: theme.spacing(2), paddingBottom: theme.spacing(2) diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/types.ts b/src/orders/components/OrderCustomerAddressesEditDialog/types.ts new file mode 100644 index 000000000..038bbdc5b --- /dev/null +++ b/src/orders/components/OrderCustomerAddressesEditDialog/types.ts @@ -0,0 +1,15 @@ +import { AddressInput, AddressTypeEnum } from "@saleor/types/globalTypes"; + +export interface OrderCustomerSearchAddressState { + open: boolean; + type: AddressTypeEnum; +} +export interface OrderCustomerAddressesEditDialogOutput { + shippingAddress: AddressInput; + billingAddress: AddressInput; +} +export enum AddressEditDialogVariant { + CHANGE_CUSTOMER, + CHANGE_SHIPPING_ADDRESS, + CHANGE_BILLING_ADDRESS +} diff --git a/src/orders/components/OrderCustomerAddressesEditDialog/utils.ts b/src/orders/components/OrderCustomerAddressesEditDialog/utils.ts index 1b8dd0de3..5417ce8f3 100644 --- a/src/orders/components/OrderCustomerAddressesEditDialog/utils.ts +++ b/src/orders/components/OrderCustomerAddressesEditDialog/utils.ts @@ -1,10 +1,28 @@ +import { SingleAutocompleteChoiceType } from "@saleor/components/SingleAutocompleteSelectField"; import { CustomerAddresses_user_addresses, CustomerAddresses_user_defaultShippingAddress } from "@saleor/customers/types/CustomerAddresses"; +import { AccountErrorFragment } from "@saleor/fragments/types/AccountErrorFragment"; +import { OrderErrorFragment } from "@saleor/fragments/types/OrderErrorFragment"; +import { FormChange } from "@saleor/hooks/useForm"; import { flatten } from "@saleor/misc"; +import { AddressTypeEnum } from "@saleor/types/globalTypes"; import { getById } from "../OrderReturnPage/utils"; +import { + OrderCustomerAddressesEditData, + OrderCustomerAddressesEditHandlers +} from "./form"; +import { OrderCustomerAddressEditProps } from "./OrderCustomerAddressEdit"; +import { OrderCustomerSearchAddressState } from "./types"; + +interface AddressEditCommonProps { + showCard: boolean; + loading: boolean; + countryChoices: SingleAutocompleteChoiceType[]; + customerAddresses: CustomerAddresses_user_addresses[]; +} export const stringifyAddress = ( address: Partial @@ -33,3 +51,58 @@ export function validateDefaultAddress< } return defaultAddress; } + +export const getAddressEditProps = ( + variant: "shipping" | "billing", + data: OrderCustomerAddressesEditData, + handlers: OrderCustomerAddressesEditHandlers, + change: FormChange, + dialogErrors: Array, + setAddressSearchState: React.Dispatch< + React.SetStateAction + >, + addressEditCommonProps: AddressEditCommonProps +): OrderCustomerAddressEditProps => { + if (variant === "shipping") { + return { + ...addressEditCommonProps, + addressInputName: "shippingAddressInputOption", + formErrors: dialogErrors.filter( + error => error.addressType === AddressTypeEnum.SHIPPING + ), + onEdit: () => + setAddressSearchState({ + open: true, + type: AddressTypeEnum.SHIPPING + }), + onChangeAddressInputOption: change, + addressInputOption: data.shippingAddressInputOption, + selectedCustomerAddressId: data.customerShippingAddress?.id, + formAddress: data.shippingAddress, + formAddressCountryDisplayName: data.shippingCountryDisplayName, + onChangeFormAddress: event => + handlers.changeFormAddress(event, "shippingAddress"), + onChangeFormAddressCountry: handlers.selectShippingCountry + }; + } + return { + ...addressEditCommonProps, + addressInputName: "billingAddressInputOption", + formErrors: dialogErrors.filter( + error => error.addressType === AddressTypeEnum.BILLING + ), + onEdit: () => + setAddressSearchState({ + open: true, + type: AddressTypeEnum.BILLING + }), + onChangeAddressInputOption: change, + addressInputOption: data.billingAddressInputOption, + selectedCustomerAddressId: data.customerBillingAddress?.id, + formAddress: data.billingAddress, + formAddressCountryDisplayName: data.billingCountryDisplayName, + onChangeFormAddress: event => + handlers.changeFormAddress(event, "billingAddress"), + onChangeFormAddressCountry: handlers.selectBillingCountry + }; +}; diff --git a/src/orders/components/OrderDraftPage/OrderDraftPage.tsx b/src/orders/components/OrderDraftPage/OrderDraftPage.tsx index eb7cd4848..80c202eaa 100644 --- a/src/orders/components/OrderDraftPage/OrderDraftPage.tsx +++ b/src/orders/components/OrderDraftPage/OrderDraftPage.tsx @@ -140,7 +140,7 @@ const OrderDraftPage: React.FC = props => {
void; - orderUpdate: PartialMutationProviderOutput; - orderDraftUpdate: PartialMutationProviderOutput< - OrderDraftUpdate, - OrderDraftUpdateVariables - >; -} - -const OrderAddressFields = ({ - action, - isDraft, - id, - onClose, - orderUpdate, - orderDraftUpdate, - data -}: Props) => { - const order = data?.order; - - const handleConfirm = (type: FieldType) => (value: AddressInput) => { - const updateMutation = isDraft ? orderDraftUpdate : orderUpdate; - - updateMutation.mutate({ - id, - input: { - [type]: value - } - }); - }; - - const addressFieldCommonProps = { - confirmButtonState: isDraft - ? orderDraftUpdate.opts.status - : orderUpdate.opts.status, - countries: data?.shop?.countries, - errors: isDraft - ? orderDraftUpdate.opts.data?.draftOrderUpdate.errors - : orderUpdate.opts.data?.orderUpdate.errors, - onClose - }; - - return ( - <> - - - - ); -}; - -export default OrderAddressFields; diff --git a/src/orders/views/OrderDetails/OrderDetails.tsx b/src/orders/views/OrderDetails/OrderDetails.tsx index 340a0723f..9bdc16a43 100644 --- a/src/orders/views/OrderDetails/OrderDetails.tsx +++ b/src/orders/views/OrderDetails/OrderDetails.tsx @@ -26,7 +26,6 @@ import { OrderUrlDialog, OrderUrlQueryParams } from "../../urls"; -import OrderAddressFields from "./OrderAddressFields"; import { OrderDetailsMessages } from "./OrderDetailsMessages"; import { OrderDraftDetails } from "./OrderDraftDetails"; import { OrderNormalDetails } from "./OrderNormalDetails"; @@ -180,6 +179,7 @@ export const OrderDetails: React.FC = ({ id, params }) => { orderAddNote={orderAddNote} orderInvoiceRequest={orderInvoiceRequest} handleSubmit={handleSubmit} + orderUpdate={orderUpdate} orderCancel={orderCancel} orderPaymentMarkAsPaid={orderPaymentMarkAsPaid} orderVoid={orderVoid} @@ -224,6 +224,7 @@ export const OrderDetails: React.FC = ({ id, params }) => { orderLineDelete={orderLineDelete} orderInvoiceRequest={orderInvoiceRequest} handleSubmit={handleSubmit} + orderUpdate={orderUpdate} orderCancel={orderCancel} orderShippingMethodUpdate={orderShippingMethodUpdate} orderLinesAdd={orderLinesAdd} @@ -242,15 +243,6 @@ export const OrderDetails: React.FC = ({ id, params }) => { closeModal={closeModal} /> )} - )} diff --git a/src/orders/views/OrderDetails/OrderDraftDetails/index.tsx b/src/orders/views/OrderDetails/OrderDraftDetails/index.tsx index b4e4f737c..585fb5f28 100644 --- a/src/orders/views/OrderDetails/OrderDraftDetails/index.tsx +++ b/src/orders/views/OrderDetails/OrderDraftDetails/index.tsx @@ -4,19 +4,22 @@ import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; import { useCustomerAddressesQuery } from "@saleor/customers/queries"; import useNavigator from "@saleor/hooks/useNavigator"; import { CustomerEditData } from "@saleor/orders/components/OrderCustomer"; -import OrderCustomerAddressesEditDialog, { - OrderCustomerAddressesEditDialogOutput -} from "@saleor/orders/components/OrderCustomerAddressesEditDialog"; +import { OrderCustomerAddressesEditDialogOutput } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/types"; import { CustomerChangeActionEnum, OrderCustomerChangeData } from "@saleor/orders/components/OrderCustomerChangeDialog/form"; import OrderCustomerChangeDialog from "@saleor/orders/components/OrderCustomerChangeDialog/OrderCustomerChangeDialog"; import { OrderDetails } from "@saleor/orders/types/OrderDetails"; +import { + OrderDraftUpdate, + OrderDraftUpdateVariables +} from "@saleor/orders/types/OrderDraftUpdate"; import { getVariantSearchAddress } from "@saleor/orders/utils/data"; import { OrderDiscountProvider } from "@saleor/products/components/OrderDiscountProviders/OrderDiscountProvider"; import { OrderLineDiscountProvider } from "@saleor/products/components/OrderDiscountProviders/OrderLineDiscountProvider"; import useCustomerSearch from "@saleor/searches/useCustomerSearch"; +import { PartialMutationProviderOutput } from "@saleor/types"; import { mapEdgesToItems } from "@saleor/utils/maps"; import React from "react"; import { useIntl } from "react-intl"; @@ -27,6 +30,7 @@ import { getStringOrPlaceholder } from "../../../../misc"; import { productUrl } from "../../../../products/urls"; +import OrderAddressFields from "../../../components/OrderAddressFields/OrderAddressFields"; import OrderDraftCancelDialog from "../../../components/OrderDraftCancelDialog/OrderDraftCancelDialog"; import OrderDraftPage from "../../../components/OrderDraftPage"; import OrderProductAddDialog from "../../../components/OrderProductAddDialog"; @@ -45,13 +49,23 @@ interface OrderDraftDetailsProps { orderLineDelete: any; orderShippingMethodUpdate: any; orderLinesAdd: any; - orderDraftUpdate: any; + orderDraftUpdate: PartialMutationProviderOutput< + OrderDraftUpdate, + OrderDraftUpdateVariables + >; orderDraftCancel: any; orderDraftFinalize: any; openModal: (action: OrderUrlDialog, newParams?: OrderUrlQueryParams) => void; closeModal: any; } +export const isAnyAddressEditModalOpen = (uri: string | undefined): boolean => + [ + "edit-customer-addresses", + "edit-shipping-address", + "edit-billing-address" + ].includes(uri); + export const OrderDraftDetails: React.FC = ({ id, params, @@ -99,7 +113,7 @@ export const OrderDraftDetails: React.FC = ({ variables: { id: order?.user?.id }, - skip: params.action !== "edit-customer-addresses" + skip: !order?.user?.id || !isAnyAddressEditModalOpen(params.action) }); const intl = useIntl(); @@ -140,21 +154,13 @@ export const OrderDraftDetails: React.FC = ({ } }; - const handleCustomerChangeAdresses = async ( - data: OrderCustomerAddressesEditDialogOutput - ) => { - const result = await orderDraftUpdate.mutate({ + const handleCustomerChangeAddresses = async ( + data: Partial + ): Promise => + orderDraftUpdate.mutate({ id, - input: { - shippingAddress: data.shippingAddress, - billingAddress: data.billingAddress - } + input: data }); - if (!result?.data?.draftOrderUpdate?.errors?.length) { - closeModal(); - } - return result; - }; return ( <> @@ -266,17 +272,18 @@ export const OrderDraftDetails: React.FC = ({ onClose={closeModal} onConfirm={handleCustomerChangeAction} /> - ); diff --git a/src/orders/views/OrderDetails/OrderNormalDetails/index.tsx b/src/orders/views/OrderDetails/OrderNormalDetails/index.tsx index ccff72af7..f27b1e420 100644 --- a/src/orders/views/OrderDetails/OrderNormalDetails/index.tsx +++ b/src/orders/views/OrderDetails/OrderNormalDetails/index.tsx @@ -1,13 +1,19 @@ import { useUser } from "@saleor/auth"; import { WindowTitle } from "@saleor/components/WindowTitle"; +import { useCustomerAddressesQuery } from "@saleor/customers/queries"; import useNavigator from "@saleor/hooks/useNavigator"; import OrderCannotCancelOrderDialog from "@saleor/orders/components/OrderCannotCancelOrderDialog"; +import { OrderCustomerAddressesEditDialogOutput } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/types"; import OrderFulfillmentApproveDialog from "@saleor/orders/components/OrderFulfillmentApproveDialog"; import OrderInvoiceEmailSendDialog from "@saleor/orders/components/OrderInvoiceEmailSendDialog"; import { OrderFulfillmentApprove, OrderFulfillmentApproveVariables } from "@saleor/orders/types/OrderFulfillmentApprove"; +import { + OrderUpdate, + OrderUpdateVariables +} from "@saleor/orders/types/OrderUpdate"; import { PartialMutationProviderOutput } from "@saleor/types"; import { mapEdgesToItems } from "@saleor/utils/maps"; import { useWarehouseList } from "@saleor/warehouses/queries"; @@ -22,6 +28,7 @@ import { } from "../../../../misc"; import { productUrl } from "../../../../products/urls"; import { FulfillmentStatus } from "../../../../types/globalTypes"; +import OrderAddressFields from "../../../components/OrderAddressFields/OrderAddressFields"; import OrderCancelDialog from "../../../components/OrderCancelDialog"; import OrderDetailsPage from "../../../components/OrderDetailsPage"; import OrderFulfillmentCancelDialog from "../../../components/OrderFulfillmentCancelDialog"; @@ -37,6 +44,7 @@ import { orderUrl, OrderUrlQueryParams } from "../../../urls"; +import { isAnyAddressEditModalOpen } from "../OrderDraftDetails"; interface OrderNormalDetailsProps { id: string; @@ -45,6 +53,7 @@ interface OrderNormalDetailsProps { orderAddNote: any; orderInvoiceRequest: any; handleSubmit: any; + orderUpdate: PartialMutationProviderOutput; orderCancel: any; orderPaymentMarkAsPaid: any; orderVoid: any; @@ -69,6 +78,7 @@ export const OrderNormalDetails: React.FC = ({ orderAddNote, orderInvoiceRequest, handleSubmit, + orderUpdate, orderCancel, orderPaymentMarkAsPaid, orderVoid, @@ -93,6 +103,24 @@ export const OrderNormalDetails: React.FC = ({ first: 30 } }); + + const { + data: customerAddresses, + loading: customerAddressesLoading + } = useCustomerAddressesQuery({ + variables: { + id: order?.user?.id + }, + skip: !order?.user?.id || !isAnyAddressEditModalOpen(params.action) + }); + const handleCustomerChangeAddresses = async ( + data: Partial + ): Promise => + orderUpdate.mutate({ + id, + input: data + }); + const intl = useIntl(); const [transactionReference, setTransactionReference] = React.useState(""); @@ -307,6 +335,19 @@ export const OrderNormalDetails: React.FC = ({ onClose={closeModal} onSend={() => orderInvoiceSend.mutate({ id: params.id })} /> + ); }; diff --git a/src/orders/views/OrderDetails/OrderUnconfirmedDetails/index.tsx b/src/orders/views/OrderDetails/OrderUnconfirmedDetails/index.tsx index 5e184ab1c..01169117f 100644 --- a/src/orders/views/OrderDetails/OrderUnconfirmedDetails/index.tsx +++ b/src/orders/views/OrderDetails/OrderUnconfirmedDetails/index.tsx @@ -1,14 +1,20 @@ import { useUser } from "@saleor/auth"; import { WindowTitle } from "@saleor/components/WindowTitle"; import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config"; +import { useCustomerAddressesQuery } from "@saleor/customers/queries"; import useNavigator from "@saleor/hooks/useNavigator"; import OrderCannotCancelOrderDialog from "@saleor/orders/components/OrderCannotCancelOrderDialog"; +import { OrderCustomerAddressesEditDialogOutput } from "@saleor/orders/components/OrderCustomerAddressesEditDialog/types"; import OrderFulfillmentApproveDialog from "@saleor/orders/components/OrderFulfillmentApproveDialog"; import OrderInvoiceEmailSendDialog from "@saleor/orders/components/OrderInvoiceEmailSendDialog"; import { OrderFulfillmentApprove, OrderFulfillmentApproveVariables } from "@saleor/orders/types/OrderFulfillmentApprove"; +import { + OrderUpdate, + OrderUpdateVariables +} from "@saleor/orders/types/OrderUpdate"; import { OrderDiscountProvider } from "@saleor/products/components/OrderDiscountProviders/OrderDiscountProvider"; import { OrderLineDiscountProvider } from "@saleor/products/components/OrderDiscountProviders/OrderLineDiscountProvider"; import { PartialMutationProviderOutput } from "@saleor/types"; @@ -25,6 +31,7 @@ import { } from "../../../../misc"; import { productUrl } from "../../../../products/urls"; import { FulfillmentStatus } from "../../../../types/globalTypes"; +import OrderAddressFields from "../../../components/OrderAddressFields/OrderAddressFields"; import OrderCancelDialog from "../../../components/OrderCancelDialog"; import OrderDetailsPage from "../../../components/OrderDetailsPage"; import OrderFulfillmentCancelDialog from "../../../components/OrderFulfillmentCancelDialog"; @@ -43,6 +50,7 @@ import { orderUrl, OrderUrlQueryParams } from "../../../urls"; +import { isAnyAddressEditModalOpen } from "../OrderDraftDetails"; interface OrderUnconfirmedDetailsProps { id: string; @@ -53,6 +61,7 @@ interface OrderUnconfirmedDetailsProps { orderLineDelete: any; orderInvoiceRequest: any; handleSubmit: any; + orderUpdate: PartialMutationProviderOutput; orderCancel: any; orderShippingMethodUpdate: any; orderLinesAdd: any; @@ -81,6 +90,7 @@ export const OrderUnconfirmedDetails: React.FC = ( orderLineDelete, orderInvoiceRequest, handleSubmit, + orderUpdate, orderCancel, orderShippingMethodUpdate, orderLinesAdd, @@ -114,6 +124,25 @@ export const OrderUnconfirmedDetails: React.FC = ( first: 30 } }); + + const { + data: customerAddresses, + loading: customerAddressesLoading + } = useCustomerAddressesQuery({ + variables: { + id: order?.user?.id + }, + skip: !order?.user?.id || !isAnyAddressEditModalOpen(params.action) + }); + + const handleCustomerChangeAddresses = async ( + data: Partial + ): Promise => + orderUpdate.mutate({ + id, + input: data + }); + const intl = useIntl(); const [transactionReference, setTransactionReference] = React.useState(""); @@ -382,6 +411,19 @@ export const OrderUnconfirmedDetails: React.FC = ( onClose={closeModal} onSend={() => orderInvoiceSend.mutate({ id: params.id })} /> + ); }; diff --git a/src/storybook/__snapshots__/Stories.test.ts.snap b/src/storybook/__snapshots__/Stories.test.ts.snap index 1abeadb7c..2da243cdf 100644 --- a/src/storybook/__snapshots__/Stories.test.ts.snap +++ b/src/storybook/__snapshots__/Stories.test.ts.snap @@ -16867,6 +16867,36 @@ exports[`Storyshots Navigation / Menu item errors 1`] = ` /> `; +exports[`Storyshots Orders / Changing address in order address change when customer is changed 1`] = ` +
+`; + +exports[`Storyshots Orders / Changing address in order billing address change 1`] = ` +
+`; + +exports[`Storyshots Orders / Changing address in order loading 1`] = ` +
+`; + +exports[`Storyshots Orders / Changing address in order no customer addresses 1`] = ` +
+`; + +exports[`Storyshots Orders / Changing address in order shipping address change 1`] = ` +
+`; + exports[`Storyshots Orders / Draft order channel section default 1`] = `
`; -exports[`Storyshots Orders / OrderAddressEditDialog billing address 1`] = ` -
-`; - -exports[`Storyshots Orders / OrderAddressEditDialog shipping address 1`] = ` -
-`; - exports[`Storyshots Orders / OrderBulkCancelDialog default 1`] = `
`; -exports[`Storyshots Orders / OrderCustomerAddressesEditDialog default 1`] = ` -
-`; - -exports[`Storyshots Orders / OrderCustomerAddressesEditDialog loading 1`] = ` -
-`; - -exports[`Storyshots Orders / OrderCustomerAddressesEditDialog no customer addresses 1`] = ` -
-`; - exports[`Storyshots Orders / OrderCustomerChangeDialog default 1`] = `
Shipping Address
-
- -
Billing Address
-
- -
Shipping Address
-
- -
Billing Address
-
- -
Shipping Address
-
- -
Billing Address
-
- -
Shipping Address
-
- -
Billing Address
-
- -
( - undefined} - onConfirm={() => undefined} - open={true} - variant="shipping" - /> - )) - .add("billing address", () => ( - undefined} - onConfirm={() => undefined} - open={true} - variant="billing" - /> - )); diff --git a/src/types.ts b/src/types.ts index 7bc3f91f4..2ad0f4330 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ import { ConfirmButtonTransitionState } from "@saleor/macaw-ui"; -import { MutationResult } from "react-apollo"; +import { MutationFetchResult, MutationResult } from "react-apollo"; import { IFilter, IFilterElement } from "./components/Filter"; import { MultiAutocompleteChoiceType } from "./components/MultiAutocompleteSelectField"; @@ -131,7 +131,7 @@ export interface PartialMutationProviderOutput< TVariables extends {} = {} > { opts: MutationResult & MutationResultAdditionalProps; - mutate: (variables: TVariables) => void; + mutate: (variables: TVariables) => Promise>; } export interface Node {