mirror of
https://github.com/grafana/grafana.git
synced 2025-02-09 23:16:16 -06:00
SearchV2: optionally exclude panels from search results (#49971)
This commit is contained in:
parent
c8d891785d
commit
4dfab0b7d5
@ -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>
|
||||
|
@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
@ -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';
|
||||
|
@ -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>
|
||||
|
@ -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}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user