| author | |
| committer | |
| log | 706231535ceac8618712913dfdc4a058c2ffb0d8 |
| tree | 69b14e0d379ad536a6a18d58f2cb86d96f6478ef |
| parent | 93c3ab4ffe408a3e06228a33efc8a0745da91178 |
| signature | Signed by PGP key B5690EEEBB952194 |
4 files changed, 43 insertions(+), 8 deletions(-)
apps/web/src/components/BranchToolbarBranchSelector.tsx+5-1| ... | ... | @@ -745,7 +745,11 @@ export function BranchToolbarBranchSelector({ |
| 745 | 745 | /> |
| 746 | 746 | } |
| 747 | 747 | > |
| 748 | <ChangeRequestStatusIcon className="size-3" /> | |
| 748 | <ChangeRequestStatusIcon | |
| 749 | state={branchPr.state} | |
| 750 | isDraft={branchPr.isDraft} | |
| 751 | className="size-3" | |
| 752 | /> | |
| 749 | 753 | <span |
| 750 | 754 | data-composer-label |
| 751 | 755 | className="min-w-0 max-w-12 overflow-hidden group-data-[compact]/composer-context:max-w-0" |
apps/web/src/components/LegacySidebar.tsx+6-2| ... | ... | @@ -720,7 +720,7 @@ export const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThr |
| 720 | 720 | onContextMenu={handleRowContextMenu} |
| 721 | 721 | > |
| 722 | 722 | <div className="flex min-w-0 flex-1 items-center gap-1.5 text-left"> |
| 723 | {prStatus && ( | |
| 723 | {prStatus && pr && ( | |
| 724 | 724 | <Tooltip> |
| 725 | 725 | <TooltipTrigger |
| 726 | 726 | render={ |
| ... | ... | @@ -733,7 +733,11 @@ export const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThr |
| 733 | 733 | onPointerDown={(event) => event.stopPropagation()} |
| 734 | 734 | onClick={handlePrClick} |
| 735 | 735 | > |
| 736 | <ChangeRequestStatusIcon className="size-3" /> | |
| 736 | <ChangeRequestStatusIcon | |
| 737 | state={pr.state} | |
| 738 | isDraft={pr.isDraft} | |
| 739 | className="size-3" | |
| 740 | /> | |
| 737 | 741 | </a> |
| 738 | 742 | } |
| 739 | 743 | /> |
apps/web/src/components/ThreadStatusIndicators.test.ts+18| ... | ... | @@ -2,8 +2,15 @@ import { ProjectId, type PullRequestSummary, type VcsStatusResult } from "@t3too |
| 2 | 2 | import { describe, expect, it } from "@effect/vitest"; |
| 3 | 3 | import * as Effect from "effect/Effect"; |
| 4 | 4 | import { AtomRegistry } from "effect/unstable/reactivity"; |
| 5 | import { | |
| 6 | GitMergeIcon, | |
| 7 | GitPullRequestClosedIcon, | |
| 8 | GitPullRequestDraftIcon, | |
| 9 | GitPullRequestIcon, | |
| 10 | } from "lucide-react"; | |
| 5 | 11 | |
| 6 | 12 | import { |
| 13 | ChangeRequestStatusIcon, | |
| 7 | 14 | nextThreadChangeRequestSnapshot, |
| 8 | 15 | prStatusIndicator, |
| 9 | 16 | resolveDisplayedThreadPr, |
| ... | ... | @@ -16,6 +23,17 @@ import { |
| 16 | 23 | } from "./ThreadStatusIndicators"; |
| 17 | 24 | import { newestPullRequestSummary } from "../state/pullRequests"; |
| 18 | 25 | |
| 26 | describe("ChangeRequestStatusIcon", () => { | |
| 27 | it.each([ | |
| 28 | ["open", "open", false, GitPullRequestIcon], | |
| 29 | ["draft", "open", true, GitPullRequestDraftIcon], | |
| 30 | ["closed", "closed", false, GitPullRequestClosedIcon], | |
| 31 | ["merged", "merged", false, GitMergeIcon], | |
| 32 | ] as const)("uses the %s pull request glyph", (_label, state, isDraft, expectedIcon) => { | |
| 33 | expect(ChangeRequestStatusIcon({ state, isDraft }).type).toBe(expectedIcon); | |
| 34 | }); | |
| 35 | }); | |
| 36 | ||
| 19 | 37 | function status(overrides: Partial<VcsStatusResult> = {}): VcsStatusResult { |
| 20 | 38 | return { |
| 21 | 39 | isRepo: true, |
apps/web/src/components/ThreadStatusIndicators.tsx+14-5| ... | ... | @@ -11,7 +11,7 @@ import { |
| 11 | 11 | type VcsStatusResult, |
| 12 | 12 | } from "@t3tools/contracts"; |
| 13 | 13 | import { Atom } from "effect/unstable/reactivity"; |
| 14 | import { FolderGit2Icon, GitPullRequestIcon, TerminalIcon } from "lucide-react"; | |
| 14 | import { FolderGit2Icon, TerminalIcon } from "lucide-react"; | |
| 15 | 15 | import { useMemo } from "react"; |
| 16 | 16 | import { appAtomRegistry } from "../rpc/atomRegistry"; |
| 17 | 17 | import { useEnvironment, usePrimaryEnvironmentId } from "../state/environments"; |
| ... | ... | @@ -24,6 +24,7 @@ import { vcsEnvironment } from "../state/vcs"; |
| 24 | 24 | import { useUiStateStore } from "../uiStateStore"; |
| 25 | 25 | import { resolveChangeRequestPresentation } from "../sourceControlPresentation"; |
| 26 | 26 | import { resolveThreadStatusPill, type ThreadStatusPill } from "./Sidebar.logic"; |
| 27 | import { resolvePullRequestState } from "./pullRequest/pullRequestPresentation"; | |
| 27 | 28 | import type { SidebarThreadSummary } from "../types"; |
| 28 | 29 | import { formatWorktreePathForDisplay } from "../worktreeCleanup"; |
| 29 | 30 | import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; |
| ... | ... | @@ -155,8 +156,16 @@ export function prStatusIndicator( |
| 155 | 156 | return null; |
| 156 | 157 | } |
| 157 | 158 | |
| 158 | export function ChangeRequestStatusIcon({ className }: { className?: string }) { | |
| 159 | return <GitPullRequestIcon className={className} />; | |
| 159 | export function ChangeRequestStatusIcon({ | |
| 160 | state, | |
| 161 | isDraft = false, | |
| 162 | className, | |
| 163 | }: Pick<NonNullable<ThreadPr>, "state"> & { | |
| 164 | readonly isDraft?: boolean | undefined; | |
| 165 | readonly className?: string | undefined; | |
| 166 | }) { | |
| 167 | const presentation = resolvePullRequestState({ state, isDraft }); | |
| 168 | return <presentation.Icon className={className} />; | |
| 160 | 169 | } |
| 161 | 170 | |
| 162 | 171 | export function PrStatusTooltipContent({ status }: { status: PrStatusIndicator }) { |
| ... | ... | @@ -585,7 +594,7 @@ export function ThreadRowLeadingStatus({ thread }: { thread: SidebarThreadSummar |
| 585 | 594 | |
| 586 | 595 | return ( |
| 587 | 596 | <span className="inline-flex shrink-0 items-center gap-1.5"> |
| 588 | {prStatus ? ( | |
| 597 | {prStatus && pr ? ( | |
| 589 | 598 | <Tooltip> |
| 590 | 599 | <TooltipTrigger |
| 591 | 600 | render={ |
| ... | ... | @@ -595,7 +604,7 @@ export function ThreadRowLeadingStatus({ thread }: { thread: SidebarThreadSummar |
| 595 | 604 | /> |
| 596 | 605 | } |
| 597 | 606 | > |
| 598 | <ChangeRequestStatusIcon className="size-3" /> | |
| 607 | <ChangeRequestStatusIcon state={pr.state} isDraft={pr.isDraft} className="size-3" /> | |
| 599 | 608 | </TooltipTrigger> |
| 600 | 609 | <TooltipPopup side="top"> |
| 601 | 610 | <PrStatusTooltipContent status={prStatus} /> |