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.

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 b10c277
Show file tree
Hide file tree
Showing 8 changed files with 508 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
: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'
Expand Down Expand Up @@ -70,7 +70,7 @@
: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'
Expand Down Expand Up @@ -118,7 +118,7 @@
: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'
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,10 +1,10 @@
<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'
Expand Down Expand Up @@ -42,11 +42,11 @@
]"
/>
<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'
Expand Down Expand Up @@ -112,7 +112,7 @@
: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'
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: 'iban-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 b10c277

Please sign in to comment.