diff --git a/plugins/ocm/README.md b/plugins/ocm/README.md index f8c828bd848..81d524b4719 100644 --- a/plugins/ocm/README.md +++ b/plugins/ocm/README.md @@ -187,19 +187,19 @@ catalog: yarn workspace app add @janus-idp/backstage-plugin-ocm ``` -1. Select the components that you want to use, such as: +2. Select the components that you want to use, such as: - `OcmPage`: This is a standalone page or dashboard displaying all clusters as tiles. You can add `OcmPage` to `packages/app/src/App.tsx` file as follows: ```tsx title="packages/app/src/App.tsx" /* highlight-add-next-line */ - import { OcmPage } from '@janus-idp/backstage-plugin-ocm'; + import { OcmIcon, OcmPage } from '@janus-idp/backstage-plugin-ocm'; const routes = ( {/* ... */} {/* highlight-add-next-line */} - } />} /> + } />} /> ); ``` @@ -208,7 +208,7 @@ catalog: ```tsx title="packages/app/src/components/Root/Root.tsx" /* highlight-add-next-line */ - import StorageIcon from '@material-ui/icons/Storage'; + import { OcmIcon } from '@janus-idp/backstage-plugin-ocm'; export const Root = ({ children }: PropsWithChildren<{}>) => ( @@ -216,7 +216,7 @@ catalog: }> {/* ... */} {/* highlight-add-next-line */} - + {/* ... */} diff --git a/plugins/ocm/dev/index.tsx b/plugins/ocm/dev/index.tsx index 9f5c49ed977..fa4e9be5e84 100644 --- a/plugins/ocm/dev/index.tsx +++ b/plugins/ocm/dev/index.tsx @@ -19,7 +19,7 @@ import { ClusterContextProvider, ClusterInfoCard, } from '../src'; -import { OcmPage, ocmPlugin } from '../src/plugin'; +import { OcmIcon, OcmPage, ocmPlugin } from '../src/plugin'; const clusterEntity = (name: string): Entity => ({ apiVersion: 'backstage.io/v1beta1', @@ -87,8 +87,9 @@ createDevApp() .addThemes(getAllThemes()) .addPage({ element: , - title: 'Root Page', + title: 'Clusters', path: '/ocm', + icon: OcmIcon, }) .addPage({ path: '/catalog/:kind/:namespace/:name', diff --git a/plugins/ocm/package.json b/plugins/ocm/package.json index 5fd17b34eac..264e0d56590 100644 --- a/plugins/ocm/package.json +++ b/plugins/ocm/package.json @@ -46,8 +46,8 @@ "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.3", "@material-ui/lab": "^4.0.0-alpha.45", + "@mui/icons-material": "^6.0.1", "@patternfly/patternfly": "^5.1.0", - "@patternfly/react-icons": "^5.1.1", "react-use": "^17.4.0", "semver": "^7.5.4" }, diff --git a/plugins/ocm/src/components/common.tsx b/plugins/ocm/src/components/common.tsx index 7114691f034..569361d069b 100644 --- a/plugins/ocm/src/components/common.tsx +++ b/plugins/ocm/src/components/common.tsx @@ -7,7 +7,7 @@ import { } from '@backstage/core-components'; import { Button, Grid, makeStyles, Tooltip } from '@material-ui/core'; -import { ArrowCircleUpIcon } from '@patternfly/react-icons'; +import ArrowCircleUpIcon from '@mui/icons-material/ArrowCircleUp'; import { ClusterStatus } from '@janus-idp/backstage-plugin-ocm-common'; diff --git a/plugins/ocm/src/index.ts b/plugins/ocm/src/index.ts index cd707f08923..9db71ab7480 100644 --- a/plugins/ocm/src/index.ts +++ b/plugins/ocm/src/index.ts @@ -1,8 +1,7 @@ -export { ocmPlugin, OcmPage } from './plugin'; +export { ocmPlugin, OcmPage, OcmIcon } from './plugin'; export { ClusterAvailableResourceCard } from './components/ClusterAvailableResourcesCard'; export { ClusterContextProvider, useCluster, } from './components/ClusterContext'; export { ClusterInfoCard } from './components/ClusterInfoCard'; -export { default as OcmIcon } from '@material-ui/icons/Storage'; diff --git a/plugins/ocm/src/plugin.ts b/plugins/ocm/src/plugin.ts index 164e20ffe2f..9933ae048f2 100644 --- a/plugins/ocm/src/plugin.ts +++ b/plugins/ocm/src/plugin.ts @@ -3,9 +3,12 @@ import { createApiFactory, createPlugin, createRoutableExtension, + IconComponent, identityApiRef, } from '@backstage/core-plugin-api'; +import HubOutlinedIcon from '@mui/icons-material/HubOutlined'; + import { OcmApiClient, OcmApiRef } from './api'; import { rootRouteRef } from './routes'; @@ -35,3 +38,5 @@ export const OcmPage = ocmPlugin.provide( mountPoint: rootRouteRef, }), ); + +export const OcmIcon = HubOutlinedIcon as IconComponent; diff --git a/plugins/shared-react/src/components/common/Status.tsx b/plugins/shared-react/src/components/common/Status.tsx index c9fca69acfc..9eba8f298f0 100644 --- a/plugins/shared-react/src/components/common/Status.tsx +++ b/plugins/shared-react/src/components/common/Status.tsx @@ -9,25 +9,28 @@ import { StatusWarning, } from '@backstage/core-components'; -import { makeStyles } from '@material-ui/core'; +import { createStyles, makeStyles, Theme } from '@material-ui/core'; import OffIcon from '@mui/icons-material/DoNotDisturbOnOutlined'; import UnknownIcon from '@mui/icons-material/HelpOutline'; import AngleDoubleRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight'; import BanIcon from '@mui/icons-material/NotInterestedOutlined'; import PauseIcon from '@mui/icons-material/PauseCircleOutlineOutlined'; +import cx from 'classnames'; import { StatusIconAndText } from './StatusIconAndText'; -const useStyles = makeStyles({ - iconStyles: { - height: '0.8em', - width: '0.8em', - top: '0.125em', - position: 'relative', - flexShrink: 0, - marginRight: '8px', - }, -}); +const useStyles = makeStyles(theme => + createStyles({ + iconStyles: { + height: '0.8em', + width: '0.8em', + top: '0.125em', + position: 'relative', + flexShrink: 0, + marginRight: theme.spacing(0.6), + }, + }), +); const DASH = '-'; @@ -59,37 +62,43 @@ const useStatusStyles = makeStyles(theme => ({ }, })); -const StatusIcon = ({ statusKey }: { statusKey: StatusClassKey }) => { +const StatusIcon = ({ + statusKey, + classNames, +}: { + statusKey: StatusClassKey; + classNames: string; +}) => { const statusStyles = useStatusStyles(); switch (statusKey) { case 'ok': return ( - + {' '} ); case 'pending': return ( - + {' '} ); case 'running': return ( - + {' '} ); case 'warning': return ( - + {' '} ); case 'error': return ( - + {' '} ); @@ -103,6 +112,7 @@ const StatusIcon = ({ statusKey }: { statusKey: StatusClassKey }) => { * @param {string} status - type of status to be displayed * @param {boolean} [iconOnly] - (optional) if true, only displays icon * @param {string} [className] - (optional) additional class name for the component + * @param {string} [displayStatusText] - (optional) use a different text to display the status * @example * ```tsx @@ -114,17 +124,24 @@ export const Status = ({ iconOnly, className, displayStatusText, + dataTestId, + iconStyles, + iconClassNames, }: { status: string | null; displayStatusText?: string; iconOnly?: boolean; className?: string; + dataTestId?: string; + iconStyles?: React.CSSProperties; + iconClassNames?: string; }): React.ReactElement => { const classes = useStyles(); const statusProps = { title: displayStatusText || status || '', iconOnly, className, + dataTestId, }; switch (status) { @@ -135,12 +152,15 @@ export const Status = ({ return ( } + icon={ + + } /> ); case 'In Progress': case 'Progress': + case 'Progressing': case 'Installing': case 'InstallReady': case 'Replacing': @@ -151,7 +171,9 @@ export const Status = ({ return ( } + icon={ + + } /> ); @@ -166,7 +188,7 @@ export const Status = ({ return ( } + icon={} /> ); @@ -175,28 +197,34 @@ export const Status = ({ return ( } + icon={ + + } /> ); case 'ImagePullBackOff': case 'Error': case 'Failed': + case 'Failure': case 'CrashLoopBackOff': case 'ErrImagePull': return ( } + icon={ + + } /> ); case 'Completed': case 'Succeeded': + case 'Synced': return ( } + icon={} /> ); @@ -204,21 +232,26 @@ export const Status = ({ return ( } + icon={ + + } /> ); case 'Paused': return ( } + icon={} /> ); case 'Stopped': return ( } + icon={} /> ); @@ -226,7 +259,9 @@ export const Status = ({ return ( } + icon={ + + } /> ); diff --git a/plugins/shared-react/src/components/common/StatusIconAndText.tsx b/plugins/shared-react/src/components/common/StatusIconAndText.tsx index 647afba846f..e07e9304539 100644 --- a/plugins/shared-react/src/components/common/StatusIconAndText.tsx +++ b/plugins/shared-react/src/components/common/StatusIconAndText.tsx @@ -6,14 +6,6 @@ import CamelCaseWrap from './CamelCaseWrap'; import './StatusIconAndText.css'; -type StatusIconAndTextProps = { - title: string; - iconOnly?: boolean; - className?: string; - icon: React.ReactElement; - spin?: boolean; -}; - const DASH = '-'; export const StatusIconAndText = ({ @@ -22,7 +14,15 @@ export const StatusIconAndText = ({ spin, iconOnly, className, -}: StatusIconAndTextProps): React.ReactElement => { + dataTestId, +}: { + title: string; + iconOnly?: boolean; + className?: string; + icon: React.ReactElement; + spin?: boolean; + dataTestId?: string; +}): React.ReactElement => { if (!title) { return <>{DASH}; } @@ -31,7 +31,7 @@ export const StatusIconAndText = ({ return ( <> {React.cloneElement(icon, { - 'data-testid': `icon-only-${title}`, + 'data-testid': dataTestId ? dataTestId : `icon-only-${title}`, className: icon.props.className, })} @@ -41,7 +41,7 @@ export const StatusIconAndText = ({ return ( {React.cloneElement(icon, {