From b66116280d8bdf3c112fe6dc985fbaba1c92dc0b Mon Sep 17 00:00:00 2001
From: Jinjing <6427696+AmethystLiang@users.noreply.github.com>
Date: Tue, 8 Sep 2026 00:54:34 -0700
Subject: [PATCH] Hide empty Filters section in activity options menu
- Extract visibility logic into reusable hook `useActivityScopeFilterMenuItemsVisible` to avoid duplication
- Only render Filters label and items when filters are available, preventing empty section in dropdown
- Improves UX by not showing unused menu sections
---
.../activity-scope-filter-controls.tsx | 22 +++++-
.../activity/activity-thread-options-menu.tsx | 70 +++++++++++--------
2 files changed, 61 insertions(+), 31 deletions(-)
diff --git a/src/renderer/src/components/activity/activity-scope-filter-controls.tsx b/src/renderer/src/components/activity/activity-scope-filter-controls.tsx
index 7aa229bc267..e90ec1f3322 100644
--- a/src/renderer/src/components/activity/activity-scope-filter-controls.tsx
+++ b/src/renderer/src/components/activity/activity-scope-filter-controls.tsx
@@ -10,6 +10,24 @@ import {
} from '@/components/sidebar/sidebar-host-options'
import { useSidebarHostScopeOptions } from '@/components/sidebar/use-sidebar-host-scope-options'
+/**
+ * Whether {@link ActivityScopeFilterMenuItems} renders anything.
+ * Why exported: the parent owns the Filters label and separator, so it has to
+ * know whether the section would be empty.
+ */
+export function useActivityScopeFilterMenuItemsVisible(): boolean {
+ const repos = useAppStore((s) => s.repos)
+ const agentsVisibleHostIds = useAppStore((s) => s.agentsVisibleHostIds)
+ const agentsFilterRepoIds = useAppStore((s) => s.agentsFilterRepoIds)
+ const { hostOptions } = useSidebarHostScopeOptions()
+ return (
+ agentsVisibleHostIds !== null ||
+ agentsFilterRepoIds.length > 0 ||
+ shouldShowHostScopeControls(hostOptions) ||
+ repos.length > 1
+ )
+}
+
/**
* Host/project scope items for the Agents activity surfaces. State is the
* persisted agents-view scope (agentsVisibleHostIds / agentsFilterRepoIds),
@@ -17,7 +35,6 @@ import { useSidebarHostScopeOptions } from '@/components/sidebar/use-sidebar-hos
* Filters label and separator.
*/
export function ActivityScopeFilterMenuItems(): React.JSX.Element | null {
- const repos = useAppStore((s) => s.repos)
const agentsVisibleHostIds = useAppStore((s) => s.agentsVisibleHostIds)
const setAgentsVisibleHostIds = useAppStore((s) => s.setAgentsVisibleHostIds)
const agentsFilterRepoIds = useAppStore((s) => s.agentsFilterRepoIds)
@@ -25,8 +42,9 @@ export function ActivityScopeFilterMenuItems(): React.JSX.Element | null {
const { hostOptions } = useSidebarHostScopeOptions()
const showHostScopeControls = shouldShowHostScopeControls(hostOptions)
const hasScopeFilter = agentsVisibleHostIds !== null || agentsFilterRepoIds.length > 0
+ const visible = useActivityScopeFilterMenuItemsVisible()
- if (!hasScopeFilter && !showHostScopeControls && repos.length <= 1) {
+ if (!visible) {
return null
}
diff --git a/src/renderer/src/components/activity/activity-thread-options-menu.tsx b/src/renderer/src/components/activity/activity-thread-options-menu.tsx
index ad8ae349ca3..5a9bd3bc59c 100644
--- a/src/renderer/src/components/activity/activity-thread-options-menu.tsx
+++ b/src/renderer/src/components/activity/activity-thread-options-menu.tsx
@@ -19,7 +19,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { translate } from '@/i18n/i18n'
import {
ActivityScopeFilterMenuItems,
- useActivityScopeFilterActive
+ useActivityScopeFilterActive,
+ useActivityScopeFilterMenuItemsVisible
} from './activity-scope-filter-controls'
import type { ActivityGroupBy } from './activity-thread-types'
@@ -79,6 +80,10 @@ export function ActivityThreadOptionsMenu({
}): React.JSX.Element {
const skipCloseAutoFocusRef = React.useRef(false)
const scopeFilterActive = useActivityScopeFilterActive()
+ const scopeFilterItemsVisible = useActivityScopeFilterMenuItemsVisible()
+ const hasFilters = Boolean(
+ onUnreadOnlyChange || onShowChildAgentsChange || scopeFilterItemsVisible
+ )
const optionsLabel = scopeFilterActive
? translate(
'auto.components.activity.ActivityPrototypePage.threadListOptionsFiltered',
@@ -131,35 +136,42 @@ export function ActivityThreadOptionsMenu({
}
}}
>
-
- {translate('auto.components.activity.ActivityPrototypePage.filtersSection', 'Filters')}
-
- {onUnreadOnlyChange ? (
- onUnreadOnlyChange(checked === true)}
- onSelect={(event) => event.preventDefault()}
- >
- {translate(
- 'auto.components.activity.ActivityPrototypePage.showUnreadOnly',
- 'Show unread only'
- )}
-
+ {hasFilters ? (
+ <>
+
+ {translate(
+ 'auto.components.activity.ActivityPrototypePage.filtersSection',
+ 'Filters'
+ )}
+
+ {onUnreadOnlyChange ? (
+ onUnreadOnlyChange(checked === true)}
+ onSelect={(event) => event.preventDefault()}
+ >
+ {translate(
+ 'auto.components.activity.ActivityPrototypePage.showUnreadOnly',
+ 'Show unread only'
+ )}
+
+ ) : null}
+ {onShowChildAgentsChange ? (
+ onShowChildAgentsChange(checked === true)}
+ onSelect={(event) => event.preventDefault()}
+ >
+ {translate(
+ 'auto.components.activity.ActivityPrototypePage.showChildAgents',
+ 'Show child agents'
+ )}
+
+ ) : null}
+
+
+ >
) : null}
- {onShowChildAgentsChange ? (
- onShowChildAgentsChange(checked === true)}
- onSelect={(event) => event.preventDefault()}
- >
- {translate(
- 'auto.components.activity.ActivityPrototypePage.showChildAgents',
- 'Show child agents'
- )}
-
- ) : null}
-
-
{translate('auto.components.activity.ActivityPrototypePage.viewSection', 'View')}