diff --git a/.changeset/fluffy-moles-deny.md b/.changeset/fluffy-moles-deny.md new file mode 100644 index 0000000000..4b4abc36fa --- /dev/null +++ b/.changeset/fluffy-moles-deny.md @@ -0,0 +1,42 @@ +--- +'@backstage/plugin-allure': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-azure-devops': patch +'@backstage/plugin-badges': patch +'@backstage/plugin-bazaar': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-config-schema': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-firehydrant': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-git-release-manager': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-gitops-profiles': patch +'@backstage/plugin-home': patch +'@backstage/plugin-ilert': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-kafka': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-newrelic': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-rollbar': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-search': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-splunk-on-call': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-todo': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-xcmetrics': patch +--- + +Refactor out the deprecated path and icon from RouteRefs diff --git a/.changeset/lucky-ads-shout.md b/.changeset/lucky-ads-shout.md new file mode 100644 index 0000000000..73063bb911 --- /dev/null +++ b/.changeset/lucky-ads-shout.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-plugin-api': patch +--- + +Add deprecation warnings around `title` `icon` and `path` as they are no longer controlled when creating `routeRefs` diff --git a/packages/core-plugin-api/src/routing/RouteRef.ts b/packages/core-plugin-api/src/routing/RouteRef.ts index a926b775e6..26e63c8f3a 100644 --- a/packages/core-plugin-api/src/routing/RouteRef.ts +++ b/packages/core-plugin-api/src/routing/RouteRef.ts @@ -23,7 +23,6 @@ import { } from './types'; import { OldIconComponent } from '../icons/types'; -// TODO(Rugvip): Remove this in the next breaking release, it's exported but unused /** * @deprecated * @internal @@ -49,21 +48,45 @@ export class RouteRefImpl private readonly id: string, readonly params: ParamKeys, private readonly config: { + /** @deprecated */ path?: string; + /** @deprecated */ icon?: OldIconComponent; + /** @deprecated */ title?: string; }, - ) {} + ) { + if (config.path) { + // eslint-disable-next-line no-console + console.warn( + `[core-plugin-api] - routeRefs no longer decide their own path, please remove the path for ${this.toString()}. This will be removed in upcoming versions.`, + ); + } + + if (config.icon) { + // eslint-disable-next-line no-console + console.warn( + `[core-plugin-api] - routeRefs no longer decide their own icon, please remove the icon for ${this.toString()}. This will be removed in upcoming versions.`, + ); + } + + if (config.title) { + // eslint-disable-next-line no-console + console.warn( + `[core-plugin-api] - routeRefs no longer decide their own title, please remove the title for ${this.toString()}. This will be removed in upcoming versions.`, + ); + } + } + + /** @deprecated use `useRouteRef` instead */ + get path() { + return this.config.path ?? ''; + } get icon() { return this.config.icon; } - // TODO(Rugvip): Remove this, routes are looked up via the registry instead - get path() { - return this.config.path ?? ''; - } - get title() { return this.config.title ?? this.id; } diff --git a/plugins/allure/src/plugin.ts b/plugins/allure/src/plugin.ts index f5ca7beeb3..a2eaa06a38 100644 --- a/plugins/allure/src/plugin.ts +++ b/plugins/allure/src/plugin.ts @@ -23,7 +23,7 @@ import { import { AllureApiClient, allureApiRef } from './api'; export const allureRouteRef = createRouteRef({ - title: 'allure-report', + id: 'allure', }); export const allurePlugin = createPlugin({ diff --git a/plugins/api-docs/src/routes.ts b/plugins/api-docs/src/routes.ts index ab976dbf18..b7c152889e 100644 --- a/plugins/api-docs/src/routes.ts +++ b/plugins/api-docs/src/routes.ts @@ -19,12 +19,8 @@ import { createRouteRef, } from '@backstage/core-plugin-api'; -const NoIcon = () => null; - export const rootRoute = createRouteRef({ - icon: NoIcon, - path: '/api-docs', - title: 'APIs', + id: 'api-docs', }); export const createComponentRouteRef = createExternalRouteRef({ diff --git a/plugins/badges/src/api/BadgesClient.ts b/plugins/badges/src/api/BadgesClient.ts index d81b042ce5..432a485a6b 100644 --- a/plugins/badges/src/api/BadgesClient.ts +++ b/plugins/badges/src/api/BadgesClient.ts @@ -17,7 +17,6 @@ import { generatePath } from 'react-router'; import { ResponseError } from '@backstage/errors'; import { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; -import { entityRoute } from '@backstage/plugin-catalog-react'; import { BadgesApi, BadgeSpec } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; @@ -53,7 +52,7 @@ export class BadgesClient implements BadgesApi { private async getEntityBadgeSpecsUrl(entity: Entity): Promise { const routeParams = this.getEntityRouteParams(entity); - const path = generatePath(entityRoute.path, routeParams); + const path = generatePath(`:kind/:namespace/:name`, routeParams); return `${await this.discoveryApi.getBaseUrl( 'badges', )}/entity/${path}/badge-specs`; diff --git a/plugins/bazaar/src/routes.ts b/plugins/bazaar/src/routes.ts index a3cc88d86f..9e4a8fb218 100644 --- a/plugins/bazaar/src/routes.ts +++ b/plugins/bazaar/src/routes.ts @@ -17,5 +17,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'bazaar', + id: 'bazaar', }); diff --git a/plugins/catalog-graph/src/routes.ts b/plugins/catalog-graph/src/routes.ts index 9f8372c7a5..3bca6ce411 100644 --- a/plugins/catalog-graph/src/routes.ts +++ b/plugins/catalog-graph/src/routes.ts @@ -24,8 +24,7 @@ import { * @public */ export const catalogGraphRouteRef = createRouteRef({ - path: '/catalog-graph', - title: 'Catalog Graph', + id: 'catalog-graph', }); /** diff --git a/plugins/catalog-import/src/plugin.ts b/plugins/catalog-import/src/plugin.ts index d7493edcca..52c1929dce 100644 --- a/plugins/catalog-import/src/plugin.ts +++ b/plugins/catalog-import/src/plugin.ts @@ -31,8 +31,7 @@ import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { catalogImportApiRef, CatalogImportClient } from './api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'catalog-import', + id: 'catalog-import', }); export const catalogImportPlugin = createPlugin({ diff --git a/plugins/catalog-react/src/routes.ts b/plugins/catalog-react/src/routes.ts index 42f394ef61..f29d52f08a 100644 --- a/plugins/catalog-react/src/routes.ts +++ b/plugins/catalog-react/src/routes.ts @@ -17,22 +17,18 @@ import { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; import { createRouteRef } from '@backstage/core-plugin-api'; -const NoIcon = () => null; - // TODO(Rugvip): Move these route refs back to the catalog plugin once we're all ported to using external routes export const rootRoute = createRouteRef({ - icon: NoIcon, - path: '', - title: 'Catalog', + id: 'catalog', }); + export const catalogRouteRef = rootRoute; export const entityRoute = createRouteRef({ - icon: NoIcon, - path: ':namespace/:kind/:name/*', - title: 'Entity', + id: 'catalog:entity', params: ['namespace', 'kind', 'name'], }); + export const entityRouteRef = entityRoute; // Utility function to get suitable route params for entityRoute, given an diff --git a/plugins/catalog/src/components/Router.tsx b/plugins/catalog/src/components/Router.tsx index 9116c0b551..2a0eacf074 100644 --- a/plugins/catalog/src/components/Router.tsx +++ b/plugins/catalog/src/components/Router.tsx @@ -16,8 +16,6 @@ import { ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model'; import { AsyncEntityProvider, - entityRoute, - rootRoute, useEntity, useEntityFromUrl, } from '@backstage/plugin-catalog-react'; @@ -87,9 +85,9 @@ export const Router = ({ EntityPage?: ComponentType; }) => ( - } /> + } /> diff --git a/plugins/circleci/api-report.md b/plugins/circleci/api-report.md index 25d4af0923..bb4334c0f9 100644 --- a/plugins/circleci/api-report.md +++ b/plugins/circleci/api-report.md @@ -16,7 +16,9 @@ import { DiscoveryApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { GitType } from 'circleci-api'; import { Me } from 'circleci-api'; +import { PathParams } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; +import { SubRouteRef } from '@backstage/core-plugin-api'; export { BuildStepAction }; @@ -68,7 +70,7 @@ export const circleCIApiRef: ApiRef; // Warning: (ae-missing-release-tag) "circleCIBuildRouteRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const circleCIBuildRouteRef: RouteRef; +export const circleCIBuildRouteRef: SubRouteRef>; // Warning: (ae-missing-release-tag) "circleCIPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/circleci/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/circleci/src/components/BuildsPage/lib/CITable/CITable.tsx index b33e1b40cc..510fd20dac 100644 --- a/plugins/circleci/src/components/BuildsPage/lib/CITable/CITable.tsx +++ b/plugins/circleci/src/components/BuildsPage/lib/CITable/CITable.tsx @@ -26,7 +26,7 @@ import { import RetryIcon from '@material-ui/icons/Replay'; import GitHubIcon from '@material-ui/icons/GitHub'; import LaunchIcon from '@material-ui/icons/Launch'; -import { Link as RouterLink, generatePath } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; import { durationHumanized, relativeTimeTo } from '../../../../util'; import { circleCIBuildRouteRef } from '../../../../route-refs'; import { @@ -38,6 +38,7 @@ import { Table, TableColumn, } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; export type CITableBuildInfo = { id: string; @@ -144,16 +145,21 @@ const generatedColumns: TableColumn[] = [ field: 'buildName', highlight: true, width: '20%', - render: (row: Partial) => ( - - {row.buildName ? row.buildName : row?.workflow?.name} - - ), + render: (row: Partial) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const routeLink = useRouteRef(circleCIBuildRouteRef); + + return ( + + {row.buildName ? row.buildName : row?.workflow?.name} + + ); + }, }, { title: 'Job', diff --git a/plugins/circleci/src/components/Router.tsx b/plugins/circleci/src/components/Router.tsx index 1bc13d6327..5aa8dd9df9 100644 --- a/plugins/circleci/src/components/Router.tsx +++ b/plugins/circleci/src/components/Router.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { Routes, Route } from 'react-router'; -import { circleCIRouteRef, circleCIBuildRouteRef } from '../route-refs'; +import { circleCIBuildRouteRef } from '../route-refs'; import { BuildWithStepsPage } from './BuildWithStepsPage/'; import { BuildsPage } from './BuildsPage'; import { CIRCLECI_ANNOTATION } from '../constants'; @@ -41,9 +41,9 @@ export const Router = (_props: Props) => { return ( - } /> + } /> } /> diff --git a/plugins/circleci/src/route-refs.tsx b/plugins/circleci/src/route-refs.tsx index 197fab4a7b..e8579b9f0d 100644 --- a/plugins/circleci/src/route-refs.tsx +++ b/plugins/circleci/src/route-refs.tsx @@ -14,30 +14,14 @@ * limitations under the License. */ -import React from 'react'; -import { SvgIcon, SvgIconProps } from '@material-ui/core'; -import { createRouteRef } from '@backstage/core-plugin-api'; - -const CircleCIIcon = (props: SvgIconProps) => ( - - - -); +import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; export const circleCIRouteRef = createRouteRef({ - icon: CircleCIIcon, - path: '', - title: 'CircleCI | All builds', + id: 'circle-ci', }); -export const circleCIBuildRouteRef = createRouteRef({ - path: ':buildId', - title: 'CircleCI | Build info', +export const circleCIBuildRouteRef = createSubRouteRef({ + id: 'circle-ci/build', + parent: circleCIRouteRef, + path: '/:buildId', }); diff --git a/plugins/cloudbuild/src/components/Router.tsx b/plugins/cloudbuild/src/components/Router.tsx index f9b9a8974f..bdeae7e8fd 100644 --- a/plugins/cloudbuild/src/components/Router.tsx +++ b/plugins/cloudbuild/src/components/Router.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Routes, Route } from 'react-router'; -import { rootRouteRef, buildRouteRef } from '../routes'; +import { buildRouteRef } from '../routes'; import { WorkflowRunDetails } from './WorkflowRunDetails'; import { WorkflowRunsTable } from './WorkflowRunsTable'; import { CLOUDBUILD_ANNOTATION } from './useProjectName'; @@ -40,15 +40,11 @@ export const Router = (_props: Props) => { } return ( + } /> } - /> - } /> - ) ); }; diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx index ac28c5bedf..0152f9d964 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.test.tsx @@ -18,6 +18,7 @@ import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; import { WorkflowRunsTableView } from './WorkflowRunsTable'; import { WorkflowRun } from '../useWorkflowRuns'; +import { rootRouteRef } from '../../routes'; describe('', () => { let runs: WorkflowRun[] = []; @@ -56,6 +57,7 @@ describe('', () => { runs={runs} total={runs.length} />, + { mountedRoutes: { '/': rootRouteRef } }, ); expect(getByTestId('cell-source')).toHaveAttribute('href', '/run_id_1'); @@ -74,6 +76,7 @@ describe('', () => { runs={runs} total={runs.length} />, + { mountedRoutes: { '/': rootRouteRef } }, ); expect(getByTestId('cell-created')).toHaveTextContent( @@ -94,6 +97,7 @@ describe('', () => { runs={runs} total={runs.length} />, + { mountedRoutes: { '/': rootRouteRef } }, ); const rerunActionElement = getByTestId('action-rerun'); diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 0d00347183..aefa140349 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { Link, Typography, Box, IconButton, Tooltip } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; import GoogleIcon from '@material-ui/icons/CloudCircle'; -import { Link as RouterLink, generatePath } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import SyncIcon from '@material-ui/icons/Sync'; @@ -26,6 +26,7 @@ import { Entity } from '@backstage/catalog-model'; import { buildRouteRef } from '../../routes'; import { DateTime } from 'luxon'; import { Table, TableColumn } from '@backstage/core-components'; +import { useRouteRef } from '@backstage/core-plugin-api'; const generatedColumns: TableColumn[] = [ { @@ -54,15 +55,19 @@ const generatedColumns: TableColumn[] = [ field: 'source', highlight: true, width: '200px', - render: (row: Partial) => ( - - {row.message} - - ), + render: (row: Partial) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const routeLink = useRouteRef(buildRouteRef); + return ( + + {row.message} + + ); + }, }, { title: 'Ref', diff --git a/plugins/cloudbuild/src/routes.ts b/plugins/cloudbuild/src/routes.ts index 5e3525c529..3737e6948f 100644 --- a/plugins/cloudbuild/src/routes.ts +++ b/plugins/cloudbuild/src/routes.ts @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createRouteRef } from '@backstage/core-plugin-api'; +import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'Google Cloudbuild', + id: 'cloudbuild', }); -export const buildRouteRef = createRouteRef({ - path: ':id', - title: 'Cloudbuild Run', +export const buildRouteRef = createSubRouteRef({ + id: 'cloudbuild/run', + path: '/:id', + parent: rootRouteRef, }); diff --git a/plugins/code-coverage/src/routes.ts b/plugins/code-coverage/src/routes.ts index bf600ab92e..0f590a53b8 100644 --- a/plugins/code-coverage/src/routes.ts +++ b/plugins/code-coverage/src/routes.ts @@ -16,5 +16,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'code-coverage', + id: 'code-coverage', }); diff --git a/plugins/config-schema/src/routes.ts b/plugins/config-schema/src/routes.ts index ebbbdd129c..043301bca1 100644 --- a/plugins/config-schema/src/routes.ts +++ b/plugins/config-schema/src/routes.ts @@ -16,5 +16,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'config-schema', + id: 'config-schema', }); diff --git a/plugins/cost-insights/src/plugin.ts b/plugins/cost-insights/src/plugin.ts index cf54dbd957..1714c5fbd5 100644 --- a/plugins/cost-insights/src/plugin.ts +++ b/plugins/cost-insights/src/plugin.ts @@ -21,18 +21,15 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/cost-insights', - title: 'Cost Insights', + id: 'cost-insights', }); export const projectGrowthAlertRef = createRouteRef({ - path: '/cost-insights/investigating-growth', - title: 'Investigating Growth', + id: 'cost-insights:investigating-growth', }); export const unlabeledDataflowAlertRef = createRouteRef({ - path: '/cost-insights/labeling-jobs', - title: 'Labeling Dataflow Jobs', + id: 'cost-insights:labeling-jobs', }); export const costInsightsPlugin = createPlugin({ diff --git a/plugins/explore/src/routes.ts b/plugins/explore/src/routes.ts index 783d334749..d3a94ea4cd 100644 --- a/plugins/explore/src/routes.ts +++ b/plugins/explore/src/routes.ts @@ -19,11 +19,8 @@ import { createRouteRef, } from '@backstage/core-plugin-api'; -const NoIcon = () => null; - export const exploreRouteRef = createRouteRef({ - icon: NoIcon, - title: 'Explore', + id: 'explore', }); export const catalogEntityRouteRef = createExternalRouteRef({ diff --git a/plugins/firehydrant/src/routes.ts b/plugins/firehydrant/src/routes.ts index eb2f8b6375..e1e3831f95 100644 --- a/plugins/firehydrant/src/routes.ts +++ b/plugins/firehydrant/src/routes.ts @@ -16,5 +16,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'firehydrant', + id: 'firehydrant', }); diff --git a/plugins/gcp-projects/src/routes.ts b/plugins/gcp-projects/src/routes.ts index 2d302a178d..f527393f5a 100644 --- a/plugins/gcp-projects/src/routes.ts +++ b/plugins/gcp-projects/src/routes.ts @@ -17,14 +17,11 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/gcp-projects', - title: 'GCP Projects', + id: 'gcp-projects', }); export const projectRouteRef = createRouteRef({ - path: '/gcp-projects/project', - title: 'GCP Project Page', + id: 'gcp-projects:project', }); export const newProjectRouteRef = createRouteRef({ - path: '/gcp-projects/new', - title: 'GCP Project Page', + id: 'gcp-projects:new', }); diff --git a/plugins/git-release-manager/src/routes.ts b/plugins/git-release-manager/src/routes.ts index 01e4cdf7ff..c4b157892a 100644 --- a/plugins/git-release-manager/src/routes.ts +++ b/plugins/git-release-manager/src/routes.ts @@ -17,5 +17,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'git-release-manager', + id: 'git-release-manager', }); diff --git a/plugins/github-actions/src/components/Router.tsx b/plugins/github-actions/src/components/Router.tsx index cbf29d1d9d..ea07213c45 100644 --- a/plugins/github-actions/src/components/Router.tsx +++ b/plugins/github-actions/src/components/Router.tsx @@ -17,7 +17,7 @@ import React from 'react'; import { Entity } from '@backstage/catalog-model'; import { useEntity } from '@backstage/plugin-catalog-react'; import { Routes, Route } from 'react-router'; -import { rootRouteRef, buildRouteRef } from '../routes'; +import { buildRouteRef } from '../routes'; import { WorkflowRunDetails } from './WorkflowRunDetails'; import { WorkflowRunsTable } from './WorkflowRunsTable'; import { GITHUB_ACTIONS_ANNOTATION } from './useProjectName'; @@ -41,12 +41,9 @@ export const Router = (_props: Props) => { } return ( + } /> } - /> - } /> ) diff --git a/plugins/github-actions/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/github-actions/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index 51f26bf5d7..d80ecc5d52 100644 --- a/plugins/github-actions/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/github-actions/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -24,7 +24,7 @@ import { } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; import GitHubIcon from '@material-ui/icons/GitHub'; -import { Link as RouterLink, generatePath } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; import SyncIcon from '@material-ui/icons/Sync'; @@ -34,7 +34,7 @@ import { Entity } from '@backstage/catalog-model'; import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { EmptyState, Table, TableColumn } from '@backstage/core-components'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; +import { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; const generatedColumns: TableColumn[] = [ { @@ -47,14 +47,15 @@ const generatedColumns: TableColumn[] = [ title: 'Message', field: 'message', highlight: true, - render: (row: Partial) => ( - - {row.message} - - ), + render: (row: Partial) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const routeLink = useRouteRef(buildRouteRef); + return ( + + {row.message} + + ); + }, }, { title: 'Source', diff --git a/plugins/github-actions/src/routes.ts b/plugins/github-actions/src/routes.ts index 6e1d8a885a..8e854fad45 100644 --- a/plugins/github-actions/src/routes.ts +++ b/plugins/github-actions/src/routes.ts @@ -14,15 +14,14 @@ * limitations under the License. */ -import { createRouteRef } from '@backstage/core-plugin-api'; +import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'GitHub Actions', + id: 'github-actions', }); -export const buildRouteRef = createRouteRef({ - path: ':id', - params: ['id'], - title: 'GitHub Actions Workflow Run', +export const buildRouteRef = createSubRouteRef({ + id: 'github-actions/build', + path: '/:id', + parent: rootRouteRef, }); diff --git a/plugins/gitops-profiles/src/routes.ts b/plugins/gitops-profiles/src/routes.ts index d57edcca2c..b79e5686d2 100644 --- a/plugins/gitops-profiles/src/routes.ts +++ b/plugins/gitops-profiles/src/routes.ts @@ -16,23 +16,15 @@ import { createRouteRef } from '@backstage/core-plugin-api'; -const NoIcon = () => null; - export const gitOpsClusterListRoute = createRouteRef({ - icon: NoIcon, - path: '/gitops-clusters', - title: 'GitOps Clusters', + id: 'gitops-clusters', }); export const gitOpsClusterDetailsRoute = createRouteRef({ - icon: NoIcon, - path: '/gitops-cluster/:owner/:repo', - title: 'GitOps Cluster details', + id: 'gitops-cluster:details', params: ['owner', 'repo'], }); export const gitOpsClusterCreateRoute = createRouteRef({ - icon: NoIcon, - path: '/gitops-cluster-create', - title: 'GitOps Cluster create', + id: 'gitops-cluster:create', }); diff --git a/plugins/home/src/routes.ts b/plugins/home/src/routes.ts index 2c641d8433..7b6b47215b 100644 --- a/plugins/home/src/routes.ts +++ b/plugins/home/src/routes.ts @@ -16,5 +16,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'home', + id: 'home', }); diff --git a/plugins/ilert/src/route-refs.tsx b/plugins/ilert/src/route-refs.tsx index 97d11df98a..8a3d53001d 100644 --- a/plugins/ilert/src/route-refs.tsx +++ b/plugins/ilert/src/route-refs.tsx @@ -14,11 +14,8 @@ * limitations under the License. */ -import ILertIcon from './assets/ilert.icon.svg'; import { createRouteRef } from '@backstage/core-plugin-api'; export const iLertRouteRef = createRouteRef({ - icon: ILertIcon, - path: '/ilert', - title: 'iLert', + id: 'ilert', }); diff --git a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx index ee17df8533..7a7b77f5dc 100644 --- a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx +++ b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx @@ -17,12 +17,13 @@ import React from 'react'; import { Box, IconButton, Link, Typography, Tooltip } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; import JenkinsLogo from '../../../../assets/JenkinsLogo.svg'; -import { generatePath, Link as RouterLink } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; import { JenkinsRunStatus } from '../Status'; import { useBuilds } from '../../../useBuilds'; import { buildRouteRef } from '../../../../plugin'; import { Table, TableColumn } from '@backstage/core-components'; import { Project } from '../../../../api/JenkinsApi'; +import { useRouteRef } from '@backstage/core-plugin-api'; const FailCount = ({ count }: { count: number }): JSX.Element | null => { if (count !== 0) { @@ -91,6 +92,8 @@ const generatedColumns: TableColumn[] = [ field: 'fullName', highlight: true, render: (row: Partial) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const routeLink = useRouteRef(buildRouteRef); if (!row.fullName || !row.lastBuild?.number) { return ( <> @@ -105,7 +108,7 @@ const generatedColumns: TableColumn[] = [ return ( { return ( - } /> + } /> } /> ); diff --git a/plugins/jenkins/src/plugin.ts b/plugins/jenkins/src/plugin.ts index d445a8cfb1..c32c9b50d1 100644 --- a/plugins/jenkins/src/plugin.ts +++ b/plugins/jenkins/src/plugin.ts @@ -20,20 +20,20 @@ import { createPlugin, createRoutableExtension, createRouteRef, + createSubRouteRef, discoveryApiRef, identityApiRef, } from '@backstage/core-plugin-api'; import { JenkinsClient, jenkinsApiRef } from './api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'Jenkins', + id: 'jenkins', }); -export const buildRouteRef = createRouteRef({ - path: 'build/:jobFullName/:buildNumber', - params: ['jobFullName', 'buildNumber'], - title: 'Jenkins build', +export const buildRouteRef = createSubRouteRef({ + id: 'jenkins/builds', + path: '/builds/:jobFullName/:buildNumber', + parent: rootRouteRef, }); export const jenkinsPlugin = createPlugin({ diff --git a/plugins/kafka/src/Router.tsx b/plugins/kafka/src/Router.tsx index 977c71712e..c63019253b 100644 --- a/plugins/kafka/src/Router.tsx +++ b/plugins/kafka/src/Router.tsx @@ -18,7 +18,6 @@ import { Entity } from '@backstage/catalog-model'; import React from 'react'; import { Route, Routes } from 'react-router'; import { useEntity } from '@backstage/plugin-catalog-react'; -import { rootCatalogKafkaRouteRef } from './plugin'; import { KAFKA_CONSUMER_GROUP_ANNOTATION } from './constants'; import { KafkaTopicsForConsumer } from './components/ConsumerGroupOffsets/ConsumerGroupOffsets'; import { MissingAnnotationEmptyState } from '@backstage/core-components'; @@ -44,10 +43,7 @@ export const Router = (_props: Props) => { return ( - } - /> + } /> ); }; diff --git a/plugins/kafka/src/plugin.ts b/plugins/kafka/src/plugin.ts index 539b0a0fda..0c345cdabc 100644 --- a/plugins/kafka/src/plugin.ts +++ b/plugins/kafka/src/plugin.ts @@ -25,8 +25,7 @@ import { } from '@backstage/core-plugin-api'; export const rootCatalogKafkaRouteRef = createRouteRef({ - path: '*', - title: 'Kafka', + id: 'kafka', }); export const kafkaPlugin = createPlugin({ diff --git a/plugins/kubernetes/src/Router.tsx b/plugins/kubernetes/src/Router.tsx index f98d3ca45e..873bf128e4 100644 --- a/plugins/kubernetes/src/Router.tsx +++ b/plugins/kubernetes/src/Router.tsx @@ -18,7 +18,6 @@ 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 { rootCatalogKubernetesRouteRef } from './plugin'; import { KubernetesContent } from './components/KubernetesContent'; import { Button } from '@material-ui/core'; import { MissingAnnotationEmptyState } from '@backstage/core-components'; @@ -53,10 +52,7 @@ export const Router = (_props: Props) => { ) { return ( - } - /> + } /> ); } diff --git a/plugins/kubernetes/src/plugin.ts b/plugins/kubernetes/src/plugin.ts index 3f2d8c6a87..a1f2f57621 100644 --- a/plugins/kubernetes/src/plugin.ts +++ b/plugins/kubernetes/src/plugin.ts @@ -28,8 +28,7 @@ import { } from '@backstage/core-plugin-api'; export const rootCatalogKubernetesRouteRef = createRouteRef({ - path: '*', - title: 'Kubernetes', + id: 'kubernetes', }); export const kubernetesPlugin = createPlugin({ diff --git a/plugins/lighthouse/src/plugin.ts b/plugins/lighthouse/src/plugin.ts index 25cbeb3f31..1c9bc295f8 100644 --- a/plugins/lighthouse/src/plugin.ts +++ b/plugins/lighthouse/src/plugin.ts @@ -25,22 +25,19 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'Lighthouse', + id: 'lighthouse', }); export const viewAuditRouteRef = createRouteRef({ - path: 'audit/:id', - title: 'View Lighthouse Audit', + id: 'lighthouse:audit', }); export const createAuditRouteRef = createRouteRef({ - path: 'create-audit', - title: 'Create Lighthouse Audit', + id: 'lighthouse:create-audit', }); export const entityContentRouteRef = createRouteRef({ - title: 'Lighthouse Entity Content', + id: 'lighthouse:entity-content', }); export const lighthousePlugin = createPlugin({ diff --git a/plugins/newrelic/src/plugin.ts b/plugins/newrelic/src/plugin.ts index cb2505e36e..6cf77a785f 100644 --- a/plugins/newrelic/src/plugin.ts +++ b/plugins/newrelic/src/plugin.ts @@ -24,8 +24,7 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/newrelic', - title: 'newrelic', + id: 'newrelic', }); export const newRelicPlugin = createPlugin({ diff --git a/plugins/pagerduty/src/plugin.ts b/plugins/pagerduty/src/plugin.ts index fb1e573f0c..d1c4e6d35b 100644 --- a/plugins/pagerduty/src/plugin.ts +++ b/plugins/pagerduty/src/plugin.ts @@ -24,8 +24,7 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/pagerduty', - title: 'pagerduty', + id: 'pagerduty', }); export const pagerDutyPlugin = createPlugin({ diff --git a/plugins/rollbar/src/components/Router.tsx b/plugins/rollbar/src/components/Router.tsx index 845da22a20..032bf0166e 100644 --- a/plugins/rollbar/src/components/Router.tsx +++ b/plugins/rollbar/src/components/Router.tsx @@ -19,7 +19,6 @@ import { useEntity } from '@backstage/plugin-catalog-react'; import React from 'react'; import { Route, Routes } from 'react-router'; import { ROLLBAR_ANNOTATION } from '../constants'; -import { rootRouteRef } from '../plugin'; import { EntityPageRollbar } from './EntityPageRollbar/EntityPageRollbar'; import { MissingAnnotationEmptyState } from '@backstage/core-components'; @@ -40,10 +39,7 @@ export const Router = (_props: Props) => { return ( - } - /> + } /> ); }; diff --git a/plugins/rollbar/src/plugin.ts b/plugins/rollbar/src/plugin.ts index b0de6510f3..3ca456058f 100644 --- a/plugins/rollbar/src/plugin.ts +++ b/plugins/rollbar/src/plugin.ts @@ -26,8 +26,7 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '', - title: 'Rollbar', + id: 'rollbar', }); export const rollbarPlugin = createPlugin({ diff --git a/plugins/scaffolder/src/routes.ts b/plugins/scaffolder/src/routes.ts index 9b4861fc1e..df5868c9ea 100644 --- a/plugins/scaffolder/src/routes.ts +++ b/plugins/scaffolder/src/routes.ts @@ -24,5 +24,5 @@ export const registerComponentRouteRef = createExternalRouteRef({ }); export const rootRouteRef = createRouteRef({ - title: 'Create new entity', + id: 'scaffolder', }); diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts index b8c016fb36..9dda2a84bb 100644 --- a/plugins/search/src/plugin.ts +++ b/plugins/search/src/plugin.ts @@ -26,13 +26,11 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/search', - title: 'search', + id: 'search', }); export const rootNextRouteRef = createRouteRef({ - path: '/search-next', - title: 'search', + id: 'search:next', }); export const searchPlugin = createPlugin({ diff --git a/plugins/sentry/src/plugin.ts b/plugins/sentry/src/plugin.ts index 454c1f02a6..981745c8fe 100644 --- a/plugins/sentry/src/plugin.ts +++ b/plugins/sentry/src/plugin.ts @@ -25,8 +25,7 @@ import { } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - path: '/sentry', - title: 'Sentry', + id: 'sentry', }); export const sentryPlugin = createPlugin({ diff --git a/plugins/splunk-on-call/src/plugin.ts b/plugins/splunk-on-call/src/plugin.ts index 0b54538f06..2256b382ee 100644 --- a/plugins/splunk-on-call/src/plugin.ts +++ b/plugins/splunk-on-call/src/plugin.ts @@ -24,9 +24,7 @@ import { createComponentExtension, } from '@backstage/core-plugin-api'; -export const rootRouteRef = createRouteRef({ - title: 'splunk-on-call', -}); +export const rootRouteRef = createRouteRef({ id: 'splunk-on-call' }); export const splunkOnCallPlugin = createPlugin({ id: 'splunk-on-call', diff --git a/plugins/tech-radar/src/plugin.ts b/plugins/tech-radar/src/plugin.ts index bd30d6a984..495aa47879 100644 --- a/plugins/tech-radar/src/plugin.ts +++ b/plugins/tech-radar/src/plugin.ts @@ -25,7 +25,7 @@ import { } from '@backstage/core-plugin-api'; const rootRouteRef = createRouteRef({ - title: 'Tech Radar', + id: 'tech-radar', }); /** diff --git a/plugins/techdocs/src/routes.ts b/plugins/techdocs/src/routes.ts index e0b7661ffd..e781550899 100644 --- a/plugins/techdocs/src/routes.ts +++ b/plugins/techdocs/src/routes.ts @@ -17,17 +17,14 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - id: 'techdocs-index-page', - title: 'TechDocs Landing Page', + id: 'techdocs:index-page', }); export const rootDocsRouteRef = createRouteRef({ - id: 'techdocs-reader-page', - title: 'Docs', + id: 'techdocs:reader-page', params: ['namespace', 'kind', 'name'], }); export const rootCatalogDocsRouteRef = createRouteRef({ - id: 'catalog-techdocs-reader-view', - title: 'Docs', + id: 'techdocs:catalog-reader-view', }); diff --git a/plugins/todo/src/routes.ts b/plugins/todo/src/routes.ts index 8ab3fb1b94..01d8d9f354 100644 --- a/plugins/todo/src/routes.ts +++ b/plugins/todo/src/routes.ts @@ -16,5 +16,5 @@ import { createRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'todo', + id: 'todo', }); diff --git a/plugins/user-settings/src/components/Settings.tsx b/plugins/user-settings/src/components/Settings.tsx index 43a00ee9cc..e9b3ae7d0a 100644 --- a/plugins/user-settings/src/components/Settings.tsx +++ b/plugins/user-settings/src/components/Settings.tsx @@ -18,14 +18,14 @@ import React from 'react'; import SettingsIcon from '@material-ui/icons/Settings'; import { settingsRouteRef } from '../plugin'; import { SidebarItem } from '@backstage/core-components'; -import { IconComponent } from '@backstage/core-plugin-api'; +import { useRouteRef, IconComponent } from '@backstage/core-plugin-api'; type SettingsProps = { icon?: IconComponent; }; export const Settings = (props: SettingsProps) => { + const routePath = useRouteRef(settingsRouteRef); const Icon = props.icon ? props.icon : SettingsIcon; - - return ; + return ; }; diff --git a/plugins/user-settings/src/plugin.ts b/plugins/user-settings/src/plugin.ts index 54f6faceed..01793dc418 100644 --- a/plugins/user-settings/src/plugin.ts +++ b/plugins/user-settings/src/plugin.ts @@ -21,8 +21,7 @@ import { } from '@backstage/core-plugin-api'; export const settingsRouteRef = createRouteRef({ - path: '/settings', - title: 'Settings', + id: 'user-settings', }); export const userSettingsPlugin = createPlugin({ diff --git a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx index 53545890a4..a21918e322 100644 --- a/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx +++ b/plugins/xcmetrics/src/components/XcmetricsLayout/XcmetricsLayout.tsx @@ -22,24 +22,23 @@ import { TabbedLayout, } from '@backstage/core-components'; import { Overview } from '../Overview'; -import { buildsRouteRef, rootRouteRef } from '../../routes'; -import { RouteRef, SubRouteRef } from '@backstage/core-plugin-api'; +import { buildsRouteRef } from '../../routes'; import { BuildsPage } from '../BuildsPage'; export interface TabConfig { - routeRef: RouteRef | SubRouteRef; + path: string; title: string; component: ReactChild; } const TABS: TabConfig[] = [ { - routeRef: rootRouteRef, + path: '/', title: 'Overview', component: , }, { - routeRef: buildsRouteRef, + path: buildsRouteRef.path, title: 'Builds', component: , }, @@ -53,11 +52,7 @@ export const XcmetricsLayout = () => ( {TABS.map(tab => ( - + {tab.component} ))} diff --git a/plugins/xcmetrics/src/routes.ts b/plugins/xcmetrics/src/routes.ts index 212ecbae48..81934c860f 100644 --- a/plugins/xcmetrics/src/routes.ts +++ b/plugins/xcmetrics/src/routes.ts @@ -16,7 +16,7 @@ import { createRouteRef, createSubRouteRef } from '@backstage/core-plugin-api'; export const rootRouteRef = createRouteRef({ - title: 'XCMetrics', + id: 'xcmetrics', }); export const buildsRouteRef = createSubRouteRef({