Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion code/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ COPY package.json yarn.lock ./
COPY packages packages

# Comment this out if you don't have any internal plugins
# COPY plugins plugins
COPY plugins plugins

RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+

Expand Down
2 changes: 2 additions & 0 deletions code/examples/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: example-website
annotations:
github.com/project-slug: test
spec:
type: website
lifecycle: experimental
Expand Down
4 changes: 3 additions & 1 deletion code/packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
"@backstage/plugin-techdocs-react": "^1.1.16",
"@backstage/plugin-user-settings": "^0.8.1",
"@backstage/theme": "^0.5.1",
"@internal/backstage-plugin-my-plugin": "^0.1.0",
"@material-ui/core": "^4.12.2",
"@material-ui/icons": "^4.9.1",
"@roadiehq/backstage-plugin-github-pull-requests": "^2.5.23",
"history": "^5.0.0",
"react": "^18.0.2",
"react-dom": "^18.0.2",
Expand All @@ -51,10 +53,10 @@
"devDependencies": {
"@backstage/test-utils": "^1.5.0",
"@playwright/test": "^1.32.3",
"@testing-library/dom": "^9.0.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.0.0",
"@testing-library/dom": "^9.0.0",
"@types/react-dom": "*",
"cross-env": "^7.0.0"
},
Expand Down
2 changes: 2 additions & 0 deletions code/packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { AppRouter, FlatRoutes } from '@backstage/core-app-api';
import { CatalogGraphPage } from '@backstage/plugin-catalog-graph';
import { RequirePermission } from '@backstage/plugin-permission-react';
import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha';
import { MyPluginPage } from '@internal/backstage-plugin-my-plugin';

const app = createApp({
apis,
Expand Down Expand Up @@ -93,6 +94,7 @@ const routes = (
</Route>
<Route path="/settings" element={<UserSettingsPage />} />
<Route path="/catalog-graph" element={<CatalogGraphPage />} />
<Route path="/my-plugin" element={<MyPluginPage />} />
</FlatRoutes>
);

Expand Down
12 changes: 12 additions & 0 deletions code/packages/app/src/components/catalog/EntityPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ import {

import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib';
import { EntityGithubPullRequestsContent } from '@roadiehq/backstage-plugin-github-pull-requests';
import { EntityGithubPullRequestsOverviewCard } from '@roadiehq/backstage-plugin-github-pull-requests';

const techdocsContent = (
<EntityTechdocsContent>
Expand Down Expand Up @@ -137,6 +139,10 @@ const overviewContent = (
<Grid item md={8} xs={12}>
<EntityHasSubcomponentsCard variant="gridItem" />
</Grid>

<Grid item md={6}>
<EntityGithubPullRequestsOverviewCard />
</Grid>
</Grid>
);

Expand Down Expand Up @@ -175,6 +181,10 @@ const serviceEntityPage = (
<EntityLayout.Route path="/docs" title="Docs">
{techdocsContent}
</EntityLayout.Route>

<EntityLayout.Route path="/pull-requests" title="Pull Requests">
<EntityGithubPullRequestsContent />
</EntityLayout.Route>
</EntityLayout>
);

Expand Down Expand Up @@ -202,6 +212,8 @@ const websiteEntityPage = (
<EntityLayout.Route path="/docs" title="Docs">
{techdocsContent}
</EntityLayout.Route>


</EntityLayout>
);

Expand Down
1 change: 1 addition & 0 deletions code/plugins/my-plugin/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
13 changes: 13 additions & 0 deletions code/plugins/my-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# my-plugin

Welcome to the my-plugin plugin!

_This plugin was created through the Backstage CLI_

## Getting started

Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/my-plugin](http://localhost:3000/my-plugin).

You can also serve the plugin in isolation by running `yarn start` in the plugin directory.
This method of serving the plugin provides quicker iteration speed and a faster startup and hot reloads.
It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory.
12 changes: 12 additions & 0 deletions code/plugins/my-plugin/dev/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { createDevApp } from '@backstage/dev-utils';
import { myPluginPlugin, MyPluginPage } from '../src/plugin';

createDevApp()
.registerPlugin(myPluginPlugin)
.addPage({
element: <MyPluginPage />,
title: 'Root Page',
path: '/my-plugin'
})
.render();
51 changes: 51 additions & 0 deletions code/plugins/my-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@internal/backstage-plugin-my-plugin",
"version": "0.1.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
"private": true,
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
"backstage": {
"role": "frontend-plugin"
},
"sideEffects": false,
"scripts": {
"start": "backstage-cli package start",
"build": "backstage-cli package build",
"lint": "backstage-cli package lint",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage/core-components": "^0.14.0",
"@backstage/core-plugin-api": "^1.9.0",
"@backstage/theme": "^0.5.1",
"@material-ui/core": "^4.9.13",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.60",
"react-use": "^17.2.4"
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.25.2",
"@backstage/core-app-api": "^1.12.0",
"@backstage/dev-utils": "^1.0.27",
"@backstage/test-utils": "^1.5.0",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.0.0",
"msw": "^1.0.0"
},
"files": [
"dist"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { ExampleComponent } from './ExampleComponent';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { screen } from '@testing-library/react';
import {
setupRequestMockHandlers,
renderInTestApp,
} from "@backstage/test-utils";

describe('ExampleComponent', () => {
const server = setupServer();
// Enable sane handlers for network requests
setupRequestMockHandlers(server);

// setup mock response
beforeEach(() => {
server.use(
rest.get('/*', (_, res, ctx) => res(ctx.status(200), ctx.json({}))),
);
});

it('should render', async () => {
await renderInTestApp(<ExampleComponent />);
expect(screen.getByText('Welcome to my-plugin!')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { Typography, Grid } from '@material-ui/core';
import {
InfoCard,
Header,
Page,
Content,
ContentHeader,
HeaderLabel,
SupportButton,
} from '@backstage/core-components';
import { ExampleFetchComponent } from '../ExampleFetchComponent';

export const ExampleComponent = () => (
<Page themeId="tool">
<Header title="Welcome to my-plugin!" subtitle="Optional subtitle">
<HeaderLabel label="Owner" value="Team X" />
<HeaderLabel label="Lifecycle" value="Alpha" />
</Header>
<Content>
<ContentHeader title="Plugin title">
<SupportButton>A description of your plugin goes here.</SupportButton>
</ContentHeader>
<Grid container spacing={3} direction="column">
<Grid item>
<InfoCard title="Information card">
<Typography variant="body1">
All content should be wrapped in a card like this.
</Typography>
</InfoCard>
</Grid>
<Grid item>
<ExampleFetchComponent />
</Grid>
</Grid>
</Content>
</Page>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ExampleComponent } from './ExampleComponent';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { ExampleFetchComponent } from './ExampleFetchComponent';

describe('ExampleFetchComponent', () => {
it('renders the user table', async () => {
render(<ExampleFetchComponent />);

// Wait for the table to render
const table = await screen.findByRole('table');
const nationality = screen.getAllByText("GB")
// Assert that the table contains the expected user data
expect(table).toBeInTheDocument();
expect(screen.getByAltText('Carolyn')).toBeInTheDocument();
expect(screen.getByText('Carolyn Moore')).toBeInTheDocument();
expect(screen.getByText('carolyn.moore@example.com')).toBeInTheDocument();
expect(nationality[0]).toBeInTheDocument();
});
});
Loading