diff --git a/src/components/HaystackQueryInput.tsx b/src/components/HaystackQueryInput.tsx index 7f31898..7f71870 100644 --- a/src/components/HaystackQueryInput.tsx +++ b/src/components/HaystackQueryInput.tsx @@ -20,7 +20,7 @@ export function HaystackQueryInput({ query, onChange }: HaystackQueryInputProps) } - onChange={onQueryChange} + onBlur={onQueryChange} value={query.eval} placeholder={DEFAULT_QUERY.eval} /> @@ -32,7 +32,7 @@ export function HaystackQueryInput({ query, onChange }: HaystackQueryInputProps) @@ -44,7 +44,7 @@ export function HaystackQueryInput({ query, onChange }: HaystackQueryInputProps) } - onChange={onQueryChange} + onBlur={onQueryChange} value={query.hisReadFilter} placeholder={DEFAULT_QUERY.hisReadFilter} /> @@ -56,7 +56,7 @@ export function HaystackQueryInput({ query, onChange }: HaystackQueryInputProps) } - onChange={onQueryChange} + onBlur={onQueryChange} value={query.read} placeholder={DEFAULT_QUERY.read} /> diff --git a/src/components/HaystackQueryTypeSelector.tsx b/src/components/HaystackQueryTypeSelector.tsx index a5717ac..962dbd4 100644 --- a/src/components/HaystackQueryTypeSelector.tsx +++ b/src/components/HaystackQueryTypeSelector.tsx @@ -5,7 +5,7 @@ import { DataSource, queryTypes } from '../datasource'; export interface HaystackQueryTypeSelectorProps { datasource: DataSource | null; - type: string; + type?: string; refId: string; onChange: (type: string) => void; } @@ -16,7 +16,7 @@ export function HaystackQueryTypeSelector({ datasource, type, refId, onChange }: }; const queryTypeDefault = queryTypes[0]; - function queryTypeFromValue(value: string): QueryType | null { + function queryTypeFromValue(value?: string): QueryType | null { return queryTypes.find((queryType) => queryType.value === value) ?? null; } diff --git a/src/components/VariableQueryEditor.tsx b/src/components/VariableQueryEditor.tsx index a4f137f..080c6ff 100644 --- a/src/components/VariableQueryEditor.tsx +++ b/src/components/VariableQueryEditor.tsx @@ -1,34 +1,28 @@ -import React, { useState } from 'react'; -import { HaystackVariableQuery } from '../types'; +import React from 'react'; +import { HaystackDataSourceOptions, HaystackQuery, HaystackVariableQuery } from '../types'; import { HaystackQueryTypeSelector } from './HaystackQueryTypeSelector'; import { HaystackQueryInput } from './HaystackQueryInput'; -import { InlineField, Input } from '@grafana/ui'; +import { QueryEditorProps } from '@grafana/data'; +import { InlineField, Input, Stack } from '@grafana/ui'; +import { DataSource } from 'datasource'; -interface VariableQueryProps { - query: HaystackVariableQuery; - onChange: (query: HaystackVariableQuery, definition: string) => void; -} +type Props = QueryEditorProps; -export const VARIABLE_REF_ID = "variable"; - -export const VariableQueryEditor: React.FC = ({ onChange, query: variableQuery }) => { +export const VariableQueryEditor = ({ onChange, query }: Props) => { let variableInputWidth = 30; - const [query, setState] = useState(variableQuery); - - const saveQuery = () => { - // refId must match but doesn't get set originally so set should set it on every change - setState({ ...query, refId: VARIABLE_REF_ID}); + // Computes the query string and calls the onChange function. Should be used instead of onChange for all mutating functions. + const onChangeAndSave = (query: HaystackVariableQuery) => { let type = query.type; let queryCmd = ""; if (query.type === "eval") { - queryCmd = query.eval + queryCmd = query.eval ?? ""; } else if (query.type === "hisRead") { - queryCmd = query.hisRead + queryCmd = query.hisRead ?? ""; } else if (query.type === "hisReadFilter") { - queryCmd = query.hisReadFilter + queryCmd = query.hisReadFilter ?? ""; } else if (query.type === "read") { - queryCmd = query.read + queryCmd = query.read ?? ""; } let column = "none"; if (query.column !== undefined && query.column !== '') { @@ -39,39 +33,42 @@ export const VariableQueryEditor: React.FC = ({ onChange, qu displayColumn = `'${query.displayColumn}'`; } let displayString = `${type}: '${queryCmd}', Column: ${column}, Display: ${displayColumn}` - onChange(query, displayString); + onChange({ ...query, query: displayString }); }; const onTypeChange = (newType: string) => { - setState({ ...query, type: newType}); + onChangeAndSave({ ...query, type: newType}); }; const onQueryChange = (newQuery: string) => { if (query.type === "eval") { - setState({ ...query, eval: newQuery }); + onChangeAndSave({ ...query, eval: newQuery }); } else if (query.type === "hisRead") { - setState({ ...query, hisRead: newQuery }); + onChangeAndSave({ ...query, hisRead: newQuery }); } else if (query.type === "hisReadFilter") { - setState({ ...query, hisReadFilter: newQuery }); + onChangeAndSave({ ...query, hisReadFilter: newQuery }); } else if (query.type === "read") { - setState({ ...query, read: newQuery }); + onChangeAndSave({ ...query, read: newQuery }); } }; const onColumnChange = (event: React.FormEvent) => { - setState({...query, column: event.currentTarget.value,}); + onChangeAndSave({...query, column: event.currentTarget.value,}); }; const onDisplayColumnChange = (event: React.FormEvent) => { - setState({...query, displayColumn: event.currentTarget.value,}); + onChangeAndSave({...query, displayColumn: event.currentTarget.value,}); }; return ( -
+ = ({ onChange, qu placeholder="Defaults to 'Column'" /> -
+ ); }; diff --git a/src/datasource.ts b/src/datasource.ts index 975fc1a..2259a55 100644 --- a/src/datasource.ts +++ b/src/datasource.ts @@ -17,7 +17,7 @@ import { HaystackQuery, OpsQuery, HaystackDataSourceOptions, HaystackVariableQue import { firstValueFrom, map, Observable } from 'rxjs'; import { isRef, parseRef } from 'haystack'; import { ComponentType } from 'react'; -import { VARIABLE_REF_ID, VariableQueryEditor } from 'components/VariableQueryEditor'; +import { VariableQueryEditor } from 'components/VariableQueryEditor'; export const queryTypes: QueryType[] = [ { label: 'Eval', value: 'eval', apiRequirements: ['eval'], description: 'Evaluate an Axon expression' }, @@ -130,7 +130,6 @@ export class HaystackVariableSupport extends CustomVariableSupport): Observable { let variableQuery = request.targets[0]; - variableQuery.refId = VARIABLE_REF_ID; let observable = this.onQuery(request); return observable.pipe( map((response) => { diff --git a/src/plugin.json b/src/plugin.json index 99c5d36..2511f3c 100644 --- a/src/plugin.json +++ b/src/plugin.json @@ -40,7 +40,7 @@ "updated": "%TODAY%" }, "dependencies": { - "grafanaDependency": ">=10.0.0", + "grafanaDependency": ">=11.0.0", "plugins": [] } } diff --git a/src/types.ts b/src/types.ts index 4366b45..5167f34 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,11 +2,11 @@ import { DataSourceJsonData, SelectableValue } from '@grafana/data'; import { DataQuery } from '@grafana/schema'; export interface HaystackQuery extends DataQuery { - type: string; // Defines the type of query that should be executed - eval: string; - hisRead: string; - hisReadFilter: string; - read: string; + type?: string; // Defines the type of query that should be executed + eval?: string; + hisRead?: string; + hisReadFilter?: string; + read?: string; } // OpsQuery is a query that is used to get the available ops from the datasource. @@ -29,6 +29,7 @@ export interface QueryType extends SelectableValue { } export interface HaystackVariableQuery extends HaystackQuery { + query: string; // Used to set 'definition' display string in the UI column: string; displayColumn: string; refId: string;