diff --git a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.test.tsx b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.test.tsx
index 77bdb1f096e..1da1da10d29 100644
--- a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.test.tsx
+++ b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.test.tsx
@@ -168,4 +168,79 @@ describe('InstallControlsButton', () => {
expect(button).toBeEnabled();
});
});
+
+ describe('uninstall button on prem', () => {
+ const store = configureStore({
+ plugins: getPluginsStateMock([]),
+ });
+
+ it('should be disabled when is Installing', () => {
+ store.dispatch({ type: 'plugins/uninstall/pending' });
+ render(
+
+
+
+ );
+ const button = screen.getByText('Uninstalling').closest('button');
+ expect(button).toBeDisabled();
+ });
+
+ it('should be enabled when it is not Installing', () => {
+ store.dispatch({ type: 'plugins/uninstall/fulfilled', payload: { id: '', changes: {} } });
+ render(
+
+
+
+ );
+ const button = screen.getByText('Uninstall').closest('button');
+ expect(button).toBeEnabled();
+ });
+ });
+
+ describe('uninstall button on managed instance', () => {
+ const oldFeatureTogglesManagedPluginsInstall = config.featureToggles.managedPluginsInstall;
+ const oldPluginAdminExternalManageEnabled = config.pluginAdminExternalManageEnabled;
+
+ beforeAll(() => {
+ config.featureToggles.managedPluginsInstall = true;
+ config.pluginAdminExternalManageEnabled = true;
+ });
+
+ afterAll(() => {
+ config.featureToggles.managedPluginsInstall = oldFeatureTogglesManagedPluginsInstall;
+ config.pluginAdminExternalManageEnabled = oldPluginAdminExternalManageEnabled;
+ });
+
+ const store = configureStore({
+ plugins: getPluginsStateMock([]),
+ });
+
+ it('should be disabled when isInstalling=false but isUninstallingFromInstance=true', () => {
+ store.dispatch({ type: 'plugins/uninstall/fulfilled', payload: { id: '', changes: {} } });
+ render(
+
+
+
+ );
+ const button = screen.getByText('Uninstall').closest('button');
+ expect(button).toBeDisabled();
+ });
+
+ it('should be enabled when isInstalling=false and isUninstallingFromInstance=false', () => {
+ store.dispatch({ type: 'plugins/uninstall/fulfilled', payload: { id: '', changes: {} } });
+ render(
+
+
+
+ );
+ const button = screen.getByText('Uninstall').closest('button');
+ expect(button).toBeEnabled();
+ });
+ });
});
diff --git a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx
index 68411e2fbdd..5ea2afbc7db 100644
--- a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx
+++ b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx
@@ -114,6 +114,11 @@ export function InstallControlsButton({
};
if (pluginStatus === PluginStatus.UNINSTALL) {
+ const disableUninstall =
+ config.pluginAdminExternalManageEnabled && configCore.featureToggles.managedPluginsInstall
+ ? plugin.isUninstallingFromInstance
+ : isUninstalling;
+
return (
<>
-
diff --git a/public/app/features/plugins/admin/helpers.ts b/public/app/features/plugins/admin/helpers.ts
index 25f32871f23..86c0c92b3e1 100644
--- a/public/app/features/plugins/admin/helpers.ts
+++ b/public/app/features/plugins/admin/helpers.ts
@@ -60,6 +60,8 @@ export function mergeLocalsAndRemotes({
instancesMap.has(remotePlugin.slug) &&
catalogPlugin.hasUpdate &&
catalogPlugin.installedVersion !== instancePlugin?.version;
+
+ catalogPlugin.isUninstallingFromInstance = Boolean(localCounterpart) && !instancesMap.has(remotePlugin.slug);
}
catalogPlugins.push(catalogPlugin);
diff --git a/public/app/features/plugins/admin/types.ts b/public/app/features/plugins/admin/types.ts
index 833cb1bc07f..7c54128e001 100644
--- a/public/app/features/plugins/admin/types.ts
+++ b/public/app/features/plugins/admin/types.ts
@@ -62,6 +62,7 @@ export interface CatalogPlugin extends WithAccessControlMetadata {
// instance plugins may not be fully installed, which means a new instance
// running the plugin didn't started yet
isFullyInstalled?: boolean;
+ isUninstallingFromInstance?: boolean;
isUpdatingFromInstance?: boolean;
iam?: IdentityAccessManagement;
}