Add View in CARD button to tooltip and action modal

Copies the Ivanti Host ID to clipboard and opens card.charter.com/ipn-search
in a new tab. ESSO prevents URL-based pre-fill so the user pastes the ID.
This commit is contained in:
Jordan Ramos
2026-06-09 12:28:56 -06:00
parent a8d3909798
commit f3319ee1f5
2 changed files with 62 additions and 8 deletions

View File

@@ -9,10 +9,9 @@
import React, { useState, useEffect, useRef, useLayoutEffect, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { Loader, AlertCircle, ExternalLink } from 'lucide-react';
import { Loader, AlertCircle, ExternalLink, Copy } from 'lucide-react';
// ⚠️ CONVENTION: Use relative API path from REACT_APP_API_BASE only (no absolute URL fallback).
// Other components use: const API_BASE = process.env.REACT_APP_API_BASE || '/api';
// ⚠️ CONVENTION: Use relative API path fallback, not absolute URL. Should be: process.env.REACT_APP_API_BASE || '/api'
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
const TOOLTIP_GAP = 8;
@@ -136,6 +135,7 @@ export default function CardOwnerTooltip({ ip, hostId, anchorRect, cache, cardCo
error={error}
anchorRect={anchorRect}
ip={ip}
hostId={hostId}
onAction={onAction}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
@@ -147,7 +147,7 @@ export default function CardOwnerTooltip({ ip, hostId, anchorRect, cache, cardCo
// ---------------------------------------------------------------------------
// TooltipBody — inner component for measurement + rendering
// ---------------------------------------------------------------------------
function TooltipBody({ data, loading, error, anchorRect, ip, onAction, onMouseEnter, onMouseLeave }) {
function TooltipBody({ data, loading, error, anchorRect, ip, hostId, onAction, onMouseEnter, onMouseLeave }) {
const tooltipRef = useRef(null);
const [pos, setPos] = useState({ top: 0, left: 0, placeAbove: true });
@@ -304,7 +304,7 @@ function TooltipBody({ data, loading, error, anchorRect, ip, onAction, onMouseEn
{/* Actions button */}
{onAction && (
<div style={{ marginTop: '0.4rem', paddingTop: '0.4rem', borderTop: '1px solid rgba(124, 58, 237, 0.2)' }}>
<div style={{ marginTop: '0.4rem', paddingTop: '0.4rem', borderTop: '1px solid rgba(124, 58, 237, 0.2)', display: 'flex', gap: '0.4rem', flexWrap: 'wrap' }}>
<button
onClick={handleAction}
style={{
@@ -325,6 +325,32 @@ function TooltipBody({ data, loading, error, anchorRect, ip, onAction, onMouseEn
<ExternalLink style={{ width: 11, height: 11 }} />
Actions
</button>
{hostId && (
<button
onClick={() => {
navigator.clipboard.writeText(String(hostId));
window.open('https://card.charter.com/ipn-search', '_blank');
}}
title={`Copy Host ID ${hostId} and open CARD`}
style={{
display: 'inline-flex', alignItems: 'center', gap: '0.35rem',
padding: '0.3rem 0.65rem',
background: 'rgba(14, 165, 233, 0.12)',
border: '1px solid rgba(14, 165, 233, 0.4)',
borderRadius: '0.3rem',
color: '#7DD3FC',
fontSize: '0.65rem', fontWeight: '600', fontFamily: 'monospace',
cursor: 'pointer',
textTransform: 'uppercase', letterSpacing: '0.04em',
transition: 'all 0.12s',
}}
onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(14, 165, 233, 0.25)'; e.currentTarget.style.borderColor = 'rgba(14, 165, 233, 0.6)'; }}
onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(14, 165, 233, 0.12)'; e.currentTarget.style.borderColor = 'rgba(14, 165, 233, 0.4)'; }}
>
<Copy style={{ width: 11, height: 11 }} />
View in CARD
</button>
)}
</div>
)}
</div>