import {Fragment, useMemo} from 'react'; import {css} from '@emotion/react'; import styled from '@emotion/styled'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Panel from 'sentry/components/panels/panel'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {useDebouncedValue} from 'sentry/utils/useDebouncedValue'; import {ProjectsTable} from 'sentry/views/settings/dynamicSampling/projectsTable'; import {SamplingBreakdown} from 'sentry/views/settings/dynamicSampling/samplingBreakdown'; import {formatPercent} from 'sentry/views/settings/dynamicSampling/utils/formatPercent'; import {organizationSamplingForm} from 'sentry/views/settings/dynamicSampling/utils/organizationSamplingForm'; import {parsePercent} from 'sentry/views/settings/dynamicSampling/utils/parsePercent'; import {balanceSampleRate} from 'sentry/views/settings/dynamicSampling/utils/rebalancing'; import type {ProjectSampleCount} from 'sentry/views/settings/dynamicSampling/utils/useProjectSampleCounts'; const {useFormField} = organizationSamplingForm; interface Props { isLoading: boolean; sampleCounts: ProjectSampleCount[]; } export function ProjectsPreviewTable({isLoading, sampleCounts}: Props) { const {value: targetSampleRate, initialValue: initialTargetSampleRate} = useFormField('targetSampleRate'); const debouncedTargetSampleRate = useDebouncedValue( targetSampleRate, // For longer lists we debounce the input to avoid too many re-renders sampleCounts.length > 100 ? 200 : 0 ); const balancingItems = useMemo( () => sampleCounts.map(item => ({ ...item, // Add properties to match the BalancingItem type of the balanceSampleRate function id: item.project.id, sampleRate: 1, })), [sampleCounts] ); const {balancedItems} = useMemo(() => { const targetRate = parsePercent(debouncedTargetSampleRate); return balanceSampleRate({ targetSampleRate: targetRate, items: balancingItems, }); }, [debouncedTargetSampleRate, balancingItems]); const initialSampleRateById = useMemo(() => { const targetRate = parsePercent(initialTargetSampleRate); const {balancedItems: initialBalancedItems} = balanceSampleRate({ targetSampleRate: targetRate, items: balancingItems, }); return initialBalancedItems.reduce((acc, item) => { acc[item.id] = item.sampleRate; return acc; }, {}); }, [initialTargetSampleRate, balancingItems]); const itemsWithFormattedNumbers = useMemo(() => { return balancedItems.map(item => ({ ...item, sampleRate: formatPercent(item.sampleRate), initialSampleRate: formatPercent(initialSampleRateById[item.id]), })); }, [balancedItems, initialSampleRateById]); const breakdownSampleRates = balancedItems.reduce((acc, item) => { acc[item.id] = item.sampleRate; return acc; }, {}); return ( {isLoading ? ( ) : ( )} ); } const BreakdownPanel = styled(Panel)` margin-bottom: ${space(3)}; padding: ${space(2)}; `;