NewDataSourcePage.tsx 2.8 KB

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