Files
grafana/public/app/features/datasources/NewDataSourcePage.tsx

181 lines
5.4 KiB
TypeScript
Raw Normal View History

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';
Plugin signing: UI information (#28469) * first pass * return list * types and cleanup * add to plugin page and add styles * update comment * update comment * fix component path * simplify error component * simplify error struct * fix tests * don't export and fix string() * update naming * remove frontend * introduce phantom loader * track single error * remove error from base * remove unused struct * remove unnecessary filter * add errors endpoint * Update set log to use id field Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * skip adding BE plugins * remove errs from plugin + ds list * remove unnecessary fields * add signature state to panels * Fetch plugins errors * grafana/ui component tweaks * DS Picker - add unsigned badge * VizPicker - add unsigned badge * PluginSignatureBadge tweaks * Plugins list - add signatures info box * New datasource page - add signatures info box * Plugin page - add signatures info box * Fix test * Do not show Core label in viz picker * Update public/app/features/plugins/PluginsErrorsInfo.tsx Co-authored-by: Torkel Ödegaard <torkel@grafana.org> * Update public/app/features/plugins/PluginListPage.test.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/plugins/PluginListPage.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Update public/app/features/datasources/NewDataSourcePage.tsx Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com> * Review comments 1 * Review comments 2 * Update public/app/features/plugins/PluginsErrorsInfo.tsx * Update public/app/features/plugins/PluginPage.tsx * Prettier fix * remove stale backend code * Docs issues fix Co-authored-by: Will Browne <will.browne@grafana.com> Co-authored-by: Will Browne <wbrowne@users.noreply.github.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Torkel Ödegaard <torkel@grafana.org> Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
2020-10-27 13:08:08 +01:00
import { PluginsErrorsInfo } from '../plugins/PluginsErrorsInfo';
2018-10-02 16:18:42 +02:00
function mapStateToProps(state: StoreState) {
return {
navModel: getNavModel(),
plugins: getDataSourcePlugins(state.dataSources),
searchQuery: state.dataSources.dataSourceTypeSearchQuery,
categories: state.dataSources.categories,
isLoading: state.dataSources.isLoadingDataSources,
};
2018-10-02 16:18:42 +02:00
}
const mapDispatchToProps = {
addDataSource,
loadDataSourcePlugins,
setDataSourceTypeSearchQuery,
};
const connector = connect(mapStateToProps, mapDispatchToProps);
type Props = ConnectedProps<typeof connector>;
2018-10-03 16:04:30 +02:00
class NewDataSourcePage extends PureComponent<Props> {
2018-10-03 09:56:15 +02:00
componentDidMount() {
this.props.loadDataSourcePlugins();
2018-10-03 09:56:15 +02:00
}
onDataSourceTypeClicked = (plugin: DataSourcePluginMeta) => {
this.props.addDataSource(plugin);
2018-10-02 16:18:42 +02:00
};
onSearchQueryChange = (value: string) => {
this.props.setDataSourceTypeSearchQuery(value);
2018-10-04 11:42:17 +02:00
};
renderPlugins(plugins: DataSourcePluginMeta[]) {
if (!plugins || !plugins.length) {
return null;
}
return (
<List
items={plugins}
getItemKey={(item) => item.id.toString()}
renderItem={(item) => (
<DataSourceTypeCard
plugin={item}
onClick={() => this.onDataSourceTypeClicked(item)}
onLearnMoreClick={this.onLearnMoreClick}
/>
)}
/>
);
}
onLearnMoreClick = (evt: React.SyntheticEvent<HTMLElement>) => {
evt.stopPropagation();
};
renderCategories() {
const { categories } = this.props;
return (
<>
{categories.map((category) => (
<div className="add-data-source-category" key={category.id}>
<div className="add-data-source-category__header">{category.title}</div>
{this.renderPlugins(category.plugins)}
</div>
))}
<div className="add-data-source-more">
<LinkButton
variant="secondary"
href="https://grafana.com/plugins?type=datasource&utm_source=grafana_add_ds"
target="_blank"
rel="noopener"
>
Find more data source plugins on grafana.com
</LinkButton>
</div>
</>
);
}
2018-10-02 16:18:42 +02:00
render() {
const { navModel, isLoading, searchQuery, plugins } = this.props;
2018-10-02 16:18:42 +02:00
return (
<Page navModel={navModel}>
<Page.Contents isLoading={isLoading}>
<div className="page-action-bar">
<FilterInput value={searchQuery} onChange={this.onSearchQueryChange} placeholder="Filter by name or type" />
<div className="page-action-bar__spacer" />
<LinkButton href="datasources" fill="outline" variant="secondary" icon="arrow-left">
Cancel
</LinkButton>
</div>
{!searchQuery && <PluginsErrorsInfo />}
<div>
{searchQuery && this.renderPlugins(plugins)}
{!searchQuery && this.renderCategories()}
2018-10-03 16:04:30 +02:00
</div>
</Page.Contents>
</Page>
2018-10-02 16:18:42 +02:00
);
}
}
interface DataSourceTypeCardProps {
plugin: DataSourcePluginMeta;
onClick: () => void;
onLearnMoreClick: (evt: React.SyntheticEvent<HTMLElement>) => void;
}
const DataSourceTypeCard: FC<DataSourceTypeCardProps> = (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 (
<Card
title={plugin.name}
description={plugin.info.description}
ariaLabel={selectors.pages.AddDataSource.dataSourcePlugins(plugin.name)}
logoUrl={plugin.info.logos.small}
actions={
<>
{learnMoreLink && (
<LinkButton
variant="secondary"
href={`${learnMoreLink.url}?utm_source=grafana_add_ds`}
target="_blank"
rel="noopener"
onClick={onLearnMoreClick}
icon="external-link-alt"
>
{learnMoreLink.name}
</LinkButton>
)}
{!isPhantom && <Button disabled={plugin.unlicensed}>Select</Button>}
</>
}
labels={!isPhantom && <PluginSignatureBadge status={plugin.signature} />}
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,
};
}
Build: Upgrade Webpack 5 (#36444) * build(webpack): bump to v5 and successful yarn start compilation * build(webpack): update postcss dependencies * build(webpack): silence warnings about hash renamed to fullhash * build(webpack): enable persistent cache to store generated webpack modules / chunks * build(webpack): prefer eslintWebpackPlugin over tschecker so eslint doesn't block typechecking * chore(yarn): run yarn-deduplicate to clean up dependencies * chore(yarn): refresh lock file after clean install * build(webpack): prefer output.clean over CleanWebpackPlugin * build(webpack): prefer esbuild over babel-loader for dev config * build(babel): turn off cache compression to improve build performance * build(webpack): get production builds working * build(webpack): remove phantomJS (removed from grafana in v7) specific loader * build(webpack): put back babel for dev builds no performance gain in using esbuild in webpack * build(webpack): prefer terser and optimise css plugins for prod. slower but smaller bundles * build(webpack): clean up redundant code. inform postcss about node_modules * build(webpack): remove deprecation warnings flag * build(webpack): bump packages, dev performance optimisations, attempt to get hot working * chore(storybook): use webpack 5 for dev and production builds * build(storybook): speed up dev build * chore(yarn): refresh lock file * chore(webpack): bump webpack and related deps to latest * refactor(webpack): put back inline-source-map, move start scripts out of grafana toolkit * feat(webpack): prefer react-refresh over react-hot-loader * build(webpack): update webpack.hot to use react-refresh * chore: remove react-hot-loader from codebase * refactor(queryeditorrow): fix circular dependency causing react-fast-refresh errors * revert(webpack): remove stats.errorDetails from common config * build(webpack): bump to v5 and successful yarn start compilation * build(webpack): update postcss dependencies * build(webpack): silence warnings about hash renamed to fullhash * build(webpack): enable persistent cache to store generated webpack modules / chunks * build(webpack): prefer eslintWebpackPlugin over tschecker so eslint doesn't block typechecking * chore(yarn): run yarn-deduplicate to clean up dependencies * chore(yarn): refresh lock file after clean install * build(webpack): prefer output.clean over CleanWebpackPlugin * build(webpack): prefer esbuild over babel-loader for dev config * build(babel): turn off cache compression to improve build performance * build(webpack): get production builds working * build(webpack): remove phantomJS (removed from grafana in v7) specific loader * build(webpack): put back babel for dev builds no performance gain in using esbuild in webpack * build(webpack): prefer terser and optimise css plugins for prod. slower but smaller bundles * build(webpack): clean up redundant code. inform postcss about node_modules * build(webpack): remove deprecation warnings flag * build(webpack): bump packages, dev performance optimisations, attempt to get hot working * chore(storybook): use webpack 5 for dev and production builds * build(storybook): speed up dev build * chore(yarn): refresh lock file * chore(webpack): bump webpack and related deps to latest * refactor(webpack): put back inline-source-map, move start scripts out of grafana toolkit * feat(webpack): prefer react-refresh over react-hot-loader * build(webpack): update webpack.hot to use react-refresh * chore: remove react-hot-loader from codebase * refactor(queryeditorrow): fix circular dependency causing react-fast-refresh errors * revert(webpack): remove stats.errorDetails from common config * revert(webpack): remove include from babel-loader so symlinks (enterprise) work as before * refactor(webpack): fix deprecation warnings in prod builds * fix(storybook): fix failing builds due to replacing css-optimise webpack plugin * fix(storybook): use raw-loader for svg icons * build(webpack): fix dev script colors error * chore(webpack): bump css-loader and react-refresh-webpack-plugin to latest versions Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2021-08-31 12:55:05 +02:00
export default connector(NewDataSourcePage);