@backstage/plugin-app-visualizer 0.2.4-next.0 → 0.2.4

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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # @backstage/plugin-app-visualizer
2
2
 
3
+ ## 0.2.4
4
+
5
+ ### Patch Changes
6
+
7
+ - e2d9831: Tightened React Aria dependency version ranges from `^` to `~` to prevent unintended minor version upgrades.
8
+ - f635139: Limited `@remixicon/react` dependency to versions below 4.9.0 due to a license change in that release.
9
+ - 44d77e9: Removed separate nav item extensions. Sidebar entries are now provided via `title` and `icon` on each plugin's page extension.
10
+ - Updated dependencies
11
+ - @backstage/core-components@0.18.10
12
+ - @backstage/ui@0.15.0
13
+ - @backstage/frontend-plugin-api@0.17.0
14
+ - @backstage/core-plugin-api@1.12.6
15
+
16
+ ## 0.2.4-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - f635139: Limited `@remixicon/react` dependency to versions below 4.9.0 due to a license change in that release.
21
+ - Updated dependencies
22
+ - @backstage/ui@0.15.0-next.1
23
+ - @backstage/frontend-plugin-api@0.17.0-next.1
24
+ - @backstage/core-plugin-api@1.12.6-next.1
25
+
3
26
  ## 0.2.4-next.0
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -4,7 +4,6 @@ A plugin to help explore the structure of your Backstage app.
4
4
 
5
5
  This plugin provides the following extensions:
6
6
 
7
- | ID | Type | Description | Default Config |
8
- | ------------------------- | --------- | ------------------------------------ | ------------------------- |
9
- | `page:app-visualizer` | `Page` | The app visualizer page | `{ path: '/visualizer' }` |
10
- | `nav-item:app-visualizer` | `NavItem` | Nav item for the app visualizer page | |
7
+ | ID | Type | Description | Default Config |
8
+ | --------------------- | ------ | ----------------------- | ------------------------- |
9
+ | `page:app-visualizer` | `Page` | The app visualizer page | `{ path: '/visualizer' }` |
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useApi, appTreeApiRef, NavItemBlueprint, coreExtensionData, ApiBlueprint, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
2
+ import { useApi, appTreeApiRef, coreExtensionData, ApiBlueprint, routeResolutionApiRef } from '@backstage/frontend-plugin-api';
3
3
  import { FullPage, Flex, Box, TooltipTrigger, Text, Tooltip, Link } from '@backstage/ui';
4
4
  import { RiCloseCircleLine, RiInputField } from '@remixicon/react';
5
5
  import { Focusable } from 'react-aria-components';
@@ -44,8 +44,7 @@ const getOutputColor = createOutputColorGenerator(
44
44
  [coreExtensionData.reactElement.id]: "#4caf50",
45
45
  [coreExtensionData.routePath.id]: "#ffeb3b",
46
46
  [coreExtensionData.routeRef.id]: "#9c27b0",
47
- [ApiBlueprint.dataRefs.factory.id]: "#2196f3",
48
- [NavItemBlueprint.dataRefs.target.id]: "#ff9800"
47
+ [ApiBlueprint.dataRefs.factory.id]: "#2196f3"
49
48
  },
50
49
  ["#90caf9", "#ffcc80", "#a5d6a7", "#ef9a9a", "#fff59d", "#ce93d8", "#e6ee9c"]
51
50
  );
@@ -242,8 +241,7 @@ const legendMap = {
242
241
  "React Element": coreExtensionData.reactElement,
243
242
  "Utility API": ApiBlueprint.dataRefs.factory,
244
243
  "Route Path": coreExtensionData.routePath,
245
- "Route Ref": coreExtensionData.routeRef,
246
- "Nav Target": NavItemBlueprint.dataRefs.target
244
+ "Route Ref": coreExtensionData.routeRef
247
245
  };
248
246
  function Legend() {
249
247
  return /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"file":"DetailedVisualizer.esm.js","sources":["../../../src/components/AppVisualizerPage/DetailedVisualizer.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 AppNode,\n ExtensionDataRef,\n coreExtensionData,\n ApiBlueprint,\n NavItemBlueprint,\n useApi,\n routeResolutionApiRef,\n appTreeApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n Box,\n Flex,\n FullPage,\n Link,\n Text,\n Tooltip,\n TooltipTrigger,\n} from '@backstage/ui';\nimport {\n RiInputField as InputIcon,\n RiCloseCircleLine as DisabledIcon,\n} from '@remixicon/react';\nimport { Focusable } from 'react-aria-components';\nimport { memo, useMemo, useState, useEffect, useRef, Fragment } from 'react';\n\nfunction getContrastColor(bgColor: string): string {\n const hex = bgColor.replace('#', '');\n const r = parseInt(hex.substr(0, 2), 16);\n const g = parseInt(hex.substr(2, 2), 16);\n const b = parseInt(hex.substr(4, 2), 16);\n const brightness = (r * 299 + g * 587 + b * 114) / 1000;\n return brightness > 128 ? '#000000' : '#ffffff';\n}\n\nfunction createOutputColorGenerator(\n colorMap: { [extDataId: string]: string },\n availableColors: string[],\n) {\n const map = new Map<string, { backgroundColor: string; color: string }>();\n let i = 0;\n\n return function getOutputColor(id: string) {\n let backgroundColor: string;\n if (id in colorMap) {\n backgroundColor = colorMap[id];\n } else {\n const cached = map.get(id);\n if (cached) {\n return cached;\n }\n backgroundColor = availableColors[i];\n i += 1;\n if (i >= availableColors.length) {\n i = 0;\n }\n }\n const result = {\n backgroundColor,\n color: getContrastColor(backgroundColor),\n };\n map.set(id, result);\n return result;\n };\n}\n\nconst getOutputColor = createOutputColorGenerator(\n {\n [coreExtensionData.reactElement.id]: '#4caf50',\n [coreExtensionData.routePath.id]: '#ffeb3b',\n [coreExtensionData.routeRef.id]: '#9c27b0',\n [ApiBlueprint.dataRefs.factory.id]: '#2196f3',\n [NavItemBlueprint.dataRefs.target.id]: '#ff9800',\n },\n\n ['#90caf9', '#ffcc80', '#a5d6a7', '#ef9a9a', '#fff59d', '#ce93d8', '#e6ee9c'],\n);\n\n// Helper function to get border color based on depth\nfunction getBorderColor(depth: number): string {\n const greyLevels = [8, 7, 6, 5]; // darker levels that contrast well with background\n const index = depth % greyLevels.length;\n const level = greyLevels[index];\n return `var(--bui-gray-${level})`;\n}\n\nfunction getFullPath(node?: AppNode): string {\n if (!node) {\n return '';\n }\n const parent = node.edges.attachedTo?.node;\n const part = node.instance?.getData(coreExtensionData.routePath);\n if (!part) {\n return getFullPath(parent);\n }\n return getFullPath(parent) + part;\n}\n\nfunction ProgressiveCollection({\n items,\n batchSize = 10,\n}: {\n items: Array<() => React.ReactElement>;\n batchSize?: number;\n}) {\n const [maxIndex, setMaxIndex] = useState(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (maxIndex >= items.length) {\n return undefined;\n }\n\n const processBatch = () => {\n const nextIndex = Math.min(maxIndex + batchSize, items.length);\n setMaxIndex(nextIndex);\n\n if (nextIndex < items.length) {\n timeoutRef.current = setTimeout(processBatch, 0);\n }\n };\n\n timeoutRef.current = setTimeout(processBatch, 0);\n\n // eslint-disable-next-line consistent-return\n return () => {\n if (timeoutRef.current !== null) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n };\n }, [maxIndex, items.length, batchSize]);\n\n return (\n <>\n {items.slice(0, maxIndex).map((item, index) => (\n <Fragment key={index}>{item()}</Fragment>\n ))}\n </>\n );\n}\n\nconst Output = memo(\n function Output(props: {\n dataRef: ExtensionDataRef<unknown>;\n node?: AppNode;\n }) {\n const { dataRef, node } = props;\n const { id } = dataRef;\n const instance = node?.instance;\n\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const { backgroundColor, color } = getOutputColor(id);\n\n const chipStyle: React.CSSProperties = {\n height: 20,\n padding: '0 10px',\n borderRadius: '10px',\n color,\n backgroundColor,\n display: 'flex',\n alignItems: 'center',\n fontWeight:\n 'var(--bui-font-weight-regular)' as React.CSSProperties['fontWeight'],\n };\n\n if (id === coreExtensionData.routeRef.id && node) {\n try {\n const routeRef = props.node?.instance?.getData(\n coreExtensionData.routeRef,\n );\n const link = routeRef && routeResolutionApi.resolve(routeRef)?.();\n if (link) {\n return (\n <TooltipTrigger>\n <Link href={link} style={chipStyle}>\n link\n </Link>\n <Tooltip>{id}</Tooltip>\n </TooltipTrigger>\n );\n }\n } catch {\n /* ignore */\n }\n }\n\n let tooltip = id;\n let text: string | undefined = undefined;\n if (id === coreExtensionData.routePath.id) {\n text = String(instance?.getData(dataRef) ?? '');\n tooltip = getFullPath(node);\n }\n\n return (\n <TooltipTrigger>\n <Focusable>\n <Text style={{ ...chipStyle, cursor: 'help' }}>{text}</Text>\n </Focusable>\n <Tooltip style={{ maxWidth: 'unset' }}>{tooltip}</Tooltip>\n </TooltipTrigger>\n );\n },\n (prevProps, nextProps) => {\n return (\n prevProps.dataRef.id === nextProps.dataRef.id &&\n prevProps.node?.spec.id === nextProps.node?.spec.id\n );\n },\n);\n\nfunction Extension({ node, depth }: { node: AppNode; depth: number }) {\n const enabled = Boolean(node.instance);\n\n const tooltipText = useMemo(() => {\n const tooltipParts = [];\n let currentNode = node;\n tooltipParts.push(currentNode.spec.id);\n while (currentNode.edges.attachedTo) {\n const input = currentNode.edges.attachedTo.input;\n currentNode = currentNode.edges.attachedTo.node;\n tooltipParts.push(`${currentNode.spec.id} [${input}]`);\n }\n tooltipParts.reverse();\n return tooltipParts.join('\\n');\n }, [node]);\n\n const sortedDataRefs = useMemo(() => {\n if (!node.instance) {\n return [];\n }\n const dataRefs = [...node.instance.getDataRefs()];\n return dataRefs.sort((a, b) => a.id.localeCompare(b.id));\n }, [node.instance]);\n\n const sortedAttachments = useMemo(() => {\n return [...node.edges.attachments.entries()].sort(([a], [b]) =>\n a.localeCompare(b),\n );\n }, [node.edges.attachments]);\n\n return (\n <Box\n key={node.spec.id}\n style={{\n borderLeftWidth: 'var(--bui-space-1_5)',\n borderLeftStyle: 'solid',\n borderLeftColor: getBorderColor(depth),\n }}\n >\n <Flex\n py=\"1\"\n px=\"2\"\n align=\"center\"\n style={{\n width: 'fit-content',\n color: enabled ? 'var(--bui-fg-primary)' : 'var(--bui-fg-disabled)',\n background: 'var(--bui-bg-neutral-1)',\n borderTopRightRadius: 'var(--bui-radius-2)',\n borderBottomRightRadius: 'var(--bui-radius-2)',\n }}\n >\n <TooltipTrigger>\n <Focusable>\n <Text style={{ userSelect: 'all' }}>{node.spec.id}</Text>\n </Focusable>\n <Tooltip style={{ maxWidth: 'unset' }}>\n <Text style={{ whiteSpace: 'pre-wrap' }}>{tooltipText}</Text>\n </Tooltip>\n </TooltipTrigger>\n <Flex ml=\"2\" align=\"center\" gap=\"2\">\n {sortedDataRefs.length > 0 &&\n sortedDataRefs.map(ref => (\n <Output key={ref.id} dataRef={ref} node={node} />\n ))}\n {!enabled && <DisabledIcon size={16} />}\n </Flex>\n </Flex>\n {sortedAttachments.length > 0 && (\n <Flex direction=\"column\" gap=\"4\">\n {sortedAttachments.map(([key, children], idx) => (\n <Box key={key}>\n <Flex\n p=\"2\"\n align=\"center\"\n style={{\n borderTopWidth: 'var(--bui-space-1_5)',\n borderTopStyle: 'solid',\n borderTopColor: getBorderColor(depth),\n borderTop: idx === 0 ? 'none' : undefined,\n width: 'fit-content',\n }}\n >\n <InputIcon size={16} />\n <div style={{ marginLeft: 'var(--bui-space-2)' }}>{key}</div>\n </Flex>\n <Flex ml=\"2\" mb=\"2\" direction=\"column\" align=\"start\" gap=\"1\">\n <ProgressiveCollection\n items={children.map(childNode => () => (\n <Extension\n key={childNode.spec.id}\n node={childNode}\n depth={depth + 1}\n />\n ))}\n />\n </Flex>\n </Box>\n ))}\n </Flex>\n )}\n </Box>\n );\n}\n\nconst legendMap = {\n 'React Element': coreExtensionData.reactElement,\n 'Utility API': ApiBlueprint.dataRefs.factory,\n 'Route Path': coreExtensionData.routePath,\n 'Route Ref': coreExtensionData.routeRef,\n 'Nav Target': NavItemBlueprint.dataRefs.target,\n};\n\nfunction Legend() {\n return (\n <Box\n p=\"2\"\n style={{\n display: 'grid',\n maxWidth: 600,\n grid: 'auto-flow / repeat(3, 1fr)',\n gap: 'var(--bui-space-4)',\n }}\n >\n {Object.entries(legendMap).map(([label, dataRef]) => (\n <Flex key={dataRef.id} gap=\"2\" align=\"center\">\n <Output dataRef={dataRef} />\n <div>{label}</div>\n </Flex>\n ))}\n </Box>\n );\n}\n\nexport function DetailedVisualizer() {\n const appTreeApi = useApi(appTreeApiRef);\n const { tree } = appTreeApi.getTree();\n\n return (\n <FullPage>\n <Flex direction=\"column\" style={{ height: '100%', flex: '1 1 100%' }}>\n <Box ml=\"4\" mt=\"4\" style={{ flex: '1 1 0', overflow: 'auto' }}>\n <Extension node={tree.root} depth={0} />\n </Box>\n\n <Box\n m=\"2\"\n style={{\n flex: '0 0 auto',\n background: 'var(--bui-bg-neutral-1)',\n border: '1px solid var(--bui-border-2)',\n borderRadius: 'var(--bui-radius-2)',\n }}\n >\n <Legend />\n </Box>\n </Flex>\n </FullPage>\n );\n}\n"],"names":["getOutputColor","Fragment","Output","DisabledIcon","InputIcon"],"mappings":"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"}
1
+ {"version":3,"file":"DetailedVisualizer.esm.js","sources":["../../../src/components/AppVisualizerPage/DetailedVisualizer.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 AppNode,\n ExtensionDataRef,\n coreExtensionData,\n ApiBlueprint,\n useApi,\n routeResolutionApiRef,\n appTreeApiRef,\n} from '@backstage/frontend-plugin-api';\nimport {\n Box,\n Flex,\n FullPage,\n Link,\n Text,\n Tooltip,\n TooltipTrigger,\n} from '@backstage/ui';\nimport {\n RiInputField as InputIcon,\n RiCloseCircleLine as DisabledIcon,\n} from '@remixicon/react';\nimport { Focusable } from 'react-aria-components';\nimport { memo, useMemo, useState, useEffect, useRef, Fragment } from 'react';\n\nfunction getContrastColor(bgColor: string): string {\n const hex = bgColor.replace('#', '');\n const r = parseInt(hex.substr(0, 2), 16);\n const g = parseInt(hex.substr(2, 2), 16);\n const b = parseInt(hex.substr(4, 2), 16);\n const brightness = (r * 299 + g * 587 + b * 114) / 1000;\n return brightness > 128 ? '#000000' : '#ffffff';\n}\n\nfunction createOutputColorGenerator(\n colorMap: { [extDataId: string]: string },\n availableColors: string[],\n) {\n const map = new Map<string, { backgroundColor: string; color: string }>();\n let i = 0;\n\n return function getOutputColor(id: string) {\n let backgroundColor: string;\n if (id in colorMap) {\n backgroundColor = colorMap[id];\n } else {\n const cached = map.get(id);\n if (cached) {\n return cached;\n }\n backgroundColor = availableColors[i];\n i += 1;\n if (i >= availableColors.length) {\n i = 0;\n }\n }\n const result = {\n backgroundColor,\n color: getContrastColor(backgroundColor),\n };\n map.set(id, result);\n return result;\n };\n}\n\nconst getOutputColor = createOutputColorGenerator(\n {\n [coreExtensionData.reactElement.id]: '#4caf50',\n [coreExtensionData.routePath.id]: '#ffeb3b',\n [coreExtensionData.routeRef.id]: '#9c27b0',\n [ApiBlueprint.dataRefs.factory.id]: '#2196f3',\n },\n\n ['#90caf9', '#ffcc80', '#a5d6a7', '#ef9a9a', '#fff59d', '#ce93d8', '#e6ee9c'],\n);\n\n// Helper function to get border color based on depth\nfunction getBorderColor(depth: number): string {\n const greyLevels = [8, 7, 6, 5]; // darker levels that contrast well with background\n const index = depth % greyLevels.length;\n const level = greyLevels[index];\n return `var(--bui-gray-${level})`;\n}\n\nfunction getFullPath(node?: AppNode): string {\n if (!node) {\n return '';\n }\n const parent = node.edges.attachedTo?.node;\n const part = node.instance?.getData(coreExtensionData.routePath);\n if (!part) {\n return getFullPath(parent);\n }\n return getFullPath(parent) + part;\n}\n\nfunction ProgressiveCollection({\n items,\n batchSize = 10,\n}: {\n items: Array<() => React.ReactElement>;\n batchSize?: number;\n}) {\n const [maxIndex, setMaxIndex] = useState(0);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (maxIndex >= items.length) {\n return undefined;\n }\n\n const processBatch = () => {\n const nextIndex = Math.min(maxIndex + batchSize, items.length);\n setMaxIndex(nextIndex);\n\n if (nextIndex < items.length) {\n timeoutRef.current = setTimeout(processBatch, 0);\n }\n };\n\n timeoutRef.current = setTimeout(processBatch, 0);\n\n // eslint-disable-next-line consistent-return\n return () => {\n if (timeoutRef.current !== null) {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = null;\n }\n };\n }, [maxIndex, items.length, batchSize]);\n\n return (\n <>\n {items.slice(0, maxIndex).map((item, index) => (\n <Fragment key={index}>{item()}</Fragment>\n ))}\n </>\n );\n}\n\nconst Output = memo(\n function Output(props: {\n dataRef: ExtensionDataRef<unknown>;\n node?: AppNode;\n }) {\n const { dataRef, node } = props;\n const { id } = dataRef;\n const instance = node?.instance;\n\n const routeResolutionApi = useApi(routeResolutionApiRef);\n\n const { backgroundColor, color } = getOutputColor(id);\n\n const chipStyle: React.CSSProperties = {\n height: 20,\n padding: '0 10px',\n borderRadius: '10px',\n color,\n backgroundColor,\n display: 'flex',\n alignItems: 'center',\n fontWeight:\n 'var(--bui-font-weight-regular)' as React.CSSProperties['fontWeight'],\n };\n\n if (id === coreExtensionData.routeRef.id && node) {\n try {\n const routeRef = props.node?.instance?.getData(\n coreExtensionData.routeRef,\n );\n const link = routeRef && routeResolutionApi.resolve(routeRef)?.();\n if (link) {\n return (\n <TooltipTrigger>\n <Link href={link} style={chipStyle}>\n link\n </Link>\n <Tooltip>{id}</Tooltip>\n </TooltipTrigger>\n );\n }\n } catch {\n /* ignore */\n }\n }\n\n let tooltip = id;\n let text: string | undefined = undefined;\n if (id === coreExtensionData.routePath.id) {\n text = String(instance?.getData(dataRef) ?? '');\n tooltip = getFullPath(node);\n }\n\n return (\n <TooltipTrigger>\n <Focusable>\n <Text style={{ ...chipStyle, cursor: 'help' }}>{text}</Text>\n </Focusable>\n <Tooltip style={{ maxWidth: 'unset' }}>{tooltip}</Tooltip>\n </TooltipTrigger>\n );\n },\n (prevProps, nextProps) => {\n return (\n prevProps.dataRef.id === nextProps.dataRef.id &&\n prevProps.node?.spec.id === nextProps.node?.spec.id\n );\n },\n);\n\nfunction Extension({ node, depth }: { node: AppNode; depth: number }) {\n const enabled = Boolean(node.instance);\n\n const tooltipText = useMemo(() => {\n const tooltipParts = [];\n let currentNode = node;\n tooltipParts.push(currentNode.spec.id);\n while (currentNode.edges.attachedTo) {\n const input = currentNode.edges.attachedTo.input;\n currentNode = currentNode.edges.attachedTo.node;\n tooltipParts.push(`${currentNode.spec.id} [${input}]`);\n }\n tooltipParts.reverse();\n return tooltipParts.join('\\n');\n }, [node]);\n\n const sortedDataRefs = useMemo(() => {\n if (!node.instance) {\n return [];\n }\n const dataRefs = [...node.instance.getDataRefs()];\n return dataRefs.sort((a, b) => a.id.localeCompare(b.id));\n }, [node.instance]);\n\n const sortedAttachments = useMemo(() => {\n return [...node.edges.attachments.entries()].sort(([a], [b]) =>\n a.localeCompare(b),\n );\n }, [node.edges.attachments]);\n\n return (\n <Box\n key={node.spec.id}\n style={{\n borderLeftWidth: 'var(--bui-space-1_5)',\n borderLeftStyle: 'solid',\n borderLeftColor: getBorderColor(depth),\n }}\n >\n <Flex\n py=\"1\"\n px=\"2\"\n align=\"center\"\n style={{\n width: 'fit-content',\n color: enabled ? 'var(--bui-fg-primary)' : 'var(--bui-fg-disabled)',\n background: 'var(--bui-bg-neutral-1)',\n borderTopRightRadius: 'var(--bui-radius-2)',\n borderBottomRightRadius: 'var(--bui-radius-2)',\n }}\n >\n <TooltipTrigger>\n <Focusable>\n <Text style={{ userSelect: 'all' }}>{node.spec.id}</Text>\n </Focusable>\n <Tooltip style={{ maxWidth: 'unset' }}>\n <Text style={{ whiteSpace: 'pre-wrap' }}>{tooltipText}</Text>\n </Tooltip>\n </TooltipTrigger>\n <Flex ml=\"2\" align=\"center\" gap=\"2\">\n {sortedDataRefs.length > 0 &&\n sortedDataRefs.map(ref => (\n <Output key={ref.id} dataRef={ref} node={node} />\n ))}\n {!enabled && <DisabledIcon size={16} />}\n </Flex>\n </Flex>\n {sortedAttachments.length > 0 && (\n <Flex direction=\"column\" gap=\"4\">\n {sortedAttachments.map(([key, children], idx) => (\n <Box key={key}>\n <Flex\n p=\"2\"\n align=\"center\"\n style={{\n borderTopWidth: 'var(--bui-space-1_5)',\n borderTopStyle: 'solid',\n borderTopColor: getBorderColor(depth),\n borderTop: idx === 0 ? 'none' : undefined,\n width: 'fit-content',\n }}\n >\n <InputIcon size={16} />\n <div style={{ marginLeft: 'var(--bui-space-2)' }}>{key}</div>\n </Flex>\n <Flex ml=\"2\" mb=\"2\" direction=\"column\" align=\"start\" gap=\"1\">\n <ProgressiveCollection\n items={children.map(childNode => () => (\n <Extension\n key={childNode.spec.id}\n node={childNode}\n depth={depth + 1}\n />\n ))}\n />\n </Flex>\n </Box>\n ))}\n </Flex>\n )}\n </Box>\n );\n}\n\nconst legendMap = {\n 'React Element': coreExtensionData.reactElement,\n 'Utility API': ApiBlueprint.dataRefs.factory,\n 'Route Path': coreExtensionData.routePath,\n 'Route Ref': coreExtensionData.routeRef,\n};\n\nfunction Legend() {\n return (\n <Box\n p=\"2\"\n style={{\n display: 'grid',\n maxWidth: 600,\n grid: 'auto-flow / repeat(3, 1fr)',\n gap: 'var(--bui-space-4)',\n }}\n >\n {Object.entries(legendMap).map(([label, dataRef]) => (\n <Flex key={dataRef.id} gap=\"2\" align=\"center\">\n <Output dataRef={dataRef} />\n <div>{label}</div>\n </Flex>\n ))}\n </Box>\n );\n}\n\nexport function DetailedVisualizer() {\n const appTreeApi = useApi(appTreeApiRef);\n const { tree } = appTreeApi.getTree();\n\n return (\n <FullPage>\n <Flex direction=\"column\" style={{ height: '100%', flex: '1 1 100%' }}>\n <Box ml=\"4\" mt=\"4\" style={{ flex: '1 1 0', overflow: 'auto' }}>\n <Extension node={tree.root} depth={0} />\n </Box>\n\n <Box\n m=\"2\"\n style={{\n flex: '0 0 auto',\n background: 'var(--bui-bg-neutral-1)',\n border: '1px solid var(--bui-border-2)',\n borderRadius: 'var(--bui-radius-2)',\n }}\n >\n <Legend />\n </Box>\n </Flex>\n </FullPage>\n );\n}\n"],"names":["getOutputColor","Fragment","Output","DisabledIcon","InputIcon"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,27 +3,6 @@ import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api'
3
3
 
4
4
  /** @public */
5
5
  declare const visualizerPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{}, {}, {
6
- "nav-item:app-visualizer": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
7
- kind: "nav-item";
8
- name: undefined;
9
- config: {
10
- title: string | undefined;
11
- };
12
- configInput: {
13
- title?: string | undefined;
14
- };
15
- output: _backstage_frontend_plugin_api.ExtensionDataRef<{
16
- title: string;
17
- icon: _backstage_frontend_plugin_api.IconComponent;
18
- routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
19
- }, "core.nav-item.target", {}>;
20
- inputs: {};
21
- params: {
22
- title: string;
23
- icon: _backstage_frontend_plugin_api.IconComponent;
24
- routeRef: _backstage_frontend_plugin_api.RouteRef<undefined>;
25
- };
26
- }>;
27
6
  "page:app-visualizer": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
28
7
  kind: "page";
29
8
  name: undefined;
@@ -1,5 +1,5 @@
1
1
  var name = "@backstage/plugin-app-visualizer";
2
- var version = "0.2.4-next.0";
2
+ var version = "0.2.4";
3
3
  var description = "Visualizes the Backstage app structure";
4
4
  var backstage = {
5
5
  role: "frontend-plugin",
@@ -37,7 +37,7 @@ var dependencies = {
37
37
  "@backstage/core-plugin-api": "workspace:^",
38
38
  "@backstage/frontend-plugin-api": "workspace:^",
39
39
  "@backstage/ui": "workspace:^",
40
- "@remixicon/react": "^4.6.0",
40
+ "@remixicon/react": ">=4.6.0 <4.9.0",
41
41
  "react-aria-components": "~1.17.0"
42
42
  };
43
43
  var devDependencies = {
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { createRouteRef, PageBlueprint, SubPageBlueprint, PluginHeaderActionBlueprint, NavItemBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
2
+ import { createRouteRef, PageBlueprint, SubPageBlueprint, PluginHeaderActionBlueprint, createFrontendPlugin } from '@backstage/frontend-plugin-api';
3
3
  import { RiEyeLine } from '@remixicon/react';
4
4
 
5
5
  const rootRouteRef = createRouteRef();
@@ -7,7 +7,8 @@ const appVisualizerPage = PageBlueprint.make({
7
7
  params: {
8
8
  path: "/visualizer",
9
9
  routeRef: rootRouteRef,
10
- title: "Visualizer"
10
+ title: "Visualizer",
11
+ icon: /* @__PURE__ */ jsx(RiEyeLine, {})
11
12
  }
12
13
  });
13
14
  const treeRouteRef = createRouteRef();
@@ -45,13 +46,6 @@ const copyTreeAsJson = PluginHeaderActionBlueprint.make({
45
46
  loader: () => import('./components/CopyTreeButton.esm.js').then((m) => /* @__PURE__ */ jsx(m.CopyTreeButton, {}))
46
47
  }
47
48
  });
48
- const appVisualizerNavItem = NavItemBlueprint.make({
49
- params: {
50
- title: "Visualizer",
51
- icon: () => /* @__PURE__ */ jsx(RiEyeLine, {}),
52
- routeRef: rootRouteRef
53
- }
54
- });
55
49
  const visualizerPlugin = createFrontendPlugin({
56
50
  pluginId: "app-visualizer",
57
51
  title: "App Visualizer",
@@ -62,10 +56,9 @@ const visualizerPlugin = createFrontendPlugin({
62
56
  appVisualizerTreePage,
63
57
  appVisualizerDetailedPage,
64
58
  appVisualizerTextPage,
65
- appVisualizerNavItem,
66
59
  copyTreeAsJson
67
60
  ]
68
61
  });
69
62
 
70
- export { appVisualizerNavItem, visualizerPlugin };
63
+ export { visualizerPlugin };
71
64
  //# sourceMappingURL=plugin.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 createFrontendPlugin,\n createRouteRef,\n NavItemBlueprint,\n PageBlueprint,\n PluginHeaderActionBlueprint,\n SubPageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { RiEyeLine } from '@remixicon/react';\n\nconst rootRouteRef = createRouteRef();\n\nconst appVisualizerPage = PageBlueprint.make({\n params: {\n path: '/visualizer',\n routeRef: rootRouteRef,\n title: 'Visualizer',\n },\n});\n\nconst treeRouteRef = createRouteRef();\nconst detailedRouteRef = createRouteRef();\nconst textRouteRef = createRouteRef();\n\nconst appVisualizerTreePage = SubPageBlueprint.make({\n name: 'tree',\n params: {\n path: 'tree',\n routeRef: treeRouteRef,\n title: 'Tree',\n loader: () =>\n import('./components/AppVisualizerPage/TreeVisualizer').then(m => (\n <m.TreeVisualizer />\n )),\n },\n});\nconst appVisualizerDetailedPage = SubPageBlueprint.make({\n name: 'details',\n params: {\n path: 'details',\n routeRef: detailedRouteRef,\n title: 'Detailed',\n loader: () =>\n import('./components/AppVisualizerPage/DetailedVisualizer').then(m => (\n <m.DetailedVisualizer />\n )),\n },\n});\nconst appVisualizerTextPage = SubPageBlueprint.make({\n name: 'text',\n params: {\n path: 'text',\n routeRef: textRouteRef,\n title: 'Text',\n loader: () =>\n import('./components/AppVisualizerPage/TextVisualizer').then(m => (\n <m.TextVisualizer />\n )),\n },\n});\n\nconst copyTreeAsJson = PluginHeaderActionBlueprint.make({\n params: {\n loader: () =>\n import('./components/CopyTreeButton').then(m => <m.CopyTreeButton />),\n },\n});\n\nexport const appVisualizerNavItem = NavItemBlueprint.make({\n params: {\n title: 'Visualizer',\n icon: () => <RiEyeLine />,\n routeRef: rootRouteRef,\n },\n});\n\n/** @public */\nexport const visualizerPlugin = createFrontendPlugin({\n pluginId: 'app-visualizer',\n title: 'App Visualizer',\n icon: <RiEyeLine />,\n info: { packageJson: () => import('../package.json') },\n extensions: [\n appVisualizerPage,\n appVisualizerTreePage,\n appVisualizerDetailedPage,\n appVisualizerTextPage,\n appVisualizerNavItem,\n copyTreeAsJson,\n ],\n});\n"],"names":[],"mappings":";;;;AA0BA,MAAM,eAAe,cAAA,EAAe;AAEpC,MAAM,iBAAA,GAAoB,cAAc,IAAA,CAAK;AAAA,EAC3C,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,aAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO;AAAA;AAEX,CAAC,CAAA;AAED,MAAM,eAAe,cAAA,EAAe;AACpC,MAAM,mBAAmB,cAAA,EAAe;AACxC,MAAM,eAAe,cAAA,EAAe;AAEpC,MAAM,qBAAA,GAAwB,iBAAiB,IAAA,CAAK;AAAA,EAClD,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,sDAA+C,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC3D,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CACnB;AAAA;AAEP,CAAC,CAAA;AACD,MAAM,yBAAA,GAA4B,iBAAiB,IAAA,CAAK;AAAA,EACtD,IAAA,EAAM,SAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,QAAA,EAAU,gBAAA;AAAA,IACV,KAAA,EAAO,UAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,0DAAmD,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC/D,GAAA,CAAC,CAAA,CAAE,kBAAA,EAAF,EAAqB,CACvB;AAAA;AAEP,CAAC,CAAA;AACD,MAAM,qBAAA,GAAwB,iBAAiB,IAAA,CAAK;AAAA,EAClD,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,sDAA+C,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC3D,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CACnB;AAAA;AAEP,CAAC,CAAA;AAED,MAAM,cAAA,GAAiB,4BAA4B,IAAA,CAAK;AAAA,EACtD,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,MACN,OAAO,oCAA6B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CAAE;AAAA;AAE1E,CAAC,CAAA;AAEM,MAAM,oBAAA,GAAuB,iBAAiB,IAAA,CAAK;AAAA,EACxD,MAAA,EAAQ;AAAA,IACN,KAAA,EAAO,YAAA;AAAA,IACP,IAAA,EAAM,sBAAM,GAAA,CAAC,SAAA,EAAA,EAAU,CAAA;AAAA,IACvB,QAAA,EAAU;AAAA;AAEd,CAAC;AAGM,MAAM,mBAAmB,oBAAA,CAAqB;AAAA,EACnD,QAAA,EAAU,gBAAA;AAAA,EACV,KAAA,EAAO,gBAAA;AAAA,EACP,IAAA,sBAAO,SAAA,EAAA,EAAU,CAAA;AAAA,EACjB,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,uBAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY;AAAA,IACV,iBAAA;AAAA,IACA,qBAAA;AAAA,IACA,yBAAA;AAAA,IACA,qBAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.tsx"],"sourcesContent":["/*\n * Copyright 2023 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 createFrontendPlugin,\n createRouteRef,\n PageBlueprint,\n PluginHeaderActionBlueprint,\n SubPageBlueprint,\n} from '@backstage/frontend-plugin-api';\nimport { RiEyeLine } from '@remixicon/react';\n\nconst rootRouteRef = createRouteRef();\n\nconst appVisualizerPage = PageBlueprint.make({\n params: {\n path: '/visualizer',\n routeRef: rootRouteRef,\n title: 'Visualizer',\n icon: <RiEyeLine />,\n },\n});\n\nconst treeRouteRef = createRouteRef();\nconst detailedRouteRef = createRouteRef();\nconst textRouteRef = createRouteRef();\n\nconst appVisualizerTreePage = SubPageBlueprint.make({\n name: 'tree',\n params: {\n path: 'tree',\n routeRef: treeRouteRef,\n title: 'Tree',\n loader: () =>\n import('./components/AppVisualizerPage/TreeVisualizer').then(m => (\n <m.TreeVisualizer />\n )),\n },\n});\nconst appVisualizerDetailedPage = SubPageBlueprint.make({\n name: 'details',\n params: {\n path: 'details',\n routeRef: detailedRouteRef,\n title: 'Detailed',\n loader: () =>\n import('./components/AppVisualizerPage/DetailedVisualizer').then(m => (\n <m.DetailedVisualizer />\n )),\n },\n});\nconst appVisualizerTextPage = SubPageBlueprint.make({\n name: 'text',\n params: {\n path: 'text',\n routeRef: textRouteRef,\n title: 'Text',\n loader: () =>\n import('./components/AppVisualizerPage/TextVisualizer').then(m => (\n <m.TextVisualizer />\n )),\n },\n});\n\nconst copyTreeAsJson = PluginHeaderActionBlueprint.make({\n params: {\n loader: () =>\n import('./components/CopyTreeButton').then(m => <m.CopyTreeButton />),\n },\n});\n\n/** @public */\nexport const visualizerPlugin = createFrontendPlugin({\n pluginId: 'app-visualizer',\n title: 'App Visualizer',\n icon: <RiEyeLine />,\n info: { packageJson: () => import('../package.json') },\n extensions: [\n appVisualizerPage,\n appVisualizerTreePage,\n appVisualizerDetailedPage,\n appVisualizerTextPage,\n copyTreeAsJson,\n ],\n});\n"],"names":[],"mappings":";;;;AAyBA,MAAM,eAAe,cAAA,EAAe;AAEpC,MAAM,iBAAA,GAAoB,cAAc,IAAA,CAAK;AAAA,EAC3C,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,aAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO,YAAA;AAAA,IACP,IAAA,sBAAO,SAAA,EAAA,EAAU;AAAA;AAErB,CAAC,CAAA;AAED,MAAM,eAAe,cAAA,EAAe;AACpC,MAAM,mBAAmB,cAAA,EAAe;AACxC,MAAM,eAAe,cAAA,EAAe;AAEpC,MAAM,qBAAA,GAAwB,iBAAiB,IAAA,CAAK;AAAA,EAClD,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,sDAA+C,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC3D,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CACnB;AAAA;AAEP,CAAC,CAAA;AACD,MAAM,yBAAA,GAA4B,iBAAiB,IAAA,CAAK;AAAA,EACtD,IAAA,EAAM,SAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,QAAA,EAAU,gBAAA;AAAA,IACV,KAAA,EAAO,UAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,0DAAmD,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC/D,GAAA,CAAC,CAAA,CAAE,kBAAA,EAAF,EAAqB,CACvB;AAAA;AAEP,CAAC,CAAA;AACD,MAAM,qBAAA,GAAwB,iBAAiB,IAAA,CAAK;AAAA,EAClD,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,MAAA;AAAA,IACN,QAAA,EAAU,YAAA;AAAA,IACV,KAAA,EAAO,MAAA;AAAA,IACP,MAAA,EAAQ,MACN,OAAO,sDAA+C,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC3D,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CACnB;AAAA;AAEP,CAAC,CAAA;AAED,MAAM,cAAA,GAAiB,4BAA4B,IAAA,CAAK;AAAA,EACtD,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,MACN,OAAO,oCAA6B,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAAK,GAAA,CAAC,CAAA,CAAE,cAAA,EAAF,EAAiB,CAAE;AAAA;AAE1E,CAAC,CAAA;AAGM,MAAM,mBAAmB,oBAAA,CAAqB;AAAA,EACnD,QAAA,EAAU,gBAAA;AAAA,EACV,KAAA,EAAO,gBAAA;AAAA,EACP,IAAA,sBAAO,SAAA,EAAA,EAAU,CAAA;AAAA,EACjB,MAAM,EAAE,WAAA,EAAa,MAAM,OAAO,uBAAiB,CAAA,EAAE;AAAA,EACrD,UAAA,EAAY;AAAA,IACV,iBAAA;AAAA,IACA,qBAAA;AAAA,IACA,yBAAA;AAAA,IACA,qBAAA;AAAA,IACA;AAAA;AAEJ,CAAC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-app-visualizer",
3
- "version": "0.2.4-next.0",
3
+ "version": "0.2.4",
4
4
  "description": "Visualizes the Backstage app structure",
5
5
  "backstage": {
6
6
  "role": "frontend-plugin",
@@ -37,16 +37,16 @@
37
37
  "test": "backstage-cli package test"
38
38
  },
39
39
  "dependencies": {
40
- "@backstage/core-components": "0.18.10-next.0",
41
- "@backstage/core-plugin-api": "1.12.6-next.0",
42
- "@backstage/frontend-plugin-api": "0.17.0-next.0",
43
- "@backstage/ui": "0.15.0-next.0",
44
- "@remixicon/react": "^4.6.0",
40
+ "@backstage/core-components": "^0.18.10",
41
+ "@backstage/core-plugin-api": "^1.12.6",
42
+ "@backstage/frontend-plugin-api": "^0.17.0",
43
+ "@backstage/ui": "^0.15.0",
44
+ "@remixicon/react": ">=4.6.0 <4.9.0",
45
45
  "react-aria-components": "~1.17.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@backstage/cli": "0.36.2-next.0",
49
- "@backstage/frontend-dev-utils": "0.1.2-next.0",
48
+ "@backstage/cli": "^0.36.2",
49
+ "@backstage/frontend-dev-utils": "^0.1.2",
50
50
  "@types/react": "^18.0.0",
51
51
  "react": "^18.0.2",
52
52
  "react-dom": "^18.0.2",