import {Fragment, useMemo, useState} from 'react'; import styled from '@emotion/styled'; import Button from 'sentry/components/button'; import ButtonBar from 'sentry/components/buttonBar'; import {SectionHeading} from 'sentry/components/charts/styles'; import Count from 'sentry/components/count'; import GridEditable, { COL_WIDTH_UNDEFINED, GridColumnOrder, } from 'sentry/components/gridEditable'; import PerformanceDuration from 'sentry/components/performanceDuration'; import {ArrayLinks} from 'sentry/components/profiling/arrayLinks'; import {IconChevron} from 'sentry/icons'; import {t} from 'sentry/locale'; import space from 'sentry/styles/space'; import {Project} from 'sentry/types'; import {FunctionCall} from 'sentry/types/profiling/core'; import {Container, NumberContainer} from 'sentry/utils/discover/styles'; import {getShortEventId} from 'sentry/utils/events'; import {formatPercentage} from 'sentry/utils/formatters'; import {generateProfileFlamegraphRouteWithQuery} from 'sentry/utils/profiling/routes'; import {renderTableHead} from 'sentry/utils/profiling/tableRenderer'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; interface FunctionsTableProps { error: string | null; functionCalls: FunctionCall[]; isLoading: boolean; project: Project; limit?: number; } function FunctionsTable(props: FunctionsTableProps) { const limit = props.limit ?? 5; const [offset, setOffset] = useState(0); const location = useLocation(); const organization = useOrganization(); const allFunctions: TableDataRow[] = useMemo(() => { return props.functionCalls.map(functionCall => ({ symbol: functionCall.symbol, image: functionCall.image, p50Duration: functionCall.duration_ns.p50, p75Duration: functionCall.duration_ns.p75, p90Duration: functionCall.duration_ns.p90, p95Duration: functionCall.duration_ns.p95, p99Duration: functionCall.duration_ns.p99, mainThreadPercent: functionCall.main_thread_percent, p50Frequency: functionCall.frequency.p50, p75Frequency: functionCall.frequency.p75, p90Frequency: functionCall.frequency.p90, p95Frequency: functionCall.frequency.p95, p99Frequency: functionCall.frequency.p99, profileIdToThreadId: Object.entries(functionCall.profile_id_to_thread_id).map( ([profileId, threadId]) => { return { value: getShortEventId(profileId), target: generateProfileFlamegraphRouteWithQuery({ orgSlug: organization.slug, projectSlug: props.project.slug, profileId, query: {tid: threadId.toString()}, }), }; } ), })); }, [organization.slug, props.project.slug, props.functionCalls]); const functions: TableDataRow[] = useMemo(() => { return allFunctions.slice(offset, offset + limit); }, [allFunctions, limit, offset]); return ( {t('Suspect Functions')}