diff --git a/packages/app/package.json b/packages/app/package.json index 5e4cf307ec..bcdcae0a60 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -17,6 +17,7 @@ "@backstage/integration-react": "^1.1.2-next.3", "@backstage/plugin-airbrake": "^0.3.7-next.3", "@backstage/plugin-api-docs": "^0.8.7-next.3", + "@backstage/plugin-apollo-explorer": "^0.0.0", "@backstage/plugin-azure-devops": "^0.1.23-next.3", "@backstage/plugin-apache-airflow": "^0.2.0-next.3", "@backstage/plugin-badges": "^0.2.31-next.3", @@ -49,18 +50,18 @@ "@backstage/plugin-rollbar": "^0.4.7-next.3", "@backstage/plugin-scaffolder": "^1.4.0-next.3", "@backstage/plugin-search": "^0.9.1-next.3", - "@backstage/plugin-search-react": "^0.2.2-next.3", "@backstage/plugin-search-common": "^0.3.6-next.0", + "@backstage/plugin-search-react": "^0.2.2-next.3", "@backstage/plugin-sentry": "^0.4.0-next.3", "@backstage/plugin-shortcuts": "^0.2.8-next.3", "@backstage/plugin-stack-overflow": "^0.1.3-next.3", + "@backstage/plugin-tech-insights": "^0.2.3-next.3", "@backstage/plugin-tech-radar": "^0.5.14-next.3", "@backstage/plugin-techdocs": "^1.2.1-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", "@backstage/plugin-techdocs-module-addons-contrib": "^1.0.2-next.3", + "@backstage/plugin-techdocs-react": "^1.0.2-next.2", "@backstage/plugin-todo": "^0.2.9-next.3", "@backstage/plugin-user-settings": "^0.4.6-next.3", - "@backstage/plugin-tech-insights": "^0.2.3-next.3", "@backstage/theme": "^0.2.16-next.1", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/apollo-explorer/.eslintrc.js b/plugins/apollo-explorer/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/apollo-explorer/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md new file mode 100644 index 0000000000..0ff279908e --- /dev/null +++ b/plugins/apollo-explorer/README.md @@ -0,0 +1,9 @@ +# apollo-explorer + +Welcome to the Apollo Explorer plugin! + +This plugin allows users to directly embed an Apollo graph explorer directly into Backstage! + +## Getting started + +TODO diff --git a/plugins/apollo-explorer/dev/index.tsx b/plugins/apollo-explorer/dev/index.tsx new file mode 100644 index 0000000000..f02c250b9a --- /dev/null +++ b/plugins/apollo-explorer/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * 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 { createDevApp } from '@backstage/dev-utils'; +import { apolloExplorerPlugin, ApolloExplorerPage } from '../src/plugin'; + +createDevApp() + .registerPlugin(apolloExplorerPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/apollo-explorer' + }) + .render(); diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json new file mode 100644 index 0000000000..9d8f2037ba --- /dev/null +++ b/plugins/apollo-explorer/package.json @@ -0,0 +1,54 @@ +{ + "name": "@backstage/plugin-apollo-explorer", + "version": "0.0.0", + "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" + }, + "backstage": { + "role": "frontend-plugin" + }, + "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.10.0-next.3", + "@backstage/core-plugin-api": "^1.0.4-next.0", + "@backstage/theme": "^0.2.16-next.1", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "react-use": "^17.2.4", + "@apollo/explorer": "^1.1.1", + "use-deep-compare-effect": "^1.8.1" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.18.0-next.3", + "@backstage/core-app-api": "^1.0.4-next.1", + "@backstage/dev-utils": "^1.0.4-next.3", + "@backstage/test-utils": "^1.1.2-next.2", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/jest": "*", + "@types/node": "*", + "msw": "^0.43.0", + "cross-fetch": "^3.1.5" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/apollo-explorer/src/components/ApolloExplorer/ApolloExplorer.tsx b/plugins/apollo-explorer/src/components/ApolloExplorer/ApolloExplorer.tsx new file mode 100644 index 0000000000..534615a4e2 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorer/ApolloExplorer.tsx @@ -0,0 +1,50 @@ +/* + * 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 { Content, Header, HeaderLabel, Page } from '@backstage/core-components'; +import { ApolloExplorer as ApolloExplorerReact } from '@apollo/explorer/react'; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles(() => ({ + explorer: { + height: '100%', + }, +})); + +type Props = { + graphRef: string; +}; + +export const ApolloExplorer = ({ graphRef }: Props) => { + const classes = useStyles(); + return ( + +
+ + +
+ + + +
+ ); +}; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.test.tsx b/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.test.tsx new file mode 100644 index 0000000000..12dde9a899 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.test.tsx @@ -0,0 +1,49 @@ +/* + * 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 { ExampleComponent } from './ExampleComponent'; +import { ThemeProvider } from '@material-ui/core'; +import { lightTheme } from '@backstage/theme'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +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 () => { + const rendered = await renderInTestApp( + + + , + ); + expect( + rendered.getByText('Welcome to apollo-explorer!'), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.tsx b/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.tsx new file mode 100644 index 0000000000..9677d008d3 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorer/ExampleComponent.tsx @@ -0,0 +1,51 @@ +/* + * 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 { Content, Header, HeaderLabel, Page } from '@backstage/core-components'; +import { ApolloExplorer } from '@apollo/explorer/react'; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles(() => ({ + explorer: { + height: '100%', + }, +})); + +export const ExampleComponent = () => { + const classes = useStyles(); + return ( + +
+ + +
+ + + +
+ ); +}; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorer/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorer/index.ts new file mode 100644 index 0000000000..2c1204b8d1 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorer/index.ts @@ -0,0 +1,16 @@ +/* + * 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 { ApolloExplorer } from './ApolloExplorer'; diff --git a/plugins/apollo-explorer/src/index.ts b/plugins/apollo-explorer/src/index.ts new file mode 100644 index 0000000000..6d07535fc3 --- /dev/null +++ b/plugins/apollo-explorer/src/index.ts @@ -0,0 +1,16 @@ +/* + * 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 { apolloExplorerPlugin, ApolloExplorerPage } from './plugin'; diff --git a/plugins/apollo-explorer/src/plugin.test.ts b/plugins/apollo-explorer/src/plugin.test.ts new file mode 100644 index 0000000000..0b5e41fe6e --- /dev/null +++ b/plugins/apollo-explorer/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * 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 { apolloExplorerPlugin } from './plugin'; + +describe('apollo-explorer', () => { + it('should export plugin', () => { + expect(apolloExplorerPlugin).toBeDefined(); + }); +}); diff --git a/plugins/apollo-explorer/src/plugin.ts b/plugins/apollo-explorer/src/plugin.ts new file mode 100644 index 0000000000..0a32394e9a --- /dev/null +++ b/plugins/apollo-explorer/src/plugin.ts @@ -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 { + createPlugin, + createRoutableExtension, +} from '@backstage/core-plugin-api'; + +import { rootRouteRef } from './routes'; + +export const apolloExplorerPlugin = createPlugin({ + id: 'apollo-explorer', + routes: { + root: rootRouteRef, + }, +}); + +export const ApolloExplorerPage = apolloExplorerPlugin.provide( + createRoutableExtension({ + name: 'ApolloExplorerPage', + component: () => + import('./components/ApolloExplorer').then(m => m.ApolloExplorer), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/apollo-explorer/src/routes.ts b/plugins/apollo-explorer/src/routes.ts new file mode 100644 index 0000000000..c8e6a3eb9a --- /dev/null +++ b/plugins/apollo-explorer/src/routes.ts @@ -0,0 +1,20 @@ +/* + * 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: 'apollo-explorer', +}); diff --git a/plugins/apollo-explorer/src/setupTests.ts b/plugins/apollo-explorer/src/setupTests.ts new file mode 100644 index 0000000000..9bb3e72355 --- /dev/null +++ b/plugins/apollo-explorer/src/setupTests.ts @@ -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'; +import 'cross-fetch/polyfill';