diff --git a/src/components/DimensionsView.tsx b/src/components/DimensionsView.tsx index dec2816..fe0a68d 100644 --- a/src/components/DimensionsView.tsx +++ b/src/components/DimensionsView.tsx @@ -46,7 +46,7 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat const [clusterSelections, setClusterSelections] = useState>>({}); const [clusterSyncTargets, setClusterSyncTargets] = useState>({}); const [pendingNearDupSync, setPendingNearDupSync] = useState<{ - clusterIndex: number; + clusterKey: string; targetGroupKey: string; selectedIndices: number[]; } | null>(null); @@ -120,7 +120,12 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat const filteredGroups = useMemo(() => { let result = groups; - if (showOnlyInconsistent) result = result.filter(g => g.isInconsistent); + if (showOnlyInconsistent) { + result = result.filter(g => + g.isInconsistent || + g.rows.some(({ row }) => rowStatuses[String(row[COLUMNS.ARTICLE_NO])] === 'pending') + ); + } if (search || lineFilter.length > 0 || classFilter.length > 0) { const s = search.toLowerCase(); @@ -137,7 +142,7 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat } return result; - }, [groups, showOnlyInconsistent, search, lineFilter, classFilter]); + }, [groups, showOnlyInconsistent, search, lineFilter, classFilter, rowStatuses]); const uniqueLines = useMemo(() => Array.from(new Set(data.map(r => String(r[COLUMNS.LINE] || '')))).sort() @@ -217,9 +222,10 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat const executeNearDupSync = async () => { if (!pendingNearDupSync) return; - const { clusterIndex, targetGroupKey, selectedIndices } = pendingNearDupSync; + const { clusterKey, targetGroupKey, selectedIndices } = pendingNearDupSync; - const cluster = nearDuplicateClusters[clusterIndex]; + const cluster = nearDuplicateClusters.find(c => c.groups[0].key === clusterKey); + if (!cluster) return; const targetGroup = cluster.groups.find(g => g.key === targetGroupKey); if (!targetGroup) return; @@ -242,7 +248,7 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat setClusterSelections(prev => { const next = { ...prev }; - delete next[clusterIndex]; + delete next[pendingNearDupSync.clusterKey]; return next; }); }; @@ -395,11 +401,12 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat {nearDuplicateClusters.map((cluster, ci) => { const allClusterRows = cluster.groups.flatMap(g => g.rows); - const selection = clusterSelections[ci] ?? new Set(); - const targetKey = clusterSyncTargets[ci] ?? cluster.groups[0].key; + const clusterKey = cluster.groups[0].key; + const selection = clusterSelections[clusterKey] ?? new Set(); + const targetKey = clusterSyncTargets[clusterKey] ?? cluster.groups[0].key; return ( -
+
{selection.size > 0 && (
- {/* Flat product list */}
{allClusterRows.map(({ row, index }) => { const isSelected = selection.has(index); @@ -476,17 +481,16 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat isSelected && "bg-violet-500/10" )} onClick={() => setClusterSelections(prev => { - const current = new Set(prev[ci] ?? []); + const current = new Set(prev[clusterKey] ?? []); if (current.has(index)) current.delete(index); else current.add(index); - return { ...prev, [ci]: current }; + return { ...prev, [clusterKey]: current }; })} > {}} - onClick={e => e.stopPropagation()} - className="rounded border-slate-600 bg-slate-700 text-violet-600 focus:ring-violet-500 shrink-0" + readOnly + className="rounded border-slate-600 bg-slate-700 text-violet-600 focus:ring-violet-500 shrink-0 pointer-events-none" />
@@ -510,11 +514,14 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat )}
- {filteredGroups.map(group => ( -
+ {filteredGroups.map(group => { + const hasPending = group.rows.some(({ row }) => rowStatuses[String(row[COLUMNS.ARTICLE_NO])] === 'pending'); + return ( +
{group.rows.length} product{group.rows.length !== 1 ? 's' : ''} in this dimension group @@ -677,7 +689,8 @@ export function DimensionsView({ data, headers, onEdit, onSaveRow, onCaptureStat
)}
- ))} + ); + })} {filteredGroups.length === 0 && (
diff --git a/src/lib/supabase.ts b/src/lib/supabase.ts index 223d2ad..a501b49 100644 --- a/src/lib/supabase.ts +++ b/src/lib/supabase.ts @@ -21,6 +21,9 @@ export async function saveRowToSupabase(articleNo: string, rowData: ExcelRow) { }); if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + console.error('Initial PATCH failed:', response.status, errorData); + // If PATCH didn't find the record, try UPSERT const upsertResponse = await fetch(`${SUPABASE_URL}/rest/v1/products_sync`, { method: 'POST', @@ -37,7 +40,13 @@ export async function saveRowToSupabase(articleNo: string, rowData: ExcelRow) { updated_at: new Date().toISOString() }) }); - return upsertResponse.ok; + + if (!upsertResponse.ok) { + const upsertError = await upsertResponse.json().catch(() => ({})); + console.error('UPSERT failed:', upsertResponse.status, upsertError); + return false; + } + return true; } return true; } catch (error) {