SearchV2: move search parameters to a nested object (#50561)

This commit is contained in:
Ryan McKinley
2022-06-10 11:06:41 -07:00
committed by GitHub
parent 5af04cf81d
commit b6f97e8101
5 changed files with 130 additions and 96 deletions

View File

@@ -9,13 +9,15 @@ import {
DataFrame,
} from '@grafana/data';
import { config, getBackendSrv, getDataSourceSrv } from '@grafana/runtime';
import { InlineField, Select, Alert, Input, InlineFieldRow, CodeEditor } from '@grafana/ui';
import { InlineField, Select, Alert, Input, InlineFieldRow } from '@grafana/ui';
import { hasAlphaPanels } from 'app/core/config';
import { SearchQuery } from 'app/features/search/service';
import { GrafanaDatasource } from '../datasource';
import { defaultQuery, GrafanaQuery, GrafanaQueryType } from '../types';
import SearchEditor from './SearchEditor';
type Props = QueryEditorProps<GrafanaDatasource, GrafanaQuery>;
const labelWidth = 12;
@@ -342,103 +344,46 @@ export class QueryEditor extends PureComponent<Props, State> {
);
}
handleSearchEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key !== 'Enter') {
return;
}
this.checkAndUpdateValue('query', (e.target as any).value);
onSearchChange = (search: SearchQuery) => {
const { query, onChange, onRunQuery } = this.props;
onChange({
...query,
search,
});
onRunQuery();
};
handleSearchBlur = (e: React.FocusEvent<HTMLInputElement>) => {
this.checkAndUpdateValue('query', e.target.value);
};
onSaveSearchJSON = (rawSearchJSON: string) => {
try {
const json = JSON.parse(rawSearchJSON) as GrafanaQuery;
json.queryType = GrafanaQueryType.Search;
this.props.onChange(json);
this.props.onRunQuery();
} catch (ex) {
console.log('UNABLE TO parse search', rawSearchJSON, ex);
}
};
renderSearch() {
let query = (this.props.query ?? {}) as SearchQuery;
const emptySearchQuery: SearchQuery = {
query: '*',
location: '', // general, etc
ds_uid: '',
sort: 'score desc',
tags: [],
kind: ['dashboard', 'folder'],
uid: [],
id: [],
explain: true,
accessInfo: true,
facet: [{ field: 'kind' }, { field: 'tag' }, { field: 'location' }],
hasPreview: 'dark',
from: 0,
limit: 20,
};
const json = JSON.stringify(query ?? {}, null, 2);
for (const [key, val] of Object.entries(emptySearchQuery)) {
if ((query as any)[key] == null) {
(query as any)[key] = val;
}
}
return (
<>
<Alert title="Grafana Search" severity="info">
This interface to the grafana search API is experimental, and subject to change at any time without notice
</Alert>
<InlineFieldRow>
<InlineField label="Query" grow={true} labelWidth={labelWidth}>
<Input
placeholder="Everything"
defaultValue={query.query ?? ''}
onKeyDown={this.handleSearchEnterKey}
onBlur={this.handleSearchBlur}
spellCheck={false}
/>
</InlineField>
</InlineFieldRow>
<CodeEditor
height={300}
language="json"
value={json}
onBlur={this.onSaveSearchJSON}
onSave={this.onSaveSearchJSON}
showMiniMap={true}
showLineNumbers={true}
/>
</>
);
}
render() {
const query = {
...defaultQuery,
...this.props.query,
};
const { queryType } = query;
return (
<>
{queryType === GrafanaQueryType.Search && (
<Alert title="Grafana Search" severity="info">
Using this datasource to call the new search system is experimental, and subject to change at any time
without notice.
</Alert>
)}
<InlineFieldRow>
<InlineField label="Query type" grow={true} labelWidth={labelWidth}>
<Select
options={this.queryTypes}
value={this.queryTypes.find((v) => v.value === query.queryType) || this.queryTypes[0]}
value={this.queryTypes.find((v) => v.value === queryType) || this.queryTypes[0]}
onChange={this.onQueryTypeChange}
/>
</InlineField>
</InlineFieldRow>
{query.queryType === GrafanaQueryType.LiveMeasurements && this.renderMeasurementsQuery()}
{query.queryType === GrafanaQueryType.List && this.renderListPublicFiles()}
{query.queryType === GrafanaQueryType.Search && this.renderSearch()}
{queryType === GrafanaQueryType.LiveMeasurements && this.renderMeasurementsQuery()}
{queryType === GrafanaQueryType.List && this.renderListPublicFiles()}
{queryType === GrafanaQueryType.Search && (
<SearchEditor value={query.search ?? {}} onChange={this.onSearchChange} />
)}
</>
);
}

View File

@@ -0,0 +1,80 @@
import React, { useEffect, useState } from 'react';
import { InlineField, Input, InlineFieldRow, CodeEditor } from '@grafana/ui';
import { SearchQuery } from 'app/features/search/service';
interface Props {
value: SearchQuery;
onChange: (value: SearchQuery) => void;
}
export default function SearchEditor({ value, onChange }: Props) {
const [json, setJSON] = useState('');
const [query, setQuery] = useState(value.query ?? '');
useEffect(() => {
const emptySearchQuery: SearchQuery = {
query: '*',
location: '', // general, etc
ds_uid: '',
sort: '',
tags: [],
kind: [],
explain: false,
facet: [{ field: 'kind' }, { field: 'tags' }],
from: 0,
limit: 20,
};
setJSON(JSON.stringify({ ...emptySearchQuery, ...value }, null, 2));
}, [value]);
const handleSearchBlur = (e: React.FocusEvent<HTMLInputElement>) => {
if (query !== value.query) {
onChange({ ...value, query });
}
};
const handleSearchEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key !== 'Enter') {
return;
}
handleSearchBlur(e as any);
};
const onSaveSearchJSON = (rawSearchJSON: string) => {
try {
const searchQuery = JSON.parse(rawSearchJSON) as SearchQuery;
onChange(searchQuery);
setQuery(searchQuery.query ?? '');
} catch (ex) {
console.log('UNABLE TO parse search', rawSearchJSON, ex);
}
};
return (
<>
<InlineFieldRow>
<InlineField label="Query" grow={true} labelWidth={12}>
<Input
placeholder="Everything"
value={query}
onChange={(e) => setQuery(e.currentTarget.value)}
onKeyDown={handleSearchEnterKey}
onBlur={handleSearchBlur}
spellCheck={false}
/>
</InlineField>
</InlineFieldRow>
<CodeEditor
height={300}
language="json"
value={json}
onBlur={onSaveSearchJSON}
onSave={onSaveSearchJSON}
showMiniMap={false}
showLineNumbers={true}
/>
</>
);
}

View File

@@ -1,5 +1,6 @@
import { DataQuery } from '@grafana/data';
import { LiveDataFilter } from '@grafana/runtime';
import { SearchQuery } from 'app/features/search/service';
//----------------------------------------------
// Query
@@ -22,8 +23,8 @@ export interface GrafanaQuery extends DataQuery {
filter?: LiveDataFilter;
buffer?: number;
path?: string; // for list and read
query?: string; // for query endpoint
} // NOTE, query will have more field!!!
search?: SearchQuery;
}
export const defaultQuery: GrafanaQuery = {
refId: 'A',