diff --git a/public/app/features/search/components/DashboardSearch.tsx b/public/app/features/search/components/DashboardSearch.tsx index ed0054f8648..409aa67fef2 100644 --- a/public/app/features/search/components/DashboardSearch.tsx +++ b/public/app/features/search/components/DashboardSearch.tsx @@ -1,11 +1,12 @@ import { css } from '@emotion/css'; import React, { FC, memo, useState } from 'react'; -import { useDebounce } from 'react-use'; +import { useDebounce, useLocalStorage } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CustomScrollbar, IconButton, stylesFactory, useStyles2, useTheme2 } from '@grafana/ui'; +import { SEARCH_PANELS_LOCAL_STORAGE_KEY } from '../constants'; import { useDashboardSearch } from '../hooks/useDashboardSearch'; import { useSearchQuery } from '../hooks/useSearchQuery'; import { SearchView } from '../page/components/SearchView'; @@ -31,6 +32,11 @@ function DashboardSearchNew({ onCloseSearch }: Props) { const styles = useStyles2(getStyles); const { query, onQueryChange } = useSearchQuery({}); + let [includePanels, setIncludePanels] = useLocalStorage(SEARCH_PANELS_LOCAL_STORAGE_KEY, true); + if (!config.featureToggles.panelTitleSearch) { + includePanels = false; + } + const [inputValue, setInputValue] = useState(query.query ?? ''); const onSearchQueryChange = (e: React.ChangeEvent) => { e.preventDefault(); @@ -45,7 +51,7 @@ function DashboardSearchNew({ onCloseSearch }: Props) {
{ setInputValue(newQueryText); }} + includePanels={includePanels!} + setIncludePanels={setIncludePanels} />
diff --git a/public/app/features/search/components/ManageDashboardsNew.tsx b/public/app/features/search/components/ManageDashboardsNew.tsx index 9651f3f8b96..8c40c37f389 100644 --- a/public/app/features/search/components/ManageDashboardsNew.tsx +++ b/public/app/features/search/components/ManageDashboardsNew.tsx @@ -1,12 +1,14 @@ import { css, cx } from '@emotion/css'; import React, { useState } from 'react'; -import { useDebounce } from 'react-use'; +import { useDebounce, useLocalStorage } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; +import { config } from '@grafana/runtime'; import { Input, useStyles2, Spinner } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import { FolderDTO } from 'app/types'; +import { SEARCH_PANELS_LOCAL_STORAGE_KEY } from '../constants'; import { useSearchQuery } from '../hooks/useSearchQuery'; import { SearchView } from '../page/components/SearchView'; @@ -27,6 +29,11 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { const canSave = folder?.canSave; const hasEditPermissionInFolders = folder ? canSave : contextSrv.hasEditPermissionInFolders; + let [includePanels, setIncludePanels] = useLocalStorage(SEARCH_PANELS_LOCAL_STORAGE_KEY, true); + if (!config.featureToggles.panelTitleSearch) { + includePanels = false; + } + const { isEditor } = contextSrv; const [inputValue, setInputValue] = useState(query.query ?? ''); @@ -45,7 +52,7 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { onChange={onSearchQueryChange} autoFocus spellCheck={false} - placeholder="Search for dashboards and panels" + placeholder={includePanels ? 'Search for dashboards and panels' : 'Search for dashboards'} className={styles.searchInput} suffix={false ? : null} /> @@ -61,6 +68,8 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => { setInputValue(newQueryText); }} hidePseudoFolders={true} + includePanels={includePanels!} + setIncludePanels={setIncludePanels} /> ); diff --git a/public/app/features/search/constants.ts b/public/app/features/search/constants.ts index 1ae5fcc8254..1ba8a9056aa 100644 --- a/public/app/features/search/constants.ts +++ b/public/app/features/search/constants.ts @@ -8,3 +8,4 @@ export const GENERAL_FOLDER_ID = 0; export const GENERAL_FOLDER_UID = 'general'; export const GENERAL_FOLDER_TITLE = 'General'; export const PREVIEWS_LOCAL_STORAGE_KEY = 'grafana.dashboard.previews'; +export const SEARCH_PANELS_LOCAL_STORAGE_KEY = 'grafana.search.include.panels'; diff --git a/public/app/features/search/page/components/ActionRow.tsx b/public/app/features/search/page/components/ActionRow.tsx index 091a057d2a2..6d974bc1747 100644 --- a/public/app/features/search/page/components/ActionRow.tsx +++ b/public/app/features/search/page/components/ActionRow.tsx @@ -26,6 +26,8 @@ interface Props { getTagOptions: () => Promise; getSortOptions: () => Promise; onDatasourceChange: (ds?: string) => void; + includePanels: boolean; + setIncludePanels: (v: boolean) => void; query: DashboardQuery; showStarredFilter?: boolean; hideLayout?: boolean; @@ -58,6 +60,8 @@ export const ActionRow: FC = ({ query, showStarredFilter, hideLayout, + includePanels, + setIncludePanels, }) => { const styles = useStyles2(getStyles); const layout = getValidQueryLayout(query); @@ -91,6 +95,10 @@ export const ActionRow: FC = ({ Datasource: {query.datasource} )} + {layout !== SearchLayout.Folders && ( + setIncludePanels(!includePanels)} label="Include panels" /> + )} + diff --git a/public/app/features/search/page/components/SearchView.tsx b/public/app/features/search/page/components/SearchView.tsx index df486eaa32e..56cc670680e 100644 --- a/public/app/features/search/page/components/SearchView.tsx +++ b/public/app/features/search/page/components/SearchView.tsx @@ -28,6 +28,8 @@ type SearchViewProps = { folderDTO?: FolderDTO; hidePseudoFolders?: boolean; // Recent + starred onQueryTextChange: (newQueryText: string) => void; + includePanels: boolean; + setIncludePanels: (v: boolean) => void; }; export const SearchView = ({ @@ -36,6 +38,8 @@ export const SearchView = ({ queryText, hidePseudoFolders, onQueryTextChange, + includePanels, + setIncludePanels, }: SearchViewProps) => { const styles = useStyles2(getStyles); @@ -69,11 +73,15 @@ export const SearchView = ({ } } + if (!includePanels && !q.kind) { + q.kind = ['dashboard', 'folder']; // skip panels + } + if (q.query === '*' && !q.sort?.length) { q.sort = 'name_sort'; } return q; - }, [query, queryText, folderDTO]); + }, [query, queryText, folderDTO, includePanels]); const results = useAsync(() => { return getGrafanaSearcher().search(searchQuery); @@ -219,6 +227,8 @@ export const SearchView = ({ getSortOptions={getGrafanaSearcher().getSortOptions} onDatasourceChange={onDatasourceChange} query={query} + includePanels={includePanels!} + setIncludePanels={setIncludePanels} /> )}