PhoenixKitProjects.CalendarDisplay (PhoenixKitProjects v0.16.0)

Copy Markdown View Source

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

anim_modes()

@spec anim_modes() :: [String.t()]

Allowed overdue-animation modes (for the settings form).

anim_patterns()

@spec anim_patterns() :: [String.t()]

Allowed overdue-marker patterns (for the settings form).

anim_range(binary)

@spec anim_range(String.t()) :: {float(), float()}

Clamp range {lo, hi} for a numeric overdue field (bounds the form input).

animation_css(cfg)

@spec animation_css(map()) :: String.t()

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.

animation_style()

@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.

animation_style(cfg)

@spec animation_style(map()) :: String.t()

As animation_style/0, for an already-read config map (avoids a re-read).

color_for(uuid)

@spec color_for(term()) :: {String.t(), String.t()}

events(active_summaries, completed, upcoming, lang, today \\ Date.utc_today(), offset \\ "0")

Builds the calendar event list from the dashboard's already-loaded data.

  • active_summariesProjects.project_tree_summary/1 maps for running projects (carry :project, :planned_end, :progress_pct), each tagged by the caller with :late (boolean) to drive the blink
  • completed / upcoming[Project.t()] (recently completed / scheduled)
  • lang — content language for project titles
  • today — anchor so a running project's bar always reaches at least today
  • offset — 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

put_animation(arg1, v)

@spec put_animation(String.t(), term()) :: term()

Persist one overdue-animation field ("pattern", "mode", "speed", "brightness_min", "brightness_max", "wave_step"). An invalid field or value is ignored.

read_animation()

@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).

reset_animation()

@spec reset_animation() :: :ok

Restore every overdue-animation setting to its default.