Skip to content

Extract shared FeedbackReplyForm + FeedbackResolutionFooter - #836

Merged
selfcontained merged 1 commit into
mainfrom
agt_e941b25d9f4c/job-debt-collector-c462693e
Jul 26, 2026
Merged

Extract shared FeedbackReplyForm + FeedbackResolutionFooter#836
selfcontained merged 1 commit into
mainfrom
agt_e941b25d9f4c/job-debt-collector-c462693e

Conversation

@selfcontained

Copy link
Copy Markdown
Owner

What

Extracts the two review-feedback card blocks that were duplicated (~180 lines) between diff-annotations.tsx (inline diff annotations) and reviews-sidebar.tsx (reviews sidebar) into a shared feedback-card-parts.tsx:

  • FeedbackReplyForm — the animated reply form (Textarea with Cmd/Ctrl-Enter submit + Escape cancel, Cancel/Send buttons) and the Reply trigger button.
  • FeedbackResolutionFooter — the resolution-note box plus the Reopen / Dismiss / Mark-fixed buttons with per-variant pending spinners.

Both components are purely presentational — reply state stays in the parents so the draft-reply text still survives collapse/re-expand exactly as before. A variant: "inline" | "sidebar" prop preserves each surface's layout classes verbatim (ml-auto … max-w-sm width-capping in the wide diff view vs full-width in the narrow sidebar).

Net -115 lines. Intentionally NOT included: consolidating ThreadMessage/InlineThreadMessage — that is a visible behavior change (state-change message rendering) and is queued as its own backlog item.

Why it's tech debt

Largest duplication in the repo per the 2026-07-21 audit; the two copies had already started drifting cosmetically (an aria-label present on one Send button but not the other — now unified, the only intentional delta: the inline Send button gains aria-label="Send reply").

Validation

  • pnpm run check, web vitest (415 passed), pnpm run finalize:web, pnpm run test:e2e (170 passed) all green.
  • Playwright-validated both surfaces on a seeded dev stack: opened/typed/submitted a reply in the sidebar card, and did a full Mark-fixed → Reopen round-trip plus reply-form open/Escape in the inline diff annotation. Screenshots shared via dispatch media.

Queued next

Top of the tech-debt backlog: InlineThreadMessage renders state-change messages as empty bubbles (behavior-change consolidation, own PR), then the server/web media-table divergence.

🤖 Generated with Claude Code

The review-feedback reply form and resolution footer were duplicated
(~180 lines) between diff-annotations.tsx and reviews-sidebar.tsx.
Extract both blocks into feedback-card-parts.tsx with a variant prop
that preserves each surface's layout classes exactly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@selfcontained
selfcontained merged commit b55efa6 into mainJul 26, 2026
1 check passed
@selfcontained
selfcontained deleted the agt_e941b25d9f4c/job-debt-collector-c462693e branch July 26, 2026 09:14
selfcontained added a commit that referenced this pull request Jul 27, 2026
- Extend loadScopedActivityEvents with an optional includeProjectDir mode
(LEFT JOIN agents, COALESCE(ae.project_dir, a.cwd)) and switch
handleWorkingTimeByProject to it, removing the hand-inlined copy of the
in-range + DISTINCT ON boundary carry-in queries so the two can't drift.
Existing real-DB boundary tests for /activity/stats, /activity/daily-status,
and /activity/working-time-by-project cover all three consumers.
- Add feedback-card-parts.test.tsx (16 tests) for the FeedbackReplyForm and
FeedbackResolutionFooter shared components extracted in #836: reply trigger
toggle, Cmd/Ctrl+Enter submit, Escape/Cancel, whitespace Send gating,
pending disable + spinner placement, inline vs sidebar action-row layout,
Dismiss/Mark fixed/Reopen resolution routing, and resolution banner states.
Verified non-vacuous with a 10-mutation battery (10/10 caught).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
selfcontained added a commit that referenced this pull request Jul 27, 2026
…eadMessage (#840)
The reviews sidebar and the inline diff annotations each carried their own
copy of the thread-message bubble. The sidebar copy handled resolution/reopen
state-change messages; the inline copy rendered content.body ?? "", so a
body-less resolution message showed an empty bubble in the Changes tab.
Move the state-change-aware version into feedback-card-parts.tsx (already
shared by both surfaces since #836) and use it in both. Also align the inline
grouping predicate with the sidebar's (includes message type) so a state
change never merges into a preceding comment group.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto 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.

1 participant

@selfcontained