diff --git a/projects/js-packages/components/components/threats-data-views/index.tsx b/projects/js-packages/components/components/threats-data-views/index.tsx index 4081fdf475adb..95aca7c2d2b04 100644 --- a/projects/js-packages/components/components/threats-data-views/index.tsx +++ b/projects/js-packages/components/components/threats-data-views/index.tsx @@ -1,4 +1,4 @@ -import { getThreatType, type Threat } from '@automattic/jetpack-scan'; +import { getThreatType, type Threat, type ThreatStatus } from '@automattic/jetpack-scan'; import { __experimentalToggleGroupControl as ToggleGroupControl, // eslint-disable-line @wordpress/no-unsafe-wp-apis __experimentalToggleGroupControlOption as ToggleGroupControlOption, // eslint-disable-line @wordpress/no-unsafe-wp-apis @@ -184,24 +184,54 @@ export default function ThreatsDataViews( { ...defaultLayouts.table, } ); + /** + * Memoized function to determine if a status filter is selected. + * + * @param {Array} threatStatuses - List of threat statuses. + */ + const isStatusFilterSelected = useMemo( + () => ( threatStatuses: ThreatStatus[] ) => + view.filters.some( + filter => + filter.field === 'status' && + Array.isArray( filter.value ) && + filter.value.length === threatStatuses.length && + threatStatuses.every( threatStatus => filter.value.includes( threatStatus ) ) + ), + [ view.filters ] + ); + /** * Compute values from the provided threats data. * + * @member {Array} activeThreatIds - List of active threat IDs. + * @member {Array} historicThreatIds - List of historic threat IDs. * @member {object} extensions - List of unique threat extensions. * @member {object} signatures - List of unique threat signatures. * @member {Array} dataFields - List of unique fields. */ const { + activeThreatIds, + historicThreatIds, extensions, signatures, dataFields, }: { + activeThreatIds: ( string | number )[]; + historicThreatIds: ( string | number )[]; extensions: { value: string; label: string }[]; signatures: { value: string; label: string }[]; dataFields: string[]; } = useMemo( () => { return data.reduce( ( acc, threat ) => { + // Active/Historic Threat IDs + if ( threat.status === 'current' ) { + acc.activeThreatIds.push( threat.id ); + } else { + acc.historicThreatIds.push( threat.id ); + } + // Extensions if ( threat.extension ) { if ( ! acc.extensions.find( ( { value } ) => value === threat.extension.slug ) ) { @@ -231,6 +261,8 @@ export default function ThreatsDataViews( { return acc; }, { + activeThreatIds: [], + historicThreatIds: [], extensions: [], signatures: [], dataFields: [], @@ -440,18 +472,6 @@ export default function ThreatsDataViews( { return result; }, [ dataFields, extensions, signatures, onFixThreats ] ); - const isStatusFilterSelected = ( threatStatuses: ThreatStatus[] ) => - view.filters.some( - filter => - filter.field === 'status' && - Array.isArray( filter.value ) && - filter.value.length === threatStatuses.length && - threatStatuses.every( threatStatus => filter.value.includes( threatStatus ) ) - ); - - const isViewingActiveThreats = isStatusFilterSelected( [ 'current' ] ); - const isViewingHistoricThreats = isStatusFilterSelected( [ 'fixed', 'ignored' ] ); - /** * DataView actions - collection of operations that can be performed upon each record. * @@ -584,22 +604,6 @@ export default function ThreatsDataViews( { [ view ] ); - /** - * Compute the number of active and historic threats. - */ - const activeThreatsCount = useMemo( - () => data.filter( item => item.status === 'current' ).length, - [ data ] - ); - - /** - * Compute the number of active and historic threats. - */ - const historicThreatsCount = useMemo( - () => data.filter( item => [ 'fixed', 'ignored' ].includes( item.status ) ).length, - [ data ] - ); - return ( } diff --git a/projects/js-packages/components/components/threats-data-views/stories/index.stories.tsx b/projects/js-packages/components/components/threats-data-views/stories/index.stories.tsx index 4693c94fdd093..4c4bfff7140e9 100644 --- a/projects/js-packages/components/components/threats-data-views/stories/index.stories.tsx +++ b/projects/js-packages/components/components/threats-data-views/stories/index.stories.tsx @@ -139,7 +139,7 @@ Default.args = { source: '', }, { - id: '7275a176-d579-471a-8492-df8edbdf27de', + id: 105846602, signature: null, title: 'WooCommerce <= 3.4.5 - Authenticated Stored XSS', description: @@ -149,7 +149,7 @@ Default.args = { fixedOn: null, severity: null, fixable: null, - status: null, + status: 'current', filename: null, context: null, source: 'https://wpscan.com/vulnerability/7275a176-d579-471a-8492-df8edbdf27de', @@ -164,8 +164,8 @@ Default.args = { filters: [ { field: 'status', - operator: 'is', - value: 'current', + operator: 'isAny', + value: [ 'current' ], }, ], onFixThreats: () => diff --git a/projects/js-packages/components/components/threats-data-views/styles.module.scss b/projects/js-packages/components/components/threats-data-views/styles.module.scss index 98789b2f794ec..93466166a2cf3 100644 --- a/projects/js-packages/components/components/threats-data-views/styles.module.scss +++ b/projects/js-packages/components/components/threats-data-views/styles.module.scss @@ -31,6 +31,10 @@ border-color: #EDFFEE; svg { - fill: black; + fill: var( --jp-black ); } } + +.toggle-control { + white-space: nowrap; +} \ No newline at end of file