Skip to content

feat(#221,#229): Timeline scale/year view, allocation editing, CSV TemplateSize, Gantt UX polish#231

Merged
NickMonrad merged 15 commits intomainfrom
feature/timeline-scale-csv-template
Apr 29, 2026
Merged

feat(#221,#229): Timeline scale/year view, allocation editing, CSV TemplateSize, Gantt UX polish#231
NickMonrad merged 15 commits intomainfrom
feature/timeline-scale-csv-template

Conversation

@NickMonrad
Copy link
Copy Markdown
Owner

Summary

Closes #221 (Timeline scale toggle) and #229 (CSV TemplateSize). Also ships a large set of Timeline UX improvements made during the same session.

Related issues

Closes #221
Closes #229

Changes

Core issues

  • Timeline scale toggle (Wk / Mo / Qtr / Yr) — new Year scale shows H1/H2 top row and Q1–Q4 bottom row at 8 px/week, suitable for 2+ year projects
  • TemplateSize column in backlog CSV — importing a row with TemplateSize=S (XS/S/M/L/XL) auto-expands linked template tasks using that tier's hours
  • Cross-epic FeatureDependsOn in CSV import — qualified format EpicName::FeatureName resolves dependencies across epic boundaries

Timeline UX

  • Allocation mode editing in Resource Counts panel — set each named resource to T&M / Full Project / Timeline, with % allocation field
  • Timeline start/end weeks — appear for named resources in Timeline mode (W[start] – W[end] inputs)
  • Expand All / Collapse All toggle in Gantt label panel header
  • Dependency picker search filter — type to filter the epic dep dropdown
  • Top mirror scrollbar — synced horizontal scrollbar above the Gantt so you can scroll without reaching the bottom
  • Full-width Gantt layout — removes the empty left/right margins; chart uses the full browser width
  • Two-line epic labels — longer epic names wrap to a second line instead of truncating

Bug fixes

  • Onboarding/buffer zone calccomputeDates() now applies onboardingWeeks offset so tooltip dates and zone positions are correct at all scales
  • Adaptive zone labels — zone text shortens at compressed scales (OnboardingOnbrdO) to fit within the zone rect
  • Label width alignmentLABEL_W=380 now consistently applied to ResourceHistogram and NamedResourcesPanel (was hardcoded 300, causing misalignment)
  • Histogram bars at year scale — bar inset is now proportional to colW (min 1px, max 4px) instead of hardcoded 8px which produced zero-width bars at year scale
  • Auto-reschedule on resource changes — scheduler only auto-fires on first run (entries.length === 0); resource mutations set a stale banner instead
  • Expand state reset on timeline refetch — uses knownEpicIds ref (tracks all ever-seen epic IDs) so collapsing all is preserved across mutations. Previous fix using expandedEpics.size === 0 check failed because Collapse All empties the set, making all epics look new
  • Named resource T&M histogram per-person — T&M bars divided by the number of named resources in the pool so each person shows their share (e.g. 2 engineers → 5/5 days each, not 10/10)
  • PNG export width — respects active scale's colW (was always using week-scale width)
  • Top scrollbar width — synced to actual Gantt content width at current scale

E2E Tests

No new E2E tests in this PR — the existing timeline and backlog specs cover the core flows. Scale toggle and CSV TemplateSize are covered by manual verification.

Tests added/modified: none

E2E test results: existing suite unmodified; server tests 142/142 ✅

Testing

  • npm test passes in /server (142 tests)
  • npx tsc --noEmit passes in /server
  • npx tsc --noEmit passes in /client
  • npm run test:e2e — not run (no new Playwright tests added)
  • e2e/TESTS.md — no changes needed

Notes

  • The knownEpicIds ref approach is the correct fix for the expand/collapse reset bug. An earlier attempt using epicInitDone ref still failed because the merge logic compared against expandedEpics (empty after collapse) not against the set of known IDs.
  • Year scale at 8 px/week means a 2-year project renders at ~832 px, fitting comfortably in a 1440 px viewport.
  • Named resource allocation changes (mode/%) do not auto-reschedule — they set the stale banner. This is intentional.

NickMonrad and others added 15 commits April 29, 2026 08:46
…and on import

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…g levels

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… example rows

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… epic

- Scheduler: after Kahn's topological sort, features with unresolvable
  inDegrees (stuck in cycles) are now scheduled at a fallback start week
  derived from their epic's position in the sequential chain. Previously
  they were silently dropped, causing 222/228 features to never appear
  on the timeline.

- CSV import: FeatureDependsOn name lookup is now scoped to the current
  row's epic instead of searching all features in the project. This
  prevents cross-epic name collisions when multiple epics share identical
  feature names (e.g. every epic has 'Infrastructure & Environment').
  Previously, the last feature with that name (across all epics) was
  matched, creating backward cross-epic dependencies that caused cycles.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Export: cross-epic deps now written as 'EpicName: FeatureName' so they
  round-trip correctly on re-import
- Import staging: validates qualified 'EpicName: FeatureName' entries
  against the known epic/feature pairs in the import
- Import commit: resolves 'EpicName: FeatureName' via cross-epic lookup;
  plain feature names continue to resolve within the same epic only
- Empty CSV template: updated description column for FeatureDependsOn to
  document both formats; added example rows showing same-epic dep
  ('Authentication') and cross-epic dep ('Platform Setup: Authentication')

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After a successful CSV import, the epicDeps and feature-deps React Query
caches were not invalidated, so newly imported dependencies were invisible
until a full page reload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move feature mode, schedule mode, and dep chips to a second line
under the epic title. Bump EPIC_ROW_H from 36 to 52px to fit.
Title now has full label width without truncation competition.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove max-w-7xl constraint on TimelinePage main wrapper so the
  Gantt chart stretches to fill the full viewport width
- Widen LABEL_W from 300 to 380px for longer epic names

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds a 12px mirror div above the GanttChart that scrolls in sync
with the main chart and histogram scrollbars so users can scroll
horizontally from the top without scrolling to the bottom first.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Last 4 epics now open the dependency dropdown upward (bottom-full)
so it isn't hidden behind the resource demand histogram.
Also adds max-h-64 + overflow-y-auto so large epic lists scroll
within the dropdown instead of overflowing off-screen.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Dropdown now has an auto-focused search input at the top that filters
the epic list by name. Search resets each time the picker is opened.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Export was hardcoded to COL_W=64 (week scale) regardless of the
active Week/Month/Quarter toggle, causing excess whitespace in
month/quarter exports. Now uses ganttColW (scale-aware) and LABEL_W.
Top mirror scrollbar width also corrected to use LABEL_W constant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eSize, Gantt UX polish

- Add week/month/quarter/year scale toggle to Timeline Gantt
- Year scale: H1/H2 top row, Q1-Q4 bottom row, 8px/week column width
- TemplateSize column in backlog CSV — auto-expand template tasks on import (XS/S/M/L/XL)
- Cross-epic FeatureDependsOn in CSV import via qualified format (Epic::Feature)
- Allocation mode (T&M/Full Project/Timeline) and % editing in Resource Counts panel
- Start/end week inputs for Timeline allocation mode named resources
- Expand All / Collapse All toggle in Gantt label panel header
- Dep picker search filter on epic dependency dropdown
- Top mirror scrollbar synced with Gantt horizontal scroll
- Full-width Gantt layout (removes empty side margins)
- Onboarding/buffer zone date calculation fix (computeDates now applies onboardingWeeks offset)
- Adaptive zone labels at compressed scales (Onboarding / Onbrd / O)
- Fix label column width alignment (LABEL_W=380 applied to ResourceHistogram and NamedResourcesPanel)
- Fix histogram bars invisible at year scale (proportional inset instead of hardcoded 8px)
- Fix auto-reschedule on resource changes — only fires on first run (entries.length === 0)
- Fix expand/collapse state reset on timeline refetch — use knownEpicIds ref to track seen epics
- Fix named resource T&M histogram showing full pool demand per row — divide by person count
- PNG export and top scrollbar width respect active scale

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@NickMonrad NickMonrad merged commit 14d3b99 into main Apr 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSV import: auto-expand template tasks and backfill estimates from template sizing Timeline: scale options (week / month / quarter)

1 participant