reduces clickable space to the external link icon and the service name and added a tooltip to show truncated paths at the pointer

This commit is contained in:
findthelorax
2026-04-22 08:49:58 -04:00
committed by Pouzor
parent 4ee68b839c
commit c1dad1a5ae
+74 -31
View File
@@ -671,27 +671,53 @@ function ServiceBadge({ svc, host, onEdit, onRemove }: { svc: ServiceInfo; host?
const pathMaxWidth = Math.max(0, maxTotalWidth - nameWidth - 60); const pathMaxWidth = Math.max(0, maxTotalWidth - nameWidth - 60);
const showPath = pathLabel && pathMaxWidth > 30; const showPath = pathLabel && pathMaxWidth > 30;
const [tooltip, setTooltip] = useState<{ visible: boolean; x: number; y: number; text: string }>({ visible: false, x: 0, y: 0, text: '' });
return ( return (
<div <div
className="group flex items-center border rounded-md text-xs transition-colors px-2 py-1.5 min-w-0" className="group flex items-center border rounded-md text-xs transition-colors px-2 py-1.5 min-w-0"
style={{ background: '#21262d', borderColor: '#30363d', position: 'relative' }} style={{ background: '#21262d', borderColor: '#30363d', position: 'relative' }}
> >
<span className="shrink-0 w-1.5 h-1.5 rounded-full mr-1" style={{ backgroundColor: color }} /> <span className="shrink-0 w-1.5 h-1.5 rounded-full mr-1" style={{ backgroundColor: color }} />
<span {url ? (
className="font-medium truncate flex-grow min-w-0" <a
style={{ color, marginRight: 12, maxWidth: '100%' }} href={url}
title={svc.service_name} target="_blank"
tabIndex={0} rel="noopener noreferrer"
aria-label={svc.service_name} className="font-medium truncate flex-grow min-w-0"
> style={{ color, marginRight: 12, maxWidth: '100%' }}
{svc.service_name} title={svc.service_name}
</span> tabIndex={0}
aria-label={svc.service_name}
onClick={e => e.stopPropagation()}
>
{svc.service_name}
</a>
) : (
<span
className="font-medium truncate flex-grow min-w-0"
style={{ color, marginRight: 12, maxWidth: '100%' }}
title={svc.service_name}
tabIndex={0}
aria-label={svc.service_name}
>
{svc.service_name}
</span>
)}
<div className="flex items-center gap-1 shrink-0" style={{ maxWidth: 180, minWidth: 0 }}> <div className="flex items-center gap-1 shrink-0" style={{ maxWidth: 180, minWidth: 0 }}>
{showPath && ( {showPath && (
<span <span
className="truncate text-[#8b949e] text-right" className="truncate text-[#8b949e] text-right"
style={{ minWidth: 0, maxWidth: pathMaxWidth, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', display: 'block' }} style={{ minWidth: 0, maxWidth: pathMaxWidth, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', display: 'block' }}
title={pathLabel} onMouseEnter={e => {
if (e.currentTarget.offsetWidth < e.currentTarget.scrollWidth) {
setTooltip({ visible: true, x: e.clientX, y: e.clientY, text: pathLabel });
}
}}
onMouseMove={e => {
setTooltip(t => t.visible ? { ...t, x: e.clientX, y: e.clientY } : t);
}}
onMouseLeave={() => setTooltip(t => ({ ...t, visible: false }))}
tabIndex={0} tabIndex={0}
aria-label={pathLabel} aria-label={pathLabel}
> >
@@ -701,9 +727,22 @@ function ServiceBadge({ svc, host, onEdit, onRemove }: { svc: ServiceInfo; host?
{hasPort && ( {hasPort && (
<span className="font-mono text-[#8b949e]" style={{ whiteSpace: 'nowrap', flexShrink: 0 }}>{portLabel}/{svc.protocol}</span> <span className="font-mono text-[#8b949e]" style={{ whiteSpace: 'nowrap', flexShrink: 0 }}>{portLabel}/{svc.protocol}</span>
)} )}
<span className="inline-flex w-2.5 h-2.5 items-center justify-center shrink-0" aria-hidden="true"> {url ? (
{url ? <ExternalLink size={10} className="text-muted-foreground" /> : <span style={{ width: 10, display: 'inline-block' }} />} <a
</span> href={url}
target="_blank"
rel="noopener noreferrer"
className="inline-flex w-2.5 h-2.5 items-center justify-center shrink-0"
tabIndex={0}
aria-label="Open service link"
style={{ color: 'inherit' }}
onClick={e => e.stopPropagation()}
>
<ExternalLink size={10} className="text-muted-foreground" />
</a>
) : (
<span style={{ width: 10, display: 'inline-block' }} />
)}
<button <button
onClick={(e) => { e.preventDefault(); e.stopPropagation(); onEdit(); }} onClick={(e) => { e.preventDefault(); e.stopPropagation(); onEdit(); }}
className="opacity-100 transition-opacity text-[#8b949e] hover:text-[#00d4ff] ml-0.5" className="opacity-100 transition-opacity text-[#8b949e] hover:text-[#00d4ff] ml-0.5"
@@ -719,24 +758,28 @@ function ServiceBadge({ svc, host, onEdit, onRemove }: { svc: ServiceInfo; host?
<X size={10} /> <X size={10} />
</button> </button>
</div> </div>
{url && (
<a {tooltip.visible && (
href={url} <div
target="_blank" style={{
rel="noopener noreferrer" position: 'fixed',
style={{ left: tooltip.x - 50,
position: 'absolute', top: tooltip.y + 10,
left: 0, background: '#222',
top: 0, color: '#fff',
bottom: 0, padding: '2px 8px',
right: 80, borderRadius: 4,
zIndex: 1, fontSize: 12,
opacity: 0, zIndex: 9999,
}} pointerEvents: 'none',
tabIndex={-1} boxShadow: '0 2px 8px #0008',
aria-hidden="true" whiteSpace: 'nowrap',
/> overflow: 'visible'
)} }}
>
{tooltip.text}
</div>
)}
</div> </div>
); );
} }