Deals Excel import/export aligned with Didar: browser-side import, new deal fields (code, probability, closedAt, creator, lostNote, referrer), Didar custom fields
This commit is contained in:
@@ -39,17 +39,24 @@ export type ClientExcelPositionalColumn = { key: string; label: string };
|
||||
export type ClientExcelReadOptions = {
|
||||
positionalColumns?: ClientExcelPositionalColumn[];
|
||||
detectHeaderless?: (firstRowCells: string[]) => boolean;
|
||||
/**
|
||||
* مقدار خام سلول بهجای متن قالببندیشده؛ خروجی دیدار به کدهای عددی قالب تاریخ میدهد
|
||||
* و بدون این گزینه «4231» بهصورت «8/1/11» خوانده میشود.
|
||||
*/
|
||||
rawValues?: boolean;
|
||||
/** ستونهای ناشناخته با کلید `${prefix}${عنوان ستون}` ارسال میشوند (فیلد سفارشی) */
|
||||
customFieldPrefix?: string;
|
||||
};
|
||||
|
||||
function readMatrix(fileBuffer: ArrayBuffer) {
|
||||
const wb = XLSX.read(fileBuffer, { type: 'array', cellDates: true });
|
||||
function readMatrix(fileBuffer: ArrayBuffer, rawValues = false) {
|
||||
const wb = XLSX.read(fileBuffer, { type: 'array', cellDates: !rawValues });
|
||||
const sheetName = wb.SheetNames[0];
|
||||
if (!sheetName) throw new Error('شیت اکسل پیدا نشد');
|
||||
const sheet = wb.Sheets[sheetName]!;
|
||||
return XLSX.utils.sheet_to_json<unknown[]>(sheet, {
|
||||
header: 1,
|
||||
defval: '',
|
||||
raw: false,
|
||||
raw: rawValues,
|
||||
}) as unknown[][];
|
||||
}
|
||||
|
||||
@@ -60,11 +67,13 @@ export async function previewExcelClient(
|
||||
fields: ExcelFieldOption[],
|
||||
options?: ClientExcelReadOptions,
|
||||
): Promise<ExcelPreviewResult> {
|
||||
const matrix = readMatrix(await file.arrayBuffer());
|
||||
const matrix = readMatrix(await file.arrayBuffer(), options?.rawValues);
|
||||
const headerRow = (matrix[0] ?? []).map((c) => cellToString(c));
|
||||
const headerless =
|
||||
Boolean(options?.positionalColumns?.length) &&
|
||||
Boolean(options?.detectHeaderless?.(headerRow));
|
||||
const prefix = options?.customFieldPrefix;
|
||||
const allFields = [...fields];
|
||||
|
||||
const columns: ExcelPreviewResult['columns'] = [];
|
||||
const suggested: Record<string, string> = {};
|
||||
@@ -96,6 +105,11 @@ export async function previewExcelClient(
|
||||
if (key && !used.has(key)) {
|
||||
suggested[header] = key;
|
||||
used.add(key);
|
||||
} else if (!key && prefix) {
|
||||
const cfKey = `${prefix}${header}`;
|
||||
allFields.push({ key: cfKey, label: `فیلد سفارشی: ${header}` });
|
||||
suggested[header] = cfKey;
|
||||
used.add(cfKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -116,7 +130,7 @@ export async function previewExcelClient(
|
||||
|
||||
return {
|
||||
columns,
|
||||
fields,
|
||||
fields: allFields,
|
||||
suggested,
|
||||
needsMapping: headerless
|
||||
? false
|
||||
@@ -132,7 +146,7 @@ export async function readMappedRowsClient(
|
||||
mapping?: Record<string, string>,
|
||||
options?: ClientExcelReadOptions,
|
||||
): Promise<Record<string, string>[]> {
|
||||
const matrix = readMatrix(await file.arrayBuffer());
|
||||
const matrix = readMatrix(await file.arrayBuffer(), options?.rawValues);
|
||||
const headerRow = (matrix[0] ?? []).map((c) => cellToString(c));
|
||||
const headerless =
|
||||
!mapping &&
|
||||
@@ -152,6 +166,9 @@ export async function readMappedRowsClient(
|
||||
if (!header) return;
|
||||
const key = resolveFieldKey(header, aliases, mapping);
|
||||
if (key) colMap.set(idx, key);
|
||||
else if (!mapping && options?.customFieldPrefix) {
|
||||
colMap.set(idx, `${options.customFieldPrefix}${header}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user