open-swe/ui/src/components/agents/ReviewTab.tsx
Caroline di Vittorio 63e4c2baac
feat: relocate review chunks and embed review in git panel (#1590)
* feat: relocate review chunks and embed review in git panel

Move the AI-sorted review chunk navigator out of the global left sidebar
and into the review page's own main panel (sidebar keeps the thread list),
and surface the review main body inside the agent thread's Git > Review
sub-tab with an expand link to the full review page.

The review main body + side panel + helpers are extracted into a shared
ReviewMainBody component with "full" and "embedded" variants.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>

* chore: move ReviewTab into its own file

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-06-23 12:27:51 -07:00

72 lines
2.2 KiB
TypeScript

import { useNavigate } from "@tanstack/react-router"
import { useQuery } from "@tanstack/react-query"
import type { AgentThread } from "@/lib/agents/types"
import { ReviewMainBody } from "@/components/agents/ReviewMainBody"
import { api } from "@/lib/api"
// The git panel's "Review" sub-tab: the PR's Open SWE review rendered inline (no
// side panel / chat), with an expand affordance that opens the full review page.
export function ReviewTab({ thread }: { thread: AgentThread }) {
const navigate = useNavigate()
const pr = thread.pr
const [owner, repo] = thread.repoFullName.split("/")
const number = pr?.number ?? null
const enabled = Boolean(owner && repo && number !== null)
const detail = useQuery({
queryKey: ["review", owner, repo, number],
queryFn: () =>
api.getReview(owner as string, repo as string, number as number),
enabled,
refetchInterval: (query) =>
query.state.data?.status === "running" ? 5000 : false,
})
const diff = useQuery({
queryKey: ["reviewDiff", owner, repo, number],
queryFn: () =>
api.getReviewDiff(owner as string, repo as string, number as number),
enabled,
})
if (!enabled) {
return (
<div className="min-h-0 flex-1 overflow-y-auto p-6 text-center text-xs text-[var(--ui-text-dim)]">
Open a pull request to see its review here.
</div>
)
}
if (detail.isLoading) {
return (
<div className="min-h-0 flex-1 overflow-y-auto p-6 text-center text-xs text-[var(--ui-text-dim)]">
Loading review…
</div>
)
}
if (detail.error || !detail.data) {
return (
<div className="min-h-0 flex-1 overflow-y-auto p-6 text-center text-xs text-[var(--ui-text-dim)]">
No review for this pull request yet.
</div>
)
}
return (
<ReviewMainBody
key={detail.data.head_sha}
detail={detail.data}
diffFiles={diff.data?.files ?? null}
variant="embedded"
onExpand={() =>
navigate({
to: "/agents/reviews/$owner/$repo/$number",
params: {
owner: owner as string,
repo: repo as string,
number: String(number),
},
})
}
/>
)
}