From a78ae537aed5988537b3e533b3a920b3e1634f4b Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 5 Jun 2023 15:16:34 +0200 Subject: [PATCH] add app-experiments with initial implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Fredrik Adelöw Co-authored-by: Johan Haals Co-authored-by: Patrik Oldsberg Co-authored-by: MT Lewis Signed-off-by: Patrik Oldsberg --- packages/app-experiments/.eslintrc.js | 1 + packages/app-experiments/README.md | 3 + packages/app-experiments/package.json | 140 ++++++++++++++++++ packages/app-experiments/src/Experiment1.tsx | 146 +++++++++++++++++++ packages/app-experiments/src/index.tsx | 22 +++ packages/app-experiments/src/setupTests.ts | 21 +++ yarn.lock | 107 ++++++++++++++ 7 files changed, 440 insertions(+) create mode 100644 packages/app-experiments/.eslintrc.js create mode 100644 packages/app-experiments/README.md create mode 100644 packages/app-experiments/package.json create mode 100644 packages/app-experiments/src/Experiment1.tsx create mode 100644 packages/app-experiments/src/index.tsx create mode 100644 packages/app-experiments/src/setupTests.ts diff --git a/packages/app-experiments/.eslintrc.js b/packages/app-experiments/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/packages/app-experiments/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/packages/app-experiments/README.md b/packages/app-experiments/README.md new file mode 100644 index 0000000000..a2c7ae1b77 --- /dev/null +++ b/packages/app-experiments/README.md @@ -0,0 +1,3 @@ +# example-app + +This package is an example of a Backstage application. diff --git a/packages/app-experiments/package.json b/packages/app-experiments/package.json new file mode 100644 index 0000000000..aa2cb39f1d --- /dev/null +++ b/packages/app-experiments/package.json @@ -0,0 +1,140 @@ +{ + "name": "app-experiments", + "version": "0.0.0", + "private": true, + "backstage": { + "role": "frontend" + }, + "bundled": true, + "dependencies": { + "@backstage/app-defaults": "workspace:^", + "@backstage/catalog-model": "workspace:^", + "@backstage/cli": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/integration-react": "workspace:^", + "@backstage/plugin-adr": "workspace:^", + "@backstage/plugin-airbrake": "workspace:^", + "@backstage/plugin-apache-airflow": "workspace:^", + "@backstage/plugin-api-docs": "workspace:^", + "@backstage/plugin-azure-devops": "workspace:^", + "@backstage/plugin-azure-sites": "workspace:^", + "@backstage/plugin-badges": "workspace:^", + "@backstage/plugin-catalog-common": "workspace:^", + "@backstage/plugin-catalog-graph": "workspace:^", + "@backstage/plugin-catalog-import": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-catalog-unprocessed-entities": "workspace:^", + "@backstage/plugin-circleci": "workspace:^", + "@backstage/plugin-cloudbuild": "workspace:^", + "@backstage/plugin-code-coverage": "workspace:^", + "@backstage/plugin-cost-insights": "workspace:^", + "@backstage/plugin-devtools": "workspace:^", + "@backstage/plugin-dynatrace": "workspace:^", + "@backstage/plugin-entity-feedback": "workspace:^", + "@backstage/plugin-explore": "workspace:^", + "@backstage/plugin-gcalendar": "workspace:^", + "@backstage/plugin-gcp-projects": "workspace:^", + "@backstage/plugin-github-actions": "workspace:^", + "@backstage/plugin-gocd": "workspace:^", + "@backstage/plugin-graphiql": "workspace:^", + "@backstage/plugin-home": "workspace:^", + "@backstage/plugin-jenkins": "workspace:^", + "@backstage/plugin-kafka": "workspace:^", + "@backstage/plugin-kubernetes": "workspace:^", + "@backstage/plugin-lighthouse": "workspace:^", + "@backstage/plugin-linguist": "workspace:^", + "@backstage/plugin-linguist-common": "workspace:^", + "@backstage/plugin-microsoft-calendar": "workspace:^", + "@backstage/plugin-newrelic": "workspace:^", + "@backstage/plugin-newrelic-dashboard": "workspace:^", + "@backstage/plugin-octopus-deploy": "workspace:^", + "@backstage/plugin-org": "workspace:^", + "@backstage/plugin-pagerduty": "workspace:^", + "@backstage/plugin-permission-react": "workspace:^", + "@backstage/plugin-playlist": "workspace:^", + "@backstage/plugin-puppetdb": "workspace:^", + "@backstage/plugin-rollbar": "workspace:^", + "@backstage/plugin-scaffolder": "workspace:^", + "@backstage/plugin-scaffolder-react": "workspace:^", + "@backstage/plugin-search": "workspace:^", + "@backstage/plugin-search-common": "workspace:^", + "@backstage/plugin-search-react": "workspace:^", + "@backstage/plugin-sentry": "workspace:^", + "@backstage/plugin-shortcuts": "workspace:^", + "@backstage/plugin-stack-overflow": "workspace:^", + "@backstage/plugin-stackstorm": "workspace:^", + "@backstage/plugin-tech-insights": "workspace:^", + "@backstage/plugin-tech-radar": "workspace:^", + "@backstage/plugin-techdocs": "workspace:^", + "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^", + "@backstage/plugin-techdocs-react": "workspace:^", + "@backstage/plugin-todo": "workspace:^", + "@backstage/plugin-user-settings": "workspace:^", + "@backstage/theme": "workspace:^", + "@internal/plugin-catalog-customized": "workspace:^", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.61", + "@octokit/rest": "^19.0.3", + "@oriflame/backstage-plugin-score-card": "^0.7.0", + "@roadiehq/backstage-plugin-buildkite": "^2.0.8", + "@roadiehq/backstage-plugin-github-insights": "^2.0.5", + "@roadiehq/backstage-plugin-github-pull-requests": "^2.2.7", + "@roadiehq/backstage-plugin-travis-ci": "^2.0.5", + "history": "^5.0.0", + "prop-types": "^15.7.2", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-router": "^6.3.0", + "react-router-dom": "^6.3.0", + "react-use": "^17.2.4", + "zen-observable": "^0.10.0" + }, + "devDependencies": { + "@backstage/test-utils": "workspace:^", + "@testing-library/cypress": "^9.0.0", + "@testing-library/dom": "^8.0.0", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/jquery": "^3.3.34", + "@types/node": "^16.11.26", + "@types/react": "*", + "@types/react-dom": "*", + "@types/zen-observable": "^0.8.0", + "cross-env": "^7.0.0", + "cypress": "^10.0.0", + "eslint-plugin-cypress": "^2.10.3", + "start-server-and-test": "^1.10.11" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "test": "backstage-cli package test", + "lint": "backstage-cli package lint", + "test:e2e": "start-server-and-test start http://localhost:3000 cy:dev", + "test:e2e:ci": "start-server-and-test start http://localhost:3000 cy:run", + "cy:dev": "cypress open", + "cy:run": "cypress run" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "files": [ + "dist" + ], + "license": "Apache-2.0" +} diff --git a/packages/app-experiments/src/Experiment1.tsx b/packages/app-experiments/src/Experiment1.tsx new file mode 100644 index 0000000000..4508d097a3 --- /dev/null +++ b/packages/app-experiments/src/Experiment1.tsx @@ -0,0 +1,146 @@ +/* + * 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, { ComponentType, createContext, useMemo } from 'react'; + +/* + +App structure: + - root + - red + - green + - blue + +*/ +// app.registerExtensionPoint() + +// import { redExtensionPointRef } from 'wherever'; + +type Extension = { + factory(instanceOptions: { config: TInstanceConfig }): ComponentType; +}; + +type ExtensionInstance = { + id: string; + config: TInstanceConfig; + extension: Extension; +}; + +const BackstageAppContext = createContext<{ + extensionInstances: ExtensionInstance[]; +}>({ extensionInstances: [] }); + +const container = { + createExtension(extensionOptions: { + render: (config: TInstanceConfig) => JSX.Element; + }): Extension { + return { + factory(instanceOptions: { config: TInstanceConfig }) { + return () => extensionOptions.render(instanceOptions.config); + }, + }; + }, +}; + +const Box = container.createExtension({ + render: (config: { color: string }) => { + return ( +
+ {config.color} +
+ ); + }, +}); + +const ExtensionInstanceDerp = (props: { id: string }) => { + const { id } = props; + const { extensionInstances } = React.useContext(BackstageAppContext); + + const instance = extensionInstances.find(i => i.id === id); + + if (!instance) { + throw new Error(`No extension instance found with id ${id}`); + } + + const Component = useMemo( + () => instance.extension.factory({ config: instance.config }), + [instance], + ); + return ; +}; + +export function Experiment1() { + // const element = useExtension("red"); + + return ( + +

Experiment 1

+

This is an experiment to see how the app-experiments package works.

+ {/* extension point */} + + + +
+ ); +} + +/* +// graphiql-plugin + + + +// App.tsx + +export default app.createRoot(); +export default app.createRoot(extensionInstanceElement('root')); + +function extensionInstanceElement(id: string): JSX.Element { +} + +app: + extensions: + - root.sidebar: + use: 'CustomSidebar' + + +function CustomSidebar() { + return ( + + {extensionInstanceElement('sidebar.items.derp')} + + + ) +} + +const customSidebar = createComponentExtension({ + component: CustomSidebar +}) + +createApp({ + extensions: [customSidebar] +}) + +*/ diff --git a/packages/app-experiments/src/index.tsx b/packages/app-experiments/src/index.tsx new file mode 100644 index 0000000000..6f0434c15e --- /dev/null +++ b/packages/app-experiments/src/index.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2020 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 '@backstage/cli/asset-types'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Experiment1 } from './Experiment1'; + +ReactDOM.render(, document.getElementById('root')); diff --git a/packages/app-experiments/src/setupTests.ts b/packages/app-experiments/src/setupTests.ts new file mode 100644 index 0000000000..23fcbe9676 --- /dev/null +++ b/packages/app-experiments/src/setupTests.ts @@ -0,0 +1,21 @@ +/* + * Copyright 2020 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. + */ + +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/yarn.lock b/yarn.lock index b97d410197..e5c4f02164 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19259,6 +19259,113 @@ __metadata: languageName: node linkType: hard +"app-experiments@workspace:packages/app-experiments": + version: 0.0.0-use.local + resolution: "app-experiments@workspace:packages/app-experiments" + dependencies: + "@backstage/app-defaults": "workspace:^" + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/integration-react": "workspace:^" + "@backstage/plugin-adr": "workspace:^" + "@backstage/plugin-airbrake": "workspace:^" + "@backstage/plugin-apache-airflow": "workspace:^" + "@backstage/plugin-api-docs": "workspace:^" + "@backstage/plugin-azure-devops": "workspace:^" + "@backstage/plugin-azure-sites": "workspace:^" + "@backstage/plugin-badges": "workspace:^" + "@backstage/plugin-catalog-common": "workspace:^" + "@backstage/plugin-catalog-graph": "workspace:^" + "@backstage/plugin-catalog-import": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/plugin-catalog-unprocessed-entities": "workspace:^" + "@backstage/plugin-circleci": "workspace:^" + "@backstage/plugin-cloudbuild": "workspace:^" + "@backstage/plugin-code-coverage": "workspace:^" + "@backstage/plugin-cost-insights": "workspace:^" + "@backstage/plugin-devtools": "workspace:^" + "@backstage/plugin-dynatrace": "workspace:^" + "@backstage/plugin-entity-feedback": "workspace:^" + "@backstage/plugin-explore": "workspace:^" + "@backstage/plugin-gcalendar": "workspace:^" + "@backstage/plugin-gcp-projects": "workspace:^" + "@backstage/plugin-github-actions": "workspace:^" + "@backstage/plugin-gocd": "workspace:^" + "@backstage/plugin-graphiql": "workspace:^" + "@backstage/plugin-home": "workspace:^" + "@backstage/plugin-jenkins": "workspace:^" + "@backstage/plugin-kafka": "workspace:^" + "@backstage/plugin-kubernetes": "workspace:^" + "@backstage/plugin-lighthouse": "workspace:^" + "@backstage/plugin-linguist": "workspace:^" + "@backstage/plugin-linguist-common": "workspace:^" + "@backstage/plugin-microsoft-calendar": "workspace:^" + "@backstage/plugin-newrelic": "workspace:^" + "@backstage/plugin-newrelic-dashboard": "workspace:^" + "@backstage/plugin-octopus-deploy": "workspace:^" + "@backstage/plugin-org": "workspace:^" + "@backstage/plugin-pagerduty": "workspace:^" + "@backstage/plugin-permission-react": "workspace:^" + "@backstage/plugin-playlist": "workspace:^" + "@backstage/plugin-puppetdb": "workspace:^" + "@backstage/plugin-rollbar": "workspace:^" + "@backstage/plugin-scaffolder": "workspace:^" + "@backstage/plugin-scaffolder-react": "workspace:^" + "@backstage/plugin-search": "workspace:^" + "@backstage/plugin-search-common": "workspace:^" + "@backstage/plugin-search-react": "workspace:^" + "@backstage/plugin-sentry": "workspace:^" + "@backstage/plugin-shortcuts": "workspace:^" + "@backstage/plugin-stack-overflow": "workspace:^" + "@backstage/plugin-stackstorm": "workspace:^" + "@backstage/plugin-tech-insights": "workspace:^" + "@backstage/plugin-tech-radar": "workspace:^" + "@backstage/plugin-techdocs": "workspace:^" + "@backstage/plugin-techdocs-module-addons-contrib": "workspace:^" + "@backstage/plugin-techdocs-react": "workspace:^" + "@backstage/plugin-todo": "workspace:^" + "@backstage/plugin-user-settings": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@internal/plugin-catalog-customized": "workspace:^" + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@octokit/rest": ^19.0.3 + "@oriflame/backstage-plugin-score-card": ^0.7.0 + "@roadiehq/backstage-plugin-buildkite": ^2.0.8 + "@roadiehq/backstage-plugin-github-insights": ^2.0.5 + "@roadiehq/backstage-plugin-github-pull-requests": ^2.2.7 + "@roadiehq/backstage-plugin-travis-ci": ^2.0.5 + "@testing-library/cypress": ^9.0.0 + "@testing-library/dom": ^8.0.0 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/jquery": ^3.3.34 + "@types/node": ^16.11.26 + "@types/react": "*" + "@types/react-dom": "*" + "@types/zen-observable": ^0.8.0 + cross-env: ^7.0.0 + cypress: ^10.0.0 + eslint-plugin-cypress: ^2.10.3 + history: ^5.0.0 + prop-types: ^15.7.2 + react: ^17.0.2 + react-dom: ^17.0.2 + react-router: ^6.3.0 + react-router-dom: ^6.3.0 + react-use: ^17.2.4 + start-server-and-test: ^1.10.11 + zen-observable: ^0.10.0 + languageName: unknown + linkType: soft + "append-field@npm:^1.0.0": version: 1.0.0 resolution: "append-field@npm:1.0.0"