Fix stale address coordinates after clearing autofill (#20264)
Closes #20082
This commit is contained in:
+2
-1
@@ -7,6 +7,7 @@ import { type FieldAddressDraftValue } from '@/object-record/record-field/ui/typ
|
||||
import { type FieldAddressValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { normalizeAddressFieldValueForPersist } from '~/utils/normalize-address-field-value-for-persist';
|
||||
|
||||
type FormAddressFieldInputProps = {
|
||||
label?: string;
|
||||
@@ -36,7 +37,7 @@ export const FormAddressFieldInput = ({
|
||||
addressLng: defaultValue?.addressLng ?? null,
|
||||
[field]: updatedAddressPart,
|
||||
};
|
||||
onChange(updatedAddress);
|
||||
onChange(normalizeAddressFieldValueForPersist(updatedAddress));
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
+3
-2
@@ -8,6 +8,7 @@ import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useContext } from 'react';
|
||||
import { castAsNumberOrNull } from '~/utils/cast-as-number-or-null';
|
||||
import { normalizeAddressFieldValueForPersist } from '~/utils/normalize-address-field-value-for-persist';
|
||||
|
||||
export const AddressFieldInput = () => {
|
||||
const { draftValue, setDraftValue, fieldDefinition } = useAddressField();
|
||||
@@ -19,7 +20,7 @@ export const AddressFieldInput = () => {
|
||||
const convertToAddress = (
|
||||
newAddress: FieldAddressDraftValue | undefined,
|
||||
): FieldAddressDraftValue => {
|
||||
return {
|
||||
return normalizeAddressFieldValueForPersist({
|
||||
addressStreet1: newAddress?.addressStreet1 ?? '',
|
||||
addressStreet2: newAddress?.addressStreet2 ?? null,
|
||||
addressCity: newAddress?.addressCity ?? null,
|
||||
@@ -28,7 +29,7 @@ export const AddressFieldInput = () => {
|
||||
addressPostcode: newAddress?.addressPostcode ?? null,
|
||||
addressLat: castAsNumberOrNull(newAddress?.addressLat),
|
||||
addressLng: castAsNumberOrNull(newAddress?.addressLng),
|
||||
};
|
||||
});
|
||||
};
|
||||
const settings = fieldDefinition.metadata.settings;
|
||||
|
||||
|
||||
+2
@@ -48,6 +48,8 @@ export const computeEmptyDraftValue = <FieldValue>({
|
||||
addressState: '',
|
||||
addressCountry: '',
|
||||
addressPostcode: '',
|
||||
addressLat: null,
|
||||
addressLng: null,
|
||||
} as unknown as FieldInputDraftValue<FieldValue>;
|
||||
}
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { type FieldAddressValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
import { normalizeAddressFieldValueForPersist } from '~/utils/normalize-address-field-value-for-persist';
|
||||
|
||||
describe('normalizeAddressFieldValueForPersist', () => {
|
||||
it('should set coordinates to null when all text subfields are empty', () => {
|
||||
const input: FieldAddressValue = {
|
||||
addressStreet1: '',
|
||||
addressStreet2: null,
|
||||
addressCity: null,
|
||||
addressState: null,
|
||||
addressPostcode: null,
|
||||
addressCountry: null,
|
||||
addressLat: 40.7128,
|
||||
addressLng: -74.006,
|
||||
};
|
||||
|
||||
const result = normalizeAddressFieldValueForPersist(input);
|
||||
|
||||
expect(result.addressLat).toBeNull();
|
||||
expect(result.addressLng).toBeNull();
|
||||
});
|
||||
|
||||
it('should preserve coordinates when any text subfield is non-empty', () => {
|
||||
const input: FieldAddressValue = {
|
||||
addressStreet1: '1600 Amphitheatre',
|
||||
addressStreet2: null,
|
||||
addressCity: null,
|
||||
addressState: null,
|
||||
addressPostcode: null,
|
||||
addressCountry: null,
|
||||
addressLat: 37.422,
|
||||
addressLng: -122.084,
|
||||
};
|
||||
|
||||
const result = normalizeAddressFieldValueForPersist(input);
|
||||
|
||||
expect(result.addressLat).toBe(37.422);
|
||||
expect(result.addressLng).toBe(-122.084);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
|
||||
import { type FieldAddressValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
|
||||
// When every user-editable text part of the address is empty, clear coordinates
|
||||
// so DB columns for addressLat/addressLng are updated (see formatCompositeField
|
||||
// in twenty-server: omitted keys are not written, leaving old coordinates in place).
|
||||
export const normalizeAddressFieldValueForPersist = (
|
||||
address: FieldAddressValue,
|
||||
): FieldAddressValue => {
|
||||
const allTextPartsEmpty =
|
||||
!isNonEmptyString(address.addressStreet1) &&
|
||||
!isNonEmptyString(address.addressStreet2) &&
|
||||
!isNonEmptyString(address.addressCity) &&
|
||||
!isNonEmptyString(address.addressState) &&
|
||||
!isNonEmptyString(address.addressPostcode) &&
|
||||
!isNonEmptyString(address.addressCountry);
|
||||
|
||||
if (!allTextPartsEmpty) {
|
||||
return address;
|
||||
}
|
||||
|
||||
return {
|
||||
...address,
|
||||
addressLat: null,
|
||||
addressLng: null,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user