Implement cell merging and enhanced weekend formatting
- Add horizontal cell merging for header rows (2-5) using jspreadsheet setMerge - Day names, year, month, and day values now span across both day/night columns - Extended weekend highlighting to year/month/day rows under weekend days - Improved visual hierarchy with grouped date information per day - Fixed font sizes for better readability (12px for all rotated values) - Increased day names row height to 50px for better text fit - Removed bold formatting from "den"/"noc" shift labels Technical improvements: - Correct jspreadsheet v4 setMerge syntax: setMerge(cellAddress, colspan, rowspan) - Excel-style column naming supports AA, AB, AC... format - Preserved all text rotation and color formatting during merging 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -68,7 +68,7 @@ export function TimeshiftSpreadsheet({ teamId: _teamId, teamName }: TimeshiftSpr
|
|||||||
const dayName = ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"][currentDate.getDay()]
|
const dayName = ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"][currentDate.getDay()]
|
||||||
|
|
||||||
titleRow.push("", "")
|
titleRow.push("", "")
|
||||||
dayNameRow.push(dayName, "")
|
dayNameRow.push(dayName, "") // Day name in first column, empty in second (for merging)
|
||||||
yearRow.push(currentDate.getFullYear().toString(), "")
|
yearRow.push(currentDate.getFullYear().toString(), "")
|
||||||
monthRow.push((currentDate.getMonth() + 1).toString(), "")
|
monthRow.push((currentDate.getMonth() + 1).toString(), "")
|
||||||
dateRow.push(currentDate.getDate().toString(), "")
|
dateRow.push(currentDate.getDate().toString(), "")
|
||||||
@@ -232,24 +232,38 @@ export function TimeshiftSpreadsheet({ teamId: _teamId, teamName }: TimeshiftSpr
|
|||||||
// Generate styles for day/night shifts based on the Excel pattern
|
// Generate styles for day/night shifts based on the Excel pattern
|
||||||
const styles: Record<string, string> = {}
|
const styles: Record<string, string> = {}
|
||||||
if (selectedMonth && selectedYear) {
|
if (selectedMonth && selectedYear) {
|
||||||
|
// Make day names row (row 2) taller
|
||||||
|
for (let col = 0; col < (data[0]?.length || 0); col++) {
|
||||||
|
const colLetter = getExcelColumnName(col)
|
||||||
|
styles[`${colLetter}2`] = "height: 50px;"
|
||||||
|
}
|
||||||
|
|
||||||
// Style header rows
|
// Style header rows
|
||||||
for (let col = 1; col < (data[0]?.length || 0); col++) {
|
for (let col = 1; col < (data[0]?.length || 0); col++) {
|
||||||
const colLetter = getExcelColumnName(col)
|
const colLetter = getExcelColumnName(col)
|
||||||
if (col % 2 === 1) { // Day shifts (odd columns after first)
|
if (col % 2 === 1) { // Day shifts (odd columns after first)
|
||||||
styles[`${colLetter}6`] = "background-color: #ffff00; font-weight: bold;" // Yellow for day
|
styles[`${colLetter}6`] = "background-color: #ffff00; font-weight: normal;" // Yellow for day, not bold
|
||||||
} else { // Night shifts (even columns after first)
|
} else { // Night shifts (even columns after first)
|
||||||
styles[`${colLetter}6`] = "background-color: #00b0f0; font-weight: bold;" // Blue for night
|
styles[`${colLetter}6`] = "background-color: #00b0f0; font-weight: normal;" // Blue for night, not bold
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Style weekend days (Saturday/Sunday in day name row)
|
// Style weekend days (Saturday/Sunday in day name row and date rows below)
|
||||||
for (let col = 1; col < (data[0]?.length || 0); col += 2) {
|
for (let col = 1; col < (data[0]?.length || 0); col += 2) {
|
||||||
const dayName = data[1]?.[col]
|
const dayName = data[1]?.[col]
|
||||||
if (dayName === "Sobota" || dayName === "Neděle") {
|
if (dayName === "Sobota" || dayName === "Neděle") {
|
||||||
const colLetter = getExcelColumnName(col)
|
const colLetter = getExcelColumnName(col)
|
||||||
const nextColLetter = getExcelColumnName(col + 1)
|
const nextColLetter = getExcelColumnName(col + 1)
|
||||||
styles[`${colLetter}2`] = "background-color: #ffd966;" // Weekend day name
|
|
||||||
styles[`${nextColLetter}2`] = "background-color: #ffd966;"
|
// Weekend day name row (row 2) - merged cells
|
||||||
|
styles[`${colLetter}2`] = "background-color: #ffd966; height: 50px;" // Weekend day name with height
|
||||||
|
styles[`${nextColLetter}2`] = "background-color: #ffd966; height: 50px;"
|
||||||
|
|
||||||
|
// Weekend date columns (rows 3, 4, 5 - year, month, day)
|
||||||
|
for (let row = 3; row <= 5; row++) {
|
||||||
|
styles[`${colLetter}${row}`] = "background-color: #ffd966;" // Weekend date values
|
||||||
|
styles[`${nextColLetter}${row}`] = "background-color: #ffd966;" // Weekend date values
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,6 +292,26 @@ export function TimeshiftSpreadsheet({ teamId: _teamId, teamName }: TimeshiftSpr
|
|||||||
|
|
||||||
console.log("jspreadsheet initialized:", !!jspreadsheetInstance.current)
|
console.log("jspreadsheet initialized:", !!jspreadsheetInstance.current)
|
||||||
|
|
||||||
|
// Apply cell merges for header rows after initialization
|
||||||
|
if (jspreadsheetInstance.current && selectedMonth && selectedYear) {
|
||||||
|
const instance = jspreadsheetInstance.current as any
|
||||||
|
if (instance.setMerge) {
|
||||||
|
// Merge all pairs in rows 2, 3, 4, 5 (day names, year, month, day)
|
||||||
|
for (let row = 2; row <= 5; row++) {
|
||||||
|
for (let col = 1; col < (data[0]?.length || 0); col += 2) {
|
||||||
|
const colLetter = getExcelColumnName(col)
|
||||||
|
try {
|
||||||
|
// Correct syntax: setMerge(cellAddress, colspan, rowspan)
|
||||||
|
instance.setMerge(`${colLetter}${row}`, 2, 1) // 2 columns, 1 row
|
||||||
|
console.log(`Merged ${colLetter}${row} with 2 columns`)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to merge ${colLetter}${row}:`, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply counter-clockwise rotation to data values only (exclude second column which contains field labels)
|
// Apply counter-clockwise rotation to data values only (exclude second column which contains field labels)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const table = spreadsheetRef.current?.querySelector('.jexcel tbody')
|
const table = spreadsheetRef.current?.querySelector('.jexcel tbody')
|
||||||
@@ -292,7 +326,8 @@ export function TimeshiftSpreadsheet({ teamId: _teamId, teamName }: TimeshiftSpr
|
|||||||
// Skip first two columns (row numbers and field labels)
|
// Skip first two columns (row numbers and field labels)
|
||||||
if (cellIndex > 1) {
|
if (cellIndex > 1) {
|
||||||
const originalText = cell.textContent
|
const originalText = cell.textContent
|
||||||
cell.innerHTML = `<div style="transform: rotate(-90deg); font-size: 9px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;">${originalText}</div>`
|
// 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>`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
screenshots/Snímek obrazovky 2025-07-28 203857.png
Normal file
BIN
screenshots/Snímek obrazovky 2025-07-28 203857.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Reference in New Issue
Block a user