Enhance spreadsheet styling with comprehensive border system and formatting

- Add contextmenu fix to prevent TypeError
- Implement complete border system with top/left borders for all header rows
- Add dotted borders for employee rows (rows 8+)
- Create alternating row backgrounds (#D9D9D9) for better readability
- Add section separators at rows 23-24 and 28
- Implement background colors for rows 7-9 (#FCD5B4)
- Add day column separators (B,D,F,H etc.) from row 6 to end
- Create merged cell CA2:CA6 with proper borders
- Fix first row rotation for all cells including weekend merged cells
- Remove borders at section breaks for clean visual separation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Docker Config Backup
2025-08-05 07:51:01 +02:00
parent 158c9f5375
commit 38d88127ba

View File

@@ -319,20 +319,38 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
}
}
// Add top border to year row (row 3) from A3 to end of table (excluding last column)
for (let col = 0; col < (data[0]?.length || 0) - 1; col++) {
// Add top border to year row (row 3) from B3 to end of table (excluding A3 and last column)
for (let col = 1; col < (data[0]?.length || 0) - 1; col++) { // Start from column B (index 1)
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}3`] || ""
styles[`${colLetter}3`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add top border to shift row (row 6) from A6 to end of table (excluding last column)
for (let col = 0; col < (data[0]?.length || 0) - 1; col++) {
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}6`] || ""
styles[`${colLetter}6`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add left borders to columns B onwards for rows 3, 4, 5 (year, month, day)
for (let row = 3; row <= 5; row++) {
for (let col = 1; col < (data[0]?.length || 0) - 1; col++) { // Start from column B (index 1)
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-left: 1px solid #000000;"
}
}
// Style header rows
for (let col = 1; col < (data[0]?.length || 0); col++) {
const colLetter = getExcelColumnName(col)
// Preserve existing styles (including top border) and add background colors
const existingStyle = styles[`${colLetter}6`] || ""
if (col % 2 === 1) { // Day shifts (odd columns after first)
styles[`${colLetter}6`] = "background-color: #ffff00; font-weight: normal;" // Yellow for day, not bold
styles[`${colLetter}6`] = existingStyle + " background-color: #ffff00; font-weight: normal;" // Yellow for day, not bold
} else { // Night shifts (even columns after first)
styles[`${colLetter}6`] = "background-color: #00b0f0; font-weight: normal;" // Blue for night, not bold
styles[`${colLetter}6`] = existingStyle + " background-color: #00b0f0; font-weight: normal;" // Blue for night, not bold
}
}
@@ -364,6 +382,9 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
styles["BZ6"] = "" // Override any formatting for BZ6
styles["CA6"] = "" // Override any formatting for CA6
// Remove top border from BZ3 cell
styles["BZ3"] = (styles["BZ3"] || "").replace(" border-top: 1px solid #000000;", "").replace("border-top: 1px solid #000000;", "")
// Add left border to BZ column from row 2 to the last employee row
const totalRows = data.length
const employeeStartRow = 7 // Row 7 is first employee (0-indexed: rows 1-6 are headers, no empty row)
@@ -371,8 +392,89 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
styles[`BZ${row}`] = (styles[`BZ${row}`] || "") + " border-left: 1px solid #000000;"
}
// Add dotted top borders to employee rows (starting from row 8) up to BY column
for (let row = 8; row <= totalRows; row++) {
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // All columns except BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-top: 1px dotted #000000;"
}
}
// Make "Pohotovost IT" header bold (employee index 16, so row 23)
styles["A23"] = "font-weight: bold;" // "Pohotovost IT"
// Set background color for rows 7, 8, and 9 (excluding BZ and CA columns)
for (let row = 7; row <= 9; row++) {
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // All columns except BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " background-color: #FCD5B4;"
}
}
// Add left borders to first column of each day (B, D, F, H, etc.) from row 6 to end of table
for (let row = 6; row <= totalRows; row++) {
for (let col = 1; col < (data[0]?.length || 0) - 2; col += 2) { // Start from B (index 1), step by 2, exclude BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-left: 1px solid #000000;"
}
}
// Add top border to row 28 from A to BY
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // All columns except BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}28`] || ""
styles[`${colLetter}28`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add alternating row background colors starting from row 10 (every odd row: 10,12,14,16,18,20,22,24,26)
for (let row = 10; row <= totalRows; row += 2) { // Start from 10, increment by 2
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // All columns except BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " background-color: #D9D9D9;"
}
}
// Add top borders to rows 23 and 24 from A to BY
for (let row of [23, 24]) {
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // All columns except BZ and CA
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-top: 1px solid #000000;"
}
}
// Remove left borders from row 23 (day column borders)
for (let col = 1; col < (data[0]?.length || 0) - 2; col += 2) { // Day columns: B, D, F, H, etc.
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}23`] || ""
// Remove left border by replacing it with empty string
styles[`${colLetter}23`] = existingStyle.replace(" border-left: 1px solid #000000;", "").replace("border-left: 1px solid #000000;", "")
}
// Remove left border from BZ23
const existingBZ23Style = styles["BZ23"] || ""
styles["BZ23"] = existingBZ23Style.replace(" border-left: 1px solid #000000;", "").replace("border-left: 1px solid #000000;", "")
// Add top and left borders to merged cell CA2 (CA2:CA6)
const existingCA2Style = styles["CA2"] || ""
styles["CA2"] = existingCA2Style + " border-top: 1px solid #000000; border-left: 1px solid #000000;"
// Add left border to CA column from row 7 to 27 (excluding row 23)
for (let row = 7; row <= 27; row++) {
if (row !== 23) { // Skip row 23 where "Pohotovost IT" is located
const existingCAStyle = styles[`CA${row}`] || ""
styles[`CA${row}`] = existingCAStyle + " border-left: 1px solid #000000;"
}
}
// Add top border to CA23
const existingCA23Style = styles["CA23"] || ""
styles["CA23"] = existingCA23Style + " border-top: 1px solid #000000;"
}
// Validate configuration before initializing
@@ -692,6 +794,15 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
console.log(`Successfully applied ${mergeCount} cell merges`)
// Merge CA2 to CA6 (5 rows, 1 column)
try {
console.log("Attempting to merge CA2:CA6")
instance.setMerge("CA2", 1, 5) // 1 column, 5 rows (CA2, CA3, CA4, CA5, CA6)
console.log("Successfully merged CA2:CA6")
} catch (error) {
console.warn("Failed to merge CA2:CA6:", error.message)
}
// Clear merging flag after completion
isMergingRef.current = false