diff --git a/.changeset/violet-pots-push.md b/.changeset/violet-pots-push.md new file mode 100644 index 0000000000..f0074ed82e --- /dev/null +++ b/.changeset/violet-pots-push.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-stack-overflow': patch +'@backstage/plugin-home-react': minor +'@backstage/plugin-home': patch +--- + +Extract new plugin-home-react package and deprecate createCardExtension in plugin-home diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3880a0facd..7518fbab96 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -56,6 +56,7 @@ yarn.lock @backstage/maintainers @back /plugins/gcalendar @backstage/maintainers @szubster @ptychu @kielosz @alexrybch /plugins/git-release-manager @backstage/maintainers @erikengervall /plugins/home @backstage/discoverability-maintainers +/plugins/home-* @backstage/discoverability-maintainers /plugins/ilert @backstage/maintainers @yacut /plugins/jenkins @backstage/maintainers @timja /plugins/jenkins-backend @backstage/maintainers @timja diff --git a/plugins/home-react/.eslintrc.js b/plugins/home-react/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/home-react/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/home-react/README.md b/plugins/home-react/README.md new file mode 100644 index 0000000000..c10ad8d323 --- /dev/null +++ b/plugins/home-react/README.md @@ -0,0 +1,3 @@ +# Home React + +A new Library that contains React Components for [home plugin](/plugins/home/README.md) depend on. diff --git a/plugins/home-react/api-report.md b/plugins/home-react/api-report.md new file mode 100644 index 0000000000..42e8fd0b0f --- /dev/null +++ b/plugins/home-react/api-report.md @@ -0,0 +1,76 @@ +## API Report File for "@backstage/plugin-home-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { Extension } from '@backstage/core-plugin-api'; +import { RJSFSchema } from '@rjsf/utils'; + +// @public (undocumented) +export type CardConfig = { + layout?: CardLayout; + settings?: CardSettings; +}; + +// @public (undocumented) +export type CardExtensionProps = ComponentRenderer & { + title?: string; +} & T; + +// @public (undocumented) +export type CardLayout = { + width?: { + minColumns?: number; + maxColumns?: number; + defaultColumns?: number; + }; + height?: { + minRows?: number; + maxRows?: number; + defaultRows?: number; + }; +}; + +// @public (undocumented) +export type CardSettings = { + schema?: RJSFSchema; +}; + +// @public (undocumented) +export type ComponentParts = { + Content: (props?: any) => JSX.Element; + Actions?: () => JSX.Element; + Settings?: () => JSX.Element; + ContextProvider?: (props: any) => JSX.Element; +}; + +// @public (undocumented) +export type ComponentRenderer = { + Renderer?: (props: RendererProps) => JSX.Element; +}; + +// @public +export function createCardExtension(options: { + title: string; + components: () => Promise; + name?: string; + description?: string; + layout?: CardLayout; + settings?: CardSettings; +}): Extension<(props: CardExtensionProps) => JSX.Element>; + +// @public (undocumented) +export type RendererProps = { + title: string; +} & ComponentParts; + +// @public (undocumented) +export const SettingsModal: (props: { + open: boolean; + close: Function; + componentName: string; + children: JSX.Element; +}) => JSX.Element; +``` diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json new file mode 100644 index 0000000000..a001db5b53 --- /dev/null +++ b/plugins/home-react/package.json @@ -0,0 +1,65 @@ +{ + "name": "@backstage/plugin-home-react", + "description": "A Backstage plugin that contains react components helps you build a home page", + "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": "web-library" + }, + "homepage": "https://github.com/backstage/backstage/tree/master/plugins/home-react#readme", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/home-react" + }, + "keywords": [ + "backstage", + "homepage" + ], + "scripts": { + "build": "backstage-cli package build", + "start": "backstage-cli package start", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "clean": "backstage-cli package clean" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@rjsf/utils": "5.6.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0", + "react-dom": "^16.13.1 || ^17.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@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/node": "^16.11.26", + "@types/react": "^16.13.1 || ^17.0.0", + "@types/react-grid-layout": "^1.3.2", + "cross-fetch": "^3.1.5", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/home/src/components/SettingsModal.tsx b/plugins/home-react/src/components/SettingsModal.tsx similarity index 100% rename from plugins/home/src/components/SettingsModal.tsx rename to plugins/home-react/src/components/SettingsModal.tsx diff --git a/plugins/home-react/src/components/index.ts b/plugins/home-react/src/components/index.ts new file mode 100644 index 0000000000..dce6968b36 --- /dev/null +++ b/plugins/home-react/src/components/index.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ + +export { SettingsModal } from './SettingsModal'; diff --git a/plugins/home/src/extensions.tsx b/plugins/home-react/src/extensions.tsx similarity index 100% rename from plugins/home/src/extensions.tsx rename to plugins/home-react/src/extensions.tsx diff --git a/plugins/home-react/src/index.ts b/plugins/home-react/src/index.ts new file mode 100644 index 0000000000..1f02ded1c6 --- /dev/null +++ b/plugins/home-react/src/index.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2021 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. + */ + +/** + * A Backstage plugin that helps you build a home page + * + * @packageDocumentation + */ +export * from './components'; +export { createCardExtension } from './extensions'; +export type { + CardExtensionProps, + ComponentParts, + ComponentRenderer, + RendererProps, + CardLayout, + CardSettings, + CardConfig, +} from './extensions'; diff --git a/plugins/home/README.md b/plugins/home/README.md index 7da0034662..20b91289b1 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -51,6 +51,8 @@ The Home Page can be composed with regular React components, so there's no magic Finally, the `createCardExtension` also accepts a generic, such that Component Developers can indicate to App Integrators what custom props their component will accept, such as the example below where the default category of the random jokes can be set. ```tsx +import { createCardExtension } from '@backstage/plugin-home-react'; + export const RandomJokeHomePageComponent = homePlugin.provide( createCardExtension<{ defaultCategory?: 'programming' | 'any' }>({ title: 'Random Joke', @@ -121,6 +123,8 @@ want to add additional configuration like component size or settings, you can de property: ```tsx +import { createCardExtension } from '@backstage/plugin-home-react'; + export const RandomJokeHomePageComponent = homePlugin.provide( createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({ name: 'HomePageRandomJoke', @@ -178,6 +182,8 @@ properties. The `settings.schema` object should follow must be `object`. ```tsx +import { createCardExtension } from '@backstage/plugin-home-react'; + export const HomePageRandomJoke = homePlugin.provide( createCardExtension<{ defaultCategory?: 'any' | 'programming' }>({ name: 'HomePageRandomJoke', diff --git a/plugins/home/api-report.md b/plugins/home/api-report.md index 43fdbf403c..56b1f54331 100644 --- a/plugins/home/api-report.md +++ b/plugins/home/api-report.md @@ -6,36 +6,30 @@ /// import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { Extension } from '@backstage/core-plugin-api'; +import { CardConfig as CardConfig_2 } from '@backstage/plugin-home-react'; +import { CardExtensionProps as CardExtensionProps_2 } from '@backstage/plugin-home-react'; +import { CardLayout as CardLayout_2 } from '@backstage/plugin-home-react'; +import { CardSettings as CardSettings_2 } from '@backstage/plugin-home-react'; +import { ComponentParts as ComponentParts_2 } from '@backstage/plugin-home-react'; +import { ComponentRenderer as ComponentRenderer_2 } from '@backstage/plugin-home-react'; +import { createCardExtension as createCardExtension_2 } from '@backstage/plugin-home-react'; import { default as React_2 } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; -import { RJSFSchema } from '@rjsf/utils'; +import { RendererProps as RendererProps_2 } from '@backstage/plugin-home-react'; import { RouteRef } from '@backstage/core-plugin-api'; -// @public (undocumented) -export type CardExtensionProps = ComponentRenderer & { - title?: string; -} & T; +// @public @deprecated (undocumented) +export type CardConfig = CardConfig_2; -// @public (undocumented) -export type CardLayout = { - width?: { - minColumns?: number; - maxColumns?: number; - defaultColumns?: number; - }; - height?: { - minRows?: number; - maxRows?: number; - defaultRows?: number; - }; -}; +// @public @deprecated (undocumented) +export type CardExtensionProps = CardExtensionProps_2; -// @public (undocumented) -export type CardSettings = { - schema?: RJSFSchema; -}; +// @public @deprecated (undocumented) +export type CardLayout = CardLayout_2; + +// @public @deprecated (undocumented) +export type CardSettings = CardSettings_2; // @public (undocumented) export type ClockConfig = { @@ -53,18 +47,11 @@ export const ComponentAccordion: (props: { ContextProvider?: ((props: any) => JSX.Element) | undefined; }) => JSX.Element; -// @public (undocumented) -export type ComponentParts = { - Content: (props?: any) => JSX.Element; - Actions?: () => JSX.Element; - Settings?: () => JSX.Element; - ContextProvider?: (props: any) => JSX.Element; -}; +// @public @deprecated (undocumented) +export type ComponentParts = ComponentParts_2; -// @public (undocumented) -export type ComponentRenderer = { - Renderer?: (props: RendererProps) => JSX.Element; -}; +// @public @deprecated (undocumented) +export type ComponentRenderer = ComponentRenderer_2; // @public (undocumented) export const ComponentTab: (props: { @@ -82,15 +69,8 @@ export const ComponentTabs: (props: { }[]; }) => JSX.Element; -// @public -export function createCardExtension(options: { - title: string; - components: () => Promise; - name?: string; - description?: string; - layout?: CardLayout; - settings?: CardSettings; -}): Extension<(props: CardExtensionProps) => JSX.Element>; +// @public @deprecated (undocumented) +export const createCardExtension: typeof createCardExtension_2; // @public export const CustomHomepageGrid: ( @@ -124,19 +104,19 @@ export const HomepageCompositionRoot: (props: { // @public (undocumented) export const HomePageRandomJoke: ( - props: CardExtensionProps<{ + props: CardExtensionProps_2<{ defaultCategory?: 'any' | 'programming' | undefined; }>, ) => JSX.Element; // @public export const HomePageStarredEntities: ( - props: CardExtensionProps, + props: CardExtensionProps_2, ) => JSX.Element; // @public export const HomePageToolkit: ( - props: CardExtensionProps, + props: CardExtensionProps_2, ) => JSX.Element; // @public (undocumented) @@ -157,12 +137,10 @@ export type LayoutConfiguration = { height: number; }; -// @public (undocumented) -export type RendererProps = { - title: string; -} & ComponentParts; +// @public @deprecated (undocumented) +export type RendererProps = RendererProps_2; -// @public (undocumented) +// @public @deprecated (undocumented) export const SettingsModal: (props: { open: boolean; close: Function; diff --git a/plugins/home/package.json b/plugins/home/package.json index ff714b16ca..c0b2b005df 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -38,6 +38,7 @@ "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-home-react": "workspace:^", "@backstage/theme": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", diff --git a/plugins/home/src/componentRenderers/ComponentAccordion.tsx b/plugins/home/src/componentRenderers/ComponentAccordion.tsx index 8b9795c9c3..77e7561e55 100644 --- a/plugins/home/src/componentRenderers/ComponentAccordion.tsx +++ b/plugins/home/src/componentRenderers/ComponentAccordion.tsx @@ -15,6 +15,7 @@ */ import React from 'react'; +import { SettingsModal } from '@backstage/plugin-home-react'; import { Accordion, AccordionDetails, @@ -27,8 +28,6 @@ import { makeStyles } from '@material-ui/core/styles'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import SettingsIcon from '@material-ui/icons/Settings'; -import { SettingsModal } from '../components'; - const useStyles = makeStyles((theme: Theme) => ({ settingsIconButton: { padding: theme.spacing(0, 1, 0, 0), diff --git a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx index 6af9044cbd..ae8e0dd9bb 100644 --- a/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx +++ b/plugins/home/src/components/CustomHomepage/CustomHomepageGrid.tsx @@ -42,7 +42,7 @@ import { LayoutConfigurationSchema, WidgetSchema, } from './types'; -import { CardConfig } from '../../extensions'; +import { CardConfig } from '@backstage/plugin-home-react'; // eslint-disable-next-line new-cap const ResponsiveGrid = WidthProvider(Responsive); diff --git a/plugins/home/src/components/index.ts b/plugins/home/src/components/index.ts index e06013d3fa..e528e0795d 100644 --- a/plugins/home/src/components/index.ts +++ b/plugins/home/src/components/index.ts @@ -15,5 +15,4 @@ */ export { HomepageCompositionRoot } from './HomepageCompositionRoot'; -export { SettingsModal } from './SettingsModal'; export * from './CustomHomepage'; diff --git a/plugins/home/src/deprecated.ts b/plugins/home/src/deprecated.ts new file mode 100644 index 0000000000..f116d2c9f9 --- /dev/null +++ b/plugins/home/src/deprecated.ts @@ -0,0 +1,81 @@ +/* + * 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 { + createCardExtension as homeReactCreateCardExtension, + CardConfig as homeReactCardConfig, + CardExtensionProps as homeReactCardExtensionProps, + CardLayout as homeReactCardLayout, + CardSettings as homeReactCardSettings, + ComponentParts as homeReactComponentParts, + ComponentRenderer as homeReactComponentRenderer, + RendererProps as homeReactRendererProps, + SettingsModal as homeReactSettingsModal, +} from '@backstage/plugin-home-react'; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export const createCardExtension = homeReactCreateCardExtension; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type CardExtensionProps = homeReactCardExtensionProps; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type CardLayout = homeReactCardLayout; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type CardSettings = homeReactCardSettings; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type CardConfig = homeReactCardConfig; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type ComponentParts = homeReactComponentParts; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type ComponentRenderer = homeReactComponentRenderer; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export type RendererProps = homeReactRendererProps; + +/** + * @public + * @deprecated Import from `@backstage/plugin-home-react` instead + */ +export const SettingsModal = homeReactSettingsModal; diff --git a/plugins/home/src/index.ts b/plugins/home/src/index.ts index daa781f02c..63407c8531 100644 --- a/plugins/home/src/index.ts +++ b/plugins/home/src/index.ts @@ -36,12 +36,4 @@ export { export * from './components'; export * from './assets'; export * from './homePageComponents'; -export { createCardExtension } from './extensions'; -export type { - CardExtensionProps, - ComponentParts, - ComponentRenderer, - RendererProps, - CardLayout, - CardSettings, -} from './extensions'; +export * from './deprecated'; diff --git a/plugins/home/src/plugin.ts b/plugins/home/src/plugin.ts index 339e6dba2b..74a1c11390 100644 --- a/plugins/home/src/plugin.ts +++ b/plugins/home/src/plugin.ts @@ -19,7 +19,7 @@ import { createPlugin, createRoutableExtension, } from '@backstage/core-plugin-api'; -import { createCardExtension } from './extensions'; +import { createCardExtension } from '@backstage/plugin-home-react'; import { ToolkitContentProps } from './homePageComponents'; import { rootRouteRef } from './routes'; diff --git a/plugins/stack-overflow/api-report.md b/plugins/stack-overflow/api-report.md index b006f263ed..3e27318acb 100644 --- a/plugins/stack-overflow/api-report.md +++ b/plugins/stack-overflow/api-report.md @@ -7,7 +7,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { CardExtensionProps } from '@backstage/plugin-home'; +import { CardExtensionProps } from '@backstage/plugin-home-react'; import { default as React_2 } from 'react'; import { ResultHighlight } from '@backstage/plugin-search-common'; import { SearchResultListItemExtensionProps } from '@backstage/plugin-search-react'; diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 5b9cdb0213..e550e15762 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -25,7 +25,7 @@ "@backstage/config": "workspace:^", "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", - "@backstage/plugin-home": "workspace:^", + "@backstage/plugin-home-react": "workspace:^", "@backstage/plugin-search-common": "workspace:^", "@backstage/plugin-search-react": "workspace:^", "@backstage/theme": "workspace:^", diff --git a/plugins/stack-overflow/src/plugin.ts b/plugins/stack-overflow/src/plugin.ts index 5be4c89cbe..017900bc02 100644 --- a/plugins/stack-overflow/src/plugin.ts +++ b/plugins/stack-overflow/src/plugin.ts @@ -20,7 +20,7 @@ import { createApiFactory, configApiRef, } from '@backstage/core-plugin-api'; -import { createCardExtension } from '@backstage/plugin-home'; +import { createCardExtension } from '@backstage/plugin-home-react'; import { StackOverflowQuestionsContentProps } from './types'; import { stackOverflowApiRef, StackOverflowClient } from './api'; import { SearchResultListItemExtensionProps } from '@backstage/plugin-search-react'; diff --git a/yarn.lock b/yarn.lock index b046cf168b..e29fa78a68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7038,6 +7038,35 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-home-react@workspace:^, @backstage/plugin-home-react@workspace:plugins/home-react": + version: 0.0.0-use.local + resolution: "@backstage/plugin-home-react@workspace:plugins/home-react" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@rjsf/utils": 5.6.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/node": ^16.11.26 + "@types/react": ^16.13.1 || ^17.0.0 + "@types/react-grid-layout": ^1.3.2 + cross-fetch: ^3.1.5 + msw: ^1.0.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + react-dom: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + languageName: unknown + linkType: soft + "@backstage/plugin-home@^0.5.1, @backstage/plugin-home@workspace:^, @backstage/plugin-home@workspace:plugins/home": version: 0.0.0-use.local resolution: "@backstage/plugin-home@workspace:plugins/home" @@ -7050,6 +7079,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/plugin-home-react": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/theme": "workspace:^" "@material-ui/core": ^4.12.2 @@ -8846,7 +8876,7 @@ __metadata: "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/dev-utils": "workspace:^" - "@backstage/plugin-home": "workspace:^" + "@backstage/plugin-home-react": "workspace:^" "@backstage/plugin-search-common": "workspace:^" "@backstage/plugin-search-react": "workspace:^" "@backstage/test-utils": "workspace:^"