mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
test(ui): reply-to-comment scenario in the Issue Chat UX Lab
Adds a fixture-backed reply section to /tests/ux/chat exercising the P3 states: composer reply chip (seeded via localStorage), sent quoted block, and the deleted-source tombstone. Gives QA a live in-app surface to test against. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0fb4f879f2
commit
ad90fa2ebe
2 files changed
+112
No files matched your search
@@ -338,6 +338,75 @@ export const issueChatUxReviewEvents: IssueTimelineEvent[] = [
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Reply-to-comment (PAP-13802 P3) scenario: a sent reply with a quoted block, a reply whose
|
||||
* source was deleted (tombstone), and the source comments they point back to. Seed
|
||||
* {@link issueChatUxReplyDraftKey} in localStorage to also render the composer reply chip.
|
||||
*/
|
||||
export const issueChatUxReplyDraftKey = "paperclip:issue-comment-draft:issue-ux-reply";
|
||||
|
||||
export const issueChatUxReplyComments: IssueChatComment[] = [
|
||||
createComment({
|
||||
id: "comment-reply-source",
|
||||
authorAgentId: primaryAgent.id,
|
||||
authorUserId: null,
|
||||
body: "I moved the composer reply chip above the editor and clamp the quoted source to 200 chars so long comments stay one line.",
|
||||
createdAt: new Date("2026-04-06T13:00:00.000Z"),
|
||||
updatedAt: new Date("2026-04-06T13:00:00.000Z"),
|
||||
runId: "run-reply-1",
|
||||
runAgentId: primaryAgent.id,
|
||||
}),
|
||||
createComment({
|
||||
id: "comment-reply-sent",
|
||||
body: "Nice — can you make the quoted block jump to the original when clicked?",
|
||||
createdAt: new Date("2026-04-06T13:02:00.000Z"),
|
||||
updatedAt: new Date("2026-04-06T13:02:00.000Z"),
|
||||
metadata: {
|
||||
version: 1,
|
||||
sections: [],
|
||||
replyTo: {
|
||||
commentId: "comment-reply-source",
|
||||
authorType: "agent",
|
||||
authorAgentId: primaryAgent.id,
|
||||
authorUserId: null,
|
||||
excerpt: "I moved the composer reply chip above the editor and clamp the quoted source to 200 chars so long comments stay one line.",
|
||||
excerptTruncated: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
createComment({
|
||||
id: "comment-reply-deleted-source",
|
||||
body: "This source comment was removed after the reply was posted.",
|
||||
createdAt: new Date("2026-04-06T13:04:00.000Z"),
|
||||
updatedAt: new Date("2026-04-06T13:04:30.000Z"),
|
||||
deletedAt: new Date("2026-04-06T13:05:00.000Z"),
|
||||
deletedByType: "user",
|
||||
deletedByUserId: "user-1",
|
||||
}),
|
||||
createComment({
|
||||
id: "comment-reply-tombstone",
|
||||
authorAgentId: reviewAgent.id,
|
||||
authorUserId: null,
|
||||
body: "Done — and when the source is deleted the quoted header falls back to a tombstone.",
|
||||
createdAt: new Date("2026-04-06T13:06:00.000Z"),
|
||||
updatedAt: new Date("2026-04-06T13:06:00.000Z"),
|
||||
runId: "run-reply-2",
|
||||
runAgentId: reviewAgent.id,
|
||||
metadata: {
|
||||
version: 1,
|
||||
sections: [],
|
||||
replyTo: {
|
||||
commentId: "comment-reply-deleted-source",
|
||||
authorType: "user",
|
||||
authorAgentId: null,
|
||||
authorUserId: "user-1",
|
||||
excerpt: "This source comment was removed after the reply was posted.",
|
||||
excerptTruncated: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
export const issueChatUxFeedbackVotes: FeedbackVote[] = [
|
||||
{
|
||||
id: "feedback-1",
|
||||
|
||||
@@ -16,6 +16,8 @@ import {
|
||||
issueChatUxLiveRuns,
|
||||
issueChatUxMentions,
|
||||
issueChatUxReassignOptions,
|
||||
issueChatUxReplyComments,
|
||||
issueChatUxReplyDraftKey,
|
||||
issueChatUxReviewComments,
|
||||
issueChatUxReviewEvents,
|
||||
issueChatUxSubmittingComments,
|
||||
@@ -143,6 +145,24 @@ function RotatingReasoningDemo({ intervalMs = 2200 }: { intervalMs?: number }) {
|
||||
export function IssueChatUxLab() {
|
||||
const [showComposer, setShowComposer] = useState(true);
|
||||
|
||||
// Seed a composer reply draft so the reply-scenario section renders the chip on load.
|
||||
useEffect(() => {
|
||||
try {
|
||||
localStorage.setItem(
|
||||
`${issueChatUxReplyDraftKey}:reply`,
|
||||
JSON.stringify({
|
||||
commentId: "comment-reply-source",
|
||||
authorName: "CodexCoder",
|
||||
excerpt:
|
||||
"I moved the composer reply chip above the editor and clamp the quoted source to 200 chars so long comments stay one line.",
|
||||
excerptTruncated: true,
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// Ignore localStorage failures in the lab preview.
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="overflow-hidden rounded-(--rad-32) border border-border/70 bg-[linear-gradient(135deg,rgba(8,145,178,0.10),transparent_28%),linear-gradient(180deg,rgba(245,158,11,0.10),transparent_44%),var(--background)] shadow-[0_30px_80px_rgba(15,23,42,0.10)]">
|
||||
@@ -296,6 +316,29 @@ export function IssueChatUxLab() {
|
||||
/>
|
||||
</LabSection>
|
||||
|
||||
<LabSection
|
||||
id="reply-to-comment"
|
||||
eyebrow="Reply to comment"
|
||||
title="Reply chip, quoted block, and tombstone"
|
||||
description="PAP-13802 P3: hover a bubble to reveal Reply, the composer shows a quoted/clamped source chip (click to jump to the original, X or Escape to clear), sent replies render a quoted header above the body, and a reply whose source was deleted falls back to an 'Original comment deleted' tombstone."
|
||||
accentClassName="bg-[linear-gradient(180deg,rgba(16,185,129,0.06),transparent_28%),var(--background)]"
|
||||
>
|
||||
<IssueChatThread
|
||||
comments={issueChatUxReplyComments}
|
||||
linkedRuns={[]}
|
||||
timelineEvents={[]}
|
||||
issueStatus="in_progress"
|
||||
agentMap={issueChatUxAgentMap}
|
||||
currentUserId="user-1"
|
||||
onAdd={noop}
|
||||
onVote={noop}
|
||||
draftKey={issueChatUxReplyDraftKey}
|
||||
mentions={issueChatUxMentions}
|
||||
showComposer={showComposer}
|
||||
enableLiveTranscriptPolling={false}
|
||||
/>
|
||||
</LabSection>
|
||||
|
||||
<LabSection
|
||||
eyebrow="Submitting state"
|
||||
title="Pending message bubble"
|
||||
|
||||
Reference in new issue
Block a user