From cce3770453dfa961966b53b0bc5f918d2585a7de Mon Sep 17 00:00:00 2001 From: Mark Dunphy Date: Fri, 21 Mar 2025 16:34:57 -0400 Subject: [PATCH] add useIsDisabled hook Signed-off-by: Mark Dunphy --- .../EntityContextMenuItemBlueprint.tsx | 8 ++- .../catalog/src/alpha/contextMenuItems.tsx | 53 ++++++++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityContextMenuItemBlueprint.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityContextMenuItemBlueprint.tsx index b5c9896696..fc8dcb0330 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityContextMenuItemBlueprint.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityContextMenuItemBlueprint.tsx @@ -30,11 +30,13 @@ export type FactoryHrefParams = useTitle: () => string; icon: React.JSX.Element; useHref: () => string; + useIsDisabled?: () => boolean; } | { useTitle: () => string; icon: React.JSX.Element; href: string; + useIsDisabled?: () => boolean; }; /** @alpha */ @@ -42,6 +44,7 @@ export type FactoryDialogParams = { useOnClick: () => React.MouseEventHandler; useTitle: () => string; icon: React.JSX.Element; + useIsDisabled?: () => boolean; }; /** @alpha */ @@ -73,9 +76,11 @@ export const EntityContextMenuItemBlueprint = createExtensionBlueprint({ return ({ onClose }) => { const onClick = params.useOnClick(); const title = params.useTitle(); + const disabled = params.useIsDisabled?.() ?? false; return ( { onClose(); onClick(e); @@ -93,9 +98,10 @@ export const EntityContextMenuItemBlueprint = createExtensionBlueprint({ return () => { const href = useHref(); const title = params.useTitle(); + const disabled = params.useIsDisabled?.() ?? false; return ( - + {params.icon} diff --git a/plugins/catalog/src/alpha/contextMenuItems.tsx b/plugins/catalog/src/alpha/contextMenuItems.tsx index f17e58c286..a5148dbfc6 100644 --- a/plugins/catalog/src/alpha/contextMenuItems.tsx +++ b/plugins/catalog/src/alpha/contextMenuItems.tsx @@ -15,15 +15,28 @@ */ import React from 'react'; -import { EntityContextMenuItemBlueprint } from '@backstage/plugin-catalog-react/alpha'; +import { + EntityContextMenuItemBlueprint, + useEntityPermission, +} from '@backstage/plugin-catalog-react/alpha'; import FileCopyTwoToneIcon from '@material-ui/icons/FileCopyTwoTone'; import BugReportIcon from '@material-ui/icons/BugReport'; import CancelIcon from '@material-ui/icons/Cancel'; import useCopyToClipboard from 'react-use/esm/useCopyToClipboard'; -import { alertApiRef, useApi } from '@backstage/core-plugin-api'; -import { useTranslationRef } from '@backstage/frontend-plugin-api'; +import { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; +import { + dialogApiRef, + useTranslationRef, + type DialogApiDialog, +} from '@backstage/frontend-plugin-api'; import { catalogTranslationRef } from './translation'; -import { useSearchParams } from 'react-router-dom'; +import { useNavigate, useSearchParams } from 'react-router-dom'; +import { + UnregisterEntityDialog, + useEntity, +} from '@backstage/plugin-catalog-react'; +import { rootRouteRef, unregisterRedirectRouteRef } from '../routes'; +import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common/alpha'; export const copyEntityUrlContextMenuItem = EntityContextMenuItemBlueprint.make( { @@ -86,10 +99,36 @@ export const unregisterEntityContextMenuItem = const { t } = useTranslationRef(catalogTranslationRef); return t('entityContextMenu.unregisterMenuTitle'); }, + useIsDisabled: () => { + const unregisterPermission = useEntityPermission( + catalogEntityDeletePermission, + ); + + return !unregisterPermission.allowed; + }, useOnClick: () => { - return () => { - // eslint-disable-next-line no-alert - window.alert('unregister clicked'); + const { entity } = useEntity(); + const dialogApi = useApi(dialogApiRef); + const navigate = useNavigate(); + const catalogRoute = useRouteRef(rootRouteRef); + const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef); + + return async () => { + dialogApi.showModal(({ dialog }: { dialog: DialogApiDialog }) => ( + dialog.close()} + onConfirm={() => { + dialog.close(); + navigate( + unregisterRedirectRoute + ? unregisterRedirectRoute() + : catalogRoute(), + ); + }} + /> + )); }; }, },