feat: Czech day name format 'Pondělí (20.2)' in canvas + PDF; wider date column
Some checks failed
Build & Push Docker / build (push) Has been cancelled
Some checks failed
Build & Push Docker / build (push) Has been cancelled
This commit is contained in:
@@ -45,6 +45,20 @@ def is_light(hex_color: str) -> bool:
|
|||||||
return (0.299 * r + 0.587 * g + 0.114 * b) > 0.6
|
return (0.299 * r + 0.587 * g + 0.114 * b) > 0.6
|
||||||
|
|
||||||
|
|
||||||
|
_CS_WEEKDAYS = ['Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota', 'Neděle']
|
||||||
|
|
||||||
|
|
||||||
|
def format_date_cs(date_str: str) -> str:
|
||||||
|
"""Format date as 'Pondělí (20.2)'."""
|
||||||
|
from datetime import date as dt_date
|
||||||
|
try:
|
||||||
|
d = dt_date.fromisoformat(date_str)
|
||||||
|
weekday = _CS_WEEKDAYS[d.weekday()]
|
||||||
|
return f"{weekday} ({d.day}.{d.month})"
|
||||||
|
except Exception:
|
||||||
|
return date_str
|
||||||
|
|
||||||
|
|
||||||
def time_to_min(s: str) -> int:
|
def time_to_min(s: str) -> int:
|
||||||
parts = s.split(':')
|
parts = s.split(':')
|
||||||
return int(parts[0]) * 60 + int(parts[1])
|
return int(parts[0]) * 60 + int(parts[1])
|
||||||
@@ -153,7 +167,7 @@ def generate_pdf(doc) -> bytes:
|
|||||||
|
|
||||||
FOOTER_H = 10
|
FOOTER_H = 10
|
||||||
TIME_AXIS_H = 18
|
TIME_AXIS_H = 18
|
||||||
DATE_COL_W = 18 * mm
|
DATE_COL_W = 28 * mm # wider for Czech day names like "Pondělí (20.2)"
|
||||||
|
|
||||||
# Available area for the timetable grid
|
# Available area for the timetable grid
|
||||||
avail_h = PAGE_H - 2 * MARGIN - header_h - LEGEND_H - FOOTER_H - TIME_AXIS_H - 6
|
avail_h = PAGE_H - 2 * MARGIN - header_h - LEGEND_H - FOOTER_H - TIME_AXIS_H - 6
|
||||||
@@ -248,7 +262,7 @@ def generate_pdf(doc) -> bytes:
|
|||||||
|
|
||||||
# Date label cell
|
# Date label cell
|
||||||
fill_rect(c, x0, row_y, DATE_COL_W, row_h, AXIS_BG, BORDER, 0.4)
|
fill_rect(c, x0, row_y, DATE_COL_W, row_h, AXIS_BG, BORDER, 0.4)
|
||||||
draw_clipped_text(c, date_key, x0, row_y, DATE_COL_W, row_h,
|
draw_clipped_text(c, format_date_cs(date_key), x0, row_y, DATE_COL_W, row_h,
|
||||||
'Helvetica-Bold', date_font, AXIS_TEXT, 'center')
|
'Helvetica-Bold', date_font, AXIS_TEXT, 'center')
|
||||||
|
|
||||||
# Vertical grid lines (15-min slots, hour lines darker)
|
# Vertical grid lines (15-min slots, hour lines darker)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
const Canvas = {
|
const Canvas = {
|
||||||
GRID_MINUTES: 15,
|
GRID_MINUTES: 15,
|
||||||
ROW_H: 52, // px height of one day row
|
ROW_H: 52, // px height of one day row
|
||||||
TIME_LABEL_W: 80, // px width of date label column
|
TIME_LABEL_W: 110, // px width of date label column (Czech day names: "Pondělí (20.2)")
|
||||||
HEADER_H: 28, // px height of time axis header
|
HEADER_H: 28, // px height of time axis header
|
||||||
MIN_BLOCK_MIN: 15, // minimum block duration in minutes
|
MIN_BLOCK_MIN: 15, // minimum block duration in minutes
|
||||||
|
|
||||||
@@ -189,7 +189,12 @@ const Canvas = {
|
|||||||
|
|
||||||
_formatDate(dateStr) {
|
_formatDate(dateStr) {
|
||||||
const d = new Date(dateStr + 'T12:00:00');
|
const d = new Date(dateStr + 'T12:00:00');
|
||||||
return d.toLocaleDateString('cs-CZ', { weekday: 'short', day: 'numeric', month: 'numeric' });
|
const weekday = d.toLocaleDateString('cs-CZ', { weekday: 'long' });
|
||||||
|
// Capitalize first letter
|
||||||
|
const weekdayCap = weekday.charAt(0).toUpperCase() + weekday.slice(1);
|
||||||
|
const day = d.getDate();
|
||||||
|
const month = d.getMonth() + 1;
|
||||||
|
return `${weekdayCap} (${day}.${month})`;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createBlockEl(block, typeMap, totalMin) {
|
_createBlockEl(block, typeMap, totalMin) {
|
||||||
|
|||||||
Reference in New Issue
Block a user