mirror of
https://github.com/grafana/grafana.git
synced 2025-02-09 23:16:16 -06:00
Search: remove special playground page and replace the standard results (#49442)
This commit is contained in:
parent
7096bc65b1
commit
521b0202e2
@ -47,7 +47,7 @@ export const DashboardListPage: FC<Props> = memo(({ navModel, match, location })
|
||||
return (
|
||||
<Page navModel={value?.pageNavModel ?? navModel}>
|
||||
{/*Todo: remove the false to test, or when we feel confident with thsi approach */}
|
||||
{false && config.featureToggles.panelTitleSearch ? (
|
||||
{Boolean(config.featureToggles.panelTitleSearch && !window.location.search?.includes('index=sql')) ? (
|
||||
<Page.Contents
|
||||
isLoading={loading}
|
||||
className={css`
|
||||
|
@ -20,7 +20,7 @@ export interface Props {
|
||||
}
|
||||
|
||||
export default function DashboardSearch({ onCloseSearch }: Props) {
|
||||
if (false && config.featureToggles.panelTitleSearch) {
|
||||
if (config.featureToggles.panelTitleSearch && !window.location.search?.includes('index=sql')) {
|
||||
// TODO: "folder:current" ????
|
||||
return <DashbaordSearchNEW onCloseSearch={onCloseSearch} />;
|
||||
}
|
||||
|
@ -1,112 +0,0 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useState } from 'react';
|
||||
import { useAsync, useDebounce } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
|
||||
import { Input, useStyles2, Spinner, InlineSwitch, InlineFieldRow, InlineField, Select } from '@grafana/ui';
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
import { backendSrv } from 'app/core/services/backend_srv';
|
||||
import { FolderDTO } from 'app/types';
|
||||
|
||||
import { useSearchQuery } from '../hooks/useSearchQuery';
|
||||
import { getGrafanaSearcher } from '../service';
|
||||
|
||||
import { SearchView } from './components/SearchView';
|
||||
|
||||
const node: NavModelItem = {
|
||||
id: 'search',
|
||||
text: 'Search playground',
|
||||
subTitle: 'The body below will eventually live inside existing UI layouts',
|
||||
icon: 'dashboard',
|
||||
url: 'search',
|
||||
};
|
||||
|
||||
export default function SearchPage() {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const [showManage, setShowManage] = useState(false); // grid vs list view
|
||||
const [folderDTO, setFolderDTO] = useState<FolderDTO>(); // grid vs list view
|
||||
const folders = useAsync(async () => {
|
||||
const rsp = await getGrafanaSearcher().search({
|
||||
query: '*',
|
||||
kind: ['folder'],
|
||||
});
|
||||
return rsp.view.map((v) => ({ value: v.uid, label: v.name }));
|
||||
}, []);
|
||||
const setFolder = async (uid?: string) => {
|
||||
if (uid?.length) {
|
||||
const dto = await backendSrv.getFolderByUid(uid);
|
||||
setFolderDTO(dto);
|
||||
} else {
|
||||
setFolderDTO(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
// since we don't use "query" from use search... it is not actually loaded from the URL!
|
||||
const { query, onQueryChange } = useSearchQuery({});
|
||||
|
||||
const [inputValue, setInputValue] = useState(query.query ?? '');
|
||||
const onSearchQueryChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
e.preventDefault();
|
||||
setInputValue(e.currentTarget.value);
|
||||
};
|
||||
useDebounce(() => onQueryChange(inputValue), 200, [inputValue]);
|
||||
|
||||
return (
|
||||
<Page navModel={{ node: node, main: node }}>
|
||||
<Page.Contents
|
||||
className={css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
`}
|
||||
>
|
||||
<Input
|
||||
value={inputValue}
|
||||
onChange={onSearchQueryChange}
|
||||
autoFocus
|
||||
spellCheck={false}
|
||||
placeholder="Search for dashboards and panels"
|
||||
className={styles.searchInput}
|
||||
suffix={false ? <Spinner /> : null}
|
||||
/>
|
||||
<InlineFieldRow>
|
||||
<InlineField label="Show manage options">
|
||||
<InlineSwitch value={showManage} onChange={() => setShowManage(!showManage)} />
|
||||
</InlineField>
|
||||
<InlineField label="Folder">
|
||||
<Select
|
||||
options={folders.value ?? []}
|
||||
isLoading={folders.loading}
|
||||
onChange={(v) => setFolder(v?.value)}
|
||||
isClearable
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
|
||||
<SearchView showManage={showManage} folderDTO={folderDTO} queryText={query.query} />
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
searchInput: css`
|
||||
margin-bottom: 6px;
|
||||
min-height: ${theme.spacing(4)};
|
||||
`,
|
||||
unsupported: css`
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
font-size: 18px;
|
||||
`,
|
||||
noResults: css`
|
||||
padding: ${theme.v1.spacing.md};
|
||||
background: ${theme.v1.colors.bg2};
|
||||
font-style: italic;
|
||||
margin-top: ${theme.v1.spacing.md};
|
||||
`,
|
||||
});
|
@ -187,7 +187,7 @@ export const FolderSection: FC<SectionHeaderProps> = ({
|
||||
|
||||
<div className={styles.text}>
|
||||
<span id={labelId}>{section.title}</span>
|
||||
{section.url && (
|
||||
{section.url && section.uid !== 'general' && (
|
||||
<a href={section.url} className={styles.link}>
|
||||
<span className={styles.separator}>|</span> <Icon name="folder-upload" /> Go to folder
|
||||
</a>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { css } from '@emotion/css';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { useAsync } from 'react-use';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
|
||||
@ -40,7 +40,7 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
|
||||
const layout = getValidQueryLayout(query);
|
||||
const isFolders = layout === SearchLayout.Folders;
|
||||
|
||||
const results = useAsync(() => {
|
||||
const searchQuery = useMemo(() => {
|
||||
const q: SearchQuery = {
|
||||
query: queryText,
|
||||
tags: query.tag as string[],
|
||||
@ -64,9 +64,12 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
|
||||
if (q.query === '*' && !q.sort?.length) {
|
||||
q.sort = 'name_sort';
|
||||
}
|
||||
return q;
|
||||
}, [query, queryText, folderDTO]);
|
||||
|
||||
return getGrafanaSearcher().search(q);
|
||||
}, [query, layout, queryText, folderDTO]);
|
||||
const results = useAsync(() => {
|
||||
return getGrafanaSearcher().search(searchQuery);
|
||||
}, [searchQuery]);
|
||||
|
||||
const clearSelection = useCallback(() => {
|
||||
searchSelection.items.clear();
|
||||
@ -87,12 +90,7 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
|
||||
|
||||
// This gets the possible tags from within the query results
|
||||
const getTagOptions = (): Promise<TermCount[]> => {
|
||||
const q: SearchQuery = {
|
||||
query: query.query?.length ? query.query : '*',
|
||||
tags: query.tag,
|
||||
ds_uid: query.datasource,
|
||||
};
|
||||
return getGrafanaSearcher().tags(q);
|
||||
return getGrafanaSearcher().tags(searchQuery);
|
||||
};
|
||||
|
||||
// function to update items when dashboards or folders are moved or deleted
|
||||
@ -145,6 +143,7 @@ export const SearchView = ({ showManage, folderDTO, queryText, hidePseudoFolders
|
||||
selectionToggle={toggleSelection}
|
||||
onTagSelected={onTagAdd}
|
||||
renderStandaloneBody={true}
|
||||
tags={query.tag}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ export class BlugeSearcher implements GrafanaSearcher {
|
||||
refId: 'A',
|
||||
queryType: GrafanaQueryType.Search,
|
||||
query: query.query ?? '*',
|
||||
sort: undefined, // no need to sort the initial query results (not used)
|
||||
facet: [{ field: 'tag' }],
|
||||
limit: 1, // 0 would be better, but is ignored by the backend
|
||||
};
|
||||
|
@ -386,12 +386,6 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
() => import(/* webpackChunkName: "PlaylistEditPage"*/ 'app/features/playlist/PlaylistEditPage')
|
||||
),
|
||||
},
|
||||
{
|
||||
path: '/search',
|
||||
component: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "SearchPage"*/ 'app/features/search/page/SearchPage')
|
||||
),
|
||||
},
|
||||
{
|
||||
path: '/sandbox/benchmarks',
|
||||
component: SafeDynamicImport(
|
||||
|
Loading…
Reference in New Issue
Block a user