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; }