diff --git a/workspaces/argocd/plugins/argocd-backend/src/router.test.ts b/workspaces/argocd/plugins/argocd-backend/src/router.test.ts index a83a08dbd46..9a7222da236 100644 --- a/workspaces/argocd/plugins/argocd-backend/src/router.test.ts +++ b/workspaces/argocd/plugins/argocd-backend/src/router.test.ts @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { ArgoCDService } from '@backstage-community/plugin-argocd-node'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import express from 'express'; import request from 'supertest'; -import { createRouter } from './router'; -import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { mockApplications, mockConfig } from './__data__/mockdata'; -import { ArgoCDService } from '@backstage-community/plugin-argocd-node'; +import { createRouter } from './router'; jest.mock('@backstage-community/plugin-argocd-node'); diff --git a/workspaces/argocd/plugins/argocd/README.md b/workspaces/argocd/plugins/argocd/README.md index d38728a6d34..5017243de39 100644 --- a/workspaces/argocd/plugins/argocd/README.md +++ b/workspaces/argocd/plugins/argocd/README.md @@ -136,8 +136,8 @@ yarn workspace app add @backstage-community/plugin-argocd ```ts // packages/app/src/components/catalog/EntityPage.tsx import { - ArgocdDeploymentSummary, ArgocdDeploymentLifecycle, + ArgocdDeploymentSummary, isArgocdConfigured, } from '@backstage-community/plugin-argocd'; diff --git a/workspaces/playlist/plugins/playlist/src/alpha.tsx b/workspaces/playlist/plugins/playlist/src/alpha.tsx index 2b35d08a9a3..1cbadb8b434 100644 --- a/workspaces/playlist/plugins/playlist/src/alpha.tsx +++ b/workspaces/playlist/plugins/playlist/src/alpha.tsx @@ -17,17 +17,16 @@ import { ApiBlueprint, createFrontendPlugin, + dialogApiRef, discoveryApiRef, fetchApiRef, PageBlueprint, - dialogApiRef, useApi, } from '@backstage/frontend-plugin-api'; import { useAsyncEntity } from '@backstage/plugin-catalog-react'; import { EntityContextMenuItemBlueprint } from '@backstage/plugin-catalog-react/alpha'; -import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; import PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'; - +import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; import { playlistApiRef, PlaylistClient } from './api'; import { EntityPlaylistDialog } from './components/EntityPlaylistDialog'; import { useTitle } from './hooks'; diff --git a/workspaces/playlist/plugins/playlist/src/api/PlaylistApi.ts b/workspaces/playlist/plugins/playlist/src/api/PlaylistApi.ts index 68b370aa3c3..baa1fb347eb 100644 --- a/workspaces/playlist/plugins/playlist/src/api/PlaylistApi.ts +++ b/workspaces/playlist/plugins/playlist/src/api/PlaylistApi.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { createApiRef } from '@backstage/frontend-plugin-api'; import { Playlist, PlaylistMetadata, } from '@backstage-community/plugin-playlist-common'; +import { Entity } from '@backstage/catalog-model'; +import { createApiRef } from '@backstage/frontend-plugin-api'; /** * @public diff --git a/workspaces/playlist/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx b/workspaces/playlist/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx index 3ef22f65bac..61f83a80c99 100644 --- a/workspaces/playlist/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx +++ b/workspaces/playlist/plugins/playlist/src/components/EntityPlaylistDialog/EntityPlaylistDialog.tsx @@ -14,6 +14,11 @@ * limitations under the License. */ +import { + permissions, + Playlist, + PlaylistMetadata, +} from '@backstage-community/plugin-playlist-common'; import { Entity, parseEntityRef, @@ -22,15 +27,10 @@ import { import { ResponseErrorPanel } from '@backstage/core-components'; import { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; import { - useAsyncEntity, EntityDisplayName, + useAsyncEntity, } from '@backstage/plugin-catalog-react'; import { usePermission } from '@backstage/plugin-permission-react'; -import { - permissions, - Playlist, - PlaylistMetadata, -} from '@backstage-community/plugin-playlist-common'; import Button from '@material-ui/core/Button'; import Dialog from '@material-ui/core/Dialog'; import DialogActions from '@material-ui/core/DialogActions'; @@ -43,16 +43,15 @@ import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; +import { makeStyles } from '@material-ui/core/styles'; import TextField from '@material-ui/core/TextField'; import Typography from '@material-ui/core/Typography'; -import { makeStyles } from '@material-ui/core/styles'; import ClearButton from '@material-ui/icons/Clear'; import PlaylistAddIcon from '@material-ui/icons/PlaylistAdd'; import SearchIcon from '@material-ui/icons/Search'; import { Fragment, useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import useAsyncFn from 'react-use/esm/useAsyncFn'; - import { playlistApiRef } from '../../api'; import { useTitle } from '../../hooks'; import { playlistRouteRef } from '../../routes'; diff --git a/workspaces/playlist/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx b/workspaces/playlist/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx index 82bf009f982..012551fd834 100644 --- a/workspaces/playlist/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx +++ b/workspaces/playlist/plugins/playlist/src/components/PlaylistIndexPage/DefaultPlaylistIndexPage.tsx @@ -15,22 +15,21 @@ */ import { - PageWithHeader, Content, ContentHeader, + PageWithHeader, SupportButton, } from '@backstage/core-components'; -import { Header } from '@backstage/ui'; import { CatalogFilterLayout } from '@backstage/plugin-catalog-react'; - +import { Header } from '@backstage/ui'; +import { PlaylistListProvider } from '../../hooks/PlaylistListProvider'; +import { useTitle } from '../../hooks/useTitle'; import { CreatePlaylistButton } from '../CreatePlaylistButton'; import { PersonalListPicker } from '../PersonalListPicker'; import { PlaylistList } from '../PlaylistList'; import { PlaylistOwnerPicker } from '../PlaylistOwnerPicker'; import { PlaylistSearchBar } from '../PlaylistSearchBar'; import { PlaylistSortPicker } from '../PlaylistSortPicker'; -import { PlaylistListProvider } from '../../hooks/PlaylistListProvider'; -import { useTitle } from '../../hooks/useTitle'; const DefaultPlaylistIndexPageContent = () => ( diff --git a/workspaces/playlist/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx b/workspaces/playlist/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx index 98b2fca413d..aff4f6e87eb 100644 --- a/workspaces/playlist/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx +++ b/workspaces/playlist/plugins/playlist/src/components/PlaylistPage/PlaylistPage.tsx @@ -14,23 +14,22 @@ * limitations under the License. */ +import { permissions } from '@backstage-community/plugin-playlist-common'; import { Content, ErrorPage, Page } from '@backstage/core-components'; import { errorApiRef, useApi } from '@backstage/core-plugin-api'; import { ResponseError } from '@backstage/errors'; import { usePermission } from '@backstage/plugin-permission-react'; -import { permissions } from '@backstage-community/plugin-playlist-common'; import Button from '@material-ui/core/Button'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; import CardHeader from '@material-ui/core/CardHeader'; import Divider from '@material-ui/core/Divider'; import LinearProgress from '@material-ui/core/LinearProgress'; -import Typography from '@material-ui/core/Typography'; import { makeStyles } from '@material-ui/core/styles'; +import Typography from '@material-ui/core/Typography'; import { useEffect } from 'react'; import { useParams } from 'react-router-dom'; import useAsyncFn from 'react-use/esm/useAsyncFn'; - import { playlistApiRef } from '../../api'; import { PlaylistEntitiesTable } from './PlaylistEntitiesTable'; import { PlaylistHeader } from './PlaylistHeader'; diff --git a/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.test.ts b/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.test.ts index 21d4e939d75..d8cf276b9c0 100644 --- a/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.test.ts +++ b/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.test.ts @@ -13,6 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { resolve } from 'path'; +import type { + RoleBasedPolicy, + RoleMetadata, +} from '@backstage-community/plugin-rbac-common'; import type { LoggerService } from '@backstage/backend-plugin-api'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; import { Config } from '@backstage/config'; @@ -24,7 +29,6 @@ import type { PolicyQuery, PolicyQueryUser, } from '@backstage/plugin-permission-node'; - import { Adapter, Enforcer, @@ -34,14 +38,16 @@ import { } from 'casbin'; import * as Knex from 'knex'; import { MockClient } from 'knex-mock-client'; - -import type { - RoleBasedPolicy, - RoleMetadata, -} from '@backstage-community/plugin-rbac-common'; - -import { resolve } from 'path'; - +import { + clearAuditorMock, + expectAuditorLogForPermission, +} from '../../__fixtures__/auditor-test-utils'; +import { + catalogMock, + mockAuditorService, + mockAuthService, + mockUserInfoService, +} from '../../__fixtures__/mock-utils'; import { ADMIN_ROLE_NAME } from '../admin-permissions/admin-creation'; import { CasbinDBAdapterFactory } from '../database/casbin-adapter-factory'; import { ConditionalStorage } from '../database/conditional-storage'; @@ -49,23 +55,15 @@ import { RoleMetadataDao, RoleMetadataStorage, } from '../database/role-metadata'; +import { + buildDefaultRoleMetadata, + DefaultPermissionsReader, +} from '../default-permissions/default-permissions'; import { BackstageRoleManager } from '../role-manager/role-manager'; -import { DefaultPermissionsReader } from '../default-permissions/default-permissions'; import { EnforcerDelegate } from '../service/enforcer-delegate'; import { MODEL } from '../service/permission-model'; import { PluginPermissionMetadataCollector } from '../service/plugin-endpoints'; import { RBACPermissionPolicy } from './permission-policy'; -import { buildDefaultRoleMetadata } from '../default-permissions/default-permissions'; -import { - catalogMock, - mockAuditorService, - mockAuthService, - mockUserInfoService, -} from '../../__fixtures__/mock-utils'; -import { - clearAuditorMock, - expectAuditorLogForPermission, -} from '../../__fixtures__/auditor-test-utils'; type PermissionAction = 'create' | 'read' | 'update' | 'delete'; diff --git a/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.ts b/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.ts index 7e9c6809526..ef4eaa3aafa 100644 --- a/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.ts +++ b/workspaces/rbac/plugins/rbac-backend/src/policies/permission-policy.ts @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { + NonEmptyArray, + toPermissionAction, +} from '@backstage-community/plugin-rbac-common'; import type { AuditorService, AuditorServiceEvent, @@ -37,14 +41,7 @@ import type { PolicyQuery, PolicyQueryUser, } from '@backstage/plugin-permission-node'; - import type { Knex } from 'knex'; - -import { - NonEmptyArray, - toPermissionAction, -} from '@backstage-community/plugin-rbac-common'; - import { setAdminPermissions, useAdminsFromConfig, diff --git a/workspaces/tech-radar/.changeset/tech-radar-mui-to-bui.md b/workspaces/tech-radar/.changeset/tech-radar-mui-to-bui.md new file mode 100644 index 00000000000..61f92639214 --- /dev/null +++ b/workspaces/tech-radar/.changeset/tech-radar-mui-to-bui.md @@ -0,0 +1,5 @@ +--- +'@backstage-community/plugin-tech-radar': major +--- + +**BREAKING** Migrated the Tech Radar plugin UI from Material UI to Backstage UI (`@backstage/ui`). Search, dialogs, typography, layout, and icons no longer depend on `@material-ui/core`. Adopters need `@backstage/ui` styles available in the app (included by default since Backstage `1.41.0`). diff --git a/workspaces/tech-radar/packages/app-next/package.json b/workspaces/tech-radar/packages/app-next/package.json index 0fc32a32664..03609badadd 100644 --- a/workspaces/tech-radar/packages/app-next/package.json +++ b/workspaces/tech-radar/packages/app-next/package.json @@ -40,6 +40,7 @@ "@backstage/plugin-signals": "backstage:^", "@backstage/plugin-user-settings": "backstage:^", "@backstage/theme": "backstage:^", + "@backstage/ui": "backstage:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "history": "^5.0.0", diff --git a/workspaces/tech-radar/packages/app-next/src/index.tsx b/workspaces/tech-radar/packages/app-next/src/index.tsx index 9784d7314a8..f10bae44a3f 100644 --- a/workspaces/tech-radar/packages/app-next/src/index.tsx +++ b/workspaces/tech-radar/packages/app-next/src/index.tsx @@ -16,5 +16,6 @@ import '@backstage/cli/asset-types'; import { createRoot } from 'react-dom/client'; import app from './App'; +import '@backstage/ui/css/styles.css'; createRoot(document.getElementById('root')!).render(app); diff --git a/workspaces/tech-radar/packages/app/package.json b/workspaces/tech-radar/packages/app/package.json index 14715eb3a4d..03933dd9784 100644 --- a/workspaces/tech-radar/packages/app/package.json +++ b/workspaces/tech-radar/packages/app/package.json @@ -44,6 +44,7 @@ "@backstage/plugin-techdocs-react": "backstage:^", "@backstage/plugin-user-settings": "backstage:^", "@backstage/theme": "backstage:^", + "@backstage/ui": "backstage:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "react": "^18.0.2", diff --git a/workspaces/tech-radar/packages/app/src/index.tsx b/workspaces/tech-radar/packages/app/src/index.tsx index ea13d30f0dd..95fd8d5212d 100644 --- a/workspaces/tech-radar/packages/app/src/index.tsx +++ b/workspaces/tech-radar/packages/app/src/index.tsx @@ -16,5 +16,6 @@ import '@backstage/cli/asset-types'; import ReactDOM from 'react-dom/client'; import App from './App'; +import '@backstage/ui/css/styles.css'; ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/workspaces/tech-radar/plugins/tech-radar/README.md b/workspaces/tech-radar/plugins/tech-radar/README.md index aa7d8a1bbd2..562d7064f82 100644 --- a/workspaces/tech-radar/plugins/tech-radar/README.md +++ b/workspaces/tech-radar/plugins/tech-radar/README.md @@ -2,6 +2,8 @@ Screenshot of Tech Radar plugin +> Backstage UI (BUI) is now required for the Tech Radar plugin to function. It has been included as part of Backstage since `1.41.0`, which means you're very likely to already have it installed. The [BUI documentation](https://ui.backstage.io/) has details on installation if needed, and the Backstage [User Interface documentation](https://backstage.io/docs/conf/user-interface/) has details on creating a custom BUI theme. + The Backstage integration for the Tech Radar based on [Zalando's Tech Radar](https://opensource.zalando.com/tech-radar/) open sourced on [GitHub](https://github.com/zalando/tech-radar). This is used at [Spotify](https://spotify.github.io) for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes. Read the [blog post on backstage.io about the Tech Radar](https://backstage.io/blog/2020/05/14/tech-radar-plugin). diff --git a/workspaces/tech-radar/plugins/tech-radar/dev/index.tsx b/workspaces/tech-radar/plugins/tech-radar/dev/index.tsx index 28377753fb4..426823ec43f 100644 --- a/workspaces/tech-radar/plugins/tech-radar/dev/index.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/dev/index.tsx @@ -17,6 +17,9 @@ import { createDevApp } from '@backstage/dev-utils'; import { techRadarPlugin, TechRadarPage } from '../src'; +// eslint-disable-next-line @backstage/no-ui-css-imports-in-non-frontend +import '@backstage/ui/css/styles.css'; + createDevApp() .registerPlugin(techRadarPlugin) .addPage({ diff --git a/workspaces/tech-radar/plugins/tech-radar/package.json b/workspaces/tech-radar/plugins/tech-radar/package.json index fb3d1a6fddd..e88912ac9c1 100644 --- a/workspaces/tech-radar/plugins/tech-radar/package.json +++ b/workspaces/tech-radar/plugins/tech-radar/package.json @@ -60,8 +60,9 @@ "@backstage/core-components": "backstage:^", "@backstage/core-plugin-api": "backstage:^", "@backstage/frontend-plugin-api": "backstage:^", - "@material-ui/core": "^4.12.2", + "@backstage/ui": "backstage:^", "@material-ui/icons": "^4.9.1", + "@remixicon/react": "^4.9.0", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "color": "^4.0.1", "d3-force": "^3.0.0", diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.module.css new file mode 100644 index 00000000000..998e3e8d3f4 --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.module.css @@ -0,0 +1,40 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .bubble { + pointer-events: none; + user-select: none; + opacity: 0; + } + + .visibleBubble { + pointer-events: none; + user-select: none; + opacity: 0.8; + } + + .background { + fill: #333; + } + + .text { + pointer-events: none; + user-select: none; + font-size: 10px; + fill: #fff; + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx index 4dcb735464b..81182bafb0f 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarBubble/RadarBubble.tsx @@ -15,7 +15,7 @@ */ import { useRef, useLayoutEffect } from 'react'; -import { makeStyles } from '@material-ui/core/styles'; +import styles from './RadarBubble.module.css'; export type Props = { visible: boolean; @@ -24,30 +24,7 @@ export type Props = { y: number; }; -const useStyles = makeStyles(theme => ({ - bubble: { - pointerEvents: 'none', - userSelect: 'none', - opacity: 0, - }, - visibleBubble: { - pointerEvents: 'none', - userSelect: 'none', - opacity: 0.8, - }, - background: { - fill: '#333', - }, - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '10px', - fill: theme.palette.common.white, - }, -})); - const RadarBubble = (props: Props): React.JSX.Element => { - const classes = useStyles(props); const { visible, text } = props; const textElem = useRef(null); @@ -97,18 +74,14 @@ const RadarBubble = (props: Props): React.JSX.Element => { ref={svgElem} x={0} y={0} - className={visible ? classes.visibleBubble : classes.bubble} + className={visible ? styles.visibleBubble : styles.bubble} data-testid="radar-bubble" > - - + + {text} - + ); }; diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.module.css new file mode 100644 index 00000000000..274342fe4db --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.module.css @@ -0,0 +1,36 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + /* + * Keep the entry dialog opaque in both themes. BUI dark-mode dialog shells can + * be translucent, which made radar labels bleed through the modal content. + */ + .dialog { + background-color: var(--bui-bg-surface-1); + color: var(--bui-fg-primary); + } + + :global([data-theme-mode='dark']) .dialog { + background-color: var(--bui-bg-surface-1); + } + + .dialogLink { + display: inline-flex; + align-items: center; + gap: var(--bui-space-1); + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx index 74aba8fa09e..aacbf544bd5 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarDescription/RadarDescription.tsx @@ -14,16 +14,13 @@ * limitations under the License. */ -import Dialog from '@material-ui/core/Dialog'; -import DialogTitle from '@material-ui/core/DialogTitle'; -import Button from '@material-ui/core/Button'; -import DialogActions from '@material-ui/core/DialogActions'; -import DialogContent from '@material-ui/core/DialogContent'; -import LinkIcon from '@material-ui/icons/Link'; +import { Dialog, DialogBody, DialogFooter, DialogHeader } from '@backstage/ui'; +import { RiLinkM } from '@remixicon/react'; import { Link, MarkdownContent } from '@backstage/core-components'; import { isValidUrl } from '../../utils/components'; import type { EntrySnapshot } from '../../utils/types'; import { RadarTimeline } from '../RadarTimeline'; +import styles from './RadarDescription.module.css'; export type Props = { open: boolean; @@ -45,48 +42,51 @@ const RadarDescription = (props: Props): React.JSX.Element => { const { open, onClose, title, description, timeline, url, links } = props; + // Controlled Dialog without DialogTrigger — matches BUI docs and avoids broken + // overlays when opened from SVG legend/blip clicks (no trigger element). return ( { + if (!isOpen) onClose(); + }} > - + {title} - - + + - + {showDialogActions(url, links) && ( - + {links?.map(link => ( - + ))} {isValidUrl(url) && ( - + )} - + )} ); diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.module.css new file mode 100644 index 00000000000..abd4ba0bd7a --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.module.css @@ -0,0 +1,29 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .text { + pointer-events: none; + user-select: none; + font-size: 9px; + fill: #fff; + text-anchor: middle; + } + + .link { + cursor: pointer; + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx index b43a8d1b394..f5c314133f3 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarEntry/RadarEntry.tsx @@ -15,10 +15,10 @@ */ import * as React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; import { WithLink } from '../../utils/components'; import { RadarDescription } from '../RadarDescription'; import type { EntrySnapshot } from '../../utils/types'; +import styles from './RadarEntry.module.css'; export type Props = { x: number; @@ -37,20 +37,6 @@ export type Props = { onClick?: (event: React.MouseEvent) => void; }; -const useStyles = makeStyles(theme => ({ - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '9px', - fill: theme.palette.common.white, - textAnchor: 'middle', - }, - - link: { - cursor: 'pointer', - }, -})); - const makeBlip = (color: string, moved?: number) => { const style = { fill: color }; @@ -65,7 +51,6 @@ const makeBlip = (color: string, moved?: number) => { }; const RadarEntry = (props: Props): React.JSX.Element => { - const classes = useStyles(props); const [open, setOpen] = React.useState(false); const { @@ -122,7 +107,7 @@ const RadarEntry = (props: Props): React.JSX.Element => { {description ? ( // eslint-disable-next-line jsx-a11y/anchor-is-valid { {blip} ) : ( - + {blip} )} - + {value} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.module.css new file mode 100644 index 00000000000..ea949e9b44b --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.module.css @@ -0,0 +1,24 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .text { + pointer-events: none; + user-select: none; + font-size: 10px; + fill: var(--bui-fg-secondary); + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx index 6ed80a7e7cd..8ef4faf6965 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarFooter/RadarFooter.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { makeStyles } from '@material-ui/core/styles'; +import styles from './RadarFooter.module.css'; export type Props = { x: number; @@ -25,25 +25,15 @@ export type Props = { const onespace = '\u00a0'; -const useStyles = makeStyles(theme => ({ - text: { - pointerEvents: 'none', - userSelect: 'none', - fontSize: '10px', - fill: theme.palette.text.secondary, - }, -})); - const RadarFooter = (props: Props): React.JSX.Element => { const { x, y, spaces = 5, labels } = props; - const classes = useStyles(props); const space = onespace.repeat(spaces); return ( {`▲ moved up${space}▼ moved down`} {labels && space} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.module.css new file mode 100644 index 00000000000..57dcaef534b --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.module.css @@ -0,0 +1,38 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .ring { + fill: none; + stroke: #bbb; + stroke-width: 1px; + } + + .axis { + fill: none; + stroke: #bbb; + stroke-width: 1px; + } + + .text { + pointer-events: none; + user-select: none; + fill: var(--bui-fg-primary); + font-size: 25px; + font-weight: 800; + opacity: 0.7; + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx index 9d3181cabaa..597cf61e840 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarGrid/RadarGrid.tsx @@ -14,43 +14,18 @@ * limitations under the License. */ -import { makeStyles } from '@material-ui/core/styles'; import type { Ring } from '../../utils/types'; +import styles from './RadarGrid.module.css'; export type Props = { radius: number; rings: Ring[]; }; -const useStyles = makeStyles( - theme => ({ - ring: { - fill: 'none', - stroke: '#bbb', - strokeWidth: '1px', - }, - axis: { - fill: 'none', - stroke: '#bbb', - strokeWidth: '1px', - }, - text: { - pointerEvents: 'none', - userSelect: 'none', - fill: theme.palette.text.primary, - fontSize: '25px', - fontWeight: 800, - opacity: 0.7, - }, - }), - { name: 'PluginTechRadarGrid' }, -); - // A component for the background grid of the radar, with axes, rings etc. It will render around the origin, i.e. // assume that (0, 0) is in the middle of the drawing. const RadarGrid = (props: Props) => { const { radius, rings } = props; - const classes = useStyles(props); const makeRingNode = (ringIndex: number, ringRadius?: number) => [ { cx={0} cy={0} r={ringRadius} - className={classes.ring} + className={styles.ring} />, @@ -80,7 +55,7 @@ const RadarGrid = (props: Props) => { y1={-radius} x2={0} y2={radius} - className={classes.axis} + className={styles.axis} data-testid="radar-grid-x-line" />, // Y axis @@ -90,7 +65,7 @@ const RadarGrid = (props: Props) => { y1={0} x2={radius} y2={0} - className={classes.axis} + className={styles.axis} data-testid="radar-grid-y-line" />, ]; diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.module.css new file mode 100644 index 00000000000..b2649365a19 --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.module.css @@ -0,0 +1,88 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .quadrant { + height: 100%; + width: 100%; + overflow-y: auto; + scrollbar-width: thin; + } + + .quadrantHeading { + pointer-events: none; + user-select: none; + margin-top: 0; + margin-bottom: var(--bui-space-4); + font-size: 18px; + } + + /* columns count is set via inline style */ + .rings { + /* dynamic columns applied inline */ + } + + .ring { + break-inside: avoid-column; + page-break-inside: avoid; + -webkit-column-break-inside: avoid; + font-size: 12px; + margin-bottom: var(--bui-space-4); + } + + .ringEmpty { + color: var(--bui-fg-secondary); + font-size: 12px; + } + + .ringHeading { + pointer-events: none; + user-select: none; + margin-top: 0; + margin-bottom: var(--bui-space-2); + font-size: 12px; + font-weight: 800; + } + + .ringList { + list-style-position: inside; + margin-top: 0; + padding-left: 0; + font-variant-numeric: proportional-nums; + -moz-font-feature-settings: 'pnum'; + -webkit-font-feature-settings: 'pnum'; + font-feature-settings: 'pnum'; + } + + .entry { + pointer-events: visiblePainted; + user-select: none; + font-size: 11px; + } + + .activeEntry { + pointer-events: visiblePainted; + user-select: none; + font-size: 11px; + background: #6f6f6f; + color: #fff; + } + + .entryLink { + pointer-events: visiblePainted; + cursor: pointer; + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx index 42b8f956bec..1cdf174b964 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx @@ -14,84 +14,18 @@ * limitations under the License. */ -import { makeStyles } from '@material-ui/core/styles'; import { RadarLegendQuadrant } from './RadarLegendQuadrant'; import { RadarLegendProps } from './types'; import { setupSegments } from './utils'; -const useStyles = makeStyles(theme => ({ - quadrant: { - height: '100%', - width: '100%', - overflowY: 'auto', - scrollbarWidth: 'thin', - }, - quadrantHeading: { - pointerEvents: 'none', - userSelect: 'none', - marginTop: 0, - marginBottom: theme.spacing(2), - fontSize: '18px', - }, - rings: { - columns: (props: { columnCount: number }) => props.columnCount, - }, - ring: { - breakInside: 'avoid-column', - pageBreakInside: 'avoid', - '-webkit-column-break-inside': 'avoid', - fontSize: '12px', - marginBottom: theme.spacing(2), - }, - ringEmpty: { - color: theme.palette.text.secondary, - fontSize: '12px', - }, - ringHeading: { - pointerEvents: 'none', - userSelect: 'none', - marginTop: 0, - marginBottom: theme.spacing(1), - fontSize: '12px', - fontWeight: 800, - }, - ringList: { - listStylePosition: 'inside', - marginTop: 0, - paddingLeft: 0, - fontVariantNumeric: 'proportional-nums', - '-moz-font-feature-settings': 'pnum', - '-webkit-font-feature-settings': 'pnum', - 'font-feature-settings': 'pnum', - }, - entry: { - pointerEvents: 'visiblePainted', - userSelect: 'none', - fontSize: '11px', - }, - activeEntry: { - pointerEvents: 'visiblePainted', - userSelect: 'none', - fontSize: '11px', - background: '#6f6f6f', - color: theme.palette.common.white, - }, - entryLink: { - pointerEvents: 'visiblePainted', - cursor: 'pointer', - }, -})); - const RadarLegend = ({ quadrants, rings, entries, + columnCount, onEntryMouseEnter, onEntryMouseLeave, - ...props }: RadarLegendProps): React.JSX.Element => { - const classes = useStyles(props); - return ( {quadrants.map(quadrant => ( @@ -100,7 +34,7 @@ const RadarLegend = ({ segments={setupSegments(entries)} quadrant={quadrant} rings={rings} - classes={classes} + columnCount={columnCount} onEntryMouseEnter={onEntryMouseEnter} onEntryMouseLeave={onEntryMouseLeave} /> diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx index c22bb18d542..c5794290626 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendLink.tsx @@ -13,19 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ClassNameMap } from '@material-ui/core/styles/withStyles'; -import Typography from '@material-ui/core/Typography'; import { useState } from 'react'; import { WithLink } from '../../utils/components'; import { RadarDescription } from '../RadarDescription'; import type { EntrySnapshot } from '../../utils/types'; +import styles from './RadarLegend.module.css'; type RadarLegendLinkProps = { entryId: string; url?: string; description?: string; title?: string; - classes: ClassNameMap; active?: boolean; links: Array<{ url: string; title: string }>; timeline: EntrySnapshot[]; @@ -36,7 +34,6 @@ export const RadarLegendLink = ({ url, description, title, - classes, active, links, timeline, @@ -58,22 +55,20 @@ export const RadarLegendLink = ({ if (description) { return ( <> - - {title} - - + + {open && ( - + + {title} - + ); }; diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx index 04c128b4648..269bf97036d 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarLegend/RadarLegendQuadrant.tsx @@ -14,17 +14,17 @@ * limitations under the License. */ -import { ClassNameMap } from '@material-ui/core/styles/withStyles'; import { Quadrant, Ring } from '../../utils/types'; import { RadarLegendRing } from './RadarLegendRing'; import { RadarLegendProps, Segments } from './types'; import { getSegment } from './utils'; +import styles from './RadarLegend.module.css'; type RadarLegendQuadrantProps = { segments: Segments; quadrant: Quadrant; rings: Ring[]; - classes: ClassNameMap; + columnCount: number; onEntryMouseEnter: RadarLegendProps['onEntryMouseEnter']; onEntryMouseLeave: RadarLegendProps['onEntryMouseLeave']; }; @@ -33,7 +33,7 @@ export const RadarLegendQuadrant = ({ segments, quadrant, rings, - classes, + columnCount, onEntryMouseEnter, onEntryMouseLeave, }: RadarLegendQuadrantProps) => { @@ -46,14 +46,13 @@ export const RadarLegendQuadrant = ({ height={quadrant.legendHeight} data-testid="radar-quadrant" > -
-

{quadrant.name}

-
+
+

{quadrant.name}

+
{rings.map(ring => ( ; onEntryMouseEnter?: RadarLegendProps['onEntryMouseEnter']; onEntryMouseLeave?: RadarLegendProps['onEntryMouseEnter']; }; @@ -30,25 +28,22 @@ type RadarLegendRingProps = { export const RadarLegendRing = ({ ring, entries, - classes, onEntryMouseEnter, onEntryMouseLeave, }: RadarLegendRingProps) => { return ( -
+

{ring.name}

{entries.length === 0 ? ( - - (empty) - +

(empty)

) : ( -
    +
      {entries.map(entry => (
    1. ({ - overflowXScroll: { - overflowX: 'scroll', - }, -})); +import styles from './RadarPage.module.css'; /** * Properties for {@link TechRadarPage} @@ -67,22 +59,29 @@ export function RadarPage(props: TechRadarPageProps) { pageTitle = 'Company Radar', ...componentProps } = props; - const classes = useStyles(); const [searchText, setSearchText] = useState(''); return (
      - + - setSearchText(e.target.value)} - /> + + setSearchText(value)} + style={{ width: '100%', minWidth: 200 }} + /> + - + This is used for visualizing the official guidelines of different areas of software development such as languages, frameworks, infrastructure and processes. You can find an explanation for the @@ -91,14 +90,16 @@ export function RadarPage(props: TechRadarPageProps) { Zalando Tech Radar . - + - - - - - + {/* + Full-width radar (demo parity). The previous MUI Grid sm=6/md=4 column + left a large empty region and made the filter feel "detached". + */} +
      + +
      ); diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.module.css b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.module.css new file mode 100644 index 00000000000..29b047bf009 --- /dev/null +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.module.css @@ -0,0 +1,53 @@ +/* + * Copyright 2026 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. + */ + +@layer components { + .tableContainer { + width: 100%; + overflow-x: auto; + margin-top: var(--bui-space-4); + border-radius: var(--bui-radius-2); + border: 1px solid var(--bui-border); + background-color: var(--bui-bg-surface-1); + } + + .table { + width: 100%; + border-collapse: collapse; + table-layout: auto; + font-size: var(--bui-font-size-2); + background-color: var(--bui-bg-surface-1); + color: var(--bui-fg-primary); + } + + .th { + padding: var(--bui-space-2) var(--bui-space-4); + text-align: left; + font-weight: var(--bui-font-weight-bold); + border-bottom: 1px solid var(--bui-border); + color: var(--bui-fg-primary); + background-color: var(--bui-bg-surface-1); + white-space: nowrap; + } + + .td { + padding: var(--bui-space-2) var(--bui-space-4); + border-bottom: 1px solid var(--bui-border); + color: var(--bui-fg-primary); + vertical-align: top; + background-color: var(--bui-bg-surface-1); + } +} diff --git a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx index 238946bfaff..6da4455ff26 100644 --- a/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx +++ b/workspaces/tech-radar/plugins/tech-radar/src/components/RadarTimeline/RadarTimeline.tsx @@ -15,21 +15,15 @@ */ import type { EntrySnapshot } from '../../utils/types'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableContainer from '@material-ui/core/TableContainer'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import Paper from '@material-ui/core/Paper'; -import Typography from '@material-ui/core/Typography'; - -import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward'; -import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; -import AdjustIcon from '@material-ui/icons/Adjust'; - +import { Text } from '@backstage/ui'; +import { + RiArrowUpLine, + RiArrowDownLine, + RiRadioButtonLine, +} from '@remixicon/react'; import { MarkdownContent } from '@backstage/core-components'; import { MovedState } from '@backstage-community/plugin-tech-radar-common'; +import styles from './RadarTimeline.module.css'; export type Props = { timeline?: EntrySnapshot[]; @@ -40,53 +34,47 @@ const RadarTimeline = (props: Props): React.JSX.Element => { return ( <> - - History - - - - - - + History +
      +
      + + + + + + + + + {timeline?.length === 0 && ( - - - No Timeline - - + + + )} {timeline?.map(timeEntry => ( - - - {timeEntry.moved === MovedState.Up ? : ''} - {timeEntry.moved === MovedState.Down ? ( - - ) : ( - '' + + + + + + ))} - -
      Moved in direction - - Moved to ring - Moved on date - Description - - - + Moved to ringMoved on dateDescription
      No Timeline
      + {timeEntry.moved === MovedState.Up && ( + )} - {timeEntry.moved === MovedState.NoChange ? ( - - ) : ( - '' + {timeEntry.moved === MovedState.Down && ( + + )} + {timeEntry.moved === MovedState.NoChange && ( + )} - - + {timeEntry.ring.name ? timeEntry.ring.name : ''} - - + {timeEntry.date.toLocaleDateString() ? timeEntry.date.toLocaleDateString() : ''} - - + {timeEntry.description ? ( { ) : ( '' )} - - +
      -
      + + +
); }; diff --git a/workspaces/tech-radar/yarn.lock b/workspaces/tech-radar/yarn.lock index 1f945755c0f..ceccf982de7 100644 --- a/workspaces/tech-radar/yarn.lock +++ b/workspaces/tech-radar/yarn.lock @@ -2153,8 +2153,9 @@ __metadata: "@backstage/frontend-plugin-api": "backstage:^" "@backstage/frontend-test-utils": "backstage:^" "@backstage/test-utils": "backstage:^" - "@material-ui/core": "npm:^4.12.2" + "@backstage/ui": "backstage:^" "@material-ui/icons": "npm:^4.9.1" + "@remixicon/react": "npm:^4.9.0" "@testing-library/dom": "npm:^10.0.0" "@testing-library/jest-dom": "npm:^6.0.0" "@testing-library/react": "npm:^15.0.0" @@ -4591,7 +4592,7 @@ __metadata: languageName: node linkType: hard -"@backstage/ui@npm:^0.17.0": +"@backstage/ui@backstage:^::backstage=1.53.0&npm=0.17.0, @backstage/ui@npm:^0.17.0": version: 0.17.0 resolution: "@backstage/ui@npm:0.17.0" dependencies: @@ -8957,7 +8958,7 @@ __metadata: languageName: node linkType: hard -"@remixicon/react@npm:>=4.6.0 <4.9.0, @remixicon/react@npm:^4.6.0": +"@remixicon/react@npm:>=4.6.0 <4.9.0": version: 4.8.0 resolution: "@remixicon/react@npm:4.8.0" peerDependencies: @@ -8966,6 +8967,15 @@ __metadata: languageName: node linkType: hard +"@remixicon/react@npm:^4.6.0, @remixicon/react@npm:^4.9.0": + version: 4.9.0 + resolution: "@remixicon/react@npm:4.9.0" + peerDependencies: + react: ">=18.2.0" + checksum: 10/3d8f1d86b2bb20ab5e44d15f18811e928b0886f7710eb7a1516afb9913ba72e46facec5dfee382825139d800bcbb6704c15d0c760d0f977c12257d4af8db3295 + languageName: node + linkType: hard + "@rjsf/core@npm:5.24.13": version: 5.24.13 resolution: "@rjsf/core@npm:5.24.13" @@ -13796,6 +13806,7 @@ __metadata: "@backstage/plugin-user-settings": "backstage:^" "@backstage/test-utils": "backstage:^" "@backstage/theme": "backstage:^" + "@backstage/ui": "backstage:^" "@material-ui/core": "npm:^4.12.2" "@material-ui/icons": "npm:^4.9.1" "@playwright/test": "npm:^1.32.3" @@ -13844,6 +13855,7 @@ __metadata: "@backstage/plugin-techdocs-react": "backstage:^" "@backstage/plugin-user-settings": "backstage:^" "@backstage/theme": "backstage:^" + "@backstage/ui": "backstage:^" "@material-ui/core": "npm:^4.12.2" "@material-ui/icons": "npm:^4.9.1" "@playwright/test": "npm:^1.32.3" diff --git a/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogDownloader.tsx b/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogDownloader.tsx index b8a6e19c91c..65964a6e194 100644 --- a/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogDownloader.tsx +++ b/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogDownloader.tsx @@ -13,24 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import type { FC } from 'react'; - -import { useMemo } from 'react'; - +import { PipelineRunKind } from '@backstage-community/plugin-tekton-react'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { V1Pod } from '@kubernetes/client-node'; import { useTheme } from '@mui/material/styles'; import { Flex, FlexItem } from '@patternfly/react-core'; - -import { PipelineRunKind } from '@backstage-community/plugin-tekton-react'; - +import type { FC } from 'react'; +import { useMemo } from 'react'; import { TEKTON_PIPELINE_RUN, TEKTON_PIPELINE_TASK, TEKTON_PIPELINE_TASKRUN, } from '../../consts/tekton-const'; -import PodLogsDownloadLink from './PodLogsDownloadLink'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { tektonTranslationRef } from '../../translations/index.ts'; +import PodLogsDownloadLink from './PodLogsDownloadLink'; const PipelineRunLogDownloader: FC<{ pods: V1Pod[]; diff --git a/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogs.tsx b/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogs.tsx index 794436b393b..af73d12c5a8 100644 --- a/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogs.tsx +++ b/workspaces/tekton/plugins/tekton/src/components/PipelineRunLogs/PipelineRunLogs.tsx @@ -13,26 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useState, useEffect, useMemo } from 'react'; - -import { LogViewer, Progress } from '@backstage/core-components'; - -import { V1Pod } from '@kubernetes/client-node'; -import Grid from '@mui/material/Grid'; -import Paper from '@mui/material/Paper'; - import { getTaskRunsForPipelineRun, pipelineRunFilterReducer, PipelineRunKind, TaskRunKind, } from '@backstage-community/plugin-tekton-react'; - +import { LogViewer, Progress } from '@backstage/core-components'; +import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { V1Pod } from '@kubernetes/client-node'; +import Grid from '@mui/material/Grid'; +import Paper from '@mui/material/Paper'; +import { useEffect, useMemo, useState } from 'react'; +import { tektonTranslationRef } from '../../translations/index.ts'; import { getActiveTaskRun, getSortedTaskRuns } from '../../utils/taskRun-utils'; import { PipelineRunLogViewer } from './PipelineRunLogViewer'; import { TaskStatusStepper } from './TaskStatusStepper'; -import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; -import { tektonTranslationRef } from '../../translations/index.ts'; type PipelineRunLogsProps = { pipelineRun: PipelineRunKind; diff --git a/workspaces/tekton/plugins/tekton/src/hooks/usePodLogsOfPipelineRun.ts b/workspaces/tekton/plugins/tekton/src/hooks/usePodLogsOfPipelineRun.ts index a736c675202..ec9b72aacfb 100644 --- a/workspaces/tekton/plugins/tekton/src/hooks/usePodLogsOfPipelineRun.ts +++ b/workspaces/tekton/plugins/tekton/src/hooks/usePodLogsOfPipelineRun.ts @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useContext } from 'react'; -import { useQuery } from '@tanstack/react-query'; -import { kubernetesProxyApiRef } from '@backstage/plugin-kubernetes-react'; import { useApi } from '@backstage/core-plugin-api'; +import { kubernetesProxyApiRef } from '@backstage/plugin-kubernetes-react'; import { V1Container, V1Pod } from '@kubernetes/client-node'; - +import { useQuery } from '@tanstack/react-query'; +import { useContext } from 'react'; import { TektonResourcesContextData } from '../types/types'; import { TektonResourcesContext } from './TektonResourcesContext';