From ba88bfa464ed664898c2eafc6ca4033fcaa519a1 Mon Sep 17 00:00:00 2001 From: deepthi-28 Date: Mon, 17 Mar 2025 15:55:21 +0530 Subject: [PATCH] Delete pop up button is added for dev tools Signed-off-by: deepthi-28 --- .changeset/deep-flies-vanish.md | 5 + .../src/components/DeleteEntityDialog.tsx | 64 +++++++++++++ .../src/components/FailedEntities.tsx | 96 +++++++++++-------- 3 files changed, 127 insertions(+), 38 deletions(-) create mode 100644 .changeset/deep-flies-vanish.md create mode 100644 plugins/catalog-unprocessed-entities/src/components/DeleteEntityDialog.tsx diff --git a/.changeset/deep-flies-vanish.md b/.changeset/deep-flies-vanish.md new file mode 100644 index 0000000000..8ae47e9b81 --- /dev/null +++ b/.changeset/deep-flies-vanish.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +Added confirmation popup for delete entities in devtools diff --git a/plugins/catalog-unprocessed-entities/src/components/DeleteEntityDialog.tsx b/plugins/catalog-unprocessed-entities/src/components/DeleteEntityDialog.tsx new file mode 100644 index 0000000000..a1843b43b6 --- /dev/null +++ b/plugins/catalog-unprocessed-entities/src/components/DeleteEntityDialog.tsx @@ -0,0 +1,64 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import React, { useState } from 'react'; +import { assertError } from '@backstage/errors'; + +interface DeleteEntityDialogProps { + open: boolean; + onClose: () => any; + onConfirm: () => any; +} + +export function DeleteEntityDialog(props: DeleteEntityDialogProps) { + const { open, onClose, onConfirm } = props; + const [busy, setBusy] = useState(false); + const onDelete = async () => { + setBusy(true); + try { + onConfirm(); + } catch (err) { + assertError(err); + } finally { + setBusy(false); + } + }; + + return ( + + + Are you sure you want to delete this entity? + + + + + + + ); +} diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index 65e6eb731e..26d3fd8b5b 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -34,6 +34,7 @@ import { EntityDialog } from './EntityDialog'; import { catalogUnprocessedEntitiesApiRef } from '../api'; import useAsync from 'react-use/esm/useAsync'; import DeleteIcon from '@material-ui/icons/Delete'; +import { DeleteEntityDialog } from './DeleteEntityDialog'; const useStyles = makeStyles((theme: Theme) => ({ errorBox: { @@ -117,6 +118,9 @@ export const FailedEntities = () => { const [, setSelectedSearchTerm] = useState(''); const unprocessedEntityApi = useApi(catalogUnprocessedEntitiesApiRef); const alertApi = useApi(alertApiRef); + const [entityID, setEntityID] = useState(''); + const [entityRefVal, setEntityRefVal] = useState(''); + const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false); if (loading) { return ; @@ -125,25 +129,32 @@ export const FailedEntities = () => { return ; } - const handleDelete = async ({ + const handleDelete = ({ entityId, entityRef, }: { entityId: string; entityRef: string; }) => { + setEntityID(entityId); + setEntityRefVal(entityRef); + setConfirmationDialogOpen(true); + }; + + const cleanUpAfterRemoval = async () => { try { - await unprocessedEntityApi.delete(entityId); + await unprocessedEntityApi.delete(entityID); alertApi.post({ - message: `Entity ${entityRef} has been deleted`, + message: `Entity ${entityRefVal} has been deleted`, severity: 'success', }); } catch (e) { alertApi.post({ - message: `Ran into an issue when deleting ${entityRef}. Please try again later.`, + message: `Ran into an issue when deleting ${entityRefVal}. Please try again later.`, severity: 'error', }); } + setConfirmationDialogOpen(false); }; const columns: TableColumn[] = [ @@ -213,8 +224,8 @@ export const FailedEntities = () => { return ( - await handleDelete({ + onClick={() => + handleDelete({ entityId: entity_id, entityRef: entity_ref, }) @@ -228,37 +239,46 @@ export const FailedEntities = () => { ]; return ( - - No failed entities found - - } - onSearchChange={(searchTerm: string) => setSelectedSearchTerm(searchTerm)} - detailPanel={({ rowData }) => { - const errors = (rowData as UnprocessedEntity).errors; - return ( - <> - {errors?.map((e, idx) => { - return ( - - - {e.name} - - - - - ); - })} - - ); - }} - /> + <> +
+ No failed entities found + + } + onSearchChange={(searchTerm: string) => + setSelectedSearchTerm(searchTerm) + } + detailPanel={({ rowData }) => { + const errors = (rowData as UnprocessedEntity).errors; + return ( + <> + {errors?.map((e, idx) => { + return ( + + + {e.name} + + + + + ); + })} + + ); + }} + /> + setConfirmationDialogOpen(false)} + onConfirm={cleanUpAfterRemoval} + /> + ); };