From abca9b8b4fbf920364eb4b35646869e3bdab836b Mon Sep 17 00:00:00 2001 From: vakarisz Date: Thu, 16 May 2024 17:05:23 +0300 Subject: [PATCH] UI: Add plugin uninstall button --- .../installed/PluginUninstallButton.tsx | 44 +++++++++++++++++++ .../(protected)/plugins/installed/page.tsx | 13 ++++-- .../api/agentPlugins/agentPluginEndpoints.tsx | 15 ++++++- 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/PluginUninstallButton.tsx diff --git a/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/PluginUninstallButton.tsx b/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/PluginUninstallButton.tsx new file mode 100644 index 00000000000..fd889ae32a5 --- /dev/null +++ b/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/PluginUninstallButton.tsx @@ -0,0 +1,44 @@ +import { GridActionsCellItem } from '@mui/x-data-grid'; +import React from 'react'; +import { useUninstallPluginMutation } from '@/redux/features/api/agentPlugins/agentPluginEndpoints'; +import MonkeyLoadingIcon from '@/_components/icons/MonkeyLoadingIcon'; +import { PluginId, PluginInfo } from '@/redux/features/api/agentPlugins/types'; +import DeleteIcon from '@mui/icons-material/Delete'; + +const PluginUninstallButton = (props: PluginInfo) => { + const [uninstallPlugin, { isLoading: isUninstalling }] = + useUninstallPluginMutation(); + + const onUninstallClick = () => { + uninstallPlugin(props); + }; + + const UninstallButton = () => { + return ( + } + label="Uninstall" + onClick={() => onUninstallClick()} + /> + ); + }; + + if (isUninstalling) { + return UninstallInProgressButton(props.pluginId); + } else { + return UninstallButton(); + } +}; + +const UninstallInProgressButton = (pluginId: PluginId) => { + return ( + } + label="Uninstalling" + /> + ); +}; + +export default PluginUninstallButton; diff --git a/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/page.tsx b/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/page.tsx index 262c73e850a..063a688e71a 100644 --- a/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/page.tsx +++ b/monkey/monkey_island/cc/next_ui/src/app/(protected)/plugins/installed/page.tsx @@ -10,6 +10,7 @@ import Grid from '@mui/material/Grid'; import { InstalledPlugin } from '@/redux/features/api/agentPlugins/types'; import InstalledPluginFilters from '@/app/(protected)/plugins/installed/InstalledPluginFilters'; import PluginUpgradeButton from '@/app/(protected)/plugins/installed/PluginUpgradeButton'; +import PluginUninstallButton from '@/app/(protected)/plugins/installed/PluginUninstallButton'; export default function InstalledPluginsPage() { const { @@ -31,9 +32,15 @@ export default function InstalledPluginsPage() { ); }; - // eslint-disable-next-line @typescript-eslint/no-unused-vars const getUninstallAction = (plugin: InstalledPlugin) => { - return []; + return ( + + ); }; const getRowActions = (row: PluginRow) => { @@ -42,7 +49,7 @@ export default function InstalledPluginsPage() { (installedPlugin) => installedPlugin.id === row.id ); if (!plugin) return []; - return [getUpgradeAction(plugin)]; + return [getUpgradeAction(plugin), getUninstallAction(plugin)]; }; const getOverlayMessage = () => { diff --git a/monkey/monkey_island/cc/next_ui/src/redux/features/api/agentPlugins/agentPluginEndpoints.tsx b/monkey/monkey_island/cc/next_ui/src/redux/features/api/agentPlugins/agentPluginEndpoints.tsx index 2500e8f67c0..2df4bb95036 100644 --- a/monkey/monkey_island/cc/next_ui/src/redux/features/api/agentPlugins/agentPluginEndpoints.tsx +++ b/monkey/monkey_island/cc/next_ui/src/redux/features/api/agentPlugins/agentPluginEndpoints.tsx @@ -19,6 +19,7 @@ enum BackendEndpoints { PLUGIN_INDEX = '/agent-plugins/available/index', PLUGIN_INDEX_FORCE_REFRESH = `${BackendEndpoints.PLUGIN_INDEX}?force_refresh=true`, PLUGIN_INSTALL = '/install-agent-plugin', + PLUGIN_UNINSTALL = '/uninstall-agent-plugin', PLUGIN_MANIFESTS = '/agent-plugins/installed/manifests' } @@ -100,6 +101,17 @@ export const agentPluginEndpoints = islandApiSlice.injectEndpoints({ } }), invalidatesTags: ['InstalledAgentPlugins'] + }), + uninstallPlugin: builder.mutation({ + query: (pluginInfo: PluginInfo) => ({ + url: BackendEndpoints.PLUGIN_UNINSTALL, + method: HTTP_METHODS.POST, + body: { + plugin_type: pluginInfo.pluginType, + name: pluginInfo.pluginName + } + }), + invalidatesTags: ['InstalledAgentPlugins'] }) }) }); @@ -109,5 +121,6 @@ export const { useGetInstalledPluginsQuery, useInstallPluginMutation, useUploadPluginMutation, - useGetLatestPluginVersionQuery + useGetLatestPluginVersionQuery, + useUninstallPluginMutation } = agentPluginEndpoints;