frontend-plugin-api: initial support for subpages
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
|
||||
import { Content, Header, HeaderTabs, Page } from '@backstage/core-components';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { appTreeApiRef } from '@backstage/frontend-plugin-api';
|
||||
import { Flex } from '@backstage/ui';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { DetailedVisualizer } from './DetailedVisualizer';
|
||||
@@ -31,31 +29,28 @@ import {
|
||||
} from 'react-router-dom';
|
||||
|
||||
export function AppVisualizerPage() {
|
||||
const appTreeApi = useApi(appTreeApiRef);
|
||||
const { tree } = appTreeApi.getTree();
|
||||
|
||||
const tabs = useMemo(
|
||||
() => [
|
||||
{
|
||||
id: 'tree',
|
||||
path: 'tree',
|
||||
label: 'Tree',
|
||||
element: <TreeVisualizer tree={tree} />,
|
||||
element: <TreeVisualizer />,
|
||||
},
|
||||
{
|
||||
id: 'detailed',
|
||||
path: 'detailed',
|
||||
label: 'Detailed',
|
||||
element: <DetailedVisualizer tree={tree} />,
|
||||
element: <DetailedVisualizer />,
|
||||
},
|
||||
{
|
||||
id: 'text',
|
||||
path: 'text',
|
||||
label: 'Text',
|
||||
element: <TextVisualizer tree={tree} />,
|
||||
element: <TextVisualizer />,
|
||||
},
|
||||
],
|
||||
[tree],
|
||||
[],
|
||||
);
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
import {
|
||||
AppNode,
|
||||
AppTree,
|
||||
ExtensionDataRef,
|
||||
coreExtensionData,
|
||||
ApiBlueprint,
|
||||
NavItemBlueprint,
|
||||
useApi,
|
||||
routeResolutionApiRef,
|
||||
appTreeApiRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { Box, Flex, Link, Text, Tooltip, TooltipTrigger } from '@backstage/ui';
|
||||
import {
|
||||
@@ -351,7 +351,10 @@ function Legend() {
|
||||
);
|
||||
}
|
||||
|
||||
export function DetailedVisualizer({ tree }: { tree: AppTree }) {
|
||||
export function DetailedVisualizer() {
|
||||
const appTreeApi = useApi(appTreeApiRef);
|
||||
const { tree } = appTreeApi.getTree();
|
||||
|
||||
return (
|
||||
<Flex direction="column" style={{ height: '100%', flex: '1 1 100%' }}>
|
||||
<Box ml="4" mt="4" style={{ flex: '1 1 0', overflow: 'auto' }}>
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AppNode, AppTree } from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
AppNode,
|
||||
useApi,
|
||||
appTreeApiRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { Box, Checkbox } from '@backstage/ui';
|
||||
import { ReactNode, useState } from 'react';
|
||||
|
||||
@@ -77,7 +81,9 @@ function nodeToText(
|
||||
]);
|
||||
}
|
||||
|
||||
export function TextVisualizer({ tree }: { tree: AppTree }) {
|
||||
export function TextVisualizer() {
|
||||
const appTreeApi = useApi(appTreeApiRef);
|
||||
const { tree } = appTreeApi.getTree();
|
||||
const [showOutputs, setShowOutputs] = useState(false);
|
||||
const [showDisabled, setShowDisabled] = useState(false);
|
||||
|
||||
|
||||
@@ -18,7 +18,12 @@ import {
|
||||
DependencyGraph,
|
||||
DependencyGraphTypes,
|
||||
} from '@backstage/core-components';
|
||||
import { AppNode, AppTree } from '@backstage/frontend-plugin-api';
|
||||
import {
|
||||
AppNode,
|
||||
AppTree,
|
||||
useApi,
|
||||
appTreeApiRef,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { Flex } from '@backstage/ui';
|
||||
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
@@ -137,7 +142,9 @@ export function Node(props: { node: NodeType }) {
|
||||
);
|
||||
}
|
||||
|
||||
export function TreeVisualizer({ tree }: { tree: AppTree }) {
|
||||
export function TreeVisualizer() {
|
||||
const appTreeApi = useApi(appTreeApiRef);
|
||||
const { tree } = appTreeApi.getTree();
|
||||
const graphData = useMemo(() => resolveGraphData(tree), [tree]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
createRouteRef,
|
||||
NavItemBlueprint,
|
||||
PageBlueprint,
|
||||
SubPageBlueprint,
|
||||
} from '@backstage/frontend-plugin-api';
|
||||
import { RiEyeLine as VisualizerIcon } from '@remixicon/react';
|
||||
|
||||
@@ -28,10 +29,87 @@ const appVisualizerPage = PageBlueprint.make({
|
||||
params: {
|
||||
path: '/visualizer',
|
||||
routeRef: rootRouteRef,
|
||||
title: 'Visualizer',
|
||||
// loader: async () => <div>The root page</div>,
|
||||
},
|
||||
});
|
||||
|
||||
const appVisualizerPage2 = PageBlueprint.make({
|
||||
name: '2',
|
||||
params: {
|
||||
path: '/visualizer/something-else',
|
||||
routeRef: createRouteRef(),
|
||||
title: 'something else',
|
||||
loader: async () => <div>The root sdsd</div>,
|
||||
},
|
||||
});
|
||||
/*
|
||||
// inputs:
|
||||
// pages: [explicitly subrouteref as a data type + element + path]
|
||||
const rootPage = TabbedPageBlueprint.make({
|
||||
params: {
|
||||
path: '/visualizer',
|
||||
routeRef: rootRouteRef,
|
||||
actions: [
|
||||
]
|
||||
subpages: [
|
||||
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const treePageThing = PluginContentTopBarNavigableContentBlueprint.make({
|
||||
attachTo: {
|
||||
|
||||
}
|
||||
params: {
|
||||
routeRef: treeSubRouteRef,
|
||||
loader: () => null,
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
const treeRouteRef = createRouteRef();
|
||||
const detailedRouteRef = createRouteRef();
|
||||
const textRouteRef = createRouteRef();
|
||||
|
||||
const appVisualizerTreePage = SubPageBlueprint.make({
|
||||
attachTo: { id: 'page:app-visualizer', input: 'pages' },
|
||||
name: 'tree',
|
||||
params: {
|
||||
path: 'tree',
|
||||
routeRef: treeRouteRef,
|
||||
title: 'Tree',
|
||||
loader: () =>
|
||||
import('./components/AppVisualizerPage').then(m => (
|
||||
<m.AppVisualizerPage />
|
||||
)),
|
||||
import('./components/AppVisualizerPage/TreeVisualizer').then(
|
||||
m => <m.TreeVisualizer />,
|
||||
),
|
||||
},
|
||||
});
|
||||
const appVisualizerDetailedPage = SubPageBlueprint.make({
|
||||
attachTo: { id: 'page:app-visualizer', input: 'pages' },
|
||||
name: 'details',
|
||||
params: {
|
||||
path: 'details',
|
||||
routeRef: detailedRouteRef,
|
||||
title: 'Detailed',
|
||||
loader: () =>
|
||||
import('./components/AppVisualizerPage/DetailedVisualizer').then(
|
||||
m => <m.DetailedVisualizer />,
|
||||
),
|
||||
},
|
||||
});
|
||||
const appVisualizerTextPage = SubPageBlueprint.make({
|
||||
attachTo: { id: 'page:app-visualizer', input: 'pages' },
|
||||
name: 'text',
|
||||
params: {
|
||||
path: 'text',
|
||||
routeRef: textRouteRef,
|
||||
title: 'Text',
|
||||
loader: () =>
|
||||
import('./components/AppVisualizerPage/TextVisualizer').then(
|
||||
m => <m.TextVisualizer />,
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -47,5 +125,12 @@ export const appVisualizerNavItem = NavItemBlueprint.make({
|
||||
export const visualizerPlugin = createFrontendPlugin({
|
||||
pluginId: 'app-visualizer',
|
||||
info: { packageJson: () => import('../package.json') },
|
||||
extensions: [appVisualizerPage, appVisualizerNavItem],
|
||||
extensions: [
|
||||
appVisualizerPage,
|
||||
appVisualizerPage2,
|
||||
appVisualizerTreePage,
|
||||
appVisualizerDetailedPage,
|
||||
appVisualizerTextPage,
|
||||
appVisualizerNavItem,
|
||||
],
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user