// Libraries import React, { PureComponent } from 'react'; import { hot } from 'react-hot-loader'; import { connect } from 'react-redux'; // Components import PageHeader from 'app/core/components/PageHeader/PageHeader'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import PluginSettings from './PluginSettings'; import BasicSettings from './BasicSettings'; import ButtonRow from './ButtonRow'; // Services & Utils import appEvents from 'app/core/app_events'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; // Actions & selectors import { getDataSource, getDataSourceMeta } from '../state/selectors'; import { deleteDataSource, loadDataSource, setDataSourceName, setIsDefault, updateDataSource } from '../state/actions'; import { getNavModel } from 'app/core/selectors/navModel'; import { getRouteParamsId } from 'app/core/selectors/location'; // Types import { NavModel, Plugin } from 'app/types/'; import { DataSourceSettings } from '@grafana/ui/src/types/'; import { getDataSourceLoadingNav } from '../state/navModel'; export interface Props { navModel: NavModel; dataSource: DataSourceSettings; dataSourceMeta: Plugin; pageId: number; deleteDataSource: typeof deleteDataSource; loadDataSource: typeof loadDataSource; setDataSourceName: typeof setDataSourceName; updateDataSource: typeof updateDataSource; setIsDefault: typeof setIsDefault; } interface State { dataSource: DataSourceSettings; isTesting?: boolean; testingMessage?: string; testingStatus?: string; } enum DataSourceStates { Alpha = 'alpha', Beta = 'beta', } export class DataSourceSettingsPage extends PureComponent { constructor(props) { super(props); this.state = { dataSource: {} as DataSourceSettings, }; } async componentDidMount() { const { loadDataSource, pageId } = this.props; await loadDataSource(pageId); } onSubmit = async event => { event.preventDefault(); await this.props.updateDataSource({ ...this.state.dataSource, name: this.props.dataSource.name }); this.testDataSource(); }; onDelete = () => { appEvents.emit('confirm-modal', { title: 'Delete', text: 'Are you sure you want to delete this data source?', yesText: 'Delete', icon: 'fa-trash', onConfirm: () => { this.confirmDelete(); }, }); }; confirmDelete = () => { this.props.deleteDataSource(); }; onModelChange = dataSource => { this.setState({ dataSource: dataSource, }); }; isReadOnly() { return this.props.dataSource.readOnly === true; } shouldRenderInfoBox() { const { state } = this.props.dataSourceMeta; return state === DataSourceStates.Alpha || state === DataSourceStates.Beta; } getInfoText() { const { dataSourceMeta } = this.props; switch (dataSourceMeta.state) { case DataSourceStates.Alpha: return ( 'This plugin is marked as being in alpha state, which means it is in early development phase and updates' + ' will include breaking changes.' ); case DataSourceStates.Beta: return ( 'This plugin is marked as being in a beta development state. This means it is in currently in active' + ' development and could be missing important features.' ); } return null; } renderIsReadOnlyMessage() { return (
This datasource was added by config and cannot be modified using the UI. Please contact your server admin to update this datasource.
); } 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() { const { dataSource, dataSourceMeta, navModel, setDataSourceName, setIsDefault } = this.props; const { testingMessage, testingStatus } = this.state; return (
{Object.keys(dataSource).length === 0 ? ( ) : (
{this.isReadOnly() && this.renderIsReadOnlyMessage()} {this.shouldRenderInfoBox() &&
{this.getInfoText()}
} setIsDefault(state)} onNameChange={name => setDataSourceName(name)} /> {dataSourceMeta.module && ( )}
{testingMessage && (
{testingStatus === 'error' ? ( ) : ( )}
{testingMessage}
)}
this.onSubmit(event)} isReadOnly={this.isReadOnly()} onDelete={this.onDelete} />
)}
); } } function mapStateToProps(state) { const pageId = getRouteParamsId(state.location); const dataSource = getDataSource(state.dataSources, pageId); return { navModel: getNavModel(state.navIndex, `datasource-settings-${pageId}`, getDataSourceLoadingNav('settings')), dataSource: getDataSource(state.dataSources, pageId), dataSourceMeta: getDataSourceMeta(state.dataSources, dataSource.type), pageId: pageId, }; } const mapDispatchToProps = { deleteDataSource, loadDataSource, setDataSourceName, updateDataSource, setIsDefault, }; export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettingsPage));