@techdocs/cli 1.10.6-next.0 → 1.10.6-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/embedded-app/.config-schema.json +46 -114
- package/dist/embedded-app/index.html +1 -1
- package/dist/embedded-app/index.html.tmpl +1 -1
- package/dist/embedded-app/static/{123.236c77e6.chunk.js → 123.c7a9a606.chunk.js} +1 -1
- package/dist/embedded-app/static/{1659.0a0397a7.chunk.js → 1659.e675bf84.chunk.js} +1 -1
- package/dist/embedded-app/static/{4445.f328dda2.chunk.js → 4445.b9a2649d.chunk.js} +2 -2
- package/dist/embedded-app/static/{4445.f328dda2.chunk.js.map → 4445.b9a2649d.chunk.js.map} +1 -1
- package/dist/embedded-app/static/{4587.bb59a5f0.chunk.js → 4587.d2528dda.chunk.js} +1 -1
- package/dist/embedded-app/static/main.654208fc.js +523 -0
- package/dist/embedded-app/static/main.654208fc.js.map +1 -0
- package/dist/embedded-app/static/main.f25a5e82.css +2 -0
- package/dist/embedded-app/static/main.f25a5e82.css.map +1 -0
- package/dist/embedded-app/static/{runtime.6118bf91.js → runtime.49204185.js} +2 -2
- package/dist/embedded-app/static/{runtime.6118bf91.js.map → runtime.49204185.js.map} +1 -1
- package/dist/embedded-app/static/{vendor.b660c175.js → vendor.3550487b.js} +2 -2
- package/dist/embedded-app/static/vendor.3550487b.js.map +1 -0
- package/dist/package.json.cjs.js +1 -1
- package/package.json +5 -5
- package/dist/embedded-app/static/main.55438749.js +0 -523
- package/dist/embedded-app/static/main.55438749.js.map +0 -1
- package/dist/embedded-app/static/main.c62196a4.css +0 -2
- package/dist/embedded-app/static/main.c62196a4.css.map +0 -1
- package/dist/embedded-app/static/vendor.b660c175.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static/4445.f328dda2.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../core-components/src/components/FavoriteToggle/FavoriteToggle.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityRefLink/humanize.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/types.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useStarredEntity.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DefaultNode.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/Node.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/constants.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DefaultLabel.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/Edge.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DependencyGraph.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityLabels/EntityLabels.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/context/EntityContextMenuContext.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityHeader/EntityHeader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsPanel.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsGroup.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ComponentProps } from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { StarIcon, UnstarredIcon } from '../../icons';\n\nconst useStyles = makeStyles<Theme>(\n () => ({\n icon: {\n color: '#f3ba37',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n iconBorder: {\n color: 'inherit',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n }),\n { name: 'BackstageFavoriteToggleIcon' },\n);\n\n/**\n * @public\n */\nexport type FavoriteToggleIconClassKey = 'icon' | 'iconBorder';\n\n/**\n * Icon used in FavoriteToggle component.\n *\n * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable}\n *\n * @public\n */\nexport function FavoriteToggleIcon(props: { isFavorite: boolean }) {\n const { isFavorite } = props;\n const classes = useStyles();\n\n return (\n <Typography\n component=\"span\"\n className={isFavorite ? classes.icon : classes.iconBorder}\n >\n {isFavorite ? <StarIcon /> : <UnstarredIcon />}\n </Typography>\n );\n}\n\n/**\n * Props for the {@link FavoriteToggle} component.\n *\n * @public\n */\nexport type FavoriteToggleProps = ComponentProps<typeof IconButton> & {\n id: string;\n title: string;\n isFavorite: boolean;\n onToggle: (value: boolean) => void;\n};\n\n/**\n * Toggle encapsulating logic for marking something as favorite,\n * primarily used in various instances of entity lists and cards but can be used elsewhere.\n *\n * This component can only be used in as a controlled toggle and does not keep internal state.\n *\n * @public\n */\nexport function FavoriteToggle(props: FavoriteToggleProps) {\n const {\n id,\n title,\n isFavorite: value,\n onToggle: onChange,\n ...iconButtonProps\n } = props;\n return (\n <Tooltip id={id} title={title}>\n <IconButton\n aria-label={title}\n id={id}\n onClick={() => onChange(!value)}\n color=\"inherit\"\n {...iconButtonProps}\n >\n <FavoriteToggleIcon isFavorite={value} />\n </IconButton>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\nimport get from 'lodash/get';\n\n/**\n * @param defaultNamespace - if set to false then namespace is never omitted,\n * if set to string which matches namespace of entity then omitted\n *\n * @public\n **/\nexport function humanizeEntityRef(\n entityRef: Entity | CompoundEntityRef,\n opts?: {\n defaultKind?: string;\n defaultNamespace?: string | false;\n },\n) {\n const defaultKind = opts?.defaultKind;\n let kind;\n let namespace;\n let name;\n\n if ('metadata' in entityRef) {\n kind = entityRef.kind;\n namespace = entityRef.metadata.namespace;\n name = entityRef.metadata.name;\n } else {\n kind = entityRef.kind;\n namespace = entityRef.namespace;\n name = entityRef.name;\n }\n\n if (namespace === undefined || namespace === '') {\n namespace = DEFAULT_NAMESPACE;\n }\n if (opts?.defaultNamespace !== undefined) {\n if (opts?.defaultNamespace === namespace) {\n namespace = undefined;\n }\n } else if (namespace === DEFAULT_NAMESPACE) {\n namespace = undefined;\n }\n\n kind = kind.toLocaleLowerCase('en-US');\n kind =\n defaultKind && defaultKind.toLocaleLowerCase('en-US') === kind\n ? undefined\n : kind;\n return `${kind ? `${kind}:` : ''}${namespace ? `${namespace}/` : ''}${name}`;\n}\n\n/**\n * Convert an entity to its more readable name if available.\n *\n * If an entity is either User or Group, this will be its `spec.profile.displayName`.\n * Otherwise, this is `metadata.title`.\n *\n * If neither of those are found or populated, fallback to `defaultName`.\n *\n * @param entity - Entity to convert.\n * @param defaultName - If entity readable name is not available, `defaultName` will be returned.\n * @returns Readable name, defaults to `defaultName`.\n *\n */\nexport function humanizeEntity(entity: Entity, defaultName: string) {\n for (const path of ['spec.profile.displayName', 'metadata.title']) {\n const value = get(entity, path);\n if (value && typeof value === 'string') {\n return value;\n }\n }\n return defaultName;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* We want to maintain the same information as an enum, so we disable the redeclaration warning */\n/* eslint-disable @typescript-eslint/no-redeclare */\n\n/**\n * Types used to customize and provide data to {@link DependencyGraph}\n *\n * @packageDocumentation\n */\n\nimport { ReactNode } from 'react';\n\n/**\n * Types for the {@link DependencyGraph} component.\n *\n * @public\n */\nexport namespace DependencyGraphTypes {\n /**\n * Edge of {@link DependencyGraph}\n *\n * @public\n */\n export type DependencyEdge<T = {}> = T & {\n /**\n * ID of {@link DependencyNode} from where the Edge start\n */\n from: string;\n /**\n * ID of {@link DependencyNode} to where the Edge goes to\n */\n to: string;\n /**\n * Label assigned and rendered with the Edge\n */\n label?: string;\n /**\n * Distance to a root entity\n */\n distance?: number;\n };\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderLabelFunction} for {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderLabelProps<T = unknown> = { edge: DependencyEdge<T> };\n\n /**\n * Custom React component for edge labels\n *\n * @public\n */\n export type RenderLabelFunction<T = {}> = (\n props: RenderLabelProps<T>,\n ) => ReactNode;\n\n /**\n * Node of {@link DependencyGraph}\n *\n * @public\n */\n export type DependencyNode<T = {}> = T & {\n id: string;\n };\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderNodeFunction} for {@link DependencyGraphTypes.DependencyNode}\n *\n * @public\n */\n export type RenderNodeProps<T = unknown> = { node: DependencyNode<T> };\n\n /**\n * Custom React component for graph {@link DependencyGraphTypes.DependencyNode}\n *\n * @public\n */\n export type RenderNodeFunction<T = {}> = (\n props: RenderNodeProps<T>,\n ) => ReactNode;\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderEdgeFunction} for {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderEdgeProps<T = {}> = {\n edge: T & {\n points: { x: number; y: number }[];\n label?: string;\n labeloffset?: number;\n labelpos?: string;\n width?: number;\n height?: number;\n weight?: number;\n minlen?: number;\n showArrowHeads?: boolean;\n from?: string;\n to?: string;\n relations?: string[];\n };\n id: {\n v: string;\n w: string;\n name?: string | undefined;\n };\n };\n\n /**\n * Custom React component for graph {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderEdgeFunction<T = {}> = (\n props: RenderEdgeProps<T>,\n ) => ReactNode;\n\n /**\n * Graph direction\n *\n * @public\n */\n export const Direction = {\n /**\n * Top to Bottom\n */\n TOP_BOTTOM: 'TB',\n /**\n * Bottom to Top\n */\n BOTTOM_TOP: 'BT',\n /**\n * Left to Right\n */\n LEFT_RIGHT: 'LR',\n /**\n * Right to Left\n */\n RIGHT_LEFT: 'RL',\n } as const;\n\n /**\n * @public\n */\n export type Direction = (typeof Direction)[keyof typeof Direction];\n\n /**\n * @public\n */\n export namespace Direction {\n export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM;\n export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP;\n export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT;\n export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT;\n }\n\n /**\n * Node alignment\n *\n * @public\n */\n export const Alignment = {\n /**\n * Up Left\n */\n UP_LEFT: 'UL',\n /**\n * Up Right\n */\n UP_RIGHT: 'UR',\n /**\n * Down Left\n */\n DOWN_LEFT: 'DL',\n /**\n * Down Right\n */\n DOWN_RIGHT: 'DR',\n } as const;\n\n /**\n * @public\n */\n export type Alignment = (typeof Alignment)[keyof typeof Alignment];\n\n /**\n * @public\n */\n export namespace Alignment {\n export type UP_LEFT = typeof Alignment.UP_LEFT;\n export type UP_RIGHT = typeof Alignment.UP_RIGHT;\n export type DOWN_LEFT = typeof Alignment.DOWN_LEFT;\n export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT;\n }\n\n /**\n * Algorithm used to rand nodes in graph\n *\n * @public\n */\n export const Ranker = {\n /**\n * {@link https://en.wikipedia.org/wiki/Network_simplex_algorithm | Network Simplex} algorithm\n */\n NETWORK_SIMPLEX: 'network-simplex',\n /**\n * Tight Tree algorithm\n */\n TIGHT_TREE: 'tight-tree',\n /**\n * Longest path algorithm\n *\n * @remarks\n *\n * Simplest and fastest\n */\n LONGEST_PATH: 'longest-path',\n } as const;\n\n /**\n * @public\n */\n export type Ranker = (typeof Ranker)[keyof typeof Ranker];\n\n /**\n * @public\n */\n export namespace Ranker {\n export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX;\n export type TIGHT_TREE = typeof Ranker.TIGHT_TREE;\n export type LONGEST_PATH = typeof Ranker.LONGEST_PATH;\n }\n\n /**\n * Position of label in relation to the edge\n *\n * @public\n */\n export const LabelPosition = {\n LEFT: 'l',\n RIGHT: 'r',\n CENTER: 'c',\n } as const;\n\n /**\n * @public\n */\n export type LabelPosition =\n (typeof LabelPosition)[keyof typeof LabelPosition];\n\n /**\n * @public\n */\n export namespace LabelPosition {\n export type LEFT = typeof LabelPosition.LEFT;\n export type RIGHT = typeof LabelPosition.RIGHT;\n export type CENTER = typeof LabelPosition.CENTER;\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useEffect, useState } from 'react';\nimport { starredEntitiesApiRef } from '../apis';\n\nfunction getEntityRef(\n entityOrRef: Entity | CompoundEntityRef | string,\n): string {\n return typeof entityOrRef === 'string'\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n}\n\n/** @public */\nexport function useStarredEntity(\n entityOrRef: Entity | CompoundEntityRef | string,\n): {\n toggleStarredEntity: () => void;\n isStarredEntity: boolean;\n} {\n const starredEntitiesApi = useApi(starredEntitiesApiRef);\n\n const [isStarredEntity, setIsStarredEntity] = useState(false);\n\n useEffect(() => {\n const subscription = starredEntitiesApi.starredEntitie$().subscribe({\n next(starredEntities: Set<string>) {\n setIsStarredEntity(starredEntities.has(getEntityRef(entityOrRef)));\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [entityOrRef, starredEntitiesApi]);\n\n const toggleStarredEntity = useCallback(\n () => starredEntitiesApi.toggleStarred(getEntityRef(entityOrRef)).then(),\n [entityOrRef, starredEntitiesApi],\n );\n\n return {\n toggleStarredEntity,\n isStarredEntity,\n };\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport IconButton from '@material-ui/core/IconButton';\nimport { ComponentProps } from 'react';\nimport { useStarredEntity } from '../../hooks/useStarredEntity';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { FavoriteToggle } from '@backstage/core-components';\n\n/** @public */\nexport type FavoriteEntityProps = ComponentProps<typeof IconButton> & {\n entity: Entity;\n};\n\n/**\n * IconButton for showing if a current entity is starred and adding/removing it from the favorite entities\n * @param props - MaterialUI IconButton props extended by required `entity` prop\n * @public\n */\nexport const FavoriteEntity = (props: FavoriteEntityProps) => {\n const { toggleStarredEntity, isStarredEntity } = useStarredEntity(\n props.entity,\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n const title = isStarredEntity\n ? t('favoriteEntity.removeFromFavorites')\n : t('favoriteEntity.addToFavorites');\n\n const id = `favorite-${stringifyEntityRef(props.entity).replace(\n /[^a-zA-Z0-9-_]/g,\n '-',\n )}`;\n\n return (\n <FavoriteToggle\n title={title}\n id={id}\n isFavorite={isStarredEntity}\n onToggle={toggleStarredEntity}\n {...props}\n />\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useRef, useLayoutEffect } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { DependencyGraphTypes as Types } from './types';\n\n/** @public */\nexport type DependencyGraphDefaultNodeClassKey = 'node' | 'text';\n\nconst useStyles = makeStyles(\n theme => ({\n node: {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n text: {\n fill: theme.palette.primary.contrastText,\n },\n }),\n { name: 'BackstageDependencyGraphDefaultNode' },\n);\n\n/** @public */\nexport function DefaultNode({ node: { id } }: Types.RenderNodeProps) {\n const classes = useStyles();\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const padding = 10;\n const paddedWidth = width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n return (\n <g>\n <rect\n className={classes.node}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n <text\n ref={idRef}\n className={classes.text}\n y={paddedHeight / 2}\n x={paddedWidth / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {id}\n </text>\n </g>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useLayoutEffect } from 'react';\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DefaultNode } from './DefaultNode';\nimport { DependencyGraphTypes as Types } from './types';\nimport { NODE_TEST_ID } from './constants';\nimport dagre from '@dagrejs/dagre';\n\n/** @public */\nexport type DependencyGraphNodeClassKey = 'node';\n\nconst useStyles = makeStyles(\n theme => ({\n node: {\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n }),\n { name: 'BackstageDependencyGraphNode' },\n);\n\nexport type GraphNode<T> = dagre.Node<Types.DependencyNode<T>>;\n\nexport type NodeComponentProps<T> = {\n node: GraphNode<T>;\n render?: Types.RenderNodeFunction<T>;\n setNode: dagre.graphlib.Graph['setNode'];\n};\n\nconst renderDefault = (props: Types.RenderNodeProps) => (\n <DefaultNode {...props} />\n);\n\nexport function Node<T>({\n render = renderDefault,\n setNode,\n node,\n}: NodeComponentProps<T>) {\n const { width, height, x = 0, y = 0 } = node;\n const nodeProps: Types.DependencyNode<T> = node;\n const classes = useStyles();\n const nodeRef = useRef<SVGGElement | null>(null);\n\n useLayoutEffect(() => {\n // set the node width to the actual rendered width to properly layout graph\n if (nodeRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n nodeRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setNode(node.id, {\n ...node,\n height: renderedHeight,\n width: renderedWidth,\n });\n }\n }\n }, [node, width, height, setNode]);\n\n return (\n <g\n ref={nodeRef}\n data-testid={NODE_TEST_ID}\n className={classes.node}\n transform={`translate(${x - width / 2},${y - height / 2})`}\n >\n {render({ node: nodeProps })}\n </g>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const ARROW_MARKER_ID = 'arrow-marker';\n\nexport const NODE_TEST_ID = 'node';\nexport const EDGE_TEST_ID = 'edge';\nexport const LABEL_TEST_ID = 'label';\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DependencyGraphTypes as Types } from './types';\n\n/** @public */\nexport type DependencyGraphDefaultLabelClassKey = 'text';\n\nconst useStyles = makeStyles(\n theme => ({\n text: {\n fill: theme.palette.textContrast,\n },\n }),\n { name: 'BackstageDependencyGraphDefaultLabel' },\n);\n\n/** @public */\nexport function DefaultLabel({ edge: { label } }: Types.RenderLabelProps) {\n const classes = useStyles();\n return (\n <text className={classes.text} textAnchor=\"middle\">\n {label}\n </text>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useLayoutEffect, useMemo } from 'react';\nimport * as d3Shape from 'd3-shape';\nimport isFinite from 'lodash/isFinite';\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DependencyGraphTypes as Types } from './types';\nimport { ARROW_MARKER_ID, EDGE_TEST_ID, LABEL_TEST_ID } from './constants';\nimport { DefaultLabel } from './DefaultLabel';\nimport dagre from '@dagrejs/dagre';\n\n/* Based on: https://github.com/dagrejs/dagre/wiki#configuring-the-layout */\nexport type EdgeProperties = {\n label?: string;\n width?: number;\n height?: number;\n labeloffset?: number;\n labelpos?: Types.LabelPosition;\n minlen?: number;\n weight?: number;\n};\nexport type GraphEdge<T> = Types.DependencyEdge<T> &\n dagre.GraphEdge &\n EdgeProperties;\n\n/** @public */\nexport type DependencyGraphEdgeClassKey = 'path' | 'label';\n\nconst useStyles = makeStyles(\n theme => ({\n path: {\n strokeWidth: 1.3,\n stroke: theme.palette.textSubtle,\n fill: 'none',\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n label: {\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n }),\n { name: 'BackstageDependencyGraphEdge' },\n);\n\ntype EdgePoint = dagre.GraphEdge['points'][0];\n\n/** @public */\nexport type EdgeComponentProps<T = unknown> = {\n id: dagre.Edge;\n edge: GraphEdge<T>;\n render?: Types.RenderLabelFunction<T>;\n setEdge: (\n id: dagre.Edge,\n edge: Types.DependencyEdge<T>,\n ) => dagre.graphlib.Graph<{}>;\n curve: 'curveStepBefore' | 'curveMonotoneX';\n showArrowHeads?: boolean;\n};\n\nconst renderDefault = (props: Types.RenderLabelProps<unknown>) => (\n <DefaultLabel {...props} />\n);\n\nexport function Edge<EdgeData>({\n render = renderDefault,\n setEdge,\n id,\n edge,\n curve,\n showArrowHeads,\n}: EdgeComponentProps<EdgeData>) {\n const { x = 0, y = 0, width, height, points } = edge;\n const labelProps: Types.DependencyEdge<EdgeData> = edge;\n const classes = useStyles();\n\n const labelRef = useRef<SVGGElement>(null);\n\n useLayoutEffect(() => {\n // set the label width to the actual rendered width to properly layout graph\n if (labelRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n labelRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setEdge(id, {\n ...edge,\n height: renderedHeight,\n width: renderedWidth,\n });\n }\n }\n }, [edge, height, width, setEdge, id]);\n\n let path: string = '';\n\n const createPath = useMemo(\n () =>\n d3Shape\n .line<EdgePoint>()\n .x(d => d.x)\n .y(d => d.y)\n .curve(d3Shape[curve]),\n [curve],\n );\n\n if (points) {\n const finitePoints = points.filter(\n (point: EdgePoint) => isFinite(point.x) && isFinite(point.y),\n );\n path = createPath(finitePoints) || '';\n }\n\n return (\n <>\n {path && (\n <path\n data-testid={EDGE_TEST_ID}\n className={classes.path}\n markerEnd={showArrowHeads ? `url(#${ARROW_MARKER_ID})` : undefined}\n d={path}\n />\n )}\n {labelProps.label ? (\n <g\n ref={labelRef}\n data-testid={LABEL_TEST_ID}\n className={classes.label}\n transform={`translate(${x},${y})`}\n >\n {render({ edge: labelProps })}\n </g>\n ) : null}\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport classNames from 'classnames';\nimport { once } from 'lodash';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n fullscreenButton: {\n position: 'absolute',\n right: 0,\n },\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fixedHeight: {\n maxHeight: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom edge rendering component\n */\n renderEdge?: Types.RenderEdgeFunction<EdgeData>;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderEdge,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n\n const [_measureRef] = useMeasure();\n const measureRef = once(_measureRef);\n\n const scalableHeight =\n fit === 'grow' && !fullScreenHandle.active ? maxHeight : '100%';\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n measureRef(root);\n\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (\n containerWidth !== newContainerWidth &&\n newContainerWidth <= maxWidth\n ) {\n setContainerWidth(newContainerWidth);\n }\n if (\n containerHeight !== newContainerHeight &&\n newContainerHeight <= maxHeight\n ) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n const setNode = useCallback(\n (id: string, node: Types.DependencyNode<NodeData>) => {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n const setEdge = useCallback(\n (id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) => {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n return (\n <FullScreen\n handle={fullScreenHandle}\n className={classNames(\n fullScreenHandle.active ? styles.fullscreen : styles.root,\n )}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n className={styles.fullscreenButton}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <div ref={containerRef} style={{ width: '100%', height: '100%' }}>\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n if (renderEdge) return renderEdge({ edge, id: e });\n\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </div>\n </FullScreen>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { useApp } from '@backstage/core-plugin-api';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\nconst DEFAULT_ICON = SvgIcon;\n\nfunction getKind(\n kind: string | undefined,\n entityRef: string | undefined,\n): string | undefined {\n if (kind) {\n return kind.toLocaleLowerCase('en-US');\n }\n\n if (entityRef) {\n try {\n return parseEntityRef(entityRef).kind.toLocaleLowerCase('en-US');\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n}\n\nfunction useIcon(kind: string | undefined, entityRef: string | undefined) {\n const app = useApp();\n\n const actualKind = getKind(kind, entityRef);\n if (!actualKind) {\n return DEFAULT_ICON;\n }\n\n const icon = app.getSystemIcon(`kind:${actualKind}`);\n return icon || DEFAULT_ICON;\n}\n\nexport function EntityKindIcon(props: {\n kind?: string;\n entityRef?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n className?: string;\n}) {\n const { kind, entityRef, ...otherProps } = props;\n const Icon = useIcon(kind, entityRef);\n return <Icon {...otherProps} />;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n DependencyGraph,\n DependencyGraphTypes,\n Link,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { useApi, useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport classNames from 'classnames';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { humanizeEntityRef } from '../../EntityRefLink';\nimport { entityRouteRef } from '../../../routes';\nimport { EntityKindIcon } from './EntityKindIcon';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n node: {\n fill: theme.palette.grey[300],\n stroke: theme.palette.grey[300],\n '&.primary': {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n '&.secondary': {\n fill: theme.palette.secondary.light,\n stroke: theme.palette.secondary.light,\n },\n },\n text: {\n fill: theme.palette.getContrastText(theme.palette.grey[300]),\n '&.primary': {\n fill: theme.palette.primary.contrastText,\n },\n '&.secondary': {\n fill: theme.palette.secondary.contrastText,\n },\n '&.focused': {\n fontWeight: 'bold',\n },\n },\n clickable: {\n cursor: 'pointer',\n },\n}));\n\ntype NodeType = Entity & { root: boolean };\n\nfunction useAncestry(root: Entity): {\n loading: boolean;\n error?: Error;\n nodes: DependencyGraphTypes.DependencyNode<NodeType>[];\n edges: DependencyGraphTypes.DependencyEdge[];\n} {\n const catalogClient = useApi(catalogApiRef);\n const entityRef = stringifyEntityRef(root);\n\n const { loading, error, value } = useAsync(async () => {\n const response = await catalogClient.getEntityAncestors({ entityRef });\n const nodes = new Array<DependencyGraphTypes.DependencyNode<NodeType>>();\n const edges = new Array<DependencyGraphTypes.DependencyEdge>();\n for (const current of response.items) {\n const currentRef = stringifyEntityRef(current.entity);\n const isRootNode = currentRef === response.rootEntityRef;\n nodes.push({ id: currentRef, root: isRootNode, ...current.entity });\n for (const parentRef of current.parentEntityRefs) {\n edges.push({ from: currentRef, to: parentRef });\n }\n }\n return { nodes, edges };\n }, [entityRef]);\n\n return {\n loading,\n error,\n nodes: value?.nodes || [],\n edges: value?.edges || [],\n };\n}\n\nfunction CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {\n const classes = useStyles();\n const navigate = useNavigate();\n const entityRoute = useRouteRef(entityRouteRef);\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const app = useApp();\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const hasKindIcon = app.getSystemIcon(\n `kind:${node.kind.toLocaleLowerCase('en-US')}`,\n );\n const padding = 10;\n const iconSize = height;\n const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;\n const paddedWidth = paddedIconWidth + width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n const displayTitle =\n node.metadata.title ||\n (node.kind && node.metadata.name && node.metadata.namespace\n ? humanizeEntityRef({\n kind: node.kind,\n name: node.metadata.name,\n namespace: node.metadata.namespace || '',\n })\n : node.id);\n\n const onClick = () => {\n navigate(\n entityRoute({\n kind: node.kind,\n namespace: node.metadata.namespace || DEFAULT_NAMESPACE,\n name: node.metadata.name,\n }),\n );\n };\n\n return (\n <g onClick={onClick} className={classes.clickable}>\n <rect\n className={classNames(\n classes.node,\n node.root ? 'secondary' : 'primary',\n )}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n {hasKindIcon && (\n <EntityKindIcon\n kind={node.kind}\n y={padding}\n x={padding}\n width={iconSize}\n height={iconSize}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n />\n )}\n <text\n ref={idRef}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n y={paddedHeight / 2}\n x={paddedIconWidth + (width + padding * 2) / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {displayTitle}\n </text>\n </g>\n );\n}\n\nexport function AncestryPage(props: { entity: Entity }) {\n const { loading, error, nodes, edges } = useAncestry(props.entity);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.ancestryPage.title')}\n </DialogContentText>\n <DialogContentText gutterBottom>\n {t('inspectEntityDialog.ancestryPage.description', {\n processorsLink: (\n <Link to=\"https://backstage.io/docs/features/software-catalog/life-of-an-entity\">\n {t('inspectEntityDialog.ancestryPage.processorsLink')}\n </Link>\n ),\n })}\n </DialogContentText>\n <Box mt={4}>\n <DependencyGraph\n nodes={nodes}\n edges={edges}\n renderNode={CustomNode}\n direction={DependencyGraphTypes.Direction.BOTTOM_TOP}\n zoom=\"enable-on-click\"\n />\n </Box>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Link } from '@backstage/core-components';\nimport Box from '@material-ui/core/Box';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport MuiListItemText from '@material-ui/core/ListItemText';\nimport MuiListSubheader from '@material-ui/core/ListSubheader';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport HelpOutlineIcon from '@material-ui/icons/HelpOutline';\nimport { ReactNode } from 'react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n marginTop: {\n marginTop: theme.spacing(2),\n },\n helpIcon: {\n marginLeft: theme.spacing(1),\n color: theme.palette.text.disabled,\n },\n monospace: {\n fontFamily: 'monospace',\n },\n}));\n\nexport function ListItemText(props: {\n primary: ReactNode;\n secondary?: ReactNode;\n}) {\n const classes = useStyles();\n return (\n <MuiListItemText\n {...props}\n primaryTypographyProps={{ className: classes.monospace }}\n secondaryTypographyProps={{ className: classes.monospace }}\n />\n );\n}\n\nexport function ListSubheader(props: { children?: ReactNode }) {\n const classes = useStyles();\n return (\n <MuiListSubheader className={classes.monospace}>\n {props.children}\n </MuiListSubheader>\n );\n}\n\nexport function Container(props: {\n title: ReactNode;\n helpLink?: string;\n children: ReactNode;\n}) {\n return (\n <Box mt={2}>\n <Card variant=\"outlined\">\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {props.title}\n {props.helpLink && <HelpIcon to={props.helpLink} />}\n </Typography>\n {props.children}\n </CardContent>\n </Card>\n </Box>\n );\n}\n\n// Extracts a link from a value, if possible\nfunction findLink(value: string): string | undefined {\n if (value.match(/^url:https?:\\/\\//)) {\n return value.slice('url:'.length);\n }\n if (value.match(/^https?:\\/\\//)) {\n return value;\n }\n return undefined;\n}\n\nexport function KeyValueListItem(props: {\n indent?: boolean;\n entry: [string, string];\n}) {\n const [key, value] = props.entry;\n const link = findLink(value);\n\n return (\n <ListItem>\n {props.indent && <ListItemIcon />}\n <ListItemText\n primary={key}\n secondary={link ? <Link to={link}>{value}</Link> : value}\n />\n </ListItem>\n );\n}\n\nexport function HelpIcon(props: { to: string }) {\n const classes = useStyles();\n return (\n <Link to={props.to} className={classes.helpIcon}>\n <HelpOutlineIcon fontSize=\"inherit\" />\n </Link>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Alert from '@material-ui/lab/Alert';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport { KeyValueListItem, ListItemText } from './common';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nfunction useColocated(entity: Entity): {\n loading: boolean;\n error?: Error;\n location?: string;\n originLocation?: string;\n colocatedEntities?: Entity[];\n} {\n const catalogApi = useApi(catalogApiRef);\n const currentEntityRef = stringifyEntityRef(entity);\n const location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n const origin = entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n\n const { loading, error, value } = useAsync(async () => {\n if (!location && !origin) {\n return [];\n }\n const response = await catalogApi.getEntities({\n filter: [\n ...(location\n ? [{ [`metadata.annotations.${ANNOTATION_LOCATION}`]: location }]\n : []),\n ...(origin\n ? [{ [`metadata.annotations.${ANNOTATION_ORIGIN_LOCATION}`]: origin }]\n : []),\n ],\n });\n return response.items;\n }, [location, origin]);\n\n return {\n loading,\n error,\n location,\n originLocation: origin,\n colocatedEntities: value?.filter(\n colocated => stringifyEntityRef(colocated) !== currentEntityRef,\n ),\n };\n}\n\nfunction EntityList(props: { entities: Entity[]; header?: [string, string] }) {\n return (\n <List dense>\n {props.header && <KeyValueListItem key=\"header\" entry={props.header} />}\n {props.entities.map(entity => (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemText primary={<EntityRefLink entityRef={entity} />} />\n </ListItem>\n ))}\n </List>\n );\n}\n\nfunction Contents(props: { entity: Entity }) {\n const { entity } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const { loading, error, location, originLocation, colocatedEntities } =\n useColocated(entity);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n if (!location && !originLocation) {\n return (\n <Alert severity=\"warning\">\n {t('inspectEntityDialog.colocatedPage.alertNoLocation')}\n </Alert>\n );\n } else if (!colocatedEntities?.length) {\n return (\n <Alert severity=\"info\">\n {t('inspectEntityDialog.colocatedPage.alertNoEntity')}\n </Alert>\n );\n }\n\n if (location === originLocation) {\n return <EntityList entities={colocatedEntities} />;\n }\n\n const atLocation = colocatedEntities.filter(\n e => e.metadata.annotations?.[ANNOTATION_LOCATION] === location,\n );\n const atOrigin = colocatedEntities.filter(\n e =>\n e.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION] === originLocation,\n );\n\n return (\n <>\n {atLocation.length > 0 && (\n <EntityList\n entities={atLocation}\n header={[\n t('inspectEntityDialog.colocatedPage.locationHeader'),\n location!,\n ]}\n />\n )}\n {atOrigin.length > 0 && (\n <EntityList\n entities={atOrigin}\n header={[\n t('inspectEntityDialog.colocatedPage.originHeader'),\n originLocation!,\n ]}\n />\n )}\n </>\n );\n}\n\nexport function ColocatedPage(props: { entity: Entity }) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.colocatedPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.colocatedPage.description')}\n </DialogContentText>\n <div className={classes.root}>\n <Contents entity={props.entity} />\n </div>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JsonObject } from '@backstage/types';\n\nexport function sortKeys(data: JsonObject): JsonObject {\n // we could do something custom, but lexicographical sorting is actually a\n // good choice at least for the default set of keys\n return Object.fromEntries(\n [...Object.entries(data)].sort((a, b) => (a[0] < b[0] ? -1 : 1)),\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { CodeSnippet } from '@backstage/core-components';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { sortKeys } from './util';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport function JsonPage(props: { entity: Entity }) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.jsonPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.jsonPage.description')}\n </DialogContentText>\n <DialogContentText>\n <div style={{ fontSize: '75%' }} data-testid=\"code-snippet\">\n <CodeSnippet\n text={JSON.stringify(sortKeys(props.entity), undefined, 2)}\n language=\"json\"\n showCopyCodeButton\n />\n </div>\n </DialogContentText>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport groupBy from 'lodash/groupBy';\nimport sortBy from 'lodash/sortBy';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport {\n Container,\n HelpIcon,\n KeyValueListItem,\n ListItemText,\n ListSubheader,\n} from './common';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CopyTextButton } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nexport function OverviewPage(props: { entity: AlphaEntity }) {\n const classes = useStyles();\n const {\n apiVersion,\n kind,\n metadata,\n spec,\n relations = [],\n status = {},\n } = props.entity;\n\n const groupedRelations = groupBy(\n sortBy(relations, r => r.targetRef),\n 'type',\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const entityRef = stringifyEntityRef(props.entity);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.overviewPage.title')}\n </DialogContentText>\n <div className={classes.root}>\n <Container title={t('inspectEntityDialog.overviewPage.identity.title')}>\n <List dense>\n <ListItem>\n <ListItemText primary=\"apiVersion\" secondary={apiVersion} />\n </ListItem>\n <ListItem>\n <ListItemText primary=\"kind\" secondary={kind} />\n </ListItem>\n {spec?.type && (\n <ListItem>\n <ListItemText\n primary=\"spec.type\"\n secondary={spec.type?.toString()}\n />\n </ListItem>\n )}\n {metadata.uid && (\n <ListItem>\n <ListItemText primary=\"uid\" secondary={metadata.uid} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.uid} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n {metadata.etag && (\n <ListItem>\n <ListItemText primary=\"etag\" secondary={metadata.etag} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.etag} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n <ListItem>\n <ListItemText primary=\"entityRef\" secondary={entityRef} />\n <ListItemSecondaryAction>\n <CopyTextButton text={entityRef} />\n </ListItemSecondaryAction>\n </ListItem>\n </List>\n </Container>\n\n <Container title={t('inspectEntityDialog.overviewPage.metadata.title')}>\n {!!Object.keys(metadata.annotations || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.annotations')}\n <HelpIcon to=\"https://backstage.io/docs/features/software-catalog/well-known-annotations\" />\n </ListSubheader>\n }\n >\n {Object.entries(metadata.annotations!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!Object.keys(metadata.labels || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.labels')}\n </ListSubheader>\n }\n >\n {Object.entries(metadata.labels!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!metadata.tags?.length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.tags')}\n </ListSubheader>\n }\n >\n {metadata.tags.map((tag, index) => (\n <ListItem key={`${tag}-${index}`}>\n <ListItemIcon />\n <ListItemText primary={tag} />\n </ListItem>\n ))}\n </List>\n )}\n </Container>\n\n {!!relations.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.relation.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-relations\"\n >\n {Object.entries(groupedRelations).map(\n ([type, groupRelations], index) => (\n <div key={index}>\n <List dense subheader={<ListSubheader>{type}</ListSubheader>}>\n {groupRelations.map(group => (\n <ListItem key={group.targetRef}>\n <ListItemText\n primary={\n <EntityRefLink entityRef={group.targetRef} />\n }\n />\n </ListItem>\n ))}\n </List>\n </div>\n ),\n )}\n </Container>\n )}\n\n {!!status.items?.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.status.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-statuses\"\n >\n {status.items.map((item, index) => (\n <div key={index}>\n <Typography>\n {item.level}: {item.type}\n </Typography>\n <Box ml={2}>{item.message}</Box>\n </div>\n ))}\n </Container>\n )}\n </div>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { CodeSnippet } from '@backstage/core-components';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport YAML from 'yaml';\nimport { sortKeys } from './util';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport function YamlPage(props: { entity: Entity }) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.yamlPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.yamlPage.description')}\n </DialogContentText>\n <DialogContentText>\n <div style={{ fontSize: '75%' }} data-testid=\"code-snippet\">\n <CodeSnippet\n text={YAML.stringify(sortKeys(props.entity))}\n language=\"yaml\"\n showCopyCodeButton\n />\n </div>\n </DialogContentText>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ComponentProps, useEffect, useState, ReactNode, useMemo } from 'react';\nimport { AncestryPage } from './components/AncestryPage';\nimport { ColocatedPage } from './components/ColocatedPage';\nimport { JsonPage } from './components/JsonPage';\nimport { OverviewPage } from './components/OverviewPage';\nimport { YamlPage } from './components/YamlPage';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n fullHeightDialog: {\n height: 'calc(100% - 64px)',\n },\n root: {\n display: 'flex',\n flexGrow: 1,\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabs: {\n borderRight: `1px solid ${theme.palette.divider}`,\n flexShrink: 0,\n },\n tabContents: {\n flexGrow: 1,\n overflowX: 'auto',\n },\n}));\n\nfunction TabPanel(props: {\n children?: ReactNode;\n index: number;\n value: number;\n}) {\n const { children, value, index, ...other } = props;\n const classes = useStyles();\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`vertical-tabpanel-${index}`}\n aria-labelledby={`vertical-tab-${index}`}\n className={classes.tabContents}\n {...other}\n >\n {value === index && (\n <Box pl={3} pr={3}>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `vertical-tab-${index}`,\n 'aria-controls': `vertical-tabpanel-${index}`,\n };\n}\n\ntype TabKey = 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n\ntype TabNames = Record<\n NonNullable<ComponentProps<typeof InspectEntityDialog>['initialTab']>,\n string\n>;\n\n/**\n * A dialog that lets users inspect the low level details of their entities.\n *\n * @public\n */\nexport function InspectEntityDialog(props: {\n open: boolean;\n entity: Entity;\n initialTab?: 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n onClose: () => void;\n onSelect?: (tab: string) => void;\n}) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const tabNames: TabNames = useMemo(\n () => ({\n overview: t('inspectEntityDialog.tabNames.overview'),\n ancestry: t('inspectEntityDialog.tabNames.ancestry'),\n colocated: t('inspectEntityDialog.tabNames.colocated'),\n json: t('inspectEntityDialog.tabNames.json'),\n yaml: t('inspectEntityDialog.tabNames.yaml'),\n }),\n [t],\n );\n\n const tabs = Object.keys(tabNames) as TabKey[];\n\n const [activeTab, setActiveTab] = useState(\n getTabIndex(tabs, props.initialTab),\n );\n\n useEffect(() => {\n getTabIndex(tabs, props.initialTab);\n }, [props.open, props.initialTab, tabs]);\n\n if (!props.entity) {\n return null;\n }\n\n return (\n <Dialog\n fullWidth\n maxWidth=\"xl\"\n open={props.open}\n onClose={props.onClose}\n aria-labelledby=\"entity-inspector-dialog-title\"\n PaperProps={{ className: classes.fullHeightDialog }}\n >\n <DialogTitle id=\"entity-inspector-dialog-title\">\n {t('inspectEntityDialog.title')}\n </DialogTitle>\n <DialogContent dividers>\n <div className={classes.root}>\n <Tabs\n orientation=\"vertical\"\n variant=\"scrollable\"\n value={activeTab}\n onChange={(_, tabIndex) => {\n setActiveTab(tabIndex);\n props.onSelect?.(tabs[tabIndex]);\n }}\n aria-label={t('inspectEntityDialog.tabsAriaLabel')}\n className={classes.tabs}\n >\n {tabs.map((tab, index) => (\n <Tab key={tab} label={tabNames[tab]} {...a11yProps(index)} />\n ))}\n </Tabs>\n\n <TabPanel value={activeTab} index={0}>\n <OverviewPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={1}>\n <AncestryPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={2}>\n <ColocatedPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={3}>\n <JsonPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={4}>\n <YamlPage entity={props.entity} />\n </TabPanel>\n </div>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} color=\"primary\">\n {t('inspectEntityDialog.closeButtonTitle')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n\nfunction getTabIndex(allTabs: string[], initialTab: TabKey | undefined) {\n return initialTab ? allTabs.indexOf(initialTab) : 0;\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HeaderLabel } from '@backstage/core-components';\nimport { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../translation';\n\ntype EntityLabelsProps = {\n entity: Entity;\n};\n\nexport function EntityLabels(props: EntityLabelsProps) {\n const { entity } = props;\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n const { t } = useTranslationRef(catalogTranslationRef);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('entityLabels.ownerLabel')}\n contentTypograpyRootComponent=\"p\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel\n label={t('entityLabels.lifecycleLabel')}\n value={entity.spec.lifecycle?.toString()}\n />\n )}\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { forwardRef } from 'react';\n\ntype VisibleType = 'visible' | 'hidden' | 'disable';\n\nexport type UnregisterEntityOptions = {\n disableUnregister: boolean | VisibleType;\n};\n\ninterface UnregisterEntityProps {\n unregisterEntityOptions?: UnregisterEntityOptions;\n isUnregisterAllowed: boolean;\n onUnregisterEntity: () => void;\n onClose: () => void;\n}\n\n// TODO: When Backstage supports only React 19+, remove the forwardRef\nexport const UnregisterEntity = forwardRef<\n HTMLLIElement,\n UnregisterEntityProps\n>((props, ref) => {\n const {\n unregisterEntityOptions,\n isUnregisterAllowed,\n onUnregisterEntity,\n onClose,\n } = props;\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const isBoolean =\n typeof unregisterEntityOptions?.disableUnregister === 'boolean';\n\n const isDisabled =\n (!isUnregisterAllowed ||\n (isBoolean\n ? !!unregisterEntityOptions?.disableUnregister\n : unregisterEntityOptions?.disableUnregister === 'disable')) ??\n false;\n\n if (unregisterEntityOptions?.disableUnregister !== 'hidden') {\n return (\n <MenuItem\n ref={ref}\n onClick={() => {\n onClose();\n onUnregisterEntity();\n }}\n disabled={isDisabled}\n {...props}\n >\n <ListItemIcon>\n <CancelIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.unregisterMenuTitle')} />\n </MenuItem>\n );\n }\n\n return null;\n});\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport { ReactNode } from 'react';\n\n/** @internal */\nexport type EntityContextMenuContextValue = {\n onMenuClose: () => void;\n};\n\nconst EntityContextMenuContext = createVersionedContext<{\n 1: EntityContextMenuContextValue;\n}>('entity-context-menu-context');\n\n/** @internal */\nexport interface EntityContextMenuProviderProps {\n children: ReactNode;\n onMenuClose: () => void;\n}\n\n/** @internal */\nexport const EntityContextMenuProvider = (\n props: EntityContextMenuProviderProps,\n) => {\n const { children, onMenuClose } = props;\n const value = { onMenuClose };\n\n return (\n <EntityContextMenuContext.Provider\n value={createVersionedValueMap({ 1: value })}\n >\n {children}\n </EntityContextMenuContext.Provider>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Divider from '@material-ui/core/Divider';\nimport FileCopyTwoToneIcon from '@material-ui/icons/FileCopyTwoTone';\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MenuList from '@material-ui/core/MenuList';\nimport Popover from '@material-ui/core/Popover';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport BugReportIcon from '@material-ui/icons/BugReport';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport { SyntheticEvent, useEffect, useState } from 'react';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';\nimport { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { UnregisterEntity, UnregisterEntityOptions } from './UnregisterEntity';\nimport { useApi, alertApiRef } from '@backstage/core-plugin-api';\nimport useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { EntityContextMenuProvider } from '../../context';\n\n/** @public */\nexport type EntityContextMenuClassKey = 'button';\n\nconst useStyles = makeStyles(\n (theme: Theme) => {\n return {\n button: {\n color: theme.page.fontColor,\n },\n };\n },\n { name: 'PluginCatalogEntityContextMenu' },\n);\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\ninterface EntityContextMenuProps {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: UnregisterEntityOptions;\n contextMenuItems?: React.JSX.Element[];\n onUnregisterEntity: () => void;\n onInspectEntity: () => void;\n}\n\nexport function EntityContextMenu(props: EntityContextMenuProps) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n onUnregisterEntity,\n onInspectEntity,\n } = props;\n const { t } = useTranslationRef(catalogTranslationRef);\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const classes = useStyles();\n const unregisterPermission = useEntityPermission(\n catalogEntityDeletePermission,\n );\n const isAllowed = unregisterPermission.allowed;\n\n const onOpen = (event: SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n const alertApi = useApi(alertApiRef);\n const [copyState, copyToClipboard] = useCopyToClipboard();\n useEffect(() => {\n if (!copyState.error && copyState.value) {\n alertApi.post({\n message: t('entityContextMenu.copiedMessage'),\n severity: 'info',\n display: 'transient',\n });\n }\n }, [copyState, alertApi, t]);\n\n const extraItems = UNSTABLE_extraContextMenuItems?.length\n ? [\n ...UNSTABLE_extraContextMenuItems.map(item => (\n <MenuItem\n key={item.title}\n onClick={() => {\n onClose();\n item.onClick();\n }}\n >\n <ListItemIcon>\n <item.Icon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={item.title} />\n </MenuItem>\n )),\n <Divider key=\"the divider is here!\" />,\n ]\n : null;\n\n const defaultMenuItems = [\n <UnregisterEntity\n unregisterEntityOptions={UNSTABLE_contextMenuOptions}\n isUnregisterAllowed={isAllowed}\n onUnregisterEntity={onUnregisterEntity}\n onClose={onClose}\n key=\"unregister-entity\"\n />,\n <MenuItem\n onClick={() => {\n onClose();\n onInspectEntity();\n }}\n key=\"inspect-entity\"\n >\n <ListItemIcon>\n <BugReportIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.inspectMenuTitle')} />\n </MenuItem>,\n <MenuItem\n onClick={() => {\n onClose();\n copyToClipboard(window.location.toString());\n }}\n key=\"copy-url\"\n >\n <ListItemIcon>\n <FileCopyTwoToneIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.copyURLMenuTitle')} />\n </MenuItem>,\n ];\n\n return (\n <>\n <Tooltip title={t('entityContextMenu.moreButtonTitle')} arrow>\n <IconButton\n aria-label={t('entityContextMenu.moreButtonAriaLabel')}\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n aria-expanded={!!anchorEl}\n role=\"button\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n className={classes.button}\n id=\"long-menu\"\n >\n <MoreVert />\n </IconButton>\n </Tooltip>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n aria-labelledby=\"long-menu\"\n PaperProps={{\n style: { minWidth: 200 },\n }}\n >\n <MenuList autoFocusItem={Boolean(anchorEl)}>\n {extraItems}\n {contextMenuItems === undefined ? (\n defaultMenuItems\n ) : (\n <EntityContextMenuProvider onMenuClose={onClose}>\n {contextMenuItems}\n </EntityContextMenuProvider>\n )}\n </MenuList>\n </Popover>\n </>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useState,\n useCallback,\n useEffect,\n ComponentProps,\n ReactNode,\n} from 'react';\nimport { useNavigate, useLocation, useSearchParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Box from '@material-ui/core/Box';\n\nimport { Header, Breadcrumbs } from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { IconComponent } from '@backstage/frontend-plugin-api';\n\nimport {\n Entity,\n EntityRelation,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\n\nimport {\n useAsyncEntity,\n entityRouteRef,\n catalogApiRef,\n EntityRefLink,\n InspectEntityDialog,\n UnregisterEntityDialog,\n EntityDisplayName,\n FavoriteEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { EntityLabels } from '../EntityLabels';\nimport { EntityContextMenu } from '../../../components/EntityContextMenu';\nimport { rootRouteRef, unregisterRedirectRouteRef } from '../../../routes';\n\nfunction headerProps(\n paramKind: string | undefined,\n paramNamespace: string | undefined,\n paramName: string | undefined,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } {\n const kind = paramKind ?? entity?.kind ?? '';\n const namespace = paramNamespace ?? entity?.metadata.namespace ?? '';\n const name =\n entity?.metadata.title ?? paramName ?? entity?.metadata.name ?? '';\n\n return {\n headerTitle: `${name}${\n namespace && namespace !== DEFAULT_NAMESPACE ? ` in ${namespace}` : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n}\n\nfunction findParentRelation(\n entityRelations: EntityRelation[] = [],\n relationTypes: string[] = [],\n) {\n for (const type of relationTypes) {\n const foundRelation = entityRelations.find(\n relation => relation.type === type,\n );\n if (foundRelation) {\n return foundRelation; // Return the first found relation and stop\n }\n }\n return null;\n}\n\nconst useStyles = makeStyles(theme => ({\n breadcrumbs: {\n color: theme.page.fontColor,\n fontSize: theme.typography.caption.fontSize,\n textTransform: 'uppercase',\n marginTop: theme.spacing(1),\n opacity: 0.8,\n '& span ': {\n color: theme.page.fontColor,\n textDecoration: 'underline',\n textUnderlineOffset: '3px',\n },\n },\n}));\n\nfunction EntityHeaderTitle() {\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: title } = headerProps(kind, namespace, name, entity);\n return (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\" maxWidth=\"100%\">\n <Box\n component=\"span\"\n textOverflow=\"ellipsis\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n {entity ? <EntityDisplayName entityRef={entity} hideIcon /> : title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n}\n\nfunction EntityHeaderSubtitle(props: { parentEntityRelations?: string[] }) {\n const { parentEntityRelations } = props;\n const classes = useStyles();\n const { entity } = useAsyncEntity();\n const { name } = useRouteRefParams(entityRouteRef);\n const parentEntity = findParentRelation(\n entity?.relations ?? [],\n parentEntityRelations ?? [],\n );\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: ancestorEntity } = useAsync(async () => {\n if (parentEntity) {\n return findParentRelation(\n (await catalogApi.getEntityByRef(parentEntity?.targetRef))?.relations,\n parentEntityRelations,\n );\n }\n return null;\n }, [parentEntity, catalogApi]);\n\n return parentEntity ? (\n <Breadcrumbs separator=\">\" className={classes.breadcrumbs}>\n {ancestorEntity && (\n <EntityRefLink entityRef={ancestorEntity.targetRef} disableTooltip />\n )}\n <EntityRefLink entityRef={parentEntity.targetRef} disableTooltip />\n {name}\n </Breadcrumbs>\n ) : null;\n}\n\n/** @alpha */\nexport function EntityHeader(props: {\n // NOTE(freben): Intentionally not exported at this point, since it's part of\n // the unstable extra context menu items concept below\n UNSTABLE_extraContextMenuItems?: {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n }[];\n // NOTE(blam): Intentionally not exported at this point, since it's part of\n // unstable context menu option, eg: disable the unregister entity menu\n UNSTABLE_contextMenuOptions?: {\n disableUnregister: boolean | 'visible' | 'hidden' | 'disable';\n };\n contextMenuItems?: React.JSX.Element[];\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n title?: ReactNode;\n subtitle?: ReactNode;\n}) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n parentEntityRelations,\n title,\n subtitle,\n } = props;\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: entityFallbackText, headerType: type } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const location = useLocation();\n const navigate = useNavigate();\n const catalogRoute = useRouteRef(rootRouteRef);\n const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef);\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n\n const openUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(true),\n [setConfirmationDialogOpen],\n );\n\n const closeUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(false),\n [setConfirmationDialogOpen],\n );\n\n const cleanUpAfterUnregisterConfirmation = useCallback(async () => {\n setConfirmationDialogOpen(false);\n navigate(\n unregisterRedirectRoute ? unregisterRedirectRoute() : catalogRoute(),\n );\n }, [\n navigate,\n catalogRoute,\n unregisterRedirectRoute,\n setConfirmationDialogOpen,\n ]);\n\n // Make sure to close the dialog if the user clicks links in it that navigate\n // to another entity.\n useEffect(() => {\n setConfirmationDialogOpen(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\n\n const [searchParams, setSearchParams] = useSearchParams();\n const selectedInspectEntityDialogTab = searchParams.get('inspect');\n\n const setInspectEntityDialogTab = useCallback(\n (newTab: string) => setSearchParams(`inspect=${newTab}`),\n [setSearchParams],\n );\n\n const openInspectEntityDialog = useCallback(\n () => setSearchParams('inspect'),\n [setSearchParams],\n );\n\n const closeInspectEntityDialog = useCallback(\n () => setSearchParams(),\n [setSearchParams],\n );\n\n const inspectDialogOpen = typeof selectedInspectEntityDialogTab === 'string';\n\n return (\n <Header\n pageTitleOverride={entityFallbackText}\n type={type}\n title={title ?? <EntityHeaderTitle />}\n subtitle={\n subtitle ?? (\n <EntityHeaderSubtitle parentEntityRelations={parentEntityRelations} />\n )\n }\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n contextMenuItems={contextMenuItems}\n onInspectEntity={openInspectEntityDialog}\n onUnregisterEntity={openUnregisterEntityDialog}\n />\n <InspectEntityDialog\n entity={entity!}\n initialTab={\n (selectedInspectEntityDialogTab as ComponentProps<\n typeof InspectEntityDialog\n >['initialTab']) || undefined\n }\n open={inspectDialogOpen}\n onClose={closeInspectEntityDialog}\n onSelect={setInspectEntityDialogTab}\n />\n <UnregisterEntityDialog\n entity={entity!}\n open={confirmationDialogOpen}\n onClose={closeUnregisterEntityDialog}\n onConfirm={cleanUpAfterUnregisterConfirmation}\n />\n </>\n )}\n </Header>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport classNames from 'classnames';\nimport { PropsWithChildren } from 'react';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\n\n/** @public */\nexport type EntityTabsPanelClassKey = 'root' | 'stretch' | 'noPadding';\n\nconst useStyles = makeStyles(\n (theme: Theme) => ({\n root: {\n gridArea: 'pageContent',\n minWidth: 0,\n paddingTop: theme.spacing(3),\n paddingBottom: theme.spacing(3),\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(2),\n [theme.breakpoints.up('sm')]: {\n paddingLeft: theme.spacing(3),\n paddingRight: theme.spacing(3),\n },\n },\n stretch: {\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n },\n noPadding: {\n padding: 0,\n },\n }),\n { name: 'EntityTabsPanel' },\n);\n\ntype EntityTabsPanelProps = PropsWithChildren<{\n stretch?: boolean;\n noPadding?: boolean;\n className?: string;\n}>;\n\nexport function EntityTabsPanel(props: EntityTabsPanelProps) {\n const { className, stretch, noPadding, children, ...restProps } = props;\n\n const classes = useStyles();\n return (\n <article\n {...restProps}\n className={classNames(classes.root, className, {\n [classes.stretch]: stretch,\n [classes.noPadding]: noPadding,\n })}\n >\n {children}\n </article>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ReactNode,\n forwardRef,\n useState,\n MouseEvent,\n MouseEventHandler,\n ReactElement,\n} from 'react';\nimport { Link } from 'react-router-dom';\nimport classnames from 'classnames';\n\nimport Typography from '@material-ui/core/Typography';\nimport Popover from '@material-ui/core/Popover';\nimport { TabProps, TabClassKey } from '@material-ui/core/Tab';\nimport { capitalize } from '@material-ui/core/utils';\nimport { createStyles, Theme, withStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Button from '@material-ui/core/Button';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport List from '@material-ui/core/List';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { IconsApi, iconsApiRef } from '@backstage/frontend-plugin-api';\n\nconst styles = (theme: Theme) =>\n createStyles({\n /* Styles applied to the root element. */\n root: {\n ...theme.typography.button,\n maxWidth: 264,\n minWidth: 72,\n position: 'relative',\n boxSizing: 'border-box',\n minHeight: 48,\n flexShrink: 0,\n padding: '6px 12px',\n [theme.breakpoints.up('sm')]: {\n padding: '6px 24px',\n },\n overflow: 'hidden',\n whiteSpace: 'normal',\n textAlign: 'center',\n [theme.breakpoints.up('sm')]: {\n minWidth: 160,\n },\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n /* Styles applied to the root element if both `icon` and `label` are provided. */\n labelIcon: {\n minHeight: 72,\n paddingTop: 9,\n '& $wrapper > *:first-child': {\n marginBottom: 6,\n },\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"inherit\"`. */\n textColorInherit: {\n color: 'inherit',\n opacity: 0.7,\n '&$selected': {\n opacity: 1,\n },\n '&$disabled': {\n opacity: 0.5,\n },\n },\n selectedButton: {\n color: `${theme.palette.text.primary}`,\n opacity: `${1}`,\n },\n unselectedButton: {\n color: `${theme.palette.text.secondary}`,\n opacity: `${0.7}`,\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"primary\"`. */\n textColorPrimary: {\n color: theme.palette.text.secondary,\n '&$selected': {\n color: theme.palette.primary.main,\n },\n '&$disabled': {\n color: theme.palette.text.disabled,\n },\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"secondary\"`. */\n textColorSecondary: {\n color: theme.palette.text.secondary,\n '&$selected': {\n color: theme.palette.secondary.main,\n },\n '&$disabled': {\n color: theme.palette.text.disabled,\n },\n },\n /* Pseudo-class applied to the root element if `selected={true}` (controlled by the Tabs component). */\n selected: {},\n /* Pseudo-class applied to the root element if `disabled={true}` (controlled by the Tabs component). */\n disabled: {},\n /* Styles applied to the root element if `fullWidth={true}` (controlled by the Tabs component). */\n fullWidth: {\n flexShrink: 1,\n flexGrow: 1,\n flexBasis: 0,\n maxWidth: 'none',\n },\n /* Styles applied to the root element if `wrapped={true}`. */\n wrapped: {\n fontSize: theme.typography.pxToRem(12),\n lineHeight: 1.5,\n },\n /* Styles applied to the `icon` and `label`'s wrapper element. */\n wrapper: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n flexDirection: 'row',\n },\n });\n\ntype EntityTabsGroupItem = {\n id: string;\n label: string;\n path: string;\n icon?: string | ReactElement;\n};\n\ntype EntityTabsGroupProps = TabProps & {\n classes?: Partial<ReturnType<typeof styles>>;\n indicator?: ReactNode;\n highlightedButton?: string;\n items: EntityTabsGroupItem[];\n onSelectTab?: MouseEventHandler<HTMLAnchorElement>;\n showIcons?: boolean;\n};\n\nfunction resolveIcon(\n icon: string | ReactElement | undefined,\n iconsApi: IconsApi,\n showIcons: boolean,\n) {\n if (!showIcons) {\n return undefined;\n }\n if (typeof icon === 'string') {\n const Icon = iconsApi.getIcon(icon);\n if (Icon) {\n return <Icon />;\n }\n return undefined;\n }\n return icon;\n}\n\nconst Tab = forwardRef(function Tab(props: EntityTabsGroupProps, ref: any) {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n const iconsApi = useApi(iconsApiRef);\n\n const open = Boolean(anchorEl);\n const submenuId = open ? 'tabbed-submenu' : undefined;\n\n const {\n classes,\n className,\n disabled = false,\n disableFocusRipple = false,\n items,\n fullWidth,\n indicator,\n label,\n onSelectTab,\n selected,\n textColor = 'inherit',\n wrapped = false,\n highlightedButton,\n showIcons = false,\n } = props;\n\n const groupIcon = resolveIcon(props.icon, iconsApi, showIcons);\n const testId = 'data-testid' in props && props['data-testid'];\n\n const handleMenuClose = () => {\n setAnchorEl(null);\n };\n\n const handleMenuClick = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const classArray = [\n classes?.root,\n classes?.[`textColor${capitalize(textColor)}` as TabClassKey],\n classes && {\n [classes.disabled!]: disabled,\n [classes.selected!]: selected,\n [classes.labelIcon!]: label && groupIcon,\n [classes.fullWidth!]: fullWidth,\n [classes.wrapped!]: wrapped,\n },\n className,\n ];\n\n if (items.length === 1) {\n return (\n <Button\n focusRipple={!disableFocusRipple}\n data-testid={testId}\n className={classnames(\n classArray,\n classes && {\n [classes.labelIcon!]: label && (items[0].icon ?? groupIcon),\n },\n )}\n ref={ref}\n role=\"tab\"\n aria-selected={selected}\n disabled={disabled}\n component={Link}\n onClick={onSelectTab}\n to={items[0]?.path}\n startIcon={resolveIcon(items[0].icon, iconsApi, showIcons)}\n >\n <Typography className={classes?.wrapper} variant=\"button\">\n {items[0].label}\n </Typography>\n {indicator}\n </Button>\n );\n }\n const hasIcons = showIcons && items.some(i => i.icon);\n return (\n <>\n <Button\n data-testid={testId}\n focusRipple={!disableFocusRipple}\n className={classnames(classArray)}\n ref={ref}\n role=\"tab\"\n aria-selected={selected}\n disabled={disabled}\n onClick={handleMenuClick}\n startIcon={groupIcon}\n >\n <Typography className={classes?.wrapper} variant=\"button\">\n {label}\n </Typography>\n <ExpandMoreIcon />\n </Button>\n <Popover\n id={submenuId}\n open={open}\n anchorEl={anchorEl}\n onClose={handleMenuClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'center',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'center',\n }}\n >\n <List component=\"nav\">\n {items.map(i => {\n const itemIcon = resolveIcon(i.icon, iconsApi, showIcons);\n return (\n <ListItem\n key={`popover_item_${i.id}`}\n button\n focusRipple={!disableFocusRipple}\n classes={{\n selected: classnames(classes?.selectedButton),\n default: classnames(classes?.unselectedButton),\n disabled: classnames(classes?.disabled),\n }}\n ref={ref}\n aria-selected={selected}\n disabled={disabled}\n selected={highlightedButton === i.id}\n component={Link}\n onClick={e => {\n handleMenuClose();\n onSelectTab?.(e);\n }}\n to={i.path}\n >\n {itemIcon && <ListItemIcon>{itemIcon}</ListItemIcon>}\n <ListItemText\n inset={!itemIcon && hasIcons}\n primary={\n <>\n <Typography variant=\"button\">{i.label}</Typography>\n {indicator}\n </>\n }\n />\n </ListItem>\n );\n })}\n </List>\n </Popover>\n </>\n );\n});\n\n// @ts-ignore\nexport const EntityTabsGroup = withStyles(styles, { name: 'MuiTab' })(Tab);\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactElement, useMemo } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\nimport { EntityTabsGroup } from './EntityTabsGroup';\nimport { catalogTranslationRef } from '../../translation';\n\n/** @public */\nexport type HeaderTabsClassKey =\n | 'tabsWrapper'\n | 'defaultTab'\n | 'selected'\n | 'tabRoot';\n\nconst useStyles = makeStyles(\n theme => ({\n tabsWrapper: {\n gridArea: 'pageSubheader',\n backgroundColor: theme.palette.background.paper,\n paddingLeft: theme.spacing(3),\n minWidth: 0,\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n selected: {\n color: theme.palette.text.primary,\n },\n tabRoot: {\n '&:hover': {\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n },\n },\n }),\n { name: 'BackstageHeaderTabs' },\n);\n\ntype Tab = {\n id: string;\n label: string;\n path: string;\n group?: string;\n icon?: string | ReactElement;\n};\n\ntype TabGroup = {\n group?: {\n title: string;\n icon?: string | ReactElement;\n };\n items: Array<Omit<Tab, 'group'>>;\n};\n\ntype EntityTabsListProps = {\n tabs: Tab[];\n groupDefinitions: EntityContentGroupDefinitions;\n showIcons?: boolean;\n selectedIndex?: number;\n};\n\nexport function EntityTabsList(props: EntityTabsListProps) {\n const styles = useStyles();\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const { tabs: items, selectedIndex = 0, showIcons, groupDefinitions } = props;\n\n const groups = useMemo(\n () =>\n items.reduce((result, tab) => {\n const group = tab.group ? groupDefinitions[tab.group] : undefined;\n const groupOrId = group && tab.group ? tab.group : tab.id;\n result[groupOrId] = result[groupOrId] ?? {\n group,\n items: [],\n };\n result[groupOrId].items.push(tab);\n return result;\n }, {} as Record<string, TabGroup>),\n [items, groupDefinitions],\n );\n\n const selectedItem = items[selectedIndex];\n return (\n <Box className={styles.tabsWrapper}>\n <Tabs\n selectionFollowsFocus\n indicatorColor=\"primary\"\n textColor=\"inherit\"\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label={t('entityTabs.tabsAriaLabel')}\n value={selectedItem?.group ?? selectedItem?.id}\n >\n {Object.entries(groups).map(([id, tabGroup]) => (\n <EntityTabsGroup\n data-testid={`header-tab-${id}`}\n className={styles.defaultTab}\n classes={{ selected: styles.selected, root: styles.tabRoot }}\n key={id}\n label={tabGroup.group?.title}\n icon={tabGroup.group?.icon}\n value={id}\n items={tabGroup.items}\n highlightedButton={selectedItem?.id}\n showIcons={showIcons}\n />\n ))}\n </Tabs>\n </Box>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ReactElement, useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { matchRoutes, useParams, useRoutes } from 'react-router-dom';\nimport { EntityTabsPanel } from './EntityTabsPanel';\nimport { EntityTabsList } from './EntityTabsList';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\ntype SubRoute = {\n group?: string;\n path: string;\n title: string;\n icon?: string | ReactElement;\n children: JSX.Element;\n};\n\nexport function useSelectedSubRoute(subRoutes: SubRoute[]): {\n index: number;\n route?: SubRoute;\n element?: JSX.Element;\n} {\n const params = useParams();\n\n const routes = subRoutes.map(({ path, children }) => ({\n caseSensitive: false,\n path: `${path}/*`,\n element: children,\n }));\n\n // TODO: remove once react-router updated\n const sortedRoutes = routes.sort((a, b) =>\n // remove \"/*\" symbols from path end before comparing\n b.path.replace(/\\/\\*$/, '').localeCompare(a.path.replace(/\\/\\*$/, '')),\n );\n\n const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;\n\n // TODO(Rugvip): Once we only support v6 stable we can always prefix\n // This avoids having a double / prefix for react-router v6 beta, which in turn breaks\n // the tab highlighting when using relative paths for the tabs.\n let currentRoute = params['*'] ?? '';\n if (!currentRoute.startsWith('/')) {\n currentRoute = `/${currentRoute}`;\n }\n\n const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];\n const foundIndex = matchedRoute\n ? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)\n : 0;\n\n return {\n index: foundIndex === -1 ? 0 : foundIndex,\n element,\n route: subRoutes[foundIndex] ?? subRoutes[0],\n };\n}\n\ntype EntityTabsProps = {\n routes: SubRoute[];\n groupDefinitions: EntityContentGroupDefinitions;\n showIcons?: boolean;\n};\n\nexport function EntityTabs(props: EntityTabsProps) {\n const { routes, groupDefinitions, showIcons } = props;\n\n const { index, route, element } = useSelectedSubRoute(routes);\n\n const tabs = useMemo(\n () =>\n routes.map(t => {\n const { path, title, group, icon } = t;\n let to = path;\n // Remove trailing /*\n to = to.replace(/\\/\\*$/, '');\n // And remove leading / for relative navigation\n to = to.replace(/^\\//, '');\n return {\n group,\n id: path,\n path: to,\n label: title,\n icon,\n };\n }),\n [routes],\n );\n\n return (\n <>\n <EntityTabsList\n tabs={tabs}\n selectedIndex={index}\n showIcons={showIcons}\n groupDefinitions={groupDefinitions}\n />\n <EntityTabsPanel>\n <Helmet title={route?.title} />\n {element}\n </EntityTabsPanel>\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentProps, ReactNode, ReactElement } from 'react';\n\nimport Alert from '@material-ui/lab/Alert';\n\nimport {\n attachComponentData,\n useElementFilter,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n Content,\n Link,\n Page,\n Progress,\n WarningPanel,\n} from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n entityRouteRef,\n useAsyncEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { catalogTranslationRef } from '../../translation';\nimport { EntityHeader } from '../EntityHeader';\nimport { EntityTabs } from '../EntityTabs';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\nexport type EntityLayoutRouteProps = {\n path: string;\n title: string;\n group?: string;\n icon?: string | ReactElement;\n children: JSX.Element;\n if?: (entity: Entity) => boolean;\n};\n\nconst dataKey = 'plugin.catalog.entityLayoutRoute';\nconst Route: (props: EntityLayoutRouteProps) => null = () => null;\nattachComponentData(Route, dataKey, true);\nattachComponentData(Route, 'core.gatherMountPoints', true); // This causes all mount points that are discovered within this route to use the path of the route itself\n\n/** @public */\nexport interface EntityLayoutProps {\n UNSTABLE_contextMenuOptions?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_contextMenuOptions'];\n UNSTABLE_extraContextMenuItems?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_extraContextMenuItems'];\n contextMenuItems?: ComponentProps<typeof EntityHeader>['contextMenuItems'];\n children?: ReactNode;\n header?: JSX.Element;\n NotFoundComponent?: ReactNode;\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n groupDefinitions: EntityContentGroupDefinitions;\n showNavItemIcons?: boolean;\n}\n\n/**\n * EntityLayout is a compound component, which allows you to define a layout for\n * entities using a sub-navigation mechanism.\n *\n * Consists of two parts: EntityLayout and EntityLayout.Route\n *\n * @example\n * ```jsx\n * <EntityLayout>\n * <EntityLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </EntityLayout.Route>\n * </EntityLayout>\n * ```\n *\n * @public\n */\nexport const EntityLayout = (props: EntityLayoutProps) => {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n children,\n header,\n NotFoundComponent,\n parentEntityRelations,\n groupDefinitions,\n showNavItemIcons,\n } = props;\n const { kind } = useRouteRefParams(entityRouteRef);\n const { entity, loading, error } = useAsyncEntity();\n\n const routes = useElementFilter(\n children,\n elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of EntityLayout must be an EntityLayout.Route',\n })\n .getElements<EntityLayoutRouteProps>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props: elementProps }) => {\n if (!entity) {\n return [];\n }\n if (elementProps.if && !elementProps.if(entity)) {\n return [];\n }\n return [\n {\n path: elementProps.path,\n title: elementProps.title,\n group: elementProps.group,\n children: elementProps.children,\n icon: elementProps.icon,\n },\n ];\n }),\n [entity],\n );\n\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n {header ?? (\n <EntityHeader\n parentEntityRelations={parentEntityRelations}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n contextMenuItems={contextMenuItems}\n />\n )}\n\n {loading && <Progress />}\n\n {entity && (\n <EntityTabs\n routes={routes}\n groupDefinitions={groupDefinitions}\n showIcons={showNavItemIcons}\n />\n )}\n\n {error && (\n <Content>\n <Alert severity=\"error\">{error.toString()}</Alert>\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n {NotFoundComponent ? (\n NotFoundComponent\n ) : (\n <WarningPanel title={t('entityLabels.warningPanelTitle')}>\n {t('entityPage.notFoundMessage', {\n kind,\n link: (\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n {t('entityPage.notFoundLinkText')}\n </Link>\n ),\n })}\n </WarningPanel>\n )}\n </Content>\n )}\n </Page>\n );\n};\n\nEntityLayout.Route = Route;\n"],"names":["useStyles","makeStyles","FavoriteToggleIcon","props","isFavorite","classes","Typography","StarIcon","UnstarredIcon","FavoriteToggle","id","title","value","onChange","iconButtonProps","Tooltip","IconButton","humanizeEntityRef","entityRef","opts","kind","namespace","name","defaultKind","undefined","DEFAULT_NAMESPACE","humanizeEntity","entity","defaultName","path","get","DependencyGraphTypes","getEntityRef","entityOrRef","stringifyEntityRef","FavoriteEntity","toggleStarredEntity","isStarredEntity","useStarredEntity","starredEntitiesApi","useApi","starredEntitiesApiRef","setIsStarredEntity","useState","useEffect","subscription","starredEntities","useCallback","t","useTranslationRef","catalogReactTranslationRef","theme","DefaultNode","width","setWidth","height","setHeight","idRef","useRef","useLayoutEffect","renderedHeight","renderedWidth","Math","paddedWidth","padding","paddedHeight","renderDefault","Node","render","setNode","node","x","y","nodeRef","NODE_TEST_ID","ARROW_MARKER_ID","DefaultLabel","label","Edge","setEdge","edge","curve","showArrowHeads","points","labelRef","createPath","useMemo","d3Shape","d","point","isFinite","EDGE_TEST_ID","labelProps","LABEL_TEST_ID","WORKSPACE_ID","DEPENDENCY_GRAPH_SVG","DependencyGraph","edges","nodes","renderNode","direction","Types","align","nodeMargin","edgeMargin","rankMargin","paddingX","paddingY","acyclicer","ranker","labelPosition","labelOffset","edgeRanks","edgeWeight","renderEdge","renderLabel","defs","zoom","fit","allowFullscreen","svgProps","useTheme","containerWidth","setContainerWidth","containerHeight","setContainerHeight","fullScreenHandle","useFullScreenHandle","styles","coreComponentsTranslationRef","graph","dagre","graphWidth","setGraphWidth","graphHeight","setGraphHeight","graphNodes","setGraphNodes","graphEdges","setGraphEdges","maxWidth","maxHeight","_measureRef","useMeasure","measureRef","once","scalableHeight","containerRef","debounce","root","container","d3Selection","workspace","enableZoom","d3Zoom","Infinity","event","newContainerWidth","newContainerHeight","setNodesAndEdges","currentGraphNodes","currentGraphEdges","nodeId","e","existingNode","updateGraph","newHeight","FullScreen","classNames","FullscreenExitIcon","FullscreenIcon","DEFAULT_ICON","SvgIcon","EntityKindIcon","app","actualKind","otherProps","Icon","useApp","getKind","parseEntityRef","CustomNode","navigate","useNavigate","entityRoute","useRouteRef","entityRouteRef","hasKindIcon","paddedIconWidth","iconSize","displayTitle","AncestryPage","loading","error","useAncestry","catalogClient","catalogApiRef","useAsync","response","Array","current","currentRef","isRootNode","parentRef","Progress","ResponseErrorPanel","DialogContentText","Link","Box","ListItemText","MuiListItemText","ListSubheader","MuiListSubheader","Container","Card","CardContent","HelpIcon","KeyValueListItem","key","link","ListItem","ListItemIcon","HelpOutlineIcon","EntityList","List","EntityRefLink","Contents","location","originLocation","colocatedEntities","useColocated","catalogApi","currentEntityRef","ANNOTATION_LOCATION","origin","ANNOTATION_ORIGIN_LOCATION","colocated","Alert","atLocation","atOrigin","ColocatedPage","sortKeys","data","Object","a","b","JsonPage","CodeSnippet","JSON","OverviewPage","apiVersion","metadata","spec","relations","status","groupedRelations","groupBy","sortBy","r","ListItemSecondaryAction","CopyTextButton","entry","tag","index","type","groupRelations","group","item","YamlPage","YAML","TabPanel","children","other","InspectEntityDialog","tabNames","tabs","activeTab","setActiveTab","getTabIndex","Dialog","DialogTitle","DialogContent","Tabs","_","tabIndex","tab","Tab","DialogActions","Button","allTabs","initialTab","EntityLabels","ownedByRelations","getEntityRelations","RELATION_OWNED_BY","catalogTranslationRef","HeaderLabel","EntityRefLinks","UnregisterEntity","forwardRef","ref","unregisterEntityOptions","isUnregisterAllowed","onUnregisterEntity","onClose","isBoolean","isDisabled","MenuItem","CancelIcon","EntityContextMenuContext","createVersionedContext","EntityContextMenuProvider","onMenuClose","createVersionedValueMap","EntityContextMenu","UNSTABLE_extraContextMenuItems","UNSTABLE_contextMenuOptions","contextMenuItems","onInspectEntity","anchorEl","setAnchorEl","isAllowed","unregisterPermission","useEntityPermission","catalogEntityDeletePermission","alertApi","alertApiRef","copyState","copyToClipboard","useCopyToClipboard","extraItems","Divider","defaultMenuItems","BugReportIcon","window","FileCopyTwoToneIcon","MoreVert","Popover","Boolean","MenuList","headerProps","paramKind","paramNamespace","paramName","findParentRelation","entityRelations","relationTypes","foundRelation","relation","EntityHeaderTitle","useAsyncEntity","useRouteRefParams","EntityDisplayName","EntityHeaderSubtitle","parentEntityRelations","parentEntity","ancestorEntity","Breadcrumbs","EntityHeader","subtitle","entityFallbackText","useLocation","catalogRoute","rootRouteRef","unregisterRedirectRoute","unregisterRedirectRouteRef","confirmationDialogOpen","setConfirmationDialogOpen","openUnregisterEntityDialog","closeUnregisterEntityDialog","cleanUpAfterUnregisterConfirmation","searchParams","setSearchParams","useSearchParams","selectedInspectEntityDialogTab","setInspectEntityDialogTab","newTab","openInspectEntityDialog","closeInspectEntityDialog","Header","UnregisterEntityDialog","EntityTabsPanel","className","stretch","noPadding","restProps","resolveIcon","icon","iconsApi","showIcons","iconsApiRef","open","disabled","disableFocusRipple","items","fullWidth","indicator","onSelectTab","selected","textColor","wrapped","highlightedButton","groupIcon","testId","handleMenuClose","classArray","capitalize","classnames","hasIcons","i","ExpandMoreIcon","itemIcon","EntityTabsGroup","withStyles","createStyles","EntityTabsList","selectedIndex","groupDefinitions","groups","result","groupOrId","selectedItem","tabGroup","EntityTabs","routes","route","element","useSelectedSubRoute","subRoutes","params","useParams","sortedRoutes","useRoutes","currentRoute","matchedRoute","matchRoutes","foundIndex","to","Helmet","dataKey","Route","attachComponentData","EntityLayout","header","NotFoundComponent","showNavItemIcons","useElementFilter","elements","elementProps","Page","Content","WarningPanel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"static/4445.b9a2649d.chunk.js","sources":["webpack://techdocs-cli-embedded-app/../core-components/src/components/FavoriteToggle/FavoriteToggle.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityRefLink/humanize.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/types.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useStarredEntity.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DefaultNode.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/Node.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/constants.ts","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DefaultLabel.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/Edge.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/DependencyGraph/DependencyGraph.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/EntityKindIcon.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/AncestryPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/common.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/ColocatedPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/util.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/JsonPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/components/YamlPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/InspectEntityDialog/InspectEntityDialog.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityLabels/EntityLabels.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityContextMenu/UnregisterEntity.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/context/EntityContextMenuContext.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityHeader/EntityHeader.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsPanel.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsGroup.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityTabs/EntityTabs.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ComponentProps } from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport Typography from '@material-ui/core/Typography';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport { StarIcon, UnstarredIcon } from '../../icons';\n\nconst useStyles = makeStyles<Theme>(\n () => ({\n icon: {\n color: '#f3ba37',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n iconBorder: {\n color: 'inherit',\n cursor: 'pointer',\n display: 'inline-flex',\n },\n }),\n { name: 'BackstageFavoriteToggleIcon' },\n);\n\n/**\n * @public\n */\nexport type FavoriteToggleIconClassKey = 'icon' | 'iconBorder';\n\n/**\n * Icon used in FavoriteToggle component.\n *\n * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable}\n *\n * @public\n */\nexport function FavoriteToggleIcon(props: { isFavorite: boolean }) {\n const { isFavorite } = props;\n const classes = useStyles();\n\n return (\n <Typography\n component=\"span\"\n className={isFavorite ? classes.icon : classes.iconBorder}\n >\n {isFavorite ? <StarIcon /> : <UnstarredIcon />}\n </Typography>\n );\n}\n\n/**\n * Props for the {@link FavoriteToggle} component.\n *\n * @public\n */\nexport type FavoriteToggleProps = ComponentProps<typeof IconButton> & {\n id: string;\n title: string;\n isFavorite: boolean;\n onToggle: (value: boolean) => void;\n};\n\n/**\n * Toggle encapsulating logic for marking something as favorite,\n * primarily used in various instances of entity lists and cards but can be used elsewhere.\n *\n * This component can only be used in as a controlled toggle and does not keep internal state.\n *\n * @public\n */\nexport function FavoriteToggle(props: FavoriteToggleProps) {\n const {\n id,\n title,\n isFavorite: value,\n onToggle: onChange,\n ...iconButtonProps\n } = props;\n return (\n <Tooltip id={id} title={title}>\n <IconButton\n aria-label={title}\n id={id}\n onClick={() => onChange(!value)}\n color=\"inherit\"\n {...iconButtonProps}\n >\n <FavoriteToggleIcon isFavorite={value} />\n </IconButton>\n </Tooltip>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\nimport get from 'lodash/get';\n\n/**\n * @param defaultNamespace - if set to false then namespace is never omitted,\n * if set to string which matches namespace of entity then omitted\n *\n * @public\n **/\nexport function humanizeEntityRef(\n entityRef: Entity | CompoundEntityRef,\n opts?: {\n defaultKind?: string;\n defaultNamespace?: string | false;\n },\n) {\n const defaultKind = opts?.defaultKind;\n let kind;\n let namespace;\n let name;\n\n if ('metadata' in entityRef) {\n kind = entityRef.kind;\n namespace = entityRef.metadata.namespace;\n name = entityRef.metadata.name;\n } else {\n kind = entityRef.kind;\n namespace = entityRef.namespace;\n name = entityRef.name;\n }\n\n if (namespace === undefined || namespace === '') {\n namespace = DEFAULT_NAMESPACE;\n }\n if (opts?.defaultNamespace !== undefined) {\n if (opts?.defaultNamespace === namespace) {\n namespace = undefined;\n }\n } else if (namespace === DEFAULT_NAMESPACE) {\n namespace = undefined;\n }\n\n kind = kind.toLocaleLowerCase('en-US');\n kind =\n defaultKind && defaultKind.toLocaleLowerCase('en-US') === kind\n ? undefined\n : kind;\n return `${kind ? `${kind}:` : ''}${namespace ? `${namespace}/` : ''}${name}`;\n}\n\n/**\n * Convert an entity to its more readable name if available.\n *\n * If an entity is either User or Group, this will be its `spec.profile.displayName`.\n * Otherwise, this is `metadata.title`.\n *\n * If neither of those are found or populated, fallback to `defaultName`.\n *\n * @param entity - Entity to convert.\n * @param defaultName - If entity readable name is not available, `defaultName` will be returned.\n * @returns Readable name, defaults to `defaultName`.\n *\n */\nexport function humanizeEntity(entity: Entity, defaultName: string) {\n for (const path of ['spec.profile.displayName', 'metadata.title']) {\n const value = get(entity, path);\n if (value && typeof value === 'string') {\n return value;\n }\n }\n return defaultName;\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* We want to maintain the same information as an enum, so we disable the redeclaration warning */\n/* eslint-disable @typescript-eslint/no-redeclare */\n\n/**\n * Types used to customize and provide data to {@link DependencyGraph}\n *\n * @packageDocumentation\n */\n\nimport { ReactNode } from 'react';\n\n/**\n * Types for the {@link DependencyGraph} component.\n *\n * @public\n */\nexport namespace DependencyGraphTypes {\n /**\n * Edge of {@link DependencyGraph}\n *\n * @public\n */\n export type DependencyEdge<T = {}> = T & {\n /**\n * ID of {@link DependencyNode} from where the Edge start\n */\n from: string;\n /**\n * ID of {@link DependencyNode} to where the Edge goes to\n */\n to: string;\n /**\n * Label assigned and rendered with the Edge\n */\n label?: string;\n /**\n * Distance to a root entity\n */\n distance?: number;\n };\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderLabelFunction} for {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderLabelProps<T = unknown> = { edge: DependencyEdge<T> };\n\n /**\n * Custom React component for edge labels\n *\n * @public\n */\n export type RenderLabelFunction<T = {}> = (\n props: RenderLabelProps<T>,\n ) => ReactNode;\n\n /**\n * Node of {@link DependencyGraph}\n *\n * @public\n */\n export type DependencyNode<T = {}> = T & {\n id: string;\n };\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderNodeFunction} for {@link DependencyGraphTypes.DependencyNode}\n *\n * @public\n */\n export type RenderNodeProps<T = unknown> = { node: DependencyNode<T> };\n\n /**\n * Custom React component for graph {@link DependencyGraphTypes.DependencyNode}\n *\n * @public\n */\n export type RenderNodeFunction<T = {}> = (\n props: RenderNodeProps<T>,\n ) => ReactNode;\n\n /**\n * Properties of {@link DependencyGraphTypes.RenderEdgeFunction} for {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderEdgeProps<T = {}> = {\n edge: T & {\n points: { x: number; y: number }[];\n label?: string;\n labeloffset?: number;\n labelpos?: string;\n width?: number;\n height?: number;\n weight?: number;\n minlen?: number;\n showArrowHeads?: boolean;\n from?: string;\n to?: string;\n relations?: string[];\n };\n id: {\n v: string;\n w: string;\n name?: string | undefined;\n };\n };\n\n /**\n * Custom React component for graph {@link DependencyGraphTypes.DependencyEdge}\n *\n * @public\n */\n export type RenderEdgeFunction<T = {}> = (\n props: RenderEdgeProps<T>,\n ) => ReactNode;\n\n /**\n * Graph direction\n *\n * @public\n */\n export const Direction = {\n /**\n * Top to Bottom\n */\n TOP_BOTTOM: 'TB',\n /**\n * Bottom to Top\n */\n BOTTOM_TOP: 'BT',\n /**\n * Left to Right\n */\n LEFT_RIGHT: 'LR',\n /**\n * Right to Left\n */\n RIGHT_LEFT: 'RL',\n } as const;\n\n /**\n * @public\n */\n export type Direction = (typeof Direction)[keyof typeof Direction];\n\n /**\n * @public\n */\n export namespace Direction {\n export type TOP_BOTTOM = typeof Direction.TOP_BOTTOM;\n export type BOTTOM_TOP = typeof Direction.BOTTOM_TOP;\n export type LEFT_RIGHT = typeof Direction.LEFT_RIGHT;\n export type RIGHT_LEFT = typeof Direction.RIGHT_LEFT;\n }\n\n /**\n * Node alignment\n *\n * @public\n */\n export const Alignment = {\n /**\n * Up Left\n */\n UP_LEFT: 'UL',\n /**\n * Up Right\n */\n UP_RIGHT: 'UR',\n /**\n * Down Left\n */\n DOWN_LEFT: 'DL',\n /**\n * Down Right\n */\n DOWN_RIGHT: 'DR',\n } as const;\n\n /**\n * @public\n */\n export type Alignment = (typeof Alignment)[keyof typeof Alignment];\n\n /**\n * @public\n */\n export namespace Alignment {\n export type UP_LEFT = typeof Alignment.UP_LEFT;\n export type UP_RIGHT = typeof Alignment.UP_RIGHT;\n export type DOWN_LEFT = typeof Alignment.DOWN_LEFT;\n export type DOWN_RIGHT = typeof Alignment.DOWN_RIGHT;\n }\n\n /**\n * Algorithm used to rand nodes in graph\n *\n * @public\n */\n export const Ranker = {\n /**\n * {@link https://en.wikipedia.org/wiki/Network_simplex_algorithm | Network Simplex} algorithm\n */\n NETWORK_SIMPLEX: 'network-simplex',\n /**\n * Tight Tree algorithm\n */\n TIGHT_TREE: 'tight-tree',\n /**\n * Longest path algorithm\n *\n * @remarks\n *\n * Simplest and fastest\n */\n LONGEST_PATH: 'longest-path',\n } as const;\n\n /**\n * @public\n */\n export type Ranker = (typeof Ranker)[keyof typeof Ranker];\n\n /**\n * @public\n */\n export namespace Ranker {\n export type NETWORK_SIMPLEX = typeof Ranker.NETWORK_SIMPLEX;\n export type TIGHT_TREE = typeof Ranker.TIGHT_TREE;\n export type LONGEST_PATH = typeof Ranker.LONGEST_PATH;\n }\n\n /**\n * Position of label in relation to the edge\n *\n * @public\n */\n export const LabelPosition = {\n LEFT: 'l',\n RIGHT: 'r',\n CENTER: 'c',\n } as const;\n\n /**\n * @public\n */\n export type LabelPosition =\n (typeof LabelPosition)[keyof typeof LabelPosition];\n\n /**\n * @public\n */\n export namespace LabelPosition {\n export type LEFT = typeof LabelPosition.LEFT;\n export type RIGHT = typeof LabelPosition.RIGHT;\n export type CENTER = typeof LabelPosition.CENTER;\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n CompoundEntityRef,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useCallback, useEffect, useState } from 'react';\nimport { starredEntitiesApiRef } from '../apis';\n\nfunction getEntityRef(\n entityOrRef: Entity | CompoundEntityRef | string,\n): string {\n return typeof entityOrRef === 'string'\n ? entityOrRef\n : stringifyEntityRef(entityOrRef);\n}\n\n/** @public */\nexport function useStarredEntity(\n entityOrRef: Entity | CompoundEntityRef | string,\n): {\n toggleStarredEntity: () => void;\n isStarredEntity: boolean;\n} {\n const starredEntitiesApi = useApi(starredEntitiesApiRef);\n\n const [isStarredEntity, setIsStarredEntity] = useState(false);\n\n useEffect(() => {\n const subscription = starredEntitiesApi.starredEntitie$().subscribe({\n next(starredEntities: Set<string>) {\n setIsStarredEntity(starredEntities.has(getEntityRef(entityOrRef)));\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [entityOrRef, starredEntitiesApi]);\n\n const toggleStarredEntity = useCallback(\n () => starredEntitiesApi.toggleStarred(getEntityRef(entityOrRef)).then(),\n [entityOrRef, starredEntitiesApi],\n );\n\n return {\n toggleStarredEntity,\n isStarredEntity,\n };\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity, stringifyEntityRef } from '@backstage/catalog-model';\nimport IconButton from '@material-ui/core/IconButton';\nimport { ComponentProps } from 'react';\nimport { useStarredEntity } from '../../hooks/useStarredEntity';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { FavoriteToggle } from '@backstage/core-components';\n\n/** @public */\nexport type FavoriteEntityProps = ComponentProps<typeof IconButton> & {\n entity: Entity;\n};\n\n/**\n * IconButton for showing if a current entity is starred and adding/removing it from the favorite entities\n * @param props - MaterialUI IconButton props extended by required `entity` prop\n * @public\n */\nexport const FavoriteEntity = (props: FavoriteEntityProps) => {\n const { toggleStarredEntity, isStarredEntity } = useStarredEntity(\n props.entity,\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n const title = isStarredEntity\n ? t('favoriteEntity.removeFromFavorites')\n : t('favoriteEntity.addToFavorites');\n\n const id = `favorite-${stringifyEntityRef(props.entity).replace(\n /[^a-zA-Z0-9-_]/g,\n '-',\n )}`;\n\n return (\n <FavoriteToggle\n title={title}\n id={id}\n isFavorite={isStarredEntity}\n onToggle={toggleStarredEntity}\n {...props}\n />\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState, useRef, useLayoutEffect } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { DependencyGraphTypes as Types } from './types';\n\n/** @public */\nexport type DependencyGraphDefaultNodeClassKey = 'node' | 'text';\n\nconst useStyles = makeStyles(\n theme => ({\n node: {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n text: {\n fill: theme.palette.primary.contrastText,\n },\n }),\n { name: 'BackstageDependencyGraphDefaultNode' },\n);\n\n/** @public */\nexport function DefaultNode({ node: { id } }: Types.RenderNodeProps) {\n const classes = useStyles();\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const padding = 10;\n const paddedWidth = width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n return (\n <g>\n <rect\n className={classes.node}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n <text\n ref={idRef}\n className={classes.text}\n y={paddedHeight / 2}\n x={paddedWidth / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {id}\n </text>\n </g>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useLayoutEffect } from 'react';\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DefaultNode } from './DefaultNode';\nimport { DependencyGraphTypes as Types } from './types';\nimport { NODE_TEST_ID } from './constants';\nimport dagre from '@dagrejs/dagre';\n\n/** @public */\nexport type DependencyGraphNodeClassKey = 'node';\n\nconst useStyles = makeStyles(\n theme => ({\n node: {\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n }),\n { name: 'BackstageDependencyGraphNode' },\n);\n\nexport type GraphNode<T> = dagre.Node<Types.DependencyNode<T>>;\n\nexport type NodeComponentProps<T> = {\n node: GraphNode<T>;\n render?: Types.RenderNodeFunction<T>;\n setNode: dagre.graphlib.Graph['setNode'];\n};\n\nconst renderDefault = (props: Types.RenderNodeProps) => (\n <DefaultNode {...props} />\n);\n\nexport function Node<T>({\n render = renderDefault,\n setNode,\n node,\n}: NodeComponentProps<T>) {\n const { width, height, x = 0, y = 0 } = node;\n const nodeProps: Types.DependencyNode<T> = node;\n const classes = useStyles();\n const nodeRef = useRef<SVGGElement | null>(null);\n\n useLayoutEffect(() => {\n // set the node width to the actual rendered width to properly layout graph\n if (nodeRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n nodeRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setNode(node.id, {\n ...node,\n height: renderedHeight,\n width: renderedWidth,\n });\n }\n }\n }, [node, width, height, setNode]);\n\n return (\n <g\n ref={nodeRef}\n data-testid={NODE_TEST_ID}\n className={classes.node}\n transform={`translate(${x - width / 2},${y - height / 2})`}\n >\n {render({ node: nodeProps })}\n </g>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const ARROW_MARKER_ID = 'arrow-marker';\n\nexport const NODE_TEST_ID = 'node';\nexport const EDGE_TEST_ID = 'edge';\nexport const LABEL_TEST_ID = 'label';\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DependencyGraphTypes as Types } from './types';\n\n/** @public */\nexport type DependencyGraphDefaultLabelClassKey = 'text';\n\nconst useStyles = makeStyles(\n theme => ({\n text: {\n fill: theme.palette.textContrast,\n },\n }),\n { name: 'BackstageDependencyGraphDefaultLabel' },\n);\n\n/** @public */\nexport function DefaultLabel({ edge: { label } }: Types.RenderLabelProps) {\n const classes = useStyles();\n return (\n <text className={classes.text} textAnchor=\"middle\">\n {label}\n </text>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useRef, useLayoutEffect, useMemo } from 'react';\nimport * as d3Shape from 'd3-shape';\nimport isFinite from 'lodash/isFinite';\nimport makeStyles from '@material-ui/core/styles/makeStyles';\nimport { DependencyGraphTypes as Types } from './types';\nimport { ARROW_MARKER_ID, EDGE_TEST_ID, LABEL_TEST_ID } from './constants';\nimport { DefaultLabel } from './DefaultLabel';\nimport dagre from '@dagrejs/dagre';\n\n/* Based on: https://github.com/dagrejs/dagre/wiki#configuring-the-layout */\nexport type EdgeProperties = {\n label?: string;\n width?: number;\n height?: number;\n labeloffset?: number;\n labelpos?: Types.LabelPosition;\n minlen?: number;\n weight?: number;\n};\nexport type GraphEdge<T> = Types.DependencyEdge<T> &\n dagre.GraphEdge &\n EdgeProperties;\n\n/** @public */\nexport type DependencyGraphEdgeClassKey = 'path' | 'label';\n\nconst useStyles = makeStyles(\n theme => ({\n path: {\n strokeWidth: 1.3,\n stroke: theme.palette.textSubtle,\n fill: 'none',\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n label: {\n transition: `${theme.transitions.duration.shortest}ms`,\n },\n }),\n { name: 'BackstageDependencyGraphEdge' },\n);\n\ntype EdgePoint = dagre.GraphEdge['points'][0];\n\n/** @public */\nexport type EdgeComponentProps<T = unknown> = {\n id: dagre.Edge;\n edge: GraphEdge<T>;\n render?: Types.RenderLabelFunction<T>;\n setEdge: (\n id: dagre.Edge,\n edge: Types.DependencyEdge<T>,\n ) => dagre.graphlib.Graph<{}>;\n curve: 'curveStepBefore' | 'curveMonotoneX';\n showArrowHeads?: boolean;\n};\n\nconst renderDefault = (props: Types.RenderLabelProps<unknown>) => (\n <DefaultLabel {...props} />\n);\n\nexport function Edge<EdgeData>({\n render = renderDefault,\n setEdge,\n id,\n edge,\n curve,\n showArrowHeads,\n}: EdgeComponentProps<EdgeData>) {\n const { x = 0, y = 0, width, height, points } = edge;\n const labelProps: Types.DependencyEdge<EdgeData> = edge;\n const classes = useStyles();\n\n const labelRef = useRef<SVGGElement>(null);\n\n useLayoutEffect(() => {\n // set the label width to the actual rendered width to properly layout graph\n if (labelRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n labelRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n\n if (renderedHeight !== height || renderedWidth !== width) {\n setEdge(id, {\n ...edge,\n height: renderedHeight,\n width: renderedWidth,\n });\n }\n }\n }, [edge, height, width, setEdge, id]);\n\n let path: string = '';\n\n const createPath = useMemo(\n () =>\n d3Shape\n .line<EdgePoint>()\n .x(d => d.x)\n .y(d => d.y)\n .curve(d3Shape[curve]),\n [curve],\n );\n\n if (points) {\n const finitePoints = points.filter(\n (point: EdgePoint) => isFinite(point.x) && isFinite(point.y),\n );\n path = createPath(finitePoints) || '';\n }\n\n return (\n <>\n {path && (\n <path\n data-testid={EDGE_TEST_ID}\n className={classes.path}\n markerEnd={showArrowHeads ? `url(#${ARROW_MARKER_ID})` : undefined}\n d={path}\n />\n )}\n {labelProps.label ? (\n <g\n ref={labelRef}\n data-testid={LABEL_TEST_ID}\n className={classes.label}\n transform={`translate(${x},${y})`}\n >\n {render({ edge: labelProps })}\n </g>\n ) : null}\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport classNames from 'classnames';\nimport { once } from 'lodash';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n fullscreenButton: {\n position: 'absolute',\n right: 0,\n },\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fixedHeight: {\n maxHeight: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.(Direction:namespace) | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.(Alignment:namespace) | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.(Ranker:namespace) | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.(LabelPosition:namespace) | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom edge rendering component\n */\n renderEdge?: Types.RenderEdgeFunction<EdgeData>;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderEdge,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n\n const [_measureRef] = useMeasure();\n const measureRef = once(_measureRef);\n\n const scalableHeight =\n fit === 'grow' && !fullScreenHandle.active ? maxHeight : '100%';\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n measureRef(root);\n\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (\n containerWidth !== newContainerWidth &&\n newContainerWidth <= maxWidth\n ) {\n setContainerWidth(newContainerWidth);\n }\n if (\n containerHeight !== newContainerHeight &&\n newContainerHeight <= maxHeight\n ) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n const setNode = useCallback(\n (id: string, node: Types.DependencyNode<NodeData>) => {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n const setEdge = useCallback(\n (id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) => {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n return (\n <FullScreen\n handle={fullScreenHandle}\n className={classNames(\n fullScreenHandle.active ? styles.fullscreen : styles.root,\n )}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n className={styles.fullscreenButton}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <div ref={containerRef} style={{ width: '100%', height: '100%' }}>\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n if (renderEdge) return renderEdge({ edge, id: e });\n\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </div>\n </FullScreen>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { useApp } from '@backstage/core-plugin-api';\nimport SvgIcon from '@material-ui/core/SvgIcon';\n\nconst DEFAULT_ICON = SvgIcon;\n\nfunction getKind(\n kind: string | undefined,\n entityRef: string | undefined,\n): string | undefined {\n if (kind) {\n return kind.toLocaleLowerCase('en-US');\n }\n\n if (entityRef) {\n try {\n return parseEntityRef(entityRef).kind.toLocaleLowerCase('en-US');\n } catch {\n return undefined;\n }\n }\n\n return undefined;\n}\n\nfunction useIcon(kind: string | undefined, entityRef: string | undefined) {\n const app = useApp();\n\n const actualKind = getKind(kind, entityRef);\n if (!actualKind) {\n return DEFAULT_ICON;\n }\n\n const icon = app.getSystemIcon(`kind:${actualKind}`);\n return icon || DEFAULT_ICON;\n}\n\nexport function EntityKindIcon(props: {\n kind?: string;\n entityRef?: string;\n x?: number;\n y?: number;\n width?: number;\n height?: number;\n className?: string;\n}) {\n const { kind, entityRef, ...otherProps } = props;\n const Icon = useIcon(kind, entityRef);\n return <Icon {...otherProps} />;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n DEFAULT_NAMESPACE,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n DependencyGraph,\n DependencyGraphTypes,\n Link,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { useApi, useApp, useRouteRef } from '@backstage/core-plugin-api';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { makeStyles } from '@material-ui/core/styles';\nimport classNames from 'classnames';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { humanizeEntityRef } from '../../EntityRefLink';\nimport { entityRouteRef } from '../../../routes';\nimport { EntityKindIcon } from './EntityKindIcon';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n node: {\n fill: theme.palette.grey[300],\n stroke: theme.palette.grey[300],\n '&.primary': {\n fill: theme.palette.primary.light,\n stroke: theme.palette.primary.light,\n },\n '&.secondary': {\n fill: theme.palette.secondary.light,\n stroke: theme.palette.secondary.light,\n },\n },\n text: {\n fill: theme.palette.getContrastText(theme.palette.grey[300]),\n '&.primary': {\n fill: theme.palette.primary.contrastText,\n },\n '&.secondary': {\n fill: theme.palette.secondary.contrastText,\n },\n '&.focused': {\n fontWeight: 'bold',\n },\n },\n clickable: {\n cursor: 'pointer',\n },\n}));\n\ntype NodeType = Entity & { root: boolean };\n\nfunction useAncestry(root: Entity): {\n loading: boolean;\n error?: Error;\n nodes: DependencyGraphTypes.DependencyNode<NodeType>[];\n edges: DependencyGraphTypes.DependencyEdge[];\n} {\n const catalogClient = useApi(catalogApiRef);\n const entityRef = stringifyEntityRef(root);\n\n const { loading, error, value } = useAsync(async () => {\n const response = await catalogClient.getEntityAncestors({ entityRef });\n const nodes = new Array<DependencyGraphTypes.DependencyNode<NodeType>>();\n const edges = new Array<DependencyGraphTypes.DependencyEdge>();\n for (const current of response.items) {\n const currentRef = stringifyEntityRef(current.entity);\n const isRootNode = currentRef === response.rootEntityRef;\n nodes.push({ id: currentRef, root: isRootNode, ...current.entity });\n for (const parentRef of current.parentEntityRefs) {\n edges.push({ from: currentRef, to: parentRef });\n }\n }\n return { nodes, edges };\n }, [entityRef]);\n\n return {\n loading,\n error,\n nodes: value?.nodes || [],\n edges: value?.edges || [],\n };\n}\n\nfunction CustomNode({ node }: DependencyGraphTypes.RenderNodeProps<NodeType>) {\n const classes = useStyles();\n const navigate = useNavigate();\n const entityRoute = useRouteRef(entityRouteRef);\n const [width, setWidth] = useState(0);\n const [height, setHeight] = useState(0);\n const app = useApp();\n const idRef = useRef<SVGTextElement | null>(null);\n\n useLayoutEffect(() => {\n // set the width to the length of the ID\n if (idRef.current) {\n let { height: renderedHeight, width: renderedWidth } =\n idRef.current.getBBox();\n renderedHeight = Math.round(renderedHeight);\n renderedWidth = Math.round(renderedWidth);\n if (renderedHeight !== height || renderedWidth !== width) {\n setWidth(renderedWidth);\n setHeight(renderedHeight);\n }\n }\n }, [width, height]);\n\n const hasKindIcon = app.getSystemIcon(\n `kind:${node.kind.toLocaleLowerCase('en-US')}`,\n );\n const padding = 10;\n const iconSize = height;\n const paddedIconWidth = hasKindIcon ? iconSize + padding : 0;\n const paddedWidth = paddedIconWidth + width + padding * 2;\n const paddedHeight = height + padding * 2;\n\n const displayTitle =\n node.metadata.title ||\n (node.kind && node.metadata.name && node.metadata.namespace\n ? humanizeEntityRef({\n kind: node.kind,\n name: node.metadata.name,\n namespace: node.metadata.namespace || '',\n })\n : node.id);\n\n const onClick = () => {\n navigate(\n entityRoute({\n kind: node.kind,\n namespace: node.metadata.namespace || DEFAULT_NAMESPACE,\n name: node.metadata.name,\n }),\n );\n };\n\n return (\n <g onClick={onClick} className={classes.clickable}>\n <rect\n className={classNames(\n classes.node,\n node.root ? 'secondary' : 'primary',\n )}\n width={paddedWidth}\n height={paddedHeight}\n rx={10}\n />\n {hasKindIcon && (\n <EntityKindIcon\n kind={node.kind}\n y={padding}\n x={padding}\n width={iconSize}\n height={iconSize}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n />\n )}\n <text\n ref={idRef}\n className={classNames(\n classes.text,\n node.root ? 'secondary' : 'primary',\n )}\n y={paddedHeight / 2}\n x={paddedIconWidth + (width + padding * 2) / 2}\n textAnchor=\"middle\"\n alignmentBaseline=\"middle\"\n >\n {displayTitle}\n </text>\n </g>\n );\n}\n\nexport function AncestryPage(props: { entity: Entity }) {\n const { loading, error, nodes, edges } = useAncestry(props.entity);\n const { t } = useTranslationRef(catalogReactTranslationRef);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.ancestryPage.title')}\n </DialogContentText>\n <DialogContentText gutterBottom>\n {t('inspectEntityDialog.ancestryPage.description', {\n processorsLink: (\n <Link to=\"https://backstage.io/docs/features/software-catalog/life-of-an-entity\">\n {t('inspectEntityDialog.ancestryPage.processorsLink')}\n </Link>\n ),\n })}\n </DialogContentText>\n <Box mt={4}>\n <DependencyGraph\n nodes={nodes}\n edges={edges}\n renderNode={CustomNode}\n direction={DependencyGraphTypes.Direction.BOTTOM_TOP}\n zoom=\"enable-on-click\"\n />\n </Box>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Link } from '@backstage/core-components';\nimport Box from '@material-ui/core/Box';\nimport Card from '@material-ui/core/Card';\nimport CardContent from '@material-ui/core/CardContent';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport MuiListItemText from '@material-ui/core/ListItemText';\nimport MuiListSubheader from '@material-ui/core/ListSubheader';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport HelpOutlineIcon from '@material-ui/icons/HelpOutline';\nimport { ReactNode } from 'react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n marginTop: {\n marginTop: theme.spacing(2),\n },\n helpIcon: {\n marginLeft: theme.spacing(1),\n color: theme.palette.text.disabled,\n },\n monospace: {\n fontFamily: 'monospace',\n },\n}));\n\nexport function ListItemText(props: {\n primary: ReactNode;\n secondary?: ReactNode;\n}) {\n const classes = useStyles();\n return (\n <MuiListItemText\n {...props}\n primaryTypographyProps={{ className: classes.monospace }}\n secondaryTypographyProps={{ className: classes.monospace }}\n />\n );\n}\n\nexport function ListSubheader(props: { children?: ReactNode }) {\n const classes = useStyles();\n return (\n <MuiListSubheader className={classes.monospace}>\n {props.children}\n </MuiListSubheader>\n );\n}\n\nexport function Container(props: {\n title: ReactNode;\n helpLink?: string;\n children: ReactNode;\n}) {\n return (\n <Box mt={2}>\n <Card variant=\"outlined\">\n <CardContent>\n <Typography variant=\"h6\" gutterBottom>\n {props.title}\n {props.helpLink && <HelpIcon to={props.helpLink} />}\n </Typography>\n {props.children}\n </CardContent>\n </Card>\n </Box>\n );\n}\n\n// Extracts a link from a value, if possible\nfunction findLink(value: string): string | undefined {\n if (value.match(/^url:https?:\\/\\//)) {\n return value.slice('url:'.length);\n }\n if (value.match(/^https?:\\/\\//)) {\n return value;\n }\n return undefined;\n}\n\nexport function KeyValueListItem(props: {\n indent?: boolean;\n entry: [string, string];\n}) {\n const [key, value] = props.entry;\n const link = findLink(value);\n\n return (\n <ListItem>\n {props.indent && <ListItemIcon />}\n <ListItemText\n primary={key}\n secondary={link ? <Link to={link}>{value}</Link> : value}\n />\n </ListItem>\n );\n}\n\nexport function HelpIcon(props: { to: string }) {\n const classes = useStyles();\n return (\n <Link to={props.to} className={classes.helpIcon}>\n <HelpOutlineIcon fontSize=\"inherit\" />\n </Link>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Entity,\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport { Progress, ResponseErrorPanel } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport { makeStyles } from '@material-ui/core/styles';\nimport Alert from '@material-ui/lab/Alert';\nimport useAsync from 'react-use/esm/useAsync';\nimport { catalogApiRef } from '../../../api';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport { KeyValueListItem, ListItemText } from './common';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nfunction useColocated(entity: Entity): {\n loading: boolean;\n error?: Error;\n location?: string;\n originLocation?: string;\n colocatedEntities?: Entity[];\n} {\n const catalogApi = useApi(catalogApiRef);\n const currentEntityRef = stringifyEntityRef(entity);\n const location = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n const origin = entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n\n const { loading, error, value } = useAsync(async () => {\n if (!location && !origin) {\n return [];\n }\n const response = await catalogApi.getEntities({\n filter: [\n ...(location\n ? [{ [`metadata.annotations.${ANNOTATION_LOCATION}`]: location }]\n : []),\n ...(origin\n ? [{ [`metadata.annotations.${ANNOTATION_ORIGIN_LOCATION}`]: origin }]\n : []),\n ],\n });\n return response.items;\n }, [location, origin]);\n\n return {\n loading,\n error,\n location,\n originLocation: origin,\n colocatedEntities: value?.filter(\n colocated => stringifyEntityRef(colocated) !== currentEntityRef,\n ),\n };\n}\n\nfunction EntityList(props: { entities: Entity[]; header?: [string, string] }) {\n return (\n <List dense>\n {props.header && <KeyValueListItem key=\"header\" entry={props.header} />}\n {props.entities.map(entity => (\n <ListItem key={stringifyEntityRef(entity)}>\n <ListItemText primary={<EntityRefLink entityRef={entity} />} />\n </ListItem>\n ))}\n </List>\n );\n}\n\nfunction Contents(props: { entity: Entity }) {\n const { entity } = props;\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const { loading, error, location, originLocation, colocatedEntities } =\n useColocated(entity);\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <ResponseErrorPanel error={error} />;\n }\n\n if (!location && !originLocation) {\n return (\n <Alert severity=\"warning\">\n {t('inspectEntityDialog.colocatedPage.alertNoLocation')}\n </Alert>\n );\n } else if (!colocatedEntities?.length) {\n return (\n <Alert severity=\"info\">\n {t('inspectEntityDialog.colocatedPage.alertNoEntity')}\n </Alert>\n );\n }\n\n if (location === originLocation) {\n return <EntityList entities={colocatedEntities} />;\n }\n\n const atLocation = colocatedEntities.filter(\n e => e.metadata.annotations?.[ANNOTATION_LOCATION] === location,\n );\n const atOrigin = colocatedEntities.filter(\n e =>\n e.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION] === originLocation,\n );\n\n return (\n <>\n {atLocation.length > 0 && (\n <EntityList\n entities={atLocation}\n header={[\n t('inspectEntityDialog.colocatedPage.locationHeader'),\n location!,\n ]}\n />\n )}\n {atOrigin.length > 0 && (\n <EntityList\n entities={atOrigin}\n header={[\n t('inspectEntityDialog.colocatedPage.originHeader'),\n originLocation!,\n ]}\n />\n )}\n </>\n );\n}\n\nexport function ColocatedPage(props: { entity: Entity }) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.colocatedPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.colocatedPage.description')}\n </DialogContentText>\n <div className={classes.root}>\n <Contents entity={props.entity} />\n </div>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JsonObject } from '@backstage/types';\n\nexport function sortKeys(data: JsonObject): JsonObject {\n // we could do something custom, but lexicographical sorting is actually a\n // good choice at least for the default set of keys\n return Object.fromEntries(\n [...Object.entries(data)].sort((a, b) => (a[0] < b[0] ? -1 : 1)),\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { CodeSnippet } from '@backstage/core-components';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { sortKeys } from './util';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport function JsonPage(props: { entity: Entity }) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.jsonPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.jsonPage.description')}\n </DialogContentText>\n <DialogContentText>\n <div style={{ fontSize: '75%' }} data-testid=\"code-snippet\">\n <CodeSnippet\n text={JSON.stringify(sortKeys(props.entity), undefined, 2)}\n language=\"json\"\n showCopyCodeButton\n />\n </div>\n </DialogContentText>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AlphaEntity } from '@backstage/catalog-model/alpha';\nimport Box from '@material-ui/core/Box';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport List from '@material-ui/core/List';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemSecondaryAction from '@material-ui/core/ListItemSecondaryAction';\nimport Typography from '@material-ui/core/Typography';\nimport { makeStyles } from '@material-ui/core/styles';\nimport groupBy from 'lodash/groupBy';\nimport sortBy from 'lodash/sortBy';\nimport { EntityRefLink } from '../../EntityRefLink';\nimport {\n Container,\n HelpIcon,\n KeyValueListItem,\n ListItemText,\n ListSubheader,\n} from './common';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { CopyTextButton } from '@backstage/core-components';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles({\n root: {\n display: 'flex',\n flexDirection: 'column',\n },\n});\n\nexport function OverviewPage(props: { entity: AlphaEntity }) {\n const classes = useStyles();\n const {\n apiVersion,\n kind,\n metadata,\n spec,\n relations = [],\n status = {},\n } = props.entity;\n\n const groupedRelations = groupBy(\n sortBy(relations, r => r.targetRef),\n 'type',\n );\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const entityRef = stringifyEntityRef(props.entity);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.overviewPage.title')}\n </DialogContentText>\n <div className={classes.root}>\n <Container title={t('inspectEntityDialog.overviewPage.identity.title')}>\n <List dense>\n <ListItem>\n <ListItemText primary=\"apiVersion\" secondary={apiVersion} />\n </ListItem>\n <ListItem>\n <ListItemText primary=\"kind\" secondary={kind} />\n </ListItem>\n {spec?.type && (\n <ListItem>\n <ListItemText\n primary=\"spec.type\"\n secondary={spec.type?.toString()}\n />\n </ListItem>\n )}\n {metadata.uid && (\n <ListItem>\n <ListItemText primary=\"uid\" secondary={metadata.uid} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.uid} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n {metadata.etag && (\n <ListItem>\n <ListItemText primary=\"etag\" secondary={metadata.etag} />\n <ListItemSecondaryAction>\n <CopyTextButton text={metadata.etag} />\n </ListItemSecondaryAction>\n </ListItem>\n )}\n <ListItem>\n <ListItemText primary=\"entityRef\" secondary={entityRef} />\n <ListItemSecondaryAction>\n <CopyTextButton text={entityRef} />\n </ListItemSecondaryAction>\n </ListItem>\n </List>\n </Container>\n\n <Container title={t('inspectEntityDialog.overviewPage.metadata.title')}>\n {!!Object.keys(metadata.annotations || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.annotations')}\n <HelpIcon to=\"https://backstage.io/docs/features/software-catalog/well-known-annotations\" />\n </ListSubheader>\n }\n >\n {Object.entries(metadata.annotations!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!Object.keys(metadata.labels || {}).length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.labels')}\n </ListSubheader>\n }\n >\n {Object.entries(metadata.labels!).map(entry => (\n <KeyValueListItem key={entry[0]} indent entry={entry} />\n ))}\n </List>\n )}\n {!!metadata.tags?.length && (\n <List\n dense\n subheader={\n <ListSubheader>\n {t('inspectEntityDialog.overviewPage.tags')}\n </ListSubheader>\n }\n >\n {metadata.tags.map((tag, index) => (\n <ListItem key={`${tag}-${index}`}>\n <ListItemIcon />\n <ListItemText primary={tag} />\n </ListItem>\n ))}\n </List>\n )}\n </Container>\n\n {!!relations.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.relation.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-relations\"\n >\n {Object.entries(groupedRelations).map(\n ([type, groupRelations], index) => (\n <div key={index}>\n <List dense subheader={<ListSubheader>{type}</ListSubheader>}>\n {groupRelations.map(group => (\n <ListItem key={group.targetRef}>\n <ListItemText\n primary={\n <EntityRefLink entityRef={group.targetRef} />\n }\n />\n </ListItem>\n ))}\n </List>\n </div>\n ),\n )}\n </Container>\n )}\n\n {!!status.items?.length && (\n <Container\n title={t('inspectEntityDialog.overviewPage.status.title')}\n helpLink=\"https://backstage.io/docs/features/software-catalog/well-known-statuses\"\n >\n {status.items.map((item, index) => (\n <div key={index}>\n <Typography>\n {item.level}: {item.type}\n </Typography>\n <Box ml={2}>{item.message}</Box>\n </div>\n ))}\n </Container>\n )}\n </div>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport { CodeSnippet } from '@backstage/core-components';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport YAML from 'yaml';\nimport { sortKeys } from './util';\nimport { catalogReactTranslationRef } from '../../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nexport function YamlPage(props: { entity: Entity }) {\n const { t } = useTranslationRef(catalogReactTranslationRef);\n return (\n <>\n <DialogContentText variant=\"h2\">\n {t('inspectEntityDialog.yamlPage.title')}\n </DialogContentText>\n <DialogContentText>\n {t('inspectEntityDialog.yamlPage.description')}\n </DialogContentText>\n <DialogContentText>\n <div style={{ fontSize: '75%' }} data-testid=\"code-snippet\">\n <CodeSnippet\n text={YAML.stringify(sortKeys(props.entity))}\n language=\"yaml\"\n showCopyCodeButton\n />\n </div>\n </DialogContentText>\n </>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Entity } from '@backstage/catalog-model';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { ComponentProps, useEffect, useState, ReactNode, useMemo } from 'react';\nimport { AncestryPage } from './components/AncestryPage';\nimport { ColocatedPage } from './components/ColocatedPage';\nimport { JsonPage } from './components/JsonPage';\nimport { OverviewPage } from './components/OverviewPage';\nimport { YamlPage } from './components/YamlPage';\nimport { catalogReactTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\nconst useStyles = makeStyles(theme => ({\n fullHeightDialog: {\n height: 'calc(100% - 64px)',\n },\n root: {\n display: 'flex',\n flexGrow: 1,\n width: '100%',\n backgroundColor: theme.palette.background.paper,\n },\n tabs: {\n borderRight: `1px solid ${theme.palette.divider}`,\n flexShrink: 0,\n },\n tabContents: {\n flexGrow: 1,\n overflowX: 'auto',\n },\n}));\n\nfunction TabPanel(props: {\n children?: ReactNode;\n index: number;\n value: number;\n}) {\n const { children, value, index, ...other } = props;\n const classes = useStyles();\n return (\n <div\n role=\"tabpanel\"\n hidden={value !== index}\n id={`vertical-tabpanel-${index}`}\n aria-labelledby={`vertical-tab-${index}`}\n className={classes.tabContents}\n {...other}\n >\n {value === index && (\n <Box pl={3} pr={3}>\n {children}\n </Box>\n )}\n </div>\n );\n}\n\nfunction a11yProps(index: number) {\n return {\n id: `vertical-tab-${index}`,\n 'aria-controls': `vertical-tabpanel-${index}`,\n };\n}\n\ntype TabKey = 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n\ntype TabNames = Record<\n NonNullable<ComponentProps<typeof InspectEntityDialog>['initialTab']>,\n string\n>;\n\n/**\n * A dialog that lets users inspect the low level details of their entities.\n *\n * @public\n */\nexport function InspectEntityDialog(props: {\n open: boolean;\n entity: Entity;\n initialTab?: 'overview' | 'ancestry' | 'colocated' | 'json' | 'yaml';\n onClose: () => void;\n onSelect?: (tab: string) => void;\n}) {\n const classes = useStyles();\n const { t } = useTranslationRef(catalogReactTranslationRef);\n\n const tabNames: TabNames = useMemo(\n () => ({\n overview: t('inspectEntityDialog.tabNames.overview'),\n ancestry: t('inspectEntityDialog.tabNames.ancestry'),\n colocated: t('inspectEntityDialog.tabNames.colocated'),\n json: t('inspectEntityDialog.tabNames.json'),\n yaml: t('inspectEntityDialog.tabNames.yaml'),\n }),\n [t],\n );\n\n const tabs = Object.keys(tabNames) as TabKey[];\n\n const [activeTab, setActiveTab] = useState(\n getTabIndex(tabs, props.initialTab),\n );\n\n useEffect(() => {\n getTabIndex(tabs, props.initialTab);\n }, [props.open, props.initialTab, tabs]);\n\n if (!props.entity) {\n return null;\n }\n\n return (\n <Dialog\n fullWidth\n maxWidth=\"xl\"\n open={props.open}\n onClose={props.onClose}\n aria-labelledby=\"entity-inspector-dialog-title\"\n PaperProps={{ className: classes.fullHeightDialog }}\n >\n <DialogTitle id=\"entity-inspector-dialog-title\">\n {t('inspectEntityDialog.title')}\n </DialogTitle>\n <DialogContent dividers>\n <div className={classes.root}>\n <Tabs\n orientation=\"vertical\"\n variant=\"scrollable\"\n value={activeTab}\n onChange={(_, tabIndex) => {\n setActiveTab(tabIndex);\n props.onSelect?.(tabs[tabIndex]);\n }}\n aria-label={t('inspectEntityDialog.tabsAriaLabel')}\n className={classes.tabs}\n >\n {tabs.map((tab, index) => (\n <Tab key={tab} label={tabNames[tab]} {...a11yProps(index)} />\n ))}\n </Tabs>\n\n <TabPanel value={activeTab} index={0}>\n <OverviewPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={1}>\n <AncestryPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={2}>\n <ColocatedPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={3}>\n <JsonPage entity={props.entity} />\n </TabPanel>\n <TabPanel value={activeTab} index={4}>\n <YamlPage entity={props.entity} />\n </TabPanel>\n </div>\n </DialogContent>\n <DialogActions>\n <Button onClick={props.onClose} color=\"primary\">\n {t('inspectEntityDialog.closeButtonTitle')}\n </Button>\n </DialogActions>\n </Dialog>\n );\n}\n\nfunction getTabIndex(allTabs: string[], initialTab: TabKey | undefined) {\n return initialTab ? allTabs.indexOf(initialTab) : 0;\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HeaderLabel } from '@backstage/core-components';\nimport { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model';\nimport {\n EntityRefLinks,\n getEntityRelations,\n} from '@backstage/plugin-catalog-react';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { catalogTranslationRef } from '../../translation';\n\ntype EntityLabelsProps = {\n entity: Entity;\n};\n\nexport function EntityLabels(props: EntityLabelsProps) {\n const { entity } = props;\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n const { t } = useTranslationRef(catalogTranslationRef);\n return (\n <>\n {ownedByRelations.length > 0 && (\n <HeaderLabel\n label={t('entityLabels.ownerLabel')}\n contentTypograpyRootComponent=\"p\"\n value={\n <EntityRefLinks\n entityRefs={ownedByRelations}\n defaultKind=\"Group\"\n color=\"inherit\"\n />\n }\n />\n )}\n {entity.spec?.lifecycle && (\n <HeaderLabel\n label={t('entityLabels.lifecycleLabel')}\n value={entity.spec.lifecycle?.toString()}\n />\n )}\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport CancelIcon from '@material-ui/icons/Cancel';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { forwardRef } from 'react';\n\ntype VisibleType = 'visible' | 'hidden' | 'disable';\n\nexport type UnregisterEntityOptions = {\n disableUnregister: boolean | VisibleType;\n};\n\ninterface UnregisterEntityProps {\n unregisterEntityOptions?: UnregisterEntityOptions;\n isUnregisterAllowed: boolean;\n onUnregisterEntity: () => void;\n onClose: () => void;\n}\n\n// TODO: When Backstage supports only React 19+, remove the forwardRef\nexport const UnregisterEntity = forwardRef<\n HTMLLIElement,\n UnregisterEntityProps\n>((props, ref) => {\n const {\n unregisterEntityOptions,\n isUnregisterAllowed,\n onUnregisterEntity,\n onClose,\n } = props;\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const isBoolean =\n typeof unregisterEntityOptions?.disableUnregister === 'boolean';\n\n const isDisabled =\n (!isUnregisterAllowed ||\n (isBoolean\n ? !!unregisterEntityOptions?.disableUnregister\n : unregisterEntityOptions?.disableUnregister === 'disable')) ??\n false;\n\n if (unregisterEntityOptions?.disableUnregister !== 'hidden') {\n return (\n <MenuItem\n ref={ref}\n onClick={() => {\n onClose();\n onUnregisterEntity();\n }}\n disabled={isDisabled}\n {...props}\n >\n <ListItemIcon>\n <CancelIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.unregisterMenuTitle')} />\n </MenuItem>\n );\n }\n\n return null;\n});\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n createVersionedContext,\n createVersionedValueMap,\n} from '@backstage/version-bridge';\nimport { ReactNode } from 'react';\n\n/** @internal */\nexport type EntityContextMenuContextValue = {\n onMenuClose: () => void;\n};\n\nconst EntityContextMenuContext = createVersionedContext<{\n 1: EntityContextMenuContextValue;\n}>('entity-context-menu-context');\n\n/** @internal */\nexport interface EntityContextMenuProviderProps {\n children: ReactNode;\n onMenuClose: () => void;\n}\n\n/** @internal */\nexport const EntityContextMenuProvider = (\n props: EntityContextMenuProviderProps,\n) => {\n const { children, onMenuClose } = props;\n const value = { onMenuClose };\n\n return (\n <EntityContextMenuContext.Provider\n value={createVersionedValueMap({ 1: value })}\n >\n {children}\n </EntityContextMenuContext.Provider>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Divider from '@material-ui/core/Divider';\nimport FileCopyTwoToneIcon from '@material-ui/icons/FileCopyTwoTone';\nimport IconButton from '@material-ui/core/IconButton';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MenuList from '@material-ui/core/MenuList';\nimport Popover from '@material-ui/core/Popover';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { Theme, makeStyles } from '@material-ui/core/styles';\nimport BugReportIcon from '@material-ui/icons/BugReport';\nimport MoreVert from '@material-ui/icons/MoreVert';\nimport { SyntheticEvent, useEffect, useState } from 'react';\nimport { IconComponent } from '@backstage/core-plugin-api';\nimport { useEntityPermission } from '@backstage/plugin-catalog-react/alpha';\nimport { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common/alpha';\nimport { UnregisterEntity, UnregisterEntityOptions } from './UnregisterEntity';\nimport { useApi, alertApiRef } from '@backstage/core-plugin-api';\nimport useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\nimport { catalogTranslationRef } from '../../alpha/translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { EntityContextMenuProvider } from '../../context';\n\n/** @public */\nexport type EntityContextMenuClassKey = 'button';\n\nconst useStyles = makeStyles(\n (theme: Theme) => {\n return {\n button: {\n color: theme.page.fontColor,\n },\n };\n },\n { name: 'PluginCatalogEntityContextMenu' },\n);\n\n// NOTE(freben): Intentionally not exported at this point, since it's part of\n// the unstable extra context menu items concept below\ninterface ExtraContextMenuItem {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n}\n\ninterface EntityContextMenuProps {\n UNSTABLE_extraContextMenuItems?: ExtraContextMenuItem[];\n UNSTABLE_contextMenuOptions?: UnregisterEntityOptions;\n contextMenuItems?: React.JSX.Element[];\n onUnregisterEntity: () => void;\n onInspectEntity: () => void;\n}\n\nexport function EntityContextMenu(props: EntityContextMenuProps) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n onUnregisterEntity,\n onInspectEntity,\n } = props;\n const { t } = useTranslationRef(catalogTranslationRef);\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>();\n const classes = useStyles();\n const unregisterPermission = useEntityPermission(\n catalogEntityDeletePermission,\n );\n const isAllowed = unregisterPermission.allowed;\n\n const onOpen = (event: SyntheticEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const onClose = () => {\n setAnchorEl(undefined);\n };\n\n const alertApi = useApi(alertApiRef);\n const [copyState, copyToClipboard] = useCopyToClipboard();\n useEffect(() => {\n if (!copyState.error && copyState.value) {\n alertApi.post({\n message: t('entityContextMenu.copiedMessage'),\n severity: 'info',\n display: 'transient',\n });\n }\n }, [copyState, alertApi, t]);\n\n const extraItems = UNSTABLE_extraContextMenuItems?.length\n ? [\n ...UNSTABLE_extraContextMenuItems.map(item => (\n <MenuItem\n key={item.title}\n onClick={() => {\n onClose();\n item.onClick();\n }}\n >\n <ListItemIcon>\n <item.Icon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={item.title} />\n </MenuItem>\n )),\n <Divider key=\"the divider is here!\" />,\n ]\n : null;\n\n const defaultMenuItems = [\n <UnregisterEntity\n unregisterEntityOptions={UNSTABLE_contextMenuOptions}\n isUnregisterAllowed={isAllowed}\n onUnregisterEntity={onUnregisterEntity}\n onClose={onClose}\n key=\"unregister-entity\"\n />,\n <MenuItem\n onClick={() => {\n onClose();\n onInspectEntity();\n }}\n key=\"inspect-entity\"\n >\n <ListItemIcon>\n <BugReportIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.inspectMenuTitle')} />\n </MenuItem>,\n <MenuItem\n onClick={() => {\n onClose();\n copyToClipboard(window.location.toString());\n }}\n key=\"copy-url\"\n >\n <ListItemIcon>\n <FileCopyTwoToneIcon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText primary={t('entityContextMenu.copyURLMenuTitle')} />\n </MenuItem>,\n ];\n\n return (\n <>\n <Tooltip title={t('entityContextMenu.moreButtonTitle')} arrow>\n <IconButton\n aria-label={t('entityContextMenu.moreButtonAriaLabel')}\n aria-controls=\"long-menu\"\n aria-haspopup=\"true\"\n aria-expanded={!!anchorEl}\n role=\"button\"\n onClick={onOpen}\n data-testid=\"menu-button\"\n className={classes.button}\n id=\"long-menu\"\n >\n <MoreVert />\n </IconButton>\n </Tooltip>\n <Popover\n open={Boolean(anchorEl)}\n onClose={onClose}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n aria-labelledby=\"long-menu\"\n PaperProps={{\n style: { minWidth: 200 },\n }}\n >\n <MenuList autoFocusItem={Boolean(anchorEl)}>\n {extraItems}\n {contextMenuItems === undefined ? (\n defaultMenuItems\n ) : (\n <EntityContextMenuProvider onMenuClose={onClose}>\n {contextMenuItems}\n </EntityContextMenuProvider>\n )}\n </MenuList>\n </Popover>\n </>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n useState,\n useCallback,\n useEffect,\n ComponentProps,\n ReactNode,\n} from 'react';\nimport { useNavigate, useLocation, useSearchParams } from 'react-router-dom';\nimport useAsync from 'react-use/esm/useAsync';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Box from '@material-ui/core/Box';\n\nimport { Header, Breadcrumbs } from '@backstage/core-components';\nimport {\n useApi,\n useRouteRef,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { IconComponent } from '@backstage/frontend-plugin-api';\n\nimport {\n Entity,\n EntityRelation,\n DEFAULT_NAMESPACE,\n} from '@backstage/catalog-model';\n\nimport {\n useAsyncEntity,\n entityRouteRef,\n catalogApiRef,\n EntityRefLink,\n InspectEntityDialog,\n UnregisterEntityDialog,\n EntityDisplayName,\n FavoriteEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { EntityLabels } from '../EntityLabels';\nimport { EntityContextMenu } from '../../../components/EntityContextMenu';\nimport { rootRouteRef, unregisterRedirectRouteRef } from '../../../routes';\n\nfunction headerProps(\n paramKind: string | undefined,\n paramNamespace: string | undefined,\n paramName: string | undefined,\n entity: Entity | undefined,\n): { headerTitle: string; headerType: string } {\n const kind = paramKind ?? entity?.kind ?? '';\n const namespace = paramNamespace ?? entity?.metadata.namespace ?? '';\n const name =\n entity?.metadata.title ?? paramName ?? entity?.metadata.name ?? '';\n\n return {\n headerTitle: `${name}${\n namespace && namespace !== DEFAULT_NAMESPACE ? ` in ${namespace}` : ''\n }`,\n headerType: (() => {\n let t = kind.toLocaleLowerCase('en-US');\n if (entity && entity.spec && 'type' in entity.spec) {\n t += ' — ';\n t += (entity.spec as { type: string }).type.toLocaleLowerCase('en-US');\n }\n return t;\n })(),\n };\n}\n\nfunction findParentRelation(\n entityRelations: EntityRelation[] = [],\n relationTypes: string[] = [],\n) {\n for (const type of relationTypes) {\n const foundRelation = entityRelations.find(\n relation => relation.type === type,\n );\n if (foundRelation) {\n return foundRelation; // Return the first found relation and stop\n }\n }\n return null;\n}\n\nconst useStyles = makeStyles(theme => ({\n breadcrumbs: {\n color: theme.page.fontColor,\n fontSize: theme.typography.caption.fontSize,\n textTransform: 'uppercase',\n marginTop: theme.spacing(1),\n opacity: 0.8,\n '& span ': {\n color: theme.page.fontColor,\n textDecoration: 'underline',\n textUnderlineOffset: '3px',\n },\n },\n}));\n\nfunction EntityHeaderTitle() {\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: title } = headerProps(kind, namespace, name, entity);\n return (\n <Box display=\"inline-flex\" alignItems=\"center\" height=\"1em\" maxWidth=\"100%\">\n <Box\n component=\"span\"\n textOverflow=\"ellipsis\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n >\n {entity ? <EntityDisplayName entityRef={entity} hideIcon /> : title}\n </Box>\n {entity && <FavoriteEntity entity={entity} />}\n </Box>\n );\n}\n\nfunction EntityHeaderSubtitle(props: { parentEntityRelations?: string[] }) {\n const { parentEntityRelations } = props;\n const classes = useStyles();\n const { entity } = useAsyncEntity();\n const { name } = useRouteRefParams(entityRouteRef);\n const parentEntity = findParentRelation(\n entity?.relations ?? [],\n parentEntityRelations ?? [],\n );\n\n const catalogApi = useApi(catalogApiRef);\n\n const { value: ancestorEntity } = useAsync(async () => {\n if (parentEntity) {\n return findParentRelation(\n (await catalogApi.getEntityByRef(parentEntity?.targetRef))?.relations,\n parentEntityRelations,\n );\n }\n return null;\n }, [parentEntity, catalogApi]);\n\n return parentEntity ? (\n <Breadcrumbs separator=\">\" className={classes.breadcrumbs}>\n {ancestorEntity && (\n <EntityRefLink entityRef={ancestorEntity.targetRef} disableTooltip />\n )}\n <EntityRefLink entityRef={parentEntity.targetRef} disableTooltip />\n {name}\n </Breadcrumbs>\n ) : null;\n}\n\n/** @alpha */\nexport function EntityHeader(props: {\n // NOTE(freben): Intentionally not exported at this point, since it's part of\n // the unstable extra context menu items concept below\n UNSTABLE_extraContextMenuItems?: {\n title: string;\n Icon: IconComponent;\n onClick: () => void;\n }[];\n // NOTE(blam): Intentionally not exported at this point, since it's part of\n // unstable context menu option, eg: disable the unregister entity menu\n UNSTABLE_contextMenuOptions?: {\n disableUnregister: boolean | 'visible' | 'hidden' | 'disable';\n };\n contextMenuItems?: React.JSX.Element[];\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n title?: ReactNode;\n subtitle?: ReactNode;\n}) {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n parentEntityRelations,\n title,\n subtitle,\n } = props;\n const { entity } = useAsyncEntity();\n const { kind, namespace, name } = useRouteRefParams(entityRouteRef);\n const { headerTitle: entityFallbackText, headerType: type } = headerProps(\n kind,\n namespace,\n name,\n entity,\n );\n\n const location = useLocation();\n const navigate = useNavigate();\n const catalogRoute = useRouteRef(rootRouteRef);\n const unregisterRedirectRoute = useRouteRef(unregisterRedirectRouteRef);\n\n const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false);\n\n const openUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(true),\n [setConfirmationDialogOpen],\n );\n\n const closeUnregisterEntityDialog = useCallback(\n () => setConfirmationDialogOpen(false),\n [setConfirmationDialogOpen],\n );\n\n const cleanUpAfterUnregisterConfirmation = useCallback(async () => {\n setConfirmationDialogOpen(false);\n navigate(\n unregisterRedirectRoute ? unregisterRedirectRoute() : catalogRoute(),\n );\n }, [\n navigate,\n catalogRoute,\n unregisterRedirectRoute,\n setConfirmationDialogOpen,\n ]);\n\n // Make sure to close the dialog if the user clicks links in it that navigate\n // to another entity.\n useEffect(() => {\n setConfirmationDialogOpen(false);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [location.pathname]);\n\n const [searchParams, setSearchParams] = useSearchParams();\n const selectedInspectEntityDialogTab = searchParams.get('inspect');\n\n const setInspectEntityDialogTab = useCallback(\n (newTab: string) => setSearchParams(`inspect=${newTab}`),\n [setSearchParams],\n );\n\n const openInspectEntityDialog = useCallback(\n () => setSearchParams('inspect'),\n [setSearchParams],\n );\n\n const closeInspectEntityDialog = useCallback(\n () => setSearchParams(),\n [setSearchParams],\n );\n\n const inspectDialogOpen = typeof selectedInspectEntityDialogTab === 'string';\n\n return (\n <Header\n pageTitleOverride={entityFallbackText}\n type={type}\n title={title ?? <EntityHeaderTitle />}\n subtitle={\n subtitle ?? (\n <EntityHeaderSubtitle parentEntityRelations={parentEntityRelations} />\n )\n }\n >\n {entity && (\n <>\n <EntityLabels entity={entity} />\n <EntityContextMenu\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n contextMenuItems={contextMenuItems}\n onInspectEntity={openInspectEntityDialog}\n onUnregisterEntity={openUnregisterEntityDialog}\n />\n <InspectEntityDialog\n entity={entity!}\n initialTab={\n (selectedInspectEntityDialogTab as ComponentProps<\n typeof InspectEntityDialog\n >['initialTab']) || undefined\n }\n open={inspectDialogOpen}\n onClose={closeInspectEntityDialog}\n onSelect={setInspectEntityDialogTab}\n />\n <UnregisterEntityDialog\n entity={entity!}\n open={confirmationDialogOpen}\n onClose={closeUnregisterEntityDialog}\n onConfirm={cleanUpAfterUnregisterConfirmation}\n />\n </>\n )}\n </Header>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport classNames from 'classnames';\nimport { PropsWithChildren } from 'react';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\n\n/** @public */\nexport type EntityTabsPanelClassKey = 'root' | 'stretch' | 'noPadding';\n\nconst useStyles = makeStyles(\n (theme: Theme) => ({\n root: {\n gridArea: 'pageContent',\n minWidth: 0,\n paddingTop: theme.spacing(3),\n paddingBottom: theme.spacing(3),\n paddingLeft: theme.spacing(2),\n paddingRight: theme.spacing(2),\n [theme.breakpoints.up('sm')]: {\n paddingLeft: theme.spacing(3),\n paddingRight: theme.spacing(3),\n },\n },\n stretch: {\n display: 'flex',\n flexDirection: 'column',\n flexGrow: 1,\n },\n noPadding: {\n padding: 0,\n },\n }),\n { name: 'EntityTabsPanel' },\n);\n\ntype EntityTabsPanelProps = PropsWithChildren<{\n stretch?: boolean;\n noPadding?: boolean;\n className?: string;\n}>;\n\nexport function EntityTabsPanel(props: EntityTabsPanelProps) {\n const { className, stretch, noPadding, children, ...restProps } = props;\n\n const classes = useStyles();\n return (\n <article\n {...restProps}\n className={classNames(classes.root, className, {\n [classes.stretch]: stretch,\n [classes.noPadding]: noPadding,\n })}\n >\n {children}\n </article>\n );\n}\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ReactNode,\n forwardRef,\n useState,\n MouseEvent,\n MouseEventHandler,\n ReactElement,\n} from 'react';\nimport { Link } from 'react-router-dom';\nimport classnames from 'classnames';\n\nimport Typography from '@material-ui/core/Typography';\nimport Popover from '@material-ui/core/Popover';\nimport { TabProps, TabClassKey } from '@material-ui/core/Tab';\nimport { capitalize } from '@material-ui/core/utils';\nimport { createStyles, Theme, withStyles } from '@material-ui/core/styles';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport Button from '@material-ui/core/Button';\nimport ListItem from '@material-ui/core/ListItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport List from '@material-ui/core/List';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { IconsApi, iconsApiRef } from '@backstage/frontend-plugin-api';\n\nconst styles = (theme: Theme) =>\n createStyles({\n /* Styles applied to the root element. */\n root: {\n ...theme.typography.button,\n maxWidth: 264,\n minWidth: 72,\n position: 'relative',\n boxSizing: 'border-box',\n minHeight: 48,\n flexShrink: 0,\n padding: '6px 12px',\n [theme.breakpoints.up('sm')]: {\n padding: '6px 24px',\n },\n overflow: 'hidden',\n whiteSpace: 'normal',\n textAlign: 'center',\n [theme.breakpoints.up('sm')]: {\n minWidth: 160,\n },\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n /* Styles applied to the root element if both `icon` and `label` are provided. */\n labelIcon: {\n minHeight: 72,\n paddingTop: 9,\n '& $wrapper > *:first-child': {\n marginBottom: 6,\n },\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"inherit\"`. */\n textColorInherit: {\n color: 'inherit',\n opacity: 0.7,\n '&$selected': {\n opacity: 1,\n },\n '&$disabled': {\n opacity: 0.5,\n },\n },\n selectedButton: {\n color: `${theme.palette.text.primary}`,\n opacity: `${1}`,\n },\n unselectedButton: {\n color: `${theme.palette.text.secondary}`,\n opacity: `${0.7}`,\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"primary\"`. */\n textColorPrimary: {\n color: theme.palette.text.secondary,\n '&$selected': {\n color: theme.palette.primary.main,\n },\n '&$disabled': {\n color: theme.palette.text.disabled,\n },\n },\n /* Styles applied to the root element if the parent [`Tabs`](/api/tabs/) has `textColor=\"secondary\"`. */\n textColorSecondary: {\n color: theme.palette.text.secondary,\n '&$selected': {\n color: theme.palette.secondary.main,\n },\n '&$disabled': {\n color: theme.palette.text.disabled,\n },\n },\n /* Pseudo-class applied to the root element if `selected={true}` (controlled by the Tabs component). */\n selected: {},\n /* Pseudo-class applied to the root element if `disabled={true}` (controlled by the Tabs component). */\n disabled: {},\n /* Styles applied to the root element if `fullWidth={true}` (controlled by the Tabs component). */\n fullWidth: {\n flexShrink: 1,\n flexGrow: 1,\n flexBasis: 0,\n maxWidth: 'none',\n },\n /* Styles applied to the root element if `wrapped={true}`. */\n wrapped: {\n fontSize: theme.typography.pxToRem(12),\n lineHeight: 1.5,\n },\n /* Styles applied to the `icon` and `label`'s wrapper element. */\n wrapper: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '100%',\n flexDirection: 'row',\n },\n });\n\ntype EntityTabsGroupItem = {\n id: string;\n label: string;\n path: string;\n icon?: string | ReactElement;\n};\n\ntype EntityTabsGroupProps = TabProps & {\n classes?: Partial<ReturnType<typeof styles>>;\n indicator?: ReactNode;\n highlightedButton?: string;\n items: EntityTabsGroupItem[];\n onSelectTab?: MouseEventHandler<HTMLAnchorElement>;\n showIcons?: boolean;\n};\n\nfunction resolveIcon(\n icon: string | ReactElement | undefined,\n iconsApi: IconsApi,\n showIcons: boolean,\n) {\n if (!showIcons) {\n return undefined;\n }\n if (typeof icon === 'string') {\n const Icon = iconsApi.getIcon(icon);\n if (Icon) {\n return <Icon />;\n }\n return undefined;\n }\n return icon;\n}\n\nconst Tab = forwardRef(function Tab(props: EntityTabsGroupProps, ref: any) {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n const iconsApi = useApi(iconsApiRef);\n\n const open = Boolean(anchorEl);\n const submenuId = open ? 'tabbed-submenu' : undefined;\n\n const {\n classes,\n className,\n disabled = false,\n disableFocusRipple = false,\n items,\n fullWidth,\n indicator,\n label,\n onSelectTab,\n selected,\n textColor = 'inherit',\n wrapped = false,\n highlightedButton,\n showIcons = false,\n } = props;\n\n const groupIcon = resolveIcon(props.icon, iconsApi, showIcons);\n const testId = 'data-testid' in props && props['data-testid'];\n\n const handleMenuClose = () => {\n setAnchorEl(null);\n };\n\n const handleMenuClick = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n };\n\n const classArray = [\n classes?.root,\n classes?.[`textColor${capitalize(textColor)}` as TabClassKey],\n classes && {\n [classes.disabled!]: disabled,\n [classes.selected!]: selected,\n [classes.labelIcon!]: label && groupIcon,\n [classes.fullWidth!]: fullWidth,\n [classes.wrapped!]: wrapped,\n },\n className,\n ];\n\n if (items.length === 1) {\n return (\n <Button\n focusRipple={!disableFocusRipple}\n data-testid={testId}\n className={classnames(\n classArray,\n classes && {\n [classes.labelIcon!]: label && (items[0].icon ?? groupIcon),\n },\n )}\n ref={ref}\n role=\"tab\"\n aria-selected={selected}\n disabled={disabled}\n component={Link}\n onClick={onSelectTab}\n to={items[0]?.path}\n startIcon={resolveIcon(items[0].icon, iconsApi, showIcons)}\n >\n <Typography className={classes?.wrapper} variant=\"button\">\n {items[0].label}\n </Typography>\n {indicator}\n </Button>\n );\n }\n const hasIcons = showIcons && items.some(i => i.icon);\n return (\n <>\n <Button\n data-testid={testId}\n focusRipple={!disableFocusRipple}\n className={classnames(classArray)}\n ref={ref}\n role=\"tab\"\n aria-selected={selected}\n disabled={disabled}\n onClick={handleMenuClick}\n startIcon={groupIcon}\n >\n <Typography className={classes?.wrapper} variant=\"button\">\n {label}\n </Typography>\n <ExpandMoreIcon />\n </Button>\n <Popover\n id={submenuId}\n open={open}\n anchorEl={anchorEl}\n onClose={handleMenuClose}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'center',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'center',\n }}\n >\n <List component=\"nav\">\n {items.map(i => {\n const itemIcon = resolveIcon(i.icon, iconsApi, showIcons);\n return (\n <ListItem\n key={`popover_item_${i.id}`}\n button\n focusRipple={!disableFocusRipple}\n classes={{\n selected: classnames(classes?.selectedButton),\n default: classnames(classes?.unselectedButton),\n disabled: classnames(classes?.disabled),\n }}\n ref={ref}\n aria-selected={selected}\n disabled={disabled}\n selected={highlightedButton === i.id}\n component={Link}\n onClick={e => {\n handleMenuClose();\n onSelectTab?.(e);\n }}\n to={i.path}\n >\n {itemIcon && <ListItemIcon>{itemIcon}</ListItemIcon>}\n <ListItemText\n inset={!itemIcon && hasIcons}\n primary={\n <>\n <Typography variant=\"button\">{i.label}</Typography>\n {indicator}\n </>\n }\n />\n </ListItem>\n );\n })}\n </List>\n </Popover>\n </>\n );\n});\n\n// @ts-ignore\nexport const EntityTabsGroup = withStyles(styles, { name: 'MuiTab' })(Tab);\n","/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ReactElement, useMemo } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Tabs from '@material-ui/core/Tabs';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\nimport { EntityTabsGroup } from './EntityTabsGroup';\nimport { catalogTranslationRef } from '../../translation';\n\n/** @public */\nexport type HeaderTabsClassKey =\n | 'tabsWrapper'\n | 'defaultTab'\n | 'selected'\n | 'tabRoot';\n\nconst useStyles = makeStyles(\n theme => ({\n tabsWrapper: {\n gridArea: 'pageSubheader',\n backgroundColor: theme.palette.background.paper,\n paddingLeft: theme.spacing(3),\n minWidth: 0,\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n selected: {\n color: theme.palette.text.primary,\n },\n tabRoot: {\n '&:hover': {\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n },\n },\n }),\n { name: 'BackstageHeaderTabs' },\n);\n\ntype Tab = {\n id: string;\n label: string;\n path: string;\n group?: string;\n icon?: string | ReactElement;\n};\n\ntype TabGroup = {\n group?: {\n title: string;\n icon?: string | ReactElement;\n };\n items: Array<Omit<Tab, 'group'>>;\n};\n\ntype EntityTabsListProps = {\n tabs: Tab[];\n groupDefinitions: EntityContentGroupDefinitions;\n defaultContentOrder?: 'title' | 'natural';\n showIcons?: boolean;\n selectedIndex?: number;\n};\n\nfunction resolveGroupId(\n tabGroup: string | undefined,\n groupDefinitions: EntityContentGroupDefinitions,\n aliasToGroup: Record<string, string>,\n): string | undefined {\n if (!tabGroup) {\n return undefined;\n }\n if (groupDefinitions[tabGroup]) {\n return tabGroup;\n }\n return aliasToGroup[tabGroup];\n}\n\nexport function EntityTabsList(props: EntityTabsListProps) {\n const styles = useStyles();\n const { t } = useTranslationRef(catalogTranslationRef);\n\n const {\n tabs: items,\n selectedIndex = 0,\n showIcons,\n groupDefinitions,\n defaultContentOrder = 'title',\n } = props;\n\n const aliasToGroup = useMemo(\n () =>\n Object.entries(groupDefinitions).reduce((map, [groupId, def]) => {\n for (const alias of def.aliases ?? []) {\n map[alias] = groupId;\n }\n return map;\n }, {} as Record<string, string>),\n [groupDefinitions],\n );\n\n const groups = useMemo(() => {\n const byKey = items.reduce((result, tab) => {\n const resolvedGroupId = resolveGroupId(\n tab.group,\n groupDefinitions,\n aliasToGroup,\n );\n const group = resolvedGroupId\n ? groupDefinitions[resolvedGroupId]\n : undefined;\n const groupOrId = group && resolvedGroupId ? resolvedGroupId : tab.id;\n result[groupOrId] = result[groupOrId] ?? {\n group,\n items: [],\n };\n result[groupOrId].items.push(tab);\n return result;\n }, {} as Record<string, TabGroup>);\n\n const groupOrder = Object.keys(groupDefinitions);\n const sorted = Object.entries(byKey).sort(([a], [b]) => {\n const ai = groupOrder.indexOf(a);\n const bi = groupOrder.indexOf(b);\n if (ai !== -1 && bi !== -1) {\n return ai - bi;\n }\n if (ai !== -1) {\n return -1;\n }\n if (bi !== -1) {\n return 1;\n }\n return 0;\n });\n\n for (const [id, tabGroup] of sorted) {\n const groupDef = groupDefinitions[id];\n if (groupDef) {\n const order = groupDef.contentOrder ?? defaultContentOrder;\n if (order === 'title') {\n tabGroup.items.sort((a, b) =>\n a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }),\n );\n }\n }\n }\n\n return sorted;\n }, [items, groupDefinitions, aliasToGroup, defaultContentOrder]);\n\n const selectedItem = items[selectedIndex];\n const selectedGroup = resolveGroupId(\n selectedItem?.group,\n groupDefinitions,\n aliasToGroup,\n );\n return (\n <Box className={styles.tabsWrapper}>\n <Tabs\n selectionFollowsFocus\n indicatorColor=\"primary\"\n textColor=\"inherit\"\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label={t('entityTabs.tabsAriaLabel')}\n value={selectedGroup ?? selectedItem?.id}\n >\n {groups.map(([id, tabGroup]) => (\n <EntityTabsGroup\n data-testid={`header-tab-${id}`}\n className={styles.defaultTab}\n classes={{ selected: styles.selected, root: styles.tabRoot }}\n key={id}\n label={tabGroup.group?.title}\n icon={tabGroup.group?.icon}\n value={id}\n items={tabGroup.items}\n highlightedButton={selectedItem?.id}\n showIcons={showIcons}\n />\n ))}\n </Tabs>\n </Box>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ReactElement, useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { matchRoutes, useParams, useRoutes } from 'react-router-dom';\nimport { EntityTabsPanel } from './EntityTabsPanel';\nimport { EntityTabsList } from './EntityTabsList';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\ntype SubRoute = {\n group?: string;\n path: string;\n title: string;\n icon?: string | ReactElement;\n children: JSX.Element;\n};\n\nexport function useSelectedSubRoute(subRoutes: SubRoute[]): {\n index: number;\n route?: SubRoute;\n element?: JSX.Element;\n} {\n const params = useParams();\n\n const routes = subRoutes.map(({ path, children }) => ({\n caseSensitive: false,\n path: `${path}/*`,\n element: children,\n }));\n\n // TODO: remove once react-router updated\n const sortedRoutes = routes.sort((a, b) =>\n // remove \"/*\" symbols from path end before comparing\n b.path.replace(/\\/\\*$/, '').localeCompare(a.path.replace(/\\/\\*$/, '')),\n );\n\n const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;\n\n // TODO(Rugvip): Once we only support v6 stable we can always prefix\n // This avoids having a double / prefix for react-router v6 beta, which in turn breaks\n // the tab highlighting when using relative paths for the tabs.\n let currentRoute = params['*'] ?? '';\n if (!currentRoute.startsWith('/')) {\n currentRoute = `/${currentRoute}`;\n }\n\n const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];\n const foundIndex = matchedRoute\n ? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)\n : 0;\n\n return {\n index: foundIndex === -1 ? 0 : foundIndex,\n element,\n route: subRoutes[foundIndex] ?? subRoutes[0],\n };\n}\n\ntype EntityTabsProps = {\n routes: SubRoute[];\n groupDefinitions: EntityContentGroupDefinitions;\n defaultContentOrder?: 'title' | 'natural';\n showIcons?: boolean;\n};\n\nexport function EntityTabs(props: EntityTabsProps) {\n const { routes, groupDefinitions, defaultContentOrder, showIcons } = props;\n\n const { index, route, element } = useSelectedSubRoute(routes);\n\n const tabs = useMemo(\n () =>\n routes.map(t => {\n const { path, title, group, icon } = t;\n let to = path;\n // Remove trailing /*\n to = to.replace(/\\/\\*$/, '');\n // And remove leading / for relative navigation\n to = to.replace(/^\\//, '');\n return {\n group,\n id: path,\n path: to,\n label: title,\n icon,\n };\n }),\n [routes],\n );\n\n return (\n <>\n <EntityTabsList\n tabs={tabs}\n selectedIndex={index}\n showIcons={showIcons}\n groupDefinitions={groupDefinitions}\n defaultContentOrder={defaultContentOrder}\n />\n <EntityTabsPanel>\n <Helmet title={route?.title} />\n {element}\n </EntityTabsPanel>\n </>\n );\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ComponentProps, ReactNode, ReactElement } from 'react';\n\nimport Alert from '@material-ui/lab/Alert';\n\nimport {\n attachComponentData,\n useElementFilter,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport {\n Content,\n Link,\n Page,\n Progress,\n WarningPanel,\n} from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport {\n entityRouteRef,\n useAsyncEntity,\n} from '@backstage/plugin-catalog-react';\n\nimport { catalogTranslationRef } from '../../translation';\nimport { EntityHeader } from '../EntityHeader';\nimport { EntityTabs } from '../EntityTabs';\nimport { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';\n\nexport type EntityLayoutRouteProps = {\n path: string;\n title: string;\n group?: string;\n icon?: string | ReactElement;\n children: JSX.Element;\n if?: (entity: Entity) => boolean;\n};\n\nconst dataKey = 'plugin.catalog.entityLayoutRoute';\nconst Route: (props: EntityLayoutRouteProps) => null = () => null;\nattachComponentData(Route, dataKey, true);\nattachComponentData(Route, 'core.gatherMountPoints', true); // This causes all mount points that are discovered within this route to use the path of the route itself\n\n/** @public */\nexport interface EntityLayoutProps {\n UNSTABLE_contextMenuOptions?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_contextMenuOptions'];\n UNSTABLE_extraContextMenuItems?: ComponentProps<\n typeof EntityHeader\n >['UNSTABLE_extraContextMenuItems'];\n contextMenuItems?: ComponentProps<typeof EntityHeader>['contextMenuItems'];\n children?: ReactNode;\n header?: JSX.Element;\n NotFoundComponent?: ReactNode;\n /**\n * An array of relation types used to determine the parent entities in the hierarchy.\n * These relations are prioritized in the order provided, allowing for flexible\n * navigation through entity relationships.\n *\n * For example, use relation types like `[\"partOf\", \"memberOf\", \"ownedBy\"]` to define how the entity is related to\n * its parents in the Entity Catalog.\n *\n * It adds breadcrumbs in the Entity page to enhance user navigation and context awareness.\n */\n parentEntityRelations?: string[];\n groupDefinitions: EntityContentGroupDefinitions;\n defaultContentOrder?: 'title' | 'natural';\n showNavItemIcons?: boolean;\n}\n\n/**\n * EntityLayout is a compound component, which allows you to define a layout for\n * entities using a sub-navigation mechanism.\n *\n * Consists of two parts: EntityLayout and EntityLayout.Route\n *\n * @example\n * ```jsx\n * <EntityLayout>\n * <EntityLayout.Route path=\"/example\" title=\"Example tab\">\n * <div>This is rendered under /example/anything-here route</div>\n * </EntityLayout.Route>\n * </EntityLayout>\n * ```\n *\n * @public\n */\nexport const EntityLayout = (props: EntityLayoutProps) => {\n const {\n UNSTABLE_extraContextMenuItems,\n UNSTABLE_contextMenuOptions,\n contextMenuItems,\n children,\n header,\n NotFoundComponent,\n parentEntityRelations,\n groupDefinitions,\n defaultContentOrder,\n showNavItemIcons,\n } = props;\n const { kind } = useRouteRefParams(entityRouteRef);\n const { entity, loading, error } = useAsyncEntity();\n\n const routes = useElementFilter(\n children,\n elements =>\n elements\n .selectByComponentData({\n key: dataKey,\n withStrictError:\n 'Child of EntityLayout must be an EntityLayout.Route',\n })\n .getElements<EntityLayoutRouteProps>() // all nodes, element data, maintain structure or not?\n .flatMap(({ props: elementProps }) => {\n if (!entity) {\n return [];\n }\n if (elementProps.if && !elementProps.if(entity)) {\n return [];\n }\n return [\n {\n path: elementProps.path,\n title: elementProps.title,\n group: elementProps.group,\n children: elementProps.children,\n icon: elementProps.icon,\n },\n ];\n }),\n [entity],\n );\n\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return (\n <Page themeId={entity?.spec?.type?.toString() ?? 'home'}>\n {header ?? (\n <EntityHeader\n parentEntityRelations={parentEntityRelations}\n UNSTABLE_contextMenuOptions={UNSTABLE_contextMenuOptions}\n UNSTABLE_extraContextMenuItems={UNSTABLE_extraContextMenuItems}\n contextMenuItems={contextMenuItems}\n />\n )}\n\n {loading && <Progress />}\n\n {entity && (\n <EntityTabs\n routes={routes}\n groupDefinitions={groupDefinitions}\n defaultContentOrder={defaultContentOrder}\n showIcons={showNavItemIcons}\n />\n )}\n\n {error && (\n <Content>\n <Alert severity=\"error\">{error.toString()}</Alert>\n </Content>\n )}\n\n {!loading && !error && !entity && (\n <Content>\n {NotFoundComponent ? (\n NotFoundComponent\n ) : (\n <WarningPanel title={t('entityLabels.warningPanelTitle')}>\n {t('entityPage.notFoundMessage', {\n kind,\n link: (\n <Link to=\"https://backstage.io/docs/features/software-catalog/references\">\n {t('entityPage.notFoundLinkText')}\n </Link>\n ),\n })}\n </WarningPanel>\n )}\n </Content>\n )}\n </Page>\n );\n};\n\nEntityLayout.Route = Route;\n"],"names":["useStyles","makeStyles","FavoriteToggleIcon","props","isFavorite","classes","Typography","StarIcon","UnstarredIcon","FavoriteToggle","id","title","value","onChange","iconButtonProps","Tooltip","IconButton","humanizeEntityRef","entityRef","opts","kind","namespace","name","defaultKind","undefined","DEFAULT_NAMESPACE","humanizeEntity","entity","defaultName","path","get","DependencyGraphTypes","getEntityRef","entityOrRef","stringifyEntityRef","FavoriteEntity","toggleStarredEntity","isStarredEntity","useStarredEntity","starredEntitiesApi","useApi","starredEntitiesApiRef","setIsStarredEntity","useState","useEffect","subscription","starredEntities","useCallback","t","useTranslationRef","catalogReactTranslationRef","theme","DefaultNode","width","setWidth","height","setHeight","idRef","useRef","useLayoutEffect","renderedHeight","renderedWidth","Math","paddedWidth","padding","paddedHeight","renderDefault","Node","render","setNode","node","x","y","nodeRef","NODE_TEST_ID","ARROW_MARKER_ID","DefaultLabel","label","Edge","setEdge","edge","curve","showArrowHeads","points","labelRef","createPath","useMemo","d3Shape","d","point","isFinite","EDGE_TEST_ID","labelProps","LABEL_TEST_ID","WORKSPACE_ID","DEPENDENCY_GRAPH_SVG","DependencyGraph","edges","nodes","renderNode","direction","Types","align","nodeMargin","edgeMargin","rankMargin","paddingX","paddingY","acyclicer","ranker","labelPosition","labelOffset","edgeRanks","edgeWeight","renderEdge","renderLabel","defs","zoom","fit","allowFullscreen","svgProps","useTheme","containerWidth","setContainerWidth","containerHeight","setContainerHeight","fullScreenHandle","useFullScreenHandle","styles","coreComponentsTranslationRef","graph","dagre","graphWidth","setGraphWidth","graphHeight","setGraphHeight","graphNodes","setGraphNodes","graphEdges","setGraphEdges","maxWidth","maxHeight","_measureRef","useMeasure","measureRef","once","scalableHeight","containerRef","debounce","root","container","d3Selection","workspace","enableZoom","d3Zoom","Infinity","event","newContainerWidth","newContainerHeight","setNodesAndEdges","currentGraphNodes","currentGraphEdges","nodeId","e","existingNode","updateGraph","newHeight","FullScreen","classNames","FullscreenExitIcon","FullscreenIcon","DEFAULT_ICON","SvgIcon","EntityKindIcon","app","actualKind","otherProps","Icon","useApp","getKind","parseEntityRef","CustomNode","navigate","useNavigate","entityRoute","useRouteRef","entityRouteRef","hasKindIcon","paddedIconWidth","iconSize","displayTitle","AncestryPage","loading","error","useAncestry","catalogClient","catalogApiRef","useAsync","response","Array","current","currentRef","isRootNode","parentRef","Progress","ResponseErrorPanel","DialogContentText","Link","Box","ListItemText","MuiListItemText","ListSubheader","MuiListSubheader","Container","Card","CardContent","HelpIcon","KeyValueListItem","key","link","ListItem","ListItemIcon","HelpOutlineIcon","EntityList","List","EntityRefLink","Contents","location","originLocation","colocatedEntities","useColocated","catalogApi","currentEntityRef","ANNOTATION_LOCATION","origin","ANNOTATION_ORIGIN_LOCATION","colocated","Alert","atLocation","atOrigin","ColocatedPage","sortKeys","data","Object","a","b","JsonPage","CodeSnippet","JSON","OverviewPage","apiVersion","metadata","spec","relations","status","groupedRelations","groupBy","sortBy","r","ListItemSecondaryAction","CopyTextButton","entry","tag","index","type","groupRelations","group","item","YamlPage","YAML","TabPanel","children","other","InspectEntityDialog","tabNames","tabs","activeTab","setActiveTab","getTabIndex","Dialog","DialogTitle","DialogContent","Tabs","_","tabIndex","tab","Tab","DialogActions","Button","allTabs","initialTab","EntityLabels","ownedByRelations","getEntityRelations","RELATION_OWNED_BY","catalogTranslationRef","HeaderLabel","EntityRefLinks","UnregisterEntity","forwardRef","ref","unregisterEntityOptions","isUnregisterAllowed","onUnregisterEntity","onClose","isBoolean","isDisabled","MenuItem","CancelIcon","EntityContextMenuContext","createVersionedContext","EntityContextMenuProvider","onMenuClose","createVersionedValueMap","EntityContextMenu","UNSTABLE_extraContextMenuItems","UNSTABLE_contextMenuOptions","contextMenuItems","onInspectEntity","anchorEl","setAnchorEl","isAllowed","unregisterPermission","useEntityPermission","catalogEntityDeletePermission","alertApi","alertApiRef","copyState","copyToClipboard","useCopyToClipboard","extraItems","Divider","defaultMenuItems","BugReportIcon","window","FileCopyTwoToneIcon","MoreVert","Popover","Boolean","MenuList","headerProps","paramKind","paramNamespace","paramName","findParentRelation","entityRelations","relationTypes","foundRelation","relation","EntityHeaderTitle","useAsyncEntity","useRouteRefParams","EntityDisplayName","EntityHeaderSubtitle","parentEntityRelations","parentEntity","ancestorEntity","Breadcrumbs","EntityHeader","subtitle","entityFallbackText","useLocation","catalogRoute","rootRouteRef","unregisterRedirectRoute","unregisterRedirectRouteRef","confirmationDialogOpen","setConfirmationDialogOpen","openUnregisterEntityDialog","closeUnregisterEntityDialog","cleanUpAfterUnregisterConfirmation","searchParams","setSearchParams","useSearchParams","selectedInspectEntityDialogTab","setInspectEntityDialogTab","newTab","openInspectEntityDialog","closeInspectEntityDialog","Header","UnregisterEntityDialog","EntityTabsPanel","className","stretch","noPadding","restProps","resolveIcon","icon","iconsApi","showIcons","iconsApiRef","open","disabled","disableFocusRipple","items","fullWidth","indicator","onSelectTab","selected","textColor","wrapped","highlightedButton","groupIcon","testId","handleMenuClose","classArray","capitalize","classnames","hasIcons","i","ExpandMoreIcon","itemIcon","EntityTabsGroup","withStyles","createStyles","resolveGroupId","tabGroup","groupDefinitions","aliasToGroup","EntityTabsList","selectedIndex","defaultContentOrder","map","groupId","def","alias","groups","byKey","result","resolvedGroupId","groupOrId","groupOrder","sorted","ai","bi","groupDef","order","selectedItem","selectedGroup","EntityTabs","routes","route","element","useSelectedSubRoute","subRoutes","params","useParams","sortedRoutes","useRoutes","currentRoute","matchedRoute","matchRoutes","foundIndex","to","Helmet","dataKey","Route","attachComponentData","EntityLayout","header","NotFoundComponent","showNavItemIcons","useElementFilter","elements","elementProps","Page","Content","WarningPanel"],"mappings":"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"}
|