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:
Docker Config Backup
2025-07-30 08:54:37 +02:00
parent 5e332aac05
commit 318fef77aa
3 changed files with 72 additions and 10 deletions

View File

@@ -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,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 = `<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