Skip to content

Commit 1a7034e

Browse files
Variables are saved from GraphiQL editor
1 parent a368264 commit 1a7034e

File tree

3 files changed

+80
-14
lines changed

3 files changed

+80
-14
lines changed

src/components/QueryEditor.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import React, {ChangeEvent, useEffect, useMemo} from 'react';
22
import {InlineField, Input} from '@grafana/ui';
33
import {QueryEditorProps} from '@grafana/data';
44
import {DataSource} from '../datasource';
5-
import {WildGraphQLDataSourceOptions, WildGraphQLMainQuery} from '../types';
5+
import {getQueryVariablesAsJsonString, WildGraphQLDataSourceOptions, WildGraphQLMainQuery} from '../types';
66
import {GraphiQLInterface} from 'graphiql';
77
import {
88
EditorContextProvider,
9+
ExecutionContextProvider,
910
ExplorerContextProvider,
1011
PluginContextProvider,
1112
SchemaContextProvider,
12-
ExecutionContextProvider,
1313
useEditorContext
1414
} from '@graphiql/react';
1515
import {Fetcher} from '@graphiql/toolkit';
@@ -87,20 +87,24 @@ export function QueryEditor(props: Props) {
8787

8888
const fetcher = useMemo(() => {
8989
return createFetcher(
90-
datasource.options.url!,
91-
datasource.options.withCredentials ?? false,
92-
datasource.options.basicAuth
90+
datasource.settings.url!,
91+
datasource.settings.withCredentials ?? false,
92+
datasource.settings.basicAuth
9393
);
94-
}, [datasource.options.url, datasource.options.withCredentials, datasource.options.basicAuth]);
95-
94+
}, [datasource.settings.url, datasource.settings.withCredentials, datasource.settings.basicAuth]);
9695

9796
return (
9897
<>
9998
{/*By not providing storage, history contexts, they won't be used*/}
10099
{/*<StorageContextProvider storage={DummyStorage}>*/}
101100
{/* <HistoryContextProvider maxHistoryLength={0}>*/}
102101
<EditorContextProvider
103-
defaultQuery={query.queryText}
102+
// defaultQuery is the query that is used for new tabs, but we already define the open tabs here
103+
defaultTabs={[{
104+
query: query.queryText,
105+
// NOTE: For some reason if you specify variable here, it just doesn't work...
106+
}]}
107+
variables={getQueryVariablesAsJsonString(query)}
104108
// we don't need to pass onEditOperationName here because we have a callback that handles it ourselves
105109
>
106110
<SchemaContextProvider fetcher={fetcher}>
@@ -162,7 +166,11 @@ function InnerQueryEditor({ query, onChange, onRunQuery, datasource }: Props) {
162166
onChange({...query, queryText: value});
163167
}}
164168
onEditVariables={(variablesJsonString) => {
165-
// TODO
169+
if (variablesJsonString) {
170+
onChange({...query, variables: variablesJsonString});
171+
} else {
172+
onChange({...query, variables: undefined});
173+
}
166174
}}
167175
/>
168176
</div>

src/datasource.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,41 @@
1-
import {CoreApp, DataSourceInstanceSettings} from '@grafana/data';
2-
import {DataSourceWithBackend} from '@grafana/runtime';
1+
import {CoreApp, DataQueryRequest, DataQueryResponse, DataSourceInstanceSettings} from '@grafana/data';
2+
import {DataSourceWithBackend, getTemplateSrv} from '@grafana/runtime';
3+
import {Observable} from 'rxjs';
34

4-
import {DEFAULT_QUERY, WildGraphQLDataSourceOptions, WildGraphQLMainQuery} from './types';
5+
import {DEFAULT_QUERY, getQueryVariablesAsJson, WildGraphQLDataSourceOptions, WildGraphQLMainQuery} from './types';
56

67
export class DataSource extends DataSourceWithBackend<WildGraphQLMainQuery, WildGraphQLDataSourceOptions> {
7-
options: DataSourceInstanceSettings<WildGraphQLDataSourceOptions>;
8+
settings: DataSourceInstanceSettings<WildGraphQLDataSourceOptions>;
89

910
constructor(instanceSettings: DataSourceInstanceSettings<WildGraphQLDataSourceOptions>) {
1011
super(instanceSettings);
11-
this.options = instanceSettings;
12+
this.settings = instanceSettings;
1213
}
1314

1415
getDefaultQuery(_: CoreApp): Partial<WildGraphQLMainQuery> {
1516
return DEFAULT_QUERY;
1617
}
18+
query(request: DataQueryRequest<WildGraphQLMainQuery>): Observable<DataQueryResponse> {
19+
20+
// Everything you see going on here is to do variable substitution for the values of the provided variables.
21+
const templateSrv = getTemplateSrv();
22+
const newTargets: WildGraphQLMainQuery[] = request.targets.map((target) => {
23+
const variables = getQueryVariablesAsJson(target);
24+
const newVariables: any = { };
25+
for (const variableName in variables) {
26+
newVariables[variableName] = templateSrv.replace(variables[variableName]);
27+
}
28+
return {
29+
...target,
30+
variables: newVariables,
31+
}
32+
})
33+
const newRequest = {
34+
...request,
35+
targets: newTargets
36+
};
37+
38+
// we aren't really supposed to change this method, but we do it anyway :)
39+
return super.query(newRequest);
40+
}
1741
}

src/types.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,44 @@
11
import { DataSourceJsonData } from '@grafana/data';
22
import { DataQuery } from '@grafana/schema';
33

4+
type VariablesType = string | Record<string, any>;
5+
6+
47
interface WildGraphQLCommonQuery extends DataQuery {
58
queryText: string;
69
/** The operation name if explicitly set. Note that an empty string should be treated the same way as an undefined value, although storing an undefined value is preferred.*/
710
operationName?: string;
11+
variables?: VariablesType;
12+
}
13+
14+
export function getQueryVariablesAsJsonString(query: WildGraphQLCommonQuery): string {
15+
const variables = query.variables;
16+
if (variables === undefined) {
17+
return "";
18+
}
19+
if (typeof variables === 'string') {
20+
return variables;
21+
}
22+
return JSON.stringify(variables); // TODO consider if we want to prettify this JSON
23+
}
24+
export function getQueryVariablesAsJson(query: WildGraphQLCommonQuery): Record<string, any> {
25+
const variables = query.variables;
26+
if (variables === undefined) {
27+
return {};
28+
}
29+
if (typeof variables === 'string') {
30+
try {
31+
return JSON.parse(variables);
32+
} catch (e) {
33+
if (e instanceof SyntaxError) {
34+
return {}; // in the case of a syntax error, let's just make it so variables are not included
35+
// TODO consider logging an error here or something
36+
} else {
37+
throw e; // unexpected exception
38+
}
39+
}
40+
}
41+
return variables;
842
}
943

1044
/**

0 commit comments

Comments
 (0)