From bc097da7e10be76b8f723c428b8f0677d62cc810 Mon Sep 17 00:00:00 2001 From: Abban Dunne Date: Thu, 14 Sep 2023 17:08:54 +0200 Subject: [PATCH] Make address form submittable This fixes validation and field names to make sure the form submits to the application correctly. https://phabricator.wikimedia.org/T345528 --- .../DonationReceipt/AddressFields.vue | 8 +-- .../DonationReceipt/NameFields.vue | 3 +- .../useAddressFormEventHandlers.ts | 71 +++++++++++++++++++ .../DonationReceipt/useAddressType.ts | 4 +- .../useAddressTypeFromReceiptSetter.ts | 28 ++++++++ .../subpages/AddressPageDonationReceipt.vue | 21 +++--- src/components/shared/Postal.vue | 22 +++--- .../form_fields/CityAutocompleteField.vue | 2 +- .../form_fields/CountryAutocompleteField.vue | 2 +- .../shared/form_fields/MailingListField.vue | 2 +- .../form_inputs/CheckboxSingleFormInput.vue | 1 + src/scss/components/form_field.scss | 5 +- src/store/address/constants.ts | 2 + src/view_models/AddressTypeModel.ts | 11 +-- 14 files changed, 149 insertions(+), 33 deletions(-) create mode 100644 src/components/pages/donation_form/DonationReceipt/useAddressFormEventHandlers.ts create mode 100644 src/components/pages/donation_form/DonationReceipt/useAddressTypeFromReceiptSetter.ts diff --git a/src/components/pages/donation_form/DonationReceipt/AddressFields.vue b/src/components/pages/donation_form/DonationReceipt/AddressFields.vue index 683059b4b..b911d348b 100644 --- a/src/components/pages/donation_form/DonationReceipt/AddressFields.vue +++ b/src/components/pages/donation_form/DonationReceipt/AddressFields.vue @@ -3,10 +3,10 @@
+ { + document.getElementsByClassName( 'help is-danger' )[ 0 ] + .scrollIntoView( { behavior: 'smooth', block: 'center', inline: 'nearest' } ); +}; + +type ReturnType = { + submit: ( e: Event ) => Promise, + previousPage: () => void, +} + +export function useAddressFormEventHandlers( + store: Store, + emit: ( eventName: string ) => void, + isDirectDebit: ComputedRef, + validateAddressUrl: string, + validateEmailUrl: string +): ReturnType { + const submit = async ( e: Event ) => { + e.preventDefault(); + + await store.dispatch( action( NS_ADDRESS, validateAddressType ), { + type: store.state.address.addressType, + disallowed: [ AddressTypeModel.UNSET ], + } ); + await store.dispatch( action( NS_ADDRESS, validateAddress ), validateAddressUrl ); + await store.dispatch( action( NS_ADDRESS, validateEmail ), validateEmailUrl ); + + if ( isDirectDebit.value ) { + await store.dispatch( action( NS_BANKDATA, markEmptyValuesAsInvalid ) ); + } + + // We need to wait for the asynchronous bank data validation, that might still be going on + await waitForServerValidationToFinish( store ); + + if ( !store.getters[ NS_ADDRESS + '/requiredFieldsAreValid' ] ) { + scrollToFirstError(); + return; + } + + if ( isDirectDebit.value && !store.getters[ NS_BANKDATA + '/bankDataIsValid' ] ) { + scrollToFirstError(); + return; + } + + const form = e.target as HTMLFormElement; + + trackFormSubmission( form ); + form.submit(); + }; + + const previousPage = async () => { + await store.dispatch( action( NS_PAYMENT, discardInitialization ) ); + emit( 'previous-page' ); + }; + + return { + submit, + previousPage, + }; +} diff --git a/src/components/pages/donation_form/DonationReceipt/useAddressType.ts b/src/components/pages/donation_form/DonationReceipt/useAddressType.ts index 040095345..05208e3a8 100644 --- a/src/components/pages/donation_form/DonationReceipt/useAddressType.ts +++ b/src/components/pages/donation_form/DonationReceipt/useAddressType.ts @@ -3,12 +3,12 @@ import { Store } from 'vuex'; import { addressTypeName as getAddressTypeName } from '@src/view_models/AddressTypeModel'; type ReturnType = { - addressType: ComputedRef, + addressType: ComputedRef, addressTypeName: ComputedRef, }; export function useAddressType( store: Store ): ReturnType { - const addressType = computed( () => store.getters[ 'address/addressType' ] ); + const addressType = computed( () => store.getters[ 'address/addressType' ] ); const addressTypeName = computed( (): string => getAddressTypeName( store.state.address.addressType ) ); return { diff --git a/src/components/pages/donation_form/DonationReceipt/useAddressTypeFromReceiptSetter.ts b/src/components/pages/donation_form/DonationReceipt/useAddressTypeFromReceiptSetter.ts new file mode 100644 index 000000000..bd8755d07 --- /dev/null +++ b/src/components/pages/donation_form/DonationReceipt/useAddressTypeFromReceiptSetter.ts @@ -0,0 +1,28 @@ +import { ComputedRef, Ref, ref, watch } from 'vue'; +import { Store } from 'vuex'; +import { action } from '@src/store/util'; +import { NS_ADDRESS } from '@src/store/namespaces'; +import { setAddressType as setAddressTypeActionType } from '@src/store/address/actionTypes'; +import { AddressTypeModel } from '@src/view_models/AddressTypeModel'; + +export function useAddressTypeFromReceiptSetter( receiptModel: Ref, addressType: ComputedRef, store: Store ): void { + const lastAddressType = ref( addressType.value ); + + if ( !receiptModel.value ) { + store.dispatch( action( NS_ADDRESS, setAddressTypeActionType ), AddressTypeModel.EMAIL ); + } else if ( ![ AddressTypeModel.PERSON, AddressTypeModel.COMPANY_WITH_CONTACT ].includes( addressType.value ) ) { + store.dispatch( action( NS_ADDRESS, setAddressTypeActionType ), AddressTypeModel.UNSET ); + } + + const setAddressTypeFromReceipt = ( receipt: boolean | null ): void => { + if ( !receipt ) { + lastAddressType.value = addressType.value; + store.dispatch( action( NS_ADDRESS, setAddressTypeActionType ), AddressTypeModel.EMAIL ); + } else { + store.dispatch( action( NS_ADDRESS, setAddressTypeActionType ), lastAddressType.value ); + lastAddressType.value = AddressTypeModel.UNSET; + } + }; + + watch( receiptModel, setAddressTypeFromReceipt ); +} diff --git a/src/components/pages/donation_form/subpages/AddressPageDonationReceipt.vue b/src/components/pages/donation_form/subpages/AddressPageDonationReceipt.vue index dbb829868..dd0e56c1a 100644 --- a/src/components/pages/donation_form/subpages/AddressPageDonationReceipt.vue +++ b/src/components/pages/donation_form/subpages/AddressPageDonationReceipt.vue @@ -1,6 +1,7 @@ diff --git a/src/components/shared/form_fields/CityAutocompleteField.vue b/src/components/shared/form_fields/CityAutocompleteField.vue index e8d1f08ec..b77be7b5d 100644 --- a/src/components/shared/form_fields/CityAutocompleteField.vue +++ b/src/components/shared/form_fields/CityAutocompleteField.vue @@ -14,7 +14,7 @@ @blur="onBlur" /> -