Provisioning: Add option to keep resources when deleting repository (#109955)
* Provisioning: Add option to keep deleted repository resources * Use existing repository * Update confirm modal * Update text
This commit is contained in:
@@ -1,50 +1,116 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom-v5-compat';
|
import { useNavigate } from 'react-router-dom-v5-compat';
|
||||||
|
|
||||||
import { t } from '@grafana/i18n';
|
import { t, Trans } from '@grafana/i18n';
|
||||||
import { ConfirmModal, IconButton } from '@grafana/ui';
|
import { Button, ConfirmModal, Dropdown, Icon, Menu, Stack } from '@grafana/ui';
|
||||||
import { useDeleteRepositoryMutation } from 'app/api/clients/provisioning/v0alpha1';
|
import {
|
||||||
|
Repository,
|
||||||
|
useDeleteRepositoryMutation,
|
||||||
|
useReplaceRepositoryMutation,
|
||||||
|
} from 'app/api/clients/provisioning/v0alpha1';
|
||||||
|
|
||||||
|
type DeleteAction = 'remove-resources' | 'keep-resources';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
name: string;
|
name: string;
|
||||||
|
repository: Repository;
|
||||||
redirectTo?: string;
|
redirectTo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DeleteRepositoryButton({ name, redirectTo }: Props) {
|
export function DeleteRepositoryButton({ name, repository, redirectTo }: Props) {
|
||||||
const [deleteRepository, request] = useDeleteRepositoryMutation();
|
const [deleteRepository, deleteRequest] = useDeleteRepositoryMutation();
|
||||||
|
const [replaceRepository, replaceRequest] = useReplaceRepositoryMutation();
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const [selectedAction, setSelectedAction] = useState<DeleteAction>('remove-resources');
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (request.isSuccess) {
|
if (deleteRequest.isSuccess) {
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
if (redirectTo) {
|
if (redirectTo) {
|
||||||
navigate(redirectTo);
|
navigate(redirectTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [request.isSuccess, redirectTo, navigate]);
|
}, [deleteRequest.isSuccess, redirectTo, navigate]);
|
||||||
|
|
||||||
const onConfirm = useCallback(() => {
|
const onConfirm = useCallback(async () => {
|
||||||
|
if (selectedAction === 'keep-resources' && repository) {
|
||||||
|
const updatedRepository = {
|
||||||
|
...repository,
|
||||||
|
metadata: {
|
||||||
|
...repository.metadata,
|
||||||
|
finalizers: ['cleanup', 'release-orphan-resources'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await replaceRepository({ name, repository: updatedRepository });
|
||||||
|
}
|
||||||
deleteRepository({ name });
|
deleteRepository({ name });
|
||||||
}, [deleteRepository, name]);
|
}, [deleteRepository, replaceRepository, name, selectedAction, repository]);
|
||||||
|
|
||||||
|
const getConfirmationMessage = () => {
|
||||||
|
if (selectedAction === 'remove-resources') {
|
||||||
|
return t(
|
||||||
|
'provisioning.delete-repository-button.confirm-delete-with-resources',
|
||||||
|
'Are you sure you want to delete the repository configuration and all its resources?'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return t(
|
||||||
|
'provisioning.delete-repository-button.confirm-delete-keep-resources',
|
||||||
|
'Are you sure you want to delete the repository configuration but keep its resources?'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getModalTitle = () => {
|
||||||
|
if (selectedAction === 'remove-resources') {
|
||||||
|
return t(
|
||||||
|
'provisioning.delete-repository-button.title-delete-repository-and-resources',
|
||||||
|
'Delete repository configuration and resources'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return t(
|
||||||
|
'provisioning.delete-repository-button.title-delete-repository-only',
|
||||||
|
'Delete repository configuration only'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isLoading = deleteRequest.isLoading || replaceRequest.isLoading;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<IconButton
|
<Dropdown
|
||||||
name="trash-alt"
|
overlay={
|
||||||
tooltip={t('provisioning.delete-repository-button.tooltip-delete-this-repository', 'Delete this repository')}
|
<Menu>
|
||||||
disabled={request.isLoading}
|
<Menu.Item
|
||||||
onClick={() => {
|
label={t(
|
||||||
setShowModal(true);
|
'provisioning.delete-repository-button.delete-and-remove-resources',
|
||||||
}}
|
'Delete and remove resources (default)'
|
||||||
/>
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedAction('remove-resources');
|
||||||
|
setShowModal(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Menu.Item
|
||||||
|
label={t('provisioning.delete-repository-button.delete-and-keep-resources', 'Delete and keep resources')}
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedAction('keep-resources');
|
||||||
|
setShowModal(true);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button variant="destructive" icon="trash-alt" disabled={isLoading}>
|
||||||
|
<Stack alignItems="center">
|
||||||
|
<Trans i18nKey="provisioning.delete-repository-button.delete">Delete</Trans>
|
||||||
|
<Icon name={'angle-down'} />
|
||||||
|
</Stack>
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={showModal}
|
isOpen={showModal}
|
||||||
title={t('provisioning.delete-repository-button.title-delete-repository', 'Delete repository config')}
|
title={getModalTitle()}
|
||||||
body={t(
|
body={getConfirmationMessage()}
|
||||||
'provisioning.delete-repository-button.confirm-delete-repository',
|
|
||||||
'Are you sure you want to delete the repository config?'
|
|
||||||
)}
|
|
||||||
confirmText={t('provisioning.delete-repository-button.button-delete', 'Delete')}
|
confirmText={t('provisioning.delete-repository-button.button-delete', 'Delete')}
|
||||||
onConfirm={onConfirm}
|
onConfirm={onConfirm}
|
||||||
onDismiss={() => setShowModal(false)}
|
onDismiss={() => setShowModal(false)}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export function RepositoryActions({ repository }: RepositoryActionsProps) {
|
|||||||
<LinkButton variant="secondary" icon="cog" href={`${PROVISIONING_URL}/${name}/edit`}>
|
<LinkButton variant="secondary" icon="cog" href={`${PROVISIONING_URL}/${name}/edit`}>
|
||||||
<Trans i18nKey="provisioning.repository-actions.settings">Settings</Trans>
|
<Trans i18nKey="provisioning.repository-actions.settings">Settings</Trans>
|
||||||
</LinkButton>
|
</LinkButton>
|
||||||
<DeleteRepositoryButton name={name} redirectTo={PROVISIONING_URL} />
|
<DeleteRepositoryButton name={name} repository={repository} redirectTo={PROVISIONING_URL} />
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import { StatusBadge } from '../Shared/StatusBadge';
|
|||||||
import { PROVISIONING_URL } from '../constants';
|
import { PROVISIONING_URL } from '../constants';
|
||||||
import { getIsReadOnlyWorkflows } from '../utils/repository';
|
import { getIsReadOnlyWorkflows } from '../utils/repository';
|
||||||
|
|
||||||
import { DeleteRepositoryButton } from './DeleteRepositoryButton';
|
|
||||||
import { SyncRepository } from './SyncRepository';
|
import { SyncRepository } from './SyncRepository';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -109,9 +108,6 @@ export function RepositoryCard({ repository }: Props) {
|
|||||||
</LinkButton>
|
</LinkButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Card.Actions>
|
</Card.Actions>
|
||||||
<Card.SecondaryActions>
|
|
||||||
<DeleteRepositoryButton name={name} />
|
|
||||||
</Card.SecondaryActions>
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11254,11 +11254,15 @@
|
|||||||
},
|
},
|
||||||
"delete-repository-button": {
|
"delete-repository-button": {
|
||||||
"button-delete": "Delete",
|
"button-delete": "Delete",
|
||||||
"confirm-delete-repository": "Are you sure you want to delete the repository config?",
|
"confirm-delete-keep-resources": "Are you sure you want to delete the repository configuration but keep its resources?",
|
||||||
|
"confirm-delete-with-resources": "Are you sure you want to delete the repository configuration and all its resources?",
|
||||||
|
"delete": "Delete",
|
||||||
|
"delete-and-keep-resources": "Delete and keep resources",
|
||||||
|
"delete-and-remove-resources": "Delete and remove resources (default)",
|
||||||
"error-repository-delete": "Failed to delete repository",
|
"error-repository-delete": "Failed to delete repository",
|
||||||
"success-repository-deleted": "Repository settings queued for deletion",
|
"success-repository-deleted": "Repository settings queued for deletion",
|
||||||
"title-delete-repository": "Delete repository config",
|
"title-delete-repository-and-resources": "Delete repository configuration and resources",
|
||||||
"tooltip-delete-this-repository": "Delete this repository"
|
"title-delete-repository-only": "Delete repository configuration only"
|
||||||
},
|
},
|
||||||
"edit-repository-page": {
|
"edit-repository-page": {
|
||||||
"back-to-repositories": "Back to repositories",
|
"back-to-repositories": "Back to repositories",
|
||||||
|
|||||||
Reference in New Issue
Block a user