DataSourceSettings.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React, { PureComponent } from 'react';
  2. import { hot } from 'react-hot-loader';
  3. import { connect } from 'react-redux';
  4. import { DataSource, NavModel, Plugin } from 'app/types/';
  5. import PageHeader from '../../../core/components/PageHeader/PageHeader';
  6. import PageLoader from '../../../core/components/PageLoader/PageLoader';
  7. import PluginSettings from './PluginSettings';
  8. import BasicSettings from './BasicSettings';
  9. import ButtonRow from './ButtonRow';
  10. import appEvents from '../../../core/app_events';
  11. import { deleteDataSource, loadDataSource, setDataSourceName, updateDataSource } from '../state/actions';
  12. import { getNavModel } from '../../../core/selectors/navModel';
  13. import { getRouteParamsId } from '../../../core/selectors/location';
  14. import { getDataSource, getDataSourceMeta } from '../state/selectors';
  15. export interface Props {
  16. navModel: NavModel;
  17. dataSource: DataSource;
  18. dataSourceMeta: Plugin;
  19. pageId: number;
  20. deleteDataSource: typeof deleteDataSource;
  21. loadDataSource: typeof loadDataSource;
  22. setDataSourceName: typeof setDataSourceName;
  23. updateDataSource: typeof updateDataSource;
  24. }
  25. interface State {
  26. dataSource: DataSource;
  27. }
  28. enum DataSourceStates {
  29. Alpha = 'alpha',
  30. Beta = 'beta',
  31. }
  32. export class DataSourceSettings extends PureComponent<Props, State> {
  33. state = {
  34. dataSource: {} as DataSource,
  35. };
  36. async componentDidMount() {
  37. const { loadDataSource, pageId } = this.props;
  38. await loadDataSource(pageId);
  39. }
  40. onSubmit = event => {
  41. event.preventDefault();
  42. this.props.updateDataSource({ ...this.state.dataSource, name: this.props.dataSource.name });
  43. };
  44. onDelete = () => {
  45. appEvents.emit('confirm-modal', {
  46. title: 'Delete',
  47. text: 'Are you sure you want to delete this data source?',
  48. yesText: 'Delete',
  49. icon: 'fa-trash',
  50. onConfirm: () => {
  51. this.confirmDelete();
  52. },
  53. });
  54. };
  55. confirmDelete = () => {
  56. this.props.deleteDataSource();
  57. };
  58. onModelChange = dataSource => {
  59. this.setState({
  60. dataSource: dataSource,
  61. });
  62. };
  63. isReadOnly() {
  64. return this.props.dataSource.readOnly === true;
  65. }
  66. shouldRenderInfoBox() {
  67. const { state } = this.props.dataSourceMeta;
  68. return state === DataSourceStates.Alpha || state === DataSourceStates.Beta;
  69. }
  70. getInfoText() {
  71. const { dataSourceMeta } = this.props;
  72. switch (dataSourceMeta.state) {
  73. case DataSourceStates.Alpha:
  74. return (
  75. 'This plugin is marked as being in alpha state, which means it is in early development phase and updates' +
  76. ' will include breaking changes.'
  77. );
  78. case DataSourceStates.Beta:
  79. return (
  80. 'This plugin is marked as being in a beta development state. This means it is in currently in active' +
  81. ' development and could be missing important features.'
  82. );
  83. }
  84. return null;
  85. }
  86. renderIsReadOnlyMessage() {
  87. return (
  88. <div className="grafana-info-box span8">
  89. This datasource was added by config and cannot be modified using the UI. Please contact your server admin to
  90. update this datasource.
  91. </div>
  92. );
  93. }
  94. render() {
  95. const { dataSource, dataSourceMeta, navModel } = this.props;
  96. return (
  97. <div>
  98. <PageHeader model={navModel} />
  99. {Object.keys(dataSource).length === 0 ? (
  100. <PageLoader pageName="Data source settings" />
  101. ) : (
  102. <div className="page-container page-body">
  103. <div>
  104. <form onSubmit={this.onSubmit}>
  105. <BasicSettings
  106. dataSourceName={this.props.dataSource.name}
  107. onChange={name => this.props.setDataSourceName(name)}
  108. />
  109. {this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
  110. {this.isReadOnly() && this.renderIsReadOnlyMessage()}
  111. {dataSourceMeta.module && (
  112. <PluginSettings
  113. dataSource={dataSource}
  114. dataSourceMeta={dataSourceMeta}
  115. onModelChange={this.onModelChange}
  116. />
  117. )}
  118. <ButtonRow
  119. onSubmit={event => this.onSubmit(event)}
  120. isReadOnly={this.isReadOnly()}
  121. onDelete={this.onDelete}
  122. />
  123. </form>
  124. </div>
  125. </div>
  126. )}
  127. </div>
  128. );
  129. }
  130. }
  131. function mapStateToProps(state) {
  132. const pageId = getRouteParamsId(state.location);
  133. const dataSource = getDataSource(state.dataSources, pageId);
  134. return {
  135. navModel: getNavModel(state.navIndex, `datasource-settings-${pageId}`),
  136. dataSource: getDataSource(state.dataSources, pageId),
  137. dataSourceMeta: getDataSourceMeta(state.dataSources, dataSource.type),
  138. pageId: pageId,
  139. };
  140. }
  141. const mapDispatchToProps = {
  142. deleteDataSource,
  143. loadDataSource,
  144. setDataSourceName,
  145. updateDataSource,
  146. };
  147. export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(DataSourceSettings));