Default address country 🗺️ & Phone prefix ☎️ (#8614)
# Default address 🗺️ country & Phone ☎️ country We add the ability to add a Default address country and a default Phone country for fields in the Data model. fix #8081 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -4,28 +4,37 @@ import { ContactLink } from 'twenty-ui';
|
||||
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
type PhoneDisplayProps = {
|
||||
value: string | null | undefined;
|
||||
interface PhoneDisplayProps {
|
||||
value: PhoneDisplayValueProps;
|
||||
}
|
||||
type PhoneDisplayValueProps = {
|
||||
number: string | null | undefined;
|
||||
callingCode: string | null | undefined;
|
||||
};
|
||||
|
||||
// TODO: see if we can find a faster way to format the phone number
|
||||
export const PhoneDisplay = ({ value }: PhoneDisplayProps) => {
|
||||
if (!isDefined(value)) {
|
||||
return <ContactLink href="#">{value}</ContactLink>;
|
||||
}
|
||||
export const PhoneDisplay = ({
|
||||
value: { number, callingCode },
|
||||
}: PhoneDisplayProps) => {
|
||||
if (!isDefined(number)) return <ContactLink href="#">{number}</ContactLink>;
|
||||
|
||||
const callingCodeSanitized = callingCode?.replace('+', '');
|
||||
|
||||
let parsedPhoneNumber: PhoneNumber | null = null;
|
||||
|
||||
try {
|
||||
// TODO: parse according to locale not hard coded FR
|
||||
parsedPhoneNumber = parsePhoneNumber(value, 'FR');
|
||||
parsedPhoneNumber = parsePhoneNumber(number, {
|
||||
defaultCallingCode: callingCodeSanitized || '1',
|
||||
});
|
||||
} catch (error) {
|
||||
return <ContactLink href="#">{value}</ContactLink>;
|
||||
if (!(error instanceof Error))
|
||||
return <ContactLink href="#">{number}</ContactLink>;
|
||||
if (error.message === 'NOT_A_NUMBER')
|
||||
return <ContactLink href="#">{`+${callingCodeSanitized}`}</ContactLink>;
|
||||
return <ContactLink href="#">{number}</ContactLink>;
|
||||
}
|
||||
|
||||
const URI = parsedPhoneNumber.getURI();
|
||||
const formatedPhoneNumber = parsedPhoneNumber.formatInternational();
|
||||
|
||||
return (
|
||||
<ContactLink
|
||||
href={URI}
|
||||
@ -33,7 +42,7 @@ export const PhoneDisplay = ({ value }: PhoneDisplayProps) => {
|
||||
event.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{formatedPhoneNumber || value}
|
||||
{formatedPhoneNumber || number}
|
||||
</ContactLink>
|
||||
);
|
||||
};
|
||||
|
||||
@ -36,16 +36,16 @@ export const PhonesDisplay = ({ value, isFocused }: PhonesDisplayProps) => {
|
||||
value?.primaryPhoneNumber
|
||||
? {
|
||||
number: value.primaryPhoneNumber,
|
||||
countryCode: value.primaryPhoneCountryCode,
|
||||
callingCode: value.primaryPhoneCountryCode,
|
||||
}
|
||||
: null,
|
||||
...parseAdditionalPhones(value?.additionalPhones),
|
||||
]
|
||||
.filter(isDefined)
|
||||
.map(({ number, countryCode }) => {
|
||||
.map(({ number, callingCode }) => {
|
||||
return {
|
||||
number,
|
||||
countryCode,
|
||||
callingCode,
|
||||
};
|
||||
}),
|
||||
[
|
||||
@ -65,9 +65,9 @@ export const PhonesDisplay = ({ value, isFocused }: PhonesDisplayProps) => {
|
||||
|
||||
return isFocused ? (
|
||||
<ExpandableList isChipCountDisplayed>
|
||||
{phones.map(({ number, countryCode }, index) => {
|
||||
{phones.map(({ number, callingCode }, index) => {
|
||||
const { parsedPhone, invalidPhone } =
|
||||
parsePhoneNumberOrReturnInvalidValue(countryCode + number);
|
||||
parsePhoneNumberOrReturnInvalidValue(`+${callingCode}` + number);
|
||||
const URI = parsedPhone?.getURI();
|
||||
return (
|
||||
<RoundedLink
|
||||
@ -82,9 +82,9 @@ export const PhonesDisplay = ({ value, isFocused }: PhonesDisplayProps) => {
|
||||
</ExpandableList>
|
||||
) : (
|
||||
<StyledContainer>
|
||||
{phones.map(({ number, countryCode }, index) => {
|
||||
{phones.map(({ number, callingCode }, index) => {
|
||||
const { parsedPhone, invalidPhone } =
|
||||
parsePhoneNumberOrReturnInvalidValue(countryCode + number);
|
||||
parsePhoneNumberOrReturnInvalidValue(`+${callingCode}` + number);
|
||||
const URI = parsedPhone?.getURI();
|
||||
return (
|
||||
<RoundedLink
|
||||
|
||||
@ -26,7 +26,9 @@ type CallToActionButton = {
|
||||
Icon?: IconComponent;
|
||||
};
|
||||
|
||||
export type SelectProps<Value extends string | number | boolean | null> = {
|
||||
export type SelectValue = string | number | boolean | null;
|
||||
|
||||
export type SelectProps<Value extends SelectValue> = {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
selectSizeVariant?: SelectSizeVariant;
|
||||
@ -57,7 +59,7 @@ const StyledLabel = styled.span`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const Select = <Value extends string | number | boolean | null>({
|
||||
export const Select = <Value extends SelectValue>({
|
||||
className,
|
||||
disabled: disabledFromProps,
|
||||
selectSizeVariant,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useMemo } from 'react';
|
||||
import { IconComponentProps } from 'twenty-ui';
|
||||
import { IconCircleOff, IconComponentProps } from 'twenty-ui';
|
||||
|
||||
import { SELECT_COUNTRY_DROPDOWN_ID } from '@/ui/input/components/internal/country/constants/SelectCountryDropdownId';
|
||||
import { useCountries } from '@/ui/input/components/internal/hooks/useCountries';
|
||||
@ -15,12 +15,20 @@ export const CountrySelect = ({
|
||||
const countries = useCountries();
|
||||
|
||||
const options: SelectOption<string>[] = useMemo(() => {
|
||||
return countries.map<SelectOption<string>>(({ countryName, Flag }) => ({
|
||||
label: countryName,
|
||||
value: countryName,
|
||||
Icon: (props: IconComponentProps) =>
|
||||
Flag({ width: props.size, height: props.size }), // TODO : improve this ?
|
||||
}));
|
||||
const countryList = countries.map<SelectOption<string>>(
|
||||
({ countryName, Flag }) => ({
|
||||
label: countryName,
|
||||
value: countryName,
|
||||
Icon: (props: IconComponentProps) =>
|
||||
Flag({ width: props.size, height: props.size }), // TODO : improve this ?
|
||||
}),
|
||||
);
|
||||
countryList.unshift({
|
||||
label: 'No country',
|
||||
value: '',
|
||||
Icon: IconCircleOff,
|
||||
});
|
||||
return countryList;
|
||||
}, [countries]);
|
||||
|
||||
return (
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import * as Flags from 'country-flag-icons/react/3x2';
|
||||
import { CountryCallingCode } from 'libphonenumber-js';
|
||||
import { CountryCallingCode, CountryCode } from 'libphonenumber-js';
|
||||
|
||||
export type Country = {
|
||||
countryCode: string;
|
||||
countryCode: CountryCode;
|
||||
countryName: string;
|
||||
callingCode: CountryCallingCode;
|
||||
Flag: Flags.FlagComponent;
|
||||
|
||||
Reference in New Issue
Block a user