feat(helm): uninstall helm app from details view [r8s-285] (#648)

pull/12567/merge
Ali 2025-04-22 09:52:52 +12:00 committed by GitHub
parent 6fcf1893d3
commit bbe94f55b6
5 changed files with 133 additions and 18 deletions

View File

@ -7,6 +7,7 @@ import { getAllSettledItems } from '@/portainer/helpers/promise-utils';
import { withGlobalError } from '@/react-tools/react-query';
import { notifyError, notifySuccess } from '@/portainer/services/notifications';
import { pluralize } from '@/portainer/helpers/strings';
import { uninstallHelmApplication } from '@/react/kubernetes/helm/HelmApplicationView/queries/useUninstallHelmAppMutation';
import { parseKubernetesAxiosError } from '../../axiosError';
import { ApplicationRowData } from '../ListView/ApplicationsDatatable/types';
@ -225,7 +226,11 @@ async function deleteApplication(
await deletePodApplication(application, stacks, environmentId);
break;
case 'Helm':
await uninstallHelmApplication(application, environmentId);
await uninstallHelmApplication(
environmentId,
application.Name,
application.ResourcePool
);
break;
default:
throw new Error(
@ -266,21 +271,6 @@ async function deletePodApplication(
}
}
async function uninstallHelmApplication(
application: ApplicationRowData,
environmentId: EnvironmentId
) {
try {
await axios.delete(
`/endpoints/${environmentId}/kubernetes/helm/${application.Name}`,
{ params: { namespace: application.ResourcePool } }
);
} catch (error) {
// parseAxiosError, because it's a regular portainer api error
throw parseAxiosError(error, 'Unable to remove application');
}
}
async function deleteHorizontalPodAutoscaler(
hpa: HorizontalPodAutoscaler,
environmentId: EnvironmentId

View File

@ -0,0 +1,30 @@
import { EnvironmentId } from '@/react/portainer/environments/types';
import { useAuthorizations } from '@/react/hooks/useUser';
import { UninstallButton } from './UninstallButton';
export function ChartActions({
environmentId,
releaseName,
namespace,
}: {
environmentId: EnvironmentId;
releaseName: string;
namespace?: string;
}) {
const { authorized } = useAuthorizations('K8sApplicationsW');
if (!authorized) {
return null;
}
return (
<div className="inline-flex gap-x-2">
<UninstallButton
environmentId={environmentId}
releaseName={releaseName}
namespace={namespace}
/>
</div>
);
}

View File

@ -0,0 +1,47 @@
import { useRouter } from '@uirouter/react';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { notifySuccess } from '@/portainer/services/notifications';
import { DeleteButton } from '@@/buttons/DeleteButton';
import { useUninstallHelmAppMutation } from '../queries/useUninstallHelmAppMutation';
export function UninstallButton({
environmentId,
releaseName,
namespace,
}: {
environmentId: EnvironmentId;
releaseName: string;
namespace?: string;
}) {
const uninstallHelmAppMutation = useUninstallHelmAppMutation(environmentId);
const router = useRouter();
return (
<DeleteButton
size="medium"
data-cy="k8sApp-removeHelmChartButton"
isLoading={uninstallHelmAppMutation.isLoading}
confirmMessage="Do you want to remove the selected Helm chart? This will delete all resources associated with the Helm chart."
onConfirmed={handleUninstall}
>
Uninstall
</DeleteButton>
);
function handleUninstall() {
uninstallHelmAppMutation.mutate(
{ releaseName, namespace },
{
onSuccess: () => {
router.stateService.go('kubernetes.applications', {
endpointId: environmentId,
});
notifySuccess('Success', 'Helm chart uninstalled successfully');
},
}
);
}
}

View File

@ -12,6 +12,7 @@ import { Alert } from '@@/Alert';
import { HelmSummary } from './HelmSummary';
import { ReleaseTabs } from './ReleaseDetails/ReleaseTabs';
import { useHelmRelease } from './queries/useHelmRelease';
import { ChartActions } from './ChartActions/ChartActions';
export function HelmApplicationView() {
const environmentId = useEnvironmentId();
@ -32,8 +33,16 @@ export function HelmApplicationView() {
<div className="row">
<div className="col-sm-12">
<Widget>
{name && <WidgetTitle icon={helm} title={name} />}
<WidgetBody className="!pt-1">
{name && (
<WidgetTitle icon={helm} title={name}>
<ChartActions
environmentId={environmentId}
releaseName={name}
namespace={namespace}
/>
</WidgetTitle>
)}
<WidgetBody>
<HelmDetails
name={name}
namespace={namespace}

View File

@ -0,0 +1,39 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { withGlobalError, withInvalidate } from '@/react-tools/react-query';
import { queryKeys as applicationsQueryKeys } from '@/react/kubernetes/applications/queries/query-keys';
import { EnvironmentId } from '@/react/portainer/environments/types';
export function useUninstallHelmAppMutation(environmentId: EnvironmentId) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
releaseName,
namespace,
}: {
releaseName: string;
namespace?: string;
}) => uninstallHelmApplication(environmentId, releaseName, namespace),
...withInvalidate(queryClient, [
applicationsQueryKeys.applications(environmentId),
]),
...withGlobalError('Unable to uninstall helm application'),
});
}
export async function uninstallHelmApplication(
environmentId: EnvironmentId,
releaseName: string,
namespace?: string
) {
try {
await axios.delete(
`/endpoints/${environmentId}/kubernetes/helm/${releaseName}`,
{ params: { namespace } }
);
} catch (error) {
// parseAxiosError, because it's a regular portainer api error
throw parseAxiosError(error, 'Unable to remove application');
}
}