fix - update error message and ease importable format for multi select (#14203)

- Add other string format ('option1,option2,..') for multi select import
- Update error message


closes : https://github.com/twentyhq/twenty/issues/14103
This commit is contained in:
Etienne
2025-09-02 14:18:45 +02:00
committed by GitHub
parent 6d6ee939cf
commit 447892b7ef
4 changed files with 42 additions and 8 deletions
@@ -0,0 +1,20 @@
import { spreadsheetImportParseMultiSelectOptionsOrThrow } from '@/spreadsheet-import/utils/spreadsheetImportParseMultiSelectOptionsOrThrow';
describe('spreadsheetImportParseMultiSelectOptionsOrThrow', () => {
it('should parse multi select options', () => {
const options = spreadsheetImportParseMultiSelectOptionsOrThrow(
'["option1", "option2"]',
);
expect(options).toEqual(['option1', 'option2']);
});
it('should parse multi select options with comma', () => {
const options =
spreadsheetImportParseMultiSelectOptionsOrThrow('option1,option2');
expect(options).toEqual(['option1', 'option2']);
});
it('should throw an error if the value is not parsable', () => {
expect(() => spreadsheetImportParseMultiSelectOptionsOrThrow({})).toThrow();
});
});
@@ -5,6 +5,7 @@ import {
} from '@/spreadsheet-import/types';
import { type SpreadsheetColumns } from '@/spreadsheet-import/types/SpreadsheetColumns';
import { SpreadsheetColumnType } from '@/spreadsheet-import/types/SpreadsheetColumnType';
import { spreadsheetImportParseMultiSelectOptionsOrThrow } from '@/spreadsheet-import/utils/spreadsheetImportParseMultiSelectOptionsOrThrow';
import { isDefined } from 'twenty-shared/utils';
import { z } from 'zod';
import { normalizeCheckboxValue } from './normalizeCheckboxValue';
@@ -60,10 +61,9 @@ export const normalizeTableData = (
}
if (field.fieldType.type === 'multiSelect' && isDefined(curr)) {
const currentOptionsSchema = z.preprocess(
(value) => JSON.parse(z.string().parse(value)),
z.array(z.unknown()),
);
const currentOptionsSchema = z.preprocess((value) => {
return spreadsheetImportParseMultiSelectOptionsOrThrow(value);
}, z.array(z.unknown()));
const rawCurrentOptions = currentOptionsSchema.safeParse(curr).data;
@@ -4,9 +4,9 @@ import { type SpreadsheetImportField } from '@/spreadsheet-import/types';
import { type SpreadsheetColumn } from '@/spreadsheet-import/types/SpreadsheetColumn';
import { SpreadsheetColumnType } from '@/spreadsheet-import/types/SpreadsheetColumnType';
import { type SpreadsheetMatchedOptions } from '@/spreadsheet-import/types/SpreadsheetMatchedOptions';
import { spreadsheetImportParseMultiSelectOptionsOrThrow } from '@/spreadsheet-import/utils/spreadsheetImportParseMultiSelectOptionsOrThrow';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { z } from 'zod';
import { uniqueEntries } from './uniqueEntries';
export const setColumn = (
@@ -55,8 +55,7 @@ export const setColumn = (
?.flatMap((row) => {
const value = row[oldColumn.index];
if (!isDefined(value)) return [];
const options = JSON.parse(z.string().parse(value));
return z.array(z.string()).parse(options);
return spreadsheetImportParseMultiSelectOptionsOrThrow(value);
})
.filter((entry) => typeof entry === 'string'),
),
@@ -67,7 +66,7 @@ export const setColumn = (
header: oldColumn.header,
type: SpreadsheetColumnType.matchedError,
value: field.key,
errorMessage: t`column data is not compatible with Multi-Select.`,
errorMessage: t`column data is not compatible with Multi-Select. Format required is '["option1", "option2"]' or option1,option2.`,
};
}
@@ -0,0 +1,15 @@
import { z } from 'zod';
export const spreadsheetImportParseMultiSelectOptionsOrThrow = (
value: unknown,
) => {
try {
return JSON.parse(z.string().parse(value));
} catch {
return z
.string()
.parse(value)
.split(',')
.map((item) => item.trim());
}
};