NewDataSourcePage.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import React, { PureComponent } from 'react';
  2. import { connect } from 'react-redux';
  3. import { hot } from 'react-hot-loader';
  4. import PageHeader from 'app/core/components/PageHeader/PageHeader';
  5. import { NavModel, Plugin } from 'app/types';
  6. import { addDataSource, loadDataSourceTypes, setDataSourceTypeSearchQuery } from './state/actions';
  7. import { updateLocation } from '../../core/actions';
  8. import { getNavModel } from 'app/core/selectors/navModel';
  9. import { getDataSourceTypes } from './state/selectors';
  10. export interface Props {
  11. navModel: NavModel;
  12. dataSourceTypes: Plugin[];
  13. addDataSource: typeof addDataSource;
  14. loadDataSourceTypes: typeof loadDataSourceTypes;
  15. updateLocation: typeof updateLocation;
  16. dataSourceTypeSearchQuery: string;
  17. setDataSourceTypeSearchQuery: typeof setDataSourceTypeSearchQuery;
  18. }
  19. class NewDataSourcePage extends PureComponent<Props> {
  20. componentDidMount() {
  21. this.props.loadDataSourceTypes();
  22. }
  23. onDataSourceTypeClicked = type => {
  24. this.props.addDataSource(type.name, type.value);
  25. };
  26. onSearchQueryChange = event => {
  27. this.props.setDataSourceTypeSearchQuery(event.target.value);
  28. };
  29. render() {
  30. const { navModel, dataSourceTypes, dataSourceTypeSearchQuery } = this.props;
  31. return (
  32. <div>
  33. <PageHeader model={navModel} />
  34. <div className="page-container page-body">
  35. <h3 className="add-data-source-header">Choose data source type</h3>
  36. <div className="add-data-source-search">
  37. <label className="gf-form--has-input-icon">
  38. <input
  39. type="text"
  40. className="gf-form-input width-20"
  41. value={dataSourceTypeSearchQuery}
  42. onChange={this.onSearchQueryChange}
  43. placeholder="Filter by name or type"
  44. />
  45. <i className="gf-form-input-icon fa fa-search" />
  46. </label>
  47. </div>
  48. <div className="add-data-source-grid">
  49. {dataSourceTypes.map((type, index) => {
  50. return (
  51. <div
  52. onClick={() => this.onDataSourceTypeClicked(type)}
  53. className="add-data-source-grid-item"
  54. key={`${type.id}-${index}`}
  55. >
  56. <img className="add-data-source-grid-item-logo" src={type.info.logos.small} />
  57. <span className="add-data-source-grid-item-text">{type.name}</span>
  58. </div>
  59. );
  60. })}
  61. </div>
  62. </div>
  63. </div>
  64. );
  65. }
  66. }
  67. function mapStateToProps(state) {
  68. return {
  69. navModel: getNavModel(state.navIndex, 'datasources'),
  70. dataSourceTypes: getDataSourceTypes(state.dataSources),
  71. };
  72. }
  73. const mapDispatchToProps = {
  74. addDataSource,
  75. loadDataSourceTypes,
  76. updateLocation,
  77. setDataSourceTypeSearchQuery,
  78. };
  79. export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(NewDataSourcePage));