MCPcopy Create free account
hub / github.com/SpecterOps/Nemesis / Containers

Function Containers

projects/frontend/src/components/Containers/Containers.jsx:470–819  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

468
469// Main Containers component
470const Containers = () => {
471 const [searchParams, setSearchParams] = useSearchParams();
472 const [containers, setContainers] = useState([]);
473 const [isLoading, setIsLoading] = useState(true);
474 const [error, setError] = useState(null);
475 const [lastUpdated, setLastUpdated] = useState(null);
476 const [hasMore, setHasMore] = useState(true);
477 const [page, setPage] = useState(0);
478 const scrollContainerRef = useRef(null);
479
480 // Filter and sort state initialized from URL parameters
481 const [filters, setFilters] = useState(() => ({
482 original_filename: searchParams.get('filename') || '',
483 agent_id: searchParams.get('agent_id') || '',
484 source: searchParams.get('source') || '',
485 status: searchParams.get('status') || '',
486 container_id: searchParams.get('container_id') || ''
487 }));
488 const [sortBy, setSortBy] = useState(() => searchParams.get('sort_by') || 'submitted_at');
489 const [sortOrder, setSortOrder] = useState(() => searchParams.get('sort_order') || 'desc');
490
491 const POLL_INTERVAL = 5000; // Poll every 5 seconds
492 const PAGE_SIZE = 20;
493
494
495 const fetchContainers = useCallback(async (pageNum = 0, reset = false) => {
496 try {
497 // Build filter variables instead of inline conditions
498 const variables = {
499 limit: PAGE_SIZE,
500 offset: pageNum * PAGE_SIZE
501 };
502
503 // Build where conditions as GraphQL variables
504 const whereConditions = [];
505
506 if (filters.original_filename) {
507 whereConditions.push({ original_filename: { _ilike: `%${filters.original_filename}%` } });
508 }
509 if (filters.agent_id) {
510 whereConditions.push({ agent_id: { _ilike: `%${filters.agent_id}%` } });
511 }
512 if (filters.source) {
513 whereConditions.push({ source: { _ilike: `%${filters.source}%` } });
514 }
515 if (filters.status) {
516 whereConditions.push({ status: { _eq: filters.status } });
517 }
518 if (filters.container_id) {
519 // Only filter when we have a complete UUID to avoid casting errors
520 // Check if it's a valid UUID format (8-4-4-4-12 hex characters)
521 const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
522 if (uuidRegex.test(filters.container_id)) {
523 whereConditions.push({ container_id: { _eq: filters.container_id } });
524 }
525 // If we want to support partial matching, we'd need a computed field or custom function in Hasura
526 }
527

Callers

nothing calls this directly

Calls 2

setMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected