From 4004907797a7fd47775fe2d26ad1da06b8cfc037 Mon Sep 17 00:00:00 2001 From: Marko Haarni Date: Fri, 1 Sep 2023 14:57:15 +0300 Subject: [PATCH 1/9] HAI-1835 Add possibility to copy user's own information to other contacts in cable report application (#364) Added button that enables user to copy the information they have entered in the first page of cable report application to other contacts in the contact page. --- src/common/components/textInput/TextInput.tsx | 3 + src/domain/johtoselvitys/BasicInfo.tsx | 4 + src/domain/johtoselvitys/Contacts.module.scss | 4 + src/domain/johtoselvitys/Contacts.test.tsx | 56 ++++++++- src/domain/johtoselvitys/Contacts.tsx | 112 ++++++++++++++++-- src/locales/fi.json | 3 +- 6 files changed, 169 insertions(+), 13 deletions(-) diff --git a/src/common/components/textInput/TextInput.tsx b/src/common/components/textInput/TextInput.tsx index 608eb1d4d..2471c4e01 100644 --- a/src/common/components/textInput/TextInput.tsx +++ b/src/common/components/textInput/TextInput.tsx @@ -17,6 +17,7 @@ type PropTypes = { helperText?: string; shouldUnregister?: boolean; className?: string; + autoComplete?: string; }; const TextInput: React.FC> = ({ @@ -30,6 +31,7 @@ const TextInput: React.FC> = ({ helperText, shouldUnregister, className, + autoComplete, }) => { const { t } = useTranslation(); const { control } = useFormContext(); @@ -57,6 +59,7 @@ const TextInput: React.FC> = ({ onBlur={onBlur} onChange={onChange} ref={ref} + autoComplete={autoComplete} {...tooltip} /> )} diff --git a/src/domain/johtoselvitys/BasicInfo.tsx b/src/domain/johtoselvitys/BasicInfo.tsx index 1abbc112d..f4da0c8ec 100644 --- a/src/domain/johtoselvitys/BasicInfo.tsx +++ b/src/domain/johtoselvitys/BasicInfo.tsx @@ -218,6 +218,7 @@ export function BasicInfo() { name="applicationData.name" label={t('hakemus:labels:nimi')} required + autoComplete="on" /> diff --git a/src/domain/johtoselvitys/Contacts.module.scss b/src/domain/johtoselvitys/Contacts.module.scss index b2f360455..aab60b427 100644 --- a/src/domain/johtoselvitys/Contacts.module.scss +++ b/src/domain/johtoselvitys/Contacts.module.scss @@ -9,3 +9,7 @@ padding: var(--spacing-s); margin-bottom: var(--spacing-s); } + +.fillOwnInfoButton { + align-self: end; +} diff --git a/src/domain/johtoselvitys/Contacts.test.tsx b/src/domain/johtoselvitys/Contacts.test.tsx index 79148ddd4..0b6484cd5 100644 --- a/src/domain/johtoselvitys/Contacts.test.tsx +++ b/src/domain/johtoselvitys/Contacts.test.tsx @@ -1,15 +1,22 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import React from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { fireEvent, render, screen } from '../../testUtils/render'; import { Contacts } from './Contacts'; import hankkeet from '../mocks/data/hankkeet-data'; +import applications from '../mocks/data/hakemukset-data'; import { HankeContact, HankeDataDraft } from '../types/hanke'; +import { JohtoselvitysFormValues } from './types'; jest.setTimeout(10000); -function Form({ hanke }: { hanke?: HankeDataDraft }) { - const methods = useForm({}); +function Form({ + hanke, + application, +}: { + hanke?: HankeDataDraft; + application?: JohtoselvitysFormValues; +}) { + const methods = useForm({ defaultValues: application ?? { applicationData: {} } }); const hankeContacts = [hanke?.omistajat, hanke?.rakennuttajat, hanke?.toteuttajat, hanke?.muut]; @@ -68,3 +75,46 @@ test('Business id field is not disabled if customer type is company or associati expect(screen.getAllByLabelText(/y-tunnus/i)[0]).toBeEnabled(); }); + +test('Customer fields can be filled with orderer information', async () => { + const application = applications[0]; + const orderer = application.applicationData.customerWithContacts.contacts[0]; + const { user } = render(
); + + await user.click( + screen.getByTestId('applicationData.customerWithContacts.customer.fillOwnInfoButton'), + ); + + expect(screen.getByTestId('applicationData.customerWithContacts.customer.name')).toHaveValue( + `${orderer.firstName} ${orderer.lastName}`, + ); + expect(screen.getByTestId('applicationData.customerWithContacts.customer.email')).toHaveValue( + orderer.email, + ); + expect(screen.getByTestId('applicationData.customerWithContacts.customer.phone')).toHaveValue( + orderer.phone, + ); +}); + +test('Contact fields can be filled with orderer information', async () => { + const application = applications[0]; + const orderer = application.applicationData.customerWithContacts.contacts[0]; + const { user } = render(); + + await user.click( + screen.getByTestId('applicationData.contractorWithContacts.contacts.0.fillOwnInfoButton'), + ); + + expect( + screen.getByTestId('applicationData.contractorWithContacts.contacts.0.firstName'), + ).toHaveValue(orderer.firstName); + expect( + screen.getByTestId('applicationData.contractorWithContacts.contacts.0.lastName'), + ).toHaveValue(orderer.lastName); + expect(screen.getByTestId('applicationData.contractorWithContacts.contacts.0.email')).toHaveValue( + orderer.email, + ); + expect(screen.getByTestId('applicationData.contractorWithContacts.contacts.0.phone')).toHaveValue( + orderer.phone, + ); +}); diff --git a/src/domain/johtoselvitys/Contacts.tsx b/src/domain/johtoselvitys/Contacts.tsx index 681042a65..735d1af59 100644 --- a/src/domain/johtoselvitys/Contacts.tsx +++ b/src/domain/johtoselvitys/Contacts.tsx @@ -21,6 +21,7 @@ import { HankeContacts } from '../types/hanke'; import PreFilledContactSelect from '../application/components/PreFilledContactSelect'; import { JohtoselvitysFormValues } from './types'; import useForceUpdate from '../../common/hooks/useForceUpdate'; +import { findOrdererKey } from './utils'; function getEmptyContact(): ApplicationContact { return { @@ -49,10 +50,33 @@ function getEmptyCustomerWithContacts(): CustomerWithContacts { }; } -const CustomerFields: React.FC<{ customerType: CustomerType; hankeContacts?: HankeContacts }> = ({ - customerType, - hankeContacts, -}) => { +function FillOwnInformationButton({ + onClick, + testId, +}: { + onClick: (event: React.MouseEvent) => void; + testId: string; +}) { + const { t } = useTranslation(); + + return ( + + ); +} + +const CustomerFields: React.FC<{ + customerType: CustomerType; + hankeContacts?: HankeContacts; + ordererInformation?: ApplicationContact; +}> = ({ customerType, hankeContacts, ordererInformation }) => { const { t } = useTranslation(); const { watch, setValue } = useFormContext(); const forceUpdate = useForceUpdate(); @@ -85,6 +109,26 @@ const CustomerFields: React.FC<{ customerType: CustomerType; hankeContacts?: Han forceUpdate(); } + function fillWithOrdererInformation() { + if (ordererInformation !== undefined) { + setValue( + `applicationData.${customerType}.customer`, + { + type: 'PERSON', + name: `${ordererInformation.firstName} ${ordererInformation.lastName}`, + email: ordererInformation.email, + phone: ordererInformation.phone, + country: 'FI', + registryKey: null, + ovt: null, + invoicingOperator: null, + sapCustomerNumber: null, + }, + { shouldValidate: true }, + ); + } + } + return ( <> {hankeContacts && ( @@ -111,25 +155,37 @@ const CustomerFields: React.FC<{ customerType: CustomerType; hankeContacts?: Han }; })} /> + + + + + @@ -141,15 +197,25 @@ const CustomerFields: React.FC<{ customerType: CustomerType; hankeContacts?: Han const ContactFields: React.FC<{ customerType: CustomerType; index: number; + ordererInformation?: ApplicationContact; onRemove: () => void; -}> = ({ customerType, index, onRemove }) => { +}> = ({ customerType, index, ordererInformation, onRemove }) => { const { t } = useTranslation(); - const { getValues } = useFormContext(); + const { getValues, setValue } = useFormContext(); const orderer = getValues(`applicationData.${customerType}.contacts.${index}.orderer`); const contactsLength: number = getValues().applicationData[customerType]?.contacts.length || 0; const showRemoveContactButton = !orderer && contactsLength > 1; + function fillWithOrdererInformation() { + if (ordererInformation !== undefined) { + setValue(`applicationData.${customerType}.contacts.${index}`, { + ...ordererInformation, + orderer: false, + }); + } + } + return (
+ {!orderer && ( + + )} {showRemoveContactButton && (