diff --git a/.betterer.results b/.betterer.results
index 053ef6bfd02..8ed22ee4bfb 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -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 or use t()", "0"],
diff --git a/pkg/promlib/go.mod b/pkg/promlib/go.mod
index 020113b5982..0d1f1995de2 100644
--- a/pkg/promlib/go.mod
+++ b/pkg/promlib/go.mod
@@ -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
diff --git a/pkg/promlib/go.sum b/pkg/promlib/go.sum
index cbc5e25726a..036425a371b 100644
--- a/pkg/promlib/go.sum
+++ b/pkg/promlib/go.sum
@@ -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=
diff --git a/public/app/features/plugins/admin/api.ts b/public/app/features/plugins/admin/api.ts
index 18145c5f004..4520989603f 100644
--- a/public/app/features/plugins/admin/api.ts
+++ b/public/app/features/plugins/admin/api.ts
@@ -3,7 +3,7 @@ import { getBackendSrv, isFetchError } from '@grafana/runtime';
import { accessControlQueryParam } from 'app/core/utils/accessControl';
import { API_ROOT, GCOM_API_ROOT, INSTANCE_API_ROOT } from './constants';
-import { dependantPlugins, isLocalPluginVisibleByConfig, isRemotePluginVisibleByConfig } from './helpers';
+import { isLocalPluginVisibleByConfig, isRemotePluginVisibleByConfig } from './helpers';
import {
LocalPlugin,
RemotePlugin,
@@ -29,7 +29,6 @@ export async function getPluginDetails(id: string): Promise dep.name);
+ 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?`;
}
diff --git a/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx b/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx
index 15c0a93a387..a6a54061c9c 100644
--- a/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx
+++ b/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx
@@ -1,6 +1,5 @@
import { css } from '@emotion/css';
import { useState } from 'react';
-import * as React from 'react';
import { GrafanaTheme2, PluginDependencyInfo } from '@grafana/data';
import { config, reportInteraction } from '@grafana/runtime';
diff --git a/public/app/features/plugins/admin/helpers.ts b/public/app/features/plugins/admin/helpers.ts
index 24d26a54c0e..a3e2a9f720f 100644
--- a/public/app/features/plugins/admin/helpers.ts
+++ b/public/app/features/plugins/admin/helpers.ts
@@ -69,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;
@@ -87,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);
}
@@ -281,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),
};
}
diff --git a/public/app/features/plugins/admin/types.ts b/public/app/features/plugins/admin/types.ts
index 191612f9df2..c0cf514a504 100644
--- a/public/app/features/plugins/admin/types.ts
+++ b/public/app/features/plugins/admin/types.ts
@@ -7,7 +7,6 @@ import {
PluginDependencies,
PluginErrorCode,
WithAccessControlMetadata,
- PluginDependencyInfo,
} from '@grafana/data';
import { IconName } from '@grafana/ui';
import { StoreState, PluginsState } from 'app/types';
@@ -65,6 +64,7 @@ export interface CatalogPlugin extends WithAccessControlMetadata {
iam?: IdentityAccessManagement;
isProvisioned?: boolean;
url?: string;
+ dependantPlugins?: any[];
}
export interface CatalogPluginDetails {
@@ -73,7 +73,6 @@ export interface CatalogPluginDetails {
links: Rel[];
grafanaDependency?: string;
pluginDependencies?: PluginDependencies['plugins'];
- dependantPlugins?: PluginDependencyInfo[];
statusContext?: string;
iam?: IdentityAccessManagement;
changelog?: string;