mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 08:02:28 +00:00
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
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<DropdownMenuLabel>
|
||||
{translate('auto.components.activity.ActivityPrototypePage.filtersSection', 'Filters')}
|
||||
</DropdownMenuLabel>
|
||||
{onUnreadOnlyChange ? (
|
||||
<DropdownMenuCheckboxItem
|
||||
checked={unreadOnly}
|
||||
onCheckedChange={(checked) => onUnreadOnlyChange(checked === true)}
|
||||
onSelect={(event) => event.preventDefault()}
|
||||
>
|
||||
{translate(
|
||||
'auto.components.activity.ActivityPrototypePage.showUnreadOnly',
|
||||
'Show unread only'
|
||||
)}
|
||||
</DropdownMenuCheckboxItem>
|
||||
{hasFilters ? (
|
||||
<>
|
||||
<DropdownMenuLabel>
|
||||
{translate(
|
||||
'auto.components.activity.ActivityPrototypePage.filtersSection',
|
||||
'Filters'
|
||||
)}
|
||||
</DropdownMenuLabel>
|
||||
{onUnreadOnlyChange ? (
|
||||
<DropdownMenuCheckboxItem
|
||||
checked={unreadOnly}
|
||||
onCheckedChange={(checked) => onUnreadOnlyChange(checked === true)}
|
||||
onSelect={(event) => event.preventDefault()}
|
||||
>
|
||||
{translate(
|
||||
'auto.components.activity.ActivityPrototypePage.showUnreadOnly',
|
||||
'Show unread only'
|
||||
)}
|
||||
</DropdownMenuCheckboxItem>
|
||||
) : null}
|
||||
{onShowChildAgentsChange ? (
|
||||
<DropdownMenuCheckboxItem
|
||||
checked={showChildAgents}
|
||||
onCheckedChange={(checked) => onShowChildAgentsChange(checked === true)}
|
||||
onSelect={(event) => event.preventDefault()}
|
||||
>
|
||||
{translate(
|
||||
'auto.components.activity.ActivityPrototypePage.showChildAgents',
|
||||
'Show child agents'
|
||||
)}
|
||||
</DropdownMenuCheckboxItem>
|
||||
) : null}
|
||||
<ActivityScopeFilterMenuItems />
|
||||
<DropdownMenuSeparator />
|
||||
</>
|
||||
) : null}
|
||||
{onShowChildAgentsChange ? (
|
||||
<DropdownMenuCheckboxItem
|
||||
checked={showChildAgents}
|
||||
onCheckedChange={(checked) => onShowChildAgentsChange(checked === true)}
|
||||
onSelect={(event) => event.preventDefault()}
|
||||
>
|
||||
{translate(
|
||||
'auto.components.activity.ActivityPrototypePage.showChildAgents',
|
||||
'Show child agents'
|
||||
)}
|
||||
</DropdownMenuCheckboxItem>
|
||||
) : null}
|
||||
<ActivityScopeFilterMenuItems />
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuLabel>
|
||||
{translate('auto.components.activity.ActivityPrototypePage.viewSection', 'View')}
|
||||
</DropdownMenuLabel>
|
||||
|
||||
Reference in New Issue
Block a user