fix(workspace): tooltip the row hover actions and open the sliders glyph

This commit is contained in:
Yif authored and imccyu committed 2026-09-19 12:04:07 +08:00
1 parent 94c62ea564
commit 9ca19474ab
3 files changed
+60 -49

No files matched your search

@@ -1559,10 +1559,10 @@ export const IconArchiveCheckOutlineMedium = (props: IconProps) => (
const IconSlidersTwoOutlineArtwork = ({ size = 16, className, strokeWidth }: WeightedIconProps) => (
<svg width={size} height={size} className={className} viewBox="0 0 16 16" fill="none"
stroke="currentColor" strokeLinecap="round" aria-hidden="true" strokeWidth={strokeWidth}>
<path d="M2.3 5.4h5.85M12.05 5.4h1.65" />
<circle cx="9.95" cy="5.4" r="1.45" />
<path d="M2.3 10.6h1.65M7.85 10.6h5.85" />
<circle cx="5.75" cy="10.6" r="1.45" />
<path d="M2.3 5h5.85M12.05 5h1.65" />
<circle cx="9.95" cy="5" r="1.45" />
<path d="M2.3 11h1.65M7.85 11h5.85" />
<circle cx="5.75" cy="11" r="1.45" />
</svg>
)
@@ -64,6 +64,8 @@ export const zh = {
'sessions.count.other': '{n} 个会话',
'actions.workspace.aria': '工作区“{name}”的操作',
'actions.session.aria': '会话“{name}”的操作',
'actions.more': '更多操作',
'actions.newSession': '新会话',
'actions.newSession.aria': '在“{name}”中新建会话',
'status.running': '进行中',
'status.subagentsRunning.one': '{n} 个子代理运行中',
@@ -152,6 +154,8 @@ export const en = {
'sessions.count.other': '{n} sessions',
'actions.workspace.aria': 'Workspace actions for {name}',
'actions.session.aria': 'Session actions for {name}',
'actions.more': 'More actions',
'actions.newSession': 'New session',
'actions.newSession.aria': 'New session in {name}',
'status.running': 'Running',
'status.subagentsRunning.one': '{n} subagent running',
@@ -12,7 +12,7 @@ import {
HoverCard, IconAlarmClockOutlineRegular, IconArchiveOutlineRegular, IconBranchOutlineRegular,
IconEditOutlineRegular, IconEllipsisOutlineRegular, IconFolderCloseRegular, IconFolderOpenRegular,
IconNewChatOutlineRegular, IconPinFillRegular, IconPinOutlineRegular, IconTrashOutlineRegular,
IconTriangleRightFillRegular, IconUnarchiveOutlineRegular, Menu, relativeTime, StateDot,
IconTriangleRightFillRegular, IconUnarchiveOutlineRegular, Menu, relativeTime, StateDot, Tooltip,
} from '@deepseek-ai/dsh-client-ui-primitives'
import type { StateDotState } from '@deepseek-ai/dsh-client-ui-primitives'
import { abbreviateHomePath } from '@deepseek-ai/dsh-util-workspace-path'
@@ -176,25 +176,29 @@ export function ProjectRowItem({ group, containsCurrentDescendant = false, onTog
portal
closeOnPointerLeave
anchor={(
<button
type="button"
className={css.iconButton}
aria-label={t('actions.workspace.aria', { name: label })}
onClick={(e) => { e.stopPropagation(); setMenuOpen(v => !v) }}
>
<IconEllipsisOutlineRegular />
</button>
<Tooltip label={t('actions.more')} side="bottom" delayMs={500}>
<button
type="button"
className={css.iconButton}
aria-label={t('actions.workspace.aria', { name: label })}
onClick={(e) => { e.stopPropagation(); setMenuOpen(v => !v) }}
>
<IconEllipsisOutlineRegular />
</button>
</Tooltip>
)}
/>
)}
<button
type="button"
className={css.iconButton}
aria-label={t('actions.newSession.aria', { name: label })}
onClick={(e) => { e.stopPropagation(); onCreate() }}
>
<IconNewChatOutlineRegular />
</button>
<Tooltip label={t('actions.newSession')} side="bottom" delayMs={500}>
<button
type="button"
className={css.iconButton}
aria-label={t('actions.newSession.aria', { name: label })}
onClick={(e) => { e.stopPropagation(); onCreate() }}
>
<IconNewChatOutlineRegular />
</button>
</Tooltip>
</span>
</div>
)
@@ -581,41 +585,44 @@ export function SessionNodeItem({
portal
closeOnPointerLeave
anchor={(
<button
type="button"
className={css.iconButton}
aria-label={t('actions.session.aria', { name: title })}
onClick={(e) => { e.stopPropagation(); setMenuOpen(v => !v) }}
>
<IconEllipsisOutlineRegular />
</button>
<Tooltip label={t('actions.more')} side="bottom" delayMs={500}>
<button
type="button"
className={css.iconButton}
aria-label={t('actions.session.aria', { name: title })}
onClick={(e) => { e.stopPropagation(); setMenuOpen(v => !v) }}
>
<IconEllipsisOutlineRegular />
</button>
</Tooltip>
)}
/>
{/* No tooltips on the hover actions: the row's hover card sits right
beside these buttons and the two bubbles collide; the actions
speak through their aria-labels and the resulting toasts. */}
<button
type="button"
className={css.iconButton}
aria-label={row.archived ? t('menu.unarchiveSession') : t('menu.archiveSession')}
onClick={(e) => {
e.stopPropagation()
if (row.archived) onUnarchive(node.id)
else onArchive(node.id)
}}
>
{row.archived ? <IconUnarchiveOutlineRegular size={14} /> : <IconArchiveOutlineRegular size={14} />}
</button>
{/* Rightmost so it lands where the rest-state pin marker sits. */}
{!row.archived && (
<Tooltip label={row.archived ? t('menu.unarchiveSession') : t('menu.archiveSession')} side="bottom" delayMs={500}>
<button
type="button"
className={css.iconButton}
aria-label={row.pinned ? t('menu.unpinSession') : t('menu.pinSession')}
onClick={(e) => { e.stopPropagation(); onPin(node.id, !row.pinned) }}
aria-label={row.archived ? t('menu.unarchiveSession') : t('menu.archiveSession')}
onClick={(e) => {
e.stopPropagation()
if (row.archived) onUnarchive(node.id)
else onArchive(node.id)
}}
>
{row.pinned ? <IconPinFillRegular size={14} /> : <IconPinOutlineRegular size={14} />}
{row.archived ? <IconUnarchiveOutlineRegular size={14} /> : <IconArchiveOutlineRegular size={14} />}
</button>
</Tooltip>
{/* Rightmost so it lands where the rest-state pin marker sits. */}
{!row.archived && (
<Tooltip label={row.pinned ? t('menu.unpinSession') : t('menu.pinSession')} side="bottom" delayMs={500}>
<button
type="button"
className={css.iconButton}
aria-label={row.pinned ? t('menu.unpinSession') : t('menu.pinSession')}
onClick={(e) => { e.stopPropagation(); onPin(node.id, !row.pinned) }}
>
{row.pinned ? <IconPinFillRegular size={14} /> : <IconPinOutlineRegular size={14} />}
</button>
</Tooltip>
)}
</span>
)}