Skip to content

Commit

Permalink
Move form functions into DonationForm
Browse files Browse the repository at this point in the history
The donation form being a single page now means that
functions to handle it are in the wrong place. This
moves them to the top level component and passes them
as props into the sections and summaries.

Changelist
- Integrated Street Autocomplete and removed toggles.
- Created sub-pages for the 2 remaining donation forms.
- Moved submit handling out of the data sections and into
  the new sub pages.
- Moved form summary, error summary, and submit buttons into
  a separate form section.
- Moved tests from form sections into donation sub form tests.
- useReceiptModel is shared so moved it into shared/composables.
- Added tests for DonationReceipt AddressFields.
- Moved salutation locale adjustment into the store and added tests.

Ticket: https://phabricator.wikimedia.org/T378075
  • Loading branch information
Abban committed Oct 24, 2024
1 parent 6bc99ed commit 9d93d94
Show file tree
Hide file tree
Showing 42 changed files with 758 additions and 2,411 deletions.
71 changes: 11 additions & 60 deletions src/components/pages/DonationForm.vue
Original file line number Diff line number Diff line change
@@ -1,68 +1,22 @@
<template>
<div id="laika-donation">
<FeatureToggle default-template="campaigns.address_pages.legacy">
<template #campaigns.address_pages.legacy>
<PaymentSection
:payment-amounts="paymentAmounts"
:payment-intervals="paymentIntervals"
:payment-types="paymentTypes"
/>
<div class="donation-page-form-section" v-if="isDirectDebit">
<IbanFields/>
</div>
<PersonalDataSection
:assets-path="assetsPath"
:validate-address-url="validateAddressUrl"
:validate-email-url="validateEmailUrl"
:validate-bank-data-url="validateBankDataUrl"
:validate-legacy-bank-data-url="validateLegacyBankDataUrl"
:countries="countries"
:salutations="salutations"
:tracking-data="trackingData"
:campaign-values="campaignValues"
:address-validation-patterns="addressValidationPatterns"
/>
</template>
<template #campaigns.address_pages.test_02>
<PaymentSection
:payment-amounts="paymentAmounts"
:payment-intervals="paymentIntervals"
:payment-types="paymentTypes"
/>
<div class="donation-page-form-section" v-if="isDirectDebit">
<IbanFields/>
</div>
<PersonalDataSectionDonationReceipt
:assets-path="assetsPath"
:validate-address-url="validateAddressUrl"
:validate-email-url="validateEmailUrl"
:validate-bank-data-url="validateBankDataUrl"
:validate-legacy-bank-data-url="validateLegacyBankDataUrl"
:countries="countries"
:salutations="salutations"
:tracking-data="trackingData"
:campaign-values="campaignValues"
:address-validation-patterns="addressValidationPatterns"
/>
</template>
</FeatureToggle>
</div>
<FeatureToggle default-template="campaigns.address_pages.legacy">
<template #campaigns.address_pages.legacy>
<StandardDonationForm v-bind="props"/>
</template>
<template #campaigns.address_pages.test_02>
<ReceiptDonationForm v-bind="props"/>
</template>
</FeatureToggle>
</template>

<script setup lang="ts">
import { TrackingData } from '@src/view_models/TrackingData';
import { Country } from '@src/view_models/Country';
import { AddressValidation } from '@src/view_models/Validation';
import { Salutation } from '@src/view_models/Salutation';
import { CampaignValues } from '@src/view_models/CampaignValues';
import PaymentSection from '@src/components/pages/donation_form/FormSections/PaymentSection.vue';
import PersonalDataSection from '@src/components/pages/donation_form/FormSections/PersonalDataSection.vue';
import PersonalDataSectionDonationReceipt
from '@src/components/pages/donation_form/FormSections/PersonalDataSectionDonationReceipt.vue';
import { computed } from 'vue';
import { useStore } from 'vuex';
import IbanFields from '@src/components/shared/IbanFields.vue';
import StandardDonationForm from '@src/components/pages/donation_form/SubPages/DonationForm.vue';
import ReceiptDonationForm from '@src/components/pages/donation_form/SubPages/DonationFormReceipt.vue';
defineOptions( {
name: 'DonationForm',
Expand All @@ -83,10 +37,7 @@ interface Props {
campaignValues: CampaignValues;
addressValidationPatterns: AddressValidation;
}
defineProps<Props>();
const store = useStore();
const isDirectDebit = computed<boolean>( (): boolean => store.getters[ 'payment/isDirectDebitPayment' ] );
const props = defineProps<Props>();
</script>

Expand Down
4 changes: 2 additions & 2 deletions src/components/pages/UpdateAddress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ import NameFields from '@src/components/shared/NameFields.vue';
import PostalAddressFields from '@src/components/shared/PostalAddressFields.vue';
import FormButton from '@src/components/shared/form_elements/FormButton.vue';
import CheckboxField from '@src/components/shared/form_fields/CheckboxField.vue';
import { useAddressTypeFunctions } from '@src/components/pages/donation_form/AddressTypeFunctions';
import { useReceiptModel } from '@src/components/pages/donation_form/useReceiptModel';
import { useAddressTypeFunctions } from '@src/components/shared/composables/useAddressTypeFunctions';
import ErrorSummary from '@src/components/shared/validation_summary/ErrorSummary.vue';
import ServerMessage from '@src/components/shared/ServerMessage.vue';
import { addressTypeName } from '@src/view_models/AddressTypeModel';
import { UpdateAddressResponse } from '@src/api/UpdateAddressResponse';
import { AddressChangeResource } from '@src/api/AddressChangeResource';
import { useReceiptModel } from '@src/components/shared/composables/useReceiptModel';
defineOptions( {
name: 'UpdateAddress',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ import ValueEqualsPlaceholderWarning from '@src/components/shared/ValueEqualsPla
import NameFields from '@src/components/shared/NameFields.vue';
import RadioField from '@src/components/shared/form_fields/RadioField.vue';
import PostalAddressFields from '@src/components/shared/PostalAddressFields.vue';
import { useAddressTypeFunctions } from '@src/components/pages/donation_form/AddressTypeFunctions';
import { useAddressTypeFunctions } from '@src/components/shared/composables/useAddressTypeFunctions';
import { MAILING_LIST_ADDRESS_PAGE } from '@src/config';
import AddressUpdateFormErrorSummaries
from '@src/components/pages/donation_confirmation/AddressUpdateFormErrorSummaries.vue';
Expand Down
78 changes: 23 additions & 55 deletions src/components/pages/donation_form/AddressForms.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,15 @@
field-id-namespace="person"
v-on:field-changed="onFieldChange"
/>
<FeatureToggle default-template="campaigns.address_field_order.legacy">
<template #campaigns.address_field_order.legacy>
<PostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="person"
v-on:field-changed="onFieldChange"
/>
</template>
<template #campaigns.address_field_order.new_order>
<StreetAutocompletePostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="person"
v-on:field-changed="onFieldChange"
/>
</template>
</FeatureToggle>
<PostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="person"
v-on:field-changed="onFieldChange"
/>
<div class="form-field form-field-donation-receipt">
<CheckboxSingleFormInput
input-id="receipt-option-person"
Expand Down Expand Up @@ -83,30 +68,15 @@
field-id-namespace="company"
v-on:field-changed="onFieldChange"
/>
<FeatureToggle default-template="campaigns.address_field_order.legacy">
<template #campaigns.address_field_order.legacy>
<PostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="company"
v-on:field-changed="onFieldChange"
/>
</template>
<template #campaigns.address_field_order.new_order>
<StreetAutocompletePostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="company"
v-on:field-changed="onFieldChange"
/>
</template>
</FeatureToggle>
<PostalAddressFields
:show-error="fieldErrors"
:form-data="formData"
:countries="countries"
:post-code-validation="addressValidationPatterns.postcode"
:country-was-restored="countryWasRestored"
field-id-namespace="company"
v-on:field-changed="onFieldChange"
/>
<div class="form-field form-field-donation-receipt">
<CheckboxSingleFormInput
input-id="receipt-option-company"
Expand Down Expand Up @@ -175,8 +145,7 @@

<script setup lang="ts">
import { computed, onBeforeMount, ref, toRefs } from 'vue';
import PostalAddressFields from '@src/components/shared/PostalAddressFields.vue';
import StreetAutocompletePostalAddressFields from '@src/components/pages/donation_form/StreetAutocomplete/PostalAddressFields.vue';
import PostalAddressFields from '@src/components/pages/donation_form/PostalAddressFields.vue';
import AutofillHandler from '@src/components/shared/AutofillHandler.vue';
import CheckboxSingleFormInput from '@src/components/shared/form_elements/CheckboxSingleFormInput.vue';
import EmailField from '@src/components/shared/form_fields/EmailField.vue';
Expand All @@ -192,27 +161,25 @@ import { CampaignValues } from '@src/view_models/CampaignValues';
import { AddressTypeIds } from '@src/components/pages/donation_form/AddressTypeIds';
import { Validity } from '@src/view_models/Validity';
import ValueEqualsPlaceholderWarning from '@src/components/shared/ValueEqualsPlaceholderWarning.vue';
import { useReceiptModel } from '@src/components/pages/donation_form/useReceiptModel';
import { useMailingListModel } from '@src/components/shared/form_fields/useMailingListModel';
import ScrollTarget from '@src/components/shared/ScrollTarget.vue';
import { useStore } from 'vuex';
import { useReceiptModel } from '@src/components/shared/composables/useReceiptModel';
interface Props {
countries: Country[],
addressValidationPatterns: AddressValidation,
addressType: AddressTypeModel,
isFullSelected?: boolean,
salutations: Salutation[],
trackingData: TrackingData,
campaignValues: CampaignValues,
}
const props = withDefaults( defineProps<Props>(), {
isFullSelected: false,
addressType: AddressTypeModel.PERSON,
} );
const { addressType, isFullSelected, addressValidationPatterns } = toRefs( props );
const { addressType, addressValidationPatterns } = toRefs( props );
const store = useStore();
const {
formData,
Expand All @@ -221,12 +188,13 @@ const {
onFieldChange,
onAutofill,
} = useAddressFunctions( { addressValidationPatterns: addressValidationPatterns.value }, store );
const mailingList = useMailingListModel( store );
const { receiptNeeded } = useReceiptModel( store );
const addressTypeId = computed( () => {
if ( isFullSelected.value && addressType.value === AddressTypeModel.UNSET ) {
if ( addressType.value === AddressTypeModel.UNSET ) {
return AddressTypeIds.get( AddressTypeModel.PERSON );
}
return AddressTypeIds.has( addressType.value ) ? AddressTypeIds.get( addressType.value ) : '';
Expand Down
4 changes: 1 addition & 3 deletions src/components/pages/donation_form/AddressTypeBasic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,10 @@ interface Props {
}
const props = defineProps<Props>();
const emit = defineEmits( [ 'address-type', 'set-full-selected' ] );
const emit = defineEmits( [ 'address-type' ] );
const addressType = ref<AddressTypeModel>( props.initialAddressType ?? AddressTypeModel.UNSET );
emit( 'set-full-selected', true );
watch( addressType, newAddressType => {
emit( 'address-type', newAddressType );
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,19 @@
@field-changed="$emit('field-changed', 'companyName')"
/>

<ScrollTarget target-id="street-scroll-target"/>
<TextField
name="street"
input-id="street"
v-model="formData.street.value"
:show-error="showError.street"
:error-message="$t('donation_form_street_error')"
autocomplete="street-address"
:label="$t( 'donation_form_street_label' )"
:placeholder="$t( 'form_for_example', { example: $t( 'donation_form_street_placeholder' ) } )"
@field-changed="$emit('field-changed', 'street')"
>
<span v-if="showStreetWarning" class="help">{{ $t('donation_form_street_number_warning') }}</span>
<ValueEqualsPlaceholderWarning
:value="formData.street.value"
:placeholder="$t( 'donation_form_street_placeholder' )"
:warning="'donation_form_street_placeholder_warning'"
/>
</TextField>
<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
Expand Down Expand Up @@ -87,18 +81,16 @@
/>
</CityAutocompleteField>

<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="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>
Expand All @@ -113,18 +105,19 @@ import { useAddressTypeModel } from '@src/components/pages/donation_form/Donatio
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 { computed, onBeforeMount, ref } from 'vue';
import CityAutocompleteField from '@src/components/shared/form_fields/CityAutocompleteField.vue';
import CountryAutocompleteField from '@src/components/shared/form_fields/CountryAutocompleteField.vue';
import StreetAutocompleteField from '@src/components/shared/form_fields/StreetAutocompleteField.vue';
import { Country } from '@src/view_models/Country';
import ScrollTarget from '@src/components/shared/ScrollTarget.vue';
import { Validity } from '@src/view_models/Validity';
interface Props {
formData: AddressFormData;
showError: AddressValidity;
countries: Country[];
postCodeValidation: string;
countryWasRestored: boolean;
}
const props = defineProps<Props>();
Expand All @@ -133,8 +126,8 @@ const emit = defineEmits( [ 'field-changed' ] );
const store = useStore();
const addressType = useAddressTypeModel( store );
const showStreetWarning = computed<boolean>( () => /^\D+$/.test( props.formData.street.value ) );
const showAddressTypeError = computed( () => store.getters[ 'address/addressTypeIsInvalid' ] );
const countryWasRestored = ref<boolean>( false );
const onCountryFieldChanged = ( country: Country | undefined ) => {
if ( country ) {
Expand All @@ -150,4 +143,8 @@ const onCountryFieldChanged = ( country: Country | undefined ) => {
}
};
onBeforeMount( () => {
countryWasRestored.value = store.state.address.validity.country === Validity.RESTORED;
} );
</script>
Loading

0 comments on commit 9d93d94

Please sign in to comment.