Skip to content

Commit 9d62eff

Browse files
committed
feat: secure state in ci security
1 parent b3e3adf commit 9d62eff

File tree

9 files changed

+71
-31
lines changed

9 files changed

+71
-31
lines changed

src/Common/SegmentedBarChart/SegmentedBarChart.tsx

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const SegmentedBarChart: React.FC<SegmentedBarChartProps> = ({
2525
countClassName,
2626
labelClassName,
2727
isProportional,
28+
swapLegendAndBar = false,
2829
}) => {
2930
const total = entities.reduce((sum, entity) => entity.value + sum, 0)
3031
const filteredEntities = entities.filter((entity) => entity.value)
@@ -70,20 +71,39 @@ const SegmentedBarChart: React.FC<SegmentedBarChartProps> = ({
7071
return null
7172
}
7273

74+
const renderLegend = () => (
75+
<div className={`flexbox flex-wrap dc__row-gap-2 ${isProportional ? 'dc__gap-24' : 'dc__gap-16'}`}>
76+
{renderContent()}
77+
</div>
78+
)
79+
80+
const renderBar = () => (
81+
<div className="flexbox dc__gap-2">
82+
{filteredEntities?.map((entity, index, map) => (
83+
<div
84+
key={entity.label}
85+
className={`h-8 ${index === 0 ? 'dc__left-radius-4' : ''} ${
86+
index === map.length - 1 ? 'dc__right-radius-4' : ''
87+
}`}
88+
style={{ backgroundColor: entity.color, width: calcSegmentWidth(entity) }}
89+
/>
90+
))}
91+
</div>
92+
)
93+
7394
return (
7495
<div className={`flexbox-col w-100 dc__gap-12 ${rootClassName}`}>
75-
<div className={`flexbox ${isProportional ? 'dc__gap-24' : 'dc__gap-16'}`}>{renderContent()}</div>
76-
<div className="flexbox dc__gap-2">
77-
{filteredEntities?.map((entity, index, map) => (
78-
<div
79-
key={entity.label}
80-
className={`h-8 ${index === 0 ? 'dc__left-radius-4' : ''} ${
81-
index === map.length - 1 ? 'dc__right-radius-4' : ''
82-
}`}
83-
style={{ backgroundColor: entity.color, width: calcSegmentWidth(entity) }}
84-
/>
85-
))}
86-
</div>
96+
{swapLegendAndBar ? (
97+
<>
98+
{renderBar()}
99+
{renderLegend()}
100+
</>
101+
) : (
102+
<>
103+
{renderLegend()}
104+
{renderBar()}
105+
</>
106+
)}
87107
</div>
88108
)
89109
}

src/Common/SegmentedBarChart/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ export interface SegmentedBarChartProps {
2626
countClassName?: string
2727
labelClassName?: string
2828
isProportional?: boolean
29+
swapLegendAndBar?: boolean
2930
}

src/Shared/Components/Security/SecurityDetailsCards/SecurityCard.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,7 @@ import './securityCard.scss'
99
import { getTotalSeverities } from '../utils'
1010
import { SECURITY_CONFIG } from '../constants'
1111

12-
const SecurityCard = ({
13-
category,
14-
subCategory,
15-
severityCount = {},
16-
handleCardClick,
17-
rootClassName = '',
18-
}: SecurityCardProps) => {
12+
const SecurityCard = ({ category, subCategory, severityCount = {}, handleCardClick }: SecurityCardProps) => {
1913
const totalCount = getTotalSeverities(severityCount)
2014

2115
const hasThreats: boolean = !!totalCount
@@ -61,7 +55,7 @@ const SecurityCard = ({
6155

6256
return (
6357
<div
64-
className={`${rootClassName} w-100 bcn-0 p-20 flexbox-col dc__gap-16 br-8 dc__border security-card security-card${hasThreats ? '--threat' : '--secure'}`}
58+
className={`w-100 bcn-0 p-20 flexbox-col dc__gap-16 br-8 dc__border security-card security-card${hasThreats ? '--threat' : '--secure'}`}
6559
role="button"
6660
tabIndex={0}
6761
onClick={handleCardClick}
@@ -87,11 +81,12 @@ const SecurityCard = ({
8781
entities={entities}
8882
labelClassName="fs-13 fw-4 lh-20 cn-9"
8983
countClassName="fs-13 fw-6 lh-20 cn-7"
84+
swapLegendAndBar
9085
/>
9186
) : (
9287
<div className="bcn-1 br-4 h-8" />
9388
)}
94-
{subtitle && <span>{subtitle}</span>}
89+
{subtitle && <span className="cn-9 fs-13">{subtitle}</span>}
9590
</div>
9691
</div>
9792
)

src/Shared/Components/Security/SecurityDetailsCards/SecurityDetailsCards.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,35 @@
11
import { ScannedByToolModal } from '@Shared/Components/ScannedByToolModal'
2-
import { SCAN_TOOL_ID_CLAIR, SCAN_TOOL_ID_TRIVY } from '@Shared/constants'
2+
import { EMPTY_STATE_STATUS, SCAN_TOOL_ID_CLAIR, SCAN_TOOL_ID_TRIVY } from '@Shared/constants'
33
import { useState } from 'react'
4+
import { GenericEmptyState } from '@Common/index'
5+
import { ReactComponent as NoVulnerability } from '@Icons/ic-vulnerability-not-found.svg'
46
import SecurityCard from './SecurityCard'
57
import { CATEGORIES, SecurityModalStateType, SUB_CATEGORIES } from '../SecurityModal/types'
68
import { SecurityCardProps, SecurityDetailsCardsProps } from './types'
79
import { SecurityModal } from '../SecurityModal'
810
import { DEFAULT_SECURITY_MODAL_IMAGE_STATE } from '../SecurityModal/constants'
911
import { ScanCategories, ScanSubCategories } from '../types'
12+
import { getSecurityConfig, getCompiledSecurityThreats, getTotalSeverities } from '../utils'
1013
import './securityCard.scss'
11-
import { getSecurityConfig } from '../utils'
1214

1315
const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps) => {
1416
const [showSecurityModal, setShowSecurityModal] = useState<boolean>(false)
1517
const [modalState, setModalState] = useState<SecurityModalStateType>(DEFAULT_SECURITY_MODAL_IMAGE_STATE)
1618
const { imageScan, codeScan, kubernetesManifest } = scanResult
1719

20+
const scanThreats = getCompiledSecurityThreats(scanResult)
21+
const threatCount = getTotalSeverities(scanThreats)
22+
23+
if (!threatCount) {
24+
return (
25+
<GenericEmptyState
26+
SvgImage={NoVulnerability}
27+
title={EMPTY_STATE_STATUS.CI_DEATILS_NO_VULNERABILITY_FOUND.TITLE}
28+
subTitle={EMPTY_STATE_STATUS.CI_DEATILS_NO_VULNERABILITY_FOUND.SUBTITLE}
29+
/>
30+
)
31+
}
32+
1833
const SECURITY_CONFIG = getSecurityConfig({
1934
imageScan: !!imageScan,
2035
codeScan: !!codeScan,
@@ -58,7 +73,7 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
5873

5974
return (
6075
<>
61-
<div className="flexbox-col dc__gap-20">
76+
<div className="flexbox-col dc__gap-20 mw-600 dc__mxw-1200">
6277
{Object.keys(SECURITY_CONFIG).map((category: ScanCategories) => (
6378
<div className="flexbox-col dc__gap-12" key={category}>
6479
<div className="flexbox dc__content-space pb-8 dc__border-bottom-n1">

src/Shared/Components/Security/SecurityDetailsCards/types.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export interface SecurityCardProps {
66
subCategory: ScanSubCategories
77
severityCount: Partial<Record<SeveritiesDTO, number>>
88
handleCardClick: () => void
9-
rootClassName?: string
109
}
1110

1211
export interface SecurityDetailsCardsProps extends Pick<SecurityModalPropsType, 'Sidebar'> {

src/Shared/Components/Security/SecurityModal/SecurityModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
stopPropagation,
1313
VisibleModal2,
1414
} from '@Common/index'
15-
import { ReactComponent as ICClose } from '@Icons/ic-cross.svg'
15+
import { ReactComponent as ICClose } from '@Icons/ic-close.svg'
1616
import { ReactComponent as ICBack } from '@Icons/ic-caret-left-small.svg'
1717
import { Button, ButtonStyleType, ButtonVariantType } from '@Shared/Components/Button'
1818
import { ComponentSizeType } from '@Shared/constants'

src/Shared/Components/Security/Vulnerabilities/Vulnerabilities.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const Vulnerabilities = ({
4949

5050
if (scanResultLoading) {
5151
return (
52-
<div className="security-tab-empty">
52+
<div className="security-tab-empty bcn-1">
5353
<Progressing />
5454
</div>
5555
)
@@ -97,7 +97,6 @@ const Vulnerabilities = ({
9797
subCategory={SUB_CATEGORIES.VULNERABILITIES}
9898
severityCount={scanResultResponse?.result?.imageScan?.vulnerability?.summary?.severities}
9999
handleCardClick={handleCardClick}
100-
rootClassName="w-100-imp"
101100
/>
102101
{showSecurityModal && (
103102
<SecurityModal

src/Shared/Components/Security/utils.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const getSecurityConfig = ({
2727
}),
2828
})
2929

30-
export const getSecurityThreatsArray = (scanResult: ScanResultDTO): Partial<Record<SeveritiesDTO, number>>[] => {
30+
export const getCompiledSecurityThreats = (scanResult: ScanResultDTO): Partial<Record<SeveritiesDTO, number>> => {
3131
const { imageScan, codeScan, kubernetesManifest } = scanResult
3232
const DYNAMIC_SECURITY_CONFIG = getSecurityConfig({
3333
imageScan: !!imageScan,
@@ -47,5 +47,16 @@ export const getSecurityThreatsArray = (scanResult: ScanResultDTO): Partial<Reco
4747
})
4848
})
4949

50-
return threatsArray
50+
const scanThreats: Partial<Record<SeveritiesDTO, number>> = threatsArray.reduce((acc, curr) => {
51+
Object.keys(curr).forEach((key) => {
52+
if (acc[key]) {
53+
acc[key] += curr[key]
54+
} else {
55+
acc[key] = curr[key]
56+
}
57+
})
58+
return acc
59+
}, {})
60+
61+
return scanThreats
5162
}

src/Shared/constants.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const EMPTY_STATE_STATUS = {
142142
},
143143
CI_DEATILS_NO_VULNERABILITY_FOUND: {
144144
TITLE: 'You’re secure!',
145-
SUBTITLE: 'No security vulnerability found for this image.',
145+
SUBTITLE: 'No security vulnerability found.',
146146
},
147147
CI_DETAILS_IMAGE_SCANNED_DISABLED: 'Go to build pipeline configurations and enable ’Scan for vulnerabilities’',
148148
CI_DETAILS_IMAGE_NOT_SCANNED: {

0 commit comments

Comments
 (0)