fix(sidebar): keep permission badge and hover actions from overlapping (#2284)

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
Serhii Dziupin
2026-08-06 19:57:07 +00:00
co-authored by Serhii Dziupin
parent fe331c093b
commit 604da92fd9
4 changed files with 71 additions and 5 deletions
@@ -26,7 +26,7 @@ import { buildSessionMessageRecordsSnapshot, useDirectoryStore, useGlobalSession
import { useSync } from '@/sync/use-sync';
import { useViewportStore, viewportSessionKey } from '@/sync/viewport-store';
import { DraggableSessionRow } from './sessionFolderDnd';
import { nodeContainsSessionId, nodeHasPinnedMembershipChange, selectQuestionBadgeSessionScopes } from './sessionNodeItemUtils';
import { nodeContainsSessionId, nodeHasPinnedMembershipChange, selectQuestionBadgeSessionScopes, selectRowBadgeVisibilityClass } from './sessionNodeItemUtils';
import type { SessionNodeChildRenderExtras, SessionNodeRenderExtras } from './sessionNodeItemUtils';
import type { SessionNode } from './types';
import { formatProjectLabel, formatSessionCompactDateLabel, formatSessionDateLabel, normalizePath, renderHighlightedText } from './utils';
@@ -684,6 +684,14 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
const pendingQuestionLabel = pendingQuestionCount === 1
? t('sessions.sidebar.session.status.questionPendingSingle')
: t('sessions.sidebar.session.status.questionPendingMany', { count: pendingQuestionCount });
// Actions are permanently visible (with matching permanent padding) only in
// the non-VSCode alwaysShowActions layout; every other layout hover-reveals
// them over the row's right edge, where the badges live (#2284).
const badgeVisibilityClass = selectRowBadgeVisibilityClass({
actionsAlwaysVisible: alwaysShowActions && !isVSCode,
menuOpen: isSessionMenuOpen,
hideOnHoverClass,
});
const showUnreadStatus = !isMovingToWorktree && !isStreaming && needsAttention && !isActive;
const showStatusMarker = isStreaming || showUnreadStatus;
// Both states are the same static dot; only the color separates "running"
@@ -1295,13 +1303,13 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
</div>
) : null}
{pendingPermissionCount > 0 ? (
<span className="inline-flex items-center gap-1 rounded bg-destructive/10 px-1 py-0.5 text-[0.7rem] text-destructive flex-shrink-0" title={t('sessions.sidebar.session.status.permissionRequired')} aria-label={t('sessions.sidebar.session.status.permissionRequired')}>
<span className={cn('inline-flex items-center gap-1 rounded bg-destructive/10 px-1 py-0.5 text-[0.7rem] text-destructive flex-shrink-0', badgeVisibilityClass)} title={t('sessions.sidebar.session.status.permissionRequired')} aria-label={t('sessions.sidebar.session.status.permissionRequired')}>
<Icon name="shield" className="h-3 w-3" />
<span className="leading-none">{pendingPermissionCount}</span>
</span>
) : null}
{pendingQuestionCount > 0 ? (
<span className="inline-flex items-center gap-1 rounded bg-status-info/10 px-1 py-0.5 text-[0.7rem] text-status-info flex-shrink-0" title={pendingQuestionLabel} aria-label={pendingQuestionLabel}>
<span className={cn('inline-flex items-center gap-1 rounded bg-status-info/10 px-1 py-0.5 text-[0.7rem] text-status-info flex-shrink-0', badgeVisibilityClass)} title={pendingQuestionLabel} aria-label={pendingQuestionLabel}>
<Icon name="question" className="h-3 w-3" />
<span className="leading-none">{pendingQuestionCount}</span>
</span>