SearchV2: optionally exclude panels from search results (#49971)

This commit is contained in:
Ryan McKinley 2022-06-01 09:05:53 -07:00 committed by GitHub
parent c8d891785d
commit 4dfab0b7d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 7 deletions

View File

@ -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<boolean>(SEARCH_PANELS_LOCAL_STORAGE_KEY, true);
if (!config.featureToggles.panelTitleSearch) {
includePanels = false;
}
const [inputValue, setInputValue] = useState(query.query ?? '');
const onSearchQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
@ -45,7 +51,7 @@ function DashboardSearchNew({ onCloseSearch }: Props) {
<div>
<input
type="text"
placeholder="Search dashboards by name"
placeholder={includePanels ? 'Search dashboards and panels by name' : 'Search dashboards by name'}
value={inputValue}
onChange={onSearchQueryChange}
tabIndex={0}
@ -60,7 +66,12 @@ function DashboardSearchNew({ onCloseSearch }: Props) {
</div>
</div>
<div className={styles.search}>
<SearchView showManage={false} queryText={query.query} />
<SearchView
showManage={false}
queryText={query.query}
includePanels={includePanels!}
setIncludePanels={setIncludePanels}
/>
</div>
</div>
</div>

View File

@ -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<boolean>(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 ? <Spinner /> : null}
/>
@ -58,6 +65,8 @@ export const ManageDashboardsNew = React.memo(({ folder }: Props) => {
folderDTO={folder}
queryText={query.query}
hidePseudoFolders={true}
includePanels={includePanels!}
setIncludePanels={setIncludePanels}
/>
</>
);

View File

@ -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';

View File

@ -26,6 +26,8 @@ interface Props {
getTagOptions: () => Promise<TermCount[]>;
getSortOptions: () => Promise<SelectableValue[]>;
onDatasourceChange: (ds?: string) => void;
includePanels: boolean;
setIncludePanels: (v: boolean) => void;
query: DashboardQuery;
showStarredFilter?: boolean;
hideLayout?: boolean;
@ -58,6 +60,8 @@ export const ActionRow: FC<Props> = ({
query,
showStarredFilter,
hideLayout,
includePanels,
setIncludePanels,
}) => {
const styles = useStyles2(getStyles);
const layout = getValidQueryLayout(query);
@ -91,6 +95,10 @@ export const ActionRow: FC<Props> = ({
Datasource: {query.datasource}
</Button>
)}
{layout !== SearchLayout.Folders && (
<Checkbox value={includePanels} onChange={() => setIncludePanels(!includePanels)} label="Include panels" />
)}
<TagFilter isClearable tags={query.tag} tagOptions={getTagOptions} onChange={onTagFilterChange} />
</HorizontalGroup>
</div>

View File

@ -27,9 +27,18 @@ type SearchViewProps = {
showManage: boolean;
folderDTO?: FolderDTO;
hidePseudoFolders?: boolean; // Recent + starred
includePanels: boolean;
setIncludePanels: (v: boolean) => void;
};
export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders }: SearchViewProps) => {
export const SearchView = ({
showManage,
folderDTO,
queryText,
hidePseudoFolders,
includePanels,
setIncludePanels,
}: SearchViewProps) => {
const styles = useStyles2(getStyles);
const { query, onQueryChange, onTagFilterChange, onTagAdd, onDatasourceChange, onSortChange, onLayoutChange } =
@ -61,11 +70,15 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
}
}
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);
@ -208,6 +221,8 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
getSortOptions={getGrafanaSearcher().getSortOptions}
onDatasourceChange={onDatasourceChange}
query={query}
includePanels={includePanels!}
setIncludePanels={setIncludePanels}
/>
)}