From 5e1a90daa2175e2ff44518b4bb8185c889f5563e Mon Sep 17 00:00:00 2001 From: Heikki Hellgren Date: Mon, 4 Dec 2023 15:00:02 +0200 Subject: [PATCH] chore: move signals client to fronend plugin Signed-off-by: Heikki Hellgren --- .changeset/real-eggs-sip.md | 1 + packages/app/package.json | 1 + packages/app/src/plugins.ts | 1 + plugins/signals-node/package.json | 4 +- plugins/signals-react/api-report.md | 16 +----- plugins/signals-react/src/api/index.ts | 1 - .../signals-react/src/hooks/useSignalsApi.ts | 11 ++-- plugins/signals/.eslintrc.js | 1 + plugins/signals/README.md | 13 +++++ plugins/signals/api-report.md | 27 ++++++++++ plugins/signals/catalog-info.yaml | 9 ++++ plugins/signals/dev/index.tsx | 35 +++++++++++++ plugins/signals/package.json | 52 +++++++++++++++++++ .../src/api/SignalsClient.ts | 2 +- plugins/signals/src/api/index.ts | 16 ++++++ plugins/signals/src/index.ts | 17 ++++++ plugins/signals/src/plugin.test.ts | 22 ++++++++ plugins/signals/src/plugin.ts | 39 ++++++++++++++ plugins/signals/src/setupTests.ts | 16 ++++++ yarn.lock | 27 ++++++++++ 20 files changed, 286 insertions(+), 25 deletions(-) create mode 100644 plugins/signals/.eslintrc.js create mode 100644 plugins/signals/README.md create mode 100644 plugins/signals/api-report.md create mode 100644 plugins/signals/catalog-info.yaml create mode 100644 plugins/signals/dev/index.tsx create mode 100644 plugins/signals/package.json rename plugins/{signals-react => signals}/src/api/SignalsClient.ts (98%) create mode 100644 plugins/signals/src/api/index.ts create mode 100644 plugins/signals/src/index.ts create mode 100644 plugins/signals/src/plugin.test.ts create mode 100644 plugins/signals/src/plugin.ts create mode 100644 plugins/signals/src/setupTests.ts diff --git a/.changeset/real-eggs-sip.md b/.changeset/real-eggs-sip.md index ca05205083..ca23d792f8 100644 --- a/.changeset/real-eggs-sip.md +++ b/.changeset/real-eggs-sip.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-signals-backend': patch +'@backstage/plugin-signals': patch '@backstage/plugin-signals-react': patch '@backstage/plugin-signals-node': patch --- diff --git a/packages/app/package.json b/packages/app/package.json index c6ceafcf04..53a2b60a52 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -73,6 +73,7 @@ "@backstage/plugin-search-react": "workspace:^", "@backstage/plugin-sentry": "workspace:^", "@backstage/plugin-shortcuts": "workspace:^", + "@backstage/plugin-signals": "workspace:^", "@backstage/plugin-stack-overflow": "workspace:^", "@backstage/plugin-stackstorm": "workspace:^", "@backstage/plugin-tech-insights": "workspace:^", diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts index 36f7a86acc..ddd12bea2c 100644 --- a/packages/app/src/plugins.ts +++ b/packages/app/src/plugins.ts @@ -19,3 +19,4 @@ export { badgesPlugin } from '@backstage/plugin-badges'; export { shortcutsPlugin } from '@backstage/plugin-shortcuts'; export { homePlugin } from '@backstage/plugin-home'; +export { signalsPlugin } from '@backstage/plugin-signals'; diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 66e4528678..2dc17f5e54 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -22,8 +22,7 @@ "postpack": "backstage-cli package postpack" }, "devDependencies": { - "@backstage/cli": "workspace:^", - "@types/express": "^4.17.21" + "@backstage/cli": "workspace:^" }, "files": [ "dist" @@ -34,6 +33,7 @@ "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", "@backstage/types": "workspace:^", + "@types/express": "^4.17.21", "express": "^4.17.1", "uuid": "^8.0.0", "winston": "^3.2.1", diff --git a/plugins/signals-react/api-report.md b/plugins/signals-react/api-report.md index 22e9306c14..0ab752be60 100644 --- a/plugins/signals-react/api-report.md +++ b/plugins/signals-react/api-report.md @@ -4,8 +4,6 @@ ```ts import { ApiRef } from '@backstage/core-plugin-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; -import { JSONObject } from '@apollo/explorer/src/helpers/types'; import { JsonObject } from '@backstage/types'; // @public (undocumented) @@ -20,22 +18,10 @@ export type SignalsApi = { // @public (undocumented) export const signalsApiRef: ApiRef; -// @public (undocumented) -export class SignalsClient implements SignalsApi { - // (undocumented) - static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; - // (undocumented) - static instance: SignalsClient | null; - // (undocumented) - subscribe(onMessage: (message: JsonObject) => void, topic: string): void; - // (undocumented) - unsubscribe(topic: string): void; -} - // @public (undocumented) export const useSignalsApi: ( topic: string, - onMessage: (message: JSONObject) => void, + onMessage: (message: JsonObject) => void, ) => void; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-react/src/api/index.ts b/plugins/signals-react/src/api/index.ts index b8dea2af34..9d5c4c5656 100644 --- a/plugins/signals-react/src/api/index.ts +++ b/plugins/signals-react/src/api/index.ts @@ -14,4 +14,3 @@ * limitations under the License. */ export * from './SignalsApi'; -export * from './SignalsClient'; diff --git a/plugins/signals-react/src/hooks/useSignalsApi.ts b/plugins/signals-react/src/hooks/useSignalsApi.ts index 88112cebc7..d97d80ed76 100644 --- a/plugins/signals-react/src/hooks/useSignalsApi.ts +++ b/plugins/signals-react/src/hooks/useSignalsApi.ts @@ -13,18 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SignalsClient } from '../api'; -import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; -import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { signalsApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; import { useEffect } from 'react'; /** @public */ export const useSignalsApi = ( topic: string, - onMessage: (message: JSONObject) => void, + onMessage: (message: JsonObject) => void, ) => { - const discovery = useApi(discoveryApiRef); - const signals = SignalsClient.create({ discoveryApi: discovery }); + const signals = useApi(signalsApiRef); useEffect(() => { signals.subscribe(onMessage, topic); }, [signals, onMessage, topic]); diff --git a/plugins/signals/.eslintrc.js b/plugins/signals/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/signals/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/signals/README.md b/plugins/signals/README.md new file mode 100644 index 0000000000..604fa98a33 --- /dev/null +++ b/plugins/signals/README.md @@ -0,0 +1,13 @@ +# signals + +Welcome to the signals 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 [/signals](http://localhost:3000/signals). + +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. diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md new file mode 100644 index 0000000000..d2dd111fe6 --- /dev/null +++ b/plugins/signals/api-report.md @@ -0,0 +1,27 @@ +## API Report File for "@backstage/plugin-signals" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { SignalsApi } from '@backstage/plugin-signals-react'; + +// @public (undocumented) +export class SignalsClient implements SignalsApi { + // (undocumented) + static create(options: { discoveryApi: DiscoveryApi }): SignalsClient; + // (undocumented) + static instance: SignalsClient | null; + // (undocumented) + subscribe(onMessage: (message: JsonObject) => void, topic: string): void; + // (undocumented) + unsubscribe(topic: string): void; +} + +// @public (undocumented) +export const signalsPlugin: BackstagePlugin<{}, {}>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/signals/catalog-info.yaml b/plugins/signals/catalog-info.yaml new file mode 100644 index 0000000000..ab52477147 --- /dev/null +++ b/plugins/signals/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-signals + title: '@backstage/plugin-signals' +spec: + lifecycle: experimental + type: backstage-frontend-plugin + owner: maintainers diff --git a/plugins/signals/dev/index.tsx b/plugins/signals/dev/index.tsx new file mode 100644 index 0000000000..e8c7928f57 --- /dev/null +++ b/plugins/signals/dev/index.tsx @@ -0,0 +1,35 @@ +/* + * Copyright 2023 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 { signalsPlugin } from '../src/plugin'; +import { Content, Header, Page } from '@backstage/core-components'; +import { Typography } from '@material-ui/core'; + +createDevApp() + .registerPlugin(signalsPlugin) + .addPage({ + title: 'Debug', + element: ( + +
+ + TODO + + + ), + }) + .render(); diff --git a/plugins/signals/package.json b/plugins/signals/package.json new file mode 100644 index 0000000000..9c0bcb5c13 --- /dev/null +++ b/plugins/signals/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/plugin-signals", + "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" + }, + "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": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-signals-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@backstage/types": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.61", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/signals-react/src/api/SignalsClient.ts b/plugins/signals/src/api/SignalsClient.ts similarity index 98% rename from plugins/signals-react/src/api/SignalsClient.ts rename to plugins/signals/src/api/SignalsClient.ts index cdfa7e5606..34ef557f31 100644 --- a/plugins/signals-react/src/api/SignalsClient.ts +++ b/plugins/signals/src/api/SignalsClient.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SignalsApi } from './SignalsApi'; +import { SignalsApi } from '@backstage/plugin-signals-react'; import { JsonObject } from '@backstage/types'; import { DiscoveryApi } from '@backstage/core-plugin-api'; diff --git a/plugins/signals/src/api/index.ts b/plugins/signals/src/api/index.ts new file mode 100644 index 0000000000..80e69259af --- /dev/null +++ b/plugins/signals/src/api/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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 './SignalsClient'; diff --git a/plugins/signals/src/index.ts b/plugins/signals/src/index.ts new file mode 100644 index 0000000000..ddf8afb9c6 --- /dev/null +++ b/plugins/signals/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 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 { signalsPlugin } from './plugin'; +export * from './api'; diff --git a/plugins/signals/src/plugin.test.ts b/plugins/signals/src/plugin.test.ts new file mode 100644 index 0000000000..cc8ecf44ed --- /dev/null +++ b/plugins/signals/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 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 { signalsPlugin } from './plugin'; + +describe('signals', () => { + it('should export plugin', () => { + expect(signalsPlugin).toBeDefined(); + }); +}); diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts new file mode 100644 index 0000000000..457b3d9925 --- /dev/null +++ b/plugins/signals/src/plugin.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2023 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, + discoveryApiRef, +} from '@backstage/core-plugin-api'; +import { signalsApiRef } from '@backstage/plugin-signals-react'; +import { SignalsClient } from './api/SignalsClient'; + +/** @public */ +export const signalsPlugin = createPlugin({ + id: 'signals', + apis: [ + createApiFactory({ + api: signalsApiRef, + deps: { + discoveryApi: discoveryApiRef, + }, + factory: ({ discoveryApi }) => + SignalsClient.create({ + discoveryApi, + }), + }), + ], +}); diff --git a/plugins/signals/src/setupTests.ts b/plugins/signals/src/setupTests.ts new file mode 100644 index 0000000000..865308e634 --- /dev/null +++ b/plugins/signals/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 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'; diff --git a/yarn.lock b/yarn.lock index cdd232b103..a6e69edc89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8893,6 +8893,32 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-signals@workspace:^, @backstage/plugin-signals@workspace:plugins/signals": + version: 0.0.0-use.local + resolution: "@backstage/plugin-signals@workspace:plugins/signals" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/plugin-signals-react": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@backstage/types": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.61 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + msw: ^1.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-sonarqube-backend@workspace:^, @backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend": version: 0.0.0-use.local resolution: "@backstage/plugin-sonarqube-backend@workspace:plugins/sonarqube-backend" @@ -26556,6 +26582,7 @@ __metadata: "@backstage/plugin-search-react": "workspace:^" "@backstage/plugin-sentry": "workspace:^" "@backstage/plugin-shortcuts": "workspace:^" + "@backstage/plugin-signals": "workspace:^" "@backstage/plugin-stack-overflow": "workspace:^" "@backstage/plugin-stackstorm": "workspace:^" "@backstage/plugin-tech-insights": "workspace:^"