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;