@pixelated-tech/components 3.5.13 → 3.5.14
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/components/admin/site-health/site-health-accessibility.js +1 -93
- package/dist/components/admin/site-health/site-health-github.js +1 -1
- package/dist/components/admin/site-health/site-health-on-site-seo.js +2 -53
- package/dist/components/admin/site-health/site-health-overview.js +1 -9
- package/dist/components/admin/site-health/site-health-performance.js +1 -157
- package/dist/components/admin/site-health/site-health-security.js +1 -138
- package/dist/components/admin/site-health/site-health-seo.js +1 -93
- package/dist/components/admin/site-health/site-health-utils.js +170 -0
- package/dist/components/admin/site-health/site-health.css +1 -9
- package/dist/index.adminclient.js +1 -0
- package/dist/index.adminserver.js +1 -0
- package/dist/types/components/admin/site-health/site-health-accessibility.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-on-site-seo.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-overview.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-performance.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-security.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-seo.d.ts.map +1 -1
- package/dist/types/components/admin/site-health/site-health-utils.d.ts +17 -0
- package/dist/types/components/admin/site-health/site-health-utils.d.ts.map +1 -0
- package/dist/types/index.adminclient.d.ts +1 -0
- package/dist/types/index.adminserver.d.ts +1 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { SiteHealthTemplate } from './site-health-template';
|
|
6
|
-
import {
|
|
6
|
+
import { formatAuditItem, getAuditScoreIcon, getScoreColor } from './site-health-utils';
|
|
7
7
|
SiteHealthAccessibility.propTypes = {
|
|
8
8
|
siteName: PropTypes.string.isRequired,
|
|
9
9
|
};
|
|
@@ -17,98 +17,6 @@ export function SiteHealthAccessibility({ siteName }) {
|
|
|
17
17
|
return result;
|
|
18
18
|
}, []);
|
|
19
19
|
return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "PageSpeed - Accessibility", fetchData: fetchAccessibilityData, children: (data) => {
|
|
20
|
-
const getScoreColor = (score) => {
|
|
21
|
-
return getScoreIndicator(score).color;
|
|
22
|
-
};
|
|
23
|
-
const getAuditScoreIcon = (score) => {
|
|
24
|
-
return getScoreIndicator(score).icon;
|
|
25
|
-
};
|
|
26
|
-
// Helper function to display audit item details
|
|
27
|
-
const formatAuditItem = (item, auditTitle) => {
|
|
28
|
-
// Handle URLs
|
|
29
|
-
if (item.url && typeof item.url === 'string') {
|
|
30
|
-
return item.url;
|
|
31
|
-
}
|
|
32
|
-
// Handle sources (like JavaScript files)
|
|
33
|
-
if (item.source && typeof item.source === 'string') {
|
|
34
|
-
return item.source;
|
|
35
|
-
}
|
|
36
|
-
// Handle text descriptions
|
|
37
|
-
if (item.text && typeof item.text === 'string') {
|
|
38
|
-
return item.text;
|
|
39
|
-
}
|
|
40
|
-
// Handle entities (like "Google Tag Manager")
|
|
41
|
-
if (item.entity && typeof item.entity === 'string') {
|
|
42
|
-
return item.entity;
|
|
43
|
-
}
|
|
44
|
-
// Handle nodes with selectors
|
|
45
|
-
if (item.node && typeof item.node === 'object' && 'selector' in item.node) {
|
|
46
|
-
return `Element: ${item.node.selector}`;
|
|
47
|
-
}
|
|
48
|
-
// Handle nodes with snippets
|
|
49
|
-
if (item.node && typeof item.node === 'object' && 'snippet' in item.node) {
|
|
50
|
-
const snippet = item.node.snippet;
|
|
51
|
-
return `Element: ${snippet.length > 50 ? snippet.substring(0, 50) + '...' : snippet}`;
|
|
52
|
-
}
|
|
53
|
-
// Handle origins (like domains)
|
|
54
|
-
if (item.origin && typeof item.origin === 'string') {
|
|
55
|
-
return item.origin;
|
|
56
|
-
}
|
|
57
|
-
// Handle labels
|
|
58
|
-
if (item.label && typeof item.label === 'string') {
|
|
59
|
-
return item.label;
|
|
60
|
-
}
|
|
61
|
-
// Handle numeric values with units
|
|
62
|
-
if (item.value && typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
63
|
-
const value = item.value;
|
|
64
|
-
return `${value.value}${item.unit || ''}`;
|
|
65
|
-
}
|
|
66
|
-
// Handle statistics
|
|
67
|
-
if (item.statistic && typeof item.statistic === 'string' && item.value) {
|
|
68
|
-
if (typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
69
|
-
const value = item.value;
|
|
70
|
-
return `${item.statistic}: ${value.value}`;
|
|
71
|
-
}
|
|
72
|
-
return item.statistic;
|
|
73
|
-
}
|
|
74
|
-
// Handle timing data with audit context
|
|
75
|
-
if (typeof item === 'number') {
|
|
76
|
-
let context = '';
|
|
77
|
-
if (auditTitle) {
|
|
78
|
-
if (auditTitle.toLowerCase().includes('server') || auditTitle.toLowerCase().includes('backend')) {
|
|
79
|
-
context = ' server response';
|
|
80
|
-
}
|
|
81
|
-
else if (auditTitle.toLowerCase().includes('network') || auditTitle.toLowerCase().includes('request')) {
|
|
82
|
-
context = ' network request';
|
|
83
|
-
}
|
|
84
|
-
else if (auditTitle.toLowerCase().includes('render') || auditTitle.toLowerCase().includes('blocking')) {
|
|
85
|
-
context = ' render blocking';
|
|
86
|
-
}
|
|
87
|
-
else if (auditTitle.toLowerCase().includes('javascript') || auditTitle.toLowerCase().includes('js')) {
|
|
88
|
-
context = ' JavaScript';
|
|
89
|
-
}
|
|
90
|
-
else if (auditTitle.toLowerCase().includes('image') || auditTitle.toLowerCase().includes('media')) {
|
|
91
|
-
context = ' media resource';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return `${item.toFixed(2)}ms${context}`;
|
|
95
|
-
}
|
|
96
|
-
if (item.value && typeof item.value === 'number') {
|
|
97
|
-
const unit = item.unit || 'ms';
|
|
98
|
-
let context = '';
|
|
99
|
-
if (auditTitle && unit === 'ms') {
|
|
100
|
-
if (auditTitle.toLowerCase().includes('server')) {
|
|
101
|
-
context = ' server time';
|
|
102
|
-
}
|
|
103
|
-
else if (auditTitle.toLowerCase().includes('network')) {
|
|
104
|
-
context = ' network time';
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return `${item.value.toFixed(2)}${unit}${context}`;
|
|
108
|
-
}
|
|
109
|
-
// If we can't find anything meaningful, show a generic message
|
|
110
|
-
return 'Details available';
|
|
111
|
-
};
|
|
112
20
|
if (!data?.data || data.data.length === 0) {
|
|
113
21
|
return (_jsx("p", { style: { color: '#6b7280' }, children: "No accessibility data available for this site." }));
|
|
114
22
|
}
|
|
@@ -32,7 +32,7 @@ export function SiteHealthGit({ siteName, startDate, endDate }) {
|
|
|
32
32
|
// Prepare table data
|
|
33
33
|
const tableData = (data.commits || []).map((commit) => ({
|
|
34
34
|
Date: new Date(commit.date).toLocaleDateString(),
|
|
35
|
-
Message: _jsx("span", {
|
|
35
|
+
Message: _jsx("span", { title: commit.message, children: commit.message }),
|
|
36
36
|
Version: commit.version ? (_jsx("span", { className: "health-version-tag", children: commit.version.split('~')[0] })) : (_jsx("span", { className: "health-text-muted", children: "-" }))
|
|
37
37
|
}));
|
|
38
38
|
return (_jsxs(_Fragment, { children: [_jsx("h4", { className: "health-site-name", children: siteName.replace('-', ' ') }), _jsx("div", { className: "health-section-list", children: tableData.length === 0 ? (_jsx("p", { className: "health-empty-state", children: "No recent commits found" })) : (_jsx(Table, { id: "git-table", data: tableData, altRowColor: "#DDD" })) }), _jsxs("p", { className: "health-timestamp", children: ["Last checked: ", new Date(data.timestamp).toLocaleString()] })] }));
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { SiteHealthTemplate } from './site-health-template';
|
|
5
|
-
import {
|
|
5
|
+
import { formatAuditItem, getAuditScoreIcon } from './site-health-utils';
|
|
6
6
|
/**
|
|
7
7
|
* Restructure audits by type with all pages and their individual results
|
|
8
8
|
*/
|
|
@@ -104,12 +104,6 @@ export function SiteHealthOnSiteSEO({ siteName }) {
|
|
|
104
104
|
}
|
|
105
105
|
// Process data to aggregate audits by type across all pages
|
|
106
106
|
const aggregatedOnPageAudits = restructureAuditsByType(data.pagesAnalyzed);
|
|
107
|
-
const getScoreColor = (score) => {
|
|
108
|
-
return getScoreIndicator(score).color;
|
|
109
|
-
};
|
|
110
|
-
const getAuditScoreIcon = (score) => {
|
|
111
|
-
return getScoreIndicator(score).icon;
|
|
112
|
-
};
|
|
113
107
|
const formatPageIssue = (item) => {
|
|
114
108
|
// Handle page-specific results from restructured data
|
|
115
109
|
if (item.page && typeof item.page === 'string') {
|
|
@@ -153,52 +147,7 @@ export function SiteHealthOnSiteSEO({ siteName }) {
|
|
|
153
147
|
// Fallback to original formatting
|
|
154
148
|
return formatAuditItem(item);
|
|
155
149
|
};
|
|
156
|
-
|
|
157
|
-
// Handle specific SEO element formatting based on the user's list
|
|
158
|
-
// Title Tags
|
|
159
|
-
if (item.title && typeof item.title === 'string') {
|
|
160
|
-
return `Title: "${item.title}" (${item.length || 'unknown'} chars)`;
|
|
161
|
-
}
|
|
162
|
-
// Meta tags
|
|
163
|
-
if (item.name && typeof item.name === 'string' && item.content) {
|
|
164
|
-
return `${item.name}: ${String(item.content)}`;
|
|
165
|
-
}
|
|
166
|
-
// Headings
|
|
167
|
-
if (item.tag && typeof item.tag === 'string' && item.tag.match(/^h[1-6]$/i)) {
|
|
168
|
-
return `${item.tag}: "${item.text || ''}"`;
|
|
169
|
-
}
|
|
170
|
-
// Links and URLs
|
|
171
|
-
if (item.url && typeof item.url === 'string') {
|
|
172
|
-
if (item.issue && typeof item.issue === 'string') {
|
|
173
|
-
return `${item.url} - ${item.issue}`;
|
|
174
|
-
}
|
|
175
|
-
return item.url;
|
|
176
|
-
}
|
|
177
|
-
// Images with alt tags
|
|
178
|
-
if (item.src && typeof item.src === 'string') {
|
|
179
|
-
return `Image: ${item.src} ${item.alt ? '(has alt)' : '(missing alt)'}`;
|
|
180
|
-
}
|
|
181
|
-
// Robots.txt directives
|
|
182
|
-
if (item.directive && typeof item.directive === 'string') {
|
|
183
|
-
return `${item.directive}: ${item.value || ''}`;
|
|
184
|
-
}
|
|
185
|
-
// Sitemap entries
|
|
186
|
-
if (item.loc && typeof item.loc === 'string') {
|
|
187
|
-
return item.loc;
|
|
188
|
-
}
|
|
189
|
-
// Default formatting
|
|
190
|
-
return Object.entries(item)
|
|
191
|
-
.map(([key, value]) => `${key}: ${String(value)}`)
|
|
192
|
-
.join(', ');
|
|
193
|
-
};
|
|
194
|
-
return (_jsxs(_Fragment, { children: [_jsx("h4", { className: "health-site-name", children: data.site.replace('-', ' ') }), _jsxs("p", { className: "health-site-url", children: ["URL: ", data.url] }), data.overallScore !== null && (_jsx("div", { className: "health-score-container", children: _jsxs("div", { className: "health-score-item", children: [_jsx("div", { className: "health-score-label", children: "On-Site SEO Score" }), _jsxs("div", { className: "health-score-value", style: { color: getScoreColor(data.overallScore) }, children: [Math.round((data.overallScore || 0) * 100), "%"] }), _jsx("div", { className: "health-score-bar", children: _jsx("div", { className: "health-score-fill", style: {
|
|
195
|
-
width: `${(data.overallScore || 0) * 100}%`,
|
|
196
|
-
backgroundColor: getScoreColor(data.overallScore)
|
|
197
|
-
} }) })] }) })), aggregatedOnPageAudits.length > 0 && (_jsxs("div", { children: [_jsx("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: "On-Page SEO Audits" }), _jsx("div", { className: "health-audit-list", children: aggregatedOnPageAudits
|
|
198
|
-
.filter(audit => audit.scoreDisplayMode !== 'notApplicable')
|
|
199
|
-
.map((audit) => (_jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", children: getAuditScoreIcon(audit.score) }), _jsxs("div", { className: "health-audit-content", children: [_jsxs("span", { className: "health-audit-title", children: [audit.score === null ? '(N/A)' : `(${Math.round((audit.score || 0) * 100)}%)`, " ", audit.title] }), audit.displayValue && audit.score !== 1 && (_jsx("p", { className: "health-audit-description", children: audit.displayValue })), audit.details && audit.details.items && Array.isArray(audit.details.items) && audit.details.items.length > 0 && audit.score !== 1 && (_jsx("div", { className: "health-audit-details", children: _jsx("div", { style: { fontSize: '0.75rem', color: '#6b7280', marginTop: '0.25rem' }, children: audit.details.items
|
|
200
|
-
.filter((item) => item.score !== 1)
|
|
201
|
-
.map((item, idx) => (_jsx("div", { style: { marginBottom: '0.125rem' }, children: formatPageIssue(item) }, idx))) }) }))] })] }, audit.id))) })] })), data.onSiteAudits.length > 0 && (_jsxs("div", { style: { marginTop: data.pagesAnalyzed.length > 0 ? '2rem' : '0' }, children: [_jsx("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: "On-Site SEO Audits" }), _jsx("div", { className: "health-audit-list", children: data.onSiteAudits
|
|
150
|
+
return (_jsxs(_Fragment, { children: [data.onSiteAudits.length > 0 && (_jsxs("div", { style: { marginTop: data.pagesAnalyzed.length > 0 ? '2rem' : '0' }, children: [_jsx("h5", { style: { fontSize: '1rem', fontWeight: '600', marginBottom: '1rem' }, children: "On-Site SEO Audits" }), _jsx("div", { className: "health-audit-list", children: data.onSiteAudits
|
|
202
151
|
.filter(audit => audit.scoreDisplayMode !== 'notApplicable')
|
|
203
152
|
.sort((a, b) => (b.score || 0) - (a.score || 0))
|
|
204
153
|
.map((audit) => (_jsxs("div", { className: "health-audit-item", children: [_jsx("span", { className: "health-audit-icon", children: getAuditScoreIcon(audit.score) }), _jsxs("div", { className: "health-audit-content", children: [_jsxs("span", { className: "health-audit-title", children: [audit.score === null ? '(N/A)' : `(${Math.round((audit.score || 0) * 100)}%)`, " ", audit.title] }), audit.displayValue && audit.score !== 1 && (_jsx("p", { className: "health-audit-description", children: audit.displayValue })), audit.details && audit.details.items && Array.isArray(audit.details.items) && audit.details.items.length > 0 && audit.score !== 1 && (_jsx("div", { className: "health-audit-details", children: _jsx("div", { style: { fontSize: '0.75rem', color: '#6b7280', marginTop: '0.25rem' }, children: audit.details.items
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { SiteHealthTemplate } from './site-health-template';
|
|
6
|
-
import {
|
|
6
|
+
import { formatScore, getScoreColor } from './site-health-utils';
|
|
7
7
|
SiteHealthOverview.propTypes = {
|
|
8
8
|
siteName: PropTypes.string.isRequired,
|
|
9
9
|
};
|
|
@@ -25,14 +25,6 @@ export function SiteHealthOverview({ siteName }) {
|
|
|
25
25
|
return (_jsxs("p", { style: { color: '#ef4444', fontSize: '0.875rem' }, children: ["Error: ", siteData.error] }));
|
|
26
26
|
}
|
|
27
27
|
// Helper functions
|
|
28
|
-
const getScoreColor = (score) => {
|
|
29
|
-
return getScoreIndicator(score).color;
|
|
30
|
-
};
|
|
31
|
-
const formatScore = (score) => {
|
|
32
|
-
if (score === null)
|
|
33
|
-
return 'N/A';
|
|
34
|
-
return `${Math.round(score * 100)}%`;
|
|
35
|
-
};
|
|
36
28
|
const getStatusColor = (status) => {
|
|
37
29
|
switch (status) {
|
|
38
30
|
case 'good': return '#10b981'; // green
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { SiteHealthTemplate } from './site-health-template';
|
|
6
|
-
import {
|
|
6
|
+
import { formatAuditItem, getAuditScoreIcon, getScoreColor, formatScore } from './site-health-utils';
|
|
7
7
|
SiteHealthPerformance.propTypes = {
|
|
8
8
|
siteName: PropTypes.string.isRequired,
|
|
9
9
|
};
|
|
@@ -24,162 +24,6 @@ export function SiteHealthPerformance({ siteName }) {
|
|
|
24
24
|
if (siteData.status === 'error') {
|
|
25
25
|
return (_jsxs("p", { style: { color: '#ef4444', fontSize: '0.875rem' }, children: ["Error: ", siteData.error] }));
|
|
26
26
|
}
|
|
27
|
-
const getAuditScoreIcon = (score) => {
|
|
28
|
-
return getScoreIndicator(score).icon;
|
|
29
|
-
};
|
|
30
|
-
const getScoreColor = (score) => {
|
|
31
|
-
return getScoreIndicator(score).color;
|
|
32
|
-
};
|
|
33
|
-
const formatScore = (score) => {
|
|
34
|
-
if (score === null)
|
|
35
|
-
return 'N/A';
|
|
36
|
-
return `${Math.round(score * 100)}%`;
|
|
37
|
-
};
|
|
38
|
-
// Helper function to display audit item details
|
|
39
|
-
const formatAuditItem = (item, auditTitle) => {
|
|
40
|
-
// Handle URLs
|
|
41
|
-
if (item.url && typeof item.url === 'string') {
|
|
42
|
-
return item.url;
|
|
43
|
-
}
|
|
44
|
-
// Handle sources (like JavaScript files)
|
|
45
|
-
if (item.source && typeof item.source === 'string') {
|
|
46
|
-
return item.source;
|
|
47
|
-
}
|
|
48
|
-
// Handle text descriptions
|
|
49
|
-
if (item.text && typeof item.text === 'string') {
|
|
50
|
-
return item.text;
|
|
51
|
-
}
|
|
52
|
-
// Handle entities (like "Google Tag Manager")
|
|
53
|
-
if (item.entity && typeof item.entity === 'string') {
|
|
54
|
-
return item.entity;
|
|
55
|
-
}
|
|
56
|
-
// Handle nodes with selectors
|
|
57
|
-
if (item.node && typeof item.node === 'object' && 'selector' in item.node) {
|
|
58
|
-
return `Element: ${item.node.selector}`;
|
|
59
|
-
}
|
|
60
|
-
// Handle nodes with snippets
|
|
61
|
-
if (item.node && typeof item.node === 'object' && 'snippet' in item.node) {
|
|
62
|
-
const snippet = item.node.snippet;
|
|
63
|
-
return `Element: ${snippet.length > 50 ? snippet.substring(0, 50) + '...' : snippet}`;
|
|
64
|
-
}
|
|
65
|
-
// Handle origins (like domains)
|
|
66
|
-
if (item.origin && typeof item.origin === 'string') {
|
|
67
|
-
return item.origin;
|
|
68
|
-
}
|
|
69
|
-
// Handle labels
|
|
70
|
-
if (item.label && typeof item.label === 'string') {
|
|
71
|
-
return item.label;
|
|
72
|
-
}
|
|
73
|
-
// Handle numeric values with units
|
|
74
|
-
if (item.value && typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
75
|
-
const value = item.value;
|
|
76
|
-
return `${value.value}${item.unit || ''}`;
|
|
77
|
-
}
|
|
78
|
-
// Handle statistics
|
|
79
|
-
if (item.statistic && typeof item.statistic === 'string' && item.value) {
|
|
80
|
-
if (typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
81
|
-
const value = item.value;
|
|
82
|
-
return `${item.statistic}: ${value.value}`;
|
|
83
|
-
}
|
|
84
|
-
return item.statistic;
|
|
85
|
-
}
|
|
86
|
-
// Handle timing data with audit context
|
|
87
|
-
if (typeof item === 'number') {
|
|
88
|
-
let context = '';
|
|
89
|
-
if (auditTitle) {
|
|
90
|
-
if (auditTitle.toLowerCase().includes('server') || auditTitle.toLowerCase().includes('backend')) {
|
|
91
|
-
context = ' server response';
|
|
92
|
-
}
|
|
93
|
-
else if (auditTitle.toLowerCase().includes('network') || auditTitle.toLowerCase().includes('request')) {
|
|
94
|
-
context = ' network request';
|
|
95
|
-
}
|
|
96
|
-
else if (auditTitle.toLowerCase().includes('render') || auditTitle.toLowerCase().includes('blocking')) {
|
|
97
|
-
context = ' render blocking';
|
|
98
|
-
}
|
|
99
|
-
else if (auditTitle.toLowerCase().includes('javascript') || auditTitle.toLowerCase().includes('js')) {
|
|
100
|
-
context = ' JavaScript';
|
|
101
|
-
}
|
|
102
|
-
else if (auditTitle.toLowerCase().includes('image') || auditTitle.toLowerCase().includes('media')) {
|
|
103
|
-
context = ' media resource';
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return `${item.toFixed(2)}ms${context}`;
|
|
107
|
-
}
|
|
108
|
-
if (item.value && typeof item.value === 'number') {
|
|
109
|
-
const unit = item.unit || 'ms';
|
|
110
|
-
let context = '';
|
|
111
|
-
if (auditTitle && unit === 'ms') {
|
|
112
|
-
if (auditTitle.toLowerCase().includes('server')) {
|
|
113
|
-
context = ' server time';
|
|
114
|
-
}
|
|
115
|
-
else if (auditTitle.toLowerCase().includes('network')) {
|
|
116
|
-
context = ' network time';
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return `${item.value.toFixed(2)}${unit}${context}`;
|
|
120
|
-
}
|
|
121
|
-
// Handle timing data with more context
|
|
122
|
-
if (item.duration && typeof item.duration === 'number') {
|
|
123
|
-
const duration = item.duration;
|
|
124
|
-
let context = '';
|
|
125
|
-
if (item.url && typeof item.url === 'string') {
|
|
126
|
-
context = ` for ${item.url}`;
|
|
127
|
-
}
|
|
128
|
-
else if (item.source && typeof item.source === 'string') {
|
|
129
|
-
context = ` for ${item.source}`;
|
|
130
|
-
}
|
|
131
|
-
else if (item.name && typeof item.name === 'string') {
|
|
132
|
-
context = ` for ${item.name}`;
|
|
133
|
-
}
|
|
134
|
-
else if (item.path && typeof item.path === 'string') {
|
|
135
|
-
context = ` for ${item.path}`;
|
|
136
|
-
}
|
|
137
|
-
else if (item.request && typeof item.request === 'string') {
|
|
138
|
-
context = ` for ${item.request}`;
|
|
139
|
-
}
|
|
140
|
-
return `${duration.toFixed(2)}ms${context}`;
|
|
141
|
-
}
|
|
142
|
-
// Handle response times
|
|
143
|
-
if (item.responseTime && typeof item.responseTime === 'number') {
|
|
144
|
-
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
145
|
-
return `${item.responseTime.toFixed(2)}ms response time${url}`;
|
|
146
|
-
}
|
|
147
|
-
// Handle start/end times
|
|
148
|
-
if ((item.startTime || item.endTime) && typeof (item.startTime || item.endTime) === 'number') {
|
|
149
|
-
const start = item.startTime && typeof item.startTime === 'number' ? item.startTime.toFixed(2) : '?';
|
|
150
|
-
const end = item.endTime && typeof item.endTime === 'number' ? item.endTime.toFixed(2) : '?';
|
|
151
|
-
const url = (item.url && typeof item.url === 'string') ? ` for ${item.url}` : '';
|
|
152
|
-
return `${start}ms - ${end}ms${url}`;
|
|
153
|
-
}
|
|
154
|
-
// Handle transfer size with timing
|
|
155
|
-
if (item.transferSize && typeof item.transferSize === 'number' && item.duration && typeof item.duration === 'number') {
|
|
156
|
-
const size = (item.transferSize / 1024).toFixed(1);
|
|
157
|
-
const time = item.duration.toFixed(2);
|
|
158
|
-
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
159
|
-
return `${size} KB in ${time}ms${url}`;
|
|
160
|
-
}
|
|
161
|
-
// Handle main thread time
|
|
162
|
-
if (item.mainThreadTime && typeof item.mainThreadTime === 'number') {
|
|
163
|
-
return `${item.mainThreadTime.toFixed(1)}ms`;
|
|
164
|
-
}
|
|
165
|
-
// For other objects, try to find a meaningful display
|
|
166
|
-
if (item.group && typeof item.group === 'string') {
|
|
167
|
-
return item.group;
|
|
168
|
-
}
|
|
169
|
-
if (item.type && typeof item.type === 'string') {
|
|
170
|
-
return item.type;
|
|
171
|
-
}
|
|
172
|
-
// If we can't find anything meaningful, provide a generic description
|
|
173
|
-
// This handles raw timing data that might be from various performance metrics
|
|
174
|
-
if (typeof item === 'number') {
|
|
175
|
-
return `${item.toFixed(2)}ms`;
|
|
176
|
-
}
|
|
177
|
-
if (item.value && typeof item.value === 'number') {
|
|
178
|
-
const unit = item.unit || 'ms';
|
|
179
|
-
return `${item.value.toFixed(2)}${unit}`;
|
|
180
|
-
}
|
|
181
|
-
return 'Performance metric data available';
|
|
182
|
-
};
|
|
183
27
|
return (_jsxs(_Fragment, { children: [_jsx("h4", { className: "health-site-name", children: siteData.site.replace('-', ' ') }), _jsxs("p", { className: "health-site-url", children: ["URL: ", siteData.url] }), _jsx("div", { style: { marginBottom: '1.5rem' }, children: _jsxs("div", { className: "health-score-item", style: { width: '100%' }, children: [_jsx("div", { className: "health-score-label", children: "Performance Score" }), _jsx("div", { className: "health-score-value", style: { color: getScoreColor(siteData.scores.performance) }, children: formatScore(siteData.scores.performance) }), _jsx("div", { className: "health-score-bar", children: _jsx("div", { className: "health-score-fill", style: {
|
|
184
28
|
width: siteData.scores.performance !== null ? `${siteData.scores.performance * 100}%` : '0%',
|
|
185
29
|
backgroundColor: siteData.scores.performance !== null ? getScoreColor(siteData.scores.performance) : '#6b7280'
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { SiteHealthTemplate } from './site-health-template';
|
|
6
|
-
import {
|
|
6
|
+
import { formatAuditItem, getAuditScoreIcon, getScoreColor } from './site-health-utils';
|
|
7
7
|
SiteHealthSecurity.propTypes = {
|
|
8
8
|
siteName: PropTypes.string.isRequired,
|
|
9
9
|
};
|
|
@@ -17,143 +17,6 @@ export function SiteHealthSecurity({ siteName }) {
|
|
|
17
17
|
};
|
|
18
18
|
}, []);
|
|
19
19
|
return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "PageSpeed - Site Security", fetchData: fetchSecurityData, children: (data) => {
|
|
20
|
-
const getScoreColor = (score) => {
|
|
21
|
-
return getScoreIndicator(score).color;
|
|
22
|
-
};
|
|
23
|
-
const getAuditScoreIcon = (score) => {
|
|
24
|
-
return getScoreIndicator(score).icon;
|
|
25
|
-
};
|
|
26
|
-
// Helper function to display audit item details
|
|
27
|
-
const formatAuditItem = (item, auditTitle) => {
|
|
28
|
-
// Handle URLs
|
|
29
|
-
if (item.url && typeof item.url === 'string') {
|
|
30
|
-
return item.url;
|
|
31
|
-
}
|
|
32
|
-
// Handle sources (like JavaScript files)
|
|
33
|
-
if (item.source && typeof item.source === 'string') {
|
|
34
|
-
return item.source;
|
|
35
|
-
}
|
|
36
|
-
// Handle text descriptions
|
|
37
|
-
if (item.text && typeof item.text === 'string') {
|
|
38
|
-
return item.text;
|
|
39
|
-
}
|
|
40
|
-
// Handle entities (like "Google Tag Manager")
|
|
41
|
-
if (item.entity && typeof item.entity === 'string') {
|
|
42
|
-
return item.entity;
|
|
43
|
-
}
|
|
44
|
-
// Handle nodes with selectors
|
|
45
|
-
if (item.node && typeof item.node === 'object' && 'selector' in item.node) {
|
|
46
|
-
return `Element: ${item.node.selector}`;
|
|
47
|
-
}
|
|
48
|
-
// Handle nodes with snippets
|
|
49
|
-
if (item.node && typeof item.node === 'object' && 'snippet' in item.node) {
|
|
50
|
-
const snippet = item.node.snippet;
|
|
51
|
-
return `Element: ${snippet.length > 50 ? snippet.substring(0, 50) + '...' : snippet}`;
|
|
52
|
-
}
|
|
53
|
-
// Handle origins (like domains)
|
|
54
|
-
if (item.origin && typeof item.origin === 'string') {
|
|
55
|
-
return item.origin;
|
|
56
|
-
}
|
|
57
|
-
// Handle labels
|
|
58
|
-
if (item.label && typeof item.label === 'string') {
|
|
59
|
-
return item.label;
|
|
60
|
-
}
|
|
61
|
-
// Handle numeric values with units
|
|
62
|
-
if (item.value && typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
63
|
-
const value = item.value;
|
|
64
|
-
return `${value.value}${item.unit || ''}`;
|
|
65
|
-
}
|
|
66
|
-
// Handle statistics
|
|
67
|
-
if (item.statistic && typeof item.statistic === 'string' && item.value) {
|
|
68
|
-
if (typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
69
|
-
const value = item.value;
|
|
70
|
-
return `${item.statistic}: ${value.value}`;
|
|
71
|
-
}
|
|
72
|
-
return item.statistic;
|
|
73
|
-
}
|
|
74
|
-
// Handle timing data with more context
|
|
75
|
-
if (item.duration && typeof item.duration === 'number') {
|
|
76
|
-
const duration = item.duration;
|
|
77
|
-
let context = '';
|
|
78
|
-
if (item.url && typeof item.url === 'string') {
|
|
79
|
-
context = ` for ${item.url}`;
|
|
80
|
-
}
|
|
81
|
-
else if (item.source && typeof item.source === 'string') {
|
|
82
|
-
context = ` for ${item.source}`;
|
|
83
|
-
}
|
|
84
|
-
else if (item.name && typeof item.name === 'string') {
|
|
85
|
-
context = ` for ${item.name}`;
|
|
86
|
-
}
|
|
87
|
-
return `${duration.toFixed(2)}ms${context}`;
|
|
88
|
-
}
|
|
89
|
-
// Handle response times
|
|
90
|
-
if (item.responseTime && typeof item.responseTime === 'number') {
|
|
91
|
-
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
92
|
-
return `${item.responseTime.toFixed(2)}ms response time${url}`;
|
|
93
|
-
}
|
|
94
|
-
// Handle start/end times
|
|
95
|
-
if ((item.startTime || item.endTime) && typeof (item.startTime || item.endTime) === 'number') {
|
|
96
|
-
const start = item.startTime && typeof item.startTime === 'number' ? item.startTime.toFixed(2) : '?';
|
|
97
|
-
const end = item.endTime && typeof item.endTime === 'number' ? item.endTime.toFixed(2) : '?';
|
|
98
|
-
const url = (item.url && typeof item.url === 'string') ? ` for ${item.url}` : '';
|
|
99
|
-
return `${start}ms - ${end}ms${url}`;
|
|
100
|
-
}
|
|
101
|
-
// Handle transfer size with timing
|
|
102
|
-
if (item.transferSize && typeof item.transferSize === 'number' && item.duration && typeof item.duration === 'number') {
|
|
103
|
-
const size = (item.transferSize / 1024).toFixed(1);
|
|
104
|
-
const time = item.duration.toFixed(2);
|
|
105
|
-
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
106
|
-
return `${size} KB in ${time}ms${url}`;
|
|
107
|
-
}
|
|
108
|
-
// Handle main thread time
|
|
109
|
-
if (item.mainThreadTime && typeof item.mainThreadTime === 'number') {
|
|
110
|
-
return `${item.mainThreadTime.toFixed(1)}ms`;
|
|
111
|
-
}
|
|
112
|
-
// For other objects, try to find a meaningful display
|
|
113
|
-
if (item.group && typeof item.group === 'string') {
|
|
114
|
-
return item.group;
|
|
115
|
-
}
|
|
116
|
-
if (item.type && typeof item.type === 'string') {
|
|
117
|
-
return item.type;
|
|
118
|
-
}
|
|
119
|
-
// If we can't find anything meaningful, provide a generic description
|
|
120
|
-
// This handles raw timing data that might be from various performance metrics
|
|
121
|
-
if (typeof item === 'number') {
|
|
122
|
-
let context = '';
|
|
123
|
-
if (auditTitle) {
|
|
124
|
-
if (auditTitle.toLowerCase().includes('server') || auditTitle.toLowerCase().includes('backend')) {
|
|
125
|
-
context = ' server response';
|
|
126
|
-
}
|
|
127
|
-
else if (auditTitle.toLowerCase().includes('network') || auditTitle.toLowerCase().includes('request')) {
|
|
128
|
-
context = ' network request';
|
|
129
|
-
}
|
|
130
|
-
else if (auditTitle.toLowerCase().includes('render') || auditTitle.toLowerCase().includes('blocking')) {
|
|
131
|
-
context = ' render blocking';
|
|
132
|
-
}
|
|
133
|
-
else if (auditTitle.toLowerCase().includes('javascript') || auditTitle.toLowerCase().includes('js')) {
|
|
134
|
-
context = ' JavaScript';
|
|
135
|
-
}
|
|
136
|
-
else if (auditTitle.toLowerCase().includes('image') || auditTitle.toLowerCase().includes('media')) {
|
|
137
|
-
context = ' media resource';
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return `${item.toFixed(2)}ms${context}`;
|
|
141
|
-
}
|
|
142
|
-
if (item.value && typeof item.value === 'number') {
|
|
143
|
-
const unit = item.unit || 'ms';
|
|
144
|
-
let context = '';
|
|
145
|
-
if (auditTitle && unit === 'ms') {
|
|
146
|
-
if (auditTitle.toLowerCase().includes('server')) {
|
|
147
|
-
context = ' server time';
|
|
148
|
-
}
|
|
149
|
-
else if (auditTitle.toLowerCase().includes('network')) {
|
|
150
|
-
context = ' network time';
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return `${item.value.toFixed(2)}${unit}${context}`;
|
|
154
|
-
}
|
|
155
|
-
return 'Details available';
|
|
156
|
-
};
|
|
157
20
|
const psiData = data?.psiData?.data?.[0];
|
|
158
21
|
if (!psiData) {
|
|
159
22
|
return (_jsx("p", { style: { color: '#6b7280' }, children: "No security data available for this site." }));
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { SiteHealthTemplate } from './site-health-template';
|
|
6
|
-
import {
|
|
6
|
+
import { formatAuditItem, getAuditScoreIcon, getScoreColor } from './site-health-utils';
|
|
7
7
|
SiteHealthSEO.propTypes = {
|
|
8
8
|
siteName: PropTypes.string.isRequired,
|
|
9
9
|
};
|
|
@@ -17,98 +17,6 @@ export function SiteHealthSEO({ siteName }) {
|
|
|
17
17
|
return result;
|
|
18
18
|
}, []);
|
|
19
19
|
return (_jsx(SiteHealthTemplate, { siteName: siteName, title: "PageSpeed - SEO", fetchData: fetchSEOData, children: (data) => {
|
|
20
|
-
const getScoreColor = (score) => {
|
|
21
|
-
return getScoreIndicator(score).color;
|
|
22
|
-
};
|
|
23
|
-
const getAuditScoreIcon = (score) => {
|
|
24
|
-
return getScoreIndicator(score).icon;
|
|
25
|
-
};
|
|
26
|
-
// Helper function to display audit item details
|
|
27
|
-
const formatAuditItem = (item, auditTitle) => {
|
|
28
|
-
// Handle URLs
|
|
29
|
-
if (item.url && typeof item.url === 'string') {
|
|
30
|
-
return item.url;
|
|
31
|
-
}
|
|
32
|
-
// Handle sources (like JavaScript files)
|
|
33
|
-
if (item.source && typeof item.source === 'string') {
|
|
34
|
-
return item.source;
|
|
35
|
-
}
|
|
36
|
-
// Handle text descriptions
|
|
37
|
-
if (item.text && typeof item.text === 'string') {
|
|
38
|
-
return item.text;
|
|
39
|
-
}
|
|
40
|
-
// Handle entities (like "Google Tag Manager")
|
|
41
|
-
if (item.entity && typeof item.entity === 'string') {
|
|
42
|
-
return item.entity;
|
|
43
|
-
}
|
|
44
|
-
// Handle nodes with selectors
|
|
45
|
-
if (item.node && typeof item.node === 'object' && 'selector' in item.node) {
|
|
46
|
-
return `Element: ${item.node.selector}`;
|
|
47
|
-
}
|
|
48
|
-
// Handle nodes with snippets
|
|
49
|
-
if (item.node && typeof item.node === 'object' && 'snippet' in item.node) {
|
|
50
|
-
const snippet = item.node.snippet;
|
|
51
|
-
return `Element: ${snippet.length > 50 ? snippet.substring(0, 50) + '...' : snippet}`;
|
|
52
|
-
}
|
|
53
|
-
// Handle origins (like domains)
|
|
54
|
-
if (item.origin && typeof item.origin === 'string') {
|
|
55
|
-
return item.origin;
|
|
56
|
-
}
|
|
57
|
-
// Handle labels
|
|
58
|
-
if (item.label && typeof item.label === 'string') {
|
|
59
|
-
return item.label;
|
|
60
|
-
}
|
|
61
|
-
// Handle numeric values with units
|
|
62
|
-
if (item.value && typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
63
|
-
const value = item.value;
|
|
64
|
-
return `${value.value}${item.unit || ''}`;
|
|
65
|
-
}
|
|
66
|
-
// Handle statistics
|
|
67
|
-
if (item.statistic && typeof item.statistic === 'string' && item.value) {
|
|
68
|
-
if (typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
69
|
-
const value = item.value;
|
|
70
|
-
return `${item.statistic}: ${value.value}`;
|
|
71
|
-
}
|
|
72
|
-
return item.statistic;
|
|
73
|
-
}
|
|
74
|
-
// Handle timing data with audit context
|
|
75
|
-
if (typeof item === 'number') {
|
|
76
|
-
let context = '';
|
|
77
|
-
if (auditTitle) {
|
|
78
|
-
if (auditTitle.toLowerCase().includes('server') || auditTitle.toLowerCase().includes('backend')) {
|
|
79
|
-
context = ' server response';
|
|
80
|
-
}
|
|
81
|
-
else if (auditTitle.toLowerCase().includes('network') || auditTitle.toLowerCase().includes('request')) {
|
|
82
|
-
context = ' network request';
|
|
83
|
-
}
|
|
84
|
-
else if (auditTitle.toLowerCase().includes('render') || auditTitle.toLowerCase().includes('blocking')) {
|
|
85
|
-
context = ' render blocking';
|
|
86
|
-
}
|
|
87
|
-
else if (auditTitle.toLowerCase().includes('javascript') || auditTitle.toLowerCase().includes('js')) {
|
|
88
|
-
context = ' JavaScript';
|
|
89
|
-
}
|
|
90
|
-
else if (auditTitle.toLowerCase().includes('image') || auditTitle.toLowerCase().includes('media')) {
|
|
91
|
-
context = ' media resource';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return `${item.toFixed(2)}ms${context}`;
|
|
95
|
-
}
|
|
96
|
-
if (item.value && typeof item.value === 'number') {
|
|
97
|
-
const unit = item.unit || 'ms';
|
|
98
|
-
let context = '';
|
|
99
|
-
if (auditTitle && unit === 'ms') {
|
|
100
|
-
if (auditTitle.toLowerCase().includes('server')) {
|
|
101
|
-
context = ' server time';
|
|
102
|
-
}
|
|
103
|
-
else if (auditTitle.toLowerCase().includes('network')) {
|
|
104
|
-
context = ' network time';
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return `${item.value.toFixed(2)}${unit}${context}`;
|
|
108
|
-
}
|
|
109
|
-
// If we can't find anything meaningful, show a generic message
|
|
110
|
-
return 'Details available';
|
|
111
|
-
};
|
|
112
20
|
if (!data?.data || data.data.length === 0) {
|
|
113
21
|
return (_jsx("p", { style: { color: '#6b7280' }, children: "No SEO data available for this site." }));
|
|
114
22
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// Shared utilities for site-health components
|
|
2
|
+
// This file contains common functions used across multiple site-health components
|
|
3
|
+
import { getScoreIndicator } from './site-health-indicators';
|
|
4
|
+
/**
|
|
5
|
+
* Gets the icon for a score
|
|
6
|
+
*/
|
|
7
|
+
export function getAuditScoreIcon(score) {
|
|
8
|
+
return getScoreIndicator(score).icon;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Gets the color for a score
|
|
12
|
+
*/
|
|
13
|
+
export function getScoreColor(score) {
|
|
14
|
+
return getScoreIndicator(score).color;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Formats a score for display
|
|
18
|
+
*/
|
|
19
|
+
export function formatScore(score) {
|
|
20
|
+
if (score === null)
|
|
21
|
+
return 'N/A';
|
|
22
|
+
return `${Math.round(score * 100)}%`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Formats audit item details for display
|
|
26
|
+
*/
|
|
27
|
+
export function formatAuditItem(item, auditTitle) {
|
|
28
|
+
// Handle URLs
|
|
29
|
+
if (item.url && typeof item.url === 'string') {
|
|
30
|
+
return item.url;
|
|
31
|
+
}
|
|
32
|
+
// Handle sources (like JavaScript files)
|
|
33
|
+
if (item.source && typeof item.source === 'string') {
|
|
34
|
+
return item.source;
|
|
35
|
+
}
|
|
36
|
+
// Handle text descriptions
|
|
37
|
+
if (item.text && typeof item.text === 'string') {
|
|
38
|
+
return item.text;
|
|
39
|
+
}
|
|
40
|
+
// Handle entities (like "Google Tag Manager")
|
|
41
|
+
if (item.entity && typeof item.entity === 'string') {
|
|
42
|
+
return item.entity;
|
|
43
|
+
}
|
|
44
|
+
// Handle nodes with selectors
|
|
45
|
+
if (item.node && typeof item.node === 'object' && 'selector' in item.node) {
|
|
46
|
+
return `Element: ${item.node.selector}`;
|
|
47
|
+
}
|
|
48
|
+
// Handle nodes with snippets
|
|
49
|
+
if (item.node && typeof item.node === 'object' && 'snippet' in item.node) {
|
|
50
|
+
const snippet = item.node.snippet;
|
|
51
|
+
return `Element: ${snippet.length > 50 ? snippet.substring(0, 50) + '...' : snippet}`;
|
|
52
|
+
}
|
|
53
|
+
// Handle origins (like domains)
|
|
54
|
+
if (item.origin && typeof item.origin === 'string') {
|
|
55
|
+
return item.origin;
|
|
56
|
+
}
|
|
57
|
+
// Handle labels
|
|
58
|
+
if (item.label && typeof item.label === 'string') {
|
|
59
|
+
return item.label;
|
|
60
|
+
}
|
|
61
|
+
// Handle numeric values with units
|
|
62
|
+
if (item.value && typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
63
|
+
const value = item.value;
|
|
64
|
+
return `${value.value}${item.unit || ''}`;
|
|
65
|
+
}
|
|
66
|
+
// Handle statistics
|
|
67
|
+
if (item.statistic && typeof item.statistic === 'string' && item.value) {
|
|
68
|
+
if (typeof item.value === 'object' && 'type' in item.value && item.value.type === 'numeric') {
|
|
69
|
+
const value = item.value;
|
|
70
|
+
return `${item.statistic}: ${value.value}`;
|
|
71
|
+
}
|
|
72
|
+
return item.statistic;
|
|
73
|
+
}
|
|
74
|
+
// Handle timing data with audit context
|
|
75
|
+
if (typeof item === 'number') {
|
|
76
|
+
let context = '';
|
|
77
|
+
if (auditTitle) {
|
|
78
|
+
if (auditTitle.toLowerCase().includes('server') || auditTitle.toLowerCase().includes('backend')) {
|
|
79
|
+
context = ' server response';
|
|
80
|
+
}
|
|
81
|
+
else if (auditTitle.toLowerCase().includes('network') || auditTitle.toLowerCase().includes('request')) {
|
|
82
|
+
context = ' network request';
|
|
83
|
+
}
|
|
84
|
+
else if (auditTitle.toLowerCase().includes('render') || auditTitle.toLowerCase().includes('blocking')) {
|
|
85
|
+
context = ' render blocking';
|
|
86
|
+
}
|
|
87
|
+
else if (auditTitle.toLowerCase().includes('javascript') || auditTitle.toLowerCase().includes('js')) {
|
|
88
|
+
context = ' JavaScript';
|
|
89
|
+
}
|
|
90
|
+
else if (auditTitle.toLowerCase().includes('image') || auditTitle.toLowerCase().includes('media')) {
|
|
91
|
+
context = ' media resource';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return `${item.toFixed(2)}ms${context}`;
|
|
95
|
+
}
|
|
96
|
+
if (item.value && typeof item.value === 'number') {
|
|
97
|
+
const unit = item.unit || 'ms';
|
|
98
|
+
let context = '';
|
|
99
|
+
if (auditTitle && unit === 'ms') {
|
|
100
|
+
if (auditTitle.toLowerCase().includes('server')) {
|
|
101
|
+
context = ' server time';
|
|
102
|
+
}
|
|
103
|
+
else if (auditTitle.toLowerCase().includes('network')) {
|
|
104
|
+
context = ' network time';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return `${item.value.toFixed(2)}${unit}${context}`;
|
|
108
|
+
}
|
|
109
|
+
// Handle timing data with more context
|
|
110
|
+
if (item.duration && typeof item.duration === 'number') {
|
|
111
|
+
const duration = item.duration;
|
|
112
|
+
let context = '';
|
|
113
|
+
if (item.url && typeof item.url === 'string') {
|
|
114
|
+
context = ` for ${item.url}`;
|
|
115
|
+
}
|
|
116
|
+
else if (item.source && typeof item.source === 'string') {
|
|
117
|
+
context = ` for ${item.source}`;
|
|
118
|
+
}
|
|
119
|
+
else if (item.name && typeof item.name === 'string') {
|
|
120
|
+
context = ` for ${item.name}`;
|
|
121
|
+
}
|
|
122
|
+
else if (item.path && typeof item.path === 'string') {
|
|
123
|
+
context = ` for ${item.path}`;
|
|
124
|
+
}
|
|
125
|
+
else if (item.request && typeof item.request === 'string') {
|
|
126
|
+
context = ` for ${item.request}`;
|
|
127
|
+
}
|
|
128
|
+
return `${duration.toFixed(2)}ms${context}`;
|
|
129
|
+
}
|
|
130
|
+
// Handle response times
|
|
131
|
+
if (item.responseTime && typeof item.responseTime === 'number') {
|
|
132
|
+
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
133
|
+
return `${item.responseTime.toFixed(2)}ms response time${url}`;
|
|
134
|
+
}
|
|
135
|
+
// Handle start/end times
|
|
136
|
+
if ((item.startTime || item.endTime) && typeof (item.startTime || item.endTime) === 'number') {
|
|
137
|
+
const start = item.startTime && typeof item.startTime === 'number' ? item.startTime.toFixed(2) : '?';
|
|
138
|
+
const end = item.endTime && typeof item.endTime === 'number' ? item.endTime.toFixed(2) : '?';
|
|
139
|
+
const url = (item.url && typeof item.url === 'string') ? ` for ${item.url}` : '';
|
|
140
|
+
return `${start}ms - ${end}ms${url}`;
|
|
141
|
+
}
|
|
142
|
+
// Handle transfer size with timing
|
|
143
|
+
if (item.transferSize && typeof item.transferSize === 'number' && item.duration && typeof item.duration === 'number') {
|
|
144
|
+
const size = (item.transferSize / 1024).toFixed(1);
|
|
145
|
+
const time = item.duration.toFixed(2);
|
|
146
|
+
const url = (item.url && typeof item.url === 'string') ? ` (${item.url})` : '';
|
|
147
|
+
return `${size} KB in ${time}ms${url}`;
|
|
148
|
+
}
|
|
149
|
+
// Handle main thread time
|
|
150
|
+
if (item.mainThreadTime && typeof item.mainThreadTime === 'number') {
|
|
151
|
+
return `${item.mainThreadTime.toFixed(1)}ms`;
|
|
152
|
+
}
|
|
153
|
+
// For other objects, try to find a meaningful display
|
|
154
|
+
if (item.group && typeof item.group === 'string') {
|
|
155
|
+
return item.group;
|
|
156
|
+
}
|
|
157
|
+
if (item.type && typeof item.type === 'string') {
|
|
158
|
+
return item.type;
|
|
159
|
+
}
|
|
160
|
+
// If we can't find anything meaningful, provide a generic description
|
|
161
|
+
// This handles raw timing data that might be from various performance metrics
|
|
162
|
+
if (typeof item === 'number') {
|
|
163
|
+
return `${item.toFixed(2)}ms`;
|
|
164
|
+
}
|
|
165
|
+
if (item.value && typeof item.value === 'number') {
|
|
166
|
+
const unit = item.unit || 'ms';
|
|
167
|
+
return `${item.value.toFixed(2)}${unit}`;
|
|
168
|
+
}
|
|
169
|
+
return 'Performance metric data available';
|
|
170
|
+
}
|
|
@@ -425,7 +425,7 @@ th, td {
|
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
/* Helper & Semantic classes */
|
|
428
|
-
.health-audit-list > * + * { margin-top: 0.
|
|
428
|
+
.health-audit-list > * + * { margin-top: 0.0rem; }
|
|
429
429
|
.health-section-list > * + * { margin-top: 1rem; }
|
|
430
430
|
|
|
431
431
|
.health-text-muted { color: #9ca3af; }
|
|
@@ -450,14 +450,6 @@ th, td {
|
|
|
450
450
|
font-weight: 500;
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
.health-truncate-text {
|
|
454
|
-
max-width: 20rem;
|
|
455
|
-
white-space: nowrap;
|
|
456
|
-
overflow: hidden;
|
|
457
|
-
text-overflow: ellipsis;
|
|
458
|
-
display: inline-block;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
453
|
.health-empty-state {
|
|
462
454
|
text-align: center;
|
|
463
455
|
padding: 1rem 0;
|
|
@@ -23,6 +23,7 @@ export * from './components/admin/site-health/site-health-indicators';
|
|
|
23
23
|
export * from './components/admin/site-health/site-health-on-site-seo.integration';
|
|
24
24
|
export * from './components/admin/site-health/site-health-types';
|
|
25
25
|
export * from './components/admin/site-health/site-health-performance';
|
|
26
|
+
export * from './components/admin/site-health/site-health-utils';
|
|
26
27
|
export * from './components/admin/site-health/site-health-cache';
|
|
27
28
|
export * from './components/admin/site-health/site-health-indicators';
|
|
28
29
|
export * from './components/admin/site-health/site-health-on-site-seo.integration';
|
|
@@ -14,6 +14,7 @@ export * from './components/admin/site-health/site-health-cloudwatch.integration
|
|
|
14
14
|
export * from './components/admin/site-health/seo-constants';
|
|
15
15
|
export * from './components/admin/site-health/site-health-security.integration';
|
|
16
16
|
export * from './components/admin/site-health/site-health-types';
|
|
17
|
+
export * from './components/admin/site-health/site-health-utils';
|
|
17
18
|
export * from './components/admin/site-health/site-health-uptime.integration';
|
|
18
19
|
export * from './components/admin/sites/sites.integration';
|
|
19
20
|
export * from './components/cms/contentful.management';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-accessibility.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-accessibility.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-accessibility.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-accessibility.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASnD,MAAM,MAAM,2BAA2B,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;AAC/F,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE,2BAA2B,2CAsJhF;yBAtJe,uBAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-on-site-seo.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-on-site-seo.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-on-site-seo.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-on-site-seo.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAsJnD,MAAM,MAAM,uBAAuB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,SAAS,CAAC,CAAC;AACvF,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE,uBAAuB,2CAgIxE;yBAhIe,mBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-overview.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-overview.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-overview.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-overview.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASnD,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;AACrF,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,sBAAsB,2CA2KtE;yBA3Ke,kBAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-performance.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-performance.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-performance.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-performance.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASnD,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC3F,wBAAgB,qBAAqB,CAAC,EAAE,QAAQ,EAAE,EAAE,yBAAyB,2CAiH5E;yBAjHe,qBAAqB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-security.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-security.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-security.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-security.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAanD,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAC;AACrF,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,EAAE,sBAAsB,2CAmHtE;yBAnHe,kBAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-health-seo.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-seo.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"site-health-seo.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-seo.tsx"],"names":[],"mappings":"AAGA,OAAO,SAAS,EAAE,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AASnD,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;AAC3E,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CAoH5D;yBApHe,aAAa"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gets the icon for a score
|
|
3
|
+
*/
|
|
4
|
+
export declare function getAuditScoreIcon(score: number | null): string;
|
|
5
|
+
/**
|
|
6
|
+
* Gets the color for a score
|
|
7
|
+
*/
|
|
8
|
+
export declare function getScoreColor(score: number | null): string;
|
|
9
|
+
/**
|
|
10
|
+
* Formats a score for display
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatScore(score: number | null): string;
|
|
13
|
+
/**
|
|
14
|
+
* Formats audit item details for display
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatAuditItem(item: Record<string, unknown>, auditTitle?: string): string;
|
|
17
|
+
//# sourceMappingURL=site-health-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site-health-utils.d.ts","sourceRoot":"","sources":["../../../../../src/components/admin/site-health/site-health-utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGxD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CA2J1F"}
|
|
@@ -19,6 +19,7 @@ export * from "./components/admin/site-health/site-health-indicators";
|
|
|
19
19
|
export * from "./components/admin/site-health/site-health-on-site-seo.integration";
|
|
20
20
|
export * from "./components/admin/site-health/site-health-types";
|
|
21
21
|
export * from "./components/admin/site-health/site-health-performance";
|
|
22
|
+
export * from "./components/admin/site-health/site-health-utils";
|
|
22
23
|
export * from "./components/admin/site-health/site-health-cache";
|
|
23
24
|
export * from "./components/admin/site-health/site-health-indicators";
|
|
24
25
|
export * from "./components/admin/site-health/site-health-on-site-seo.integration";
|
|
@@ -14,6 +14,7 @@ export * from "./components/admin/site-health/site-health-cloudwatch.integration
|
|
|
14
14
|
export * from "./components/admin/site-health/seo-constants";
|
|
15
15
|
export * from "./components/admin/site-health/site-health-security.integration";
|
|
16
16
|
export * from "./components/admin/site-health/site-health-types";
|
|
17
|
+
export * from "./components/admin/site-health/site-health-utils";
|
|
17
18
|
export * from "./components/admin/site-health/site-health-uptime.integration";
|
|
18
19
|
export * from "./components/admin/sites/sites.integration";
|
|
19
20
|
export * from "./components/cms/contentful.management";
|