diff --git a/packages/grafana-data/src/types/plugin.ts b/packages/grafana-data/src/types/plugin.ts index 6ca498a827e..a0869666a45 100644 --- a/packages/grafana-data/src/types/plugin.ts +++ b/packages/grafana-data/src/types/plugin.ts @@ -49,6 +49,7 @@ export enum PluginErrorCode { export interface PluginError { errorCode: PluginErrorCode; pluginId: string; + pluginType?: PluginType; } export interface PluginMeta { diff --git a/public/app/features/datasources/components/NewDataSource.tsx b/public/app/features/datasources/components/NewDataSource.tsx index 29f787044aa..4414ed7971e 100644 --- a/public/app/features/datasources/components/NewDataSource.tsx +++ b/public/app/features/datasources/components/NewDataSource.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { AnyAction } from 'redux'; -import { DataSourcePluginMeta } from '@grafana/data'; +import { DataSourcePluginMeta, PluginType } from '@grafana/data'; import { LinkButton, FilterInput } from '@grafana/ui'; import PageLoader from 'app/core/components/PageLoader/PageLoader'; import { PluginsErrorsInfo } from 'app/features/plugins/components/PluginsErrorsInfo'; @@ -74,8 +74,8 @@ export function NewDataSourceView({ - {/* Show any plugin errors while not searching for anything specific */} - {!searchQuery && } + {/* Show datasource plugin errors while not searching for anything specific */} + {!searchQuery && } {/* Search results */}
diff --git a/public/app/features/plugins/admin/state/hooks.ts b/public/app/features/plugins/admin/state/hooks.ts index d499a0833e3..f6592a9e128 100644 --- a/public/app/features/plugins/admin/state/hooks.ts +++ b/public/app/features/plugins/admin/state/hooks.ts @@ -1,6 +1,6 @@ import { useEffect, useMemo } from 'react'; -import { PluginError } from '@grafana/data'; +import { PluginError, PluginType } from '@grafana/data'; import { useDispatch, useSelector } from 'app/types'; import { sortPlugins, Sorters } from '../helpers'; @@ -48,10 +48,10 @@ export const useGetSingleLocalWithoutDetails = (id: string): CatalogPlugin | und return useSelector((state) => selectById(state, id)); }; -export const useGetErrors = (): PluginError[] => { +export const useGetErrors = (filterByPluginType?: PluginType): PluginError[] => { useFetchAll(); - return useSelector(selectPluginErrors); + return useSelector(selectPluginErrors(filterByPluginType)); }; export const useInstall = () => { diff --git a/public/app/features/plugins/admin/state/selectors.ts b/public/app/features/plugins/admin/state/selectors.ts index c794296fa43..e3b2cefbfb4 100644 --- a/public/app/features/plugins/admin/state/selectors.ts +++ b/public/app/features/plugins/admin/state/selectors.ts @@ -63,19 +63,20 @@ export const selectPlugins = (filters: PluginFilters) => }); }); -export const selectPluginErrors = createSelector(selectAll, (plugins) => { - const pluginErrors: PluginError[] = []; - for (const plugin of plugins) { - if (plugin.error) { - pluginErrors.push({ - pluginId: plugin.id, - errorCode: plugin.error, - }); +export const selectPluginErrors = (filterByPluginType?: PluginType) => + createSelector(selectAll, (plugins) => { + const pluginErrors: PluginError[] = []; + for (const plugin of plugins) { + if (plugin.error && (!filterByPluginType || plugin.type === filterByPluginType)) { + pluginErrors.push({ + pluginId: plugin.id, + errorCode: plugin.error, + pluginType: plugin.type, + }); + } } - } - - return pluginErrors; -}); + return pluginErrors; + }); // The following selectors are used to get information about the outstanding or completed plugins-related network requests. export const selectRequest = (actionType: string) => diff --git a/public/app/features/plugins/components/PluginsErrorsInfo.tsx b/public/app/features/plugins/components/PluginsErrorsInfo.tsx index b550cfcea67..655057b470d 100644 --- a/public/app/features/plugins/components/PluginsErrorsInfo.tsx +++ b/public/app/features/plugins/components/PluginsErrorsInfo.tsx @@ -1,14 +1,18 @@ import { css } from '@emotion/css'; import React from 'react'; -import { GrafanaTheme2, PluginErrorCode, PluginSignatureStatus } from '@grafana/data'; +import { GrafanaTheme2, PluginErrorCode, PluginSignatureStatus, PluginType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { HorizontalGroup, InfoBox, List, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; +import { Alert, HorizontalGroup, Icon, List, PluginSignatureBadge, useStyles2 } from '@grafana/ui'; import { useGetErrors, useFetchStatus } from '../admin/state/hooks'; -export function PluginsErrorsInfo() { - const errors = useGetErrors(); +type PluginsErrorInfoProps = { + filterByPluginType?: PluginType; +}; + +export function PluginsErrorsInfo({ filterByPluginType }: PluginsErrorInfoProps) { + let errors = useGetErrors(filterByPluginType); const { isLoading } = useFetchStatus(); const styles = useStyles2(getStyles); @@ -17,35 +21,36 @@ export function PluginsErrorsInfo() { } return ( - -
-

- Unsigned plugins were found during plugin initialization. Grafana Labs cannot guarantee the integrity of these - plugins. We recommend only using signed plugins. -

- The following plugins are disabled and not shown in the list below: - ( -
- - {error.pluginId} - - -
- )} - /> -
-
+

The following plugins are disabled and not shown in the list below:

+ ( +
+ + {error.pluginId} + + +
+ )} + /> + + Read more about plugin signing + + ); } @@ -73,5 +78,10 @@ function getStyles(theme: GrafanaTheme2) { badge: css({ marginTop: 0, }), + docsLink: css({ + display: 'inline-block', + color: theme.colors.text.link, + marginTop: theme.spacing(2), + }), }; }