feat(tasks): add Gantt timeline view for tasks#182
Conversation
|
please add demo video and resolve the conflicts |
Adds a Timeline view to the Tasks page, alongside List, Kanban and Calendar. Each task is drawn as a horizontal bar spanning its start_date -> due_date on a scrollable day axis, grouped by project. - New TaskTimeline component: sticky task labels, status-colored bars, today highlighting, and an "Unscheduled" tray for tasks with no dates so none are hidden - Timeline toggle button added to the Tasks view switcher - Saveable as a named view: adds "timeline" to Hive View.view_type Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4c6a27d to
e49b2ba
Compare
Greptile SummaryAdds a Gantt-style Timeline view to the Tasks page, rendering each task as a horizontal bar spanning its
Confidence Score: 5/5Safe to merge — the change is purely additive with no modifications to existing views or backend APIs. All four changed files introduce the new timeline mode without touching existing paths. The UTC date-parsing fix (T00:00:00 local-time literal) is correctly applied, the projectMap is reused without duplication, and edge cases (single-date tasks, reversed ranges, tasks without dates) are all handled. No issues were found beyond the DOM-node scalability note already raised in the prior review thread. No files require special attention.
|
| Filename | Overview |
|---|---|
| frontend/src/components/TaskTimeline.tsx | New Gantt component; UTC date-parsing bug addressed via parseLocalDate; logic for single-date tasks, reversed ranges, and unscheduled tasks all handled correctly |
| frontend/src/pages/TasksPage.tsx | Adds timeline toggle and renders TaskTimeline with the pre-existing projectMap; no duplicate memo; view type label and saved-view logic updated correctly |
| frontend/src/types.ts | Adds "timeline" to the HiveView.view_type union; straightforward additive change |
| bwh_hive/bwh_hive/doctype/hive_view/hive_view.json | Appends "timeline" to the view_type Select options; additive and consistent with the frontend type change |
Reviews (2): Last reviewed commit: "fix(timeline): parse date-only values as..." | Re-trigger Greptile
| const rStart = minDate(scheduled.map((s) => s.start)) | ||
| const rEnd = maxDate(scheduled.map((s) => s.end)) | ||
| const allDays = eachDayOfInterval({ start: rStart, end: rEnd }) |
There was a problem hiding this comment.
Unbounded DOM node count on wide date ranges
eachDayOfInterval returns one Date per day, and the render loop produces one div DOM node per entry in the header — no virtualisation. For a dataset where the earliest start_date and latest due_date span a year or more, the header alone generates 365+ nodes on every render. At 500 tasks (the query limit) covering different calendar years this is entirely realistic. Consider capping the visible window or switching to a virtual-scroll approach if performance becomes an issue.
Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/components/TaskTimeline.tsx
Line: 55-57
Comment:
**Unbounded DOM node count on wide date ranges**
`eachDayOfInterval` returns one `Date` per day, and the render loop produces one `div` DOM node per entry in the header — no virtualisation. For a dataset where the earliest `start_date` and latest `due_date` span a year or more, the header alone generates 365+ nodes on every render. At 500 tasks (the query limit) covering different calendar years this is entirely realistic. Consider capping the visible window or switching to a virtual-scroll approach if performance becomes an issue.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Left as-is for now: the axis spans only the min/max dates of the tasks currently in view (the page filters apply first), so in practice it is weeks-to-months rather than years, and a day cell is a single lightweight div. I would rather not add virtualisation complexity pre-emptively — happy to cap the window or switch to virtual scroll in a follow-up if you would prefer it hardened now.
🤖 Addressed by Claude Code
…tMap
Addresses review feedback:
- Date-only strings ("yyyy-MM-dd") were passed to `new Date()`, which V8
parses as UTC midnight. For users west of UTC that resolved to the
previous local day, shifting every bar one column to the left. Parse via
an explicit local time component instead.
- Drop the redundant `projectTitles` memo and pass the pre-existing
`projectMap` (same name -> title lookup) through to TaskTimeline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@Rl0007 — demo video and conflicts both sorted 👇 Demo — Timeline view: bars spanning Conflicts — resolved. #178 (calendar) landing on Also pushed fixes for the two Greptile findings (local date parsing, and reusing the existing |

Summary
Adds a Timeline (Gantt) view to the Tasks page, alongside List and Kanban. Each task is drawn as a horizontal bar spanning its
start_date→due_dateon a scrollable day axis, grouped by project.What's included
TaskTimelinecomponenttimelinetoHive View.view_type; the mode is restored from saved views and the sidebarNotes
Hive View.view_typeSelect field.date-fns(already a dependency); no new packages.Testing
tsc --noEmitand ESLint clean on the changed files.