-
Notifications
You must be signed in to change notification settings - Fork 843
Components: Add ScanReport #40419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Components: Add ScanReport #40419
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
d0e310e
Init project branch
nateweller c741513
Add ScanReport component
dkmyta 7784874
Add icons and tooltips
dkmyta 5a7d70f
Add ShieldCheckIcon and ShieldAlertIcon
dkmyta a5cdeed
Fix icons
dkmyta 600a05e
Simplify
dkmyta 60ba2de
changelog
dkmyta 257f90a
Remove file type
dkmyta a5c2691
Add dedicated components for shield icons
dkmyta 4742c9a
Update constants
dkmyta 8cfc9b6
Updates
dkmyta 448c05b
Correct text domain in constants
dkmyta 6cd56cb
Correct missed text domain
dkmyta 7715221
Simplify
dkmyta ed4eb50
Use dynamic ShieldIcon
dkmyta 402c95f
Remove check and alert shield icons
dkmyta e491ac9
Add info variant
dkmyta 83d9312
Use path from @wordpress/icons info icon for shield info icon
nateweller 8b720f6
Suggestions
dkmyta 2c8de2e
Disable hide and sorting for icon field
dkmyta 5d8f4ef
Add Extension type
dkmyta 519bac2
changelog
dkmyta d44ca54
Add/apply ScanReportExtension typing
dkmyta File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
projects/js-packages/components/changelog/components-add-scan-report
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: minor | ||
| Type: added | ||
|
|
||
| Adds ScanReport component |
30 changes: 30 additions & 0 deletions
30
projects/js-packages/components/components/scan-report/constants.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { | ||
| code as fileIcon, | ||
| color as themeIcon, | ||
| plugins as pluginIcon, | ||
| shield as shieldIcon, | ||
| wordpress as coreIcon, | ||
| } from '@wordpress/icons'; | ||
|
|
||
| export const TYPES = [ | ||
| { value: 'core', label: __( 'WordPress', 'jetpack-components' ) }, | ||
| { value: 'plugins', label: __( 'Plugin', 'jetpack-components' ) }, | ||
| { value: 'themes', label: __( 'Theme', 'jetpack-components' ) }, | ||
| { value: 'files', label: __( 'Files', 'jetpack-components' ) }, | ||
| ]; | ||
|
|
||
| export const ICONS = { | ||
| plugins: pluginIcon, | ||
| themes: themeIcon, | ||
| core: coreIcon, | ||
| files: fileIcon, | ||
| default: shieldIcon, | ||
| }; | ||
|
|
||
| export const FIELD_ICON = 'icon'; | ||
| export const FIELD_TYPE = 'type'; | ||
| export const FIELD_NAME = 'name'; | ||
| export const FIELD_STATUS = 'status'; | ||
| export const FIELD_UPDATE = 'update'; | ||
| export const FIELD_VERSION = 'version'; |
197 changes: 197 additions & 0 deletions
197
projects/js-packages/components/components/scan-report/index.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| import { type ScanReportExtension } from '@automattic/jetpack-scan'; | ||
| import { Tooltip } from '@wordpress/components'; | ||
| import { | ||
| type SupportedLayouts, | ||
| type View, | ||
| type Field, | ||
| DataViews, | ||
| filterSortAndPaginate, | ||
| } from '@wordpress/dataviews'; | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { Icon } from '@wordpress/icons'; | ||
| import { useCallback, useMemo, useState } from 'react'; | ||
| import ShieldIcon from '../shield-icon'; | ||
| import { | ||
| FIELD_NAME, | ||
| FIELD_VERSION, | ||
| FIELD_ICON, | ||
| FIELD_STATUS, | ||
| FIELD_TYPE, | ||
| TYPES, | ||
| ICONS, | ||
| } from './constants'; | ||
| import styles from './styles.module.scss'; | ||
|
|
||
| /** | ||
| * DataViews component for displaying a scan report. | ||
| * | ||
| * @param {object} props - Component props. | ||
| * @param {Array} props.data - Scan report data. | ||
| * @param {Function} props.onChangeSelection - Callback function run when an item is selected. | ||
| * | ||
| * @return {JSX.Element} The ScanReport component. | ||
| */ | ||
| export default function ScanReport( { data, onChangeSelection } ): JSX.Element { | ||
| const baseView = { | ||
| search: '', | ||
| filters: [], | ||
| page: 1, | ||
| perPage: 20, | ||
| }; | ||
|
|
||
| /** | ||
| * DataView default layouts. | ||
| * | ||
| * This property provides layout information about the view types that are active. If empty, enables all layout types (see “Layout Types”) with empty layout data. | ||
| * | ||
| * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dataviews/#defaultlayouts-record-string-view | ||
| */ | ||
| const defaultLayouts: SupportedLayouts = { | ||
| table: { | ||
| ...baseView, | ||
| fields: [ FIELD_STATUS, FIELD_TYPE, FIELD_NAME, FIELD_VERSION ], | ||
| layout: { | ||
| primaryField: FIELD_STATUS, | ||
| }, | ||
| }, | ||
| list: { | ||
| ...baseView, | ||
| fields: [ FIELD_STATUS, FIELD_VERSION ], | ||
| layout: { | ||
| primaryField: FIELD_NAME, | ||
| mediaField: FIELD_ICON, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| /** | ||
| * DataView view object - configures how the dataset is visible to the user. | ||
| * | ||
| * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dataviews/#view-object | ||
| */ | ||
| const [ view, setView ] = useState< View >( { | ||
| type: 'table', | ||
| ...defaultLayouts.table, | ||
| } ); | ||
|
|
||
| /** | ||
| * DataView fields - describes the visible items for each record in the dataset. | ||
| * | ||
| * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dataviews/#fields-object | ||
| */ | ||
| const fields = useMemo( () => { | ||
| const iconHeight = 20; | ||
| const result: Field< ScanReportExtension >[] = [ | ||
| { | ||
| id: FIELD_STATUS, | ||
| label: __( 'Status', 'jetpack-components' ), | ||
| render( { item }: { item: ScanReportExtension } ) { | ||
| let variant: 'info' | 'warning' | 'success' = 'info'; | ||
| let text = __( | ||
| 'This item was added to your site after the most recent scan. We will check for threats during the next scheduled one.', | ||
| 'jetpack-components' | ||
| ); | ||
|
|
||
| if ( item.checked ) { | ||
| if ( item.threats.length > 0 ) { | ||
| variant = 'warning'; | ||
| text = __( 'Threat detected.', 'jetpack-components' ); | ||
| } else { | ||
| variant = 'success'; | ||
| text = __( 'No known threats found that affect this version.', 'jetpack-components' ); | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <Tooltip className={ styles.tooltip } text={ text }> | ||
| <div className={ styles.icon }> | ||
| <ShieldIcon variant={ variant } height={ iconHeight } /> | ||
| </div> | ||
| </Tooltip> | ||
| ); | ||
| }, | ||
| }, | ||
| { | ||
| id: FIELD_TYPE, | ||
| label: __( 'Type', 'jetpack-components' ), | ||
| elements: TYPES, | ||
| }, | ||
| { | ||
| id: FIELD_NAME, | ||
| label: __( 'Name', 'jetpack-components' ), | ||
| enableGlobalSearch: true, | ||
| getValue( { item }: { item: ScanReportExtension } ) { | ||
| return item.name ? item.name : ''; | ||
| }, | ||
| }, | ||
| { | ||
| id: FIELD_VERSION, | ||
| label: __( 'Version', 'jetpack-components' ), | ||
| enableGlobalSearch: true, | ||
| getValue( { item }: { item: ScanReportExtension } ) { | ||
| return item.version ? item.version : ''; | ||
| }, | ||
| }, | ||
| ...( view.type === 'list' | ||
| ? [ | ||
| { | ||
| id: FIELD_ICON, | ||
| label: __( 'Icon', 'jetpack-components' ), | ||
| enableSorting: false, | ||
| enableHiding: false, | ||
| getValue( { item }: { item: ScanReportExtension } ) { | ||
| return ICONS[ item.type ] || ''; | ||
| }, | ||
| render( { item }: { item: ScanReportExtension } ) { | ||
| return ( | ||
| <div className={ styles.threat__media }> | ||
| <Icon icon={ ICONS[ item.type ] } /> | ||
| </div> | ||
| ); | ||
| }, | ||
| }, | ||
| ] | ||
| : [] ), | ||
| ]; | ||
|
|
||
| return result; | ||
| }, [ view ] ); | ||
|
|
||
| /** | ||
| * Apply the view settings (i.e. filters, sorting, pagination) to the dataset. | ||
| * | ||
| * @see https://github.com/WordPress/gutenberg/blob/trunk/packages/dataviews/src/filter-and-sort-data-view.ts | ||
| */ | ||
| const { data: processedData, paginationInfo } = useMemo( () => { | ||
| return filterSortAndPaginate( data, view, fields ); | ||
| }, [ data, view, fields ] ); | ||
|
|
||
| /** | ||
| * Callback function to update the view state. | ||
| * | ||
| * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dataviews/#onchangeview-function | ||
| */ | ||
| const onChangeView = useCallback( ( newView: View ) => { | ||
| setView( newView ); | ||
| }, [] ); | ||
|
|
||
| /** | ||
| * DataView getItemId function - returns the unique ID for each record in the dataset. | ||
| * | ||
| * @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dataviews/#getitemid-function | ||
| */ | ||
| const getItemId = useCallback( ( item: ScanReportExtension ) => item.id.toString(), [] ); | ||
|
|
||
| return ( | ||
| <DataViews | ||
| data={ processedData } | ||
| defaultLayouts={ defaultLayouts } | ||
| fields={ fields } | ||
| getItemId={ getItemId } | ||
| onChangeSelection={ onChangeSelection } | ||
| onChangeView={ onChangeView } | ||
| paginationInfo={ paginationInfo } | ||
| view={ view } | ||
| /> | ||
| ); | ||
| } | ||
72 changes: 72 additions & 0 deletions
72
projects/js-packages/components/components/scan-report/stories/index.stories.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import ScanReport from '..'; | ||
|
|
||
| export default { | ||
| title: 'JS Packages/Components/Scan Report', | ||
| component: ScanReport, | ||
| parameters: { | ||
| backgrounds: { | ||
| default: 'light', | ||
| values: [ { name: 'light', value: 'white' } ], | ||
| }, | ||
| }, | ||
| decorators: [ | ||
| Story => ( | ||
| <div style={ { maxWidth: '100%', backgroundColor: 'white' } }> | ||
| <Story /> | ||
| </div> | ||
| ), | ||
| ], | ||
| }; | ||
|
|
||
| export const Default = args => <ScanReport { ...args } />; | ||
| Default.args = { | ||
| data: [ | ||
| { | ||
| id: 1, | ||
| name: 'WordPress', | ||
| slug: null, | ||
| version: '6.7.1', | ||
| threats: [], | ||
| checked: true, | ||
| type: 'core', | ||
| }, | ||
| { | ||
| id: 2, | ||
| name: 'Jetpack', | ||
| slug: 'jetpack/jetpack.php', | ||
| version: '14.1-a.7', | ||
| threats: [], | ||
| checked: false, | ||
| type: 'plugins', | ||
| }, | ||
| { | ||
| id: 3, | ||
| name: 'Twenty Fifteen', | ||
| slug: 'twentyfifteen', | ||
| version: '1.1', | ||
| threats: [ | ||
| { | ||
| id: 198352527, | ||
| signature: 'Vulnerable.WP.Extension', | ||
| description: 'Vulnerable WordPress extension', | ||
| severity: 3, | ||
| }, | ||
| ], | ||
| checked: true, | ||
| type: 'themes', | ||
| }, | ||
| { | ||
| id: 4, | ||
| threats: [ | ||
| { | ||
| id: 198352406, | ||
| signature: 'EICAR_AV_Test_Suspicious', | ||
| title: 'Malicious code found in file: jptt_eicar.php', | ||
| severity: 1, | ||
| }, | ||
| ], | ||
| checked: true, | ||
| type: 'files', | ||
| }, | ||
| ], | ||
| }; |
21 changes: 21 additions & 0 deletions
21
projects/js-packages/components/components/scan-report/styles.module.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| @import '@wordpress/dataviews/build-style/style.css'; | ||
|
|
||
| .threat__media { | ||
| width: 100%; | ||
| height: 100%; | ||
| display: flex; | ||
| align-items: center; | ||
| justify-content: center; | ||
| background-color: #EDFFEE; | ||
| border-color: #EDFFEE; | ||
|
|
||
| svg { | ||
| fill: var( --jp-black ); | ||
| } | ||
| } | ||
|
|
||
| .tooltip { | ||
| max-width: 240px; | ||
| border-radius: 4px; | ||
| text-align: left; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.