PluginsCatalog: Fix so we display the correct badges when a plugin is disabled. (#41159)

This commit is contained in:
Marcus Andersson 2021-11-02 13:41:08 +01:00 committed by GitHub
parent 8a3e192e6a
commit ad888813c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 18 deletions

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { ReactElement } from 'react';
import { PluginErrorCode } from '@grafana/data';
import { Alert } from '@grafana/ui';
import { CatalogPlugin } from '../types';
@ -9,7 +9,7 @@ type Props = {
plugin: CatalogPlugin;
};
export function PluginDetailsDisabledError({ className, plugin }: Props): React.ReactElement | null {
export function PluginDetailsDisabledError({ className, plugin }: Props): ReactElement | null {
if (!plugin.isDisabled) {
return null;
}
@ -35,7 +35,7 @@ export function PluginDetailsDisabledError({ className, plugin }: Props): React.
);
}
function renderDescriptionFromError(error?: PluginErrorCode): React.ReactElement {
function renderDescriptionFromError(error?: PluginErrorCode): ReactElement {
switch (error) {
case PluginErrorCode.modifiedSignature:
return (

View File

@ -1,6 +1,7 @@
import React from 'react';
import { PluginSignatureStatus } from '@grafana/data';
import { PluginSignatureBadge } from '@grafana/ui';
import { css } from '@emotion/css';
import { GrafanaTheme2, PluginSignatureStatus } from '@grafana/data';
import { PluginSignatureBadge, useStyles2 } from '@grafana/ui';
import { PluginSignatureDetailsBadge } from './PluginSignatureDetailsBadge';
import { CatalogPlugin } from '../types';
@ -10,11 +11,17 @@ type Props = {
// Designed to show plugin signature information in the header on the plugin's details page
export function PluginDetailsHeaderSignature({ plugin }: Props): React.ReactElement {
const styles = useStyles2(getStyles);
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
return (
<div>
<a href="https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/" target="_blank" rel="noreferrer">
<div className={styles.container}>
<a
href="https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/"
target="_blank"
rel="noreferrer"
className={styles.link}
>
<PluginSignatureBadge status={plugin.signature} />
</a>
@ -24,3 +31,15 @@ export function PluginDetailsHeaderSignature({ plugin }: Props): React.ReactElem
</div>
);
}
export const getStyles = (theme: GrafanaTheme2) => {
return {
container: css`
display: flex;
`,
link: css`
display: inline-flex;
align-items: center;
`,
};
};

View File

@ -1,6 +1,6 @@
import React from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { PluginSignatureStatus } from '@grafana/data';
import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data';
import { Alert } from '@grafana/ui';
import { CatalogPlugin } from '../types';
@ -13,9 +13,10 @@ type Props = {
export function PluginDetailsSignature({ className, plugin }: Props): React.ReactElement | null {
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
const isCore = plugin.signature === PluginSignatureStatus.internal;
const isDisabled = plugin.isDisabled && isDisabledDueTooSignatureError(plugin.error);
// The basic information is already available in the header
if (isSignatureValid || isCore) {
if (isSignatureValid || isCore || isDisabled) {
return null;
}
@ -43,3 +44,18 @@ export function PluginDetailsSignature({ className, plugin }: Props): React.Reac
</Alert>
);
}
function isDisabledDueTooSignatureError(error: PluginErrorCode | undefined) {
// If the plugin is disabled due to signature error we rely on the disabled
// error message instad of the warning about the signature.
switch (error) {
case PluginErrorCode.invalidSignature:
case PluginErrorCode.missingSignature:
case PluginErrorCode.modifiedSignature:
return true;
default:
return false;
}
}

View File

@ -1,6 +1,6 @@
import { config } from '@grafana/runtime';
import { gt } from 'semver';
import { PluginSignatureStatus, dateTimeParse, PluginError } from '@grafana/data';
import { PluginSignatureStatus, dateTimeParse, PluginError, PluginErrorCode } from '@grafana/data';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { Settings } from 'app/core/config';
import { CatalogPlugin, LocalPlugin, RemotePlugin } from './types';
@ -59,11 +59,8 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
updatedAt,
createdAt: publishedAt,
status,
versionSignatureType,
signatureType,
} = plugin;
const hasSignature = signatureType !== '' || versionSignatureType !== '';
const isDisabled = !!error;
const catalogPlugin = {
description,
@ -79,7 +76,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
orgName,
popularity,
publishedAt,
signature: hasSignature ? PluginSignatureStatus.valid : PluginSignatureStatus.missing,
signature: getPluginSignature({ remote: plugin, error }),
updatedAt,
version,
hasUpdate: false,
@ -115,7 +112,7 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat
orgName: author.name,
popularity: 0,
publishedAt: '',
signature,
signature: getPluginSignature({ local: plugin, error }),
signatureOrg,
signatureType,
updatedAt: updated,
@ -136,7 +133,6 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
const hasUpdate =
local?.hasUpdate || Boolean(remote?.version && local?.info.version && gt(remote?.version, local?.info.version));
const id = remote?.slug || local?.id || '';
const hasRemoteSignature = remote?.signatureType || remote?.versionSignatureType;
const isDisabled = !!error;
let logos = {
@ -171,7 +167,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
popularity: remote?.popularity || 0,
publishedAt: remote?.createdAt || '',
type: remote?.typeCode || local?.type,
signature: local?.signature || (hasRemoteSignature ? PluginSignatureStatus.valid : PluginSignatureStatus.missing),
signature: getPluginSignature({ local, remote, error }),
signatureOrg: local?.signatureOrg || remote?.versionSignedByOrgName,
signatureType: local?.signatureType || remote?.versionSignatureType || remote?.signatureType || undefined,
updatedAt: remote?.updatedAt || local?.info.updated || '',
@ -215,6 +211,35 @@ function groupErrorsByPluginId(errors: PluginError[] = []): Record<string, Plugi
}, {} as Record<string, PluginError | undefined>);
}
function getPluginSignature(options: {
local?: LocalPlugin;
remote?: RemotePlugin;
error?: PluginError;
}): PluginSignatureStatus {
const { error, local, remote } = options;
if (error) {
switch (error.errorCode) {
case PluginErrorCode.invalidSignature:
return PluginSignatureStatus.invalid;
case PluginErrorCode.missingSignature:
return PluginSignatureStatus.missing;
case PluginErrorCode.modifiedSignature:
return PluginSignatureStatus.modified;
}
}
if (local?.signature) {
return local.signature;
}
if (remote?.signatureType || remote?.versionSignatureType) {
return PluginSignatureStatus.valid;
}
return PluginSignatureStatus.missing;
}
// Updates the core Grafana config to have the correct list available panels
export const updatePanels = () =>
getBackendSrv()

View File

@ -99,8 +99,8 @@ export default function PluginDetails({ match, queryParams }: Props): JSX.Elemen
{/* Active tab */}
<TabContent className={styles.tabContent}>
<PluginDetailsDisabledError plugin={plugin} className={styles.alert} />
<PluginDetailsSignature plugin={plugin} className={styles.alert} />
<PluginDetailsDisabledError plugin={plugin} className={styles.alert} />
<PluginDetailsBody queryParams={queryParams} plugin={plugin} />
</TabContent>
</PluginPage>