import React, { FC, PureComponent } from 'react'; import { connect, ConnectedProps } from 'react-redux'; import { DataSourcePluginMeta, NavModel } from '@grafana/data'; import { Button, LinkButton, List, PluginSignatureBadge, FilterInput } from '@grafana/ui'; import { selectors } from '@grafana/e2e-selectors'; import Page from 'app/core/components/Page/Page'; import { StoreState } from 'app/types'; import { addDataSource, loadDataSourcePlugins } from './state/actions'; import { getDataSourcePlugins } from './state/selectors'; import { setDataSourceTypeSearchQuery } from './state/reducers'; import { Card } from 'app/core/components/Card/Card'; import { PluginsErrorsInfo } from '../plugins/PluginsErrorsInfo'; function mapStateToProps(state: StoreState) { return { navModel: getNavModel(), plugins: getDataSourcePlugins(state.dataSources), searchQuery: state.dataSources.dataSourceTypeSearchQuery, categories: state.dataSources.categories, isLoading: state.dataSources.isLoadingDataSources, }; } const mapDispatchToProps = { addDataSource, loadDataSourcePlugins, setDataSourceTypeSearchQuery, }; const connector = connect(mapStateToProps, mapDispatchToProps); type Props = ConnectedProps; class NewDataSourcePage extends PureComponent { componentDidMount() { this.props.loadDataSourcePlugins(); } onDataSourceTypeClicked = (plugin: DataSourcePluginMeta) => { this.props.addDataSource(plugin); }; onSearchQueryChange = (value: string) => { this.props.setDataSourceTypeSearchQuery(value); }; renderPlugins(plugins: DataSourcePluginMeta[]) { if (!plugins || !plugins.length) { return null; } return ( item.id.toString()} renderItem={(item) => ( this.onDataSourceTypeClicked(item)} onLearnMoreClick={this.onLearnMoreClick} /> )} /> ); } onLearnMoreClick = (evt: React.SyntheticEvent) => { evt.stopPropagation(); }; renderCategories() { const { categories } = this.props; return ( <> {categories.map((category) => (
{category.title}
{this.renderPlugins(category.plugins)}
))}
Find more data source plugins on grafana.com
); } render() { const { navModel, isLoading, searchQuery, plugins } = this.props; return (
Cancel
{!searchQuery && }
{searchQuery && this.renderPlugins(plugins)} {!searchQuery && this.renderCategories()}
); } } interface DataSourceTypeCardProps { plugin: DataSourcePluginMeta; onClick: () => void; onLearnMoreClick: (evt: React.SyntheticEvent) => void; } const DataSourceTypeCard: FC = (props) => { const { plugin, onLearnMoreClick } = props; const isPhantom = plugin.module === 'phantom'; const onClick = !isPhantom && !plugin.unlicensed ? props.onClick : () => {}; // find first plugin info link const learnMoreLink = plugin.info?.links?.length > 0 ? plugin.info.links[0] : null; return ( {learnMoreLink && ( {learnMoreLink.name} )} {!isPhantom && } } labels={!isPhantom && } className={isPhantom ? 'add-data-source-item--phantom' : ''} onClick={onClick} aria-label={selectors.pages.AddDataSource.dataSourcePlugins(plugin.name)} /> ); }; export function getNavModel(): NavModel { const main = { icon: 'database', id: 'datasource-new', text: 'Add data source', href: 'datasources/new', subTitle: 'Choose a data source type', }; return { main: main, node: main, }; } export default connector(NewDataSourcePage);