import TeamsTable from "@/app/workspace/governance/views/teamsTable"; import FullPageLoader from "@/components/fullPageLoader"; import { useDebouncedValue } from "@/hooks/useDebounce"; import { getErrorMessage, useGetCustomersQuery, useGetTeamsQuery, useGetVirtualKeysQuery } from "@/lib/store"; import { RbacOperation, RbacResource, useRbac } from "@enterprise/lib"; import { useEffect, useRef, useState } from "react"; import { toast } from "sonner"; const POLLING_INTERVAL = 5000; const PAGE_SIZE = 25; export function TeamsView() { const hasVirtualKeysAccess = useRbac(RbacResource.VirtualKeys, RbacOperation.View); const hasCustomersAccess = useRbac(RbacResource.Customers, RbacOperation.View); const hasTeamsAccess = useRbac(RbacResource.Teams, RbacOperation.View); const shownErrorsRef = useRef(new Set()); const [search, setSearch] = useState(""); const [offset, setOffset] = useState(0); const debouncedSearch = useDebouncedValue(search, 300); useEffect(() => { setOffset(0); }, [debouncedSearch]); const { data: virtualKeysData, error: vkError, isLoading: vkLoading, } = useGetVirtualKeysQuery(undefined, { skip: !hasVirtualKeysAccess, pollingInterval: POLLING_INTERVAL, }); const { data: customersData, error: customersError, isLoading: customersLoading, } = useGetCustomersQuery(undefined, { skip: !hasCustomersAccess, pollingInterval: POLLING_INTERVAL, }); const { data: teamsData, error: teamsError, isLoading: teamsLoading, } = useGetTeamsQuery( { limit: PAGE_SIZE, offset, search: debouncedSearch || undefined, }, { skip: !hasTeamsAccess, pollingInterval: POLLING_INTERVAL, }, ); const teamsTotal = teamsData?.total_count ?? 0; // Snap offset back when total shrinks past current page (e.g. delete last item on last page) useEffect(() => { if (!teamsData || offset < teamsTotal) return; setOffset(teamsTotal === 0 ? 0 : Math.floor((teamsTotal - 1) / PAGE_SIZE) * PAGE_SIZE); }, [teamsTotal, offset]); const isLoading = vkLoading || customersLoading || teamsLoading; useEffect(() => { if (!vkError && !customersError && !teamsError) { shownErrorsRef.current.clear(); return; } const errorKey = `${!!vkError}-${!!customersError}-${!!teamsError}`; if (shownErrorsRef.current.has(errorKey)) return; shownErrorsRef.current.add(errorKey); if (vkError && customersError && teamsError) { toast.error("Failed to load governance data."); } else { if (vkError) toast.error(`Failed to load virtual keys: ${getErrorMessage(vkError)}`); if (customersError) toast.error(`Failed to load customers: ${getErrorMessage(customersError)}`); if (teamsError) toast.error(`Failed to load teams: ${getErrorMessage(teamsError)}`); } }, [vkError, customersError, teamsError]); if (isLoading) { return ; } return (
); }