feat(triage): Ivanti findings trend chart + rename Reporting to Vulnerability Triage

Add time-based open/closed tracking for Ivanti findings (Tier 2 from
the reporting recommendations doc) and rename the Reporting page to
Vulnerability Triage to better reflect its purpose.

Backend — ivantiFindings.js:
  - Create ivanti_counts_history table (appended on every sync, never
    overwritten — Option B from design discussion)
  - INSERT snapshot after each successful syncClosedCount() call
  - GET /api/ivanti/findings/counts/history endpoint — returns last
    snapshot per calendar day using ROW_NUMBER window function, so
    multiple daily syncs collapse to the end-of-day value

Frontend:
  - New IvantiCountsChart component: collapsible dual-line chart
    (open vs closed) with dark tooltip, delta label showing change
    since previous day, and graceful no-data states
  - Chart placed between the donut metrics panel and the findings table
    on the Vulnerability Triage page
  - Renamed page: 'reporting' → 'triage' (page ID, nav label, component
    export, all cross-file references)
  - ComplianceDetailPanel "View in Reporting" link updated to "View in
    Triage" and navigates to the correct page ID

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 10:12:04 -06:00
parent b111273e5a
commit 15ad207464
6 changed files with 266 additions and 9 deletions

View File

@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
import { RefreshCw, Loader, AlertCircle, PieChart, ChevronUp, ChevronDown, ChevronsUpDown, Settings2, GripVertical, Eye, EyeOff, Filter, Download, RotateCcw, Trash2, X, ListTodo } from 'lucide-react';
import * as XLSX from 'xlsx';
import { useAuth } from '../../contexts/AuthContext';
import IvantiCountsChart from './IvantiCountsChart';
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
const STORAGE_KEY = 'steam_findings_columns_v2';
@@ -1536,7 +1537,7 @@ function QueuePanel({ open, items, onClose, onUpdate, onDelete, onDeleteMany, on
// ---------------------------------------------------------------------------
// Main ReportingPage
// ---------------------------------------------------------------------------
export default function ReportingPage({ filterDate, filterEXC }) {
export default function VulnerabilityTriagePage({ filterDate, filterEXC }) {
const { canWrite } = useAuth();
const [findings, setFindings] = useState([]);
const [total, setTotal] = useState(null);
@@ -1965,6 +1966,11 @@ export default function ReportingPage({ filterDate, filterEXC }) {
</div>
</div>
{/* ----------------------------------------------------------------
Panel 1.5 — Open vs Closed trend over time
---------------------------------------------------------------- */}
<IvantiCountsChart />
{/* ----------------------------------------------------------------
Panel 2 — Findings table
---------------------------------------------------------------- */}