NewDataSourcePage.tsx 3.0 KB

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