From 66bebe94e064c9d6dc460254e1fc83355d5ae9cf Mon Sep 17 00:00:00 2001 From: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com> Date: Thu, 31 Jul 2025 10:28:24 +0200 Subject: [PATCH] Scopes: Add autofocus, aria-label and search area to selector (#108906) * Add autofocus, aria-label and search area * Clean up search area * Clean up search area * Add test * Remove superflous memo * Undo values change --- public/app/features/scopes/selector/ScopesTree.tsx | 11 ++++++++++- .../features/scopes/selector/ScopesTreeSearch.tsx | 12 ++++++++++-- public/app/features/scopes/tests/tree.test.ts | 10 ++++++++++ public/locales/en-US/grafana.json | 2 +- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/public/app/features/scopes/selector/ScopesTree.tsx b/public/app/features/scopes/selector/ScopesTree.tsx index 71c7a879d63..e3fbc06e203 100644 --- a/public/app/features/scopes/selector/ScopesTree.tsx +++ b/public/app/features/scopes/selector/ScopesTree.tsx @@ -63,11 +63,20 @@ export function ScopesTree({ } } + // Used as a label and placeholder for search field + const nodeTitle = scopeNodes[tree.scopeNodeId]?.spec?.title || ''; + const searchArea = tree.scopeNodeId === '' ? '' : nodeTitle; + const lastExpandedNode = !anyChildExpanded && tree.expanded; return ( <> - + {tree.scopeNodeId === '' && !anyChildExpanded && recentScopes && diff --git a/public/app/features/scopes/selector/ScopesTreeSearch.tsx b/public/app/features/scopes/selector/ScopesTreeSearch.tsx index 99a251d20bd..e84407aa00f 100644 --- a/public/app/features/scopes/selector/ScopesTreeSearch.tsx +++ b/public/app/features/scopes/selector/ScopesTreeSearch.tsx @@ -10,11 +10,12 @@ import { TreeNode } from './types'; export interface ScopesTreeSearchProps { anyChildExpanded: boolean; + searchArea: string; treeNode: TreeNode; onNodeUpdate: (scopeNodeId: string, expanded: boolean, query: string) => void; } -export function ScopesTreeSearch({ anyChildExpanded, treeNode, onNodeUpdate }: ScopesTreeSearchProps) { +export function ScopesTreeSearch({ anyChildExpanded, treeNode, onNodeUpdate, searchArea }: ScopesTreeSearchProps) { const styles = useStyles2(getStyles); const [inputState, setInputState] = useState<{ value: string; dirty: boolean }>({ @@ -42,9 +43,16 @@ export function ScopesTreeSearch({ anyChildExpanded, treeNode, onNodeUpdate }: S return null; } + const searchLabel = t('scopes.tree.search', 'Search {{parentTitle}}', { + parentTitle: searchArea, + }); + return ( { await resetScenes([fetchNodesSpy, fetchScopeSpy]); }); + it('Gives autofocus to search field when node is expanded', async () => { + await openSelector(); + expect(screen.getByRole('textbox', { name: 'Search' })).not.toHaveFocus(); + + await expandResultApplications(); + expect(screen.getByRole('textbox', { name: 'Search Applications' })).toHaveFocus(); + }); + it('Fetches scope details on select', async () => { await openSelector(); await expandResultApplications(); diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 0a72605b908..40ccbf5b567 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -11874,7 +11874,7 @@ "recommended": "Recommended", "results": "Results" }, - "search": "Search" + "search": "Search {{parentTitle}}" } }, "search": {