Skip to content

Commit 3fa63a6

Browse files
committed
feat: use state filters in scan vulnerabilities table
1 parent f6b5fdd commit 3fa63a6

File tree

10 files changed

+69
-74
lines changed

10 files changed

+69
-74
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.15-beta-10",
3+
"version": "0.1.18-beta-1",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",

src/Common/Constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,11 @@ export const DATE_TIME_FORMATS = {
518518
DD_MMM_YYYY_HH_MM: 'DD MMM YYYY, hh:mm',
519519
DD_MMM_YYYY: 'DD MMM YYYY',
520520
}
521+
522+
export const VULNERABILITIES_SORT_PRIORITY = {
523+
critical: 1,
524+
high: 2,
525+
medium: 3,
526+
low: 4,
527+
unknown: 5,
528+
}

src/Common/SearchBar/SearchBar.component.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import { ChangeEvent, useCallback, useRef, useState, KeyboardEvent, useEffect } from 'react'
18+
import { ComponentSizeType } from '@Shared/constants'
1819
import { ReactComponent as Search } from '@Icons/ic-search.svg'
1920
import { ReactComponent as Clear } from '@Icons/ic-error-cross.svg'
2021
import { SearchBarProps } from './types'
@@ -65,7 +66,7 @@ const SearchBar = ({
6566
debounceTimeout = 300,
6667
dataTestId = 'search-bar',
6768
noBackgroundAndBorder = false,
68-
height = '32',
69+
componentSize = ComponentSizeType.medium,
6970
}: SearchBarProps) => {
7071
const [showClearButton, setShowClearButton] = useState(!!initialSearchText)
7172
const inputRef = useRef<HTMLInputElement>()
@@ -117,7 +118,7 @@ const SearchBar = ({
117118
return (
118119
<div className={containerClassName}>
119120
<div
120-
className={`search-bar ${noBackgroundAndBorder ? 'dc__no-border dc__no-background dc__hover-n50' : 'bc-n50 en-2 dc__hover-border-n300'} focus-within-border-b5 dc__block w-100 min-w-200 dc__position-rel br-4 bw-1 h-${height}`}
121+
className={`search-bar ${noBackgroundAndBorder ? 'dc__no-border dc__no-background dc__hover-n50' : 'bc-n50 en-2 dc__hover-border-n300'} focus-within-border-b5 dc__block w-100 min-w-200 dc__position-rel br-4 bw-1 ${componentSize === ComponentSizeType.large ? 'h-36' : 'h-32'}`}
121122
>
122123
<Search className="search-bar__icon dc__position-abs icon-color-n6 icon-dim-16" />
123124
<input

src/Common/SearchBar/types.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import { ComponentSizeType } from '@Shared/constants'
18+
1719
export interface SearchBarProps {
1820
/**
1921
* Initial search text
@@ -56,7 +58,7 @@ export interface SearchBarProps {
5658
*/
5759
noBackgroundAndBorder?: boolean
5860
/**
59-
* Height of the Search bar
61+
* Height of the Search bar, Large is 36px and Medium is 32px
6062
*/
61-
height?: '32' | '36'
63+
componentSize?: ComponentSizeType.large | ComponentSizeType.medium
6264
}

src/Common/Security/ScanVulnerabilitiesTable.tsx

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,40 @@ import DOMPurify from 'dompurify'
1818
import { ScanVulnerabilitiesTableProps, VulnerabilityType } from '../Types'
1919
import './scanVulnerabilities.css'
2020
import { SortableTableHeaderCell } from '@Common/SortableTableHeaderCell'
21-
import { SortingOrder } from '@Common/Constants'
22-
import { useMemo, useState } from 'react'
21+
import { useMemo } from 'react'
2322
import { numberComparatorBySortOrder, stringComparatorBySortOrder } from '@Shared/Helpers'
24-
import { SortBy, SortConfig } from './types'
25-
import { sortPriority } from './constants'
23+
import { VulnerabilitiesTableSortKeys } from './types'
24+
import { VULNERABILITIES_SORT_PRIORITY } from '@Common/Constants'
25+
import { useStateFilters } from '@Common/Hooks'
2626

2727
// To be replaced with Scan V2 Modal Table
2828
export default function ScanVulnerabilitiesTable({
2929
vulnerabilities,
3030
hidePolicy,
3131
shouldStick,
3232
}: ScanVulnerabilitiesTableProps) {
33-
const [sortConfig, setSortConfig] = useState<SortConfig>({
34-
sortBy: SortBy.SEVERITY,
35-
sortOrder: SortingOrder.ASC,
33+
const { sortBy, sortOrder, handleSorting } = useStateFilters<VulnerabilitiesTableSortKeys>({
34+
initialSortKey: VulnerabilitiesTableSortKeys.SEVERITY,
3635
})
3736

38-
const sortedVulnerabilities = useMemo(() => {
39-
return vulnerabilities.sort((a, b) => {
40-
if (sortConfig.sortBy === SortBy.PACKAGE) {
41-
return stringComparatorBySortOrder(a.package, b.package, sortConfig.sortOrder)
42-
}
37+
const sortedVulnerabilities = useMemo(
38+
() =>
39+
vulnerabilities.sort((a, b) => {
40+
if (sortBy === VulnerabilitiesTableSortKeys.PACKAGE) {
41+
return stringComparatorBySortOrder(a.package, b.package, sortOrder)
42+
}
4343

44-
return numberComparatorBySortOrder(sortPriority[a.severity], sortPriority[b.severity], sortConfig.sortOrder)
45-
})
46-
}, [sortConfig])
44+
return numberComparatorBySortOrder(
45+
VULNERABILITIES_SORT_PRIORITY[a.severity],
46+
VULNERABILITIES_SORT_PRIORITY[b.severity],
47+
sortOrder,
48+
)
49+
}),
50+
[sortBy, sortOrder, vulnerabilities],
51+
)
4752

48-
const triggerSorting = (sortBy: SortBy) => {
49-
setSortConfig({
50-
sortBy: sortBy,
51-
sortOrder: sortConfig.sortOrder === SortingOrder.ASC ? SortingOrder.DESC : SortingOrder.ASC,
52-
})
53-
}
53+
const triggerSeveritySorting = () => handleSorting(VulnerabilitiesTableSortKeys.SEVERITY)
54+
const triggerPackageSorting = () => handleSorting(VulnerabilitiesTableSortKeys.PACKAGE)
5455

5556
const renderRow = (vulnerability: VulnerabilityType) => (
5657
<tr
@@ -100,26 +101,26 @@ export default function ScanVulnerabilitiesTable({
100101
<table className="security-tab__table">
101102
<tbody>
102103
<tr
103-
className={`security-tab__table-header ${shouldStick ? 'dc__position-sticky bcn-0 dc__zi-4 dc__top-42' : ''}`}
104+
className={`security-tab__table-header ${shouldStick ? 'dc__position-sticky bcn-0 dc__zi-4 dc__top-0' : ''}`}
104105
>
105106
<th className="security-cell-header security-tab__cell-cve">CVE</th>
106107
<th className="security-cell-header security-tab__cell-severity">
107108
<SortableTableHeaderCell
108109
title="Severity"
109-
isSorted={sortConfig.sortBy === SortBy.SEVERITY}
110+
isSorted={sortBy === VulnerabilitiesTableSortKeys.SEVERITY}
110111
isSortable
111-
sortOrder={sortConfig.sortOrder}
112-
triggerSorting={() => triggerSorting(SortBy.SEVERITY)}
112+
sortOrder={sortOrder}
113+
triggerSorting={triggerSeveritySorting}
113114
disabled={false}
114115
/>
115116
</th>
116117
<th className="security-cell-header security-tab__cell-package">
117118
<SortableTableHeaderCell
118119
title="Package"
119-
isSorted={sortConfig.sortBy === SortBy.PACKAGE}
120+
isSorted={sortBy === VulnerabilitiesTableSortKeys.PACKAGE}
120121
isSortable
121-
sortOrder={sortConfig.sortOrder}
122-
triggerSorting={() => triggerSorting(SortBy.PACKAGE)}
122+
sortOrder={sortOrder}
123+
triggerSorting={triggerPackageSorting}
123124
disabled={false}
124125
/>
125126
</th>

src/Common/Security/constants.tsx

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

src/Common/Security/types.tsx

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import { SortingOrder } from '@Common/Constants'
2-
3-
export enum SortBy {
1+
export enum VulnerabilitiesTableSortKeys {
42
SEVERITY = 'severity',
53
PACKAGE = 'package',
64
}
7-
8-
export interface SortConfig {
9-
sortBy: SortBy
10-
sortOrder: SortingOrder
11-
}

src/Common/Types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import React, { ReactNode, CSSProperties } from 'react'
1818
import { Placement } from 'tippy.js'
1919
import { ImageComment, ReleaseTag } from './ImageTags.Types'
2020
import { ACTION_STATE, DEPLOYMENT_WINDOW_TYPE, DockerConfigOverrideType, SortingOrder, TaskErrorObj } from '.'
21-
import { RegistryType } from '../Shared'
21+
import { RegistryType, Severity } from '../Shared'
2222

2323
/**
2424
* Generic response type object with support for overriding the result type
@@ -568,7 +568,7 @@ export enum DeploymentAppTypes {
568568

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

src/Shared/Components/Vulnerabilities/utils.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,39 +15,36 @@
1515
*/
1616

1717
import moment from 'moment'
18+
import { numberComparatorBySortOrder } from '@Shared/Helpers'
1819
import { DATE_TIME_FORMAT_STRING } from '../../constants'
19-
import { ZERO_TIME_STRING, sortCallback } from '../../../Common'
20-
import { LastExecutionResponseType, LastExecutionResultType, Severity } from '../../types'
20+
import { SortingOrder, VULNERABILITIES_SORT_PRIORITY, ZERO_TIME_STRING } from '../../../Common'
21+
import { LastExecutionResponseType, LastExecutionResultType } from '../../types'
22+
23+
export const getSortedVulnerabilities = (vulnerabilities) =>
24+
vulnerabilities.sort((a, b) =>
25+
numberComparatorBySortOrder(
26+
VULNERABILITIES_SORT_PRIORITY[a.severity],
27+
VULNERABILITIES_SORT_PRIORITY[b.severity],
28+
SortingOrder.ASC,
29+
),
30+
)
2131

2232
export const getParsedScanResult = (scanResult): LastExecutionResultType => {
2333
const vulnerabilities = scanResult?.vulnerabilities || []
24-
const critical = vulnerabilities
25-
.filter((v) => v.severity === Severity.CRITICAL)
26-
.sort((a, b) => sortCallback('cveName', a, b))
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)
32-
.sort((a, b) => sortCallback('cveName', a, b))
33-
const low = vulnerabilities.filter((v) => v.severity === Severity.LOW).sort((a, b) => sortCallback('cveName', a, b))
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)
34+
const sortedVulnerabilities = getSortedVulnerabilities(vulnerabilities)
3835

3936
return {
4037
...(scanResult || {}),
4138
lastExecution:
4239
scanResult?.executionTime && scanResult.executionTime !== ZERO_TIME_STRING
43-
? moment(scanResult.executionTime).utc(false).format(DATE_TIME_FORMAT_STRING)
40+
? moment(scanResult.executionTime).format(DATE_TIME_FORMAT_STRING)
4441
: '',
4542
severityCount: {
46-
critical: scanResult?.severityCount?.high,
47-
high: scanResult?.severityCount?.high,
48-
medium: scanResult?.severityCount?.moderate,
49-
low: scanResult?.severityCount?.low,
50-
unknown: scanResult?.severityCount?.unknown,
43+
critical: scanResult?.severityCount?.critical ?? 0,
44+
high: scanResult?.severityCount?.high ?? 0,
45+
medium: scanResult?.severityCount?.medium ?? 0,
46+
low: scanResult?.severityCount?.low ?? 0,
47+
unknown: scanResult?.severityCount?.unknown ?? 0,
5148
},
5249
vulnerabilities: sortedVulnerabilities.map((cve) => ({
5350
name: cve.cveName,

0 commit comments

Comments
 (0)