From 318fef77aab4efe934a58fa5abad6c903b1d7265 Mon Sep 17 00:00:00 2001 From: Docker Config Backup Date: Wed, 30 Jul 2025 08:54:37 +0200 Subject: [PATCH] Save before creating restore point: Periodic backup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-saved at 2025-07-30 08:54:37 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- components/timeshift-spreadsheet.tsx | 76 ++++++++++++++++++++++++---- logs/auto-commit.log | 3 ++ logs/auto-commit.out.log | 3 ++ 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/components/timeshift-spreadsheet.tsx b/components/timeshift-spreadsheet.tsx index 2173a40..8dd5026 100644 --- a/components/timeshift-spreadsheet.tsx +++ b/components/timeshift-spreadsheet.tsx @@ -17,6 +17,8 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const jspreadsheetInstance = React.useRef(null) const isActiveRef = React.useRef(true) const isMergingRef = React.useRef(false) + const isInitializingRef = React.useRef(false) + const initTimeoutRef = React.useRef(null) const currentDate = new Date() const [selectedMonth, setSelectedMonth] = React.useState((currentDate.getMonth() + 1).toString()) const [selectedYear, setSelectedYear] = React.useState(currentDate.getFullYear().toString()) @@ -147,7 +149,33 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP React.useEffect(() => { console.log("useEffect triggered - Month:", selectedMonth, "Year:", selectedYear, "Force:", forceUpdate) - isActiveRef.current = true + + // Clear any existing timeout + if (initTimeoutRef.current) { + console.log("CLEARING: existing timeout, debouncing useEffect") + clearTimeout(initTimeoutRef.current) + } + + // Prevent multiple simultaneous initializations with immediate return + if (isInitializingRef.current) { + console.log("BLOCKED: useEffect - already initializing, skipping completely") + return + } + + console.log("DEBOUNCING: useEffect with 100ms delay") + + // Debounce the initialization to prevent rapid successive calls + initTimeoutRef.current = setTimeout(() => { + console.log("EXECUTING: debounced useEffect after delay") + + // Double-check we're still not initializing (could have started between timeout set and execution) + if (isInitializingRef.current) { + console.log("BLOCKED: Still initializing at timeout execution") + return + } + + isInitializingRef.current = true + isActiveRef.current = true const loadJSpreadsheet = async () => { console.log("Starting loadJSpreadsheet function") @@ -370,8 +398,8 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP if (!isActiveRef.current || !jspreadsheetInstance.current) return // Apply rotation to first row (y === 0) when text is entered - if (y === 0 && value && value.trim()) { - console.log("First row change detected, applying rotation...") + if (y === 0 && value !== undefined) { + console.log("First row change detected, applying rotation...", { x, y, value }) setTimeout(() => { if (!isActiveRef.current || !spreadsheetRef.current) return @@ -384,15 +412,24 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const targetCell = cells[x + 1] as HTMLElement // +1 because first cell is row number console.log("Target cell found:", !!targetCell, "Cell content:", targetCell?.textContent) if (targetCell) { - targetCell.innerHTML = `
${value}
` - console.log("Rotation applied to cell:", targetCell) + // Apply rotation even for empty values to maintain consistent styling + const displayValue = value && value.trim() ? value.trim() : '' + if (displayValue) { + targetCell.innerHTML = `
${displayValue}
` + console.log("Rotation applied to cell with value:", displayValue) + } else { + // Clear rotation for empty cells + targetCell.innerHTML = '' + targetCell.style.transform = 'none' + console.log("Cleared rotation for empty cell") + } } } } } catch (error) { console.error("Error applying rotation:", error) } - }, 100) + }, 50) // Reduced timeout for faster response } } }) @@ -477,6 +514,13 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP } }, 300) // Increased timeout to ensure spreadsheet is fully ready + // Clear initialization flag after successful setup - increased timeout to prevent rapid re-initializations + setTimeout(() => { + isInitializingRef.current = false + initTimeoutRef.current = null + console.log("Initialization completed, flag and timeout cleared") + }, 2000) // Extended to 2 seconds to ensure complete initialization + // Apply counter-clockwise rotation to data values only (exclude second column which contains field labels) setTimeout(() => { const table = spreadsheetRef.current?.querySelector('.jexcel tbody') @@ -484,8 +528,8 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const rows = table.querySelectorAll('tr') const totalCells = data[0]?.length || 0 - // Rotate data values in rows 2, 3, 4, 5, 6 (day names, year, month, day, shifts) - ;[1, 2, 3, 4, 5].forEach(rowIndex => { + // Rotate data values in rows 1, 2, 3, 4, 5, 6 (first row, day names, year, month, day, shifts) + ;[0, 1, 2, 3, 4, 5].forEach(rowIndex => { if (rows[rowIndex]) { const cells = rows[rowIndex].querySelectorAll('td') cells.forEach((cell, cellIndex) => { @@ -494,7 +538,9 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP const originalText = cell.textContent?.trim() if (originalText) { // Use 12px font for all rotated values (date values, day names, and shifts) - cell.innerHTML = `
${originalText}
` + // For first row (rowIndex 0), ensure width: 100% for better text display + const extraStyle = rowIndex === 0 ? ' width: 100%;' : '' + cell.innerHTML = `
${originalText}
` } } }) @@ -502,7 +548,7 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP }) // Make only "Pohotovost TKB" bold, keep other field labels regular and ensure they're not rotated - ;[0, 2, 3, 4, 5].forEach(rowIndex => { + ;[0, 1, 2, 3, 4, 5].forEach(rowIndex => { if (rows[rowIndex]) { const cells = rows[rowIndex].querySelectorAll('td') if (cells[1]) { // Second column (index 1) @@ -521,17 +567,27 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP } else { console.log("Cannot initialize - missing ref or jexcel library") + isInitializingRef.current = false } } console.log("Calling loadJSpreadsheet...") loadJSpreadsheet().catch(error => { console.error("Error in loadJSpreadsheet:", error) + isInitializingRef.current = false }) + + }, 100) // 100ms debounce delay return () => { + // Clear timeout on cleanup + if (initTimeoutRef.current) { + clearTimeout(initTimeoutRef.current) + initTimeoutRef.current = null + } isActiveRef.current = false isMergingRef.current = false + isInitializingRef.current = false if (jspreadsheetInstance.current) { jspreadsheetInstance.current.destroy() jspreadsheetInstance.current = null diff --git a/logs/auto-commit.log b/logs/auto-commit.log index 18b3df0..c2707b8 100644 --- a/logs/auto-commit.log +++ b/logs/auto-commit.log @@ -148,3 +148,6 @@ 2025-07-30 07:54:37 +02:00: 🔖 Creating restore point... 2025-07-30 07:54:43 +02:00: ✅ Restore point created 2025-07-30 08:24:37 +02:00: 🔖 Creating restore point... +2025-07-30 08:24:45 +02:00: ✅ Restore point created +2025-07-30 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0 +2025-07-30 08:54:37 +02:00: 🔖 Creating restore point... diff --git a/logs/auto-commit.out.log b/logs/auto-commit.out.log index fd389cd..7284519 100644 --- a/logs/auto-commit.out.log +++ b/logs/auto-commit.out.log @@ -144,3 +144,6 @@ 2025-07-30 07:54:37 +02:00: 🔖 Creating restore point... 2025-07-30 07:54:43 +02:00: ✅ Restore point created 2025-07-30 08:24:37 +02:00: 🔖 Creating restore point... +2025-07-30 08:24:45 +02:00: ✅ Restore point created +2025-07-30 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0 +2025-07-30 08:54:37 +02:00: 🔖 Creating restore point...