Show a project with a vertical timeline of assignments. Supports inline status changes, duration editing, dependency management, and tracks who completed each task.
List / Timeline tabs
The page has two views — the vertical task list and the embedded
ProjectGanttLive Timeline — toggled by tabs under the shared header.
Switching is instant (an assign flip) and the gantt is lazily mounted on first
open. The tabs render in every mount context, embedded live_render renders
included (only templates stay list-only). Note this means the Timeline tab is
a nested live_render of ProjectGanttLive, which is itself a nested LV when
the show page is embedded — deliberate, server-rendered, so the chart shows
even before any JS loads.
Keeping the URL in sync (the trailing /gantt segment + browser back/forward)
is optional and off by default: it's only on when @tab_url_sync? is true,
which the router-mounted standalone admin page sets (so its deep-linking keeps
working) and an embed can opt into via session["tab_url_sync"]. When on, the
ProjectTabsUrl JS hook pushes/reads history state. With it off the tabs
still switch fully — they just never touch the host page's URL (the right
default for an embed, which must not rewrite the host's address bar).