"""Tasks widget: a simple outstanding-task checklist merged from one or more of its linked users' CalDAV task lists, in its own region -- split out of the calendar widget's old week-view-only, single-list task list (see models.TaskWidgetConfig) so a task list can be placed and sized on its own, independent of any calendar's view/footprint, and can merge more than one person's list the same way a calendar widget merges more than one person's calendar (see models.FrameTaskList). No "enabled" concept and no button actions: the widget's mere presence on the grid is the on/off switch (same as every other widget type), and its cache refreshes on the same throttled schedule as weather -- nothing here to advance/back/force. No placeholder for "nothing included yet" either -- same posture as app/widgets/calendar.py, which this otherwise mirrors closely: render() always draws through get_or_refresh_tasks_ for_widget's result even when it's [], showing "Nothing outstanding" rather than a distinct not-configured state (the dialog's preview endpoint is what actually 400s for that case, same asymmetry calendar already has).""" from __future__ import annotations from PIL import Image from sqlalchemy.orm import Session from ..calendar_render import _build_tasks from ..models import Frame, TaskWidgetConfig, Widget from ..routers.common import get_or_refresh_tasks_for_widget ACTION_LABELS: dict[str, str] = {} def render(db: Session, frame: Frame, widget: Widget, target_w: int, target_h: int, is_normal_wake: bool = True) -> Image.Image: """is_normal_wake is unused here -- see app/widgets/photos.py's identical note; every widget type's render() shares one call signature regardless of which ones actually care.""" tasks = get_or_refresh_tasks_for_widget(db, frame, widget) cfg = db.get(TaskWidgetConfig, widget.id) title = cfg.name or "Tasks" if cfg.render_style == "modern": # Local import: html_render pulls in Playwright, a real headless- # Chromium dependency -- every other widget type, and this one's # own classic path, should never pay for it. from .. import html_render return html_render.build_tasks(tasks, target_w, target_h, frame.palette_rgb, title, frame.theme) return _build_tasks(tasks, target_w, target_h, frame.palette_rgb, title) ACTIONS: dict = {}