mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-28 01:09:11 +03:00
Fix phone input and link input (#2679)
* wip * phone picker is appearing * fixing picker placement * set phone picker width * fix link input
This commit is contained in:
parent
c795db33b2
commit
4f55243b30
@ -140,7 +140,8 @@ export const CountryPickerDropdownButton = ({
|
||||
onChange={handleChange}
|
||||
/>
|
||||
}
|
||||
dropdownOffset={{ x: -60, y: -34 }}
|
||||
dropdownPlacement="bottom-start"
|
||||
dropdownOffset={{ x: 0, y: 4 }}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
|
@ -27,13 +27,6 @@ const StyledIconContainer = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledDropdownMenuContainer = styled.ul`
|
||||
left: 6px;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
`;
|
||||
|
||||
export const CountryPickerDropdownSelect = ({
|
||||
countries,
|
||||
selectedCountry,
|
||||
@ -56,54 +49,50 @@ export const CountryPickerDropdownSelect = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledDropdownMenuContainer data-select-disable>
|
||||
<DropdownMenu width="240px" disableBlur>
|
||||
<DropdownMenuSearchInput
|
||||
value={searchFilter}
|
||||
onChange={(event) => setSearchFilter(event.currentTarget.value)}
|
||||
autoFocus
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredCountries?.length === 0 ? (
|
||||
<MenuItem text="No result" />
|
||||
) : (
|
||||
<>
|
||||
{selectedCountry && (
|
||||
<DropdownMenu width="200px" disableBlur>
|
||||
<DropdownMenuSearchInput
|
||||
value={searchFilter}
|
||||
onChange={(event) => setSearchFilter(event.currentTarget.value)}
|
||||
autoFocus
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredCountries?.length === 0 ? (
|
||||
<MenuItem text="No result" />
|
||||
) : (
|
||||
<>
|
||||
{selectedCountry && (
|
||||
<MenuItemSelectAvatar
|
||||
key={selectedCountry.countryCode}
|
||||
selected={true}
|
||||
onClick={() => onChange(selectedCountry.countryCode)}
|
||||
text={`${selectedCountry.countryName} (+${selectedCountry.callingCode})`}
|
||||
avatar={
|
||||
<StyledIconContainer>
|
||||
<selectedCountry.Flag />
|
||||
</StyledIconContainer>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{filteredCountries.map(
|
||||
({ countryCode, countryName, callingCode, Flag }) =>
|
||||
selectedCountry?.countryCode === countryCode ? null : (
|
||||
<MenuItemSelectAvatar
|
||||
key={selectedCountry.countryCode}
|
||||
selected={true}
|
||||
onClick={() => onChange(selectedCountry.countryCode)}
|
||||
text={`${selectedCountry.countryName} (+${selectedCountry.callingCode})`}
|
||||
key={countryCode}
|
||||
selected={selectedCountry?.countryCode === countryCode}
|
||||
onClick={() => onChange(countryCode)}
|
||||
text={`${countryName} (+${callingCode})`}
|
||||
avatar={
|
||||
<StyledIconContainer>
|
||||
<selectedCountry.Flag />
|
||||
<Flag />
|
||||
</StyledIconContainer>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{filteredCountries.map(
|
||||
({ countryCode, countryName, callingCode, Flag }) =>
|
||||
selectedCountry?.countryCode === countryCode ? null : (
|
||||
<MenuItemSelectAvatar
|
||||
key={countryCode}
|
||||
selected={selectedCountry?.countryCode === countryCode}
|
||||
onClick={() => onChange(countryCode)}
|
||||
text={`${countryName} (+${callingCode})`}
|
||||
avatar={
|
||||
<StyledIconContainer>
|
||||
<Flag />
|
||||
</StyledIconContainer>
|
||||
}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</>
|
||||
),
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownMenu>
|
||||
</StyledDropdownMenuContainer>
|
||||
</>
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
|
@ -6,18 +6,16 @@ const StyledDropdownMenu = styled.div<{
|
||||
}>`
|
||||
backdrop-filter: ${({ disableBlur }) =>
|
||||
disableBlur ? 'none' : 'blur(20px)'};
|
||||
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
|
||||
display: flex;
|
||||
|
||||
flex-direction: column;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: ${({ width }) =>
|
||||
width ? `${typeof width === 'number' ? `${width}px` : width}` : '160px'};
|
||||
`;
|
||||
|
@ -48,12 +48,22 @@ export const FieldInput = ({
|
||||
}: FieldInputProps) => {
|
||||
const { fieldDefinition } = useContext(FieldContext);
|
||||
|
||||
console.log(fieldDefinition);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isFieldRelation(fieldDefinition) ? (
|
||||
<RecoilScope>
|
||||
<RelationFieldInput onSubmit={onSubmit} onCancel={onCancel} />
|
||||
</RecoilScope>
|
||||
) : isFieldPhone(fieldDefinition) ? (
|
||||
<PhoneFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
) : isFieldText(fieldDefinition) ? (
|
||||
<TextFieldInput
|
||||
onEnter={onEnter}
|
||||
@ -110,14 +120,6 @@ export const FieldInput = ({
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
) : isFieldPhone(fieldDefinition) ? (
|
||||
<PhoneFieldInput
|
||||
onEnter={onEnter}
|
||||
onEscape={onEscape}
|
||||
onClickOutside={onClickOutside}
|
||||
onTab={onTab}
|
||||
onShiftTab={onShiftTab}
|
||||
/>
|
||||
) : isFieldBoolean(fieldDefinition) ? (
|
||||
<BooleanFieldInput onSubmit={onSubmit} />
|
||||
) : isFieldProbability(fieldDefinition) ? (
|
||||
|
@ -12,7 +12,8 @@ import { isFieldPhone } from '../../types/guards/isFieldPhone';
|
||||
export const usePhoneField = () => {
|
||||
const { entityId, fieldDefinition, hotkeyScope } = useContext(FieldContext);
|
||||
|
||||
assertFieldMetadata('PHONE', isFieldPhone, fieldDefinition);
|
||||
//assertFieldMetadata('PHONE', isFieldPhone, fieldDefinition);
|
||||
assertFieldMetadata('TEXT', isFieldPhone, fieldDefinition);
|
||||
|
||||
const fieldName = fieldDefinition.metadata.fieldName;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { FieldDoubleText } from '../../../types/FieldDoubleText';
|
||||
import { TextInput } from '@/ui/object/field/meta-types/input/components/internal/TextInput';
|
||||
|
||||
import { useLinkField } from '../../hooks/useLinkField';
|
||||
|
||||
import { DoubleTextInput } from './internal/DoubleTextInput';
|
||||
import { FieldInputOverlay } from './internal/FieldInputOverlay';
|
||||
import { FieldInputEvent } from './DateFieldInput';
|
||||
|
||||
@ -22,61 +22,59 @@ export const LinkFieldInput = ({
|
||||
}: LinkFieldInputProps) => {
|
||||
const { initialValue, hotkeyScope, persistLinkField } = useLinkField();
|
||||
|
||||
const handleEnter = (newURL: FieldDoubleText) => {
|
||||
const handleEnter = (newURL: string) => {
|
||||
onEnter?.(() =>
|
||||
persistLinkField({
|
||||
url: newURL.firstValue,
|
||||
label: newURL.secondValue,
|
||||
url: newURL,
|
||||
label: newURL,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const handleEscape = (newURL: FieldDoubleText) => {
|
||||
const handleEscape = (newURL: string) => {
|
||||
onEscape?.(() =>
|
||||
persistLinkField({
|
||||
url: newURL.firstValue,
|
||||
label: newURL.secondValue,
|
||||
url: newURL,
|
||||
label: newURL,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const handleClickOutside = (
|
||||
event: MouseEvent | TouchEvent,
|
||||
newURL: FieldDoubleText,
|
||||
newURL: string,
|
||||
) => {
|
||||
onClickOutside?.(() =>
|
||||
persistLinkField({
|
||||
url: newURL.firstValue,
|
||||
label: newURL.secondValue,
|
||||
url: newURL,
|
||||
label: newURL,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const handleTab = (newURL: FieldDoubleText) => {
|
||||
const handleTab = (newURL: string) => {
|
||||
onTab?.(() =>
|
||||
persistLinkField({
|
||||
url: newURL.firstValue,
|
||||
label: newURL.secondValue,
|
||||
url: newURL,
|
||||
label: newURL,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const handleShiftTab = (newURL: FieldDoubleText) => {
|
||||
const handleShiftTab = (newURL: string) => {
|
||||
onShiftTab?.(() =>
|
||||
persistLinkField({
|
||||
url: newURL.firstValue,
|
||||
label: newURL.secondValue,
|
||||
url: newURL,
|
||||
label: newURL,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<FieldInputOverlay>
|
||||
<DoubleTextInput
|
||||
firstValue={initialValue.url}
|
||||
secondValue={initialValue.label}
|
||||
firstValuePlaceholder={'Url'}
|
||||
secondValuePlaceholder={'Label'}
|
||||
<TextInput
|
||||
value={initialValue.url}
|
||||
placeholder="URL"
|
||||
hotkeyScope={hotkeyScope}
|
||||
onClickOutside={handleClickOutside}
|
||||
onEnter={handleEnter}
|
||||
|
@ -15,7 +15,6 @@ import { isFieldEmail } from '../../types/guards/isFieldEmail';
|
||||
import { isFieldLink } from '../../types/guards/isFieldLink';
|
||||
import { isFieldLinkValue } from '../../types/guards/isFieldLinkValue';
|
||||
import { isFieldNumber } from '../../types/guards/isFieldNumber';
|
||||
import { isFieldPhone } from '../../types/guards/isFieldPhone';
|
||||
import { isFieldProbability } from '../../types/guards/isFieldProbability';
|
||||
import { isFieldRelation } from '../../types/guards/isFieldRelation';
|
||||
import { isFieldRelationValue } from '../../types/guards/isFieldRelationValue';
|
||||
@ -43,8 +42,8 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
|
||||
isFieldNumber(fieldDefinition) ||
|
||||
isFieldProbability(fieldDefinition) ||
|
||||
isFieldEmail(fieldDefinition) ||
|
||||
isFieldBoolean(fieldDefinition) ||
|
||||
isFieldPhone(fieldDefinition)
|
||||
isFieldBoolean(fieldDefinition)
|
||||
//|| isFieldPhone(fieldDefinition)
|
||||
) {
|
||||
const fieldValue = get(entityFieldsFamilyState(entityId))?.[
|
||||
fieldName
|
||||
|
@ -1,58 +1,67 @@
|
||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||
|
||||
export type FieldUuidMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldBooleanMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldTextMetadata = {
|
||||
objectMetadataNameSingular: string;
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldDateTimeMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldNumberMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
placeHolder: string;
|
||||
isPositive?: boolean;
|
||||
};
|
||||
|
||||
export type FieldLinkMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldCurrencyMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
placeHolder: string;
|
||||
isPositive?: boolean;
|
||||
};
|
||||
|
||||
export type FieldFullNameMetadata = {
|
||||
objectMetadataNameSingular: string;
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldEmailMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldPhoneMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
placeHolder: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
export type FieldProbabilityMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
};
|
||||
|
||||
@ -63,6 +72,7 @@ export type FieldDefinitionRelationType =
|
||||
| 'TO_ONE_OBJECT';
|
||||
|
||||
export type FieldRelationMetadata = {
|
||||
objectMetadataNameSingular?: string;
|
||||
fieldName: string;
|
||||
useEditButton?: boolean;
|
||||
relationType?: FieldDefinitionRelationType;
|
||||
|
@ -2,5 +2,8 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldPhoneMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldPhone = (
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldPhoneMetadata> => field.type === 'PHONE';
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type' | 'metadata'>,
|
||||
): field is FieldDefinition<FieldPhoneMetadata> =>
|
||||
field.metadata.objectMetadataNameSingular === 'person' &&
|
||||
field.metadata.fieldName === 'phone' &&
|
||||
field.type === 'TEXT';
|
||||
|
Loading…
Reference in New Issue
Block a user