import {Fragment} from 'react'; import styled from '@emotion/styled'; import type {Location, LocationDescriptor} from 'history'; import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import {SectionHeading} from 'sentry/components/charts/styles'; import Link from 'sentry/components/links/link'; import Placeholder from 'sentry/components/placeholder'; import QuestionTooltip from 'sentry/components/questionTooltip'; import UserMisery from 'sentry/components/userMisery'; import {IconOpen} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; import type EventView from 'sentry/utils/discover/eventView'; import type {QueryError} from 'sentry/utils/discover/genericDiscoverQuery'; import {WebVital} from 'sentry/utils/fields'; import {useMetricsCardinalityContext} from 'sentry/utils/performance/contexts/metricsCardinality'; import {useMEPSettingContext} from 'sentry/utils/performance/contexts/metricsEnhancedSetting'; import {decodeScalar} from 'sentry/utils/queryString'; import {useModuleURL} from 'sentry/views/insights/common/utils/useModuleURL'; import {ModuleName} from 'sentry/views/insights/types'; import {getTermHelp, PerformanceTerm} from 'sentry/views/performance/data'; import {getTransactionMEPParamsIfApplicable} from 'sentry/views/performance/transactionSummary/transactionOverview/utils'; import {vitalsRouteWithQuery} from 'sentry/views/performance/transactionSummary/transactionVitals/utils'; import {SidebarSpacer} from 'sentry/views/performance/transactionSummary/utils'; import VitalInfo from 'sentry/views/performance/vitalDetail/vitalInfo'; type Props = { error: QueryError | null; eventView: EventView; hasWebVitals: boolean; isLoading: boolean; location: Location; organization: Organization; totals: Record | null; transactionName: string; }; function UserStats({ isLoading, hasWebVitals, error, totals, location, organization, transactionName, eventView, }: Props) { const hasTransactionSummaryCleanupFlag = organization.features.includes( 'performance-transaction-summary-cleanup' ); const webVitalsUrl = useModuleURL(ModuleName.VITAL, false, 'frontend'); const hasWebVitalsFlag = organization.features.includes('insights-initial-modules'); const hasDomainViewFlag = organization.features.includes('insights-domain-view'); let userMisery = error !== null ?
{'\u2014'}
: ; if (!isLoading && error === null && totals) { const threshold: number | undefined = totals.project_threshold_config ? totals.project_threshold_config[1] : undefined; const miserableUsers: number | undefined = totals['count_miserable_user()']; const userMiseryScore: number = totals['user_misery()'] || 0; const totalUsers = totals['count_unique_user()']; userMisery = ( ); } const orgSlug = organization.slug; let webVitalsTarget: LocationDescriptor = vitalsRouteWithQuery({ orgSlug, transaction: transactionName, projectID: decodeScalar(location.query.project), query: location.query, }); if (hasWebVitalsFlag && hasDomainViewFlag) { webVitalsTarget = { pathname: `${webVitalsUrl}/overview/`, query: { transaction: transactionName, }, }; } const showLink = !hasDomainViewFlag || (hasDomainViewFlag && hasWebVitalsFlag); const mepSetting = useMEPSettingContext(); const mepCardinalityContext = useMetricsCardinalityContext(); const queryExtras = getTransactionMEPParamsIfApplicable( mepSetting, mepCardinalityContext, organization ); return ( {hasWebVitals && ( {t('Web Vitals')} {showLink && ( )} )} {!hasTransactionSummaryCleanupFlag && ( {t('User Misery')} {userMisery} )} ); } const VitalsHeading = styled('div')` display: flex; justify-content: space-between; align-items: center; `; export default UserStats;