Fix stale address coordinates after clearing autofill (#20264)

Closes #20082
This commit is contained in:
Abdul Rahman
2026-05-05 20:13:51 +05:30
committed by GitHub
parent e89b12488c
commit 3d60e6dbfc
5 changed files with 75 additions and 3 deletions
@@ -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 (
@@ -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;
@@ -48,6 +48,8 @@ export const computeEmptyDraftValue = <FieldValue>({
addressState: '',
addressCountry: '',
addressPostcode: '',
addressLat: null,
addressLng: null,
} as unknown as FieldInputDraftValue<FieldValue>;
}
@@ -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,
};
};