Skip to content

Commit

Permalink
Add street autocomplete to alternate address form
Browse files Browse the repository at this point in the history
We're about to do a test that needs both features
so now both address forms have both form orders.

The bank validation error in the summary wasn't appearing
so I modified the summary components to watch the store
through a computed value.

Some of the error summaries contained the wrong focus and
scroll ids for the direct debit field. This should now be
fixed.

The summary was vanishing if the bankdata was invalid and
the rest of the form was valid, so I updated the
useAddressFormEventHandlers composable to mark it as invalid
properly and added a test.

I also noticed that the error summaries weren't displaying
all the errors on the alternate form when the donor had
selected yes for receipt and not selected an address type.

Ticket: https://phabricator.wikimedia.org/T374216
  • Loading branch information
Abban committed Sep 10, 2024
1 parent 2b1cbe9 commit a88f01f
Show file tree
Hide file tree
Showing 10 changed files with 521 additions and 39 deletions.
14 changes: 8 additions & 6 deletions src/components/pages/donation_form/AddressFormErrorSummaries.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.addressType,
Expand Down Expand Up @@ -70,10 +70,10 @@
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.companyName,
Expand Down Expand Up @@ -118,10 +118,10 @@
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.firstName,
Expand Down Expand Up @@ -151,6 +151,7 @@ import ErrorSummary from '@src/components/shared/validation_summary/ErrorSummary
import { useStore } from 'vuex';
import { AddressTypeModel } from '@src/view_models/AddressTypeModel';
import { Validity } from '@src/view_models/Validity';
import { computed } from 'vue';
interface Props {
showErrorSummary: boolean;
Expand All @@ -159,5 +160,6 @@ interface Props {
defineProps<Props>();
const store = useStore();
const bankDataValidity = computed<Validity>( () => store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID );
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<template>
<div class="address-section">

<ScrollTarget target-id="address-type-scroll-target"/>
<RadioField
v-model="addressType"
name="addressTypeSelector"
:options="[
{ value: AddressTypeModel.PERSON, label: $t( 'C24_WMDE_Desktop_DE_01_contact_details_private' ), id: 'addressType-0' },
{ value: AddressTypeModel.COMPANY_WITH_CONTACT, label: $t( 'C24_WMDE_Desktop_DE_01_contact_details_company' ), id: 'addressType-1' },
]"
:label="$t( 'C24_WMDE_Desktop_DE_01_contact_details_label' )"
:show-error="showAddressTypeError"
:error-message="$t( 'donation_form_section_address_error' )"
alignment="row"
/>

<ScrollTarget target-id="company-name-scroll-target"/>
<TextField
v-if="addressType === AddressTypeModel.COMPANY_WITH_CONTACT"
name="companyName"
input-id="company-name"
v-model="formData.companyName.value"
:show-error="showError.companyName"
:error-message="$t( 'donation_form_companyname_error' )"
autocomplete="organization"
:label="$t( 'donation_form_companyname_label' )"
:placeholder="$t( 'form_for_example', { example: $t( 'donation_form_companyname_placeholder' ) } )"
@field-changed="$emit('field-changed', 'companyName')"
/>

<ScrollTarget target-id="country-scroll-target"/>
<CountryAutocompleteField
v-model="formData.country.value"
input-id="country"
scroll-target-id="country-scroll-target"
:countries="countries"
:was-restored="countryWasRestored"
:show-error="showError.country"
:error-message="$t('donation_form_country_error')"
:label="$t( 'donation_form_country_label' )"
:placeholder="$t( 'form_for_example', { example: countries[0].countryFullName } )"
@field-changed="onCountryFieldChanged"
/>

<ScrollTarget target-id="post-code-scroll-target"/>
<TextField
name="postcode"
input-id="post-code"
v-model="formData.postcode.value"
:show-error="showError.postcode"
:error-message="$t('donation_form_zip_error')"
autocomplete="postal-code"
:label="$t( 'donation_form_zip_label' )"
:placeholder="$t( 'form_for_example', { example: $t( 'donation_form_zip_placeholder' ) } )"
@field-changed="$emit('field-changed', 'postcode')"
>
<ValueEqualsPlaceholderWarning
:value="formData.postcode.value"
:placeholder="$t( 'donation_form_zip_placeholder' )"
:warning="'donation_form_zip_placeholder_warning'"
/>
</TextField>

<ScrollTarget target-id="city-scroll-target"/>
<CityAutocompleteField
v-model="formData.city.value"
input-id="city"
scroll-target-id="city-scroll-target"
:show-error="showError.city"
:label="$t( 'donation_form_city_label' )"
:error-message="$t( 'donation_form_city_error' )"
:postcode="formData.postcode.value"
example-placeholder="donation_form_city_placeholder"
@field-changed="$emit('field-changed', 'city' )"
>
<ValueEqualsPlaceholderWarning
:value="formData.city.value"
:placeholder="$t( 'donation_form_city_placeholder' )"
warning="donation_form_city_placeholder_warning"
/>
</CityAutocompleteField>

<ScrollTarget target-id="street-scroll-target"/>
<StreetAutocompleteField
input-id-street-name="street"
input-id-building-number="building-number"
scroll-target-id="street-scroll-target"
v-model="formData.street.value"
:postcode="formData.postcode.value"
:show-error="showError.street"
:error-message="$t( 'donation_form_street_error' )"
@field-changed="$emit('field-changed', 'street' )"
/>

</div>
</template>

<script setup lang="ts">
import RadioField from '@src/components/shared/form_fields/RadioField.vue';
import { AddressTypeModel } from '@src/view_models/AddressTypeModel';
import { useStore } from 'vuex';
import { StoreKey } from '@src/store/donation_store';
import { useAddressTypeModel } from '@src/components/pages/donation_form/DonationReceipt/useAddressTypeModel';
import { AddressFormData, AddressValidity } from '@src/view_models/Address';
import TextField from '@src/components/shared/form_fields/TextField.vue';
import ValueEqualsPlaceholderWarning from '@src/components/shared/ValueEqualsPlaceholderWarning.vue';
import { computed } from 'vue';
import CityAutocompleteField from '@src/components/shared/form_fields/CityAutocompleteField.vue';
import CountryAutocompleteField from '@src/components/shared/form_fields/CountryAutocompleteField.vue';
import { Country } from '@src/view_models/Country';
import ScrollTarget from '@src/components/shared/ScrollTarget.vue';
import StreetAutocompleteField from '@src/components/shared/form_fields/StreetAutocompleteField.vue';
interface Props {
formData: AddressFormData;
showError: AddressValidity;
countries: Country[];
postCodeValidation: string;
countryWasRestored: boolean;
}
const props = defineProps<Props>();
const emit = defineEmits( [ 'field-changed' ] );
const store = useStore( StoreKey );
const addressType = useAddressTypeModel( store );
const showAddressTypeError = computed( () => store.getters[ 'address/addressTypeIsInvalid' ] );
const onCountryFieldChanged = ( country: Country | undefined ) => {
if ( country ) {
props.formData.postcode.pattern = country.postCodeValidation;
} else {
props.formData.postcode.pattern = props.postCodeValidation;
}
emit( 'field-changed', 'country' );
if ( props.formData.postcode.value !== '' ) {
emit( 'field-changed', 'postcode' );
}
};
</script>

<style scoped lang="scss">
</style>
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<ErrorSummary
v-if="addressType === AddressTypeModel.UNSET"
v-if="!receiptNeeded && addressType === AddressTypeModel.UNSET"
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.salutation,
Expand Down Expand Up @@ -42,14 +42,14 @@
]"
/>
<ErrorSummary
v-if="addressType === AddressTypeModel.PERSON"
v-if="( receiptNeeded && addressType === AddressTypeModel.UNSET ) || addressType === AddressTypeModel.PERSON"
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.salutation,
Expand Down Expand Up @@ -112,10 +112,10 @@
:is-visible="showErrorSummary"
:items="[
{
validity: store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID,
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'iban-scroll-target'
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.salutation,
Expand Down Expand Up @@ -183,6 +183,12 @@
v-if="addressType === AddressTypeModel.EMAIL"
:is-visible="showErrorSummary"
:items="[
{
validity: bankDataValidity,
message: $t( 'donation_form_payment_bankdata_error' ),
focusElement: 'account-number',
scrollElement: 'account-number-scroll-target'
},
{
validity: store.state.address.validity.salutation,
message: $t( 'donation_form_salutation_error' ),
Expand Down Expand Up @@ -217,14 +223,17 @@ import ErrorSummary from '@src/components/shared/validation_summary/ErrorSummary
import { useStore } from 'vuex';
import { AddressTypeModel } from '@src/view_models/AddressTypeModel';
import { Validity } from '@src/view_models/Validity';
import { computed } from 'vue';
interface Props {
showErrorSummary: boolean;
addressType: AddressTypeModel;
showReceiptOptionError: boolean;
receiptNeeded?: boolean;
}
defineProps<Props>();
const store = useStore();
const bankDataValidity = computed<Validity>( () => store.getters[ 'bankdata/bankDataIsInvalid' ] ? Validity.INVALID : Validity.VALID );
</script>
Loading

0 comments on commit a88f01f

Please sign in to comment.