mirror of
https://github.com/grafana/grafana.git
synced 2025-12-21 03:54:29 +08:00
Compare commits
28 Commits
zoltan/pos
...
plugin-dep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
335f005dac | ||
|
|
da01063688 | ||
|
|
bc498dc780 | ||
|
|
5108ca2ac8 | ||
|
|
c01fb907ad | ||
|
|
440587a510 | ||
|
|
949025bbf3 | ||
|
|
f33ac76119 | ||
|
|
e6d4dffe4f | ||
|
|
3228650d22 | ||
|
|
4011ac4dd2 | ||
|
|
3e67467872 | ||
|
|
6ad57d0e6e | ||
|
|
a9c410c380 | ||
|
|
6b62cbb5b0 | ||
|
|
374fede490 | ||
|
|
2f87e10296 | ||
|
|
e547ee52b5 | ||
|
|
81110f0ea3 | ||
|
|
0c01993ed4 | ||
|
|
00e6b0ea9f | ||
|
|
919dc5377c | ||
|
|
6ab5581fc5 | ||
|
|
c9ff568c91 | ||
|
|
30696c0966 | ||
|
|
705c86b6fe | ||
|
|
34f4409b0d | ||
|
|
367bfdddfe |
@@ -4862,7 +4862,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/plugins/admin/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/features/plugins/angularDeprecation/AngularDeprecationNotice.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
|
||||
@@ -981,6 +981,7 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250129195454-3e5b80036b7a/go.mod h1:QsnoKX/iYZxA4Cv+H+wC7uxutBD8qi8ZW5UJvD2TYmU=
|
||||
github.com/grafana/alerting v0.0.0-20250221202230-9d7e00921e44/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/authlib v0.0.0-20250123104008-e99947858901/go.mod h1:/gYfphsNu9v1qYWXxpv1NSvMEMSwvdf8qb8YlgwIRl8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120144156-d6737a7dc8f5/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/authlib/types v0.0.0-20250120145936-5f0e28e7a87c/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
|
||||
@@ -594,6 +594,7 @@ export {
|
||||
type AngularMeta,
|
||||
type PluginMeta,
|
||||
type PluginDependencies,
|
||||
type PluginDependencyInfo,
|
||||
type PluginExtensions,
|
||||
type PluginInclude,
|
||||
type PluginBuildInfo,
|
||||
|
||||
@@ -102,7 +102,7 @@ export interface PluginMeta<T extends KeyValue = {}> {
|
||||
moduleHash?: string;
|
||||
}
|
||||
|
||||
interface PluginDependencyInfo {
|
||||
export interface PluginDependencyInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
AngularMeta,
|
||||
PluginLoadingStrategy,
|
||||
PluginDependencies,
|
||||
PluginDependencyInfo,
|
||||
PluginExtensions,
|
||||
} from '@grafana/data';
|
||||
|
||||
@@ -140,6 +141,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
|
||||
pluginCatalogManagedPlugins: string[] = [];
|
||||
pluginCatalogPreinstalledPlugins: PreinstalledPlugin[] = [];
|
||||
pluginsCDNBaseURL = '';
|
||||
pluginDependants?: { [key: string]: PluginDependencyInfo[] } = {};
|
||||
expressionsEnabled = false;
|
||||
awsAllowedAuthProviders: string[] = [];
|
||||
awsAssumeRoleEnabled = false;
|
||||
|
||||
@@ -2,6 +2,7 @@ package dtos
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-azure-sdk-go/v2/azsettings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
@@ -221,29 +222,30 @@ type FrontendSettingsDTO struct {
|
||||
|
||||
LicenseInfo FrontendSettingsLicenseInfoDTO `json:"licenseInfo"`
|
||||
|
||||
FeatureToggles map[string]bool `json:"featureToggles"`
|
||||
AnonymousEnabled bool `json:"anonymousEnabled"`
|
||||
AnonymousDeviceLimit int64 `json:"anonymousDeviceLimit"`
|
||||
RendererAvailable bool `json:"rendererAvailable"`
|
||||
RendererVersion string `json:"rendererVersion"`
|
||||
RendererDefaultImageWidth int `json:"rendererDefaultImageWidth"`
|
||||
RendererDefaultImageHeight int `json:"rendererDefaultImageHeight"`
|
||||
RendererDefaultImageScale float64 `json:"rendererDefaultImageScale"`
|
||||
Http2Enabled bool `json:"http2Enabled"`
|
||||
GrafanaJavascriptAgent setting.GrafanaJavascriptAgent `json:"grafanaJavascriptAgent"`
|
||||
PluginCatalogURL string `json:"pluginCatalogURL"`
|
||||
PluginAdminEnabled bool `json:"pluginAdminEnabled"`
|
||||
PluginAdminExternalManageEnabled bool `json:"pluginAdminExternalManageEnabled"`
|
||||
PluginCatalogHiddenPlugins []string `json:"pluginCatalogHiddenPlugins"`
|
||||
PluginCatalogManagedPlugins []string `json:"pluginCatalogManagedPlugins"`
|
||||
PluginCatalogPreinstalledPlugins []setting.InstallPlugin `json:"pluginCatalogPreinstalledPlugins"`
|
||||
ExpressionsEnabled bool `json:"expressionsEnabled"`
|
||||
AwsAllowedAuthProviders []string `json:"awsAllowedAuthProviders"`
|
||||
AwsAssumeRoleEnabled bool `json:"awsAssumeRoleEnabled"`
|
||||
SupportBundlesEnabled bool `json:"supportBundlesEnabled"`
|
||||
SnapshotEnabled bool `json:"snapshotEnabled"`
|
||||
SecureSocksDSProxyEnabled bool `json:"secureSocksDSProxyEnabled"`
|
||||
ReportingStaticContext map[string]string `json:"reportingStaticContext"`
|
||||
FeatureToggles map[string]bool `json:"featureToggles"`
|
||||
AnonymousEnabled bool `json:"anonymousEnabled"`
|
||||
AnonymousDeviceLimit int64 `json:"anonymousDeviceLimit"`
|
||||
RendererAvailable bool `json:"rendererAvailable"`
|
||||
RendererVersion string `json:"rendererVersion"`
|
||||
RendererDefaultImageWidth int `json:"rendererDefaultImageWidth"`
|
||||
RendererDefaultImageHeight int `json:"rendererDefaultImageHeight"`
|
||||
RendererDefaultImageScale float64 `json:"rendererDefaultImageScale"`
|
||||
Http2Enabled bool `json:"http2Enabled"`
|
||||
GrafanaJavascriptAgent setting.GrafanaJavascriptAgent `json:"grafanaJavascriptAgent"`
|
||||
PluginCatalogURL string `json:"pluginCatalogURL"`
|
||||
PluginAdminEnabled bool `json:"pluginAdminEnabled"`
|
||||
PluginAdminExternalManageEnabled bool `json:"pluginAdminExternalManageEnabled"`
|
||||
PluginCatalogHiddenPlugins []string `json:"pluginCatalogHiddenPlugins"`
|
||||
PluginCatalogManagedPlugins []string `json:"pluginCatalogManagedPlugins"`
|
||||
PluginCatalogPreinstalledPlugins []setting.InstallPlugin `json:"pluginCatalogPreinstalledPlugins"`
|
||||
ExpressionsEnabled bool `json:"expressionsEnabled"`
|
||||
AwsAllowedAuthProviders []string `json:"awsAllowedAuthProviders"`
|
||||
AwsAssumeRoleEnabled bool `json:"awsAssumeRoleEnabled"`
|
||||
SupportBundlesEnabled bool `json:"supportBundlesEnabled"`
|
||||
SnapshotEnabled bool `json:"snapshotEnabled"`
|
||||
SecureSocksDSProxyEnabled bool `json:"secureSocksDSProxyEnabled"`
|
||||
ReportingStaticContext map[string]string `json:"reportingStaticContext"`
|
||||
PluginDependencies map[string][]plugins.Dependency `json:"pluginDependants"`
|
||||
|
||||
Azure FrontendSettingsAzureDTO `json:"azure"`
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
ExploreHideLogsDownload: hs.Cfg.ExploreHideLogsDownload,
|
||||
|
||||
DefaultDatasourceManageAlertsUIToggle: hs.Cfg.DefaultDatasourceManageAlertsUIToggle,
|
||||
PluginDependencies: pluginDependencyMap(c.Req.Context(), hs.pluginStore),
|
||||
|
||||
BuildInfo: dtos.FrontendSettingsBuildInfoDTO{
|
||||
HideVersion: hideVersion,
|
||||
@@ -790,3 +791,24 @@ func (hs *HTTPServer) getEnabledOAuthProviders() map[string]any {
|
||||
}
|
||||
return providers
|
||||
}
|
||||
|
||||
// pluginDependencyMap returns a map of dependant plugin IDs to their parent.
|
||||
func pluginDependencyMap(ctx context.Context, pluginStore pluginstore.Store) map[string][]plugins.Dependency {
|
||||
dependencies := make(map[string][]plugins.Dependency)
|
||||
|
||||
for _, plugin := range pluginStore.Plugins(ctx) {
|
||||
for _, dep := range plugin.Dependencies.Plugins {
|
||||
if _, exists := dependencies[dep.ID]; !exists {
|
||||
dependencies[dep.ID] = []plugins.Dependency{}
|
||||
}
|
||||
dependencies[dep.ID] = append(dependencies[dep.ID], plugins.Dependency{
|
||||
ID: plugin.ID,
|
||||
Version: plugin.Info.Version,
|
||||
Name: plugin.Name,
|
||||
Type: string(plugin.Type),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return dependencies
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ require (
|
||||
github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c // indirect
|
||||
github.com/apache/arrow-go/v18 v18.0.1-0.20241212180703-82be143d7c30 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go v1.55.6 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
|
||||
@@ -26,8 +26,8 @@ github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE=
|
||||
github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
|
||||
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk=
|
||||
github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps=
|
||||
|
||||
@@ -130,12 +130,19 @@ export function InstallControlsButton({
|
||||
uninstallTitle = 'Preinstalled plugin. Remove from Grafana config before uninstalling.';
|
||||
}
|
||||
|
||||
let uninstallConfirmationBody = 'Are you sure you want to uninstall this plugin?';
|
||||
// TODO && dependant plugin is still installed
|
||||
const dependencyOf = plugin.dependantPlugins?.map((dep) => dep.name);
|
||||
if (dependencyOf?.length) {
|
||||
uninstallConfirmationBody = `This plugin is a dependency of ${dependencyOf.join(', ')}. Are you sure you want to uninstall this plugin?`;
|
||||
}
|
||||
|
||||
const uninstallControls = (
|
||||
<>
|
||||
<ConfirmModal
|
||||
isOpen={isConfirmModalVisible}
|
||||
title={`Uninstall ${plugin.name}`}
|
||||
body="Are you sure you want to uninstall this plugin?"
|
||||
body={uninstallConfirmationBody}
|
||||
confirmText="Confirm"
|
||||
icon="exclamation-triangle"
|
||||
onConfirm={onUninstall}
|
||||
@@ -162,7 +169,7 @@ export function InstallControlsButton({
|
||||
}
|
||||
|
||||
if (!plugin.isPublished || hasInstallWarning) {
|
||||
// Cannot be updated or installed
|
||||
// Cannot be updated/installed/uninstalled
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { GrafanaTheme2, PluginDependencyInfo } from '@grafana/data';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { PageInfoItem } from '@grafana/runtime/src/components/PluginPage';
|
||||
import {
|
||||
Stack,
|
||||
@@ -20,7 +20,8 @@ import {
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { formatDate } from 'app/core/internationalization/dates';
|
||||
|
||||
import { CatalogPlugin } from '../types';
|
||||
import { getLatestCompatibleVersion } from '../helpers';
|
||||
import { CatalogPlugin, PluginIconName } from '../types';
|
||||
|
||||
type Props = {
|
||||
pluginExtentionsInfo: PageInfoItem[];
|
||||
@@ -51,6 +52,25 @@ export function PluginDetailsPanel(props: Props): React.ReactElement | null {
|
||||
});
|
||||
};
|
||||
|
||||
const pluginDependencies = plugin.details?.pluginDependencies;
|
||||
let grafanaDependency = plugin.details?.grafanaDependency;
|
||||
if (!grafanaDependency) {
|
||||
grafanaDependency = 'unknown';
|
||||
}
|
||||
|
||||
const useLatestCompatibleInfo = !plugin.isInstalled;
|
||||
const latestCompatibleVersion = getLatestCompatibleVersion(plugin.details?.versions);
|
||||
if (useLatestCompatibleInfo && latestCompatibleVersion?.grafanaDependency) {
|
||||
grafanaDependency = latestCompatibleVersion?.grafanaDependency;
|
||||
}
|
||||
|
||||
let pluginDependants: PluginDependencyInfo[] = [];
|
||||
if (config.pluginDependants && config.pluginDependants[plugin.id]) {
|
||||
pluginDependants = config.pluginDependants[plugin.id];
|
||||
}
|
||||
const hasDependencyInfo =
|
||||
grafanaDependency || (pluginDependencies && pluginDependencies.length) || pluginDependants.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack direction="column" gap={3} shrink={0} grow={0} width={width} data-testid="plugin-details-panel">
|
||||
@@ -90,6 +110,50 @@ export function PluginDetailsPanel(props: Props): React.ReactElement | null {
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
{hasDependencyInfo && (
|
||||
<Box padding={2} borderColor="medium" borderStyle="solid">
|
||||
<Stack direction="column" gap={1}>
|
||||
<Text color="secondary">
|
||||
<Trans i18nKey="plugins.details.labels.dependencies">Dependencies</Trans>
|
||||
</Text>
|
||||
<Stack direction="column" gap={1}>
|
||||
<span className={styles.depBadge}>
|
||||
<Icon name="grafana" className={styles.icon} />
|
||||
<Trans i18nKey="plugins.details.labels.grafanaDependency">Grafana </Trans> {grafanaDependency}
|
||||
</span>
|
||||
</Stack>
|
||||
|
||||
{pluginDependencies && pluginDependencies.length > 0 && (
|
||||
<Stack direction="column" gap={1}>
|
||||
{pluginDependencies.map((p) => {
|
||||
return (
|
||||
<TextLink key={p.id} href={'/plugins/' + p.id}>
|
||||
<Icon name={PluginIconName[p.type]} className={styles.icon} />
|
||||
{p.name} {p.version}
|
||||
</TextLink>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
{pluginDependants && pluginDependants.length > 0 && (
|
||||
<Stack direction="column" gap={1}>
|
||||
<Text color="secondary">
|
||||
<Trans i18nKey={'plugins.details.labels.pluginDependants'}>Required by: </Trans>
|
||||
</Text>
|
||||
{pluginDependants.map((p) => {
|
||||
return (
|
||||
<TextLink key={p.id} href={'/plugins/' + p.id}>
|
||||
<Icon name={PluginIconName[p.type]} className={styles.icon} />
|
||||
{p.name} {p.version}
|
||||
</TextLink>
|
||||
);
|
||||
})}
|
||||
</Stack>
|
||||
)}
|
||||
</Stack>
|
||||
</Box>
|
||||
)}
|
||||
{shouldRenderLinks && (
|
||||
<>
|
||||
<Box padding={2} borderColor="medium" borderStyle="solid">
|
||||
@@ -241,5 +305,13 @@ export const getStyles = (theme: GrafanaTheme2) => {
|
||||
pluginVersionDetails: css({
|
||||
wordBreak: 'break-word',
|
||||
}),
|
||||
depBadge: css({
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
}),
|
||||
icon: css({
|
||||
color: theme.colors.text.secondary,
|
||||
marginRight: theme.spacing(0.5),
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -349,6 +349,7 @@ describe('Plugins/Helpers', () => {
|
||||
isFullyInstalled: true,
|
||||
angularDetected: false,
|
||||
url: 'https://github.com/alexanderzobnin/grafana-zabbix',
|
||||
dependantPlugins: [],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
import uFuzzy from '@leeoniya/ufuzzy';
|
||||
|
||||
import { PluginSignatureStatus, dateTimeParse, PluginError, PluginType, PluginErrorCode } from '@grafana/data';
|
||||
import {
|
||||
PluginSignatureStatus,
|
||||
dateTimeParse,
|
||||
PluginError,
|
||||
PluginType,
|
||||
PluginErrorCode,
|
||||
PluginDependencyInfo,
|
||||
} from '@grafana/data';
|
||||
import { config, featureEnabled } from '@grafana/runtime';
|
||||
import { Settings } from 'app/core/config';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
@@ -62,11 +69,14 @@ export function mergeLocalsAndRemotes({
|
||||
if (!shouldSkip) {
|
||||
const catalogPlugin = mergeLocalAndRemote(localCounterpart, remotePlugin, error);
|
||||
|
||||
const isDependency = catalogPlugin?.dependantPlugins && catalogPlugin?.dependantPlugins.length > 0;
|
||||
|
||||
// for managed instances, check if plugin is installed, but not yet present in the current instance
|
||||
if (config.pluginAdminExternalManageEnabled) {
|
||||
catalogPlugin.isFullyInstalled = catalogPlugin.isCore
|
||||
? true
|
||||
: (instancesMap.has(remotePlugin.slug) || provisionedSet.has(remotePlugin.slug)) && catalogPlugin.isInstalled;
|
||||
: (instancesMap.has(remotePlugin.slug) || provisionedSet.has(remotePlugin.slug) || isDependency) &&
|
||||
catalogPlugin.isInstalled;
|
||||
|
||||
catalogPlugin.isInstalled = instancesMap.has(remotePlugin.slug) || catalogPlugin.isInstalled;
|
||||
|
||||
@@ -80,7 +90,8 @@ export function mergeLocalsAndRemotes({
|
||||
catalogPlugin.hasUpdate = true;
|
||||
}
|
||||
|
||||
catalogPlugin.isUninstallingFromInstance = Boolean(localCounterpart) && !instancesMap.has(remotePlugin.slug);
|
||||
catalogPlugin.isUninstallingFromInstance =
|
||||
Boolean(localCounterpart) && !instancesMap.has(remotePlugin.slug) && !isDependency;
|
||||
catalogPlugin.isProvisioned = provisionedSet.has(remotePlugin.slug);
|
||||
}
|
||||
|
||||
@@ -274,6 +285,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
|
||||
iam: local?.iam,
|
||||
latestVersion: local?.latestVersion || remote?.version || '',
|
||||
url: remote?.url || '',
|
||||
dependantPlugins: dependantPlugins(id),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -395,6 +407,22 @@ export function isManagedPlugin(id: string) {
|
||||
return pluginCatalogManagedPlugins?.includes(id);
|
||||
}
|
||||
|
||||
export function dependantPlugins(id: string): PluginDependencyInfo[] {
|
||||
const { pluginDependants } = config;
|
||||
if (!pluginDependants) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const dependants: PluginDependencyInfo[] = [];
|
||||
if (pluginDependants[id]) {
|
||||
for (let dependant of pluginDependants[id]) {
|
||||
dependants.push(dependant);
|
||||
}
|
||||
}
|
||||
|
||||
return dependants;
|
||||
}
|
||||
|
||||
export function isPreinstalledPlugin(id: string): { found: boolean; withVersion: boolean } {
|
||||
const { pluginCatalogPreinstalledPlugins } = config;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2, PluginSignatureType } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { PageInfoItem } from '../../../../core/components/Page/types';
|
||||
@@ -84,7 +85,7 @@ export const usePluginInfo = (plugin?: CatalogPlugin): PageInfoItem[] => {
|
||||
}
|
||||
const hasNoDependencyInfo = !grafanaDependency && (!pluginDependencies || !pluginDependencies.length);
|
||||
|
||||
if (!hasNoDependencyInfo) {
|
||||
if (!hasNoDependencyInfo && !config.featureToggles.pluginsDetailsRightPanel) {
|
||||
info.push({
|
||||
label: t('plugins.details.labels.dependencies', 'Dependencies'),
|
||||
value: <PluginDetailsHeaderDependencies plugin={plugin} grafanaDependency={grafanaDependency} />,
|
||||
|
||||
@@ -64,15 +64,13 @@ export interface CatalogPlugin extends WithAccessControlMetadata {
|
||||
iam?: IdentityAccessManagement;
|
||||
isProvisioned?: boolean;
|
||||
url?: string;
|
||||
dependantPlugins?: any[];
|
||||
}
|
||||
|
||||
export interface CatalogPluginDetails {
|
||||
readme?: string;
|
||||
versions?: Version[];
|
||||
links: Array<{
|
||||
name: string;
|
||||
url: string;
|
||||
}>;
|
||||
links: Rel[];
|
||||
grafanaDependency?: string;
|
||||
pluginDependencies?: PluginDependencies['plugins'];
|
||||
statusContext?: string;
|
||||
|
||||
@@ -3574,10 +3574,12 @@
|
||||
"documentation": "Documentation",
|
||||
"downloads": "Downloads",
|
||||
"from": "From",
|
||||
"grafanaDependency": "Grafana ",
|
||||
"installedVersion": "Installed Version",
|
||||
"lastCommitDate": "Last commit date:",
|
||||
"latestVersion": "Latest Version",
|
||||
"license": "License",
|
||||
"pluginDependants": "Required by: ",
|
||||
"raiseAnIssue": "Raise an issue",
|
||||
"reportAbuse": "Report a concern ",
|
||||
"reportAbuseTooltip": "Report issues related to malicious or harmful plugins directly to Grafana Labs.",
|
||||
|
||||
Reference in New Issue
Block a user