make context menu items first class
Signed-off-by: Mark Dunphy <markd@spotify.com>
This commit is contained in:
@@ -17,10 +17,8 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
createExtensionBlueprint,
|
||||
ApiHolder,
|
||||
createExtensionDataRef,
|
||||
dialogApiRef,
|
||||
useApiHolder,
|
||||
ExtensionBoundary,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
@@ -69,11 +67,11 @@ export const EntityContextMenuItemBlueprint = createExtensionBlueprint({
|
||||
kind: 'entity-context-menu-item',
|
||||
attachTo: { id: 'page:catalog/entity', input: 'contextMenuItems' },
|
||||
output: [contextMenuItemComponentDataRef],
|
||||
*factory(params: EntityContextMenuItemParams, { apis }) {
|
||||
const loaderFactory = (): ContextMenuItemComponent => {
|
||||
*factory(params: EntityContextMenuItemParams, { node }) {
|
||||
const loader = async (): Promise<ContextMenuItemComponent> => {
|
||||
if ('useOnClick' in params) {
|
||||
return ({ onClose }) => {
|
||||
const onClick = params.useOnClick({ apis });
|
||||
const onClick = params.useOnClick();
|
||||
const title = params.useTitle();
|
||||
|
||||
return (
|
||||
@@ -105,6 +103,8 @@ export const EntityContextMenuItemBlueprint = createExtensionBlueprint({
|
||||
};
|
||||
};
|
||||
|
||||
yield contextMenuItemComponentDataRef(loaderFactory());
|
||||
yield contextMenuItemComponentDataRef(
|
||||
ExtensionBoundary.lazyComponent(node, loader),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ export function EntityHeader(props: {
|
||||
UNSTABLE_contextMenuOptions?: {
|
||||
disableUnregister: boolean | 'visible' | 'hidden' | 'disable';
|
||||
};
|
||||
extraMenuItems?: ContextMenuItemComponent[];
|
||||
contextMenuItems?: ContextMenuItemComponent[];
|
||||
/**
|
||||
* An array of relation types used to determine the parent entities in the hierarchy.
|
||||
* These relations are prioritized in the order provided, allowing for flexible
|
||||
@@ -197,7 +197,7 @@ export function EntityHeader(props: {
|
||||
const {
|
||||
UNSTABLE_extraContextMenuItems,
|
||||
UNSTABLE_contextMenuOptions,
|
||||
extraMenuItems,
|
||||
contextMenuItems,
|
||||
parentEntityRelations,
|
||||
title,
|
||||
subtitle,
|
||||
@@ -284,7 +284,7 @@ export function EntityHeader(props: {
|
||||
<EntityContextMenu
|
||||
UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}
|
||||
UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}
|
||||
extraMenuItems={extraMenuItems}
|
||||
contextMenuItems={contextMenuItems}
|
||||
onInspectEntity={openInspectEntityDialog}
|
||||
onUnregisterEntity={openUnregisterEntityDialog}
|
||||
/>
|
||||
|
||||
@@ -62,7 +62,7 @@ export interface EntityLayoutProps {
|
||||
UNSTABLE_extraContextMenuItems?: ComponentProps<
|
||||
typeof EntityHeader
|
||||
>['UNSTABLE_extraContextMenuItems'];
|
||||
extraMenuItems?: ComponentProps<typeof EntityHeader>['extraMenuItems'];
|
||||
contextMenuItems?: ComponentProps<typeof EntityHeader>['contextMenuItems'];
|
||||
children?: ReactNode;
|
||||
header?: JSX.Element;
|
||||
NotFoundComponent?: ReactNode;
|
||||
@@ -100,7 +100,7 @@ export const EntityLayout = (props: EntityLayoutProps) => {
|
||||
const {
|
||||
UNSTABLE_extraContextMenuItems,
|
||||
UNSTABLE_contextMenuOptions,
|
||||
extraMenuItems,
|
||||
contextMenuItems,
|
||||
children,
|
||||
header,
|
||||
NotFoundComponent,
|
||||
@@ -147,7 +147,7 @@ export const EntityLayout = (props: EntityLayoutProps) => {
|
||||
parentEntityRelations={parentEntityRelations}
|
||||
UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}
|
||||
UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}
|
||||
extraMenuItems={extraMenuItems}
|
||||
contextMenuItems={contextMenuItems}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ export const catalogEntityPage = PageBlueprint.makeWithOverrides({
|
||||
|
||||
const header = inputs.header?.get(
|
||||
EntityHeaderBlueprint.dataRefs.element,
|
||||
) ?? <EntityHeader extraMenuItems={menuItems} />;
|
||||
) ?? <EntityHeader contextMenuItems={menuItems} />;
|
||||
|
||||
let groups = Object.entries(defaultEntityContentGroups).reduce<Groups>(
|
||||
(rest, group) => {
|
||||
@@ -140,7 +140,7 @@ export const catalogEntityPage = PageBlueprint.makeWithOverrides({
|
||||
const Component = () => {
|
||||
return (
|
||||
<AsyncEntityProvider {...useEntityFromUrl()}>
|
||||
<EntityLayout header={header} extraMenuItems={menuItems}>
|
||||
<EntityLayout header={header} contextMenuItems={menuItems}>
|
||||
{Object.values(groups).flatMap(({ title, items }) =>
|
||||
items.map(output => (
|
||||
<EntityLayout.Route
|
||||
|
||||
@@ -62,7 +62,7 @@ interface ExtraContextMenuItem {
|
||||
interface EntityContextMenuProps {
|
||||
UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];
|
||||
UNSTABLE_contextMenuOptions?: UnregisterEntityOptions;
|
||||
extraMenuItems?: ContextMenuItemComponent[];
|
||||
contextMenuItems?: ContextMenuItemComponent[];
|
||||
onUnregisterEntity: () => void;
|
||||
onInspectEntity: () => void;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) {
|
||||
const {
|
||||
UNSTABLE_extraContextMenuItems,
|
||||
UNSTABLE_contextMenuOptions,
|
||||
extraMenuItems,
|
||||
contextMenuItems,
|
||||
onUnregisterEntity,
|
||||
onInspectEntity,
|
||||
} = props;
|
||||
@@ -148,37 +148,46 @@ export function EntityContextMenu(props: EntityContextMenuProps) {
|
||||
>
|
||||
<MenuList autoFocusItem={Boolean(anchorEl)}>
|
||||
{extraItems}
|
||||
{extraMenuItems?.map(ExtraMenuItem => (
|
||||
<ExtraMenuItem onClose={onClose} />
|
||||
))}
|
||||
<UnregisterEntity
|
||||
unregisterEntityOptions={UNSTABLE_contextMenuOptions}
|
||||
isUnregisterAllowed={isAllowed}
|
||||
onUnregisterEntity={onUnregisterEntity}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onInspectEntity();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<BugReportIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t('entityContextMenu.inspectMenuTitle')} />
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onClose();
|
||||
copyToClipboard(window.location.toString());
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<FileCopyTwoToneIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t('entityContextMenu.copyURLMenuTitle')} />
|
||||
</MenuItem>
|
||||
{contextMenuItems === undefined ? (
|
||||
<>
|
||||
<UnregisterEntity
|
||||
unregisterEntityOptions={UNSTABLE_contextMenuOptions}
|
||||
isUnregisterAllowed={isAllowed}
|
||||
onUnregisterEntity={onUnregisterEntity}
|
||||
onClose={onClose}
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onClose();
|
||||
onInspectEntity();
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<BugReportIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t('entityContextMenu.inspectMenuTitle')}
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
onClose();
|
||||
copyToClipboard(window.location.toString());
|
||||
}}
|
||||
>
|
||||
<ListItemIcon>
|
||||
<FileCopyTwoToneIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={t('entityContextMenu.copyURLMenuTitle')}
|
||||
/>
|
||||
</MenuItem>
|
||||
</>
|
||||
) : (
|
||||
contextMenuItems.map(ExtraMenuItem => (
|
||||
<ExtraMenuItem onClose={onClose} />
|
||||
))
|
||||
)}
|
||||
</MenuList>
|
||||
</Popover>
|
||||
</>
|
||||
|
||||
@@ -246,7 +246,6 @@ export const EntityLayout = (props: EntityLayoutProps) => {
|
||||
const {
|
||||
UNSTABLE_extraContextMenuItems,
|
||||
UNSTABLE_contextMenuOptions,
|
||||
extraMenuItems,
|
||||
children,
|
||||
NotFoundComponent,
|
||||
parentEntityRelations,
|
||||
@@ -362,7 +361,6 @@ export const EntityLayout = (props: EntityLayoutProps) => {
|
||||
<EntityContextMenu
|
||||
UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}
|
||||
UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}
|
||||
extraMenuItems={extraMenuItems}
|
||||
onUnregisterEntity={() => setConfirmationDialogOpen(true)}
|
||||
onInspectEntity={() => setSearchParams('inspect')}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user