Add priority icons and prevent column wrapping
- Add getPriorityIcon() function with visual priority indicators: 🔥 VeryHigh, 🔺 High, 🟡 Medium, 🔹 Low, 🐢 VeryLow - Display priority icons in both table rows and detail view - Add priorityCell CSS class with fixed width and no-wrap styling - Update tooltip to show icon legend for all priority levels - Enhance table hover effects with brightness filter and dashed borders 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2ee9c3fc28
commit
35537b8a5b
@ -8,7 +8,8 @@ import {
|
|||||||
getTotalResponseTimeColor,
|
getTotalResponseTimeColor,
|
||||||
getQueueAnalysisIcon,
|
getQueueAnalysisIcon,
|
||||||
getCDNIcon,
|
getCDNIcon,
|
||||||
getCDNDisplayName
|
getCDNDisplayName,
|
||||||
|
getPriorityIcon
|
||||||
} from './lib/colorUtils'
|
} from './lib/colorUtils'
|
||||||
|
|
||||||
interface RequestRowDetailsProps {
|
interface RequestRowDetailsProps {
|
||||||
@ -27,7 +28,12 @@ const RequestRowDetails: React.FC<RequestRowDetailsProps> = ({ request }) => {
|
|||||||
<div className={styles.detailList}>
|
<div className={styles.detailList}>
|
||||||
<div className={styles.detailListItem}><strong>Request ID:</strong> {request.requestId}</div>
|
<div className={styles.detailListItem}><strong>Request ID:</strong> {request.requestId}</div>
|
||||||
<div className={styles.detailListItem}><strong>Method:</strong> {request.method}</div>
|
<div className={styles.detailListItem}><strong>Method:</strong> {request.method}</div>
|
||||||
<div className={styles.detailListItem}><strong>Priority:</strong> {request.priority}</div>
|
<div className={styles.detailListItem}>
|
||||||
|
<strong>Priority:</strong>
|
||||||
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: '4px', marginLeft: '4px' }}>
|
||||||
|
{getPriorityIcon(request.priority)} {request.priority || '-'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div className={styles.detailListItem}><strong>MIME Type:</strong> {request.mimeType || '-'}</div>
|
<div className={styles.detailListItem}><strong>MIME Type:</strong> {request.mimeType || '-'}</div>
|
||||||
<div className={styles.detailListItem}><strong>Content-Length:</strong> {request.contentLength ? formatSize(request.contentLength) : '-'}</div>
|
<div className={styles.detailListItem}><strong>Content-Length:</strong> {request.contentLength ? formatSize(request.contentLength) : '-'}</div>
|
||||||
<div className={styles.detailListItem}><strong>From Cache:</strong> {request.fromCache ? 'Yes' : 'No'}</div>
|
<div className={styles.detailListItem}><strong>From Cache:</strong> {request.fromCache ? 'Yes' : 'No'}</div>
|
||||||
|
@ -19,11 +19,34 @@
|
|||||||
td {
|
td {
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
border-radius: var(--radius-md);
|
border-radius: var(--radius-md);
|
||||||
|
border: 1px solid var(--color-bg);
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
border: 1px solid #ffffff;
|
border: 1px solid #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tr:hover, tr:hover td {
|
||||||
|
border: 1px dashed var(--color-bg-hover);
|
||||||
|
}
|
||||||
|
tr:hover {
|
||||||
|
filter: brightness(290%);
|
||||||
|
}
|
||||||
a {
|
a {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Priority cell styling to prevent wrapping */
|
||||||
|
.priorityCell {
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 120px;
|
||||||
|
width: 120px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.priorityCell span {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
@ -13,7 +13,10 @@ import {
|
|||||||
getSizeClass,
|
getSizeClass,
|
||||||
getQueueAnalysisIcon,
|
getQueueAnalysisIcon,
|
||||||
getCDNIcon,
|
getCDNIcon,
|
||||||
getCDNDisplayName, getProtocolClass, getConnectionClass
|
getCDNDisplayName,
|
||||||
|
getPriorityIcon,
|
||||||
|
getProtocolClass,
|
||||||
|
getConnectionClass
|
||||||
} from './lib/colorUtils'
|
} from './lib/colorUtils'
|
||||||
import { truncateUrl } from './lib/urlUtils'
|
import { truncateUrl } from './lib/urlUtils'
|
||||||
|
|
||||||
@ -47,8 +50,11 @@ const RequestRowSummary: React.FC<RequestRowSummaryProps> = ({
|
|||||||
<td>
|
<td>
|
||||||
{request.resourceType}
|
{request.resourceType}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td className={styles.priorityCell}>
|
||||||
|
<span>
|
||||||
|
{getPriorityIcon(request.priority)}
|
||||||
{request.priority || '-'}
|
{request.priority || '-'}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href={request.url} target="_blank" rel="noopener noreferrer">
|
<a href={request.url} target="_blank" rel="noopener noreferrer">
|
||||||
|
@ -166,3 +166,17 @@ export const getCDNDisplayName = (provider: CDNAnalysis['provider']): string =>
|
|||||||
default: return 'Unknown CDN'
|
default: return 'Unknown CDN'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getPriorityIcon = (priority?: string): string => {
|
||||||
|
if (!priority) return '➖'
|
||||||
|
|
||||||
|
const upperPriority = priority.toUpperCase()
|
||||||
|
switch (upperPriority) {
|
||||||
|
case 'VERYHIGH': return '🔥' // Very high priority - fire/urgent
|
||||||
|
case 'HIGH': return '🔺' // High priority - red triangle up
|
||||||
|
case 'MEDIUM': return '🟡' // Medium priority - yellow circle
|
||||||
|
case 'LOW': return '🔹' // Low priority - red triangle down
|
||||||
|
case 'VERYLOW': return '🐢' // Very low priority - small blue diamond
|
||||||
|
default: return '➖' // Unknown/empty priority
|
||||||
|
}
|
||||||
|
}
|
@ -23,66 +23,23 @@ export function Tooltip({ children, type }: TooltipProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ position: 'relative', display: 'inline-flex', alignItems: 'center' }}>
|
<div>
|
||||||
{children}
|
{children}
|
||||||
<span
|
<span
|
||||||
onMouseEnter={() => setIsHovered(true)}
|
onClick={handleIconClick}>
|
||||||
onMouseLeave={() => setIsHovered(false)}
|
|
||||||
onClick={handleIconClick}
|
|
||||||
style={{
|
|
||||||
marginLeft: '6px',
|
|
||||||
cursor: 'pointer',
|
|
||||||
color: '#007bff',
|
|
||||||
fontSize: '14px',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
width: '16px',
|
|
||||||
height: '16px',
|
|
||||||
borderRadius: '50%',
|
|
||||||
backgroundColor: '#e3f2fd',
|
|
||||||
display: 'inline-flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
userSelect: 'none',
|
|
||||||
transition: 'all 0.2s ease',
|
|
||||||
border: '1px solid transparent'
|
|
||||||
}}
|
|
||||||
onMouseDown={(e) => {
|
|
||||||
e.currentTarget.style.backgroundColor = '#bbdefb'
|
|
||||||
e.currentTarget.style.borderColor = '#2196f3'
|
|
||||||
}}
|
|
||||||
onMouseUp={(e) => {
|
|
||||||
e.currentTarget.style.backgroundColor = '#e3f2fd'
|
|
||||||
e.currentTarget.style.borderColor = 'transparent'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
?
|
?
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{/* Hover tooltip - only show when not modal open */}
|
{/* Hover tooltip - only show when not modal open */}
|
||||||
{isHovered && !isModalOpen && (
|
{isHovered && !isModalOpen && (
|
||||||
<div style={{
|
<div>
|
||||||
position: 'absolute',
|
<div>
|
||||||
top: '25px',
|
|
||||||
left: '0',
|
|
||||||
backgroundColor: '#333',
|
|
||||||
color: 'white',
|
|
||||||
padding: '8px 12px',
|
|
||||||
borderRadius: '6px',
|
|
||||||
fontSize: '12px',
|
|
||||||
lineHeight: '1.4',
|
|
||||||
maxWidth: '300px',
|
|
||||||
zIndex: 1000,
|
|
||||||
boxShadow: '0 4px 8px rgba(0,0,0,0.3)',
|
|
||||||
whiteSpace: 'normal',
|
|
||||||
pointerEvents: 'none'
|
|
||||||
}}>
|
|
||||||
<div style={{ fontWeight: 'bold', marginBottom: '4px', color: '#4fc3f7' }}>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ marginBottom: '6px' }}>
|
<div>
|
||||||
{description}
|
{description}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: '11px', color: '#90caf9', fontStyle: 'italic' }}>
|
<div>
|
||||||
Click for detailed information
|
Click for detailed information
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -95,113 +52,45 @@ export function Tooltip({ children, type }: TooltipProps) {
|
|||||||
onClose={() => setIsModalOpen(false)}
|
onClose={() => setIsModalOpen(false)}
|
||||||
title={title}
|
title={title}
|
||||||
>
|
>
|
||||||
<div style={{ lineHeight: '1.6' }}>
|
<div>
|
||||||
<div style={{
|
<div>
|
||||||
marginBottom: '20px',
|
|
||||||
fontSize: '15px',
|
|
||||||
color: '#495057'
|
|
||||||
}}>
|
|
||||||
{description}
|
{description}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{lighthouseRelation && (
|
{lighthouseRelation && (
|
||||||
<div style={{
|
<div>
|
||||||
marginBottom: '20px',
|
<div>
|
||||||
padding: '15px',
|
|
||||||
backgroundColor: '#fff3e0',
|
|
||||||
borderRadius: '6px',
|
|
||||||
borderLeft: '4px solid #ffb74d'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: '8px',
|
|
||||||
color: '#e65100',
|
|
||||||
fontSize: '14px'
|
|
||||||
}}>
|
|
||||||
🎯 Lighthouse Relationship
|
🎯 Lighthouse Relationship
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: '#5d4037', fontSize: '14px' }}>
|
<div>
|
||||||
{lighthouseRelation}
|
{lighthouseRelation}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{calculation && (
|
{calculation && (
|
||||||
<div style={{
|
<div>
|
||||||
marginBottom: '20px',
|
<div>
|
||||||
padding: '15px',
|
|
||||||
backgroundColor: '#e8f5e8',
|
|
||||||
borderRadius: '6px',
|
|
||||||
borderLeft: '4px solid #81c784'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: '8px',
|
|
||||||
color: '#2e7d32',
|
|
||||||
fontSize: '14px'
|
|
||||||
}}>
|
|
||||||
🧮 Calculation
|
🧮 Calculation
|
||||||
</div>
|
</div>
|
||||||
<div style={{
|
<div>
|
||||||
color: '#1b5e20',
|
|
||||||
fontSize: '14px',
|
|
||||||
fontFamily: 'monospace',
|
|
||||||
backgroundColor: '#f1f8e9',
|
|
||||||
padding: '8px',
|
|
||||||
borderRadius: '4px',
|
|
||||||
border: '1px solid #c8e6c9'
|
|
||||||
}}>
|
|
||||||
{calculation}
|
{calculation}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{links && links.length > 0 && (
|
{links && links.length > 0 && (
|
||||||
<div style={{
|
<div>
|
||||||
padding: '15px',
|
<div>
|
||||||
backgroundColor: '#f3e5f5',
|
|
||||||
borderRadius: '6px',
|
|
||||||
borderLeft: '4px solid #ba68c8'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: '12px',
|
|
||||||
color: '#6a1b9a',
|
|
||||||
fontSize: '14px'
|
|
||||||
}}>
|
|
||||||
📚 Learn More
|
📚 Learn More
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
<div>
|
||||||
{links.map((link, index) => (
|
{links.map((link, index) => (
|
||||||
<a
|
<a
|
||||||
key={index}
|
key={index}
|
||||||
href={link.url}
|
href={link.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer">
|
||||||
style={{
|
|
||||||
color: '#1976d2',
|
|
||||||
textDecoration: 'none',
|
|
||||||
fontSize: '14px',
|
|
||||||
padding: '8px 12px',
|
|
||||||
backgroundColor: 'white',
|
|
||||||
borderRadius: '4px',
|
|
||||||
border: '1px solid #e3f2fd',
|
|
||||||
transition: 'all 0.2s ease',
|
|
||||||
display: 'inline-block'
|
|
||||||
}}
|
|
||||||
onMouseEnter={(e) => {
|
|
||||||
e.currentTarget.style.backgroundColor = '#e3f2fd'
|
|
||||||
e.currentTarget.style.borderColor = '#2196f3'
|
|
||||||
e.currentTarget.style.transform = 'translateY(-1px)'
|
|
||||||
e.currentTarget.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)'
|
|
||||||
}}
|
|
||||||
onMouseLeave={(e) => {
|
|
||||||
e.currentTarget.style.backgroundColor = 'white'
|
|
||||||
e.currentTarget.style.borderColor = '#e3f2fd'
|
|
||||||
e.currentTarget.style.transform = 'translateY(0)'
|
|
||||||
e.currentTarget.style.boxShadow = 'none'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
🔗 {link.text}
|
🔗 {link.text}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
|
@ -85,7 +85,7 @@ export const TOOLTIP_DEFINITIONS: Record<TooltipTypeValues, TooltipDefinition> =
|
|||||||
|
|
||||||
[TooltipType.REQUEST_PRIORITY]: {
|
[TooltipType.REQUEST_PRIORITY]: {
|
||||||
title: "Request Priority",
|
title: "Request Priority",
|
||||||
description: "Browser's internal priority for this request: VeryHigh, High, Medium, Low, VeryLow. Determines resource loading order.",
|
description: "Browser's internal priority for this request. Icons: 🔥 VeryHigh, 🔺 High, 🟡 Medium, 🔹 Low, 🐢 VeryLow. Determines resource loading order.",
|
||||||
lighthouseRelation: "High priority resources are critical for LCP and FCP. Low priority resources should not block critical content.",
|
lighthouseRelation: "High priority resources are critical for LCP and FCP. Low priority resources should not block critical content.",
|
||||||
links: [
|
links: [
|
||||||
{ text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" },
|
{ text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" },
|
||||||
|
Loading…
Reference in New Issue
Block a user