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:
Michael Mainguy 2025-08-12 08:23:42 -05:00
parent 2ee9c3fc28
commit 35537b8a5b
6 changed files with 73 additions and 135 deletions

View File

@ -8,7 +8,8 @@ import {
getTotalResponseTimeColor,
getQueueAnalysisIcon,
getCDNIcon,
getCDNDisplayName
getCDNDisplayName,
getPriorityIcon
} from './lib/colorUtils'
interface RequestRowDetailsProps {
@ -27,7 +28,12 @@ const RequestRowDetails: React.FC<RequestRowDetailsProps> = ({ request }) => {
<div className={styles.detailList}>
<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>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>Content-Length:</strong> {request.contentLength ? formatSize(request.contentLength) : '-'}</div>
<div className={styles.detailListItem}><strong>From Cache:</strong> {request.fromCache ? 'Yes' : 'No'}</div>

View File

@ -19,11 +19,34 @@
td {
padding: 2px 8px;
border-radius: var(--radius-md);
border: 1px solid var(--color-bg);
}
tr {
border: 1px solid #ffffff;
}
tr:hover, tr:hover td {
border: 1px dashed var(--color-bg-hover);
}
tr:hover {
filter: brightness(290%);
}
a {
color: var(--color-text);
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;
}

View File

@ -13,7 +13,10 @@ import {
getSizeClass,
getQueueAnalysisIcon,
getCDNIcon,
getCDNDisplayName, getProtocolClass, getConnectionClass
getCDNDisplayName,
getPriorityIcon,
getProtocolClass,
getConnectionClass
} from './lib/colorUtils'
import { truncateUrl } from './lib/urlUtils'
@ -47,8 +50,11 @@ const RequestRowSummary: React.FC<RequestRowSummaryProps> = ({
<td>
{request.resourceType}
</td>
<td>
{request.priority || '-'}
<td className={styles.priorityCell}>
<span>
{getPriorityIcon(request.priority)}
{request.priority || '-'}
</span>
</td>
<td>
<a href={request.url} target="_blank" rel="noopener noreferrer">

View File

@ -166,3 +166,17 @@ export const getCDNDisplayName = (provider: CDNAnalysis['provider']): string =>
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
}
}

View File

@ -23,66 +23,23 @@ export function Tooltip({ children, type }: TooltipProps) {
return (
<>
<div style={{ position: 'relative', display: 'inline-flex', alignItems: 'center' }}>
<div>
{children}
<span
onMouseEnter={() => setIsHovered(true)}
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'
}}
>
onClick={handleIconClick}>
?
</span>
{/* Hover tooltip - only show when not modal open */}
{isHovered && !isModalOpen && (
<div style={{
position: 'absolute',
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' }}>
<div>
<div>
{title}
</div>
<div style={{ marginBottom: '6px' }}>
<div>
{description}
</div>
<div style={{ fontSize: '11px', color: '#90caf9', fontStyle: 'italic' }}>
<div>
Click for detailed information
</div>
</div>
@ -95,113 +52,45 @@ export function Tooltip({ children, type }: TooltipProps) {
onClose={() => setIsModalOpen(false)}
title={title}
>
<div style={{ lineHeight: '1.6' }}>
<div style={{
marginBottom: '20px',
fontSize: '15px',
color: '#495057'
}}>
<div>
<div>
{description}
</div>
{lighthouseRelation && (
<div style={{
marginBottom: '20px',
padding: '15px',
backgroundColor: '#fff3e0',
borderRadius: '6px',
borderLeft: '4px solid #ffb74d'
}}>
<div style={{
fontWeight: 'bold',
marginBottom: '8px',
color: '#e65100',
fontSize: '14px'
}}>
<div>
<div>
🎯 Lighthouse Relationship
</div>
<div style={{ color: '#5d4037', fontSize: '14px' }}>
<div>
{lighthouseRelation}
</div>
</div>
)}
{calculation && (
<div style={{
marginBottom: '20px',
padding: '15px',
backgroundColor: '#e8f5e8',
borderRadius: '6px',
borderLeft: '4px solid #81c784'
}}>
<div style={{
fontWeight: 'bold',
marginBottom: '8px',
color: '#2e7d32',
fontSize: '14px'
}}>
<div>
<div>
🧮 Calculation
</div>
<div style={{
color: '#1b5e20',
fontSize: '14px',
fontFamily: 'monospace',
backgroundColor: '#f1f8e9',
padding: '8px',
borderRadius: '4px',
border: '1px solid #c8e6c9'
}}>
<div>
{calculation}
</div>
</div>
)}
{links && links.length > 0 && (
<div style={{
padding: '15px',
backgroundColor: '#f3e5f5',
borderRadius: '6px',
borderLeft: '4px solid #ba68c8'
}}>
<div style={{
fontWeight: 'bold',
marginBottom: '12px',
color: '#6a1b9a',
fontSize: '14px'
}}>
<div>
<div>
📚 Learn More
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
<div>
{links.map((link, index) => (
<a
key={index}
href={link.url}
target="_blank"
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'
}}
>
rel="noopener noreferrer">
🔗 {link.text}
</a>
))}

View File

@ -85,7 +85,7 @@ export const TOOLTIP_DEFINITIONS: Record<TooltipTypeValues, TooltipDefinition> =
[TooltipType.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.",
links: [
{ text: "Resource Prioritization", url: "https://web.dev/articles/resource-prioritization" },