|
@@ -1,33 +1,40 @@
|
|
|
import React, { PureComponent } from 'react';
|
|
import React, { PureComponent } from 'react';
|
|
|
import { hot } from 'react-hot-loader';
|
|
import { hot } from 'react-hot-loader';
|
|
|
import { connect } from 'react-redux';
|
|
import { connect } from 'react-redux';
|
|
|
-import { DataSource, DataSourceTest, NavModel, Plugin } from 'app/types/';
|
|
|
|
|
-import PageHeader from '../../../core/components/PageHeader/PageHeader';
|
|
|
|
|
-import PageLoader from '../../../core/components/PageLoader/PageLoader';
|
|
|
|
|
|
|
+
|
|
|
|
|
+import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
|
|
|
|
+import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
|
|
import PluginSettings from './PluginSettings';
|
|
import PluginSettings from './PluginSettings';
|
|
|
import BasicSettings from './BasicSettings';
|
|
import BasicSettings from './BasicSettings';
|
|
|
import ButtonRow from './ButtonRow';
|
|
import ButtonRow from './ButtonRow';
|
|
|
-import appEvents from '../../../core/app_events';
|
|
|
|
|
-import { clearTesting, deleteDataSource, loadDataSource, setDataSourceName, updateDataSource } from '../state/actions';
|
|
|
|
|
-import { getNavModel } from '../../../core/selectors/navModel';
|
|
|
|
|
-import { getRouteParamsId } from '../../../core/selectors/location';
|
|
|
|
|
|
|
+
|
|
|
|
|
+import appEvents from 'app/core/app_events';
|
|
|
|
|
+import { getBackendSrv } from 'app/core/services/backend_srv';
|
|
|
|
|
+import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
|
|
|
|
+
|
|
|
import { getDataSource, getDataSourceMeta } from '../state/selectors';
|
|
import { getDataSource, getDataSourceMeta } from '../state/selectors';
|
|
|
|
|
+import { deleteDataSource, loadDataSource, setDataSourceName, updateDataSource } from '../state/actions';
|
|
|
|
|
+import { getNavModel } from 'app/core/selectors/navModel';
|
|
|
|
|
+import { getRouteParamsId } from 'app/core/selectors/location';
|
|
|
|
|
+
|
|
|
|
|
+import { DataSource, NavModel, Plugin } from 'app/types/';
|
|
|
|
|
|
|
|
export interface Props {
|
|
export interface Props {
|
|
|
navModel: NavModel;
|
|
navModel: NavModel;
|
|
|
dataSource: DataSource;
|
|
dataSource: DataSource;
|
|
|
dataSourceMeta: Plugin;
|
|
dataSourceMeta: Plugin;
|
|
|
pageId: number;
|
|
pageId: number;
|
|
|
- testing: DataSourceTest;
|
|
|
|
|
deleteDataSource: typeof deleteDataSource;
|
|
deleteDataSource: typeof deleteDataSource;
|
|
|
loadDataSource: typeof loadDataSource;
|
|
loadDataSource: typeof loadDataSource;
|
|
|
setDataSourceName: typeof setDataSourceName;
|
|
setDataSourceName: typeof setDataSourceName;
|
|
|
updateDataSource: typeof updateDataSource;
|
|
updateDataSource: typeof updateDataSource;
|
|
|
- clearTesting: typeof clearTesting;
|
|
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
interface State {
|
|
interface State {
|
|
|
dataSource: DataSource;
|
|
dataSource: DataSource;
|
|
|
- hasClosedTest: boolean;
|
|
|
|
|
|
|
+ isTesting?: boolean;
|
|
|
|
|
+ testingMessage?: string;
|
|
|
|
|
+ testingStatus?: string;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
enum DataSourceStates {
|
|
enum DataSourceStates {
|
|
@@ -36,10 +43,13 @@ enum DataSourceStates {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export class DataSourceSettings extends PureComponent<Props, State> {
|
|
export class DataSourceSettings extends PureComponent<Props, State> {
|
|
|
- state = {
|
|
|
|
|
- dataSource: {} as DataSource,
|
|
|
|
|
- hasClosedTest: false,
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ constructor(props) {
|
|
|
|
|
+ super(props);
|
|
|
|
|
+
|
|
|
|
|
+ this.state = {
|
|
|
|
|
+ dataSource: {} as DataSource,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
async componentDidMount() {
|
|
async componentDidMount() {
|
|
|
const { loadDataSource, pageId } = this.props;
|
|
const { loadDataSource, pageId } = this.props;
|
|
@@ -47,27 +57,12 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
|
|
await loadDataSource(pageId);
|
|
await loadDataSource(pageId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- componentDidUpdate(prevProps) {
|
|
|
|
|
- const { clearTesting } = this.props;
|
|
|
|
|
-
|
|
|
|
|
- if (!this.state.hasClosedTest && prevProps.testing.status === 'success') {
|
|
|
|
|
- this.setState({ hasClosedTest: true });
|
|
|
|
|
-
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- clearTesting();
|
|
|
|
|
- this.setState({ hasClosedTest: false });
|
|
|
|
|
- }, 3000);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- componentWillUnmount() {
|
|
|
|
|
- this.props.clearTesting();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- onSubmit = event => {
|
|
|
|
|
|
|
+ onSubmit = async event => {
|
|
|
event.preventDefault();
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
- this.props.updateDataSource({ ...this.state.dataSource, name: this.props.dataSource.name });
|
|
|
|
|
|
|
+ await this.props.updateDataSource({ ...this.state.dataSource, name: this.props.dataSource.name });
|
|
|
|
|
+
|
|
|
|
|
+ this.testDataSource();
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
onDelete = () => {
|
|
onDelete = () => {
|
|
@@ -131,8 +126,45 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ async testDataSource() {
|
|
|
|
|
+ const dsApi = await getDatasourceSrv().get(this.state.dataSource.name);
|
|
|
|
|
+
|
|
|
|
|
+ if (!dsApi.testDatasource) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setState({ isTesting: true, testingMessage: 'Testing...', testingStatus: 'info' });
|
|
|
|
|
+
|
|
|
|
|
+ getBackendSrv().withNoBackendCache(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await dsApi.testDatasource();
|
|
|
|
|
+
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ isTesting: false,
|
|
|
|
|
+ testingStatus: result.status,
|
|
|
|
|
+ testingMessage: result.message,
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ let message = '';
|
|
|
|
|
+
|
|
|
|
|
+ if (err.statusText) {
|
|
|
|
|
+ message = 'HTTP Error ' + err.statusText;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message = err.message;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setState({
|
|
|
|
|
+ isTesting: false,
|
|
|
|
|
+ testingStatus: 'error',
|
|
|
|
|
+ testingMessage: message,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
render() {
|
|
render() {
|
|
|
- const { dataSource, dataSourceMeta, navModel, testing } = this.props;
|
|
|
|
|
|
|
+ const { dataSource, dataSourceMeta, navModel } = this.props;
|
|
|
|
|
+ const { testingMessage, testingStatus } = this.state;
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<div>
|
|
<div>
|
|
@@ -160,26 +192,20 @@ export class DataSourceSettings extends PureComponent<Props, State> {
|
|
|
)}
|
|
)}
|
|
|
|
|
|
|
|
<div className="gf-form-group section">
|
|
<div className="gf-form-group section">
|
|
|
- {testing.inProgress && (
|
|
|
|
|
- <h5>
|
|
|
|
|
- Testing.... <i className="fa fa-spiner fa-spin" />
|
|
|
|
|
- </h5>
|
|
|
|
|
- )}
|
|
|
|
|
- {!testing.inProgress &&
|
|
|
|
|
- testing.status && (
|
|
|
|
|
- <div className={`alert-${testing.status} alert`}>
|
|
|
|
|
- <div className="alert-icon">
|
|
|
|
|
- {testing.status === 'error' ? (
|
|
|
|
|
- <i className="fa fa-exclamation-triangle" />
|
|
|
|
|
- ) : (
|
|
|
|
|
- <i className="fa fa-check" />
|
|
|
|
|
- )}
|
|
|
|
|
- </div>
|
|
|
|
|
- <div className="alert-body">
|
|
|
|
|
- <div className="alert-title">{testing.message}</div>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ {testingMessage && (
|
|
|
|
|
+ <div className={`alert-${testingStatus} alert`}>
|
|
|
|
|
+ <div className="alert-icon">
|
|
|
|
|
+ {testingStatus === 'error' ? (
|
|
|
|
|
+ <i className="fa fa-exclamation-triangle" />
|
|
|
|
|
+ ) : (
|
|
|
|
|
+ <i className="fa fa-check" />
|
|
|
|
|
+ )}
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div className="alert-body">
|
|
|
|
|
+ <div className="alert-title">{testingMessage}</div>
|
|
|
</div>
|
|
</div>
|
|
|
- )}
|
|
|
|
|
|
|
+ </div>
|
|
|
|
|
+ )}
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<ButtonRow
|
|
<ButtonRow
|
|
@@ -205,7 +231,6 @@ function mapStateToProps(state) {
|
|
|
dataSource: getDataSource(state.dataSources, pageId),
|
|
dataSource: getDataSource(state.dataSources, pageId),
|
|
|
dataSourceMeta: getDataSourceMeta(state.dataSources, dataSource.type),
|
|
dataSourceMeta: getDataSourceMeta(state.dataSources, dataSource.type),
|
|
|
pageId: pageId,
|
|
pageId: pageId,
|
|
|
- testing: state.dataSources.testing,
|
|
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -214,7 +239,6 @@ const mapDispatchToProps = {
|
|
|
loadDataSource,
|
|
loadDataSource,
|
|
|
setDataSourceName,
|
|
setDataSourceName,
|
|
|
updateDataSource,
|
|
updateDataSource,
|
|
|
- clearTesting,
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings));
|
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings));
|