fix(web-shell): Polish transcript, sidebar, and manager page visuals (#10157)

* fix(web-shell): Polish transcript, sidebar, and manager page visuals

* fix(web-shell): Unify sidebar attention label branching and pin pill pairing (#10157)

Co-authored-by: Qwen-Coder <[email protected]>

* fix(web-shell): Pin sidebar attention pill style variant in test (#10157)

---------

Co-authored-by: qwen-code-ci-bot[bot] <qwen-code-ci-bot[bot]@users.noreply.github.com>
Co-authored-by: Qwen-Coder <[email protected]>
This commit is contained in:
authored and GitHub committed 2026-08-27 02:05:11 +00:00
1 parent 8241905392
commit 1ca8cc5fdb
5 files changed
+81 -10

No files matched your search

@@ -38,7 +38,7 @@
.metrics {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(86px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
gap: 8px;
}
@@ -57,6 +57,7 @@
.metric span {
color: var(--muted-foreground);
font-size: 11px;
white-space: nowrap;
}
.caps {
@@ -27,7 +27,7 @@
.content strong,
.content b {
color: var(--foreground);
font-weight: 500;
font-weight: 600;
}
.content h1,
@@ -548,6 +548,66 @@ describe('WebShellSidebar collapsed session group persistence', () => {
).not.toBeNull();
});
it('shows the expanded attention pill short label with the full accessible name', async () => {
active.sessions = [
makeSession('attention-approval', {
displayName: 'Needs approval',
isWaitingForPermission: true,
}),
];
active.data = active.sessions;
renderSidebar();
await flushSidebar();
let pill = container.querySelector<HTMLElement>(
`.${sidebarStyles.sessionAttention}`,
);
expect(pill?.textContent).toBe('Approval');
expect(pill?.getAttribute('aria-label')).toBe('Waiting for approval');
expect(
pill?.classList.contains(sidebarStyles.sessionAttentionUserInput),
).toBe(false);
active.sessions = [
makeSession('attention-approval-and-input', {
displayName: 'Needs approval and input',
isWaitingForPermission: true,
isWaitingForUserQuestion: true,
}),
];
active.data = active.sessions;
renderSidebar();
await flushSidebar();
pill = container.querySelector<HTMLElement>(
`.${sidebarStyles.sessionAttention}`,
);
expect(pill?.textContent).toBe('Approval');
expect(pill?.getAttribute('aria-label')).toBe('Waiting for approval');
expect(
pill?.classList.contains(sidebarStyles.sessionAttentionUserInput),
).toBe(false);
active.sessions = [
makeSession('attention-input', {
displayName: 'Needs input',
isWaitingForUserQuestion: true,
}),
];
active.data = active.sessions;
renderSidebar();
await flushSidebar();
pill = container.querySelector<HTMLElement>(
`.${sidebarStyles.sessionAttention}`,
);
expect(pill?.textContent).toBe('Input');
expect(pill?.getAttribute('aria-label')).toBe('User input needed');
expect(
pill?.classList.contains(sidebarStyles.sessionAttentionUserInput),
).toBe(true);
});
it('keeps project sessions available from the collapsed sidebar', async () => {
connection.capabilities = {
qwenCodeVersion: '1.2.3',
@@ -3976,10 +3976,16 @@ export function WebShellSidebar({
const isCurrent = isCurrentSession(session);
const needsUserInput =
!session.isWaitingForPermission && session.isWaitingForUserQuestion;
const attentionLabel = session.isWaitingForPermission
? t('sidebar.waitingForApproval')
const attention = session.isWaitingForPermission
? {
full: t('sidebar.waitingForApproval'),
short: t('sidebar.waitingForApprovalShort'),
}
: needsUserInput
? t('sidebar.userInputNeeded')
? {
full: t('sidebar.userInputNeeded'),
short: t('sidebar.userInputNeededShort'),
}
: null;
const showPin = canOrganizeSession(session, 'pin');
const showArchive =
@@ -4079,15 +4085,15 @@ export function WebShellSidebar({
: undefined
}
>
{attentionLabel && (
{attention && (
<span
className={cx(
styles.sessionAttention,
needsUserInput && styles.sessionAttentionUserInput,
)}
aria-label={attentionLabel}
aria-label={attention.full}
>
{attentionLabel}
{attention.short}
</span>
)}
{session.hasActivePrompt ? (
@@ -4095,7 +4101,7 @@ export function WebShellSidebar({
className={styles.sessionLoading}
aria-label={t('sidebar.running')}
/>
) : !attentionLabel && gitIcon ? (
) : !attention && gitIcon ? (
<span className={styles.sessionGitIcon}>{gitIcon}</span>
) : null}
{(showPin ||
+5 -1
View File
@@ -584,7 +584,7 @@ const EN: Messages = {
'common.previous': 'previous',
'common.expand': 'Expand',
'common.collapse': 'Collapse',
'common.refresh': 'refresh',
'common.refresh': 'Refresh',
'common.search': 'Search',
'common.valid': 'valid',
'common.clients': (v) => `${v?.count ?? 0} clients`,
@@ -1398,10 +1398,12 @@ const EN: Messages = {
'sidebar.clients': (v) => `${v?.count ?? 0} client(s)`,
'sidebar.running': 'Running',
'sidebar.waitingForApproval': 'Waiting for approval',
'sidebar.waitingForApprovalShort': 'Approval',
'sidebar.sessionPr': (v) => `Pull Request #${v?.number ?? ''}`,
'sidebar.sessionPrMultiple': (v) =>
`Pull Request #${v?.number ?? ''} (${v?.count ?? 0} total)`,
'sidebar.userInputNeeded': 'User input needed',
'sidebar.userInputNeededShort': 'Input',
'sidebar.completedUnread': 'Finished',
'sidebar.pin': 'Pin',
'sidebar.unpin': 'Unpin',
@@ -4448,10 +4450,12 @@ const ZH: Messages = {
'sidebar.clients': (v) => `${v?.count ?? 0} 个客户端`,
'sidebar.running': '运行中',
'sidebar.waitingForApproval': '等待批准',
'sidebar.waitingForApprovalShort': '待批准',
'sidebar.sessionPr': (v) => `合并请求 #${v?.number ?? ''}`,
'sidebar.sessionPrMultiple': (v) =>
`合并请求 #${v?.number ?? ''}(共 ${v?.count ?? 0} 个)`,
'sidebar.userInputNeeded': '需要用户输入',
'sidebar.userInputNeededShort': '需输入',
'sidebar.completedUnread': '刚完成',
'sidebar.pin': '置顶',
'sidebar.unpin': '取消置顶',