Skip to content

Commit 148572d

Browse files
committed
feat: add sorting in scan v1 modal
1 parent 9f7d1c9 commit 148572d

File tree

12 files changed

+101
-183
lines changed

12 files changed

+101
-183
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "0.1.14",
3+
"version": "0.1.15-beta-8",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Common/Security/ScanVulnerabilitiesTable.tsx

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,61 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React from 'react'
1817
import DOMPurify from 'dompurify'
1918
import { ScanVulnerabilitiesTableProps, VulnerabilityType } from '../Types'
2019
import './scanVulnerabilities.css'
20+
import { SortableTableHeaderCell } from '@Common/SortableTableHeaderCell'
21+
import { SortingOrder } from '@Common/Constants'
22+
import { useState } from 'react'
23+
import { numberComparatorBySortOrder } from '@Shared/Helpers'
24+
25+
const sortPriority = {
26+
'critical': 1,
27+
'high': 2,
28+
'medium': 3,
29+
'low': 4,
30+
'unknown': 5
31+
}
32+
33+
export enum SortBy {
34+
SEVERITY = 'severity',
35+
PACKAGE = 'package'
36+
}
37+
38+
// To be replaced with Scan V2 Modal Table
39+
export default function ScanVulnerabilitiesTable({
40+
vulnerabilities,
41+
hidePolicy,
42+
shouldStick,
43+
}: ScanVulnerabilitiesTableProps) {
44+
45+
const [sortConfig, setSortConfig] = useState({
46+
sortBy: SortBy.SEVERITY,
47+
sortOrder: SortingOrder.ASC,
48+
})
49+
50+
const sortedVulnerabilities = vulnerabilities.sort((a, b) => {
51+
return numberComparatorBySortOrder(sortPriority[a.severity], sortPriority[b.severity], sortConfig.sortOrder)
52+
})
53+
54+
// const critical = vulnerabilities.filter((v) => v.severity === 'critical')
55+
// const high = vulnerabilities.filter((v) => v.severity === 'high')
56+
// const medium = vulnerabilities.filter((v) => v.severity === 'medium')
57+
// const low = vulnerabilities.filter((v) => v.severity === 'low')
58+
// const unknown = vulnerabilities.filter((v) => v.severity === 'unknown')
59+
60+
// const ascVulnerabilities = [...critical, ...high, ...medium, ...low, ...unknown]
61+
// const descVulnerabilities = [...unknown, ...low, ...medium, ...high, ...critical]
62+
63+
const triggerSeveritySorting = () => setSortConfig({sortBy: SortBy.SEVERITY, sortOrder: sortConfig.sortOrder === SortingOrder.ASC ? SortingOrder.DESC : SortingOrder.DESC })
2164

22-
export default function ScanVulnerabilitiesTable({ vulnerabilities, hidePolicy, shouldStick }: ScanVulnerabilitiesTableProps) {
2365
const renderRow = (vulnerability: VulnerabilityType) => (
2466
<tr
2567
className="dc__security-tab__table-row cursor"
2668
onClick={(e) => {
2769
window.open(`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${vulnerability.name}`, '_blank')
2870
}}
71+
key={vulnerability.name}
2972
>
3073
<td className="security-tab__cell-cve dc__cve-cell">
3174
<a
@@ -37,14 +80,21 @@ export default function ScanVulnerabilitiesTable({ vulnerabilities, hidePolicy,
3780
</a>
3881
</td>
3982
<td className="security-tab__cell-severity">
40-
<span className={`dc__fill-${vulnerability.severity?.toLowerCase()}`}>{vulnerability.severity}</span>
83+
<span
84+
className={`severity-chip severity-chip--${vulnerability.severity?.toLowerCase()} dc__capitalize dc__w-fit-content`}
85+
>
86+
{vulnerability.severity}
87+
</span>
4188
</td>
4289
<td className="security-tab__cell-package">{vulnerability.package}</td>
4390
{/* QUERY: Do we need to add DOMPurify at any other key for this table as well? */}
4491
<td className="security-tab__cell-current-ver">
45-
<p className="m-0 cn-9 fs-13 fw-4" dangerouslySetInnerHTML={{
46-
__html: DOMPurify.sanitize(vulnerability.version)
47-
}} />
92+
<p
93+
className="m-0 cn-9 fs-13 fw-4"
94+
dangerouslySetInnerHTML={{
95+
__html: DOMPurify.sanitize(vulnerability.version),
96+
}}
97+
/>
4898
</td>
4999
<td className="security-tab__cell-fixed-ver">{vulnerability.fixedVersion}</td>
50100
{!hidePolicy && (
@@ -60,17 +110,26 @@ export default function ScanVulnerabilitiesTable({ vulnerabilities, hidePolicy,
60110
return (
61111
<table className="security-tab__table">
62112
<tbody>
63-
<tr className={`security-tab__table-header ${shouldStick ? 'dc__position-sticky bcn-0 dc__zi-4 dc__top-0' : ''}`}>
113+
<tr
114+
className={`security-tab__table-header ${shouldStick ? 'dc__position-sticky bcn-0 dc__zi-4 dc__top-42' : ''}`}
115+
>
64116
<th className="security-cell-header security-tab__cell-cve">CVE</th>
65-
<th className="security-cell-header security-tab__cell-severity">Severity</th>
117+
<th className="security-cell-header security-tab__cell-severity">
118+
<SortableTableHeaderCell
119+
title="Severity"
120+
isSorted
121+
isSortable
122+
sortOrder={sortConfig.sortOrder}
123+
triggerSorting={triggerSeveritySorting}
124+
disabled={false}
125+
/>
126+
</th>
66127
<th className="security-cell-header security-tab__cell-package">Package</th>
67128
<th className="security-cell-header security-tab__cell-current-ver">Current Version</th>
68129
<th className="security-cell-header security-tab__cell-fixed-ver">Fixed In Version</th>
69-
{!hidePolicy && (
70-
<th className="security-cell-header security-tab__cell-policy">Policy</th>
71-
)}
130+
{!hidePolicy && <th className="security-cell-header security-tab__cell-policy">Policy</th>}
72131
</tr>
73-
{vulnerabilities.map((vulnerability) => renderRow(vulnerability))}
132+
{sortedVulnerabilities.map((vulnerability) => renderRow(vulnerability))}
74133
</tbody>
75134
</table>
76135
)

src/Common/SegmentedBarChart/SegmentedBarChart.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,9 @@ const SegmentedBarChart: React.FC<SegmentedBarChartProps> = ({
2626
labelClassName,
2727
}) => {
2828
const total = entities.reduce((sum, entity) => entity.value + sum, 0)
29+
const filteredEntities = entities.filter((entity) => entity.value)
2930

30-
const calcSegmentWidth = (entity: Entity) => {
31-
if (!entity.value) {
32-
return '100%'
33-
}
34-
return `${(entity.value / total) * 100}%`
35-
}
31+
const calcSegmentWidth = (entity: Entity) => `${(entity.value / total) * 100}%`
3632

3733
return (
3834
<div className={`flexbox-col w-100 dc__gap-12 ${rootClassName}`}>
@@ -50,7 +46,7 @@ const SegmentedBarChart: React.FC<SegmentedBarChartProps> = ({
5046
))}
5147
</div>
5248
<div className="flexbox dc__gap-2">
53-
{entities?.map((entity, index, map) => (
49+
{filteredEntities?.map((entity, index, map) => (
5450
<div
5551
key={entity.label}
5652
className={`h-8 ${index === 0 ? 'dc__left-radius-4' : ''} ${

src/Common/Types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ export enum DeploymentAppTypes {
568568

569569
export interface VulnerabilityType {
570570
name: string
571-
severity: 'CRITICAL' | 'MODERATE' | 'LOW'
571+
severity: 'critical' | 'high' | 'medium' | 'low' | 'unknown'
572572
package: string
573573
version: string
574574
fixedVersion: string

src/Shared/Components/ScannedObjectBar/ScannedObjectBar.tsx

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/Shared/Components/ScannedObjectBar/index.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/Shared/Components/ScannedObjectBar/styles.scss

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/Shared/Components/ScannedObjectBar/types.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/Shared/Components/Vulnerabilities/utils.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,17 @@ export const getParsedScanResult = (scanResult): LastExecutionResultType => {
2424
const critical = vulnerabilities
2525
.filter((v) => v.severity === Severity.CRITICAL)
2626
.sort((a, b) => sortCallback('cveName', a, b))
27-
const moderate = vulnerabilities
28-
.filter((v) => v.severity === Severity.MODERATE)
27+
const high = vulnerabilities
28+
.filter((v) => v.severity === Severity.HIGH)
29+
.sort((a, b) => sortCallback('cveName', a, b))
30+
const medium = vulnerabilities
31+
.filter((v) => v.severity === Severity.MEDIUM)
2932
.sort((a, b) => sortCallback('cveName', a, b))
3033
const low = vulnerabilities.filter((v) => v.severity === Severity.LOW).sort((a, b) => sortCallback('cveName', a, b))
31-
const sortedVulnerabilities = critical.concat(moderate, low)
34+
const unknown = vulnerabilities
35+
.filter((v) => v.severity === Severity.UNKNOWN)
36+
.sort((a, b) => sortCallback('cveName', a, b))
37+
const sortedVulnerabilities = critical.concat(medium, low, high, unknown)
3238

3339
return {
3440
...(scanResult || {}),
@@ -38,8 +44,10 @@ export const getParsedScanResult = (scanResult): LastExecutionResultType => {
3844
: '',
3945
severityCount: {
4046
critical: scanResult?.severityCount?.high,
41-
moderate: scanResult?.severityCount?.moderate,
47+
high: scanResult?.severityCount?.high,
48+
medium: scanResult?.severityCount?.moderate,
4249
low: scanResult?.severityCount?.low,
50+
unknown: scanResult?.severityCount?.unknown,
4351
},
4452
vulnerabilities: sortedVulnerabilities.map((cve) => ({
4553
name: cve.cveName,

0 commit comments

Comments
 (0)