diff --git a/src/lib/components/wizard/StepRowFilter.svelte b/src/lib/components/wizard/StepRowFilter.svelte index 1009418..5ffcd8f 100644 --- a/src/lib/components/wizard/StepRowFilter.svelte +++ b/src/lib/components/wizard/StepRowFilter.svelte @@ -4,8 +4,7 @@ columnMapping, rawSheetData, filteredSheetData, - currentStep, - sheetData + currentStep } from '$lib/stores'; import Navigator from './subcomponents/Navigator.svelte'; import { onMount } from 'svelte'; @@ -16,30 +15,52 @@ let sortDirection: 'asc' | 'desc' = 'asc'; let selectedRows = new Set(); let selectAll = false; - let processedData: any[] = []; - let filteredData: any[] = []; + let processedData = $state([]); let headers: string[] = []; - let isLoading = false; + let isLoading = $state(false); + let showAlreadyPrinted = $state(false); - $: { - // Filter data based on search term + // Use $state for displayData instead of $derived to avoid TypeScript errors + let displayData = $state([]); + + // Update displayData whenever relevant values change + $effect(() => { + // Debug log at the start + console.log('Updating displayData from processedData:', processedData); + + // If processedData is empty, return empty array + if (!processedData || !processedData.length) { + displayData = []; + return; + } + + // Clone array to avoid mutations + let data = [...processedData]; + console.log('Initial data length:', data.length); + + // 1. Filter by search term if (searchTerm.trim()) { - filteredData = processedData.filter((row) => + data = data.filter((row) => Object.values(row).some((value) => - String(value).toLowerCase().includes(searchTerm.toLowerCase()) + String(value) + .toLowerCase() + .includes(searchTerm.toLowerCase()) ) ); - } else { - filteredData = processedData; + console.log('After search term filter:', data.length); } - } - $: { - // Sort data if sort column is selected - if (sortColumn && filteredData.length > 0) { - filteredData = [...filteredData].sort((a, b) => { - const aVal = String(a[sortColumn]).toLowerCase(); - const bVal = String(b[sortColumn]).toLowerCase(); + // 2. Filter out already printed rows if collapsed + if (!showAlreadyPrinted) { + data = data.filter((row) => !isRowAlreadyPrinted(row)); + console.log('After already printed filter:', data.length); + } + + // 3. Sort the data + if (sortColumn) { + data = [...data].sort((a, b) => { + const aVal = String(a[sortColumn] || '').toLowerCase(); + const bVal = String(b[sortColumn] || '').toLowerCase(); if (sortDirection === 'asc') { return aVal.localeCompare(bVal); @@ -48,7 +69,10 @@ } }); } - } + + console.log('Final filtered data:', data); + displayData = data; + }); onMount(() => { console.log('StepRowFilter mounted'); @@ -57,13 +81,25 @@ // Fetch raw sheet data from Google Sheets if not already loaded async function fetchRawSheetData() { - console.log("Fetching raw sheet data..."); - const sheetNames = await getSheetNames($selectedSheet.spreadsheetId); - if (sheetNames.length === 0) return; - const sheetName = sheetNames[0]; - const range = `${sheetName}!A:Z`; - const data = await getSheetData($selectedSheet.spreadsheetId, range); - rawSheetData.set(data); + console.log('Fetching raw sheet data...'); + try { + if (!$selectedSheet) { + console.error('No sheet selected'); + return; + } + + const sheetNames = await getSheetNames($selectedSheet.spreadsheetId); + if (sheetNames.length === 0) return; + const sheetName = sheetNames[0]; + const range = `${sheetName}!A:Z`; + const data = await getSheetData($selectedSheet.spreadsheetId, range); + console.log('Fetched data:', data); + rawSheetData.set(data); + } catch (e) { + console.error('Error fetching raw sheet data:', e); + // Re-throw the error to be caught by the caller + throw e; + } } async function processSheetData() { @@ -74,6 +110,13 @@ await fetchRawSheetData(); + // Debug logging + console.log('Raw sheet data:', $rawSheetData); + console.log('Column mapping:', $columnMapping); + + // Clear existing state before processing new data + selectedRows = new Set(); + // Process the data starting from row 2 (skip header row) processedData = $rawSheetData.slice(1).map((row, index) => { const processedRow: any = { @@ -119,9 +162,20 @@ }); const initialSelection = rowsToConsider.map((row) => row._rowIndex); - selectedRows = new Set(initialSelection); + // Make sure we create a completely new Set for reactivity + selectedRows = new Set([...initialSelection]); + // Update UI state updateSelectAllState(); + updateSelectedValidCount(); + + // Debug logging + console.log('Processed data:', processedData); + console.log('Display data:', displayData); + console.log('Selected rows:', selectedRows); + console.log('Selected valid count after initialization:', selectedValidCount); + } catch (e) { + console.error('Error processing sheet data:', e); } finally { isLoading = false; } @@ -133,43 +187,62 @@ } else { selectedRows.add(rowIndex); } - selectedRows = new Set(selectedRows); // Trigger reactivity + // Force reactivity with new Set + selectedRows = new Set([...selectedRows]); + console.log('Toggled row selection, new selectedRows size:', selectedRows.size); updateSelectAllState(); + updateSelectedValidCount(); + console.log('After toggle - canProceed:', canProceed); + console.log('After toggle - selectedValidCount > 0:', selectedValidCount > 0); + console.log('After toggle - selectedValidCount:', selectedValidCount); } function toggleSelectAll() { - if (selectAll) { - // Deselect all visible valid rows - filteredData.forEach((row) => { + // Toggle selectAll state first + selectAll = !selectAll; + console.log('Toggle select all clicked, new state:', selectAll); + + if (!selectAll) { + // If now unchecked, deselect all visible valid rows + displayData.forEach((row) => { if (row._isValid) { selectedRows.delete(row._rowIndex); } }); } else { - // Select all visible valid rows that aren't already printed - const rowsToSelect = filteredData.filter( - (row) => row._isValid && !isRowAlreadyPrinted(row) && !selectedRows.has(row._rowIndex) - ); - - for (const row of rowsToSelect) { - selectedRows.add(row._rowIndex); - } + // If now checked, select all visible valid rows + displayData.forEach((row) => { + if (row._isValid) { + selectedRows.add(row._rowIndex); + } + }); } - selectedRows = new Set(selectedRows); - updateSelectAllState(); + + // Force reactivity with new Set + selectedRows = new Set([...selectedRows]); + console.log('Toggled select all, new selectedRows size:', selectedRows.size); + updateSelectedValidCount(); + console.log('Selected valid count after toggleSelectAll:', selectedValidCount); } function updateSelectAllState() { - const visibleValidUnprintedRows = filteredData.filter( - (row) => row._isValid && !isRowAlreadyPrinted(row) - ); - const selectedVisibleValidUnprintedRows = visibleValidUnprintedRows.filter((row) => - selectedRows.has(row._rowIndex) - ); - - selectAll = - visibleValidUnprintedRows.length > 0 && - selectedVisibleValidUnprintedRows.length === visibleValidUnprintedRows.length; + // Find all valid rows that are currently visible + const visibleValidRows = displayData.filter(row => row._isValid); + + if (visibleValidRows.length === 0) { + // No valid rows to select + selectAll = false; + return; + } + + // Check if all visible valid rows are selected + const allSelected = visibleValidRows.every(row => selectedRows.has(row._rowIndex)); + + // Update selectAll state + selectAll = allSelected; + console.log('updateSelectAllState: selectAll =', selectAll, + ', visibleValidRows =', visibleValidRows.length, + ', selectedRows size =', selectedRows.size); } function handleSort(column: string) { @@ -211,12 +284,41 @@ filteredSheetData.set(selectedData); } - $: selectedValidCount = Array.from(selectedRows).filter((rowIndex) => { - const row = processedData.find((r) => r._rowIndex === rowIndex); - return row && row._isValid; - }).length; + // Use $state for selectedValidCount + let selectedValidCount = $state(0); + + // Create a dedicated function to recalculate selectedValidCount + function updateSelectedValidCount() { + // Get array of row indices + const rowIndices = Array.from(selectedRows); + console.log('Selected row indices:', rowIndices); + + // Count valid rows + let count = 0; + for (const rowIndex of rowIndices) { + // Find the row in processedData + const row = processedData.find(r => r._rowIndex === rowIndex); + if (row && row._isValid) { + count++; + } + } + + console.log('Setting selectedValidCount to:', count, 'from', selectedValidCount); + selectedValidCount = count; + } + + // Update count when selectedRows or processedData changes + $effect(() => { + // Track dependencies explicitly + const rowsSize = selectedRows.size; + const dataSize = processedData.length; + + console.log('Effect triggered - selectedRows size:', rowsSize, 'processedData size:', dataSize); + updateSelectedValidCount(); + }); + // Allow proceeding only if at least one valid row is selected - $: canProceed = selectedValidCount > 0; + let canProceed = $derived(selectedValidCount > 0);
@@ -269,41 +371,57 @@ Printed: {processedData.filter((row) => isRowAlreadyPrinted(row)).length} - Filtered rows: {filteredData.length} + Filtered rows: {displayData.length} Selected: {selectedValidCount} - + +
+ + + +
- {#if filteredData.length === 0 && !isLoading} + {#if displayData.length === 0 && !isLoading}