Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 08:54:37 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,8 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
|
||||
const jspreadsheetInstance = React.useRef<unknown>(null)
|
||||
const isActiveRef = React.useRef<boolean>(true)
|
||||
const isMergingRef = React.useRef<boolean>(false)
|
||||
const isInitializingRef = React.useRef<boolean>(false)
|
||||
const initTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)
|
||||
const currentDate = new Date()
|
||||
const [selectedMonth, setSelectedMonth] = React.useState<string>((currentDate.getMonth() + 1).toString())
|
||||
const [selectedYear, setSelectedYear] = React.useState<string>(currentDate.getFullYear().toString())
|
||||
@@ -147,6 +149,32 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log("useEffect triggered - Month:", selectedMonth, "Year:", selectedYear, "Force:", forceUpdate)
|
||||
|
||||
// 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 () => {
|
||||
@@ -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 = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;">${value}</div>`
|
||||
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 = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap; width: 100%;">${displayValue}</div>`
|
||||
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 = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;">${originalText}</div>`
|
||||
// For first row (rowIndex 0), ensure width: 100% for better text display
|
||||
const extraStyle = rowIndex === 0 ? ' width: 100%;' : ''
|
||||
cell.innerHTML = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;${extraStyle}">${originalText}</div>`
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -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
|
||||
|
||||
@@ -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...
|
||||
|
||||
@@ -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...
|
||||
|
||||
Reference in New Issue
Block a user