feat: change default icon for unknown entities

Signed-off-by: David Weber <david.weber@w3tec.ch>
This commit is contained in:
David Weber
2023-12-21 13:59:48 +01:00
committed by Fredrik Adelöw
parent ab1682e85d
commit 916da47e8a
11 changed files with 57 additions and 54 deletions
+9
View File
@@ -0,0 +1,9 @@
---
'@backstage/plugin-entity-validation': patch
'@backstage/plugin-catalog-import': patch
'@backstage/plugin-catalog-graph': patch
'@backstage/plugin-catalog-react': patch
'@backstage/plugin-catalog': patch
---
Change default icon for unknown entities to nothing instead of the help icon.
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import { DependencyGraphTypes } from '@backstage/core-components';
import { useApp } from '@backstage/core-plugin-api';
import { humanizeEntityRef } from '@backstage/plugin-catalog-react';
import { makeStyles } from '@material-ui/core/styles';
import classNames from 'classnames';
@@ -63,6 +64,7 @@ export function DefaultRenderNode({
const classes = useStyles();
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const app = useApp();
const idRef = useRef<SVGTextElement | null>(null);
useLayoutEffect(() => {
@@ -85,9 +87,12 @@ export function DefaultRenderNode({
metadata: { name, namespace = DEFAULT_NAMESPACE, title },
} = entity;
const hasKindIcon = app.getSystemIcon(
`kind:${kind.toLocaleLowerCase('en-US')}`,
);
const padding = 10;
const iconSize = height;
const paddedIconWidth = kind ? iconSize + padding : 0;
const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;
const paddedWidth = paddedIconWidth + width + padding * 2;
const paddedHeight = height + padding * 2;
@@ -109,7 +114,7 @@ export function DefaultRenderNode({
height={paddedHeight}
rx={10}
/>
{kind && (
{hasKindIcon && (
<EntityKindIcon
kind={kind}
y={padding}
@@ -14,8 +14,8 @@
* limitations under the License.
*/
import { useApp } from '@backstage/core-plugin-api';
import WorkIcon from '@material-ui/icons/Work';
import React from 'react';
import SvgIcon from '@material-ui/core/SvgIcon';
export function EntityKindIcon({
kind,
@@ -30,6 +30,6 @@ export function EntityKindIcon({
}) {
const app = useApp();
const Icon =
app.getSystemIcon(`kind:${kind.toLocaleLowerCase('en-US')}`) ?? WorkIcon;
app.getSystemIcon(`kind:${kind.toLocaleLowerCase('en-US')}`) ?? SvgIcon;
return <Icon {...props} />;
}
@@ -32,7 +32,6 @@ import {
import { makeStyles } from '@material-ui/core/styles';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import WorkIcon from '@material-ui/icons/Work';
import React, { useState } from 'react';
const useStyles = makeStyles(theme => ({
@@ -127,10 +126,9 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
>
<List component="div" disablePadding dense>
{sortEntities(r.entities).map(entity => {
const Icon =
app.getSystemIcon(
`kind:${entity.kind.toLocaleLowerCase('en-US')}`,
) ?? WorkIcon;
const Icon = app.getSystemIcon(
`kind:${entity.kind.toLocaleLowerCase('en-US')}`,
);
return (
<ListItem
key={humanizeEntityRef(entity)}
@@ -143,9 +141,7 @@ export const EntityListComponent = (props: EntityListComponentProps) => {
}
: {})}
>
<ListItemIcon>
<Icon />
</ListItemIcon>
<ListItemIcon>{Icon && <Icon />}</ListItemIcon>
<ListItemText primary={humanizeEntityRef(entity)} />
</ListItem>
);
@@ -26,7 +26,7 @@ import {
Progress,
ResponseErrorPanel,
} from '@backstage/core-components';
import { useApi, useRouteRef } from '@backstage/core-plugin-api';
import { useApi, useApp, useRouteRef } from '@backstage/core-plugin-api';
import { Box, DialogContentText, makeStyles } from '@material-ui/core';
import classNames from 'classnames';
import React, { useLayoutEffect, useRef, useState } from 'react';
@@ -107,6 +107,7 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {
const entityRoute = useRouteRef(entityRouteRef);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const app = useApp();
const idRef = useRef<SVGTextElement | null>(null);
useLayoutEffect(() => {
@@ -123,9 +124,12 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {
}
}, [width, height]);
const hasKindIcon = app.getSystemIcon(
`kind:${node.kind.toLocaleLowerCase('en-US')}`,
);
const padding = 10;
const iconSize = height;
const paddedIconWidth = iconSize + padding;
const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;
const paddedWidth = paddedIconWidth + width + padding * 2;
const paddedHeight = height + padding * 2;
@@ -160,17 +164,19 @@ function CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {
height={paddedHeight}
rx={10}
/>
<EntityKindIcon
kind={node.kind}
y={padding}
x={padding}
width={iconSize}
height={iconSize}
className={classNames(
classes.text,
node.root ? 'secondary' : 'primary',
)}
/>
{hasKindIcon && (
<EntityKindIcon
kind={node.kind}
y={padding}
x={padding}
width={iconSize}
height={iconSize}
className={classNames(
classes.text,
node.root ? 'secondary' : 'primary',
)}
/>
)}
<text
ref={idRef}
className={classNames(
@@ -26,7 +26,6 @@ import {
DialogContentText,
List,
ListItem,
ListItemIcon,
makeStyles,
} from '@material-ui/core';
import { Alert } from '@material-ui/lab';
@@ -35,7 +34,6 @@ import useAsync from 'react-use/lib/useAsync';
import { catalogApiRef } from '../../../api';
import { EntityRefLink } from '../../EntityRefLink';
import { KeyValueListItem, ListItemText } from './common';
import { EntityKindIcon } from './EntityKindIcon';
const useStyles = makeStyles({
root: {
@@ -90,9 +88,6 @@ function EntityList(props: { entities: Entity[]; header?: [string, string] }) {
{props.header && <KeyValueListItem key="header" entry={props.header} />}
{props.entities.map(entity => (
<ListItem key={stringifyEntityRef(entity)}>
<ListItemIcon>
<EntityKindIcon kind={entity.kind} />
</ListItemIcon>
<ListItemText primary={<EntityRefLink entityRef={entity} />} />
</ListItem>
))}
@@ -16,10 +16,10 @@
import { parseEntityRef } from '@backstage/catalog-model';
import { useApp } from '@backstage/core-plugin-api';
import WorkIcon from '@material-ui/icons/Work';
import React from 'react';
import SvgIcon from '@material-ui/core/SvgIcon';
const DEFAULT_ICON = WorkIcon;
const DEFAULT_ICON = SvgIcon;
function getKind(
kind: string | undefined,
@@ -36,7 +36,6 @@ import {
ListItemText,
ListSubheader,
} from './common';
import { EntityKindIcon } from './EntityKindIcon';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { CopyTextButton } from '@backstage/core-components';
@@ -155,9 +154,6 @@ export function OverviewPage(props: { entity: AlphaEntity }) {
<List dense subheader={<ListSubheader>{type}</ListSubheader>}>
{groupRelations.map(group => (
<ListItem key={group.targetRef}>
<ListItemIcon>
<EntityKindIcon entityRef={group.targetRef} />
</ListItemIcon>
<ListItemText
primary={
<EntityRefLink entityRef={group.targetRef} />
@@ -34,7 +34,6 @@ import {
DEFAULT_BATCH_DELAY,
DEFAULT_CACHE_TTL,
DEFAULT_ICONS,
UNKNOWN_KIND_ICON,
createDefaultRenderer,
} from './defaults';
@@ -395,8 +394,6 @@ export class DefaultEntityPresentationApi implements EntityPresentationApi {
return false;
}
return (
this.#kindIcons[kind.toLocaleLowerCase('en-US')] ?? UNKNOWN_KIND_ICON
);
return this.#kindIcons[kind.toLocaleLowerCase('en-US')];
}
}
@@ -20,7 +20,6 @@ import { HumanDuration } from '@backstage/types';
import ApartmentIcon from '@material-ui/icons/Apartment';
import CategoryIcon from '@material-ui/icons/Category';
import ExtensionIcon from '@material-ui/icons/Extension';
import HelpIcon from '@material-ui/icons/Help';
import FeaturedPlayListIcon from '@material-ui/icons/FeaturedPlayList';
import LocationOnIcon from '@material-ui/icons/LocationOn';
import MemoryIcon from '@material-ui/icons/Memory';
@@ -33,8 +32,6 @@ export const DEFAULT_CACHE_TTL: HumanDuration = { seconds: 10 };
export const DEFAULT_BATCH_DELAY: HumanDuration = { milliseconds: 50 };
export const UNKNOWN_KIND_ICON: IconComponent = HelpIcon;
export const DEFAULT_ICONS: Record<string, IconComponent> = {
api: ExtensionIcon,
component: MemoryIcon,
@@ -27,11 +27,11 @@ import {
Paper,
} from '@material-ui/core';
import { humanizeEntityRef } from '@backstage/plugin-catalog-react';
import WorkIcon from '@material-ui/icons/Work';
import ExpandLessIcon from '@material-ui/icons/ExpandLess';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { MarkdownContent } from '@backstage/core-components';
import { ValidationOutputOk } from '../../types';
import SvgIcon from '@material-ui/core/SvgIcon';
const useStyles = makeStyles(theme => ({
validationOk: {
@@ -60,9 +60,9 @@ export const EntityResult = ({
const app = useApp();
const [expanded, setExpanded] = useState(isFirstError);
const Icon =
app.getSystemIcon(`kind:${item.entity.kind.toLocaleLowerCase('en-US')}`) ??
WorkIcon;
const Icon = app.getSystemIcon(
`kind:${item.entity.kind.toLocaleLowerCase('en-US')}`,
) as typeof SvgIcon;
const fetchErrorMessages = (response: ValidateEntityResponse) => {
if (!response.valid) {
@@ -75,13 +75,15 @@ export const EntityResult = ({
<>
<ListItem key={humanizeEntityRef(item.entity)}>
<ListItemIcon>
<Icon
className={
item.response.valid
? classes.validationOk
: classes.validationNotOk
}
/>
{Icon && (
<Icon
className={
item.response.valid
? classes.validationOk
: classes.validationNotOk
}
/>
)}
</ListItemIcon>
<ListItemText
primary={humanizeEntityRef(item.entity)}