Skip to content

Commit

Permalink
Add ThreatsDataView
Browse files Browse the repository at this point in the history
Add support for list view in threats data table

Minor adjustments

Add badge component and integrate with threats data view

Update stories and align auto-fix column

Update ThreatDataView list view fixer status (#39854)

Update ThreatsDataView to use js-packages IconTooltip (#39856)
  • Loading branch information
nateweller committed Oct 24, 2024
1 parent c2b7dc0 commit 38f2ad5
Show file tree
Hide file tree
Showing 24 changed files with 1,985 additions and 26 deletions.
357 changes: 357 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add ThreatsDataView component
39 changes: 39 additions & 0 deletions projects/js-packages/components/components/badge/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import clsx from 'clsx';
import React from 'react';
import styles from './style.module.scss';

type BadgeProps = {
children?: React.ReactNode;
className?: string;
variant?: 'success' | 'warning' | 'danger';
[ key: string ]: unknown;
};

/**
* Badge component
*
* @param {object} props - The component properties.
* @param {string} props.variant - The badge variant (i.e. 'success', 'warning', 'danger').
* @param {JSX.Element} props.children - Badge text or content.
* @param {string} props.className - Additional class name to pass to the Badge component.
*
* @return {React.ReactElement} The `Badge` component.
*/
const Badge: React.FC< BadgeProps > = ( { children, className, variant = 'info', ...props } ) => {
const classes = clsx(
styles.badge,
{
[ styles[ 'is-success' ] ]: variant === 'success',
[ styles[ 'is-warning' ] ]: variant === 'warning',
[ styles[ 'is-danger' ] ]: variant === 'danger',
},
className
);
return (
<span className={ classes } { ...props }>
{ children }
</span>
);
};

export default Badge;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Badge from '../index';

export default {
title: 'JS Packages/Components/Badge',
component: Badge,
argTypes: {
type: {
control: {
type: 'select',
},
options: [ 'info', 'danger', 'warning', 'success' ],
},
},
};

const Template = args => <Badge { ...args } />;

export const _default = Template.bind( {} );
_default.args = {
type: 'info',
children: 'Hello World',
};
25 changes: 25 additions & 0 deletions projects/js-packages/components/components/badge/style.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.badge {
display: inline-block;
border-radius: 4px;
background-color: var(--jp-gray-0);
color: var(--jp-gray-80);
padding: 4px 8px;
font-size: 13px;
font-weight: 400;
line-height: 16px;

&.is-success {
background-color: var(--jp-green-5);
color: var(--jp-green-50);
}

&.is-warning {
background-color: var(--jp-yellow-5);
color: var(--jp-yellow-60);
}

&.is-danger {
background-color: var(--jp-red-5);
color: var(--jp-red-70);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ const IconTooltip: React.FC< IconTooltipProps > = ( {
wide = false,
inline = true,
shift = false,
hoverShow = false,
} ) => {
const POPOVER_HELPER_WIDTH = 124;
const [ isVisible, setIsVisible ] = useState( false );
const [ timeoutId, setTimeoutId ] = useState( null );

const hideTooltip = useCallback( () => setIsVisible( false ), [ setIsVisible ] );
const toggleTooltip = useCallback(
e => {
Expand All @@ -53,6 +56,26 @@ const IconTooltip: React.FC< IconTooltipProps > = ( {
[ isVisible, setIsVisible ]
);

const handleMouseEnter = useCallback( () => {
if ( hoverShow ) {
if ( timeoutId ) {
clearTimeout( timeoutId );
setTimeoutId( null );
}
setIsVisible( true );
}
}, [ hoverShow, timeoutId ] );

const handleMouseLeave = useCallback( () => {
if ( hoverShow ) {
const id = setTimeout( () => {
setIsVisible( false );
setTimeoutId( null );
}, 100 );
setTimeoutId( id );
}
}, [ hoverShow ] );

const args = {
// To be compatible with deprecating prop `position`.
position: placementsToPositions( placement ),
Expand All @@ -79,7 +102,12 @@ const IconTooltip: React.FC< IconTooltipProps > = ( {
const isForcedToShow = isAnchorWrapper && forceShow;

return (
<div className={ wrapperClassNames } data-testid="icon-tooltip_wrapper">
<div
className={ wrapperClassNames }
data-testid="icon-tooltip_wrapper"
onMouseEnter={ handleMouseEnter }
onMouseLeave={ handleMouseLeave }
>
{ ! isAnchorWrapper && (
<Button variant="link" onMouseDown={ toggleTooltip }>
<Gridicon className={ iconClassName } icon={ iconCode } size={ iconSize } />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export default {
wide: {
control: { type: 'boolean' },
},
hoverShow: {
control: { type: 'boolean' },
},
},
};

Expand Down Expand Up @@ -106,3 +109,11 @@ Wide.args = {
wide: true,
placement: 'bottom-start',
};

export const HoverShow = Template.bind( {} );
HoverShow.args = {
title: 'This is title!',
children: <div>This is a tooltip!</div>,
placement: 'bottom-start',
hoverShow: true,
};
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,9 @@ export type IconTooltipProps = {
* Enables the Popover to shift in order to stay in view when meeting the viewport edges.
*/
shift?: boolean;

/**
* Enables the Popover to show on hover.
*/
hoverShow?: boolean;
};
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import { _x } from '@wordpress/i18n';
import styles from './styles.module.scss';
import Badge from '../badge';

const severityClassNames = severity => {
const ThreatSeverityBadge = ( { severity } ) => {
if ( severity >= 5 ) {
return 'is-critical';
} else if ( severity >= 3 && severity < 5 ) {
return 'is-high';
return (
<Badge variant="danger">
{ _x( 'Critical', 'Severity label for issues rated 5 or higher.', 'jetpack' ) }
</Badge>
);
}
return 'is-low';
};

const severityText = severity => {
if ( severity >= 5 ) {
return _x( 'Critical', 'Severity label for issues rated 5 or higher.', 'jetpack' );
} else if ( severity >= 3 && severity < 5 ) {
return _x( 'High', 'Severity label for issues rated between 3 and 5.', 'jetpack' );
if ( severity >= 3 && severity < 5 ) {
return (
<Badge variant="warning">
{ _x( 'High', 'Severity label for issues rated between 3 and 5.', 'jetpack' ) }
</Badge>
);
}
return _x( 'Low', 'Severity label for issues rated below 3.', 'jetpack' );
};

const ThreatSeverityBadge = ( { severity } ) => {
return (
<div
className={ `${ styles[ 'threat-severity-badge' ] } ${
styles[ severityClassNames( severity ) ]
}` }
>
{ severityText( severity ) }
</div>
);
return <Badge>{ _x( 'Low', 'Severity label for issues rated below 3.', 'jetpack' ) }</Badge>;
};

export default ThreatSeverityBadge;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { __ } from '@wordpress/i18n';

export const PAID_PLUGIN_SUPPORT_URL = 'https://jetpack.com/contact-support/?rel=support';

export const THREAT_STATUSES: { value: string; label: string; variant?: 'success' | 'warning' }[] =
[
{ value: 'current', label: __( 'Active', 'jetpack' ), variant: 'warning' },
{ value: 'fixed', label: __( 'Fixed', 'jetpack' ), variant: 'success' },
{ value: 'ignored', label: __( 'Ignored', 'jetpack' ) },
];

export const THREAT_TYPES = [
{ value: 'plugin', label: __( 'Plugin', 'jetpack' ) },
{ value: 'theme', label: __( 'Theme', 'jetpack' ) },
{ value: 'core', label: __( 'WordPress', 'jetpack' ) },
{ value: 'file', label: __( 'File', 'jetpack' ) },
{ value: 'database', label: __( 'Database', 'jetpack' ) },
];
Loading

0 comments on commit 38f2ad5

Please sign in to comment.