From 317085836d2b3b58a62e63af3b4657b1095d9b94 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 11:36:42 -0700 Subject: [PATCH] feat: delete unprocessed entity Signed-off-by: Kurt King --- .../src/UnprocessedEntitiesModule.ts | 12 +- .../src/api/index.ts | 10 ++ .../src/components/FailedEntities.tsx | 108 ++++++++++++------ 3 files changed, 92 insertions(+), 38 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index a01f717e12..72713178e8 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -120,6 +120,16 @@ export class UnprocessedEntitiesModule { owner: req.query.owner as string, }), ); - }); + }) + .delete( + '/entities/unprocessed/delete/:entity_id', + async (request, response) => { + await this.database('refresh_state') + .where({ entity_id: request.params.entity_id }) + .delete(); + + response.status(204).send(); + }, + ); } } diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index 92dde93a93..030a4d0293 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -54,6 +54,10 @@ export interface CatalogUnprocessedEntitiesApi { * Returns a list of entities with state 'failed' */ failed(): Promise; + /** + * Deletes an entity from the refresh_state table + */ + delete(entity_id: string): Promise; } /** @@ -83,4 +87,10 @@ export class CatalogUnprocessedEntitiesClient async failed(): Promise { return await this.fetch('entities/unprocessed/failed'); } + + async delete(entity_id: string): Promise { + await this.fetch(`entities/unprocessed/delete/${entity_id}`, { + method: 'DELETE', + }); + } } diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index a1044c6679..4c01b888b2 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -22,15 +22,18 @@ import { Table, TableColumn, } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; + import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; +import IconButton from '@material-ui/core/IconButton'; import { Theme, makeStyles } from '@material-ui/core/styles'; +import { alertApiRef, useApi } from '@backstage/core-plugin-api'; import { UnprocessedEntity } from '../types'; import { EntityDialog } from './EntityDialog'; import { catalogUnprocessedEntitiesApiRef } from '../api'; import useAsync from 'react-use/lib/useAsync'; +import DeleteIcon from '@material-ui/icons/Delete'; const useStyles = makeStyles((theme: Theme) => ({ errorBox: { @@ -94,6 +97,8 @@ export const FailedEntities = () => { value: data, } = useAsync(async () => await unprocessedApi.failed()); const [, setSelectedSearchTerm] = useState(''); + const unprocessedEntityApi = useApi(catalogUnprocessedEntitiesApiRef); + const alertApi = useApi(alertApiRef); if (loading) { return ; @@ -102,6 +107,21 @@ export const FailedEntities = () => { return ; } + const handleDelete = async ({ id }: { id: string }) => { + try { + await unprocessedEntityApi.delete(id); + alertApi.post({ + message: `Entity has been deleted`, + severity: 'success', + }); + } catch (e) { + alertApi.post({ + message: `Ran into an issue when deleting. Please try again later.`, + severity: 'error', + }); + } + }; + const columns: TableColumn[] = [ { title: entityRef, @@ -136,43 +156,57 @@ export const FailedEntities = () => { ), }, + { + title: Actions, + render: (rowData: UnprocessedEntity | {}) => { + return ( + + await handleDelete({ + id: (rowData as UnprocessedEntity).entity_id, + }) + } + > + + + ); + }, + }, ]; + return ( - <> - - No failed entities found - - } - onSearchChange={(searchTerm: string) => - setSelectedSearchTerm(searchTerm) - } - detailPanel={({ rowData }) => { - const errors = (rowData as UnprocessedEntity).errors; - return ( - <> - {errors?.map(e => { - 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} + + + + + ); + })} + + ); + }} + /> ); };