Added DevTools plugin
Signed-off-by: Andre Wanlin <67169551+awanlin@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createApiRef } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
ConfigInfo,
|
||||
DevToolsInfo,
|
||||
ExternalDependency,
|
||||
} from '@backstage/plugin-devtools-common';
|
||||
|
||||
export const devToolsApiRef = createApiRef<DevToolsApi>({
|
||||
id: 'plugin.devtools.service',
|
||||
});
|
||||
|
||||
export interface DevToolsApi {
|
||||
getConfig(): Promise<ConfigInfo | undefined>;
|
||||
getExternalDependencies(): Promise<ExternalDependency[] | undefined>;
|
||||
getInfo(): Promise<DevToolsInfo | undefined>;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
|
||||
import {
|
||||
ConfigInfo,
|
||||
DevToolsInfo,
|
||||
ExternalDependency,
|
||||
} from '@backstage/plugin-devtools-common';
|
||||
import { ResponseError } from '@backstage/errors';
|
||||
import { DevToolsApi } from './DevToolsApi';
|
||||
|
||||
export class DevToolsClient implements DevToolsApi {
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
private readonly identityApi: IdentityApi;
|
||||
|
||||
public constructor(options: {
|
||||
discoveryApi: DiscoveryApi;
|
||||
identityApi: IdentityApi;
|
||||
}) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
this.identityApi = options.identityApi;
|
||||
}
|
||||
|
||||
public async getConfig(): Promise<ConfigInfo | undefined> {
|
||||
const urlSegment = 'config';
|
||||
|
||||
const configInfo = await this.get<ConfigInfo | undefined>(urlSegment);
|
||||
return configInfo;
|
||||
}
|
||||
|
||||
public async getExternalDependencies(): Promise<
|
||||
ExternalDependency[] | undefined
|
||||
> {
|
||||
const urlSegment = 'external-dependencies';
|
||||
|
||||
const externalDependencies = await this.get<
|
||||
ExternalDependency[] | undefined
|
||||
>(urlSegment);
|
||||
return externalDependencies;
|
||||
}
|
||||
|
||||
public async getInfo(): Promise<DevToolsInfo | undefined> {
|
||||
const urlSegment = 'info';
|
||||
|
||||
const info = await this.get<DevToolsInfo | undefined>(urlSegment);
|
||||
return info;
|
||||
}
|
||||
|
||||
private async get<T>(path: string): Promise<T> {
|
||||
const baseUrl = `${await this.discoveryApi.getBaseUrl('devtools')}/`;
|
||||
const url = new URL(path, baseUrl);
|
||||
|
||||
const { token } = await this.identityApi.getCredentials();
|
||||
const response = await fetch(url.toString(), {
|
||||
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw await ResponseError.fromResponse(response);
|
||||
}
|
||||
|
||||
return response.json() as Promise<T>;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './DevToolsApi';
|
||||
export * from './DevToolsClient';
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Progress, WarningPanel } from '@backstage/core-components';
|
||||
import {
|
||||
Box,
|
||||
createStyles,
|
||||
makeStyles,
|
||||
Paper,
|
||||
Theme,
|
||||
Typography,
|
||||
useTheme,
|
||||
} from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import React from 'react';
|
||||
import ReactJson from 'react-json-view';
|
||||
import { useConfig } from '../../../hooks';
|
||||
import { ConfigError } from '@backstage/plugin-devtools-common';
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
warningStyle: {
|
||||
paddingBottom: theme.spacing(2),
|
||||
},
|
||||
paperStyle: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const WarningContent = ({ error }: { error: ConfigError }) => {
|
||||
if (!error.messages) {
|
||||
return <Typography>{error.message}</Typography>;
|
||||
}
|
||||
|
||||
const messages = error.messages as string[];
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{messages.map(message => (
|
||||
<Typography>{message}</Typography>
|
||||
))}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const ConfigContent = () => {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
const { configInfo, loading, error } = useConfig();
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
} else if (error) {
|
||||
return <Alert severity="error">{error.message}</Alert>;
|
||||
}
|
||||
|
||||
if (!configInfo) {
|
||||
return <Alert severity="error">Unable to load config data</Alert>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{configInfo && configInfo.error && (
|
||||
<Box className={classes.warningStyle}>
|
||||
<WarningPanel title="Config validation failed">
|
||||
<WarningContent error={configInfo.error} />
|
||||
</WarningPanel>
|
||||
</Box>
|
||||
)}
|
||||
<Paper className={classes.paperStyle}>
|
||||
<ReactJson
|
||||
src={configInfo.config as object}
|
||||
name="config"
|
||||
enableClipboard={false}
|
||||
theme={theme.palette.type === 'dark' ? 'monokai' : 'rjv-default'}
|
||||
/>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ConfigContent } from './ConfigContent';
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Progress,
|
||||
StatusError,
|
||||
StatusOK,
|
||||
StatusWarning,
|
||||
Table,
|
||||
TableColumn,
|
||||
} from '@backstage/core-components';
|
||||
import { ExternalDependency } from '@backstage/plugin-devtools-common';
|
||||
import {
|
||||
Box,
|
||||
createStyles,
|
||||
Grid,
|
||||
makeStyles,
|
||||
Paper,
|
||||
Theme,
|
||||
Typography,
|
||||
} from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import React from 'react';
|
||||
import { useExternalDependencies } from '../../../hooks';
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
paperStyle: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
export const getExternalDependencyStatus = (
|
||||
result: Partial<ExternalDependency> | undefined,
|
||||
) => {
|
||||
switch (result?.status) {
|
||||
case 'Healthy':
|
||||
return (
|
||||
<Typography component="span">
|
||||
<StatusOK /> {result.status}
|
||||
</Typography>
|
||||
);
|
||||
case 'Unhealthy':
|
||||
return (
|
||||
<Typography component="span">
|
||||
<StatusError /> {`${result.status}`}
|
||||
</Typography>
|
||||
);
|
||||
case undefined:
|
||||
default:
|
||||
return (
|
||||
<Typography component="span">
|
||||
<StatusWarning /> Unknown
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
width: 'auto',
|
||||
field: 'name',
|
||||
},
|
||||
{
|
||||
title: 'Target',
|
||||
width: 'auto',
|
||||
field: 'target',
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
width: 'auto',
|
||||
field: 'type',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
width: 'auto',
|
||||
render: (row: Partial<ExternalDependency>) => (
|
||||
<Grid container direction="column">
|
||||
<Grid item>
|
||||
<Typography variant="button">
|
||||
{getExternalDependencyStatus(row)}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>{row.error && <Typography>{row.error}</Typography>}</Grid>
|
||||
</Grid>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
/** @public */
|
||||
export const ExternalDependenciesContent = () => {
|
||||
const classes = useStyles();
|
||||
const { externalDependencies, loading, error } = useExternalDependencies();
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
} else if (error) {
|
||||
return <Alert severity="error">{error.message}</Alert>;
|
||||
}
|
||||
|
||||
if (!externalDependencies || externalDependencies.length === 0) {
|
||||
return (
|
||||
<Box>
|
||||
<Paper className={classes.paperStyle}>
|
||||
<Typography>No external dependencies found</Typography>
|
||||
</Paper>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Table
|
||||
title="Status"
|
||||
options={{
|
||||
paging: true,
|
||||
pageSize: 20,
|
||||
pageSizeOptions: [20, 50, 100],
|
||||
loadingType: 'linear',
|
||||
showEmptyDataSourceMessage: !loading,
|
||||
}}
|
||||
columns={columns}
|
||||
data={externalDependencies || []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ExternalDependenciesContent } from './ExternalDependenciesContent';
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SvgIcon, SvgIconProps } from '@material-ui/core';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export const BackstageLogoIcon = (props: SvgIconProps) => (
|
||||
<SvgIcon {...props} viewBox="0 0 337.46 428.5">
|
||||
<path d="M303 166.05a80.69 80.69 0 0013.45-10.37c.79-.77 1.55-1.53 2.3-2.3a83.12 83.12 0 007.93-9.38 63.69 63.69 0 006.32-10.77 48.58 48.58 0 004.35-16.4c1.49-19.39-10-38.67-35.62-54.22L198.56 0 78.3 115.23 0 190.25l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.69 19.16-18.36 25.52-42.12 13.7-61.87a49.22 49.22 0 00-6.8-8.87 89.17 89.17 0 0019.32 2.15h.15a85.08 85.08 0 0031-5.79 80.88 80.88 0 0012.85-6.45zm-100.55 59.81c-19.32 18.51-50.4 21.23-75.7 5.9l-75.14-45.61 67.45-64.64 76.41 46.38c27.53 16.69 26.02 39.72 6.98 57.97zm8.93-82.22l-70.65-42.89L205.14 39l69.37 42.1c25.94 15.72 29.31 37 10.55 55a60.69 60.69 0 01-73.68 7.54zm29.86 190c-19.57 18.75-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 282.52v24.67l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.75-46.17 29.08-74.88 29.08a123.81 123.81 0 01-64.1-18.19L0 243.53v24.68l108.6 65.91a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.81 66.42-25.69 12.88-12.34 20-27.13 19.68-41.5v-1.78a87.27 87.27 0 01-11.22 13.13zm0-39c-19.57 18.76-46.17 29.09-74.88 29.09a123.81 123.81 0 01-64.1-18.19L0 204.55v24.68l108.6 65.91a111.59 111.59 0 0057.76 16.41c24.92 0 48.8-8.8 66.42-25.68 12.88-12.35 20-27.13 19.68-41.5v-1.82a86.09 86.09 0 01-11.22 13.16zm83.7 25.74a94.15 94.15 0 01-60.2 25.86V334a81.6 81.6 0 0051.74-22.37c14-13.38 21.14-28.11 21-42.64v-2.19a94.92 94.92 0 01-12.54 14.65zm-83.7 91.21c-19.57 18.76-46.17 29.09-74.88 29.09a123.73 123.73 0 01-64.1-18.2L0 321.5v24.68l108.6 65.9a111.6 111.6 0 0057.76 16.42c24.92 0 48.8-8.8 66.42-25.69 12.88-12.34 20-27.13 19.68-41.49v-1.79a86.29 86.29 0 01-11.22 13.13zM327 162.45c-.68.69-1.35 1.38-2.05 2.06a94.37 94.37 0 01-10.64 8.65 91.35 91.35 0 01-11.6 7 94.53 94.53 0 01-26.24 8.71 97.69 97.69 0 01-14.16 1.57c.5 1.61.9 3.25 1.25 4.9a53.27 53.27 0 011.14 12V217h.05a84.41 84.41 0 0025.35-5.55 81 81 0 0026.39-16.82c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.32-10.74 48.55 48.55 0 004.32-16.45c.09-1.23.2-2.47.19-3.7V150q-1.08 1.54-2.25 3.09a96.73 96.73 0 01-8.26 9.36zm0 77.92c-.69.7-1.31 1.41-2 2.1a94.2 94.2 0 01-60.2 25.86V295a81.6 81.6 0 0051.74-22.37 73.51 73.51 0 0016.46-22.5 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.47.19-3.71v-2.19c-.74 1.07-1.46 2.15-2.27 3.21a95.68 95.68 0 01-8.24 9.37zm0-39c-.69.7-1.31 1.41-2 2.1a93.18 93.18 0 01-10.63 8.65 91.63 91.63 0 01-11.63 7 95.47 95.47 0 01-37.94 10.18V256a81.65 81.65 0 0051.74-22.37c.8-.77 1.5-1.56 2.26-2.34a82.08 82.08 0 007.93-9.38 63.76 63.76 0 006.27-10.76 48.56 48.56 0 004.32-16.44c.09-1.24.2-2.48.19-3.71v-2.2c-.74 1.08-1.46 2.16-2.27 3.22a95.68 95.68 0 01-8.24 9.37z" />
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Progress } from '@backstage/core-components';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
createStyles,
|
||||
Divider,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
Paper,
|
||||
Theme,
|
||||
} from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import React from 'react';
|
||||
import { useInfo } from '../../../hooks';
|
||||
import { InfoDependenciesTable } from './InfoDependenciesTable';
|
||||
import DescriptionIcon from '@material-ui/icons/Description';
|
||||
import DeveloperBoardIcon from '@material-ui/icons/DeveloperBoard';
|
||||
import { BackstageLogoIcon } from './BackstageLogoIcon';
|
||||
import FileCopyIcon from '@material-ui/icons/FileCopy';
|
||||
import { DevToolsInfo } from '@backstage/plugin-devtools-common';
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
paperStyle: {
|
||||
marginBottom: theme.spacing(2),
|
||||
},
|
||||
flexContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
padding: 0,
|
||||
},
|
||||
copyButton: {
|
||||
float: 'left',
|
||||
margin: theme.spacing(2),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const copyToClipboard = ({ about }: { about: DevToolsInfo | undefined }) => {
|
||||
if (about) {
|
||||
let formatted = `OS: ${about.operatingSystem}\nnode: ${about.nodeJsVersion}\nbackstage: ${about.backstageVersion}\nDependencies:\n`;
|
||||
const deps = about.dependencies;
|
||||
for (const key in deps) {
|
||||
if (Object.prototype.hasOwnProperty.call(deps, key)) {
|
||||
formatted = `${formatted} ${deps[key].name}: ${deps[key].versions}\n`;
|
||||
}
|
||||
}
|
||||
window.navigator.clipboard.writeText(formatted);
|
||||
}
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const InfoContent = () => {
|
||||
const classes = useStyles();
|
||||
const { about, loading, error } = useInfo();
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
} else if (error) {
|
||||
return <Alert severity="error">{error.message}</Alert>;
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Paper className={classes.paperStyle}>
|
||||
<List className={classes.flexContainer}>
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DeveloperBoardIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary="Operating System"
|
||||
secondary={about?.operatingSystem}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<DescriptionIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary="NodeJS Version"
|
||||
secondary={about?.nodeJsVersion}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<BackstageLogoIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText
|
||||
primary="Backstage Version"
|
||||
secondary={about?.backstageVersion}
|
||||
/>
|
||||
</ListItem>
|
||||
<Divider orientation="vertical" variant="middle" flexItem />
|
||||
<ListItem
|
||||
button
|
||||
onClick={() => {
|
||||
copyToClipboard({ about });
|
||||
}}
|
||||
className={classes.copyButton}
|
||||
>
|
||||
<ListItemAvatar>
|
||||
<Avatar>
|
||||
<FileCopyIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Copy Info to Clipboard" />
|
||||
</ListItem>
|
||||
</List>
|
||||
</Paper>
|
||||
<InfoDependenciesTable infoDependencies={about?.dependencies} />
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Table, TableColumn } from '@backstage/core-components';
|
||||
import { PackageDependency } from '@backstage/plugin-devtools-common';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const columns: TableColumn[] = [
|
||||
{
|
||||
title: 'Name',
|
||||
width: 'auto',
|
||||
field: 'name',
|
||||
defaultSort: 'asc',
|
||||
},
|
||||
{
|
||||
title: 'Versions',
|
||||
width: 'auto',
|
||||
field: 'versions',
|
||||
},
|
||||
];
|
||||
|
||||
export const InfoDependenciesTable = ({
|
||||
infoDependencies,
|
||||
}: {
|
||||
infoDependencies: PackageDependency[] | undefined;
|
||||
}) => {
|
||||
return (
|
||||
<Table
|
||||
title="Package Dependencies"
|
||||
options={{
|
||||
paging: true,
|
||||
pageSize: 15,
|
||||
pageSizeOptions: [15, 30, 100],
|
||||
loadingType: 'linear',
|
||||
padding: 'dense',
|
||||
}}
|
||||
columns={columns}
|
||||
data={infoDependencies || []}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { InfoContent } from './InfoContent';
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './ConfigContent';
|
||||
export * from './InfoContent';
|
||||
export * from './ExternalDependenciesContent';
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
devToolsConfigReadPermission,
|
||||
devToolsInfoReadPermission,
|
||||
} from '@backstage/plugin-devtools-common';
|
||||
|
||||
import { ConfigContent } from '../Content/ConfigContent';
|
||||
import { DevToolsLayout } from '../DevToolsLayout';
|
||||
import { InfoContent } from '../Content/InfoContent';
|
||||
import React from 'react';
|
||||
import { RequirePermission } from '@backstage/plugin-permission-react';
|
||||
|
||||
/** @public */
|
||||
export const DefaultDevToolsPage = () => (
|
||||
<DevToolsLayout>
|
||||
<DevToolsLayout.Route path="info" title="Info">
|
||||
<RequirePermission permission={devToolsInfoReadPermission}>
|
||||
<InfoContent />
|
||||
</RequirePermission>
|
||||
</DevToolsLayout.Route>
|
||||
<DevToolsLayout.Route path="config" title="Config">
|
||||
<RequirePermission permission={devToolsConfigReadPermission}>
|
||||
<ConfigContent />
|
||||
</RequirePermission>
|
||||
</DevToolsLayout.Route>
|
||||
</DevToolsLayout>
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DefaultDevToolsPage } from './DefaultDevToolsPage';
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Header, Page, RoutedTabs } from '@backstage/core-components';
|
||||
import {
|
||||
attachComponentData,
|
||||
useElementFilter,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { TabProps } from '@material-ui/core';
|
||||
import { default as React } from 'react';
|
||||
|
||||
/** @public */
|
||||
export type SubRoute = {
|
||||
path: string;
|
||||
title: string;
|
||||
children: JSX.Element;
|
||||
tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;
|
||||
};
|
||||
|
||||
const dataKey = 'plugin.devtools.devtoolsLayoutRoute';
|
||||
|
||||
const Route: (props: SubRoute) => null = () => null;
|
||||
attachComponentData(Route, dataKey, true);
|
||||
|
||||
// This causes all mount points that are discovered within this route to use the path of the route itself
|
||||
attachComponentData(Route, 'core.gatherMountPoints', true);
|
||||
|
||||
/** @public */
|
||||
export type DevToolsLayoutProps = {
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* DevTools is a compound component, which allows you to define a custom layout
|
||||
*
|
||||
* @example
|
||||
* ```jsx
|
||||
* <DevToolsLayout>
|
||||
* <DevToolsLayout.Route path="/example" title="Example tab">
|
||||
* <div>This is rendered under /example/anything-here route</div>
|
||||
* </DevToolsLayout.Route>
|
||||
* </DevToolsLayout>
|
||||
* ```
|
||||
* @public
|
||||
*/
|
||||
export const DevToolsLayout = ({ children }: DevToolsLayoutProps) => {
|
||||
const routes = useElementFilter(children, elements =>
|
||||
elements
|
||||
.selectByComponentData({
|
||||
key: dataKey,
|
||||
withStrictError:
|
||||
'Child of DevToolsLayout must be an DevToolsLayout.Route',
|
||||
})
|
||||
.getElements<SubRoute>()
|
||||
.map(child => child.props),
|
||||
);
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
<Header title="Backstage DevTools" />
|
||||
<RoutedTabs routes={routes} />
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
DevToolsLayout.Route = Route;
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type { DevToolsLayoutProps, SubRoute } from './DevToolsLayout';
|
||||
export { DevToolsLayout } from './DevToolsLayout';
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { useOutlet } from 'react-router-dom';
|
||||
import { DefaultDevToolsPage } from '../DefaultDevToolsPage';
|
||||
|
||||
export const DevToolsPage = () => {
|
||||
const outlet = useOutlet();
|
||||
|
||||
return <>{outlet || <DefaultDevToolsPage />}</>;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DevToolsPage } from './DevToolsPage';
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './Content';
|
||||
export * from './DevToolsLayout';
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { useConfig } from './useConfig';
|
||||
export { useExternalDependencies } from './useExternalDependencies';
|
||||
export { useInfo } from './useInfo';
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devToolsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { ConfigInfo } from '@backstage/plugin-devtools-common';
|
||||
|
||||
export function useConfig(): {
|
||||
configInfo?: ConfigInfo;
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const api = useApi(devToolsApiRef);
|
||||
const { value, loading, error } = useAsync(() => {
|
||||
return api.getConfig();
|
||||
}, [api]);
|
||||
|
||||
return {
|
||||
configInfo: value,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devToolsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { ExternalDependency } from '@backstage/plugin-devtools-common';
|
||||
|
||||
export function useExternalDependencies(): {
|
||||
externalDependencies?: ExternalDependency[];
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const api = useApi(devToolsApiRef);
|
||||
const { value, loading, error } = useAsync(() => {
|
||||
return api.getExternalDependencies();
|
||||
}, [api]);
|
||||
|
||||
return {
|
||||
externalDependencies: value,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devToolsApiRef } from '../api';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
import { DevToolsInfo } from '@backstage/plugin-devtools-common';
|
||||
|
||||
export function useInfo(): {
|
||||
about?: DevToolsInfo;
|
||||
loading: boolean;
|
||||
error?: Error;
|
||||
} {
|
||||
const api = useApi(devToolsApiRef);
|
||||
const { value, loading, error } = useAsync(() => {
|
||||
return api.getInfo();
|
||||
}, [api]);
|
||||
|
||||
return {
|
||||
about: value,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { devToolsPlugin, DevToolsPage } from './plugin';
|
||||
export * from './components';
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { devToolsPlugin } from './plugin';
|
||||
|
||||
describe('devtools', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(devToolsPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
createApiFactory,
|
||||
createPlugin,
|
||||
createRoutableExtension,
|
||||
discoveryApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { devToolsApiRef, DevToolsClient } from './api';
|
||||
|
||||
import { rootRouteRef } from './routes';
|
||||
|
||||
/** @public */
|
||||
export const devToolsPlugin = createPlugin({
|
||||
id: 'devtools',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
api: devToolsApiRef,
|
||||
deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },
|
||||
factory: ({ discoveryApi, identityApi }) =>
|
||||
new DevToolsClient({ discoveryApi, identityApi }),
|
||||
}),
|
||||
],
|
||||
routes: {
|
||||
root: rootRouteRef,
|
||||
},
|
||||
});
|
||||
|
||||
/** @public */
|
||||
export const DevToolsPage = devToolsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
name: 'DevToolsPage',
|
||||
component: () =>
|
||||
import('./components/DevToolsPage').then(m => m.DevToolsPage),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouteRef } from '@backstage/core-plugin-api';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
id: 'devtools',
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import '@testing-library/jest-dom';
|
||||
Reference in New Issue
Block a user