Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
44f8f5b
Init project branch
nateweller Nov 14, 2024
01718e9
Protect: Add Go to Cloud and Scan now button to Protect primary heade…
dkmyta Nov 14, 2024
8937043
Protect: Update Scan and History headers (#40058)
dkmyta Nov 14, 2024
657dbef
Protect: de-emphasize cloud link by using link variant (#40211)
nateweller Nov 18, 2024
ddc735e
Protect: add ShieldIcon component
nateweller Nov 30, 2024
29e05eb
Protect: Add ShieldIcon Component (#40402)
nateweller Dec 5, 2024
f0fcba8
Protect: Integrate ThreatsDataViews Component (#40076)
nateweller Dec 5, 2024
d339c35
Components: Add ScanReport (#40419)
dkmyta Dec 5, 2024
983ef0c
Fix type errors
nateweller Dec 6, 2024
c91afb8
Protect: Refactor AdminSectionHero (#40516)
nateweller Dec 9, 2024
a9763ae
Protect: Update Scan History extension types (#40548)
dkmyta Dec 10, 2024
69648c8
Protect: Add Home page (#40317)
dkmyta Dec 10, 2024
cebc921
Protect: Integrate ScanReport (#40420)
dkmyta Dec 11, 2024
ccf0ed8
Fix duplicate imports
nateweller Dec 15, 2024
02a1f2e
ScanReport: Fix defaultLayout (#40603)
dkmyta Dec 15, 2024
4aff770
Update onboarding popover placement (#40550)
dkmyta Dec 15, 2024
4a9294b
Protect Meets Core: Home Page Scan Report Data Adjustments (#40616)
nateweller Dec 18, 2024
21b7ae1
Scan Report: Align Status Icon (#40617)
nateweller Dec 18, 2024
94732c6
Apply max width to hero content (#40618)
nateweller Dec 18, 2024
f6b6d75
Protect: Hide Scan Report When No Data (#40619)
nateweller Dec 18, 2024
7d5ad6e
Protect: Hide Threats Report When No Data (#40620)
nateweller Dec 18, 2024
f0dfecd
Protect: Update Threat Icons (#40621)
nateweller Dec 18, 2024
51f270f
Protect: fix home page stat card spacing (#40623)
nateweller Dec 18, 2024
fb68c51
Fix ESLint issue
nateweller Jan 1, 2025
3fa38b5
ScanReport: Disable hiding relevant fields (#40602)
dkmyta Jan 2, 2025
cb979da
Use error variant (#40832)
dkmyta Jan 3, 2025
e42e4ef
Protect: Restore HistoryAdminSectionHero (#40551)
dkmyta Jan 4, 2025
e181c22
Protect: Separate scan results and history DataViews (#40845)
dkmyta Jan 14, 2025
aa5b2a3
ThreatsDataViews: Improve responsiveness (#40670)
dkmyta Jan 14, 2025
193070d
ThreatsDataViews: ThreatModal integration (#40202)
dkmyta Jan 14, 2025
5eda38e
Protect Meets Core: Fix "0" rendered by conditional render chain (#40…
nateweller Jan 14, 2025
3af8b55
Fix: add missing return
nateweller Jan 16, 2025
c24ad4d
Fix: reduce of empty array with no initial value
nateweller Jan 16, 2025
94010c9
Fix: hide home report when first protect report scan initializing
nateweller Jan 16, 2025
6b592a9
minor adjustments
nateweller Jan 31, 2025
149ae4c
Update lockfile
nateweller Jan 31, 2025
eb000c5
Remove changes to protect-status package
nateweller Jan 31, 2025
35f474d
Remove changes to badge components, moved to #41450
nateweller Jan 31, 2025
b368b68
Fix type error
nateweller Feb 3, 2025
556e0f5
Fix stories
nateweller Feb 4, 2025
4a8d00b
Fix case where status.core is empty
nateweller Feb 4, 2025
6f73041
Spacing and sizing adjustments
nateweller Feb 5, 2025
5f2b0e8
Restore unintended webpack-cli version change
nateweller Feb 5, 2025
4953bd8
Fix ThreatsDataViews test
nateweller Feb 6, 2025
d3e68cf
changelog
nateweller Feb 9, 2025
138753d
Fix width of hero content
nateweller Feb 9, 2025
c03770c
Improve threat ignore/unignore queries
nateweller Feb 9, 2025
dc202f0
Remove close button from threat details modal actions
nateweller Feb 9, 2025
fa36e2b
Remove unneccessary changes to protect-status package
nateweller Feb 22, 2025
37fc1a0
Fix z-index conflict between Notice and DataViews components
nateweller Feb 22, 2025
1776bd1
Fix ThreatsDataViews title line wrapping
nateweller Feb 22, 2025
332009e
Add alternate 'how to fix it' message when no fixer or fixed in versi…
nateweller Feb 23, 2025
c44edb1
Fix imports and enhance types
nateweller Feb 23, 2025
aa98338
Additional import fixes and type improvements
nateweller Feb 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ThreatsDataViews: ThreatModal integration (#40202)
  • Loading branch information
dkmyta authored and nateweller committed Mar 22, 2025
commit 193070df338de0fed51c907cde20afa5ccdbfebd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Integrates ThreatModal in ThreatsDataViews
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { CONTACT_SUPPORT_URL } from '@automattic/jetpack-scan';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useMemo } from 'react';
import { Button } from '@automattic/jetpack-components';
import styles from './styles.module.scss';
import ThreatNotice from './threat-notice.js';

Expand All @@ -19,14 +22,28 @@ const FixerStateNotice = ( {
}: {
fixerState: { inProgress: boolean; error: boolean; stale: boolean };
} ) => {
const getInterpolatedContent = (): JSX.Element => {
return createInterpolateElement(
__( 'Please try again or <supportLink>contact support</supportLink>.', 'jetpack-components' ),
{
supportLink: <Button variant="link" isExternalLink={ true } href={ CONTACT_SUPPORT_URL } />,
}
);
};

const { status, title, content } = useMemo( () => {
if ( fixerState.error ) {
return {
status: 'error' as const,
title: __( 'An error occurred auto-fixing this threat', 'jetpack-components' ),
content: __(
'Jetpack encountered a filesystem error while attempting to auto-fix this threat. Please try again later or contact support.',
'jetpack-components'
content: (
<>
{ __(
'Jetpack encountered a filesystem error while attempting to auto-fix this threat.',
'jetpack-components'
) }{ ' ' }
{ getInterpolatedContent() }
</>
),
};
}
Expand All @@ -35,9 +52,14 @@ const FixerStateNotice = ( {
return {
status: 'error' as const,
title: __( 'The auto-fixer is taking longer than expected', 'jetpack-components' ),
content: __(
'Jetpack has been attempting to auto-fix this threat for too long, and something may have gone wrong. Please try again later or contact support.',
'jetpack-components'
content: (
<>
{ __(
'Jetpack has been attempting to auto-fix this threat for too long, and something may have gone wrong.',
'jetpack-components'
) }{ ' ' }
{ getInterpolatedContent() }
</>
),
};
}
Expand All @@ -55,7 +77,7 @@ const FixerStateNotice = ( {

return title ? (
<div className={ styles[ 'fixer-notice' ] }>
<ThreatNotice status={ status } title={ title } content={ content } />
<ThreatNotice status={ status } title={ title } content={ content } showActions={ false } />
</div>
) : null;
};
Expand Down
10 changes: 10 additions & 0 deletions projects/js-packages/components/components/threat-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import ThreatFixConfirmation from './threat-fix-confirmation.js';
interface ThreatModalContextType {
closeModal: () => void;
threat: Threat;
isSupportedEnvironment: boolean;
actionToConfirm: string | null;
handleUpgradeClick?: () => void;
userConnectionNeeded: boolean;
handleConnectUser: () => void;
Expand All @@ -28,6 +30,7 @@ export const ThreatModalContext = createContext< ThreatModalContextType | null >
*
* @param {object} props - The props.
* @param {object} props.threat - The threat.
* @param {boolean} props.isSupportedEnvironment - Whether the environment is supported.
* @param {boolean} props.isUserConnected - Whether the user is connected.
* @param {boolean} props.hasConnectedOwner - Whether the user has a connected owner.
* @param {boolean} props.userIsConnecting - Whether the user is connecting.
Expand All @@ -39,11 +42,13 @@ export const ThreatModalContext = createContext< ThreatModalContextType | null >
* @param {Function} props.handleFixThreatClick - The handleFixThreatClick function.
* @param {Function} props.handleIgnoreThreatClick - The handleIgnoreThreatClick function.
* @param {Function} props.handleUnignoreThreatClick - The handleUnignoreThreatClick function.
* @param {string} props.actionToConfirm - The action to confirm.
*
* @return {JSX.Element} The threat modal.
*/
export default function ThreatModal( {
threat,
isSupportedEnvironment,
isUserConnected,
hasConnectedOwner,
userIsConnecting,
Expand All @@ -55,9 +60,11 @@ export default function ThreatModal( {
handleFixThreatClick,
handleIgnoreThreatClick,
handleUnignoreThreatClick,
actionToConfirm,
...modalProps
}: {
threat: Threat;
isSupportedEnvironment: boolean;
isUserConnected: boolean;
hasConnectedOwner: boolean;
userIsConnecting: boolean;
Expand All @@ -69,6 +76,7 @@ export default function ThreatModal( {
handleFixThreatClick?: ( threats: Threat[] ) => void;
handleIgnoreThreatClick?: ( threats: Threat[] ) => void;
handleUnignoreThreatClick?: ( threats: Threat[] ) => void;
actionToConfirm: string | null;
} & React.ComponentProps< typeof Modal > ): JSX.Element {
const userConnectionNeeded = ! isUserConnected || ! hasConnectedOwner;
const siteCredentialsNeeded = ! credentials || credentials.length === 0;
Expand All @@ -89,6 +97,8 @@ export default function ThreatModal( {
value={ {
closeModal: modalProps.onRequestClose,
threat,
isSupportedEnvironment,
actionToConfirm,
handleUpgradeClick,
userConnectionNeeded,
handleConnectUser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ const Base = args => {
const [ isOpen, setIsOpen ] = useState( false );
const onClick = useCallback( () => setIsOpen( true ), [] );
const onRequestClose = useCallback( () => setIsOpen( false ), [] );

return (
<div>
<Button onClick={ onClick }>Open Threat Modal</Button>
{ isOpen ? <ThreatModal { ...args } onRequestClose={ onRequestClose } /> : null }
{ isOpen ? (
<ThreatModal { ...args } onRequestClose={ onRequestClose } actionToConfirm={ 'all' } />
) : null }
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
display: flex;
flex-direction: column;
gap: calc( var( --spacing-base ) * 2 ); // 16px
}

.section .section__toggle {
text-decoration: none;

&:hover {
text-decoration: underline;
}

&__content {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px
align-items: center;
.section__toggle {
text-decoration: none;

&:hover {
text-decoration: underline;
}

&__content {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px
align-items: center;
}
}
}

Expand All @@ -43,6 +43,7 @@
.threat-actions {
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
gap: calc( var( --spacing-base ) * 2 ); // 16px;
}
}
Expand All @@ -55,10 +56,6 @@
&__title {
display: flex;
gap: calc( var( --spacing-base ) / 2 ); // 4px

p {
font-weight: bold;
}
}

&__actions {
Expand All @@ -77,5 +74,4 @@ svg.spinner {
width: 20px;
margin-left: calc( var( --spacing-base ) / 2 ); // 4px;
margin-right: 6px;

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const ThreatActions = (): JSX.Element => {
const {
closeModal,
threat,
actionToConfirm,
handleFixThreatClick,
handleIgnoreThreatClick,
handleUnignoreThreatClick,
Expand Down Expand Up @@ -64,15 +65,17 @@ const ThreatActions = (): JSX.Element => {
) }
{ threat.status === 'current' && (
<>
<Button
isDestructive={ true }
variant="secondary"
onClick={ onIgnoreClick }
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
>
{ __( 'Ignore threat', 'jetpack-components' ) }
</Button>
{ threat.fixable && (
{ [ 'all', 'ignore' ].includes( actionToConfirm ) && (
<Button
isDestructive={ true }
variant="secondary"
onClick={ onIgnoreClick }
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
>
{ __( 'Ignore threat', 'jetpack-components' ) }
</Button>
) }
{ threat.fixable && [ 'all', 'fix' ].includes( actionToConfirm ) && (
<Button
isPrimary
disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { __ } from '@wordpress/i18n';
import { useContext } from 'react';
import ContextualUpgradeTrigger from '../contextual-upgrade-trigger/index.js';
import ThreatActions from './threat-actions.js';
import ThreatFixDetails from './threat-fix-details.js';
import ThreatIgnoreDetails from './threat-ignore-details.js';
import ThreatNotice from './threat-notice.js';
import ThreatSummary from './threat-summary.js';
import ThreatTechnicalDetails from './threat-technical-details.js';
Expand All @@ -13,12 +15,14 @@ import { ThreatModalContext } from './index.js';
* @return {JSX.Element} The rendered fix confirmation.
*/
const ThreatFixConfirmation = () => {
const { userConnectionNeeded, siteCredentialsNeeded } = useContext( ThreatModalContext );
const { actionToConfirm, userConnectionNeeded, siteCredentialsNeeded, handleUpgradeClick } =
useContext( ThreatModalContext );
return (
<>
<ThreatSummary />
<ThreatTechnicalDetails />
<ThreatFixDetails />
{ [ 'all', 'fix' ].includes( actionToConfirm ) && <ThreatFixDetails /> }
{ [ 'all', 'ignore' ].includes( actionToConfirm ) && <ThreatIgnoreDetails /> }
{ siteCredentialsNeeded && userConnectionNeeded && (
<ThreatNotice
title={ 'Additional connections needed' }
Expand Down Expand Up @@ -46,6 +50,16 @@ const ThreatFixConfirmation = () => {
) }
/>
) }
{ handleUpgradeClick && (
<ContextualUpgradeTrigger
description={ __(
'Looking for advanced scan results and one-click fixes?',
'jetpack-components'
) }
cta={ __( 'Upgrade Jetpack now', 'jetpack-components' ) }
onClick={ handleUpgradeClick }
/>
) }
<ThreatActions />
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { getFixerDescription } from '@automattic/jetpack-scan';
import { __, sprintf } from '@wordpress/i18n';
import React, { useMemo, useContext } from 'react';
import ContextualUpgradeTrigger from '../contextual-upgrade-trigger/index.js';
import Text from '../text/index.js';
import styles from './styles.module.scss';
import { ThreatModalContext } from './index.js';
Expand All @@ -12,7 +11,7 @@ import { ThreatModalContext } from './index.js';
* @return {JSX.Element | null} The rendered fix details or null if no fixable details are available.
*/
const ThreatFixDetails = (): JSX.Element => {
const { threat, handleUpgradeClick } = useContext( ThreatModalContext );
const { threat } = useContext( ThreatModalContext );

const title = useMemo( () => {
if ( threat.status === 'fixed' ) {
Expand Down Expand Up @@ -48,16 +47,6 @@ const ThreatFixDetails = (): JSX.Element => {
<div className={ styles.section }>
<Text variant="title-small">{ title }</Text>
<Text>{ fix }</Text>
{ handleUpgradeClick && (
<ContextualUpgradeTrigger
description={ __(
'Looking for advanced scan results and one-click fixes?',
'jetpack-components'
) }
cta={ __( 'Upgrade Jetpack now', 'jetpack-components' ) }
onClick={ handleUpgradeClick }
/>
) }
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useContext } from 'react';
import { Text, Button, getRedirectUrl } from '@automattic/jetpack-components';
import styles from './styles.module.scss';
import { ThreatModalContext } from '.';

const ThreatIgnoreDetails = () => {
const { threat, isSupportedEnvironment } = useContext( ThreatModalContext );

if ( ! threat?.status || [ 'ignored', 'fixed' ].includes( threat.status ) ) {
return null;
}

const codeableURL = getRedirectUrl( 'jetpack-protect-codeable-referral' );

return (
<div className={ styles.section }>
<Text variant="title-small">
{ __( 'Do you really want to ignore this threat?', 'jetpack-components' ) }
</Text>
<Text>
{ __(
'By choosing to ignore this threat, you acknowledge that you have reviewed the detected code. You are accepting the risks of maintaining a potentially malicious or vulnerable file on your site.',
'jetpack-components'
) }{ ' ' }
{ isSupportedEnvironment &&
createInterpolateElement(
__(
'If you are unsure, please request an estimate with <codeableLink>Codeable</codeableLink>.',
'jetpack-components'
),
{
codeableLink: <Button variant="link" isExternalLink={ true } href={ codeableURL } />,
}
) }
</Text>
</div>
);
};

export default ThreatIgnoreDetails;
Loading