add field validation + add other subfields import (#12444)

- Add some subfield imports : primaryLinkLabel / primaryPhoneCallingCode
/ additionalPhones
- Add validation rules for field and subfield

Comments
- Check other validations that can be done
- Refacto on subFieldKey ("...Label")
- Add global tests on validation step -
[issue](https://github.com/twentyhq/core-team-issues/issues/1067)

closes https://github.com/twentyhq/core-team-issues/issues/903 
closes https://github.com/twentyhq/core-team-issues/issues/910
closes https://github.com/twentyhq/core-team-issues/issues/985
closes https://github.com/twentyhq/core-team-issues/issues/904
This commit is contained in:
Etienne
2025-06-05 14:12:24 +02:00
committed by GitHub
parent b481abbb0f
commit 2dd8b9af10
7 changed files with 731 additions and 89 deletions

View File

@ -9,6 +9,7 @@ import {
} from '@/spreadsheet-import/types';
import { TextInput } from '@/ui/input/components/TextInput';
import camelCase from 'lodash.camelcase';
import { isDefined } from 'twenty-shared/utils';
import { AppTooltip } from 'twenty-ui/display';
import { Checkbox, CheckboxVariant, Toggle } from 'twenty-ui/input';
@ -66,6 +67,10 @@ const StyledSelectReadonlyValueContianer = styled.div`
const SELECT_COLUMN_KEY = 'select-row';
const formatSafeId = (columnKey: string) => {
return camelCase(columnKey.replace('(', '').replace(')', ''));
};
export const generateColumns = <T extends string>(
fields: SpreadsheetImportFields<T>,
): Column<ImportedStructuredRow<T> & ImportedStructuredRowMetadata>[] => [
@ -110,13 +115,13 @@ export const generateColumns = <T extends string>(
resizable: true,
headerRenderer: () => (
<StyledHeaderContainer>
<StyledHeaderLabel id={`${column.key}`}>
<StyledHeaderLabel id={formatSafeId(column.key)}>
{column.label}
</StyledHeaderLabel>
{column.description &&
createPortal(
<AppTooltip
anchorSelect={`#${column.key}`}
anchorSelect={`#${formatSafeId(column.key)}`}
place="top"
content={column.description}
/>,
@ -168,7 +173,7 @@ export const generateColumns = <T extends string>(
case 'checkbox':
component = (
<StyledToggleContainer
id={`${columnKey}-${row.__index}`}
id={formatSafeId(`${columnKey}-${row.__index}`)}
onClick={(event) => {
event.stopPropagation();
}}
@ -187,7 +192,9 @@ export const generateColumns = <T extends string>(
break;
case 'select':
component = (
<StyledDefaultContainer id={`${columnKey}-${row.__index}`}>
<StyledDefaultContainer
id={formatSafeId(`${columnKey}-${row.__index}`)}
>
{column.fieldType.options.find(
(option) => option.value === row[columnKey as T],
)?.label || null}
@ -196,7 +203,9 @@ export const generateColumns = <T extends string>(
break;
default:
component = (
<StyledDefaultContainer id={`${columnKey}-${row.__index}`}>
<StyledDefaultContainer
id={formatSafeId(`${columnKey}-${row.__index}`)}
>
{row[columnKey]}
</StyledDefaultContainer>
);
@ -208,7 +217,7 @@ export const generateColumns = <T extends string>(
{component}
{createPortal(
<AppTooltip
anchorSelect={`#${columnKey}-${row.__index}`}
anchorSelect={`#${formatSafeId(`${columnKey}-${row.__index}`)}`}
place="top"
content={row.__errors?.[columnKey]?.message}
/>,