From 253ef03b1eb4fe297be5797f808aa8af26597260 Mon Sep 17 00:00:00 2001 From: brennanb2025 Date: Wed, 24 Jun 2026 12:28:59 -0700 Subject: [PATCH] Improve PR comment sidebar readability Co-authored-by: Orca --- .../components/right-sidebar/ChecksPanel.tsx | 10 +++---- .../ChecksPanel.updated-at-metadata.test.tsx | 28 +++++++++++++++++++ .../checks-panel-updated-at-metadata.tsx | 20 +++++++++++++ .../pr-comment-presentation.test.ts | 8 ++++-- .../right-sidebar/pr-comment-presentation.ts | 11 ++++---- 5 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/renderer/src/components/right-sidebar/ChecksPanel.updated-at-metadata.test.tsx create mode 100644 src/renderer/src/components/right-sidebar/checks-panel-updated-at-metadata.tsx diff --git a/src/renderer/src/components/right-sidebar/ChecksPanel.tsx b/src/renderer/src/components/right-sidebar/ChecksPanel.tsx index 9eb7cef2eee..9f54c3c8470 100644 --- a/src/renderer/src/components/right-sidebar/ChecksPanel.tsx +++ b/src/renderer/src/components/right-sidebar/ChecksPanel.tsx @@ -145,6 +145,7 @@ import { localizedHostedReviewCopy } from '@/i18n/hosted-review-localized-copy' import { translate } from '@/i18n/i18n' import { groupPRComments, type PRCommentGroup } from '@/lib/pr-comment-groups' import { openChecksPanelHostedReviewUrl } from './checks-panel-hosted-review-click-routing' +import { ChecksPanelUpdatedAtMetadata } from './checks-panel-updated-at-metadata' import { clearPullRequestGenerationRequiresPushBeforeCreate, createRunningPullRequestGenerationRecord, @@ -3469,11 +3470,10 @@ export default function ChecksPanel(): React.JSX.Element { {/* Updated at */} {activeReview.updatedAt && ( -
- {reviewShortLabel}{' '} - {translate('auto.components.right.sidebar.ChecksPanel.34464d00b9', 'updated')} - {new Date(activeReview.updatedAt).toLocaleString()} -
+ )} {/* Merge / Delete Workspace actions */} {activeReview && activeWorktree && repo && ( diff --git a/src/renderer/src/components/right-sidebar/ChecksPanel.updated-at-metadata.test.tsx b/src/renderer/src/components/right-sidebar/ChecksPanel.updated-at-metadata.test.tsx new file mode 100644 index 00000000000..48e9dc210ea --- /dev/null +++ b/src/renderer/src/components/right-sidebar/ChecksPanel.updated-at-metadata.test.tsx @@ -0,0 +1,28 @@ +// @vitest-environment happy-dom + +import { renderToStaticMarkup } from 'react-dom/server' +import { describe, expect, it } from 'vitest' +import { ChecksPanelUpdatedAtMetadata } from './checks-panel-updated-at-metadata' + +function renderMetadataText(reviewShortLabel: string): string { + const container = document.createElement('div') + container.innerHTML = renderToStaticMarkup( + + ) + return container.textContent ?? '' +} + +describe('ChecksPanel updated-at metadata', () => { + it.each(['PR', 'MR'])( + 'renders a whitespace boundary between the %s updated label and timestamp', + (reviewShortLabel) => { + const text = renderMetadataText(reviewShortLabel) + + expect(text).toMatch(new RegExp(`${reviewShortLabel} updated\\s+\\S`)) + expect(text).not.toMatch(new RegExp(`${reviewShortLabel} updated\\S`)) + } + ) +}) diff --git a/src/renderer/src/components/right-sidebar/checks-panel-updated-at-metadata.tsx b/src/renderer/src/components/right-sidebar/checks-panel-updated-at-metadata.tsx new file mode 100644 index 00000000000..4c4a90b7ecd --- /dev/null +++ b/src/renderer/src/components/right-sidebar/checks-panel-updated-at-metadata.tsx @@ -0,0 +1,20 @@ +import type React from 'react' +import { translate } from '@/i18n/i18n' + +type ChecksPanelUpdatedAtMetadataProps = { + reviewShortLabel: string + updatedAt: string +} + +export function ChecksPanelUpdatedAtMetadata({ + reviewShortLabel, + updatedAt +}: ChecksPanelUpdatedAtMetadataProps): React.JSX.Element { + return ( +
+ {reviewShortLabel}{' '} + {translate('auto.components.right.sidebar.ChecksPanel.34464d00b9', 'updated')}{' '} + {new Date(updatedAt).toLocaleString()} +
+ ) +} diff --git a/src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts b/src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts index cfee6f48d8b..abe5ddbe8de 100644 --- a/src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts +++ b/src/renderer/src/components/right-sidebar/pr-comment-presentation.test.ts @@ -22,8 +22,12 @@ describe('pr-comment-presentation', () => { expect(cards.avatar).toContain('border-border') expect(cards.avatar).toContain('bg-background') - expect(getPRCommentPresentationClasses('focus').useCardLayout).toBe(true) - expect(getPRCommentPresentationClasses('focus').commentBody).toContain('text-[14px]') + const focus = getPRCommentPresentationClasses('focus') + expect(focus.useCardLayout).toBe(true) + expect(focus.commentBody).toContain('text-[13px]') + expect(focus.commentBodyReply).toContain('text-[13px]') + expect(focus.author).toContain('text-[13px]') + expect(focus.list).toContain('gap-3') }) it('preserves the legacy flat layout tokens', () => { diff --git a/src/renderer/src/components/right-sidebar/pr-comment-presentation.ts b/src/renderer/src/components/right-sidebar/pr-comment-presentation.ts index 7b9a645b994..3553d6b798b 100644 --- a/src/renderer/src/components/right-sidebar/pr-comment-presentation.ts +++ b/src/renderer/src/components/right-sidebar/pr-comment-presentation.ts @@ -96,6 +96,9 @@ const COMMENT_AVATAR = const RESOLVED_SECTION_LABEL = 'text-[11px] font-semibold uppercase tracking-wider text-muted-foreground' +const CARD_COMMENT_BODY_SIZE = 'text-[13px] leading-relaxed' +const CARD_COMMENT_AUTHOR_SIZE = 'text-[13px]' + const RESOLVED_SECTION_TRIGGER = cn( RESOLVED_SECTION_LABEL, 'rounded-none border-0 bg-transparent px-3 py-2 shadow-none hover:bg-accent/40 hover:text-foreground hover:no-underline' @@ -173,8 +176,6 @@ export function getPRCommentPresentationClasses( } const isFocus = variant === 'focus' - const bodySize = isFocus ? 'text-[14px] leading-relaxed' : 'text-[13px] leading-relaxed' - const authorSize = isFocus ? 'text-[14px]' : 'text-[13px]' const listGap = isFocus ? 'gap-3' : 'gap-2' const bodyPadding = isFocus ? 'px-4 py-3' : 'px-4 py-2.5' const headerPadding = isFocus ? 'px-3.5 py-2.5' : 'px-3 py-2' @@ -191,10 +192,10 @@ export function getPRCommentPresentationClasses( commentRowReply: `border-t ${COMMENT_CARD_DIVIDER} bg-muted/25 dark:bg-muted/10`, commentHeader: `flex flex-col gap-1 border-b ${COMMENT_CARD_DIVIDER} ${headerPadding}`, commentHeaderReply: `flex min-w-0 items-center gap-2 ${headerPadding}`, - commentBody: `${bodyPadding} ${bodySize} text-foreground`, - commentBodyReply: `${bodyPadding} ${bodySize} text-foreground`, + commentBody: `${bodyPadding} ${CARD_COMMENT_BODY_SIZE} text-foreground`, + commentBodyReply: `${bodyPadding} ${CARD_COMMENT_BODY_SIZE} text-foreground`, commentBodyMarkdown: MARKDOWN_BASE, - author: `min-w-0 flex-1 truncate ${authorSize} font-semibold text-foreground`, + author: `min-w-0 flex-1 truncate ${CARD_COMMENT_AUTHOR_SIZE} font-semibold text-foreground`, authorResolved: 'text-muted-foreground', avatar: `size-5 ${COMMENT_AVATAR}`, avatarReply: `size-4 ${COMMENT_AVATAR}`,