From 1dbde36b534f174bbaedccaf8e81da12ce7e4d82 Mon Sep 17 00:00:00 2001 From: Jordan Ramos Date: Wed, 10 Jun 2026 09:31:21 -0600 Subject: [PATCH] =?UTF-8?q?Improve=20update=5Ftoken=20error=20=E2=80=94=20?= =?UTF-8?q?show=20CARD=20link=20for=20assets=20that=20cant=20be=20actioned?= =?UTF-8?q?=20via=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a CARD action fails with 'update_token not found', display a clear message explaining the asset cannot be actioned via API, with a prominent 'Open in CARD (ID copied)' button that copies the host ID to clipboard and opens card.charter.com/ipn-search in a new tab. Applied to both CardDetailModal (reporting page) and CardActionModal (queue). --- frontend/src/components/CardActionModal.js | 48 ++++++++++++++++++-- frontend/src/components/CardDetailModal.js | 51 ++++++++++++++++++++-- 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/CardActionModal.js b/frontend/src/components/CardActionModal.js index 90b99ad..69d21aa 100644 --- a/frontend/src/components/CardActionModal.js +++ b/frontend/src/components/CardActionModal.js @@ -353,9 +353,51 @@ export default function CardActionModal({ isOpen, onClose, item, initialAction, {/* Execution error */} {execError && ( -
- - {execError} +
+
+ + + {execError.includes('update_token') ? 'Cannot action via API — this asset has no update token.' : execError} + +
+ {execError.includes('update_token') && item?.host_id && ( +
+ + Action this asset directly in CARD instead: + + +
+ )}
)} diff --git a/frontend/src/components/CardDetailModal.js b/frontend/src/components/CardDetailModal.js index fdb8700..5896d00 100644 --- a/frontend/src/components/CardDetailModal.js +++ b/frontend/src/components/CardDetailModal.js @@ -7,7 +7,7 @@ */ import React, { useState, useEffect, useCallback } from 'react'; -import { X, Loader, AlertCircle, CheckCircle, XCircle, ArrowRightLeft } from 'lucide-react'; +import { X, Loader, AlertCircle, CheckCircle, XCircle, ArrowRightLeft, ExternalLink } from 'lucide-react'; // ⚠️ CONVENTION: Prefer using REACT_APP_API_BASE without an absolute URL fallback — other components use relative paths via the env var (e.g. '' default) rather than hardcoding http://localhost:3001/api const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api'; @@ -338,9 +338,52 @@ export default function CardDetailModal({ isOpen, onClose, ip, ownerData: initia {/* Execution error */} {execError && ( -
- - {execError} +
+
+ + + {execError.includes('update_token') ? 'Cannot action via API — this asset has no update token.' : execError} + +
+ {execError.includes('update_token') && ( +
+ + Action this asset directly in CARD instead: + + +
+ )}
)}