Files
twenty/packages/twenty-front/src/modules/spreadsheet-import/utils/normalizeTableData.ts
T
Félix Malfait e9e33c4d29 Refactor spreadsheet import (#11250)
Mostly renaming objects to avoid conflicts (it was painful because names
were too generic so you could cmd+replace easily)

Also refactoring `useBuildAvailableFieldsForImport`
2025-03-28 07:56:51 +01:00

106 lines
3.4 KiB
TypeScript

import {
ImportedRow,
ImportedStructuredRow,
SpreadsheetImportFields,
} from '@/spreadsheet-import/types';
import { SpreadsheetColumns } from '@/spreadsheet-import/types/SpreadsheetColumns';
import { SpreadsheetColumnType } from '@/spreadsheet-import/types/SpreadsheetColumnType';
import { isDefined } from 'twenty-shared/utils';
import { z } from 'zod';
import { normalizeCheckboxValue } from './normalizeCheckboxValue';
export const normalizeTableData = <T extends string>(
columns: SpreadsheetColumns<T>,
data: ImportedRow[],
fields: SpreadsheetImportFields<T>,
) =>
data.map((row) =>
columns.reduce((acc, column, index) => {
const curr = row[index];
switch (column.type) {
case SpreadsheetColumnType.matchedCheckbox: {
const field = fields.find((field) => field.key === column.value);
if (!field) {
return acc;
}
if (
'booleanMatches' in field.fieldType &&
Object.keys(field.fieldType).length > 0
) {
const booleanMatchKey = Object.keys(
field.fieldType.booleanMatches || [],
).find((key) => key.toLowerCase() === curr?.toLowerCase());
if (!booleanMatchKey) {
return acc;
}
const booleanMatch =
field.fieldType.booleanMatches?.[booleanMatchKey];
acc[column.value] = booleanMatchKey
? booleanMatch
: normalizeCheckboxValue(curr);
} else {
acc[column.value] = normalizeCheckboxValue(curr);
}
return acc;
}
case SpreadsheetColumnType.matched: {
acc[column.value] = curr === '' ? undefined : curr;
return acc;
}
case SpreadsheetColumnType.matchedSelect:
case SpreadsheetColumnType.matchedSelectOptions: {
const field = fields.find((field) => field.key === column.value);
if (!field) {
return acc;
}
if (field.fieldType.type === 'multiSelect' && isDefined(curr)) {
const currentOptionsSchema = z.preprocess(
(value) => JSON.parse(z.string().parse(value)),
z.array(z.unknown()),
);
const rawCurrentOptions = currentOptionsSchema.safeParse(curr).data;
const matchedOptionValues = [
...new Set(
rawCurrentOptions
?.map(
(option) =>
column.matchedOptions.find(
(matchedOption) => matchedOption.entry === option,
)?.value,
)
.filter(isDefined),
),
];
const fieldValue =
matchedOptionValues && matchedOptionValues.length > 0
? JSON.stringify(matchedOptionValues)
: undefined;
acc[column.value] = fieldValue;
} else {
const matchedOption = column.matchedOptions.find(
({ entry }) => entry === curr,
);
acc[column.value] = matchedOption?.value || undefined;
}
return acc;
}
case SpreadsheetColumnType.empty:
case SpreadsheetColumnType.ignored: {
return acc;
}
default:
return acc;
}
}, {} as ImportedStructuredRow<T>),
);