Repository navigation
Expand file tree
/
Copy pathPullRequestStackPopover.tsx
More file actions
107 lines (105 loc) · 3.36 KB
/
Copy pathPullRequestStackPopover.tsx
File metadata and controls
107 lines (105 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { Tooltip, TooltipTrigger, TooltipPopup } from "../ui/tooltip";
import type { EnvironmentId, PullRequestRef, PullRequestStackMembership } from "@t3tools/contracts";
import { useState } from "react";
import { usePullRequestStack } from "~/state/usePullRequestStack";
import { Menu, MenuTrigger, MenuPopup, MenuGroup, MenuGroupLabel, MenuItem } from "../ui/menu";
import { PullRequestStackLayers } from "./PullRequestStackLayers";
import { PullRequestStackHeader } from "./PullRequestStackHeader";
import { PullRequestGlyph } from "./pullRequestIcons";
// Mount only on open to avoid per-row stack fetches.
function StackBody({
environmentId,
reference,
onSelect,
stackNumber,
}: {
environmentId: EnvironmentId;
reference: PullRequestRef;
onSelect: (reference: PullRequestRef) => void;
stackNumber: number;
}) {
const query = usePullRequestStack(environmentId, reference);
if (query.data !== null) {
return (
<>
<PullRequestStackHeader
number={query.data.number}
notice={query.notice}
stale={!!query.error}
/>
{query.error ? <MenuItem onClick={query.refresh}>Retry stack refresh</MenuItem> : null}
<PullRequestStackLayers stack={query.data} reference={reference} onSelect={onSelect} />
</>
);
}
return (
<>
<PullRequestStackHeader number={stackNumber} />
<MenuGroupLabel>
{query.error ??
(query.isPending ? "Loading stack…" : "This pull request is no longer in a stack.")}
</MenuGroupLabel>
</>
);
}
export function PullRequestStackPopover({
environmentId,
reference,
membership,
onSelect,
}: {
environmentId: EnvironmentId;
reference: PullRequestRef;
membership: PullRequestStackMembership;
onSelect: (reference: PullRequestRef) => void;
}) {
const [open, setOpen] = useState(false);
return (
<Menu open={open} onOpenChange={setOpen}>
<Tooltip>
<TooltipTrigger
render={
<MenuTrigger
nativeButton={false}
render={
<span
role="button"
tabIndex={0}
className="inline-flex shrink-0 cursor-pointer items-center gap-1 text-xs font-normal text-muted-foreground"
/>
}
aria-label={`Stack ${membership.number}, layer ${membership.position} of ${membership.size}`}
onClick={(event) => event.stopPropagation()}
onKeyDown={(event) => event.stopPropagation()}
>
<PullRequestGlyph.stack aria-hidden className="size-3" />
{membership.position}/{membership.size}
</MenuTrigger>
}
/>
<TooltipPopup>
View stack #{membership.number}, layer {membership.position} of {membership.size}
</TooltipPopup>
</Tooltip>
<MenuPopup
align="start"
onClick={(event) => event.stopPropagation()}
onKeyDown={(event) => event.stopPropagation()}
>
<MenuGroup>
{open ? (
<StackBody
environmentId={environmentId}
reference={reference}
stackNumber={membership.number}
onSelect={(target) => {
setOpen(false);
onSelect(target);
}}
/>
) : null}
</MenuGroup>
</MenuPopup>
</Menu>
);
}