feat(work): add inline run duration bars to Work table rows#1059
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
nhopeatall
left a comment
There was a problem hiding this comment.
Summary
Clean, well-structured feature. The two-query approach, pure segment function, and reuse of existing getAgentColor/formatDuration/agentTypeLabel infrastructure are all solid choices. One CSS bug to fix.
Code Issues
Should Fix
-
web/src/components/projects/project-work-table.tsx:252 — CSS class conflict between
flexandhiddenin the legend container. Bothflex(display: flex) andhidden(display: none) are applied at the base breakpoint, creating non-deterministic display behavior depending on Tailwind's CSS generation order. The legend may be visible on mobile instead of hidden.Fix: remove the unprefixed
flexso onlyhiddenapplies at the base level, andsm:flexoverrides it at thesmbreakpoint:<div className="hidden sm:flex flex-wrap gap-3" style={{ fontSize: 12 }}>
Everything else looks good:
- Backend
listUnifiedWorkWithDurationscleanly reuseslistUnifiedWorkForProjectand correctly filters to completed/failed/timed_out runs with non-null durations buildDurationSegmentsis properly extracted as a pure testable function with good test coverage- Auth/access control mirrors the existing
listUnifiedpattern colSpancorrectly bumped from 4→5 for the new Duration column- Duration column and legend properly hidden on mobile (
hidden sm:table-cell) - Segment labeling logic (
#1,#2for repeated agent types) matches the existingWorkItemDurationChartpattern - The
as numbercast ondurationMsis safe since the query filters withisNotNull - Tests cover segment building, outlier threshold logic, and tRPC procedure auth
🕵️ claude-code · claude-opus-4-6 · run details
Remove unprefixed `flex` that conflicted with `hidden` at the base breakpoint. Now `hidden` applies at mobile and `sm:flex` overrides at the sm breakpoint, preventing non-deterministic display behaviour. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nhopeatall
left a comment
There was a problem hiding this comment.
Summary
LGTM — Well-structured feature addition that follows existing codebase patterns consistently.
The two-query approach in listUnifiedWorkWithDurations cleanly extends the existing listUnifiedWorkForProject without modifying it, maintaining backward compatibility. The pure buildDurationSegments function is properly separated for testability, and the component correctly reuses getAgentColor/formatDuration/agentTypeLabel from existing chart infrastructure rather than introducing duplicates.
Auth, responsive behavior (hidden on mobile), colSpan updates, and the outlier detection logic are all correct. Test coverage is solid across the pure segment logic, tRPC procedure (auth, happy path, empty state), and outlier threshold boundaries.
🕵️ claude-code · claude-opus-4-6 · run details
Summary
listUnifiedWorkWithDurationsrepository function fetches unified work items with per-run duration breakdowns and a project-wide average for outlier detectionprs.listUnifiedWithDurationsendpoint exposes the data with the same auth aslistUnifiedgetAgentColor()/formatDuration()from existing chart infrastructure; no rechartsWhat changed
src/db/repositories/prWorkItemsRepository.tslistUnifiedWorkWithDurations(two-query: unified items + run durations, compute project avg)src/api/routers/prs.tslistUnifiedWithDurationstRPC procedureweb/src/components/projects/work-item-duration-bar.tsxWorkItemDurationBar+ exportedbuildDurationSegmentspure functionweb/src/components/projects/project-work-table.tsxWorkItemRuninterface,projectAvgDurationMspropweb/src/routes/projects/$projectId.work.tsxlistUnifiedWithDurationsquery, passes avg to tabletests/unit/web/work-item-duration-bar.test.tstests/unit/api/routers/prs.test.tslistUnifiedWithDurationsprocedureTest plan
buildDurationSegments(empty, zero durations, percentages, colors, repeated agent types, outlier threshold)listUnifiedWithDurationstRPC procedure (auth, mock repo call, empty result)Key decisions
listUnifiedconsumershidden sm:table-cell) to avoid overflow on narrow screens; legend also hidden on mobilecolSpanbumped from 4 to 5 to account for the new Duration column in the empty-state rowhttps://trello.com/c/yySaJYFa/568-lets-put-run-durations-horizontal-stacked-bar-chart-directly-on-rows-in-work-section-of-the-project-so-at-a-glance-we-see-any-wo
🤖 Generated with Claude Code
🕵️ claude-code · claude-sonnet-4-6 · run details