Dynamically detect ASIN column from Excel headers

This commit is contained in:
Christian Vidal Wolf
2026-04-09 16:33:05 +02:00
parent 4a6440f58a
commit 22dfa30708
3 changed files with 18 additions and 8 deletions
+8 -3
View File
@@ -33,7 +33,8 @@ export default function App() {
data: [], data: [],
fileName: '', fileName: '',
fileDate: null, fileDate: null,
hasUnsavedChanges: false hasUnsavedChanges: false,
asinColumnIndex: null
}); });
const [activeModule, setActiveModule] = useState<'descriptions' | 'article_details' | 'matrix' | 'dimensions' | 'pricing' | 'pending_validation' | 'history'>('descriptions'); const [activeModule, setActiveModule] = useState<'descriptions' | 'article_details' | 'matrix' | 'dimensions' | 'pricing' | 'pending_validation' | 'history'>('descriptions');
const [undoHistory, setUndoHistory] = useState<{ data: ExcelRow[], message: string }[]>([]); const [undoHistory, setUndoHistory] = useState<{ data: ExcelRow[], message: string }[]>([]);
@@ -135,7 +136,8 @@ export default function App() {
data: processedRows, data: processedRows,
fileName: 'Data-Matrix.xlsx (Cloud Sync)', fileName: 'Data-Matrix.xlsx (Cloud Sync)',
fileDate: new Date(), fileDate: new Date(),
hasUnsavedChanges: false hasUnsavedChanges: false,
asinColumnIndex: asinIdx !== -1 ? asinIdx : null
}); });
setActiveModule('descriptions'); setActiveModule('descriptions');
} }
@@ -219,7 +221,8 @@ export default function App() {
data: processedRows, data: processedRows,
fileName: file.name, fileName: file.name,
fileDate: new Date(), fileDate: new Date(),
hasUnsavedChanges: false hasUnsavedChanges: false,
asinColumnIndex: null
}); });
setActiveModule('descriptions'); setActiveModule('descriptions');
} }
@@ -411,6 +414,8 @@ export default function App() {
{activeModule === 'descriptions' && ( {activeModule === 'descriptions' && (
<ProductDescriptions <ProductDescriptions
data={appState.data} data={appState.data}
headers={appState.headers}
asinColumnIndex={appState.asinColumnIndex}
onEdit={(index) => setEditingRowIndex(index)} onEdit={(index) => setEditingRowIndex(index)}
rowStatuses={rowStatuses} rowStatuses={rowStatuses}
/> />
+9 -5
View File
@@ -6,6 +6,8 @@ import { ColumnFilterPopover } from './ColumnFilterPopover';
interface ProductDescriptionsProps { interface ProductDescriptionsProps {
data: ExcelRow[]; data: ExcelRow[];
headers: string[];
asinColumnIndex: number | null;
onEdit: (index: number) => void; onEdit: (index: number) => void;
rowStatuses: Record<string, string>; rowStatuses: Record<string, string>;
} }
@@ -15,7 +17,7 @@ type TabType = 'all' | 'missingLongDE' | 'missingLongEN' | 'missingShortDE' | 'm
// Description columns that should only have Present/Missing filters // Description columns that should only have Present/Missing filters
const DESCRIPTION_COLUMNS = [COLUMNS.LONG_DE, COLUMNS.LONG_EN, COLUMNS.SHORT_DE, COLUMNS.SHORT_EN]; const DESCRIPTION_COLUMNS = [COLUMNS.LONG_DE, COLUMNS.LONG_EN, COLUMNS.SHORT_DE, COLUMNS.SHORT_EN];
export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescriptionsProps) { export function ProductDescriptions({ data, headers, asinColumnIndex, onEdit, rowStatuses }: ProductDescriptionsProps) {
const [activeTab, setActiveTab] = useState<TabType>('all'); const [activeTab, setActiveTab] = useState<TabType>('all');
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const [lineFilter, setLineFilter] = useState(''); const [lineFilter, setLineFilter] = useState('');
@@ -29,7 +31,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
const [columnWidths, setColumnWidths] = useState<Record<number, number>>({ const [columnWidths, setColumnWidths] = useState<Record<number, number>>({
[COLUMNS.ARTICLE_NO]: 100, [COLUMNS.ARTICLE_NO]: 100,
[COLUMNS.ARTICLE_NAME]: 250, [COLUMNS.ARTICLE_NAME]: 250,
[COLUMNS.ASIN]: 150, [COLUMNS.ASIN]: asinColumnIndex !== null ? 150 : 0,
[COLUMNS.LINE]: 80, [COLUMNS.LINE]: 80,
[COLUMNS.LICENSE]: 120, [COLUMNS.LICENSE]: 120,
[COLUMNS.CLASSIFICATION]: 100, [COLUMNS.CLASSIFICATION]: 100,
@@ -285,7 +287,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
{[ {[
{ col: COLUMNS.ARTICLE_NO, label: 'Article No.' }, { col: COLUMNS.ARTICLE_NO, label: 'Article No.' },
{ col: COLUMNS.ARTICLE_NAME, label: 'Article Name' }, { col: COLUMNS.ARTICLE_NAME, label: 'Article Name' },
{ col: COLUMNS.ASIN, label: 'ASIN' }, ...(asinColumnIndex !== null ? [{ col: asinColumnIndex, label: 'ASIN' }] : []),
{ col: COLUMNS.LINE, label: 'Line' }, { col: COLUMNS.LINE, label: 'Line' },
{ col: COLUMNS.LICENSE, label: 'License' }, { col: COLUMNS.LICENSE, label: 'License' },
{ col: COLUMNS.CLASSIFICATION, label: 'Classification' }, { col: COLUMNS.CLASSIFICATION, label: 'Classification' },
@@ -363,7 +365,9 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
> >
<td className="px-4 py-3 font-mono text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NO] }}>{row[COLUMNS.ARTICLE_NO]}</td> <td className="px-4 py-3 font-mono text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NO] }}>{row[COLUMNS.ARTICLE_NO]}</td>
<td className="px-4 py-3 font-medium text-white truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NAME] }} title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td> <td className="px-4 py-3 font-medium text-white truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NAME] }} title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
<td className="px-4 py-3 font-mono text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.ASIN] }} title={row[COLUMNS.ASIN]}>{row[COLUMNS.ASIN] || '—'}</td> {asinColumnIndex !== null && (
<td className="px-4 py-3 font-mono text-slate-300 text-xs truncate" style={{ width: columnWidths[asinColumnIndex] || 150 }} title={row[asinColumnIndex]}>{row[asinColumnIndex] || '—'}</td>
)}
<td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LINE] }}>{row[COLUMNS.LINE]}</td> <td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LINE] }}>{row[COLUMNS.LINE]}</td>
<td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LICENSE] }} title={row[COLUMNS.LICENSE]}>{row[COLUMNS.LICENSE] || '—'}</td> <td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LICENSE] }} title={row[COLUMNS.LICENSE]}>{row[COLUMNS.LICENSE] || '—'}</td>
<td className="px-4 py-3 truncate" style={{ width: columnWidths[COLUMNS.CLASSIFICATION] }}> <td className="px-4 py-3 truncate" style={{ width: columnWidths[COLUMNS.CLASSIFICATION] }}>
@@ -394,7 +398,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
})} })}
{paginatedData.length === 0 && ( {paginatedData.length === 0 && (
<tr> <tr>
<td colSpan={10} className="px-4 py-8 text-center text-slate-500"> <td colSpan={asinColumnIndex !== null ? 10 : 9} className="px-4 py-8 text-center text-slate-500">
No products found matching the criteria. No products found matching the criteria.
</td> </td>
</tr> </tr>
+1
View File
@@ -6,6 +6,7 @@ export interface AppState {
fileName: string; fileName: string;
fileDate: Date | null; fileDate: Date | null;
hasUnsavedChanges: boolean; hasUnsavedChanges: boolean;
asinColumnIndex: number | null;
} }
export const COLUMNS = { export const COLUMNS = {