From f1488e77a2e183d13da1a74cde6c4df0d544a112 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Sat, 21 Dec 2024 13:00:06 -0800 Subject: [PATCH] Add threat selection in bulk view --- .../components/threats-modal/index.tsx | 13 +-- .../threats-modal/threat-fix-confirmation.tsx | 80 +++++++++++++------ .../threats-modal/threat-notice.tsx | 6 +- 3 files changed, 66 insertions(+), 33 deletions(-) diff --git a/projects/js-packages/components/components/threats-modal/index.tsx b/projects/js-packages/components/components/threats-modal/index.tsx index 69b1eb449b03c..3b31f05204a31 100644 --- a/projects/js-packages/components/components/threats-modal/index.tsx +++ b/projects/js-packages/components/components/threats-modal/index.tsx @@ -1,7 +1,7 @@ import { getLabel, type Threat } from '@automattic/jetpack-scan'; import { Modal } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { createContext } from 'react'; +import { createContext, useState, Dispatch, SetStateAction } from 'react'; import Text from '../text'; import ThreatSeverityBadge from '../threat-severity-badge'; import styles from './styles.module.scss'; @@ -9,7 +9,8 @@ import ThreatFixConfirmation from './threat-fix-confirmation'; interface ThreatModalContextType { closeModal: () => void; - currentThreats: Threat[]; + threatsList: Threat[]; + setThreatsList: Dispatch< SetStateAction< Threat[] > >; isBulk: boolean; actionToConfirm: string | null; isSupportedEnvironment: boolean; @@ -82,8 +83,9 @@ export default function ThreatsModal( { } & React.ComponentProps< typeof Modal > ): JSX.Element { const userConnectionNeeded = ! isUserConnected || ! hasConnectedOwner; const siteCredentialsNeeded = ! credentials || credentials.length === 0; - const isBulk = currentThreats.length > 1; - const firstThreat = currentThreats[ 0 ]; + const [ threatsList, setThreatsList ] = useState< Threat[] >( currentThreats ); + const isBulk = threatsList.length > 1; + const firstThreat = threatsList[ 0 ]; return ( { const [ isSm ] = useBreakpointMatch( [ 'sm', 'lg' ], [ null, '<' ] ); - const { currentThreats, isBulk, handleUpgradeClick } = useContext( ThreatsModalContext ); + const { threatsList, isBulk, handleUpgradeClick } = useContext( ThreatsModalContext ); - const [ selectedThreats, setSelectedThreats ] = useState( currentThreats ); + const [ selectedThreats, setSelectedThreats ] = useState( threatsList ); const handleToggleThreat = useCallback( ( threat: Threat, isChecked: boolean ) => { setSelectedThreats( prevSelectedThreats => { @@ -41,34 +41,64 @@ const ThreatFixConfirmation = () => { // Memoize toggle handlers for each threat const toggleHandlers = useMemo( () => { - return currentThreats.reduce( ( handlers, threat ) => { + return threatsList.reduce( ( handlers, threat ) => { handlers[ threat.id ] = isChecked => handleToggleThreat( threat, isChecked ); return handlers; }, {} ); - }, [ currentThreats, handleToggleThreat ] ); + }, [ threatsList, handleToggleThreat ] ); - const renderBulkThreat = threat => ( -
-
- { ! isSm && ( -
- + const viewIndividualThreat = useCallback( threat => { + console.log( threat ); + }, [] ); + + const handleThreatClick = useCallback( + threat => () => { + viewIndividualThreat( threat ); + }, + [ viewIndividualThreat ] + ); + + const handleKeyPress = useCallback( + threat => event => { + if ( event.key === 'Enter' ) { + viewIndividualThreat( threat ); + } + }, + [ viewIndividualThreat ] + ); + + const renderBulkThreat = threat => { + return ( +
+
+
+ { ! isSm && ( +
+ +
+ ) } +
+ { getLabel( threat ) } + +
- ) } -
- { getLabel( threat ) } - + { !! threat.severity && } + selectedThreat.id === threat.id ) } + onChange={ toggleHandlers[ threat.id ] } + />
- { !! threat.severity && } - selectedThreat.id === threat.id ) } - onChange={ toggleHandlers[ threat.id ] } - /> -
- ); + ); + }; const renderIndividualThreat = threat => (
@@ -84,10 +114,10 @@ const ThreatFixConfirmation = () => { { isBulk ? ( <> { 'Jetpack will be fixing the selected threats:' } -
{ currentThreats.map( threat => renderBulkThreat( threat ) ) }
+
{ threatsList.map( threat => renderBulkThreat( threat ) ) }
) : ( - currentThreats.map( threat => renderIndividualThreat( threat ) ) + threatsList.map( threat => renderIndividualThreat( threat ) ) ) } { handleUpgradeClick && ( diff --git a/projects/js-packages/components/components/threats-modal/threat-notice.tsx b/projects/js-packages/components/components/threats-modal/threat-notice.tsx index 112bf99a6fab3..06b988e22ccc7 100644 --- a/projects/js-packages/components/components/threats-modal/threat-notice.tsx +++ b/projects/js-packages/components/components/threats-modal/threat-notice.tsx @@ -29,7 +29,7 @@ const ThreatNotice = ( { showActions?: boolean; } ): JSX.Element => { const { - currentThreats, + threatsList, isBulk, userConnectionNeeded, userIsConnecting, @@ -40,8 +40,8 @@ const ThreatNotice = ( { } = useContext( ThreatsModalContext ); if ( - currentThreats.every( threat => ! threat?.status ) || - ( ! isBulk && currentThreats[ 0 ].status === 'fixed' ) + threatsList.every( threat => ! threat?.status ) || + ( ! isBulk && threatsList[ 0 ].status === 'fixed' ) ) { return null; }