mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 12:15:23 +02:00
feat: bulk ASIN selection via space-separated paste in filters
Allow pasting multiple ASINs separated by spaces in any MultiSelectDropdown search field and pressing Enter to auto-select all matching options. Also switch ads CSV/Excel parsing to header-based column mapping for robustness across different file formats. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
69eafe8335
commit
487b8e105e
+32
-64
@@ -417,7 +417,7 @@ export const processAdsCSV = (file: File): Promise<AdsRecord[]> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// @ts-ignore
|
||||
Papa.parse(file, {
|
||||
header: false, // Index-based mapping
|
||||
header: true,
|
||||
skipEmptyLines: true,
|
||||
complete: (results: any) => {
|
||||
try {
|
||||
@@ -427,40 +427,22 @@ export const processAdsCSV = (file: File): Promise<AdsRecord[]> => {
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const row = rows[i];
|
||||
if (!Array.isArray(row) || row.length < 12) continue;
|
||||
if (!row || Object.keys(row).length < 5) continue;
|
||||
|
||||
// Check header row (Column A: Customer or Country)
|
||||
const c0 = String(row[0]).trim().toLowerCase();
|
||||
if (c0.includes('customer') || c0.includes('country') || c0.includes('marketplace')) continue;
|
||||
const countryRaw = getColumnValue(row, ['country', 'marketplace', 'portfolio', 'customer', 'kunde']);
|
||||
const weekRaw = getColumnValue(row, ['week', 'woche', 'semana']);
|
||||
const asin = getColumnValue(row, ['asin']);
|
||||
const costRaw = getColumnValue(row, ['cost', 'spend', 'ausgaben', 'gasto', 'coste', 'ad spend']);
|
||||
const clicksRaw = getColumnValue(row, ['clicks', 'klicks', 'clics']);
|
||||
const impressionsRaw = getColumnValue(row, ['impressions', 'impresiones', 'imp']);
|
||||
const cpcRaw = getColumnValue(row, ['cpc', 'cost-per-click', 'coste por clic']);
|
||||
const ctrRaw = getColumnValue(row, ['ctr', 'click-through rate', 'click-through-rate', 'click through rate']);
|
||||
const acosRaw = getColumnValue(row, ['acos', 'advertising cost of sales', 'aCOS']);
|
||||
const conversionsRaw = getColumnValue(row, ['conversions', 'konversionen', 'orders', 'pedidos', 'total orders']);
|
||||
const unitsRaw = getColumnValue(row, ['units', 'einheiten', 'unidades', 'units sold', 'total units']);
|
||||
const salesRaw = getColumnValue(row, ['sales', 'umsatz', 'ventas', 'ad sales', 'total sales', 'sales (30d)']);
|
||||
|
||||
// Column mapping for CSV (same as Excel):
|
||||
// A (0): Country
|
||||
// B (1): Week
|
||||
// C (2): ASIN
|
||||
// D (3): Cost
|
||||
// E (4): Clicks
|
||||
// F (5): Impressions
|
||||
// G (6): CPC
|
||||
// H (7): CTR %
|
||||
// I (8): ACOS %
|
||||
// J (9): Conversions (30d)
|
||||
// K (10): Units (30d)
|
||||
// L (11): Sales (30d)
|
||||
|
||||
const countryRaw = row[0];
|
||||
const weekRaw = row[1];
|
||||
const asin = row[2];
|
||||
const costRaw = row[3];
|
||||
const clicksRaw = row[4];
|
||||
const impressionsRaw = row[5];
|
||||
const cpcRaw = row[6];
|
||||
const ctrRaw = row[7];
|
||||
const acosRaw = row[8];
|
||||
const conversionsRaw = row[9];
|
||||
const unitsRaw = row[10];
|
||||
const salesRaw = row[11];
|
||||
|
||||
if (!asin || !countryRaw || weekRaw === undefined) continue;
|
||||
if (!asin || !countryRaw || weekRaw === undefined || weekRaw === '') continue;
|
||||
|
||||
const weekNum = parseInt(String(weekRaw));
|
||||
if (isNaN(weekNum) || weekNum < 1 || weekNum > 53) continue;
|
||||
@@ -511,42 +493,28 @@ export const processAdsExcel = async (fileOrBuffer: File | ArrayBuffer): Promise
|
||||
}
|
||||
|
||||
const worksheet = workbook.Sheets[sheetName];
|
||||
// Use header: 1 to get array of arrays (row-based)
|
||||
const jsonData: any[][] = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: "" });
|
||||
// Use default format (header mapping) instead of array rows
|
||||
const jsonData: any[] = XLSX.utils.sheet_to_json(worksheet, { defval: "" });
|
||||
|
||||
console.log(`Processing sheet ${sheetName}: ${jsonData.length} rows`);
|
||||
|
||||
// Skip header row (index 0), process data rows
|
||||
for (let i = 1; i < jsonData.length; i++) {
|
||||
// No need to skip index 0 since headers are mapped as keys automatically
|
||||
for (let i = 0; i < jsonData.length; i++) {
|
||||
const row = jsonData[i];
|
||||
if (!row || row.length < 12) continue;
|
||||
if (!row || Object.keys(row).length < 5) continue;
|
||||
|
||||
// Column mapping for Ads Weekly.xlsx:
|
||||
// A (0): Country
|
||||
// B (1): Week
|
||||
// C (2): ASIN
|
||||
// D (3): Cost
|
||||
// E (4): Clicks
|
||||
// F (5): Impressions
|
||||
// G (6): CPC
|
||||
// H (7): CTR %
|
||||
// I (8): ACOS %
|
||||
// J (9): Conversions (30d)
|
||||
// K (10): Units (30d)
|
||||
// L (11): Sales (30d)
|
||||
|
||||
const countryRaw = row[0];
|
||||
const weekRaw = row[1];
|
||||
const asin = row[2];
|
||||
const costRaw = row[3];
|
||||
const clicksRaw = row[4];
|
||||
const impressionsRaw = row[5];
|
||||
const cpcRaw = row[6];
|
||||
const ctrRaw = row[7];
|
||||
const acosRaw = row[8];
|
||||
const conversionsRaw = row[9];
|
||||
const unitsRaw = row[10];
|
||||
const salesRaw = row[11];
|
||||
const countryRaw = getColumnValue(row, ['country', 'marketplace', 'portfolio', 'customer', 'kunde']);
|
||||
const weekRaw = getColumnValue(row, ['week', 'woche', 'semana']);
|
||||
const asin = getColumnValue(row, ['asin']);
|
||||
const costRaw = getColumnValue(row, ['cost', 'spend', 'ausgaben', 'gasto', 'coste', 'ad spend']);
|
||||
const clicksRaw = getColumnValue(row, ['clicks', 'klicks', 'clics']);
|
||||
const impressionsRaw = getColumnValue(row, ['impressions', 'impresiones', 'imp']);
|
||||
const cpcRaw = getColumnValue(row, ['cpc', 'cost-per-click', 'coste por clic']);
|
||||
const ctrRaw = getColumnValue(row, ['ctr', 'click-through rate', 'click-through-rate', 'click through rate']);
|
||||
const acosRaw = getColumnValue(row, ['acos', 'advertising cost of sales', 'aCOS']);
|
||||
const conversionsRaw = getColumnValue(row, ['conversions', 'konversionen', 'orders', 'pedidos', 'total orders']);
|
||||
const unitsRaw = getColumnValue(row, ['units', 'einheiten', 'unidades', 'units sold', 'total units']);
|
||||
const salesRaw = getColumnValue(row, ['sales', 'umsatz', 'ventas', 'ad sales', 'total sales', 'sales (30d)']);
|
||||
|
||||
// Skip if missing essential data
|
||||
if (!asin || !countryRaw || weekRaw === undefined || weekRaw === '') continue;
|
||||
|
||||
Reference in New Issue
Block a user