Merge pull request #6339 from ngranander/xcmetrics-dashboard-mvp
Add XCMetrics Plugin
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@backstage/cli/config/eslint')],
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
# XCMetrics
|
||||
|
||||
[XCMetrics](https://xcmetrics.io) is a tool for collecting build metrics from XCode.
|
||||
With this plugin, you can view data from XCMetrics directly in Backstage.
|
||||
|
||||

|
||||
|
||||
## Getting started
|
||||
|
||||
From `packages/app`:
|
||||
|
||||
```bash
|
||||
yarn add @backstage/plugin-xcmetrics
|
||||
```
|
||||
|
||||
In `packages/app/src/App.tsx`, add the following:
|
||||
|
||||
```ts
|
||||
import { XcmetricsPage } from '@backstage/plugin-xcmetrics';
|
||||
```
|
||||
|
||||
```tsx
|
||||
<FlatRoutes>
|
||||
{/* Other routes... */}
|
||||
<Route path="/xcmetrics" element={<XcmetricsPage />} />
|
||||
</FlatRoutes>
|
||||
```
|
||||
|
||||
Add the URL to your XCMetrics backend instance in `app-config.yaml` like so:
|
||||
|
||||
```yaml
|
||||
proxy:
|
||||
...
|
||||
'/xcmetrics':
|
||||
target: http://127.0.0.1:8080/v1
|
||||
```
|
||||
|
||||
Start Backstage and navigate to `/xcmetrics` to view your build metrics!
|
||||
@@ -0,0 +1,23 @@
|
||||
## API Report File for "@backstage/plugin-xcmetrics"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
/// <reference types="react" />
|
||||
|
||||
import { BackstagePlugin } from '@backstage/core-plugin-api';
|
||||
import { RouteRef } from '@backstage/core-plugin-api';
|
||||
|
||||
// @public (undocumented)
|
||||
export const XcmetricsPage: () => JSX.Element;
|
||||
|
||||
// @public (undocumented)
|
||||
export const xcmetricsPlugin: BackstagePlugin<
|
||||
{
|
||||
root: RouteRef<undefined>;
|
||||
},
|
||||
{}
|
||||
>;
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2021 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 { createDevApp } from '@backstage/dev-utils';
|
||||
import { xcmetricsPlugin, XcmetricsPage } from '../src/plugin';
|
||||
|
||||
createDevApp()
|
||||
.registerPlugin(xcmetricsPlugin)
|
||||
.addPage({
|
||||
element: <XcmetricsPage />,
|
||||
title: 'Root Page',
|
||||
path: '/xcmetrics',
|
||||
})
|
||||
.render();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 622 KiB |
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "@backstage/plugin-xcmetrics",
|
||||
"version": "0.1.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "backstage-cli plugin:build",
|
||||
"start": "backstage-cli plugin:serve",
|
||||
"lint": "backstage-cli lint",
|
||||
"test": "backstage-cli test",
|
||||
"diff": "backstage-cli plugin:diff",
|
||||
"prepack": "backstage-cli prepack",
|
||||
"postpack": "backstage-cli postpack",
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-components": "^0.1.5",
|
||||
"@backstage/core-plugin-api": "^0.1.3",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.8",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.45",
|
||||
"luxon": "^1.27.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.7.3",
|
||||
"@backstage/core-app-api": "^0.1.4",
|
||||
"@backstage/dev-utils": "^0.2.1",
|
||||
"@backstage/test-utils": "^0.1.14",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/luxon": "^1.27.0",
|
||||
"@types/node": "^14.14.32",
|
||||
"cross-fetch": "^3.0.6",
|
||||
"msw": "^0.29.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2021 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 } from '@backstage/core-plugin-api';
|
||||
import { ResponseError } from '@backstage/errors';
|
||||
import { BuildItem, BuildsResult, XcmetricsApi } from './types';
|
||||
|
||||
interface Options {
|
||||
discoveryApi: DiscoveryApi;
|
||||
}
|
||||
|
||||
export class XcmetricsClient implements XcmetricsApi {
|
||||
private readonly discoveryApi: DiscoveryApi;
|
||||
|
||||
constructor(options: Options) {
|
||||
this.discoveryApi = options.discoveryApi;
|
||||
}
|
||||
|
||||
async getBuilds(): Promise<BuildItem[]> {
|
||||
const baseUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/xcmetrics`;
|
||||
const response = await fetch(`${baseUrl}/build`);
|
||||
|
||||
if (!response.ok) {
|
||||
throw await ResponseError.fromResponse(response);
|
||||
}
|
||||
|
||||
return ((await response.json()) as BuildsResult).items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2021 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 './types';
|
||||
export * from './XcmetricsClient';
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2021 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';
|
||||
|
||||
export type BuildStatus = 'succeeded' | 'failed' | 'stopped';
|
||||
|
||||
export type BuildItem = {
|
||||
userid: string;
|
||||
warningCount: number;
|
||||
duration: number;
|
||||
startTimestamp: string;
|
||||
isCi: boolean;
|
||||
startTimestampMicroseconds: number;
|
||||
category: string;
|
||||
endTimestampMicroseconds: number;
|
||||
day: string;
|
||||
compilationEndTimestamp: string;
|
||||
tag: string;
|
||||
projectName: string;
|
||||
compilationEndTimestampMicroseconds: number;
|
||||
errorCount: number;
|
||||
id: string;
|
||||
buildStatus: BuildStatus;
|
||||
compilationDuration: number;
|
||||
schema: string;
|
||||
compiledCount: number;
|
||||
endTimestamp: string;
|
||||
userid256: string;
|
||||
machineName: string;
|
||||
wasSuspended: boolean;
|
||||
};
|
||||
|
||||
export type BuildsResult = {
|
||||
items: BuildItem[];
|
||||
metadata: {
|
||||
per: number;
|
||||
total: number;
|
||||
page: number;
|
||||
};
|
||||
};
|
||||
|
||||
export interface XcmetricsApi {
|
||||
getBuilds(): Promise<BuildItem[]>;
|
||||
}
|
||||
|
||||
export const xcmetricsApiRef = createApiRef<XcmetricsApi>({
|
||||
id: 'plugin.xcmetrics.api',
|
||||
description: 'Used by the XCMetrics plugin to make requests',
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2021 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 { OverviewComponent } from './OverviewComponent';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { XcmetricsApi, xcmetricsApiRef } from '../../api';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
|
||||
|
||||
describe('OverviewComponent', () => {
|
||||
it('should render', async () => {
|
||||
const mockUserId = 'mockUser';
|
||||
const mockApi: jest.Mocked<XcmetricsApi> = {
|
||||
getBuilds: jest.fn().mockResolvedValue([
|
||||
{
|
||||
userid: mockUserId,
|
||||
warningCount: 1,
|
||||
duration: 123.45,
|
||||
isCi: false,
|
||||
projectName: 'App',
|
||||
buildStatus: 'succeeded',
|
||||
schema: 'AppSchema',
|
||||
},
|
||||
]),
|
||||
};
|
||||
|
||||
const rendered = await renderInTestApp(
|
||||
<ApiProvider apis={ApiRegistry.with(xcmetricsApiRef, mockApi)}>
|
||||
<OverviewComponent />
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(rendered.getByText('XCMetrics Dashboard')).toBeInTheDocument();
|
||||
expect(rendered.getByText(mockUserId)).toBeInTheDocument();
|
||||
expect(rendered.queryByText('CI')).toBeNull();
|
||||
});
|
||||
|
||||
it('should render an empty state when no builds exist', async () => {
|
||||
const mockApi: jest.Mocked<XcmetricsApi> = {
|
||||
getBuilds: jest.fn().mockResolvedValue([]),
|
||||
};
|
||||
|
||||
const rendered = await renderInTestApp(
|
||||
<ApiProvider apis={ApiRegistry.with(xcmetricsApiRef, mockApi)}>
|
||||
<OverviewComponent />
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(rendered.getByText('No builds to show')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show an error when API not responding', async () => {
|
||||
const errorMessage = 'MockErrorMessage';
|
||||
const mockApi: jest.Mocked<XcmetricsApi> = {
|
||||
getBuilds: jest.fn().mockRejectedValue({ message: errorMessage }),
|
||||
};
|
||||
|
||||
const rendered = await renderInTestApp(
|
||||
<ApiProvider apis={ApiRegistry.with(xcmetricsApiRef, mockApi)}>
|
||||
<OverviewComponent />
|
||||
</ApiProvider>,
|
||||
);
|
||||
expect(rendered.getByText(errorMessage)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2021 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 {
|
||||
ContentHeader,
|
||||
SupportButton,
|
||||
Progress,
|
||||
StatusOK,
|
||||
StatusError,
|
||||
StatusWarning,
|
||||
Table,
|
||||
TableColumn,
|
||||
EmptyState,
|
||||
} from '@backstage/core-components';
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
import { BuildItem, BuildStatus, xcmetricsApiRef } from '../../api';
|
||||
import { useAsync } from 'react-use';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { Duration } from 'luxon';
|
||||
import { Chip } from '@material-ui/core';
|
||||
|
||||
const formatStatus = (status: BuildStatus, warningCount: number) => {
|
||||
const statusIcons = {
|
||||
succeeded: <StatusOK />,
|
||||
failed: <StatusError />,
|
||||
stopped: <StatusWarning />,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{statusIcons[status]} {status[0].toUpperCase() + status.slice(1)}
|
||||
{warningCount > 0 && ` with ${warningCount} warning`}
|
||||
{warningCount > 1 && 's'}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const columns: TableColumn<BuildItem>[] = [
|
||||
{
|
||||
title: 'Project',
|
||||
field: 'projectName',
|
||||
},
|
||||
{
|
||||
title: 'Schema',
|
||||
field: 'schema',
|
||||
},
|
||||
{
|
||||
title: 'Duration',
|
||||
field: 'duration',
|
||||
type: 'time',
|
||||
searchable: false,
|
||||
render: data => Duration.fromObject({ seconds: data.duration }).toISOTime(),
|
||||
},
|
||||
{
|
||||
title: 'User',
|
||||
field: 'userid',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
field: 'buildStatus',
|
||||
render: data => formatStatus(data.buildStatus, data.warningCount),
|
||||
},
|
||||
{
|
||||
field: 'isCI',
|
||||
render: data => data.isCi && <Chip label="CI" size="small" />,
|
||||
width: '10',
|
||||
sorting: false,
|
||||
},
|
||||
];
|
||||
|
||||
export const OverviewComponent = () => {
|
||||
const client = useApi(xcmetricsApiRef);
|
||||
const { value: builds, loading, error } = useAsync(
|
||||
async (): Promise<BuildItem[]> => client.getBuilds(),
|
||||
[],
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return <Progress />;
|
||||
} else if (error) {
|
||||
return <Alert severity="error">{error.message}</Alert>;
|
||||
}
|
||||
|
||||
if (!builds || !builds.length) {
|
||||
return (
|
||||
<EmptyState
|
||||
missing="data"
|
||||
title="No builds to show"
|
||||
description="There are no builds in XCMetrics yet"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContentHeader title="XCMetrics Dashboard">
|
||||
<SupportButton>Dashboard for XCMetrics</SupportButton>
|
||||
</ContentHeader>
|
||||
<Table
|
||||
options={{ paging: false, search: false }}
|
||||
data={builds}
|
||||
columns={columns}
|
||||
title="Latest Builds"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 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 './OverviewComponent';
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2021 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 { Content, Header, HeaderLabel, Page } from '@backstage/core-components';
|
||||
import { OverviewComponent } from '../OverviewComponent';
|
||||
|
||||
export const XcmetricsLayout = () => (
|
||||
<Page themeId="tool">
|
||||
<Header title="XCMetrics" subtitle="Dashboard">
|
||||
<HeaderLabel label="Owner" value="Spotify" />
|
||||
<HeaderLabel label="Lifecycle" value="Alpha" />
|
||||
</Header>
|
||||
<Content>
|
||||
<OverviewComponent />
|
||||
</Content>
|
||||
</Page>
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 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 './XcmetricsLayout';
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 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 { xcmetricsPlugin, XcmetricsPage } from './plugin';
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2021 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 { xcmetricsPlugin } from './plugin';
|
||||
|
||||
describe('xcmetrics', () => {
|
||||
it('should export plugin', () => {
|
||||
expect(xcmetricsPlugin).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2021 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,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { xcmetricsApiRef, XcmetricsClient } from './api';
|
||||
import { rootRouteRef } from './routes';
|
||||
|
||||
export const xcmetricsPlugin = createPlugin({
|
||||
id: 'xcmetrics',
|
||||
routes: {
|
||||
root: rootRouteRef,
|
||||
},
|
||||
apis: [
|
||||
createApiFactory({
|
||||
api: xcmetricsApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
},
|
||||
factory({ discoveryApi }) {
|
||||
return new XcmetricsClient({ discoveryApi });
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export const XcmetricsPage = xcmetricsPlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () =>
|
||||
import('./components/XcmetricsLayout').then(m => m.XcmetricsLayout),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2021 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({
|
||||
title: 'XCMetrics',
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2021 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';
|
||||
import 'cross-fetch/polyfill';
|
||||
Reference in New Issue
Block a user