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 (
+
+ );
+}
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}
+ />
+ >
);
};