/******************************************************************************** * Copyright (c) 2026 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * https://www.eclipse.org/legal/epl-2.0 * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ import { FunctionComponent } from 'react'; import { Box, Typography, Pagination, CircularProgress } from '@mui/material'; import { ScanCard } from '../scan-card'; import { SearchToolbar, CountsToolbar } from '../toolbars'; import { AutoRefresh } from '../common'; import { useQuarantinedTab } from '../../../hooks/scan-admin'; import { useScanContext } from '../../../context/scan-admin'; import { useTheme } from '@mui/material/styles'; /** * Quarantined tab component that displays extensions flagged by security scans. * Uses the useQuarantinedTab hook to consume context. */ export const QuarantinedTabContent: FunctionComponent = () => { const theme = useTheme(); const { state } = useScanContext(); const { scans, isLoading, lastRefreshed, autoRefresh, onAutoRefreshChange, totalCount, search, globalFilters, quarantineFilters, pagination, selection, toggleCheck, selectAll, deselectAll, isAllSelected, bulkActions, hasThreatScanners, } = useQuarantinedTab(); // Calculate allowed/blocked/needs review counts from scanCounts const allowedCount = state.scanCounts?.ALLOWED ?? 0; const blockedCount = state.scanCounts?.BLOCKED ?? 0; const needsReviewCount = state.scanCounts?.NEEDS_REVIEW ?? 0; const handleSelectAllChange = (checked: boolean) => { if (checked) { selectAll(); } else { deselectAll(); } }; return ( <> ({ label: scanner, value: scanner, checked: quarantineFilters.threatScannerFilters.has(scanner), }))} onFilterOptionToggle={quarantineFilters.toggleThreatScanner} dateRange={globalFilters.dateRange} onDateRangeChange={globalFilters.setDateRange} enforcement={globalFilters.enforcement} onEnforcementChange={globalFilters.setEnforcement} /> {isLoading ? ( ) : (!hasThreatScanners || scans.length === 0) ? ( No quarantined extensions Extensions flagged by security scans will appear here ) : ( scans.map((scan) => { // Only show checkbox for scans that need review: // - No admin decision yet AND // - Has at least one enforced threat (unenforced threats don't require review) const hasEnforcedThreat = scan.threats.some(t => t.enforcedFlag); const needsReview = !scan.adminDecision?.decision && hasEnforcedThreat; return ( ); }) )} {pagination.totalPages > 1 && ( pagination.goToPage(page - 1)} disabled={isLoading} color='secondary' size='large' showFirstButton showLastButton /> )} ); };