diff --git a/src/components/SnykEntityComponent/SnykOverviewComponent.tsx b/src/components/SnykEntityComponent/SnykOverviewComponent.tsx index a60d2ff..74e2f66 100644 --- a/src/components/SnykEntityComponent/SnykOverviewComponent.tsx +++ b/src/components/SnykEntityComponent/SnykOverviewComponent.tsx @@ -7,7 +7,7 @@ import { useAsync } from "react-use"; import { Alert } from '@mui/material'; import { Grid } from "@mui/material"; -import { SnykCircularCounter } from "./components/SnykCircularCountersComponent"; +import { SnykCounter } from "./components/SnykCountersComponent"; import { IssuesCount as IssuesCountType } from "../../types/types"; import { useEntity } from "@backstage/plugin-catalog-react"; import { UnifiedIssues } from "../../types/unifiedIssuesTypes"; @@ -129,18 +129,8 @@ export const SnykOverviewComponent = ({ entity }: { entity: Entity }) => { if (loading) { return ( - ); @@ -162,8 +152,7 @@ export const SnykOverviewComponent = ({ entity }: { entity: Entity }) => { return ( - - + ); }; diff --git a/src/components/SnykEntityComponent/SnykTab.tsx b/src/components/SnykEntityComponent/SnykTab.tsx index 1e44611..07eef6f 100644 --- a/src/components/SnykEntityComponent/SnykTab.tsx +++ b/src/components/SnykEntityComponent/SnykTab.tsx @@ -13,7 +13,7 @@ import { useAsync } from "react-use"; import { Alert } from "@material-ui/lab"; import { IssuesTable } from "./components/SnykIssuesComponent"; import { DepGraphInfo } from "./components/SnykDepGraphComponent"; -import { SnykCircularCounter } from "./components/SnykCircularCountersComponent"; +import { SnykCounter } from "./components/SnykCountersComponent"; import { ProjectGetResponseType, DepgraphGetResponseType, @@ -125,25 +125,22 @@ export const generateSnykTabForProject = ( > - - - @@ -213,25 +210,22 @@ export const generateSnykTabForProject = ( > - - - diff --git a/src/components/SnykEntityComponent/components/SnykCircularCountersComponent.tsx b/src/components/SnykEntityComponent/components/SnykCircularCountersComponent.tsx deleted file mode 100644 index 779a0f1..0000000 --- a/src/components/SnykEntityComponent/components/SnykCircularCountersComponent.tsx +++ /dev/null @@ -1,210 +0,0 @@ -import React, { FC, useEffect, useRef, useState } from "react"; -import { - CircularProgressbarWithChildren, - buildStyles, -} from "react-circular-progressbar"; -import "react-circular-progressbar/dist/styles.css"; -import { IssuesCount } from "../../../types/types"; - -export type SnykCircularCounterProps = { - issuesCount: IssuesCount; - loading: boolean; -}; -export const SnykCircularCounter: FC = ({ - issuesCount, - loading, -}) => { - const criticalSevCount = issuesCount.critical; - const highSevCount = issuesCount.high; - const mediumSevCount = issuesCount.medium; - const lowSevCount = issuesCount.low; - const total = criticalSevCount + highSevCount + mediumSevCount + lowSevCount; - - const [lines, setLines] = useState([ - { - color: `rgb(${Math.floor(Math.random() * 256)}, 0, ${Math.floor( - 128 + Math.random() * 128 - )})`, - value: Math.floor(Math.random() * 10), - }, - { - color: `rgb(${Math.floor(Math.random() * 256)}, 0, ${Math.floor( - 128 + Math.random() * 128 - )})`, - value: Math.floor(Math.random() * 10), - }, - { - color: `rgb(${Math.floor(Math.random() * 256)}, 0, ${Math.floor( - 128 + Math.random() * 128 - )})`, - value: Math.floor(Math.random() * 10), - }, - { - color: `rgb(${Math.floor(Math.random() * 256)}, 0, ${Math.floor( - 128 + Math.random() * 128 - )})`, - value: Math.floor(Math.random() * 10), - }, - ]); - - const intervalId = useRef(null); - - // In seconds - const transitionDuration = 1; - - useEffect(() => { - if (loading) { - intervalId.current = setInterval(() => { - setLines((allLines) => - allLines.map((line) => ({ - // Random color between blue and purple - color: `rgb(${Math.floor(Math.random() * 256)}, 0, ${Math.floor( - 128 + Math.random() * 128 - )})`, - // Increase/decrease value by a random amount between 20 and -20, no more than 50 and no less than 0 - value: Math.max( - 0, - Math.min(50, line.value + Math.floor(Math.random() * 40) - 10) - ), - })) - ); - }, transitionDuration * 1000); - } else { - setLines((allLines) => - allLines.map((line: { color: string; value: number }) => ({ - ...line, - })) - ); - if (intervalId.current) { - clearInterval(intervalId.current); - intervalId.current = null; - } - } - - return () => { - if (intervalId.current) { - clearInterval(intervalId.current); - intervalId.current = null; - } - }; - }, [loading]); - - useEffect(() => { - // Cleanup function to clear the interval - return () => { - if (intervalId) { - if (intervalId.current) { - clearInterval(intervalId.current); - intervalId.current = null; - } - } - }; - }, []); - - if (!loading) { - if (total === 0) { - lines[0].value = 100; - lines[1].value = 100; - lines[2].value = 100; - lines[3].value = 100; - lines[0].color = "#00ff00"; - lines[1].color = "#44ff44"; - lines[2].color = "#88ff88"; - lines[3].color = "#bbffbb"; - } else { - lines[0].value = (criticalSevCount * 100) / total; - lines[1].value = (highSevCount * 100) / total; - lines[2].value = (mediumSevCount * 100) / total; - lines[3].value = (lowSevCount * 100) / total; - lines[0].color = "#f00"; - lines[1].color = "orange"; - lines[2].color = "yellow"; - lines[3].color = "#dcff00"; - } - } - return ( - - {/* - Width here needs to be (100 - 2 * strokeWidth)% - in order to fit exactly inside the outer progressbar. - */} - - - - - - - - {criticalSevCount} Critical - - {highSevCount} High - - {mediumSevCount} Medium - - {lowSevCount} Low - - - - - - - - ); -}; diff --git a/src/components/SnykEntityComponent/components/SnykCounterStyle.ts b/src/components/SnykEntityComponent/components/SnykCounterStyle.ts new file mode 100644 index 0000000..955fd32 --- /dev/null +++ b/src/components/SnykEntityComponent/components/SnykCounterStyle.ts @@ -0,0 +1,94 @@ +import { createStyles, makeStyles } from '@material-ui/core'; + +const styles = createStyles({ + root: { + display: 'flex', + fontVariant: 'proportional-nums', + listStyle: 'none', + lineHeight: '1', + margin: '0', + padding: '0', + gap: '8px', + }, + count: { + minWidth: '28px', + lineHeight: '1rem', + padding: '0 8px', + fontVariantNumeric: 'tabular-nums', + justifyContent: 'center', + fontSize:'16px', + fontWeight:400, + alignItems: 'center', + borderBottomLeftRadius:'3px', + borderRight: '1px solid white', + borderTopLeftRadius:'3px', + boxSizing: 'border-box', + display: 'inline-flex', + letterSpacing: '-.0125rem', + }, + item: { + display: 'flex', + fontSize: '18px', + fontWeight: 500, + textAlign: 'center', + borderRadius: '3px', + minHeight: '28px', + }, + text: { + padding: '0 4px', + lineHeight: '1', + textDecoration: 'none', + borderTopRightRadius: '3px', + borderBottomRightRadius: '3px', + minWidth: '28px', + fontSize: '18px', + fontWeight: 500, + display: 'inline-flex', + justifyContent: 'center', + alignItems: 'center', + boxSizing: 'border-box', + letterSpacing: '0', + }, + item_disabled: { + backgroundColor: '#e7e7e7', + color: '#828282', + }, + item_disabled_text: { + backgroundColor: '#bebebe', + color: '#fff', + }, + item_critical: { + backgroundColor: '#ffdad8', + color: '#9e261e', + }, + item_critical_text: { + backgroundColor: '#9e261e', + color: '#fff', + }, + item_high: { + backgroundColor: '#ffdbcc', + color: '#9b3d15', + }, + item_high_text: { + backgroundColor: '#ce5019', + color: '#fff', + }, + item_medium: { + backgroundColor: '#ffe8cd', + color: '#925c1e', + }, + item_medium_text: { + backgroundColor: '#d68000', + color: '#fff', + }, + item_low: { + backgroundColor: '#eeeeee', + color: '#585675', + }, + item_low_text: { + backgroundColor: '#88879e', + color: '#fff', + }, +}); + +export const useSnykCounterStyle = makeStyles(styles); diff --git a/src/components/SnykEntityComponent/components/SnykCountersComponent.tsx b/src/components/SnykEntityComponent/components/SnykCountersComponent.tsx new file mode 100644 index 0000000..efa89bc --- /dev/null +++ b/src/components/SnykEntityComponent/components/SnykCountersComponent.tsx @@ -0,0 +1,33 @@ +import React, { FC } from "react"; +import { IssuesCount } from "../../../types/types"; +import {useSnykCounterStyle} from './SnykCounterStyle' + + +export type SnykCounterProps = { + issuesCount: IssuesCount; +}; + + +export const SnykCounter: FC = ({ + issuesCount, +}) => { + const classes = useSnykCounterStyle(); + type keys = keyof typeof classes; + + const defaultIssueCount = {critical: 0, high: 0, medium: 0, low: 0} + + const children = Object.entries({...defaultIssueCount, ...issuesCount}).map(([key, value]) => { + + const cssSuffix = value > 0 ? key : 'disabled'; + + return + + {value} + {key.slice(0,1).toUpperCase()} + + }) + + return + {children} + +}