diff --git a/.changeset/cyan-lies-flow.md b/.changeset/cyan-lies-flow.md
new file mode 100644
index 0000000000..e7da9fab0a
--- /dev/null
+++ b/.changeset/cyan-lies-flow.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-search': minor
+---
+
+Migrated to new composability API, exporting the plugin instance as `searchPlugin`, and page as `SearchPage`. Due to the old router component also being called `SearchPage`, this is a breaking change. The old page component is now exported as `Router`, which can be used to maintain the old behavior.
diff --git a/.changeset/funny-students-shout.md b/.changeset/funny-students-shout.md
new file mode 100644
index 0000000000..97b273c687
--- /dev/null
+++ b/.changeset/funny-students-shout.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-register-component': patch
+---
+
+Migrated to new composability API, exporting the plugin instance as `registerComponentPlugin`, and page as `RegisterComponentPage`.
diff --git a/.changeset/ninety-houses-shout.md b/.changeset/ninety-houses-shout.md
new file mode 100644
index 0000000000..845decc74c
--- /dev/null
+++ b/.changeset/ninety-houses-shout.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-techdocs': patch
+---
+
+Migrated to new composability API, exporting the plugin instance as `techdocsPlugin`, the top-level page as `TechdocsPage`, and the entity content as `EntityTechdocsContent`.
diff --git a/.changeset/perfect-ladybugs-listen.md b/.changeset/perfect-ladybugs-listen.md
new file mode 100644
index 0000000000..2f9e65c1d9
--- /dev/null
+++ b/.changeset/perfect-ladybugs-listen.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-pagerduty': patch
+---
+
+Migrated to new composability API, exporting the plugin instance as `pagerDutyPlugin`, entity card as `EntityPagerDutyCard`, and entity conditional as `isPagerDutyAvailable`.
diff --git a/.changeset/two-dogs-search.md b/.changeset/two-dogs-search.md
new file mode 100644
index 0000000000..5f673c0cfb
--- /dev/null
+++ b/.changeset/two-dogs-search.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-gitops-profiles': patch
+---
+
+Migrated to new composability API, exporting the plugin instance as `gitopsProfilesPlugin` and pages as `GitopsProfilesClusterListPage`, `GitopsProfilesClusterPage`, and `GitopsProfilesCreatePage`.
diff --git a/plugins/gitops-profiles/dev/index.tsx b/plugins/gitops-profiles/dev/index.tsx
index 812a5585d4..c164e4005d 100644
--- a/plugins/gitops-profiles/dev/index.tsx
+++ b/plugins/gitops-profiles/dev/index.tsx
@@ -15,6 +15,6 @@
*/
import { createDevApp } from '@backstage/dev-utils';
-import { plugin } from '../src/plugin';
+import { gitopsProfilesPlugin } from '../src/plugin';
-createDevApp().registerPlugin(plugin).render();
+createDevApp().registerPlugin(gitopsProfilesPlugin).render();
diff --git a/plugins/gitops-profiles/src/index.ts b/plugins/gitops-profiles/src/index.ts
index d67bc6a864..876c7c3263 100644
--- a/plugins/gitops-profiles/src/index.ts
+++ b/plugins/gitops-profiles/src/index.ts
@@ -14,5 +14,11 @@
* limitations under the License.
*/
-export { plugin } from './plugin';
+export {
+ gitopsProfilesPlugin,
+ gitopsProfilesPlugin as plugin,
+ GitopsProfilesClusterListPage,
+ GitopsProfilesClusterPage,
+ GitopsProfilesCreatePage,
+} from './plugin';
export * from './api';
diff --git a/plugins/gitops-profiles/src/plugin.test.ts b/plugins/gitops-profiles/src/plugin.test.ts
index 19bc49eba7..fa26902f2b 100644
--- a/plugins/gitops-profiles/src/plugin.test.ts
+++ b/plugins/gitops-profiles/src/plugin.test.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-import { plugin } from './plugin';
+import { gitopsProfilesPlugin } from './plugin';
describe('gitops-profiles', () => {
it('should export plugin', () => {
- expect(plugin).toBeDefined();
+ expect(gitopsProfilesPlugin).toBeDefined();
});
});
diff --git a/plugins/gitops-profiles/src/plugin.ts b/plugins/gitops-profiles/src/plugin.ts
index 45820644f7..98a0067969 100644
--- a/plugins/gitops-profiles/src/plugin.ts
+++ b/plugins/gitops-profiles/src/plugin.ts
@@ -14,7 +14,11 @@
* limitations under the License.
*/
-import { createPlugin, createApiFactory } from '@backstage/core';
+import {
+ createPlugin,
+ createApiFactory,
+ createRoutableExtension,
+} from '@backstage/core';
import ProfileCatalog from './components/ProfileCatalog';
import ClusterPage from './components/ClusterPage';
import ClusterList from './components/ClusterList';
@@ -25,7 +29,7 @@ import {
} from './routes';
import { gitOpsApiRef, GitOpsRestApi } from './api';
-export const plugin = createPlugin({
+export const gitopsProfilesPlugin = createPlugin({
id: 'gitops-profiles',
apis: [
createApiFactory(gitOpsApiRef, new GitOpsRestApi('http://localhost:3008')),
@@ -35,4 +39,30 @@ export const plugin = createPlugin({
router.addRoute(gitOpsClusterDetailsRoute, ClusterPage);
router.addRoute(gitOpsClusterCreateRoute, ProfileCatalog);
},
+ routes: {
+ listPage: gitOpsClusterListRoute,
+ detailsPage: gitOpsClusterDetailsRoute,
+ createPage: gitOpsClusterCreateRoute,
+ },
});
+
+export const GitopsProfilesClusterListPage = gitopsProfilesPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./components/ClusterList').then(m => m.default),
+ mountPoint: gitOpsClusterListRoute,
+ }),
+);
+
+export const GitopsProfilesClusterPage = gitopsProfilesPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./components/ClusterPage').then(m => m.default),
+ mountPoint: gitOpsClusterDetailsRoute,
+ }),
+);
+
+export const GitopsProfilesCreatePage = gitopsProfilesPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./components/ProfileCatalog').then(m => m.default),
+ mountPoint: gitOpsClusterCreateRoute,
+ }),
+);
diff --git a/plugins/gitops-profiles/src/routes.ts b/plugins/gitops-profiles/src/routes.ts
index f9bdefa806..28be85bd38 100644
--- a/plugins/gitops-profiles/src/routes.ts
+++ b/plugins/gitops-profiles/src/routes.ts
@@ -28,6 +28,7 @@ export const gitOpsClusterDetailsRoute = createRouteRef({
icon: NoIcon,
path: '/gitops-cluster/:owner/:repo',
title: 'GitOps Cluster details',
+ params: ['owner', 'repo'],
});
export const gitOpsClusterCreateRoute = createRouteRef({
diff --git a/plugins/pagerduty/dev/index.tsx b/plugins/pagerduty/dev/index.tsx
index 264d6f801f..ad46c0ca9e 100644
--- a/plugins/pagerduty/dev/index.tsx
+++ b/plugins/pagerduty/dev/index.tsx
@@ -14,6 +14,6 @@
* limitations under the License.
*/
import { createDevApp } from '@backstage/dev-utils';
-import { plugin } from '../src/plugin';
+import { pagerDutyPlugin } from '../src/plugin';
-createDevApp().registerPlugin(plugin).render();
+createDevApp().registerPlugin(pagerDutyPlugin).render();
diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json
index a5db20e9ab..afd41dcc46 100644
--- a/plugins/pagerduty/package.json
+++ b/plugins/pagerduty/package.json
@@ -31,6 +31,7 @@
},
"dependencies": {
"@backstage/catalog-model": "^0.7.1",
+ "@backstage/plugin-catalog-react": "^0.0.2",
"@backstage/core": "^0.6.0",
"@backstage/theme": "^0.2.3",
"@material-ui/core": "^4.11.0",
diff --git a/plugins/pagerduty/src/components/PagerDutyCard.test.tsx b/plugins/pagerduty/src/components/PagerDutyCard.test.tsx
index a6615aee82..a719a27f86 100644
--- a/plugins/pagerduty/src/components/PagerDutyCard.test.tsx
+++ b/plugins/pagerduty/src/components/PagerDutyCard.test.tsx
@@ -17,6 +17,7 @@ import React from 'react';
import { render, waitFor, fireEvent, act } from '@testing-library/react';
import { PagerDutyCard } from './PagerDutyCard';
import { Entity } from '@backstage/catalog-model';
+import { EntityProvider } from '@backstage/plugin-catalog-react';
import { wrapInTestApp } from '@backstage/test-utils';
import {
alertApiRef,
@@ -80,7 +81,9 @@ describe('PageDutyCard', () => {
const { getByText, queryByTestId } = render(
wrapInTestApp(
-
+
+
+
,
),
);
@@ -99,7 +102,9 @@ describe('PageDutyCard', () => {
const { getByText, queryByTestId } = render(
wrapInTestApp(
-
+
+
+
,
),
);
@@ -114,7 +119,9 @@ describe('PageDutyCard', () => {
const { getByText, queryByTestId } = render(
wrapInTestApp(
-
+
+
+
,
),
);
@@ -134,7 +141,9 @@ describe('PageDutyCard', () => {
const { getByText, queryByTestId, getByTestId, getByRole } = render(
wrapInTestApp(
-
+
+
+
,
),
);
diff --git a/plugins/pagerduty/src/components/PagerDutyCard.tsx b/plugins/pagerduty/src/components/PagerDutyCard.tsx
index 5fb2cd7f4a..e03fb0fdbe 100644
--- a/plugins/pagerduty/src/components/PagerDutyCard.tsx
+++ b/plugins/pagerduty/src/components/PagerDutyCard.tsx
@@ -16,6 +16,7 @@
import React, { useState, useCallback } from 'react';
import { useApi, Progress, HeaderIconLinkRow } from '@backstage/core';
import { Entity } from '@backstage/catalog-model';
+import { useEntity } from '@backstage/plugin-catalog-react';
import {
Button,
makeStyles,
@@ -56,11 +57,13 @@ export const isPluginApplicableToEntity = (entity: Entity) =>
Boolean(entity.metadata.annotations?.[PAGERDUTY_INTEGRATION_KEY]);
type Props = {
- entity: Entity;
+ /** @deprecated The entity is now grabbed from context instead */
+ entity?: Entity;
};
-export const PagerDutyCard = ({ entity }: Props) => {
+export const PagerDutyCard = (_props: Props) => {
const classes = useStyles();
+ const { entity } = useEntity();
const api = useApi(pagerDutyApiRef);
const [showDialog, setShowDialog] = useState(false);
const [refreshIncidents, setRefreshIncidents] = useState(false);
diff --git a/plugins/pagerduty/src/index.ts b/plugins/pagerduty/src/index.ts
index 4ecd4edcc6..2dfedab164 100644
--- a/plugins/pagerduty/src/index.ts
+++ b/plugins/pagerduty/src/index.ts
@@ -13,9 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export { plugin } from './plugin';
+export {
+ pagerDutyPlugin,
+ pagerDutyPlugin as plugin,
+ EntityPagerDutyCard,
+} from './plugin';
export {
isPluginApplicableToEntity,
+ isPluginApplicableToEntity as isPagerDutyAvailable,
PagerDutyCard,
} from './components/PagerDutyCard';
export {
diff --git a/plugins/pagerduty/src/plugin.test.ts b/plugins/pagerduty/src/plugin.test.ts
index 8d4545ac12..c1175ab384 100644
--- a/plugins/pagerduty/src/plugin.test.ts
+++ b/plugins/pagerduty/src/plugin.test.ts
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { plugin } from './plugin';
+import { pagerDutyPlugin } from './plugin';
describe('pagerduty', () => {
it('should export plugin', () => {
- expect(plugin).toBeDefined();
+ expect(pagerDutyPlugin).toBeDefined();
});
});
diff --git a/plugins/pagerduty/src/plugin.ts b/plugins/pagerduty/src/plugin.ts
index 34796f491e..fbe827b90d 100644
--- a/plugins/pagerduty/src/plugin.ts
+++ b/plugins/pagerduty/src/plugin.ts
@@ -19,6 +19,7 @@ import {
createRouteRef,
discoveryApiRef,
configApiRef,
+ createComponentExtension,
} from '@backstage/core';
import { pagerDutyApiRef, PagerDutyClient } from './api';
@@ -27,7 +28,7 @@ export const rootRouteRef = createRouteRef({
title: 'pagerduty',
});
-export const plugin = createPlugin({
+export const pagerDutyPlugin = createPlugin({
id: 'pagerduty',
apis: [
createApiFactory({
@@ -38,3 +39,12 @@ export const plugin = createPlugin({
}),
],
});
+
+export const EntityPagerDutyCard = pagerDutyPlugin.provide(
+ createComponentExtension({
+ component: {
+ lazy: () =>
+ import('./components/PagerDutyCard').then(m => m.PagerDutyCard),
+ },
+ }),
+);
diff --git a/plugins/register-component/dev/index.tsx b/plugins/register-component/dev/index.tsx
index 812a5585d4..3304d0874f 100644
--- a/plugins/register-component/dev/index.tsx
+++ b/plugins/register-component/dev/index.tsx
@@ -15,6 +15,6 @@
*/
import { createDevApp } from '@backstage/dev-utils';
-import { plugin } from '../src/plugin';
+import { registerComponentPlugin } from '../src/plugin';
-createDevApp().registerPlugin(plugin).render();
+createDevApp().registerPlugin(registerComponentPlugin).render();
diff --git a/plugins/register-component/src/index.ts b/plugins/register-component/src/index.ts
index ff7857cacd..56bcd06fde 100644
--- a/plugins/register-component/src/index.ts
+++ b/plugins/register-component/src/index.ts
@@ -14,5 +14,9 @@
* limitations under the License.
*/
-export { plugin } from './plugin';
+export {
+ registerComponentPlugin,
+ registerComponentPlugin as plugin,
+ RegisterComponentPage,
+} from './plugin';
export { Router } from './components/Router';
diff --git a/plugins/register-component/src/plugin.test.ts b/plugins/register-component/src/plugin.test.ts
index 1e61060202..2b6ad48bcf 100644
--- a/plugins/register-component/src/plugin.test.ts
+++ b/plugins/register-component/src/plugin.test.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-import { plugin } from './plugin';
+import { registerComponentPlugin } from './plugin';
describe('register-component', () => {
it('should export plugin', () => {
- expect(plugin).toBeDefined();
+ expect(registerComponentPlugin).toBeDefined();
});
});
diff --git a/plugins/register-component/src/plugin.ts b/plugins/register-component/src/plugin.ts
index 17f99917c8..d3727158e5 100644
--- a/plugins/register-component/src/plugin.ts
+++ b/plugins/register-component/src/plugin.ts
@@ -14,8 +14,29 @@
* limitations under the License.
*/
-import { createPlugin } from '@backstage/core';
+import {
+ createPlugin,
+ createRoutableExtension,
+ createRouteRef,
+} from '@backstage/core';
-export const plugin = createPlugin({
- id: 'register-component',
+const rootRouteRef = createRouteRef({
+ title: 'Register Component',
});
+
+export const registerComponentPlugin = createPlugin({
+ id: 'register-component',
+ routes: {
+ root: rootRouteRef,
+ },
+});
+
+export const RegisterComponentPage = registerComponentPlugin.provide(
+ createRoutableExtension({
+ component: () =>
+ import('./components/RegisterComponentPage').then(
+ m => m.RegisterComponentPage,
+ ),
+ mountPoint: rootRouteRef,
+ }),
+);
diff --git a/plugins/search/dev/index.tsx b/plugins/search/dev/index.tsx
index 264d6f801f..e6e97ead6d 100644
--- a/plugins/search/dev/index.tsx
+++ b/plugins/search/dev/index.tsx
@@ -14,6 +14,6 @@
* limitations under the License.
*/
import { createDevApp } from '@backstage/dev-utils';
-import { plugin } from '../src/plugin';
+import { searchPlugin } from '../src/plugin';
-createDevApp().registerPlugin(plugin).render();
+createDevApp().registerPlugin(searchPlugin).render();
diff --git a/plugins/search/src/index.ts b/plugins/search/src/index.ts
index 77ad7f9266..572d75bea5 100644
--- a/plugins/search/src/index.ts
+++ b/plugins/search/src/index.ts
@@ -13,5 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export { plugin } from './plugin';
-export * from './components';
+export { searchPlugin, searchPlugin as plugin, SearchPage } from './plugin';
+export {
+ Filters,
+ FiltersButton,
+ SearchBar,
+ SearchPage as Router,
+ SearchResult,
+ SidebarSearch,
+} from './components';
+export type { FiltersState } from './components';
diff --git a/plugins/search/src/plugin.test.ts b/plugins/search/src/plugin.test.ts
index 92b8d5bcbf..902faeaf9e 100644
--- a/plugins/search/src/plugin.test.ts
+++ b/plugins/search/src/plugin.test.ts
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { plugin } from './plugin';
+import { searchPlugin } from './plugin';
describe('search', () => {
it('should export plugin', () => {
- expect(plugin).toBeDefined();
+ expect(searchPlugin).toBeDefined();
});
});
diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts
index 44c7bcb042..37503b7751 100644
--- a/plugins/search/src/plugin.ts
+++ b/plugins/search/src/plugin.ts
@@ -13,17 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { createPlugin, createRouteRef } from '@backstage/core';
-import { SearchPage } from './components/SearchPage';
+import {
+ createPlugin,
+ createRouteRef,
+ createRoutableExtension,
+} from '@backstage/core';
+import { SearchPage as SearchPageComponent } from './components/SearchPage';
export const rootRouteRef = createRouteRef({
path: '/search',
title: 'search',
});
-export const plugin = createPlugin({
+export const searchPlugin = createPlugin({
id: 'search',
register({ router }) {
- router.addRoute(rootRouteRef, SearchPage);
+ router.addRoute(rootRouteRef, SearchPageComponent);
+ },
+ routes: {
+ root: rootRouteRef,
},
});
+
+export const SearchPage = searchPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./components/SearchPage').then(m => m.SearchPage),
+ mountPoint: rootRouteRef,
+ }),
+);
diff --git a/plugins/techdocs/dev/index.tsx b/plugins/techdocs/dev/index.tsx
index 42fa9a9ec4..4cf74c9622 100644
--- a/plugins/techdocs/dev/index.tsx
+++ b/plugins/techdocs/dev/index.tsx
@@ -16,7 +16,7 @@
import { configApiRef, discoveryApiRef } from '@backstage/core';
import { createDevApp } from '@backstage/dev-utils';
-import { plugin } from '../src/plugin';
+import { techdocsPlugin } from '../src/plugin';
import { TechDocsDevStorageApi } from './api';
import { techdocsStorageApiRef } from '../src';
@@ -30,5 +30,5 @@ createDevApp()
discoveryApi,
}),
})
- .registerPlugin(plugin)
+ .registerPlugin(techdocsPlugin)
.render();
diff --git a/plugins/techdocs/src/Router.tsx b/plugins/techdocs/src/Router.tsx
index 262f542ee6..b220912174 100644
--- a/plugins/techdocs/src/Router.tsx
+++ b/plugins/techdocs/src/Router.tsx
@@ -16,6 +16,7 @@
import React from 'react';
import { Entity } from '@backstage/catalog-model';
+import { useEntity } from '@backstage/plugin-catalog-react';
import { Route, Routes } from 'react-router-dom';
import { MissingAnnotationEmptyState } from '@backstage/core';
import {
@@ -38,7 +39,14 @@ export const Router = () => {
);
};
-export const EmbeddedDocsRouter = ({ entity }: { entity: Entity }) => {
+type Props = {
+ /** @deprecated The entity is now grabbed from context instead */
+ entity?: Entity;
+};
+
+export const EmbeddedDocsRouter = (_props: Props) => {
+ const { entity } = useEntity();
+
const projectId = entity.metadata.annotations?.[TECHDOCS_ANNOTATION];
if (!projectId) {
diff --git a/plugins/techdocs/src/index.ts b/plugins/techdocs/src/index.ts
index 1726e0daf3..30c143e31f 100644
--- a/plugins/techdocs/src/index.ts
+++ b/plugins/techdocs/src/index.ts
@@ -14,7 +14,12 @@
* limitations under the License.
*/
-export { plugin } from './plugin';
+export {
+ techdocsPlugin,
+ techdocsPlugin as plugin,
+ TechdocsPage,
+ EntityTechdocsContent,
+} from './plugin';
export { Router, EmbeddedDocsRouter } from './Router';
export * from './reader';
export * from './api';
diff --git a/plugins/techdocs/src/plugin.test.ts b/plugins/techdocs/src/plugin.test.ts
index e750be9ac3..52f072627c 100644
--- a/plugins/techdocs/src/plugin.test.ts
+++ b/plugins/techdocs/src/plugin.test.ts
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-import { plugin } from './plugin';
+import { techdocsPlugin } from './plugin';
describe('techdocs', () => {
it('should export plugin', () => {
- expect(plugin).toBeDefined();
+ expect(techdocsPlugin).toBeDefined();
});
});
diff --git a/plugins/techdocs/src/plugin.ts b/plugins/techdocs/src/plugin.ts
index 982b749f2c..0b4063c237 100644
--- a/plugins/techdocs/src/plugin.ts
+++ b/plugins/techdocs/src/plugin.ts
@@ -35,6 +35,7 @@ import {
createApiFactory,
configApiRef,
discoveryApiRef,
+ createRoutableExtension,
} from '@backstage/core';
import {
techdocsStorageApiRef,
@@ -58,7 +59,7 @@ export const rootCatalogDocsRouteRef = createRouteRef({
title: 'Docs',
});
-export const plugin = createPlugin({
+export const techdocsPlugin = createPlugin({
id: 'techdocs',
apis: [
createApiFactory({
@@ -80,4 +81,22 @@ export const plugin = createPlugin({
}),
}),
],
+ routes: {
+ root: rootRouteRef,
+ entityContent: rootCatalogDocsRouteRef,
+ },
});
+
+export const TechdocsPage = techdocsPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./Router').then(m => m.Router),
+ mountPoint: rootRouteRef,
+ }),
+);
+
+export const EntityTechdocsContent = techdocsPlugin.provide(
+ createRoutableExtension({
+ component: () => import('./Router').then(m => m.EmbeddedDocsRouter),
+ mountPoint: rootCatalogDocsRouteRef,
+ }),
+);