diff --git a/components/timeshift-spreadsheet.tsx b/components/timeshift-spreadsheet.tsx index 3c136cc..2ba017e 100644 --- a/components/timeshift-spreadsheet.tsx +++ b/components/timeshift-spreadsheet.tsx @@ -304,18 +304,18 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP styles[`${colLetter}1`] = "height: 97px;" } - // Make day names row (row 2) taller and add top border from column B onwards (except last two columns) + // Make day names row (row 2) taller and add top and left borders from column B onwards (except last two columns) for (let col = 0; col < (data[0]?.length || 0); col++) { const colLetter = getExcelColumnName(col) if (col === 0) { // First column (A) - just height styles[`${colLetter}2`] = "height: 50px;" } else if (colLetter === 'BZ' || colLetter === 'CA') { - // Last two columns (BZ, CA) - height only, no top border + // Last two columns (BZ, CA) - height only, no borders styles[`${colLetter}2`] = "height: 50px;" } else { - // All other columns (B onwards except BZ, CA) - height + top border - styles[`${colLetter}2`] = "height: 50px; border-top: 1px solid #000000;" + // All other columns (B onwards except BZ, CA) - height + top and left borders + styles[`${colLetter}2`] = "height: 50px; border-top: 1px solid #000000; border-left: 1px solid #000000;" } } @@ -386,18 +386,20 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP }) const config = { - data: data || [], - columns: columns || [], + data, + columns, minDimensions: [data[0]?.length || 8, Math.max(data.length + 3, 10)], allowInsertRow: true, allowInsertColumn: false, allowDeleteRow: true, allowDeleteColumn: false, - contextMenu: true, + contextMenu: function(obj: any, x: number, y: number) { + return [] // Empty context menu to avoid issues + }, tableOverflow: true, tableWidth: "100%", tableHeight: "500px", - style: styles || {}, + style: styles, onchange: (instance: any, cell: HTMLElement, x: number, y: number, value: string) => { console.log("onChange triggered:", { x, y, value, isMerging: isMergingRef.current }) @@ -424,29 +426,36 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const rows = table.querySelectorAll('tr') if (rows[0]) { const cells = rows[0].querySelectorAll('td') - let targetCell = cells[x + 1] as HTMLElement // +1 because first cell is row number - console.log("Initial target cell found:", !!targetCell, "Cell display:", targetCell?.style.display, "Target cell:", targetCell) + const targetX = parseInt(String(x)) + let targetCell = cells[targetX + 1] as HTMLElement // +1 because first cell is row number + console.log("Initial target cell found:", !!targetCell, "Cell display:", targetCell?.style.display, "Target X:", targetX) - // Handle both hidden and visible cells + // Handle both merged and non-merged cells if (targetCell) { + // If target cell is hidden (part of a merge), find the visible merged cell if (targetCell.style.display === 'none') { console.log("🔍 Target cell is hidden, finding visible merged cell...") - const targetX = parseInt(String(x)) - // For merged cells, find the visible cell that represents this position + // Look for visible merged cells that cover this position let foundCell = null - // Look for visible cells around this position + // Search all visible cells to find which one covers our position for (let i = 1; i < cells.length; i++) { const cell = cells[i] as HTMLElement - if (cell && cell.style.display !== 'none') { - const cellX = parseInt(cell.getAttribute('data-x') || '0') - const cellSpan = cell.colSpan || 1 + if (cell && cell.style.display !== 'none' && cell.colSpan && cell.colSpan > 1) { + // Get the starting column of this merged cell + const cellIndex = i - 1 // Subtract 1 for row number cell + const cellSpan = cell.colSpan - // Check if this visible cell covers our target position - if (cellX <= targetX && targetX < cellX + cellSpan) { + // Check if our target position falls within this merged cell's span + if (cellIndex <= targetX && targetX < cellIndex + cellSpan) { foundCell = cell - console.log("🎯 Found covering visible cell:", foundCell, "covers position", targetX) + console.log("🎯 Found covering merged cell:", { + cellIndex, + cellSpan, + targetX, + covers: `${cellIndex} to ${cellIndex + cellSpan - 1}` + }) break } } @@ -454,9 +463,11 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP if (foundCell) { targetCell = foundCell + console.log("✅ Using merged cell for rotation") } else { - console.warn("❌ Could not find visible cell for hidden position") - return // Skip if we can't find a visible cell + console.warn("❌ Could not find visible merged cell for position", targetX) + // Try to use the target cell anyway, even if hidden + console.log("🔄 Attempting to use hidden cell directly") } } else { console.log("✅ Target cell is visible, using directly") @@ -465,14 +476,13 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP if (targetCell) { const displayValue = value !== undefined && value !== null ? String(value).trim() : '' - console.log("Processing value:", displayValue) - console.log("Target cell before rotation:", targetCell.outerHTML) + console.log("Processing value:", displayValue, "for cell at position:", targetX) if (displayValue) { // Force clear any existing content first targetCell.innerHTML = '' - // Apply rotation with improved styling - using important to override jspreadsheet styles + // Apply rotation with improved styling const rotatedDiv = document.createElement('div') rotatedDiv.style.cssText = ` transform: rotate(-90deg) !important; @@ -493,14 +503,13 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP targetCell.appendChild(rotatedDiv) console.log("✅ Rotation applied successfully to cell with value:", displayValue) - console.log("Target cell after rotation:", targetCell.outerHTML) } else { // Clear cell content but maintain structure targetCell.innerHTML = '' console.log("✅ Cleared cell content") } } else { - console.warn("❌ Target cell not found at index:", x + 1) + console.warn("❌ Target cell not found at index:", targetX + 1) } } else { console.warn("❌ First row not found") @@ -517,13 +526,20 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP } console.log("Config validation passed, creating jspreadsheet instance...") + console.log("Full config object:", JSON.stringify(config, null, 2)) + console.log("Config keys:", Object.keys(config)) + console.log("Data sample:", data.slice(0, 2)) + console.log("Columns sample:", columns.slice(0, 3)) try { jspreadsheetInstance.current = (jexcelLib as (el: HTMLElement, config: unknown) => unknown)(spreadsheetRef.current, config) console.log("jspreadsheet initialized:", !!jspreadsheetInstance.current) } catch (error) { console.error("Error initializing jspreadsheet:", error) - console.error("Config that caused error:", config) + console.error("Config that caused error:", JSON.stringify(config, null, 2)) + console.error("Config keys that caused error:", Object.keys(config)) + console.error("Data that caused error:", data?.slice(0, 2)) + console.error("Columns that caused error:", columns?.slice(0, 3)) isInitializingRef.current = false return } @@ -540,53 +556,57 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const cells = firstRow.querySelectorAll('td') cells.forEach((cell, index) => { if (index > 0) { // Skip row number cell - // Listen for input events on the cell - cell.addEventListener('input', (e) => { - const target = e.target as HTMLElement - const value = target.textContent || target.innerText || '' - console.log("🎯 Direct input event on first row cell:", { index, value }) - + const cellElement = cell as HTMLElement + + // Create rotation function for reuse + const applyRotation = (target: HTMLElement, value: string) => { if (value.trim()) { requestAnimationFrame(() => { target.innerHTML = `