@automattic/jetpack-components 0.70.1 → 0.72.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/build/components/dot-pager/index.d.ts +14 -0
  3. package/build/components/dot-pager/index.js +52 -0
  4. package/build/components/number-control/index.js +1 -1
  5. package/build/components/split-button/index.js +2 -2
  6. package/build/components/swipeable/index.d.ts +12 -0
  7. package/build/components/swipeable/index.js +293 -0
  8. package/build/index.d.ts +2 -3
  9. package/build/index.js +2 -3
  10. package/components/dot-pager/README.md +20 -0
  11. package/components/dot-pager/index.tsx +147 -0
  12. package/components/dot-pager/style.scss +80 -0
  13. package/components/number-control/index.jsx +3 -1
  14. package/components/split-button/index.tsx +14 -12
  15. package/components/split-button/style.module.scss +5 -0
  16. package/components/swipeable/README.md +34 -0
  17. package/components/swipeable/index.tsx +425 -0
  18. package/components/swipeable/style.scss +34 -0
  19. package/index.ts +2 -3
  20. package/package.json +1 -3
  21. package/build/components/threat-fixer-button/index.d.ts +0 -17
  22. package/build/components/threat-fixer-button/index.js +0 -56
  23. package/build/components/threat-severity-badge/index.d.ts +0 -4
  24. package/build/components/threat-severity-badge/index.js +0 -13
  25. package/build/components/threats-data-views/constants.d.ts +0 -33
  26. package/build/components/threats-data-views/constants.js +0 -37
  27. package/build/components/threats-data-views/index.d.ts +0 -30
  28. package/build/components/threats-data-views/index.js +0 -413
  29. package/build/components/threats-data-views/threats-status-toggle-group-control.d.ts +0 -16
  30. package/build/components/threats-data-views/threats-status-toggle-group-control.js +0 -95
  31. package/components/threat-fixer-button/index.tsx +0 -101
  32. package/components/threat-fixer-button/styles.module.scss +0 -16
  33. package/components/threat-modal/fixer-state-notice.tsx +0 -63
  34. package/components/threat-modal/index.tsx +0 -109
  35. package/components/threat-modal/styles.module.scss +0 -81
  36. package/components/threat-modal/threat-actions.tsx +0 -93
  37. package/components/threat-modal/threat-fix-confirmation.tsx +0 -54
  38. package/components/threat-modal/threat-fix-details.tsx +0 -65
  39. package/components/threat-modal/threat-notice.tsx +0 -84
  40. package/components/threat-modal/threat-summary.tsx +0 -30
  41. package/components/threat-modal/threat-technical-details.tsx +0 -67
  42. package/components/threat-severity-badge/index.tsx +0 -26
  43. package/components/threat-severity-badge/styles.module.scss +0 -27
  44. package/components/threats-data-views/constants.ts +0 -49
  45. package/components/threats-data-views/index.tsx +0 -534
  46. package/components/threats-data-views/styles.module.scss +0 -40
  47. package/components/threats-data-views/threats-status-toggle-group-control.tsx +0 -158
@@ -1,95 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { __experimentalToggleGroupControl as ToggleGroupControl, // eslint-disable-line @wordpress/no-unsafe-wp-apis
3
- __experimentalToggleGroupControlOption as ToggleGroupControlOption, // eslint-disable-line @wordpress/no-unsafe-wp-apis
4
- } from '@wordpress/components';
5
- import { useMemo, useCallback } from '@wordpress/element';
6
- import { __, sprintf } from '@wordpress/i18n';
7
- import styles from './styles.module.scss';
8
- /**
9
- * ToggleGroupControl component for filtering threats by status.
10
- * @param {object} props - Component props.
11
- * @param { Threat[]} props.data - Threats data.
12
- * @param { View } props.view - The current view.
13
- * @param { Function } props.onChangeView - Callback function to handle view changes.
14
- * @return {JSX.Element|null} The component or null.
15
- */
16
- export default function ThreatsStatusToggleGroupControl({ data, view, onChangeView, }) {
17
- /**
18
- * Compute values from the provided threats data.
19
- *
20
- * @member {number} activeThreatsCount - Count of active threats.
21
- * @member {number} historicThreatsCount - Count of historic threats.
22
- */
23
- const { activeThreatsCount, historicThreatsCount, } = useMemo(() => {
24
- return data.reduce((acc, threat) => {
25
- if (threat.status) {
26
- if (threat.status === 'current') {
27
- acc.activeThreatsCount++;
28
- }
29
- else {
30
- acc.historicThreatsCount++;
31
- }
32
- }
33
- return acc;
34
- }, {
35
- activeThreatsCount: 0,
36
- historicThreatsCount: 0,
37
- });
38
- }, [data]);
39
- /**
40
- * Callback function to handle the status change filter.
41
- *
42
- * @param {string} newStatus - The new status filter value.
43
- */
44
- const onStatusFilterChange = useCallback((newStatus) => {
45
- const updatedFilters = view.filters.filter(filter => filter.field !== 'status');
46
- if (newStatus === 'active') {
47
- updatedFilters.push({
48
- field: 'status',
49
- operator: 'isAny',
50
- value: ['current'],
51
- });
52
- }
53
- else if (newStatus === 'historic') {
54
- updatedFilters.push({
55
- field: 'status',
56
- operator: 'isAny',
57
- value: ['fixed', 'ignored'],
58
- });
59
- }
60
- onChangeView({
61
- ...view,
62
- filters: updatedFilters,
63
- });
64
- }, [view, onChangeView]);
65
- /**
66
- * Memoized function to determine if a status filter is selected.
67
- *
68
- * @param {Array} threatStatuses - List of threat statuses.
69
- */
70
- const isStatusFilterSelected = useMemo(() => (threatStatuses) => view.filters.some(filter => filter.field === 'status' &&
71
- Array.isArray(filter.value) &&
72
- filter.value.length === threatStatuses.length &&
73
- threatStatuses.every(threatStatus => filter.value.includes(threatStatus))), [view.filters]);
74
- const selectedValue = useMemo(() => {
75
- if (isStatusFilterSelected(['current'])) {
76
- return 'active';
77
- }
78
- if (isStatusFilterSelected(['fixed', 'ignored'])) {
79
- return 'historic';
80
- }
81
- return '';
82
- }, [isStatusFilterSelected]);
83
- if (!(activeThreatsCount + historicThreatsCount)) {
84
- return null;
85
- }
86
- try {
87
- return (_jsx("div", { children: _jsx("div", { className: styles['toggle-group-control'], children: _jsxs(ToggleGroupControl, { value: selectedValue, onChange: onStatusFilterChange, isBlock: true, hideLabelFromVision: true, __nextHasNoMarginBottom: true, __next40pxDefaultSize: true, children: [_jsx(ToggleGroupControlOption, { value: "active", label: sprintf(
88
- /* translators: %d: number of active threats */ __('Active threats (%d)', 'jetpack-components'), activeThreatsCount) }), _jsx(ToggleGroupControlOption, { value: "historic", label: sprintf(
89
- /* translators: %d: number of historic threats */
90
- __('History (%d)', 'jetpack-components'), historicThreatsCount) })] }) }) }));
91
- }
92
- catch {
93
- return null;
94
- }
95
- }
@@ -1,101 +0,0 @@
1
- import {
2
- type Threat,
3
- getFixerState,
4
- getFixerAction,
5
- getFixerDescription,
6
- } from '@automattic/jetpack-scan';
7
- import { Tooltip } from '@wordpress/components';
8
- import { useCallback, useMemo } from '@wordpress/element';
9
- import { __ } from '@wordpress/i18n';
10
- import { Button } from '@automattic/jetpack-components';
11
- import styles from './styles.module.scss';
12
-
13
- /**
14
- * Threat Fixer Button component.
15
- *
16
- * @param {object} props - Component props.
17
- * @param {object} props.threat - The threat.
18
- * @param {Function} props.onClick - The onClick function.
19
- * @param {string} props.className - The className.
20
- *
21
- * @return {JSX.Element} The component.
22
- */
23
- export default function ThreatFixerButton( {
24
- threat,
25
- className,
26
- onClick,
27
- }: {
28
- threat: Threat;
29
- onClick: ( items: Threat[] ) => void;
30
- className?: string;
31
- } ): JSX.Element {
32
- const fixerState = useMemo( () => {
33
- return getFixerState( threat.fixer );
34
- }, [ threat.fixer ] );
35
-
36
- const tooltipText = useMemo( () => {
37
- if ( ! threat.fixable ) {
38
- return null;
39
- }
40
-
41
- if ( fixerState.error ) {
42
- return __( 'An error occurred auto-fixing this threat.', 'jetpack-components' );
43
- }
44
-
45
- if ( fixerState.stale ) {
46
- return __( 'The auto-fixer is taking longer than expected.', 'jetpack-components' );
47
- }
48
-
49
- if ( fixerState.inProgress ) {
50
- return __( 'An auto-fixer is in progress.', 'jetpack-components' );
51
- }
52
-
53
- return getFixerDescription( threat );
54
- }, [ threat, fixerState ] );
55
-
56
- const buttonText = useMemo( () => {
57
- if ( ! threat.fixable ) {
58
- return null;
59
- }
60
-
61
- if ( fixerState.error ) {
62
- return __( 'Error', 'jetpack-components' );
63
- }
64
-
65
- return getFixerAction( threat );
66
- }, [ threat, fixerState.error ] );
67
-
68
- const handleClick = useCallback(
69
- ( event: React.MouseEvent ) => {
70
- event.stopPropagation();
71
- onClick( [ threat ] );
72
- },
73
- [ onClick, threat ]
74
- );
75
-
76
- if ( ! threat.fixable ) {
77
- return null;
78
- }
79
-
80
- return (
81
- <div>
82
- <Tooltip className={ styles.tooltip } text={ tooltipText }>
83
- <Button
84
- size="small"
85
- weight="regular"
86
- variant="secondary"
87
- onClick={ handleClick }
88
- children={ buttonText }
89
- className={ className }
90
- isLoading={ fixerState.inProgress }
91
- isDestructive={
92
- ( threat.fixable && threat.fixable.fixer === 'delete' ) ||
93
- fixerState.error ||
94
- fixerState.stale
95
- }
96
- style={ { minWidth: '72px' } }
97
- />
98
- </Tooltip>
99
- </div>
100
- );
101
- }
@@ -1,16 +0,0 @@
1
- .support-link {
2
- color: inherit;
3
-
4
- &:focus,
5
- &:hover {
6
- color: inherit;
7
- box-shadow: none;
8
- }
9
- }
10
-
11
- .tooltip {
12
- margin-top: var( --spacing-base ) ;
13
- max-width: 240px;
14
- border-radius: 4px;
15
- text-align: left;
16
- }
@@ -1,63 +0,0 @@
1
- import { __ } from '@wordpress/i18n';
2
- import { useMemo } from 'react';
3
- import styles from './styles.module.scss';
4
- import ThreatNotice from './threat-notice.js';
5
-
6
- /**
7
- * FixerStateNotice component
8
- *
9
- * @param {object} props - The component props.
10
- * @param {object} props.fixerState - The state of the fixer (inProgress, error, stale).
11
- * @param {boolean} props.fixerState.inProgress - Whether the fixer is in progress.
12
- * @param {boolean} props.fixerState.error - Whether the fixer encountered an error.
13
- * @param {boolean} props.fixerState.stale - Whether the fixer is stale.
14
- *
15
- * @return {JSX.Element | null} The rendered fixer notice or null if no notice is available.
16
- */
17
- const FixerStateNotice = ( {
18
- fixerState,
19
- }: {
20
- fixerState: { inProgress: boolean; error: boolean; stale: boolean };
21
- } ) => {
22
- const { status, title, content } = useMemo( () => {
23
- if ( fixerState.error ) {
24
- return {
25
- status: 'error' as const,
26
- title: __( 'An error occurred auto-fixing this threat', 'jetpack-components' ),
27
- content: __(
28
- 'Jetpack encountered a filesystem error while attempting to auto-fix this threat. Please try again later or contact support.',
29
- 'jetpack-components'
30
- ),
31
- };
32
- }
33
-
34
- if ( fixerState.stale ) {
35
- return {
36
- status: 'error' as const,
37
- title: __( 'The auto-fixer is taking longer than expected', 'jetpack-components' ),
38
- content: __(
39
- '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.',
40
- 'jetpack-components'
41
- ),
42
- };
43
- }
44
-
45
- if ( fixerState.inProgress ) {
46
- return {
47
- status: 'success' as const,
48
- title: __( 'An auto-fixer is in progress', 'jetpack-components' ),
49
- content: __( 'Please wait while Jetpack auto-fixes the threat.', 'jetpack-components' ),
50
- };
51
- }
52
-
53
- return {};
54
- }, [ fixerState ] );
55
-
56
- return title ? (
57
- <div className={ styles[ 'fixer-notice' ] }>
58
- <ThreatNotice status={ status } title={ title } content={ content } />
59
- </div>
60
- ) : null;
61
- };
62
-
63
- export default FixerStateNotice;
@@ -1,109 +0,0 @@
1
- import { type Threat } from '@automattic/jetpack-scan';
2
- import { Modal } from '@wordpress/components';
3
- import { createContext } from 'react';
4
- import Text from '../text/index.js';
5
- import ThreatSeverityBadge from '../threat-severity-badge/index.js';
6
- import styles from './styles.module.scss';
7
- import ThreatFixConfirmation from './threat-fix-confirmation.js';
8
-
9
- interface ThreatModalContextType {
10
- closeModal: () => void;
11
- threat: Threat;
12
- handleUpgradeClick?: () => void;
13
- userConnectionNeeded: boolean;
14
- handleConnectUser: () => void;
15
- userIsConnecting: boolean;
16
- siteCredentialsNeeded: boolean;
17
- credentialsIsFetching: boolean;
18
- credentialsRedirectUrl: string;
19
- handleFixThreatClick?: ( threats: Threat[] ) => void;
20
- handleIgnoreThreatClick?: ( threats: Threat[] ) => void;
21
- handleUnignoreThreatClick?: ( threats: Threat[] ) => void;
22
- }
23
-
24
- export const ThreatModalContext = createContext< ThreatModalContextType | null >( null );
25
-
26
- /**
27
- * ThreatModal component
28
- *
29
- * @param {object} props - The props.
30
- * @param {object} props.threat - The threat.
31
- * @param {boolean} props.isUserConnected - Whether the user is connected.
32
- * @param {boolean} props.hasConnectedOwner - Whether the user has a connected owner.
33
- * @param {boolean} props.userIsConnecting - Whether the user is connecting.
34
- * @param {Function} props.handleConnectUser - The handleConnectUser function.
35
- * @param {object} props.credentials - The credentials.
36
- * @param {boolean} props.credentialsIsFetching - Whether the credentials are fetching.
37
- * @param {string} props.credentialsRedirectUrl - The credentials redirect URL.
38
- * @param {Function} props.handleUpgradeClick - The handleUpgradeClick function.
39
- * @param {Function} props.handleFixThreatClick - The handleFixThreatClick function.
40
- * @param {Function} props.handleIgnoreThreatClick - The handleIgnoreThreatClick function.
41
- * @param {Function} props.handleUnignoreThreatClick - The handleUnignoreThreatClick function.
42
- *
43
- * @return {JSX.Element} The threat modal.
44
- */
45
- export default function ThreatModal( {
46
- threat,
47
- isUserConnected,
48
- hasConnectedOwner,
49
- userIsConnecting,
50
- handleConnectUser,
51
- credentials,
52
- credentialsIsFetching,
53
- credentialsRedirectUrl,
54
- handleUpgradeClick,
55
- handleFixThreatClick,
56
- handleIgnoreThreatClick,
57
- handleUnignoreThreatClick,
58
- ...modalProps
59
- }: {
60
- threat: Threat;
61
- isUserConnected: boolean;
62
- hasConnectedOwner: boolean;
63
- userIsConnecting: boolean;
64
- handleConnectUser: () => void;
65
- credentials: false | Record< string, unknown >[];
66
- credentialsIsFetching: boolean;
67
- credentialsRedirectUrl: string;
68
- handleUpgradeClick?: () => void;
69
- handleFixThreatClick?: ( threats: Threat[] ) => void;
70
- handleIgnoreThreatClick?: ( threats: Threat[] ) => void;
71
- handleUnignoreThreatClick?: ( threats: Threat[] ) => void;
72
- } & React.ComponentProps< typeof Modal > ): JSX.Element {
73
- const userConnectionNeeded = ! isUserConnected || ! hasConnectedOwner;
74
- const siteCredentialsNeeded = ! credentials || credentials.length === 0;
75
-
76
- return (
77
- <Modal
78
- title={
79
- <div className={ styles.title }>
80
- <Text variant="title-small">{ threat.title }</Text>
81
- { !! threat.severity && <ThreatSeverityBadge severity={ threat.severity } /> }
82
- </div>
83
- }
84
- size="large"
85
- { ...modalProps }
86
- >
87
- <div className={ styles[ 'threat-details' ] }>
88
- <ThreatModalContext.Provider
89
- value={ {
90
- closeModal: modalProps.onRequestClose,
91
- threat,
92
- handleUpgradeClick,
93
- userConnectionNeeded,
94
- handleConnectUser,
95
- userIsConnecting,
96
- siteCredentialsNeeded,
97
- credentialsIsFetching,
98
- credentialsRedirectUrl,
99
- handleFixThreatClick,
100
- handleIgnoreThreatClick,
101
- handleUnignoreThreatClick,
102
- } }
103
- >
104
- <ThreatFixConfirmation />
105
- </ThreatModalContext.Provider>
106
- </div>
107
- </Modal>
108
- );
109
- }
@@ -1,81 +0,0 @@
1
- .threat-details {
2
- display: flex;
3
- flex-direction: column;
4
- gap: calc( var( --spacing-base ) * 3 ); // 24px
5
- }
6
-
7
- .section {
8
- display: flex;
9
- flex-direction: column;
10
- gap: calc( var( --spacing-base ) * 2 ); // 16px
11
- }
12
-
13
- .section .section__toggle {
14
- text-decoration: none;
15
-
16
- &:hover {
17
- text-decoration: underline;
18
- }
19
-
20
- &__content {
21
- display: flex;
22
- gap: calc( var( --spacing-base ) / 2 ); // 4px
23
- align-items: center;
24
- }
25
- }
26
-
27
- .title {
28
- display: flex;
29
- align-items: center;
30
- gap: calc( var( --spacing-base ) * 1.5 ); // 12px
31
- }
32
-
33
- .filename {
34
- background-color: var( --jp-gray-0 );
35
- padding: calc( var( --spacing-base ) * 3 ); // 24px
36
- overflow-x: auto;
37
- }
38
-
39
- .modal-footer {
40
- padding-top: calc( var( --spacing-base ) * 3 ); // 24px
41
- border-top: 1px solid var( --jp-gray-5 );
42
-
43
- .threat-actions {
44
- display: flex;
45
- justify-content: flex-end;
46
- gap: calc( var( --spacing-base ) * 2 ); // 16px;
47
- }
48
- }
49
-
50
- .fixer-notice {
51
- padding-bottom: calc( var( --spacing-base ) * 3 ); // 24px
52
- }
53
-
54
- .notice {
55
- &__title {
56
- display: flex;
57
- gap: calc( var( --spacing-base ) / 2 ); // 4px
58
-
59
- p {
60
- font-weight: bold;
61
- }
62
- }
63
-
64
- &__actions {
65
- display: flex;
66
- gap: calc( var( --spacing-base ) * 2 ); // 16px;
67
- }
68
-
69
- &__action {
70
- margin-top: calc( var( --spacing-base ) * 2 ); // 16px;
71
- }
72
- }
73
-
74
- svg.spinner {
75
- color: var( --jp-black );
76
- height: 20px;
77
- width: 20px;
78
- margin-left: calc( var( --spacing-base ) / 2 ); // 4px;
79
- margin-right: 6px;
80
-
81
- }
@@ -1,93 +0,0 @@
1
- import { getFixerState, getDetailedFixerAction } from '@automattic/jetpack-scan';
2
- import { __ } from '@wordpress/i18n';
3
- import { useCallback, useContext, useMemo } from 'react';
4
- import { Button } from '@automattic/jetpack-components';
5
- import FixerStateNotice from './fixer-state-notice.js';
6
- import styles from './styles.module.scss';
7
- import { ThreatModalContext } from './index.js';
8
-
9
- /**
10
- * ThreatActions component
11
- *
12
- * @return {JSX.Element | null} The rendered action buttons or null if no actions are available.
13
- */
14
- const ThreatActions = (): JSX.Element => {
15
- const {
16
- closeModal,
17
- threat,
18
- handleFixThreatClick,
19
- handleIgnoreThreatClick,
20
- handleUnignoreThreatClick,
21
- userConnectionNeeded,
22
- siteCredentialsNeeded,
23
- } = useContext( ThreatModalContext );
24
- const disabled = userConnectionNeeded || siteCredentialsNeeded;
25
-
26
- const fixerState = useMemo( () => {
27
- return getFixerState( threat.fixer );
28
- }, [ threat.fixer ] );
29
-
30
- const detailedFixerAction = useMemo( () => getDetailedFixerAction( threat ), [ threat ] );
31
-
32
- const onFixClick = useCallback( () => {
33
- handleFixThreatClick?.( [ threat ] );
34
- closeModal();
35
- }, [ threat, handleFixThreatClick, closeModal ] );
36
-
37
- const onIgnoreClick = useCallback( () => {
38
- handleIgnoreThreatClick?.( [ threat ] );
39
- closeModal();
40
- }, [ threat, handleIgnoreThreatClick, closeModal ] );
41
-
42
- const onUnignoreClick = useCallback( () => {
43
- handleUnignoreThreatClick?.( [ threat ] );
44
- closeModal();
45
- }, [ threat, handleUnignoreThreatClick, closeModal ] );
46
-
47
- if ( ! threat?.status || threat.status === 'fixed' ) {
48
- return null;
49
- }
50
-
51
- return (
52
- <div className={ styles[ 'modal-footer' ] }>
53
- <FixerStateNotice fixerState={ fixerState } />
54
- <div className={ styles[ 'threat-actions' ] }>
55
- { threat.status === 'ignored' && (
56
- <Button
57
- disabled={ disabled }
58
- isDestructive={ true }
59
- variant="secondary"
60
- onClick={ onUnignoreClick }
61
- >
62
- { __( 'Un-ignore threat', 'jetpack-components' ) }
63
- </Button>
64
- ) }
65
- { threat.status === 'current' && (
66
- <>
67
- <Button
68
- isDestructive={ true }
69
- variant="secondary"
70
- onClick={ onIgnoreClick }
71
- disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
72
- >
73
- { __( 'Ignore threat', 'jetpack-components' ) }
74
- </Button>
75
- { threat.fixable && (
76
- <Button
77
- isPrimary
78
- disabled={ disabled || ( fixerState.inProgress && ! fixerState.stale ) }
79
- onClick={ onFixClick }
80
- >
81
- { fixerState.error || fixerState.stale
82
- ? __( 'Retry fixer', 'jetpack-components' )
83
- : detailedFixerAction }
84
- </Button>
85
- ) }
86
- </>
87
- ) }
88
- </div>
89
- </div>
90
- );
91
- };
92
-
93
- export default ThreatActions;
@@ -1,54 +0,0 @@
1
- import { __ } from '@wordpress/i18n';
2
- import { useContext } from 'react';
3
- import ThreatActions from './threat-actions.js';
4
- import ThreatFixDetails from './threat-fix-details.js';
5
- import ThreatNotice from './threat-notice.js';
6
- import ThreatSummary from './threat-summary.js';
7
- import ThreatTechnicalDetails from './threat-technical-details.js';
8
- import { ThreatModalContext } from './index.js';
9
-
10
- /**
11
- * ThreatFixConfirmation component
12
- *
13
- * @return {JSX.Element} The rendered fix confirmation.
14
- */
15
- const ThreatFixConfirmation = () => {
16
- const { userConnectionNeeded, siteCredentialsNeeded } = useContext( ThreatModalContext );
17
- return (
18
- <>
19
- <ThreatSummary />
20
- <ThreatTechnicalDetails />
21
- <ThreatFixDetails />
22
- { siteCredentialsNeeded && userConnectionNeeded && (
23
- <ThreatNotice
24
- title={ 'Additional connections needed' }
25
- content={ __(
26
- 'A user connection and server credentials provide Jetpack the access necessary to ignore and auto-fix threats on your site.',
27
- 'jetpack-components'
28
- ) }
29
- />
30
- ) }
31
- { ! siteCredentialsNeeded && userConnectionNeeded && (
32
- <ThreatNotice
33
- title={ __( 'User connection needed', 'jetpack-components' ) }
34
- content={ __(
35
- 'A user connection provides Jetpack the access necessary to ignore and auto-fix threats on your site.',
36
- 'jetpack-components'
37
- ) }
38
- />
39
- ) }
40
- { siteCredentialsNeeded && ! userConnectionNeeded && (
41
- <ThreatNotice
42
- title={ __( 'Site credentials needed', 'jetpack-components' ) }
43
- content={ __(
44
- 'Your server credentials allow Jetpack to access the server that’s powering your website. This information is securely saved and only used to ignore and auto-fix threats detected on your site.',
45
- 'jetpack-components'
46
- ) }
47
- />
48
- ) }
49
- <ThreatActions />
50
- </>
51
- );
52
- };
53
-
54
- export default ThreatFixConfirmation;
@@ -1,65 +0,0 @@
1
- import { getFixerDescription } from '@automattic/jetpack-scan';
2
- import { __, sprintf } from '@wordpress/i18n';
3
- import React, { useMemo, useContext } from 'react';
4
- import ContextualUpgradeTrigger from '../contextual-upgrade-trigger/index.js';
5
- import Text from '../text/index.js';
6
- import styles from './styles.module.scss';
7
- import { ThreatModalContext } from './index.js';
8
-
9
- /**
10
- * ThreatFixDetails component
11
- *
12
- * @return {JSX.Element | null} The rendered fix details or null if no fixable details are available.
13
- */
14
- const ThreatFixDetails = (): JSX.Element => {
15
- const { threat, handleUpgradeClick } = useContext( ThreatModalContext );
16
-
17
- const title = useMemo( () => {
18
- if ( threat.status === 'fixed' ) {
19
- return __( 'How did Jetpack fix it?', 'jetpack-components' );
20
- }
21
- if ( threat.status === 'current' && threat.fixable ) {
22
- return __( 'How can Jetpack auto-fix this threat?', 'jetpack-components' );
23
- }
24
- return __( 'How to fix it?', 'jetpack-components' );
25
- }, [ threat ] );
26
-
27
- const fix = useMemo( () => {
28
- // The threat has a fixed version available, but no auto-fix is available.
29
- // The user needs to update the extension to the fixed version.
30
- if ( ! threat.fixable && threat.fixedIn ) {
31
- return sprintf(
32
- /* translators: Translates to Updates to version. %1$s: Name. %2$s: Fixed version */
33
- __( 'Update %1$s to version %2$s.', 'jetpack-components' ),
34
- threat.extension.name,
35
- threat.fixedIn
36
- );
37
- }
38
-
39
- // The threat has an auto-fix available.
40
- return getFixerDescription( threat );
41
- }, [ threat ] );
42
-
43
- if ( ! threat.fixable && ! threat.fixedIn ) {
44
- return null;
45
- }
46
-
47
- return (
48
- <div className={ styles.section }>
49
- <Text variant="title-small">{ title }</Text>
50
- <Text>{ fix }</Text>
51
- { handleUpgradeClick && (
52
- <ContextualUpgradeTrigger
53
- description={ __(
54
- 'Looking for advanced scan results and one-click fixes?',
55
- 'jetpack-components'
56
- ) }
57
- cta={ __( 'Upgrade Jetpack now', 'jetpack-components' ) }
58
- onClick={ handleUpgradeClick }
59
- />
60
- ) }
61
- </div>
62
- );
63
- };
64
-
65
- export default ThreatFixDetails;