diff --git a/apps/web/src/components/pullRequest/PullRequestMarkdown.tsx b/apps/web/src/components/pullRequest/PullRequestMarkdown.tsx index edfc1c19f10..9a4b63044ad 100644 --- a/apps/web/src/components/pullRequest/PullRequestMarkdown.tsx +++ b/apps/web/src/components/pullRequest/PullRequestMarkdown.tsx @@ -39,7 +39,13 @@ export function PullRequestMarkdown({ [repositoryUrl], ); return ( -
+
svg]:text-muted-foreground/60", + className, + )} + data-image-gallery + > {segments.map((segment) => { if (segment.kind === "markdown") { return ( diff --git a/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx b/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx index fed932d457a..c3650d72cc5 100644 --- a/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx +++ b/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx @@ -12,14 +12,13 @@ import { ChevronRightIcon, GitPullRequestClosedIcon, HammerIcon, - MessageSquareIcon, PencilIcon, RotateCcwIcon, SendIcon, TagIcon, UsersIcon, } from "lucide-react"; -import { useRef, useState, type ReactNode } from "react"; +import { useId, useRef, useState, type ReactNode } from "react"; import { useAtomCommand } from "~/state/use-atom-command"; import { pullRequestEnvironment } from "~/state/pullRequests"; @@ -187,7 +186,7 @@ function CollapsedComment({ @@ -229,8 +228,8 @@ function MetaRow({ children: ReactNode; }) { return ( -
- +
+ {icon} {label} @@ -241,16 +240,13 @@ function MetaRow({ function Section({ title, - count, defaultOpen = true, actions, children, }: { title: string; - count?: number; defaultOpen?: boolean; - /** Controls riding on the heading row itself. A sibling of the trigger, not a child of it — - a button cannot hold a button — and only while open, since they act on what is shown. */ + /** Heading controls stay separate from the collapse trigger so they remain independently usable. */ actions?: ReactNode; children: ReactNode; }) { @@ -286,24 +282,19 @@ function Section({ where it started. Opaque, because the rows it covers scroll beneath it. */}
- {/* Title first, chevron riding to its right, count last: the row reads as a heading - with an affordance rather than a tree node. */} - + {title} - {count === undefined ? null : ( - {count} - )} - {open ? actions : null} + {actions}
{children}
@@ -461,6 +452,9 @@ export function PullRequestSummaryTab({ // Keyed by the pull request, so opening another one starts at the end of its conversation // rather than wherever the last one had been read back to. const [shown, setShown] = useState({ url: detail.url, count: COMMENT_PAGE }); + const checksId = useId(); + const [expandedChecksUrl, setExpandedChecksUrl] = useState(null); + const showChecks = expandedChecksUrl === detail.url; const shownComments = shown.url === detail.url ? shown.count : COMMENT_PAGE; // Windowed by recency regardless of display order: expanding always reaches further back in // time, whether the newest comment currently reads first or last. @@ -596,8 +590,8 @@ export function PullRequestSummaryTab({ return (
-
-
+
+
} label="Reviewers"> {reviewerEntries.length === 0 ? ( @@ -701,7 +695,7 @@ export function PullRequestSummaryTab({ return ( ) : null} - } label="Comments"> - {activityPending - ? "Loading conversation…" - : activityError - ? "Conversation unavailable" - : detail.commentCount === 1 - ? "1 comment" - : `${detail.commentCount} comments`} -
-
+
{bodyScope === detail.url ? (
-
+
-
+
{detail.checks.length === 0 ? (

No checks reported.

) : ( -
- {detail.checks.map((check, index) => { - const finding = { kind: "check", check } as const; - const failing = check.status === "failure" || check.status === "cancelled"; - return ( -
- +
+
+ {(showChecks ? detail.checks : []).map((check, index) => { + const finding = { kind: "check", check } as const; + const failing = check.status === "failure" || check.status === "cancelled"; + return ( +
- - {check.name} - - {pullRequestCheckStatusLabel(check)} - - - {/* Only where there is something to fix. A passing check has no failure to - reproduce, and the button would be an invitation to waste a thread. */} - {onFixFinding && failing ? ( - - ) : null} -
- ); - })} + + {check.name} + + {pullRequestCheckStatusLabel(check)} + + + {/* Only where there is something to fix. A passing check has no failure to + reproduce, and the button would be an invitation to waste a thread. */} + {onFixFinding && failing ? ( + + ) : null} +
+ ); + })} +
)} -
+
0 ? ( - - ) : null + } > {activityPending ? (