mirror of
https://github.com/block/buzz.git
synced 2026-11-06 09:21:45 +00:00
desktop: keep PR metadata readable in Inbox
Wrap pull request metadata between complete phrases and truncate long channel names so the Inbox detail rail cannot compress copy into word-wide columns. Signed-off-by: Thomas Petersen <thomasp@squareup.com>
This commit is contained in:
@@ -17,7 +17,7 @@ export function ProjectOriginReference({
|
||||
if (channelId) {
|
||||
return (
|
||||
<span
|
||||
className="inline-flex min-w-0 items-center gap-1"
|
||||
className="inline-flex max-w-full min-w-0 items-center gap-1"
|
||||
title={
|
||||
channel
|
||||
? "Origin is claimed by the event author and is not relay-verified."
|
||||
@@ -27,20 +27,30 @@ export function ProjectOriginReference({
|
||||
`Origin channel ${channelId} is not visible to you. Origin is claimed by the event author and is not relay-verified.`
|
||||
}
|
||||
>
|
||||
<span>started from</span>
|
||||
<span
|
||||
className="shrink-0 whitespace-nowrap"
|
||||
data-project-metadata-phrase
|
||||
>
|
||||
started from
|
||||
</span>
|
||||
{channel ? (
|
||||
<button
|
||||
aria-label={`Open author-claimed origin channel #${channel.name}`}
|
||||
className="truncate font-medium text-foreground underline-offset-2 hover:underline"
|
||||
className="min-w-0 truncate font-medium text-foreground underline-offset-2 hover:underline"
|
||||
onClick={() => void goChannel(channel.id)}
|
||||
type="button"
|
||||
>
|
||||
#{channel.name}
|
||||
</button>
|
||||
) : (
|
||||
<span>a private channel</span>
|
||||
<span className="shrink-0 whitespace-nowrap">a private channel</span>
|
||||
)}
|
||||
<span>(author-claimed)</span>
|
||||
<span
|
||||
className="shrink-0 whitespace-nowrap"
|
||||
data-project-metadata-phrase
|
||||
>
|
||||
(author-claimed)
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -48,10 +58,15 @@ export function ProjectOriginReference({
|
||||
if (agentName) {
|
||||
return (
|
||||
<span
|
||||
className="inline-flex min-w-0 items-center gap-1"
|
||||
className="inline-flex max-w-full min-w-0 items-center gap-1"
|
||||
title="The private conversation identifier is intentionally omitted."
|
||||
>
|
||||
<span>started privately with</span>
|
||||
<span
|
||||
className="shrink-0 whitespace-nowrap"
|
||||
data-project-metadata-phrase
|
||||
>
|
||||
started privately with
|
||||
</span>
|
||||
<span className="truncate font-medium text-foreground">
|
||||
{agentName}
|
||||
</span>
|
||||
|
||||
@@ -359,9 +359,15 @@ export function PullRequestDetailHeader({
|
||||
testId="project-pull-request-copy-link"
|
||||
/>
|
||||
</h3>
|
||||
<p className="flex items-center gap-1 text-xs font-medium text-muted-foreground">
|
||||
<GitPullRequest className="h-3.5 w-3.5" />
|
||||
<span className="flex min-w-0 items-center gap-1">
|
||||
<p
|
||||
className="flex flex-wrap items-center gap-x-1 gap-y-1 text-xs font-medium text-muted-foreground"
|
||||
data-testid="project-pull-request-detail-metadata"
|
||||
>
|
||||
<GitPullRequest className="h-3.5 w-3.5 shrink-0" />
|
||||
<span
|
||||
className="flex min-w-0 items-center gap-1"
|
||||
data-project-metadata-phrase
|
||||
>
|
||||
<AuthorIdentity
|
||||
avatarSize="xs"
|
||||
profiles={profiles}
|
||||
@@ -372,7 +378,11 @@ export function PullRequestDetailHeader({
|
||||
{authorLabel}
|
||||
</ProfileAuthorName>
|
||||
</span>
|
||||
<span title={formatExactTimestamp(pullRequest.createdAt)}>
|
||||
<span
|
||||
className="shrink-0 whitespace-nowrap"
|
||||
data-project-metadata-phrase
|
||||
title={formatExactTimestamp(pullRequest.createdAt)}
|
||||
>
|
||||
created {relativeTime(pullRequest.createdAt)}
|
||||
</span>
|
||||
<ProjectOriginReference
|
||||
|
||||
@@ -143,4 +143,41 @@ test("Buzz Git pull request renders and stays actionable in Inbox", async ({
|
||||
await detail.screenshot({
|
||||
path: "test-results/project-inbox/01-pull-request-detail.png",
|
||||
});
|
||||
|
||||
// At the wide two-column breakpoint, metadata may wrap between phrases but
|
||||
// must never compress individual phrases into word-wide columns.
|
||||
await page.setViewportSize({ width: 1440, height: 900 });
|
||||
await expect
|
||||
.poll(() =>
|
||||
layout.evaluate(
|
||||
(element) =>
|
||||
getComputedStyle(element)
|
||||
.gridTemplateColumns.split(" ")
|
||||
.filter(Boolean).length,
|
||||
),
|
||||
)
|
||||
.toBe(2);
|
||||
await expect(
|
||||
detail.getByRole("button", {
|
||||
name: "Open author-claimed origin channel #general",
|
||||
}),
|
||||
).toBeVisible();
|
||||
const metadataPhrases = detail.locator("[data-project-metadata-phrase]");
|
||||
await expect(metadataPhrases).not.toHaveCount(0);
|
||||
const phraseLayouts = await metadataPhrases.evaluateAll((phrases) =>
|
||||
phrases.map((phrase) => {
|
||||
const style = getComputedStyle(phrase);
|
||||
return {
|
||||
height: phrase.getBoundingClientRect().height,
|
||||
lineHeight: Number.parseFloat(style.lineHeight),
|
||||
};
|
||||
}),
|
||||
);
|
||||
for (const phrase of phraseLayouts) {
|
||||
expect(phrase.height).toBeLessThanOrEqual(phrase.lineHeight * 1.5);
|
||||
}
|
||||
await waitForAnimations(page);
|
||||
await detail.screenshot({
|
||||
path: "test-results/project-inbox/02-pull-request-detail-wide.png",
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user