Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 847f9d6

Browse files
author
Scott Lepper
committed
fix form field; lint; fixes #1
1 parent 89aea7a commit 847f9d6

File tree

9 files changed

+12193
-62
lines changed

9 files changed

+12193
-62
lines changed

coverage/junit.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuites name="jest tests" tests="0" failures="0" time="0.002">
3+
</testsuites>

jest.config.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file is needed because it is used by vscode and other tools that
2+
// call `jest` directly. However, unless you are doing anything special
3+
// do not edit this file
4+
5+
const standard = require('@grafana/toolkit/src/config/jest.plugin.config');
6+
7+
// This process will use the same config that `yarn test` is using
8+
module.exports = standard.jestConfig();

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
"private": true,
1212
"license": "SEE LICENSE IN LICENSE",
1313
"devDependencies": {
14-
"@grafana/data": "next",
15-
"@grafana/runtime": "next",
16-
"@grafana/toolkit": "next",
17-
"@grafana/ui": "next",
14+
"@grafana/data": "7.0.6",
15+
"@grafana/runtime": "7.0.6",
16+
"@grafana/toolkit": "7.0.6",
17+
"@grafana/ui": "7.0.6",
1818
"@types/lodash": "4.14.123",
1919
"@types/react": "16.8.16 ",
2020
"@types/request-promise-native": "^1.0.17"

src/SqlProxyDatasource.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,10 @@ import {
1010
guessFieldTypeFromValue,
1111
} from '@grafana/data';
1212

13-
import {
14-
SqlQuery,
15-
} from './types';
13+
import { SqlQuery } from './types';
1614
import { getBackendSrv } from '@grafana/runtime';
1715

1816
export class DataSource extends DataSourceApi<SqlQuery, DataSourceJsonData> {
19-
2017
/** @ngInject */
2118
constructor(private instanceSettings: DataSourceInstanceSettings<DataSourceJsonData>, public templateSrv: any) {
2219
super(instanceSettings);
@@ -31,32 +28,34 @@ export class DataSource extends DataSourceApi<SqlQuery, DataSourceJsonData> {
3128
options.startTime = range.from.valueOf();
3229
options.endTime = range.to.valueOf();
3330

34-
const baseUrl = this.instanceSettings.url!
31+
const baseUrl = this.instanceSettings.url!;
3532
const route = baseUrl.endsWith('/') ? 'query?' : '/query?';
3633

3734
const opts = this.interpolate(options);
3835

3936
const calls = opts.targets.map(target => {
4037
const url = `${baseUrl}${route}sql=${target.sql}`;
41-
return getBackendSrv().datasourceRequest({ url }).then(res => {
42-
return this.arrayToDataFrame(res.data);
43-
});
38+
return getBackendSrv()
39+
.datasourceRequest({ url })
40+
.then(res => {
41+
return this.arrayToDataFrame(res.data);
42+
});
4443
});
4544

4645
const data = await Promise.all(calls);
4746

4847
return {
49-
data
50-
}
48+
data,
49+
};
5150
}
5251

53-
arrayToDataFrame(array:Array<any>):DataFrame {
52+
arrayToDataFrame(array: any[]): DataFrame {
5453
let dataFrame: MutableDataFrame = new MutableDataFrame();
5554
if (array.length > 0) {
5655
const fields = Object.keys(array[0]).map(field => {
57-
return {name: field, type: guessFieldTypeFromValue(array[0][field])}
58-
})
59-
dataFrame = new MutableDataFrame({fields});
56+
return { name: field, type: guessFieldTypeFromValue(array[0][field]) };
57+
});
58+
dataFrame = new MutableDataFrame({ fields });
6059
array.forEach((row, index) => {
6160
dataFrame.appendRow(Object.values(row));
6261
});
@@ -71,7 +70,7 @@ export class DataSource extends DataSourceApi<SqlQuery, DataSourceJsonData> {
7170
targets: visibleTargets.map(target => {
7271
const query: SqlQuery = {
7372
...target,
74-
sql: this.templateSrv.replace(target.sql)
73+
sql: this.templateSrv.replace(target.sql),
7574
};
7675
return query;
7776
}),

src/components/ConfigEditor.tsx

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import React, { PureComponent } from 'react';
2-
import { Input, FormField } from '@grafana/ui';
2+
import { Input, LegacyForms } from '@grafana/ui';
3+
const { FormField } = LegacyForms;
34

45
import { DataSourcePluginOptionsEditorProps, DataSourceJsonData, DataSourceSettings } from '@grafana/data';
56
import { css, cx } from 'emotion';
67

78
interface Props extends DataSourcePluginOptionsEditorProps<DataSourceJsonData> {}
89
interface ProxySettings extends DataSourceSettings {
9-
host: string
10+
host: string;
1011
}
1112

12-
interface State extends DataSourceSettings{}
13+
interface State extends DataSourceSettings {}
1314

1415
export class ConfigEditor extends PureComponent<Props, State> {
15-
1616
isValidUrl = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test(
1717
this.props.options.url
1818
);
@@ -21,34 +21,34 @@ export class ConfigEditor extends PureComponent<Props, State> {
2121
box-shadow: inset 0 0px 5px red;
2222
`;
2323

24-
inputStyle = cx({ [`width-10`]: true});
24+
inputStyle = cx({ [`width-10`]: true });
2525
urlStyle = cx({ [`width-20`]: true, [this.notValidStyle]: !this.isValidUrl });
26-
fullStyle = cx({ [`width-20`]: true});
26+
fullStyle = cx({ [`width-20`]: true });
2727

2828
inputs = [
29-
{key: 'url', placeholder:'http://localhost:8080', style:this.urlStyle, type: 'text'},
30-
{key: 'host', placeholder:'host[:port]', style:this.fullStyle, type: 'text'},
31-
{key: 'type', placeholder:'Database Type', style:this.fullStyle, type: 'text'},
32-
{key: 'database', placeholder:'Database Name', style:this.fullStyle, type: 'text'},
33-
{key: 'username', placeholder:'User Name', style:this.inputStyle, type: 'test'},
34-
{key: 'password', placeholder:'User Password', style:this.inputStyle, type:'password'}
35-
]
29+
{ key: 'url', placeholder: 'http://localhost:8080', style: this.urlStyle, type: 'text' },
30+
{ key: 'host', placeholder: 'host[:port]', style: this.fullStyle, type: 'text' },
31+
{ key: 'type', placeholder: 'Database Type', style: this.fullStyle, type: 'text' },
32+
{ key: 'database', placeholder: 'Database Name', style: this.fullStyle, type: 'text' },
33+
{ key: 'username', placeholder: 'User Name', style: this.inputStyle, type: 'test' },
34+
{ key: 'password', placeholder: 'User Password', style: this.inputStyle, type: 'password' },
35+
];
3636

3737
componentWillMount() {
38-
this.setState(this.props.options)
38+
this.setState(this.props.options);
3939
}
4040

4141
onChange(option: ProxySettings) {
4242
const state = this.state;
43-
const jsonData = {...state.jsonData, ...option};
43+
const jsonData = { ...state.jsonData, ...option };
4444

4545
const { onOptionsChange, options } = this.props;
4646
onOptionsChange({
4747
...options,
48-
jsonData
48+
jsonData,
4949
});
5050

51-
this.setState({jsonData});
51+
this.setState({ jsonData });
5252
}
5353

5454
getElement(input) {
@@ -59,9 +59,9 @@ export class ConfigEditor extends PureComponent<Props, State> {
5959
placeholder={input.placeholder}
6060
value={this.state.jsonData[input.key]}
6161
autoComplete={'new-password'}
62-
onChange={event => this.onChange({ [input.key]: event.currentTarget.value } as unknown as ProxySettings)}
62+
onChange={event => this.onChange(({ [input.key]: event.currentTarget.value } as unknown) as ProxySettings)}
6363
/>
64-
)
64+
);
6565
}
6666

6767
render() {
@@ -85,14 +85,38 @@ export class ConfigEditor extends PureComponent<Props, State> {
8585
<FormField label="Host" inputWidth={30} labelWidth={10} tooltip={'Database Host'} inputEl={get('host')} />
8686
</div>
8787
<div className="gf-form">
88-
<FormField label="Database Type" inputWidth={30} labelWidth={10} tooltip={'Database Type'} inputEl={get('type')} />
88+
<FormField
89+
label="Database Type"
90+
inputWidth={30}
91+
labelWidth={10}
92+
tooltip={'Database Type'}
93+
inputEl={get('type')}
94+
/>
8995
</div>
9096
<div className="gf-form">
91-
<FormField label="Database Name" inputWidth={30} labelWidth={10} tooltip={'Database Name'} inputEl={get('database')} />
97+
<FormField
98+
label="Database Name"
99+
inputWidth={30}
100+
labelWidth={10}
101+
tooltip={'Database Name'}
102+
inputEl={get('database')}
103+
/>
92104
</div>
93105
<div className="gf-form-inline">
94-
<FormField label="User Name" inputWidth={20} labelWidth={10} tooltip={'Database User Name'} inputEl={get('username')} />
95-
<FormField label="Password" inputWidth={20} labelWidth={10} tooltip={'Database User Password'} inputEl={get('password')} />
106+
<FormField
107+
label="User Name"
108+
inputWidth={20}
109+
labelWidth={10}
110+
tooltip={'Database User Name'}
111+
inputEl={get('username')}
112+
/>
113+
<FormField
114+
label="Password"
115+
inputWidth={20}
116+
labelWidth={10}
117+
tooltip={'Database User Password'}
118+
inputEl={get('password')}
119+
/>
96120
</div>
97121
</div>
98122
</div>

src/components/QueryEditor.tsx

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
22
import { DataSource } from '../SqlProxyDatasource';
33
import { QueryEditorProps, DataSourceJsonData } from '@grafana/data';
44
import { SqlQuery } from 'types';
5-
import {Controlled as CodeMirror} from 'react-codemirror2'
5+
import { Controlled as CodeMirror } from 'react-codemirror2';
66

77
import 'codemirror/lib/codemirror.css';
88
import 'codemirror/theme/darcula.css';
@@ -18,13 +18,13 @@ interface State {
1818
export class QueryEditor extends Component<Props, State> {
1919
constructor(props: QueryEditorProps<DataSource, SqlQuery, DataSourceJsonData>, context: any) {
2020
super(props, context);
21-
this.state = {sql: props.query.sql}
21+
this.state = { sql: props.query.sql };
2222
}
2323

2424
onChange = (editor: any, event: Event) => {
2525
const { onChange, query, onRunQuery } = this.props;
2626
const sql = this.state.sql;
27-
this.setState({sql});
27+
this.setState({ sql });
2828
onChange({ ...query, sql });
2929
onRunQuery(); // executes the query
3030
};
@@ -34,25 +34,25 @@ export class QueryEditor extends Component<Props, State> {
3434

3535
const options = {
3636
mode: 'sql',
37-
theme: 'darcula'
38-
}
37+
theme: 'darcula',
38+
};
3939

4040
return (
4141
<>
4242
<div className={'sql-query-editor'}>
43-
<CodeMirror
44-
value={sql}
45-
options={options}
46-
onBeforeChange={(editor, data, value) => {
47-
this.setState({sql: value});
48-
}}
49-
onChange={(editor, data, value) => {
50-
this.setState({sql: value});
51-
}}
52-
onBlur={(editor, event) => {
53-
this.onChange(editor, event)
54-
}}
55-
/>
43+
<CodeMirror
44+
value={sql}
45+
options={options}
46+
onBeforeChange={(editor, data, value) => {
47+
this.setState({ sql: value });
48+
}}
49+
onChange={(editor, data, value) => {
50+
this.setState({ sql: value });
51+
}}
52+
onBlur={(editor, event) => {
53+
this.onChange(editor, event);
54+
}}
55+
/>
5656
</div>
5757
</>
5858
);

src/module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ import { DataSource } from './SqlProxyDatasource';
66

77
export const plugin = new DataSourcePlugin<DataSource, SqlQuery, DataSourceJsonData>(DataSource)
88
.setConfigEditor(ConfigEditor)
9-
.setQueryEditor(QueryEditor)
9+
.setQueryEditor(QueryEditor);

src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import { DataQuery } from '@grafana/data';
22

33
export interface SqlQuery extends DataQuery {
44
sql: string;
5-
}
5+
}

0 commit comments

Comments
 (0)