mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
fix(desktop): remove activity count badge
Keep the Activity entry available without showing persistent numeric attention markers. Confidence: high Scope-risk: narrow Tested: bun run check:desktop Not-tested: manual Electron visual smoke
This commit is contained in:
parent
899ec2c3b4
commit
745112a136
@ -4,21 +4,17 @@ import { useActivityPanelStore } from '../../stores/activityPanelStore'
|
||||
|
||||
type SessionActivityButtonProps = {
|
||||
sessionId: string
|
||||
badgeCount: number
|
||||
label?: string
|
||||
}
|
||||
|
||||
export function SessionActivityButton({
|
||||
sessionId,
|
||||
badgeCount,
|
||||
label,
|
||||
}: SessionActivityButtonProps) {
|
||||
const t = useTranslation()
|
||||
const resolvedLabel = label ?? t('session.activity.title')
|
||||
const isOpen = useActivityPanelStore((state) => state.isOpen(sessionId))
|
||||
const toggle = useActivityPanelStore((state) => state.toggle)
|
||||
const visibleBadgeCount = Math.max(0, badgeCount)
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
@ -36,14 +32,6 @@ export function SessionActivityButton({
|
||||
}`}
|
||||
>
|
||||
<ListChecks size={17} strokeWidth={1.9} />
|
||||
{visibleBadgeCount > 0 && (
|
||||
<span
|
||||
data-testid="session-activity-badge"
|
||||
className="absolute -right-1 -top-1 inline-flex min-w-4 h-4 items-center justify-center rounded-full bg-[var(--color-error)] px-1 text-[10px] font-semibold leading-none text-white"
|
||||
>
|
||||
{visibleBadgeCount > 9 ? '9+' : visibleBadgeCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ describe('TabBar', () => {
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows the activity button with a badge for running or failed activity', async () => {
|
||||
it('shows the activity button without a numeric badge for running or failed activity', async () => {
|
||||
const { TabBar } = await import('./TabBar')
|
||||
const { useTabStore } = await import('../../stores/tabStore')
|
||||
const { useChatStore } = await import('../../stores/chatStore')
|
||||
@ -375,7 +375,7 @@ describe('TabBar', () => {
|
||||
|
||||
const button = screen.getByRole('button', { name: /activity/i })
|
||||
expect(button).toBeInTheDocument()
|
||||
expect(screen.getByTestId('session-activity-badge')).toHaveTextContent('2')
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
expect(useActivityPanelStore.getState().isOpen(sessionId)).toBe(false)
|
||||
expect(button).toHaveAttribute('aria-expanded', 'false')
|
||||
expect(button).toHaveAttribute('aria-pressed', 'false')
|
||||
@ -426,7 +426,7 @@ describe('TabBar', () => {
|
||||
})
|
||||
|
||||
expect(screen.getByRole('button', { name: /activity/i })).toBeInTheDocument()
|
||||
expect(screen.getByTestId('session-activity-badge')).toHaveTextContent('1')
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('hides team-only activity when the active team belongs to another session', async () => {
|
||||
@ -469,7 +469,7 @@ describe('TabBar', () => {
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows the activity button when team activity arrives after initial render', async () => {
|
||||
it('shows the activity button without a badge when team activity arrives after initial render', async () => {
|
||||
const { TabBar } = await import('./TabBar')
|
||||
const { useTabStore } = await import('../../stores/tabStore')
|
||||
const { useChatStore } = await import('../../stores/chatStore')
|
||||
@ -511,7 +511,7 @@ describe('TabBar', () => {
|
||||
})
|
||||
|
||||
expect(screen.getByRole('button', { name: /activity/i })).toBeInTheDocument()
|
||||
expect(screen.getByTestId('session-activity-badge')).toHaveTextContent('1')
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('does not show the activity button for settings tabs', async () => {
|
||||
@ -530,7 +530,7 @@ describe('TabBar', () => {
|
||||
expect(screen.queryByRole('button', { name: /activity/i })).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('includes current-session CLI tasks in the activity badge', async () => {
|
||||
it('shows current-session CLI tasks without a numeric activity badge', async () => {
|
||||
const { TabBar } = await import('./TabBar')
|
||||
const { useTabStore } = await import('../../stores/tabStore')
|
||||
const { useChatStore } = await import('../../stores/chatStore')
|
||||
@ -580,10 +580,10 @@ describe('TabBar', () => {
|
||||
render(<TabBar />)
|
||||
})
|
||||
|
||||
expect(screen.getByTestId('session-activity-badge')).toHaveTextContent('2')
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('excludes dismissed failed background tasks from the activity badge while keeping running tasks', async () => {
|
||||
it('keeps running activity available without showing a numeric badge', async () => {
|
||||
const { TabBar } = await import('./TabBar')
|
||||
const { useTabStore } = await import('../../stores/tabStore')
|
||||
const { useChatStore } = await import('../../stores/chatStore')
|
||||
@ -636,7 +636,7 @@ describe('TabBar', () => {
|
||||
render(<TabBar />)
|
||||
})
|
||||
|
||||
expect(screen.getByTestId('session-activity-badge')).toHaveTextContent('1')
|
||||
expect(screen.queryByTestId('session-activity-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('ignores CLI tasks from a different session in the activity badge', async () => {
|
||||
|
||||
@ -122,7 +122,7 @@ export function TabBar() {
|
||||
}))
|
||||
const activityState = useChatStore(useShallow((state) => {
|
||||
if (!activeTabId || !isActiveSessionTab) {
|
||||
return { badgeCount: 0, hasVisibleActivity: false }
|
||||
return { hasVisibleActivity: false }
|
||||
}
|
||||
const sessionState = state.sessions[activeTabId]
|
||||
const includeCliTasks = cliTasksSessionId === activeTabId
|
||||
@ -138,12 +138,10 @@ export function TabBar() {
|
||||
teamMembers: activityTeamMembers,
|
||||
})
|
||||
return {
|
||||
badgeCount: model.badgeCount,
|
||||
hasVisibleActivity: hasVisibleSessionActivity(model),
|
||||
}
|
||||
}))
|
||||
const showActivityButton = activeTabId && activityState.hasVisibleActivity
|
||||
const activityBadgeCount = activityState.badgeCount
|
||||
|
||||
const moveTab = useTabStore((s) => s.moveTab)
|
||||
const scrollRef = useRef<HTMLDivElement>(null)
|
||||
@ -435,7 +433,7 @@ export function TabBar() {
|
||||
|
||||
<div className="flex shrink-0 items-center gap-1 border-l border-[var(--color-border)]/70 px-2">
|
||||
{showActivityButton && activeTabId && (
|
||||
<SessionActivityButton sessionId={activeTabId} badgeCount={activityBadgeCount} />
|
||||
<SessionActivityButton sessionId={activeTabId} />
|
||||
)}
|
||||
{isDesktopRuntime && isActiveSessionTab && (
|
||||
<OpenProjectMenu path={openProjectPath} />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user