mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PluginsCatalog: Fix so we display the correct badges when a plugin is disabled. (#41159)
This commit is contained in:
parent
8a3e192e6a
commit
ad888813c6
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { ReactElement } from 'react';
|
||||||
import { PluginErrorCode } from '@grafana/data';
|
import { PluginErrorCode } from '@grafana/data';
|
||||||
import { Alert } from '@grafana/ui';
|
import { Alert } from '@grafana/ui';
|
||||||
import { CatalogPlugin } from '../types';
|
import { CatalogPlugin } from '../types';
|
||||||
@ -9,7 +9,7 @@ type Props = {
|
|||||||
plugin: CatalogPlugin;
|
plugin: CatalogPlugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PluginDetailsDisabledError({ className, plugin }: Props): React.ReactElement | null {
|
export function PluginDetailsDisabledError({ className, plugin }: Props): ReactElement | null {
|
||||||
if (!plugin.isDisabled) {
|
if (!plugin.isDisabled) {
|
||||||
return null;
|
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) {
|
switch (error) {
|
||||||
case PluginErrorCode.modifiedSignature:
|
case PluginErrorCode.modifiedSignature:
|
||||||
return (
|
return (
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { PluginSignatureStatus } from '@grafana/data';
|
import { css } from '@emotion/css';
|
||||||
import { PluginSignatureBadge } from '@grafana/ui';
|
import { GrafanaTheme2, PluginSignatureStatus } from '@grafana/data';
|
||||||
|
import { PluginSignatureBadge, useStyles2 } from '@grafana/ui';
|
||||||
import { PluginSignatureDetailsBadge } from './PluginSignatureDetailsBadge';
|
import { PluginSignatureDetailsBadge } from './PluginSignatureDetailsBadge';
|
||||||
import { CatalogPlugin } from '../types';
|
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
|
// Designed to show plugin signature information in the header on the plugin's details page
|
||||||
export function PluginDetailsHeaderSignature({ plugin }: Props): React.ReactElement {
|
export function PluginDetailsHeaderSignature({ plugin }: Props): React.ReactElement {
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
|
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={styles.container}>
|
||||||
<a href="https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/" target="_blank" rel="noreferrer">
|
<a
|
||||||
|
href="https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
className={styles.link}
|
||||||
|
>
|
||||||
<PluginSignatureBadge status={plugin.signature} />
|
<PluginSignatureBadge status={plugin.signature} />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -24,3 +31,15 @@ export function PluginDetailsHeaderSignature({ plugin }: Props): React.ReactElem
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getStyles = (theme: GrafanaTheme2) => {
|
||||||
|
return {
|
||||||
|
container: css`
|
||||||
|
display: flex;
|
||||||
|
`,
|
||||||
|
link: css`
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { PluginSignatureStatus } from '@grafana/data';
|
import { PluginErrorCode, PluginSignatureStatus } from '@grafana/data';
|
||||||
import { Alert } from '@grafana/ui';
|
import { Alert } from '@grafana/ui';
|
||||||
import { CatalogPlugin } from '../types';
|
import { CatalogPlugin } from '../types';
|
||||||
|
|
||||||
@ -13,9 +13,10 @@ type Props = {
|
|||||||
export function PluginDetailsSignature({ className, plugin }: Props): React.ReactElement | null {
|
export function PluginDetailsSignature({ className, plugin }: Props): React.ReactElement | null {
|
||||||
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
|
const isSignatureValid = plugin.signature === PluginSignatureStatus.valid;
|
||||||
const isCore = plugin.signature === PluginSignatureStatus.internal;
|
const isCore = plugin.signature === PluginSignatureStatus.internal;
|
||||||
|
const isDisabled = plugin.isDisabled && isDisabledDueTooSignatureError(plugin.error);
|
||||||
|
|
||||||
// The basic information is already available in the header
|
// The basic information is already available in the header
|
||||||
if (isSignatureValid || isCore) {
|
if (isSignatureValid || isCore || isDisabled) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,3 +44,18 @@ export function PluginDetailsSignature({ className, plugin }: Props): React.Reac
|
|||||||
</Alert>
|
</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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { gt } from 'semver';
|
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 { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { Settings } from 'app/core/config';
|
import { Settings } from 'app/core/config';
|
||||||
import { CatalogPlugin, LocalPlugin, RemotePlugin } from './types';
|
import { CatalogPlugin, LocalPlugin, RemotePlugin } from './types';
|
||||||
@ -59,11 +59,8 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
|
|||||||
updatedAt,
|
updatedAt,
|
||||||
createdAt: publishedAt,
|
createdAt: publishedAt,
|
||||||
status,
|
status,
|
||||||
versionSignatureType,
|
|
||||||
signatureType,
|
|
||||||
} = plugin;
|
} = plugin;
|
||||||
|
|
||||||
const hasSignature = signatureType !== '' || versionSignatureType !== '';
|
|
||||||
const isDisabled = !!error;
|
const isDisabled = !!error;
|
||||||
const catalogPlugin = {
|
const catalogPlugin = {
|
||||||
description,
|
description,
|
||||||
@ -79,7 +76,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
|
|||||||
orgName,
|
orgName,
|
||||||
popularity,
|
popularity,
|
||||||
publishedAt,
|
publishedAt,
|
||||||
signature: hasSignature ? PluginSignatureStatus.valid : PluginSignatureStatus.missing,
|
signature: getPluginSignature({ remote: plugin, error }),
|
||||||
updatedAt,
|
updatedAt,
|
||||||
version,
|
version,
|
||||||
hasUpdate: false,
|
hasUpdate: false,
|
||||||
@ -115,7 +112,7 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat
|
|||||||
orgName: author.name,
|
orgName: author.name,
|
||||||
popularity: 0,
|
popularity: 0,
|
||||||
publishedAt: '',
|
publishedAt: '',
|
||||||
signature,
|
signature: getPluginSignature({ local: plugin, error }),
|
||||||
signatureOrg,
|
signatureOrg,
|
||||||
signatureType,
|
signatureType,
|
||||||
updatedAt: updated,
|
updatedAt: updated,
|
||||||
@ -136,7 +133,6 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
|
|||||||
const hasUpdate =
|
const hasUpdate =
|
||||||
local?.hasUpdate || Boolean(remote?.version && local?.info.version && gt(remote?.version, local?.info.version));
|
local?.hasUpdate || Boolean(remote?.version && local?.info.version && gt(remote?.version, local?.info.version));
|
||||||
const id = remote?.slug || local?.id || '';
|
const id = remote?.slug || local?.id || '';
|
||||||
const hasRemoteSignature = remote?.signatureType || remote?.versionSignatureType;
|
|
||||||
const isDisabled = !!error;
|
const isDisabled = !!error;
|
||||||
|
|
||||||
let logos = {
|
let logos = {
|
||||||
@ -171,7 +167,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
|
|||||||
popularity: remote?.popularity || 0,
|
popularity: remote?.popularity || 0,
|
||||||
publishedAt: remote?.createdAt || '',
|
publishedAt: remote?.createdAt || '',
|
||||||
type: remote?.typeCode || local?.type,
|
type: remote?.typeCode || local?.type,
|
||||||
signature: local?.signature || (hasRemoteSignature ? PluginSignatureStatus.valid : PluginSignatureStatus.missing),
|
signature: getPluginSignature({ local, remote, error }),
|
||||||
signatureOrg: local?.signatureOrg || remote?.versionSignedByOrgName,
|
signatureOrg: local?.signatureOrg || remote?.versionSignedByOrgName,
|
||||||
signatureType: local?.signatureType || remote?.versionSignatureType || remote?.signatureType || undefined,
|
signatureType: local?.signatureType || remote?.versionSignatureType || remote?.signatureType || undefined,
|
||||||
updatedAt: remote?.updatedAt || local?.info.updated || '',
|
updatedAt: remote?.updatedAt || local?.info.updated || '',
|
||||||
@ -215,6 +211,35 @@ function groupErrorsByPluginId(errors: PluginError[] = []): Record<string, Plugi
|
|||||||
}, {} as Record<string, PluginError | undefined>);
|
}, {} 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
|
// Updates the core Grafana config to have the correct list available panels
|
||||||
export const updatePanels = () =>
|
export const updatePanels = () =>
|
||||||
getBackendSrv()
|
getBackendSrv()
|
||||||
|
@ -99,8 +99,8 @@ export default function PluginDetails({ match, queryParams }: Props): JSX.Elemen
|
|||||||
|
|
||||||
{/* Active tab */}
|
{/* Active tab */}
|
||||||
<TabContent className={styles.tabContent}>
|
<TabContent className={styles.tabContent}>
|
||||||
<PluginDetailsDisabledError plugin={plugin} className={styles.alert} />
|
|
||||||
<PluginDetailsSignature plugin={plugin} className={styles.alert} />
|
<PluginDetailsSignature plugin={plugin} className={styles.alert} />
|
||||||
|
<PluginDetailsDisabledError plugin={plugin} className={styles.alert} />
|
||||||
<PluginDetailsBody queryParams={queryParams} plugin={plugin} />
|
<PluginDetailsBody queryParams={queryParams} plugin={plugin} />
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</PluginPage>
|
</PluginPage>
|
||||||
|
Loading…
Reference in New Issue
Block a user