feat(work-item): make the Gantt timeline interactive (zoom + drag-to-reschedule) - #310
Conversation
…reschedule) The Gantt was a read-only timeline. It now supports: - Zoom: step the day scale in/out with toolbar controls (14-56 px/day). - Drag-to-reschedule: drag a bar to move start + target together, or drag either edge to change just the start or the target. Changes commit through the existing onUpdateIssue path (same PATCH the list/board/calendar use), with a live preview while dragging and clamping so a resized edge can't cross the other. A drag doesn't trigger navigation; a plain click still opens the issue. Dependency lines between bars are a planned follow-up. Closes Devlaner#180 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 43 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesGantt interactivity
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant IssueLayoutGantt
participant Window
participant IssueListPage
User->>IssueLayoutGantt: Drag a dated bar or resize handle
IssueLayoutGantt->>Window: Track pointer movement and release
Window->>IssueLayoutGantt: Send pointer events
IssueLayoutGantt->>IssueLayoutGantt: Preview and calculate date changes
IssueLayoutGantt->>IssueListPage: Submit formatted date patch
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx (1)
60-89: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winUse calendar-day arithmetic instead of fixed 24-hour milliseconds.
These local dates are added and divided using
DAY_MS. Across daylight-saving transitions, headers can duplicate/skip dates and dragging by one day can serialize an unchanged or skipped date. Use calendar-day add/difference helpers throughout the window and drag calculations.Also applies to: 380-412
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx` around lines 60 - 89, Replace fixed DAY_MS arithmetic in the IssueLayoutGantt viewWindow, days generation, todayOffset, and drag calculations with the existing calendar-day add/difference helpers. Preserve the current padding, shifting, and date-range behavior while ensuring one-day movement and serialization remain correct across daylight-saving transitions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx`:
- Around line 294-295: Update the bar positioning logic in IssueLayoutGantt
around offset and span to intersect each issue’s [start, end] range with
viewWindow, omit bars with no overlap, and calculate offset/span from the
clipped range rather than clamping the original offset to zero.
- Around line 102-153: Update the drag gesture state used by beginDrag, the
pointermove/pointerup handlers, and the related click suppression logic to track
pointerId and movement in pixels, suppressing navigation once the configured
pixel threshold is crossed rather than only after deltaDays changes. Handle
pointercancel by clearing the active drag and preview, and ensure suppression is
consumed only by the matching pointer’s click and expires when that gesture does
not produce one.
---
Outside diff comments:
In `@apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsx`:
- Around line 60-89: Replace fixed DAY_MS arithmetic in the IssueLayoutGantt
viewWindow, days generation, todayOffset, and drag calculations with the
existing calendar-day add/difference helpers. Preserve the current padding,
shifting, and date-range behavior while ensuring one-day movement and
serialization remain correct across daylight-saving transitions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9710867c-f6c9-4899-a156-6ec5c9b6a7ef
📒 Files selected for processing (2)
apps/web/src/components/work-item/layouts/IssueLayoutGantt.tsxapps/web/src/pages/IssueListPage.tsx
…he window Address review findings on the interactive Gantt: - Distinguish click from drag by a pixel threshold on the whole gesture, and resolve navigation in the pointer-up handler (a click, i.e. no meaningful move, opens the item) instead of a separate onClick guarded by a suppress flag. A sub-day drag no longer navigates, and a drag released off the bar no longer swallows a later click. - Clip each bar to the visible window: a bar with no overlap renders as an empty row (preserving sidebar alignment) rather than being pinned to the first column after panning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@martian56 addressed both CodeRabbit notes (pixel-threshold click/drag detection + clipping bars to the visible window). Green with no open comments — good to merge. Interactive drag-reschedule + zoom; dependency lines noted as a follow-up. |
Feature summary
The Gantt/Timeline layout is now interactive: you can zoom the day scale and drag work-item bars to reschedule them (move or resize), instead of only reading a static timeline.
Linked issues / discussion
Closes #180
User-facing behavior
On a project's work items, switch to the Timeline (Gantt) layout:
Changes persist through the same PATCH the list/board/calendar layouts already use for inline date edits.
What changed
UI (
apps/web/)IssueLayoutGantt.tsx: zoom state + controls; pointer-based drag (move / resize-start / resize-end) tracked in a ref with a state-mirrored preview so the render never reads a ref; commits viaonUpdateIssuewithYYYY-MM-DDdates (matching the calendar's format).IssueListPage.tsx: passesonUpdateIssue={handleInlineUpdate}to the Gantt.API / Database
Why this design
Reused the shared
onUpdateIssueinline-update path so Gantt edits go through the same optimistic-update + serialized-PATCH machinery as the other layouts (no new endpoint, consistent behavior). Drag state lives in a ref so the global pointer listeners read live values without re-subscribing each move, and it's mirrored into a small state object purely for the preview render (keeping the render ref-free, which the React Compiler lint requires). Kept the scope to drag + zoom; dependency lines between bars are a natural follow-up.Test plan
npm run validate(typecheck + lint + prettier) greenOut of scope (follow-ups)
AI assistance
Claude Code (Claude Opus 4.8)— and AI-assisted commits include aCo-Authored-By:trailerChecklist
Summary by CodeRabbit
New Features
Bug Fixes