diff --git a/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts b/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts index 4f8f6e448506..c58b0142fba1 100644 --- a/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts +++ b/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts @@ -1,11 +1,11 @@ import { isNonEmptyString } from '@sniptt/guards'; -import { IconComponent, useIcons } from 'twenty-ui'; +import { useIcons } from 'twenty-ui'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords'; import { getSpreadSheetValidation } from '@/object-record/spreadsheet-import/util/getSpreadSheetValidation'; import { useSpreadsheetImport } from '@/spreadsheet-import/hooks/useSpreadsheetImport'; -import { SpreadsheetOptions, Validation } from '@/spreadsheet-import/types'; +import { Field, SpreadsheetOptions } from '@/spreadsheet-import/types'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { FieldMetadataType } from '~/generated-metadata/graphql'; @@ -32,15 +32,7 @@ export const useSpreadsheetRecordImport = (objectNameSingular: string) => { ) .sort((a, b) => a.name.localeCompare(b.name)); - const templateFields: { - icon: IconComponent; - label: string; - key: string; - fieldType: { - type: 'input' | 'checkbox'; - }; - validations?: Validation[]; - }[] = []; + const templateFields: Field[] = []; for (const field of fields) { if (field.type === FieldMetadataType.FullName) { templateFields.push({ @@ -80,6 +72,24 @@ export const useSpreadsheetRecordImport = (objectNameSingular: string) => { field.label + ' (ID)', ), }); + } else if (field.type === FieldMetadataType.Select) { + templateFields.push({ + icon: getIcon(field.icon), + label: field.label, + key: field.name, + fieldType: { + type: 'select', + options: + field.options?.map((option) => ({ + label: option.label, + value: option.value, + })) || [], + }, + validations: getSpreadSheetValidation( + field.type, + field.label + ' (ID)', + ), + }); } else { templateFields.push({ icon: getIcon(field.icon), diff --git a/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnSelect.tsx b/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnSelect.tsx index 55ec39cf8398..9908d66a94e9 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnSelect.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/components/MatchColumnSelect.tsx @@ -125,7 +125,7 @@ export const MatchColumnSelect = ({ ({ (importColumn) => (importColumn.type === ColumnType.matched && importColumn.value === column.key) || + (importColumn.type === ColumnType.matchedSelect && + importColumn.value === column.key) || + (importColumn.type === ColumnType.matchedSelectOptions && + importColumn.value === column.key) || column.key === 'select-row', ).length > 0; diff --git a/packages/twenty-front/src/modules/spreadsheet-import/utils/__tests__/setColumn.test.ts b/packages/twenty-front/src/modules/spreadsheet-import/utils/__tests__/setColumn.test.ts index 012dfbabfc31..e71aaddfa869 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/utils/__tests__/setColumn.test.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/utils/__tests__/setColumn.test.ts @@ -20,10 +20,13 @@ describe('setColumn', () => { value: 'oldValue', }; - it('should return a matchedSelect column if field type is "select"', () => { + it('should return a matchedSelectOptions column if field type is "select"', () => { const field = { ...defaultField, - fieldType: { type: 'select' }, + fieldType: { + type: 'select', + options: [{ value: 'John' }, { value: 'Alice' }], + }, } as Field<'Name'>; const data = [['John'], ['Alice']]; @@ -32,14 +35,16 @@ describe('setColumn', () => { expect(result).toEqual({ index: 0, header: 'Name', - type: ColumnType.matchedSelect, + type: ColumnType.matchedSelectOptions, value: 'Name', matchedOptions: [ { entry: 'John', + value: 'John', }, { entry: 'Alice', + value: 'Alice', }, ], }); diff --git a/packages/twenty-front/src/modules/spreadsheet-import/utils/setColumn.ts b/packages/twenty-front/src/modules/spreadsheet-import/utils/setColumn.ts index 0b428321872c..191cdf2081cc 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/utils/setColumn.ts +++ b/packages/twenty-front/src/modules/spreadsheet-import/utils/setColumn.ts @@ -2,6 +2,7 @@ import { Column, ColumnType, MatchColumnsStepProps, + MatchedOptions, } from '@/spreadsheet-import/steps/components/MatchColumnsStep/MatchColumnsStep'; import { Field } from '@/spreadsheet-import/types'; @@ -12,33 +13,56 @@ export const setColumn = ( field?: Field, data?: MatchColumnsStepProps['data'], ): Column => { - switch (field?.fieldType.type) { - case 'select': - return { - ...oldColumn, - type: ColumnType.matchedSelect, - value: field.key, - matchedOptions: uniqueEntries(data || [], oldColumn.index), - }; - case 'checkbox': - return { - index: oldColumn.index, - type: ColumnType.matchedCheckbox, - value: field.key, - header: oldColumn.header, - }; - case 'input': - return { - index: oldColumn.index, - type: ColumnType.matched, - value: field.key, - header: oldColumn.header, - }; - default: - return { - index: oldColumn.index, - header: oldColumn.header, - type: ColumnType.empty, - }; + if (field?.fieldType.type === 'select') { + const fieldOptions = field.fieldType.options; + const uniqueData = uniqueEntries( + data || [], + oldColumn.index, + ) as MatchedOptions[]; + const matchedOptions = uniqueData.map((record) => { + const value = fieldOptions.find( + (fieldOption) => + fieldOption.value === record.entry || + fieldOption.label === record.entry, + )?.value; + return value + ? ({ ...record, value } as MatchedOptions) + : (record as MatchedOptions); + }); + const allMatched = + matchedOptions.filter((o) => o.value).length === uniqueData?.length; + + return { + ...oldColumn, + type: allMatched + ? ColumnType.matchedSelectOptions + : ColumnType.matchedSelect, + value: field.key, + matchedOptions, + }; + } + + if (field?.fieldType.type === 'checkbox') { + return { + index: oldColumn.index, + type: ColumnType.matchedCheckbox, + value: field.key, + header: oldColumn.header, + }; } + + if (field?.fieldType.type === 'input') { + return { + index: oldColumn.index, + type: ColumnType.matched, + value: field.key, + header: oldColumn.header, + }; + } + + return { + index: oldColumn.index, + header: oldColumn.header, + type: ColumnType.empty, + }; };