@elementor/editor-audits 4.4.0-1114 → 4.4.0-1116
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.
- package/dist/index.js +327 -781
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +301 -755
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/components/audit-panel.tsx +3 -1
- package/src/components/pages/overview-page.tsx +24 -29
- package/src/components/report-shell.tsx +10 -91
- package/src/components/severity-summary-cards.tsx +52 -0
- package/src/components/violation-row.tsx +3 -3
- package/src/utils/audit-status-summary.ts +0 -57
- package/src/components/audit-statuses-section.tsx +0 -65
- package/src/components/count-summary-circle.tsx +0 -66
- package/src/components/pages/all-audits-page.tsx +0 -84
- package/src/components/pages/issues-page.tsx +0 -65
- package/src/components/score-bar.tsx +0 -56
- package/src/components/score-circle.tsx +0 -60
- package/src/components/severity-filter-chips.tsx +0 -57
- package/src/utils/score-thresholds.ts +0 -23
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { Box, Link, Typography } from '@elementor/ui';
|
|
4
|
-
import { __ } from '@wordpress/i18n';
|
|
5
|
-
|
|
6
|
-
import { ALL_CATEGORIES, CATEGORY_LABELS } from '../../constants';
|
|
7
|
-
import { type AuditCategory, type PageAuditReport } from '../../types';
|
|
8
|
-
import { type AuditStatusGroup, getPopulatedCategories } from '../../utils/audit-status-summary';
|
|
9
|
-
import { countSeverities, type SeverityCounts } from '../../utils/severity-counts';
|
|
10
|
-
import AuditStatusesSection from '../audit-statuses-section';
|
|
11
|
-
import IssuesCategoryRow from '../issues-category-row';
|
|
12
|
-
import SeverityFilterChips, { type SeverityFilter } from '../severity-filter-chips';
|
|
13
|
-
|
|
14
|
-
type Props = {
|
|
15
|
-
report: PageAuditReport;
|
|
16
|
-
onCategoryClick: ( category: AuditCategory ) => void;
|
|
17
|
-
onAllAuditsClick: () => void;
|
|
18
|
-
onStatusClick: ( status: AuditStatusGroup ) => void;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
function filterCounts( counts: SeverityCounts, filter: SeverityFilter ): SeverityCounts {
|
|
22
|
-
if ( filter === 'all' ) {
|
|
23
|
-
return counts;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return { error: 0, warning: 0, info: 0, [ filter ]: counts[ filter ] };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default function IssuesPage( { report, onCategoryClick, onAllAuditsClick, onStatusClick }: Props ) {
|
|
30
|
-
const [ filter, setFilter ] = useState< SeverityFilter >( 'all' );
|
|
31
|
-
const populatedCategories = getPopulatedCategories( report.categories, ALL_CATEGORIES );
|
|
32
|
-
|
|
33
|
-
const categoryRows = populatedCategories
|
|
34
|
-
.map( ( category ) => ( { category, counts: filterCounts( countSeverities( report, category ), filter ) } ) )
|
|
35
|
-
.filter( ( { counts } ) => Object.values( counts ).some( ( count ) => count > 0 ) );
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<Box sx={ { display: 'flex', flexDirection: 'column', gap: 4, p: 2 } }>
|
|
39
|
-
<AuditStatusesSection report={ report } onStatusClick={ onStatusClick } />
|
|
40
|
-
<Link
|
|
41
|
-
component="button"
|
|
42
|
-
underline="none"
|
|
43
|
-
color="inherit"
|
|
44
|
-
onClick={ onAllAuditsClick }
|
|
45
|
-
sx={ { textAlign: 'start' } }
|
|
46
|
-
>
|
|
47
|
-
<Typography variant="subtitle1" component="h2">
|
|
48
|
-
{ __( 'All issues', 'elementor' ) }
|
|
49
|
-
</Typography>
|
|
50
|
-
</Link>
|
|
51
|
-
<SeverityFilterChips selected={ filter } onChange={ setFilter } />
|
|
52
|
-
<Box sx={ { display: 'flex', flexDirection: 'column', gap: 1 } }>
|
|
53
|
-
{ categoryRows.map( ( { category, counts } ) => (
|
|
54
|
-
<IssuesCategoryRow
|
|
55
|
-
key={ category }
|
|
56
|
-
category={ category }
|
|
57
|
-
label={ CATEGORY_LABELS[ category ] }
|
|
58
|
-
counts={ counts }
|
|
59
|
-
onClick={ () => onCategoryClick( category ) }
|
|
60
|
-
/>
|
|
61
|
-
) ) }
|
|
62
|
-
</Box>
|
|
63
|
-
</Box>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { ChevronRightIcon } from '@elementor/icons';
|
|
3
|
-
import { Box, LinearProgress, Rotate, Typography, useTheme } from '@elementor/ui';
|
|
4
|
-
|
|
5
|
-
import { onKeyboardClick } from '../utils/keyboard-click';
|
|
6
|
-
import { getScoreTier } from '../utils/score-thresholds';
|
|
7
|
-
|
|
8
|
-
type Props = {
|
|
9
|
-
label: string;
|
|
10
|
-
score: number;
|
|
11
|
-
onClick?: () => void;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export default function ScoreBar( { label, score, onClick }: Props ) {
|
|
15
|
-
const isRtl = 'rtl' === useTheme().direction;
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<Box
|
|
19
|
-
role={ onClick ? 'button' : undefined }
|
|
20
|
-
tabIndex={ onClick ? 0 : undefined }
|
|
21
|
-
onClick={ onClick }
|
|
22
|
-
onKeyDown={ onClick ? onKeyboardClick( onClick ) : undefined }
|
|
23
|
-
sx={ {
|
|
24
|
-
display: 'flex',
|
|
25
|
-
alignItems: 'center',
|
|
26
|
-
gap: 1,
|
|
27
|
-
cursor: onClick ? 'pointer' : 'default',
|
|
28
|
-
outline: 'none',
|
|
29
|
-
'&:focus-visible': { outline: '2px solid', outlineColor: 'primary.main', borderRadius: 1 },
|
|
30
|
-
py: 0.5,
|
|
31
|
-
} }
|
|
32
|
-
>
|
|
33
|
-
<Typography variant="body2" sx={ { minWidth: 96 } }>
|
|
34
|
-
{ label }
|
|
35
|
-
</Typography>
|
|
36
|
-
<LinearProgress
|
|
37
|
-
variant="determinate"
|
|
38
|
-
value={ score }
|
|
39
|
-
color={ getScoreTier( score ).color }
|
|
40
|
-
sx={ { flex: 1, height: 6, borderRadius: 4, bgcolor: 'action.disabledBackground' } }
|
|
41
|
-
/>
|
|
42
|
-
<Typography
|
|
43
|
-
variant="body2"
|
|
44
|
-
color="text.primary"
|
|
45
|
-
sx={ { minWidth: 24, textAlign: 'right', fontWeight: 900 } }
|
|
46
|
-
>
|
|
47
|
-
{ score }
|
|
48
|
-
</Typography>
|
|
49
|
-
{ onClick && (
|
|
50
|
-
<Rotate in={ isRtl }>
|
|
51
|
-
<ChevronRightIcon fontSize="small" color="action" />
|
|
52
|
-
</Rotate>
|
|
53
|
-
) }
|
|
54
|
-
</Box>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { Box, CircularProgress, Typography } from '@elementor/ui';
|
|
3
|
-
|
|
4
|
-
import { getScoreTier, type ScoreColor } from '../utils/score-thresholds';
|
|
5
|
-
|
|
6
|
-
type Props = {
|
|
7
|
-
color?: ScoreColor;
|
|
8
|
-
score: number;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const SCORE_CIRCLE_SIZE = 88;
|
|
12
|
-
const SCORE_CIRCLE_THICKNESS = 3;
|
|
13
|
-
|
|
14
|
-
export default function ScoreCircle( { color, score }: Props ) {
|
|
15
|
-
const progressColor = color ?? getScoreTier( score ).color;
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<Box
|
|
19
|
-
role="progressbar"
|
|
20
|
-
aria-valuenow={ score }
|
|
21
|
-
aria-valuemin={ 0 }
|
|
22
|
-
aria-valuemax={ 100 }
|
|
23
|
-
sx={ { position: 'relative', display: 'inline-flex' } }
|
|
24
|
-
>
|
|
25
|
-
<CircularProgress
|
|
26
|
-
variant="determinate"
|
|
27
|
-
value={ 100 }
|
|
28
|
-
size={ SCORE_CIRCLE_SIZE }
|
|
29
|
-
thickness={ SCORE_CIRCLE_THICKNESS }
|
|
30
|
-
sx={ { color: 'action.disabledBackground' } }
|
|
31
|
-
/>
|
|
32
|
-
<CircularProgress
|
|
33
|
-
variant="determinate"
|
|
34
|
-
value={ score }
|
|
35
|
-
size={ SCORE_CIRCLE_SIZE }
|
|
36
|
-
thickness={ SCORE_CIRCLE_THICKNESS }
|
|
37
|
-
color={ progressColor }
|
|
38
|
-
sx={ { position: 'absolute', left: 0 } }
|
|
39
|
-
/>
|
|
40
|
-
<Box
|
|
41
|
-
sx={ {
|
|
42
|
-
position: 'absolute',
|
|
43
|
-
inset: 0,
|
|
44
|
-
display: 'flex',
|
|
45
|
-
alignItems: 'center',
|
|
46
|
-
justifyContent: 'center',
|
|
47
|
-
} }
|
|
48
|
-
>
|
|
49
|
-
<Typography
|
|
50
|
-
variant="h4"
|
|
51
|
-
component="span"
|
|
52
|
-
color="text.primary"
|
|
53
|
-
sx={ { fontWeight: 700, lineHeight: 1 } }
|
|
54
|
-
>
|
|
55
|
-
{ score }
|
|
56
|
-
</Typography>
|
|
57
|
-
</Box>
|
|
58
|
-
</Box>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { Box, Chip } from '@elementor/ui';
|
|
3
|
-
import { __ } from '@wordpress/i18n';
|
|
4
|
-
|
|
5
|
-
import { type AuditSeverity } from '../types';
|
|
6
|
-
import { ALL_SEVERITIES, severityPluralLabel } from '../utils/severity-counts';
|
|
7
|
-
import SeverityIcon from './severity-icons';
|
|
8
|
-
|
|
9
|
-
export type SeverityFilter = 'all' | AuditSeverity;
|
|
10
|
-
|
|
11
|
-
type Props = {
|
|
12
|
-
selected: SeverityFilter;
|
|
13
|
-
onChange: ( filter: SeverityFilter ) => void;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default function SeverityFilterChips( { selected, onChange }: Props ) {
|
|
17
|
-
return (
|
|
18
|
-
<Box sx={ { display: 'flex', alignItems: 'center', gap: 1 } }>
|
|
19
|
-
<FilterChip
|
|
20
|
-
label={ __( 'All', 'elementor' ) }
|
|
21
|
-
isSelected={ selected === 'all' }
|
|
22
|
-
onClick={ () => onChange( 'all' ) }
|
|
23
|
-
/>
|
|
24
|
-
{ ALL_SEVERITIES.map( ( severity ) => (
|
|
25
|
-
<FilterChip
|
|
26
|
-
key={ severity }
|
|
27
|
-
label={ severityPluralLabel( severity ) }
|
|
28
|
-
icon={ <SeverityIcon severity={ severity } /> }
|
|
29
|
-
isSelected={ selected === severity }
|
|
30
|
-
onClick={ () => onChange( severity ) }
|
|
31
|
-
/>
|
|
32
|
-
) ) }
|
|
33
|
-
</Box>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type FilterChipProps = {
|
|
38
|
-
label: string;
|
|
39
|
-
icon?: React.ReactElement;
|
|
40
|
-
isSelected: boolean;
|
|
41
|
-
onClick: () => void;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
function FilterChip( { label, icon, isSelected, onClick }: FilterChipProps ) {
|
|
45
|
-
return (
|
|
46
|
-
<Chip
|
|
47
|
-
label={ label }
|
|
48
|
-
icon={ icon }
|
|
49
|
-
size="small"
|
|
50
|
-
variant="filled"
|
|
51
|
-
color="default"
|
|
52
|
-
onClick={ onClick }
|
|
53
|
-
aria-pressed={ isSelected }
|
|
54
|
-
sx={ { bgcolor: isSelected ? 'action.selected' : 'transparent' } }
|
|
55
|
-
/>
|
|
56
|
-
);
|
|
57
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { __ } from '@wordpress/i18n';
|
|
2
|
-
|
|
3
|
-
export const GOOD_THRESHOLD = 90;
|
|
4
|
-
export const OK_THRESHOLD = 50;
|
|
5
|
-
|
|
6
|
-
export type ScoreColor = 'success' | 'warning' | 'error';
|
|
7
|
-
|
|
8
|
-
export type ScoreTier = {
|
|
9
|
-
color: ScoreColor;
|
|
10
|
-
label: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export function getScoreTier( score: number ): ScoreTier {
|
|
14
|
-
if ( score >= GOOD_THRESHOLD ) {
|
|
15
|
-
return { color: 'success', label: __( 'Good', 'elementor' ) };
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if ( score >= OK_THRESHOLD ) {
|
|
19
|
-
return { color: 'warning', label: __( 'Needs work', 'elementor' ) };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return { color: 'error', label: __( 'At risk', 'elementor' ) };
|
|
23
|
-
}
|