mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SearchV2: move search parameters to a nested object (#50561)
This commit is contained in:
@@ -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} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user