From 2255e00081f7905015710c7f357ddad7a980321f Mon Sep 17 00:00:00 2001 From: Christoph Jerolimov Date: Thu, 7 Nov 2024 08:55:56 +0100 Subject: [PATCH] chore(dynamic-home-page): add plugin scaffold Signed-off-by: Christoph Jerolimov --- .../packages/app/package.json | 1 + .../packages/app/src/App.tsx | 3 +- .../packages/app/src/components/Root/Root.tsx | 4 +- .../plugins/dynamic-home-page/.eslintrc.js | 1 + .../plugins/dynamic-home-page/README.md | 13 + .../plugins/dynamic-home-page/api-report.md | 25 ++ .../plugins/dynamic-home-page/dev/index.tsx | 27 ++ .../plugins/dynamic-home-page/package.json | 61 ++++ .../ExampleComponent.test.tsx | 41 +++ .../ExampleComponent/ExampleComponent.tsx | 53 +++ .../src/components/ExampleComponent/index.ts | 16 + .../ExampleFetchComponent.test.tsx | 34 ++ .../ExampleFetchComponent.tsx | 323 ++++++++++++++++++ .../components/ExampleFetchComponent/index.ts | 16 + .../plugins/dynamic-home-page/src/index.ts | 16 + .../dynamic-home-page/src/plugin.test.ts | 22 ++ .../plugins/dynamic-home-page/src/plugin.ts | 43 +++ .../plugins/dynamic-home-page/src/routes.ts | 20 ++ .../dynamic-home-page/src/setupTests.ts | 16 + workspaces/dynamic-home-page/yarn.lock | 55 ++- 20 files changed, 787 insertions(+), 3 deletions(-) create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/.eslintrc.js create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/README.md create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/api-report.md create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/dev/index.tsx create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/package.json create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.test.tsx create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.tsx create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/index.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/index.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/index.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.test.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/routes.ts create mode 100644 workspaces/dynamic-home-page/plugins/dynamic-home-page/src/setupTests.ts diff --git a/workspaces/dynamic-home-page/packages/app/package.json b/workspaces/dynamic-home-page/packages/app/package.json index 387c528..1c72859 100644 --- a/workspaces/dynamic-home-page/packages/app/package.json +++ b/workspaces/dynamic-home-page/packages/app/package.json @@ -45,6 +45,7 @@ "@backstage/theme": "^0.6.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", + "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "workspace:^", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", diff --git a/workspaces/dynamic-home-page/packages/app/src/App.tsx b/workspaces/dynamic-home-page/packages/app/src/App.tsx index 86d0354..9ca0d55 100644 --- a/workspaces/dynamic-home-page/packages/app/src/App.tsx +++ b/workspaces/dynamic-home-page/packages/app/src/App.tsx @@ -51,6 +51,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 { DynamicHomePagePage } from '@red-hat-developer-hub/backstage-plugin-dynamic-home-page'; const app = createApp({ apis, @@ -78,7 +79,7 @@ const app = createApp({ const routes = ( - } /> + } /> } /> ) => ( }> {/* Global nav, not org-specific */} - + + 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 { JSX as JSX_2 } from 'react'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// @public (undocumented) +export const DynamicHomePagePage: () => JSX_2.Element; + +// @public (undocumented) +export const dynamicHomePagePlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/dev/index.tsx b/workspaces/dynamic-home-page/plugins/dynamic-home-page/dev/index.tsx new file mode 100644 index 0000000..401521b --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2024 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 { dynamicHomePagePlugin, DynamicHomePagePage } from '../src/plugin'; + +createDevApp() + .registerPlugin(dynamicHomePagePlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/dynamic-home-page', + }) + .render(); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/package.json b/workspaces/dynamic-home-page/plugins/dynamic-home-page/package.json new file mode 100644 index 0000000..fda0bb7 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/package.json @@ -0,0 +1,61 @@ +{ + "name": "@red-hat-developer-hub/backstage-plugin-dynamic-home-page", + "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" + }, + "repository": { + "type": "git", + "url": "https://github.com/redhat-developer/rhdh-plugins", + "directory": "workspaces/dynamic-home-page/plugins/dynamic-home-page" + }, + "backstage": { + "role": "frontend-plugin", + "pluginId": "dynamic-home-page", + "pluginPackages": [ + "@red-hat-developer-hub/backstage-plugin-dynamic-home-page" + ] + }, + "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.15.1", + "@backstage/core-plugin-api": "^1.10.0", + "@backstage/theme": "^0.6.0", + "@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 || ^18.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.28.0", + "@backstage/core-app-api": "^1.15.1", + "@backstage/dev-utils": "^1.1.2", + "@backstage/test-utils": "^1.7.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", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.test.tsx b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.test.tsx new file mode 100644 index 0000000..d2b13a3 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.test.tsx @@ -0,0 +1,41 @@ +/* + * Copyright 2024 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 { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { screen } from '@testing-library/react'; +import { registerMswTestHooks, renderInTestApp } from '@backstage/test-utils'; + +describe('ExampleComponent', () => { + const server = setupServer(); + // Enable sane handlers for network requests + registerMswTestHooks(server); + + // setup mock response + beforeEach(() => { + server.use( + rest.get('/*', (_, res, ctx) => res(ctx.status(200), ctx.json({}))), + ); + }); + + it('should render', async () => { + await renderInTestApp(); + expect( + screen.getByText('Welcome to dynamic-home-page!'), + ).toBeInTheDocument(); + }); +}); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.tsx b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.tsx new file mode 100644 index 0000000..56108e7 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/ExampleComponent.tsx @@ -0,0 +1,53 @@ +/* + * Copyright 2024 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 { 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 = () => ( + +
+ + +
+ + + A description of your plugin goes here. + + + + + + All content should be wrapped in a card like this. + + + + + + + + +
+); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/index.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/index.ts new file mode 100644 index 0000000..0d855a0 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleComponent/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 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 { ExampleComponent } from './ExampleComponent'; diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx new file mode 100644 index 0000000..ccc6015 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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 { render, screen } from '@testing-library/react'; +import { ExampleFetchComponent } from './ExampleFetchComponent'; + +describe('ExampleFetchComponent', () => { + it('renders the user table', async () => { + render(); + + // 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(); + }); +}); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx new file mode 100644 index 0000000..624c6eb --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx @@ -0,0 +1,323 @@ +/* + * Copyright 2024 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 { makeStyles } from '@material-ui/core/styles'; +import { + Table, + TableColumn, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; +import useAsync from 'react-use/lib/useAsync'; + +export const exampleUsers = { + results: [ + { + gender: 'female', + name: { + title: 'Miss', + first: 'Carolyn', + last: 'Moore', + }, + email: 'carolyn.moore@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Carolyn', + nat: 'GB', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Esma', + last: 'Berberoğlu', + }, + email: 'esma.berberoglu@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Esma', + nat: 'TR', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Isabella', + last: 'Rhodes', + }, + email: 'isabella.rhodes@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Isabella', + nat: 'GB', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Derrick', + last: 'Carter', + }, + email: 'derrick.carter@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Derrick', + nat: 'IE', + }, + { + gender: 'female', + name: { + title: 'Miss', + first: 'Mattie', + last: 'Lambert', + }, + email: 'mattie.lambert@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mattie', + nat: 'AU', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Mijat', + last: 'Rakić', + }, + email: 'mijat.rakic@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mijat', + nat: 'RS', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Javier', + last: 'Reid', + }, + email: 'javier.reid@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Javier', + nat: 'US', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Isabella', + last: 'Li', + }, + email: 'isabella.li@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Isabella', + nat: 'CA', + }, + { + gender: 'female', + name: { + title: 'Mrs', + first: 'Stephanie', + last: 'Garrett', + }, + email: 'stephanie.garrett@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Stephanie', + nat: 'AU', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Antonia', + last: 'Núñez', + }, + email: 'antonia.nunez@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Antonia', + nat: 'ES', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Donald', + last: 'Young', + }, + email: 'donald.young@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Donald', + nat: 'US', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Iegor', + last: 'Holodovskiy', + }, + email: 'iegor.holodovskiy@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Iegor', + nat: 'UA', + }, + { + gender: 'female', + name: { + title: 'Madame', + first: 'Jessica', + last: 'David', + }, + email: 'jessica.david@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Jessica', + nat: 'CH', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Eve', + last: 'Martinez', + }, + email: 'eve.martinez@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Eve', + nat: 'FR', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Caleb', + last: 'Silva', + }, + email: 'caleb.silva@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Caleb', + nat: 'US', + }, + { + gender: 'female', + name: { + title: 'Miss', + first: 'Marcia', + last: 'Jenkins', + }, + email: 'marcia.jenkins@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Marcia', + nat: 'US', + }, + { + gender: 'female', + name: { + title: 'Mrs', + first: 'Mackenzie', + last: 'Jones', + }, + email: 'mackenzie.jones@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Mackenzie', + nat: 'NZ', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Jeremiah', + last: 'Gutierrez', + }, + email: 'jeremiah.gutierrez@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Jeremiah', + nat: 'AU', + }, + { + gender: 'female', + name: { + title: 'Ms', + first: 'Luciara', + last: 'Souza', + }, + email: 'luciara.souza@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Luciara', + nat: 'BR', + }, + { + gender: 'male', + name: { + title: 'Mr', + first: 'Valgi', + last: 'da Cunha', + }, + email: 'valgi.dacunha@example.com', + picture: 'https://api.dicebear.com/6.x/open-peeps/svg?seed=Valgi', + nat: 'BR', + }, + ], +}; + +const useStyles = makeStyles({ + avatar: { + height: 32, + width: 32, + borderRadius: '50%', + }, +}); + +type User = { + gender: string; // "male" + name: { + title: string; // "Mr", + first: string; // "Duane", + last: string; // "Reed" + }; + email: string; // "duane.reed@example.com" + picture: string; // "https://api.dicebear.com/6.x/open-peeps/svg?seed=Duane" + nat: string; // "AU" +}; + +type DenseTableProps = { + users: User[]; +}; + +export const DenseTable = ({ users }: DenseTableProps) => { + const classes = useStyles(); + + const columns: TableColumn[] = [ + { title: 'Avatar', field: 'avatar' }, + { title: 'Name', field: 'name' }, + { title: 'Email', field: 'email' }, + { title: 'Nationality', field: 'nationality' }, + ]; + + const data = users.map(user => { + return { + avatar: ( + {user.name.first} + ), + name: `${user.name.first} ${user.name.last}`, + email: user.email, + nationality: user.nat, + }; + }); + + return ( + + ); +}; + +export const ExampleFetchComponent = () => { + const { value, loading, error } = useAsync(async (): Promise => { + // Would use fetch in a real world example + return exampleUsers.results; + }, []); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ; +}; diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/index.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/index.ts new file mode 100644 index 0000000..bc761d4 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/components/ExampleFetchComponent/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 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 { ExampleFetchComponent } from './ExampleFetchComponent'; diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/index.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/index.ts new file mode 100644 index 0000000..d2b80f4 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 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 { dynamicHomePagePlugin, DynamicHomePagePage } from './plugin'; diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.test.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.test.ts new file mode 100644 index 0000000..da2f77a --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2024 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 { dynamicHomePagePlugin } from './plugin'; + +describe('dynamic-home-page', () => { + it('should export plugin', () => { + expect(dynamicHomePagePlugin).toBeDefined(); + }); +}); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.ts new file mode 100644 index 0000000..1b1f166 --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/plugin.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2024 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'; + +/** + * @public + */ +export const dynamicHomePagePlugin = createPlugin({ + id: 'dynamic-home-page', + routes: { + root: rootRouteRef, + }, +}); + +/** + * @public + */ +export const DynamicHomePagePage = dynamicHomePagePlugin.provide( + createRoutableExtension({ + name: 'DynamicHomePagePage', + component: () => + import('./components/ExampleComponent').then(m => m.ExampleComponent), + mountPoint: rootRouteRef, + }), +); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/routes.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/routes.ts new file mode 100644 index 0000000..a0af3be --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2024 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: 'dynamic-home-page', +}); diff --git a/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/setupTests.ts b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/setupTests.ts new file mode 100644 index 0000000..658016f --- /dev/null +++ b/workspaces/dynamic-home-page/plugins/dynamic-home-page/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 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/workspaces/dynamic-home-page/yarn.lock b/workspaces/dynamic-home-page/yarn.lock index 0fab441..1ed708b 100644 --- a/workspaces/dynamic-home-page/yarn.lock +++ b/workspaces/dynamic-home-page/yarn.lock @@ -3661,6 +3661,33 @@ __metadata: languageName: node linkType: hard +"@backstage/dev-utils@npm:^1.1.2": + version: 1.1.2 + resolution: "@backstage/dev-utils@npm:1.1.2" + dependencies: + "@backstage/app-defaults": ^1.5.12 + "@backstage/catalog-model": ^1.7.0 + "@backstage/core-app-api": ^1.15.1 + "@backstage/core-components": ^0.15.1 + "@backstage/core-plugin-api": ^1.10.0 + "@backstage/integration-react": ^1.2.0 + "@backstage/plugin-catalog-react": ^1.14.0 + "@backstage/theme": ^0.6.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + react-use: ^17.2.4 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 6695acd5d4633892a3f55848e95b3ea2c969ad0f4601134aad1256a5366505f29fcfe1b0ee35c6086c1b16a92706fa585b6d91fdbff30bf0697d47815e6724b6 + languageName: node + linkType: hard + "@backstage/e2e-test-utils@npm:^0.1.1": version: 0.1.1 resolution: "@backstage/e2e-test-utils@npm:0.1.1" @@ -10262,6 +10289,31 @@ __metadata: languageName: node linkType: hard +"@red-hat-developer-hub/backstage-plugin-dynamic-home-page@workspace:^, @red-hat-developer-hub/backstage-plugin-dynamic-home-page@workspace:plugins/dynamic-home-page": + version: 0.0.0-use.local + resolution: "@red-hat-developer-hub/backstage-plugin-dynamic-home-page@workspace:plugins/dynamic-home-page" + dependencies: + "@backstage/cli": ^0.28.0 + "@backstage/core-app-api": ^1.15.1 + "@backstage/core-components": ^0.15.1 + "@backstage/core-plugin-api": ^1.10.0 + "@backstage/dev-utils": ^1.1.2 + "@backstage/test-utils": ^1.7.0 + "@backstage/theme": ^0.6.0 + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.61 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^14.0.0 + "@testing-library/user-event": ^14.0.0 + msw: ^1.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + languageName: unknown + linkType: soft + "@remix-run/router@npm:1.21.0": version: 1.21.0 resolution: "@remix-run/router@npm:1.21.0" @@ -14494,6 +14546,7 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@playwright/test": ^1.32.3 + "@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "workspace:^" "@testing-library/dom": ^9.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^14.0.0 @@ -28947,7 +29000,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.0.2": +"react@npm:^16.13.1 || ^17.0.0 || ^18.0.0, react@npm:^18.0.2": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: