diff --git a/src/lib/components/wizard/StepColumnMap.svelte b/src/lib/components/wizard/StepColumnMap.svelte index 5ec41fe..48e4e52 100644 --- a/src/lib/components/wizard/StepColumnMap.svelte +++ b/src/lib/components/wizard/StepColumnMap.svelte @@ -695,13 +695,23 @@ {/if} -
+ +
+ +
diff --git a/src/lib/components/wizard/StepRowFilter.svelte b/src/lib/components/wizard/StepRowFilter.svelte index dcf74f8..9bbb0f2 100644 --- a/src/lib/components/wizard/StepRowFilter.svelte +++ b/src/lib/components/wizard/StepRowFilter.svelte @@ -2,6 +2,7 @@ import { selectedSheet, columnMapping, rawSheetData, filteredSheetData, currentStep, sheetData } from '$lib/stores'; import type { RowData } from '$lib/stores'; import { onMount } from 'svelte'; + import { getSheetNames, getSheetData } from '$lib/google'; let searchTerm = ''; let sortColumn = ''; @@ -11,6 +12,7 @@ let processedData: any[] = []; let filteredData: any[] = []; let headers: string[] = []; + let isLoading = false; $: { // Filter data based on search term @@ -46,68 +48,87 @@ processSheetData(); }); - function processSheetData() { - if (!$rawSheetData || $rawSheetData.length === 0 || !$columnMapping) { - return; + // Fetch raw sheet data from Google Sheets if not already loaded + async function fetchRawSheetData() { + if (!$rawSheetData || $rawSheetData.length === 0) { + if (!$selectedSheet) 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); + rawSheetData.set(data); } + } - // Get headers from the mapping - headers = Object.keys($columnMapping); - - // Process the data starting from row 2 (skip header row) - processedData = $rawSheetData.slice(1).map((row, index) => { - const processedRow: any = { - _rowIndex: index + 1, // Store original row index - _isValid: true - }; + async function processSheetData() { + isLoading = true; + try { + await fetchRawSheetData(); + if (!$rawSheetData || $rawSheetData.length === 0 || !$columnMapping) { + return; + } - // Map each column according to the column mapping - for (const [field, columnIndex] of Object.entries($columnMapping)) { - if (columnIndex !== -1 && columnIndex !== undefined && columnIndex < row.length) { - processedRow[field] = row[columnIndex] || ''; - } else { - processedRow[field] = ''; - // Only mark as invalid if it's a required field - if (field !== 'alreadyPrinted') { - processedRow._isValid = false; + // Get headers from the mapping + headers = Object.keys($columnMapping); + + // Process the data starting from row 2 (skip header row) + processedData = $rawSheetData.slice(1).map((row, index) => { + const processedRow: any = { + _rowIndex: index + 1, // Store original row index + _isValid: true + }; + + // Map each column according to the column mapping + for (const [field, columnIndex] of Object.entries($columnMapping)) { + if (columnIndex !== -1 && columnIndex !== undefined && columnIndex < row.length) { + processedRow[field] = row[columnIndex] || ''; + } else { + processedRow[field] = ''; + // Only mark as invalid if it's a required field + if (field !== 'alreadyPrinted') { + processedRow._isValid = false; + } } } - } - // Check if all required fields have values (excluding alreadyPrinted) - const requiredFields = ['name', 'surname', 'nationality', 'birthday', 'pictureUrl']; - const hasAllRequiredFields = requiredFields.every(field => - processedRow[field] && String(processedRow[field]).trim() !== '' + // Check if all required fields have values (excluding alreadyPrinted) + const requiredFields = ['name', 'surname', 'nationality', 'birthday', 'pictureUrl']; + const hasAllRequiredFields = requiredFields.every(field => + processedRow[field] && String(processedRow[field]).trim() !== '' + ); + + if (!hasAllRequiredFields) { + processedRow._isValid = false; + } + + return processedRow; + }); + + // Initially select rows based on validity and "Already Printed" status + selectedRows = new Set( + processedData + .filter(row => { + if (!row._isValid) return false; + + // Check "Already Printed" column value + const alreadyPrinted = row.alreadyPrinted; + if (alreadyPrinted) { + const value = String(alreadyPrinted).toLowerCase().trim(); + // If the value is "true", "yes", "1", or any truthy value, don't select + return !(value === 'true' || value === 'yes' || value === '1' || value === 'x'); + } + + // If empty or falsy, select the row + return true; + }) + .map(row => row._rowIndex) ); - if (!hasAllRequiredFields) { - processedRow._isValid = false; - } - - return processedRow; - }); - - // Initially select rows based on validity and "Already Printed" status - selectedRows = new Set( - processedData - .filter(row => { - if (!row._isValid) return false; - - // Check "Already Printed" column value - const alreadyPrinted = row.alreadyPrinted; - if (alreadyPrinted) { - const value = String(alreadyPrinted).toLowerCase().trim(); - // If the value is "true", "yes", "1", or any truthy value, don't select - return !(value === 'true' || value === 'yes' || value === '1' || value === 'x'); - } - - // If empty or falsy, select the row - return true; - }) - .map(row => row._rowIndex) - ); - - updateSelectAllState(); + updateSelectAllState(); + } finally { + isLoading = false; + } } function toggleRowSelection(rowIndex: number) { @@ -193,6 +214,8 @@ const row = processedData.find(r => r._rowIndex === rowIndex); return row && row._isValid; }).length; + // Allow proceeding only if at least one valid row is selected + $: canProceed = selectedValidCount > 0;
@@ -244,17 +267,40 @@
-
+
Total rows: {processedData.length} Valid rows: {processedData.filter(row => row._isValid).length} - Already printed: {processedData.filter(row => isRowAlreadyPrinted(row)).length} + Printed: {processedData.filter(row => isRowAlreadyPrinted(row)).length} Filtered rows: {filteredData.length} Selected: {selectedValidCount} +
-
+
+ {#if isLoading} +
+ + + + +
+ {/if} {#if filteredData.length === 0}
@@ -275,16 +321,16 @@ - {#each headers as header} + {#each headers.filter(h => h !== 'alreadyPrinted') as header} handleSort(header)} + onclick={() => handleSort(header)} >
{getFieldLabel(header)} @@ -300,7 +346,7 @@
{/each} - + Status @@ -316,37 +362,21 @@ toggleRowSelection(row._rowIndex)} + onchange={() => toggleRowSelection(row._rowIndex)} class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" - disabled={isRowAlreadyPrinted(row)} /> - {#if isRowAlreadyPrinted(row)} -
Already printed
- {/if} {:else}
{/if} - {#each headers as header} + {#each headers.filter(h => h !== 'alreadyPrinted') as header} - {#if header === 'alreadyPrinted'} - {#if isRowAlreadyPrinted(row)} - - Already Printed - - {:else} - - Not Printed - - {/if} - {:else} - {row[header] || ''} - {/if} + {row[header] || ''} {/each} - +
@@ -390,13 +420,21 @@ {/if} -
+
+