Skip to content

Commit c4e4edc

Browse files
committed
feat(web): collapse resolved conversations on the pull request summary
1 parent d06636c commit c4e4edc

1 file changed

Lines changed: 62 additions & 10 deletions

File tree

‎apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx‎

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import type { EnvironmentId, PullRequestDetailView, PullRequestRef } from "@t3tools/contracts";
1+
import type {
2+
EnvironmentId,
3+
PullRequestComment,
4+
PullRequestDetailView,
5+
PullRequestRef,
6+
} from "@t3tools/contracts";
27
import {
38
ArrowDownUpIcon,
49
CheckCircle2Icon,
10+
ChevronDownIcon,
511
ChevronRightIcon,
612
HammerIcon,
713
MessageSquareIcon,
@@ -44,6 +50,51 @@ function labelDotColor(color: string | null): string | null {
4450
return /^[0-9a-fA-F]{6}$/.test(hex) ? `#${hex}` : null;
4551
}
4652

53+
/** A resolved conversation is finished work, so it opens collapsed the way the timeline folds. */
54+
function ResolvedComment({ comment, cwd }: { comment: PullRequestComment; cwd: string }) {
55+
const [open, setOpen] = useState(false);
56+
return (
57+
<Collapsible open={open} onOpenChange={setOpen}>
58+
<article className="rounded-lg border border-border/60 [contain-intrinsic-block-size:44px] [content-visibility:auto]">
59+
<CollapsibleTrigger
60+
className={cn(
61+
"flex w-full items-center gap-2 p-3 text-left transition-opacity hover:opacity-100",
62+
open ? "opacity-100" : "opacity-65",
63+
)}
64+
>
65+
<PullRequestMetaLine className="min-w-0 flex-1 text-xs text-muted-foreground">
66+
<PullRequestActorLabel actor={comment.author} className="font-medium text-foreground" />
67+
<span>{formatRelativeTimeLabel(comment.createdAt)}</span>
68+
<span className="flex items-center gap-1 text-emerald-600 dark:text-emerald-500">
69+
<CheckCircle2Icon className="size-3" />
70+
Resolved
71+
</span>
72+
</PullRequestMetaLine>
73+
<ChevronDownIcon
74+
aria-hidden
75+
className={cn(
76+
"size-3.5 shrink-0 text-muted-foreground transition-transform",
77+
open && "rotate-180",
78+
)}
79+
/>
80+
</CollapsibleTrigger>
81+
<CollapsiblePanel>
82+
{open ? (
83+
<div className="px-3 pb-3">
84+
{comment.path ? (
85+
<p className="truncate text-xs text-muted-foreground" title={comment.path}>
86+
{comment.path}
87+
</p>
88+
) : null}
89+
<PullRequestMarkdown className="mt-2" text={comment.body} cwd={cwd} />
90+
</div>
91+
) : null}
92+
</CollapsiblePanel>
93+
</article>
94+
</Collapsible>
95+
);
96+
}
97+
4798
function MetaRow({
4899
icon,
49100
label,
@@ -415,16 +466,23 @@ export function PullRequestSummaryTab({
415466
) : null}
416467
{visibleComments.map((comment) => {
417468
const thread = threadByCommentId.get(comment.id);
469+
if (thread?.isResolved) {
470+
return (
471+
<ResolvedComment
472+
key={comment.id}
473+
comment={comment}
474+
cwd={detail.workspaceRoot}
475+
/>
476+
);
477+
}
418478
// An approval is a verdict, not a finding: there is nothing in it to fix.
419479
const finding: PullRequestFinding | null =
420480
(comment.kind !== "review" && comment.kind !== "review-comment") ||
421481
comment.reviewState?.toLowerCase() === "approved"
422482
? null
423483
: thread === undefined
424484
? { kind: "comment", comment }
425-
: thread.isResolved
426-
? null
427-
: { kind: "thread", thread };
485+
: { kind: "thread", thread };
428486
return (
429487
<article
430488
key={comment.id}
@@ -442,12 +500,6 @@ export function PullRequestSummaryTab({
442500
{comment.reviewState ? (
443501
<span>{comment.reviewState.toLowerCase()}</span>
444502
) : null}
445-
{thread?.isResolved ? (
446-
<span className="flex items-center gap-1 text-emerald-600 dark:text-emerald-500">
447-
<CheckCircle2Icon className="size-3" />
448-
Resolved
449-
</span>
450-
) : null}
451503
</PullRequestMetaLine>
452504
{/* Review remarks only. A plain conversation comment is talk, not a finding,
453505
and offering to fix one would promise more than it says. */}

0 commit comments

Comments
 (0)