Maps projects to PhoenixLiveCalendar.Event structs for the Overview
dashboard calendar.
Each project becomes an all-day, multi-day "ongoing line" on a month grid: running projects span start → planned-end (reaching at least today, so they read as ongoing), completed projects span start → completion, and scheduled projects get a one-day marker on their planned start.
Bars are colored by project identity — a stable color per project, picked
by hashing the project id over a fixed palette of hues spread around the color
wheel — so adjacent and stacked bars stay tellable apart. Lifecycle status is
conveyed by the dashboard's project cards, with one exception: for a running
summary the caller tags late: true, only the stretch of the bar PAST its
planned end (planned_end+1 .. today) is highlighted — via extra.highlight
with the pk-overdue class (it marks that stretch in the INVERSE of the bar's
own colour — diagonal stripes over the identity colour, or a solid fill —
animated per animation_style/0, all configured on /admin/settings/projects)
— so the length of the marked tail shows how late the project is. The rest
keeps its identity color.
end is exclusive in PhoenixLiveCalendar ([start, end)), so the inclusive
last day gets +1. Projects without a placeable start date are dropped.
Summary
Functions
Allowed overdue-animation modes (for the settings form).
Allowed overdue-marker patterns (for the settings form).
Clamp range {lo, hi} for a numeric overdue field (bounds the form input).
CSS body (no surrounding <style> tag) for an overdue-animation config map of
the shape read_animation/0 returns. Public so tests and a settings preview
can render a given config without touching the settings store.
The <style> block for the overdue animation, generated from the current
settings. Safe to inject with Phoenix.HTML.raw/1: every interpolated value
is a validated enum or clamped number, never free text.
As animation_style/0, for an already-read config map (avoids a re-read).
Builds the calendar event list from the dashboard's already-loaded data.
Persist one overdue-animation field ("pattern", "mode", "speed",
"brightness_min", "brightness_max", "wave_step"). An invalid field or
value is ignored.
Current overdue-animation settings (validated, with safe defaults).
Restore every overdue-animation setting to its default.
Functions
@spec anim_modes() :: [String.t()]
Allowed overdue-animation modes (for the settings form).
@spec anim_patterns() :: [String.t()]
Allowed overdue-marker patterns (for the settings form).
Clamp range {lo, hi} for a numeric overdue field (bounds the form input).
CSS body (no surrounding <style> tag) for an overdue-animation config map of
the shape read_animation/0 returns. Public so tests and a settings preview
can render a given config without touching the settings store.
@spec animation_style() :: String.t()
The <style> block for the overdue animation, generated from the current
settings. Safe to inject with Phoenix.HTML.raw/1: every interpolated value
is a validated enum or clamped number, never free text.
As animation_style/0, for an already-read config map (avoids a re-read).
@spec events( [map()], [PhoenixKitProjects.Schemas.Project.t()], [PhoenixKitProjects.Schemas.Project.t()], String.t() | nil, Date.t(), String.t() ) :: [PhoenixLiveCalendar.Event.t()]
Builds the calendar event list from the dashboard's already-loaded data.
active_summaries—Projects.project_tree_summary/1maps for running projects (carry:project,:planned_end,:progress_pct), each tagged by the caller with:late(boolean) to drive the blinkcompleted/upcoming—[Project.t()](recently completed / scheduled)lang— content language for project titlestoday— anchor so a running project's bar always reaches at least todayoffset— viewer timezone offset (e.g. "+3"); UTC datetimes are converted to local calendar dates with it, so bars land on the same day the viewer sees
Persist one overdue-animation field ("pattern", "mode", "speed",
"brightness_min", "brightness_max", "wave_step"). An invalid field or
value is ignored.
@spec read_animation() :: %{ pattern: String.t(), mode: String.t(), speed: float(), brightness_min: float(), brightness_max: float(), wave_step: float() }
Current overdue-animation settings (validated, with safe defaults).
@spec reset_animation() :: :ok
Restore every overdue-animation setting to its default.