Add Granite Loader to AEO Compliance page with CARD enrichment and pagination
- Add checkbox selection + Granite Loader button to compliance device table - Integrate LoaderModal for generating loader sheets from compliance devices - Add direct IP resolve path (resolveAssetId + searchByAssetId) for CARD enrichment on compliance devices without Ivanti host IDs - Add searchByAssetId helper for full enriched record via asset-search endpoint - Include NTS-AEO-ACCESS-OPS in default enrich-batch team search - Increase CARD quick-mode timeout from 15s to 30s - Add timeout vs not-found distinction in enrichment error reporting - Fix LoaderModal enriching state not resetting on modal reopen - Add pagination to compliance device table (25/50/100/200 per page) - Page resets on team, tab, filter, or search change
This commit is contained in:
@@ -95,6 +95,7 @@ export default function LoaderModal({ isOpen, onClose, initialDevices }) {
|
||||
setBulkDefaults({});
|
||||
setEnrichErrors([]);
|
||||
setValidationWarnings([]);
|
||||
setEnriching(false);
|
||||
}, [isOpen, initialDevices]);
|
||||
|
||||
// Auto-select required columns + useful defaults when operation type changes
|
||||
@@ -417,11 +418,27 @@ export default function LoaderModal({ isOpen, onClose, initialDevices }) {
|
||||
{/* Enrich errors */}
|
||||
{enrichErrors.length > 0 && (
|
||||
<div style={{ marginBottom: '0.75rem', padding: '0.5rem 0.75rem', background: 'rgba(239, 68, 68, 0.1)', border: '1px solid rgba(239, 68, 68, 0.3)', borderRadius: '0.375rem' }}>
|
||||
<div style={{ fontSize: '0.7rem', color: '#EF4444', display: 'flex', alignItems: 'center', gap: '0.3rem' }}>
|
||||
<AlertCircle style={{ width: '12px', height: '12px' }} />
|
||||
{enrichErrors.length === 1 && enrichErrors[0].ip === 'all'
|
||||
? enrichErrors[0].error
|
||||
: `${enrichErrors.length} device(s) not found in CARD`}
|
||||
<div style={{ fontSize: '0.7rem', color: '#EF4444', display: 'flex', alignItems: 'center', gap: '0.3rem', justifyContent: 'space-between' }}>
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: '0.3rem' }}>
|
||||
<AlertCircle style={{ width: '12px', height: '12px' }} />
|
||||
{enrichErrors.length === 1 && enrichErrors[0].ip === 'all'
|
||||
? enrichErrors[0].error
|
||||
: enrichErrors.some(e => e.error && e.error.includes('timed out'))
|
||||
? `${enrichErrors.length} device(s) timed out — CARD may be slow`
|
||||
: `${enrichErrors.length} device(s) not found in CARD`}
|
||||
</span>
|
||||
<button
|
||||
onClick={enrichFromCard}
|
||||
disabled={enriching}
|
||||
style={{
|
||||
background: 'rgba(239, 68, 68, 0.15)', border: '1px solid rgba(239, 68, 68, 0.4)',
|
||||
borderRadius: '0.25rem', padding: '0.2rem 0.5rem',
|
||||
color: '#F87171', cursor: 'pointer',
|
||||
fontSize: '0.65rem', fontFamily: 'monospace', fontWeight: '600',
|
||||
}}
|
||||
>
|
||||
Retry
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user