/** * WordPress dependencies */ import { useSelect } from '@safe-wordpress/data'; /** * External dependencies */ import { sum } from 'lodash'; import { store as NAB_DATA } from '@nab/data'; import type { AlternativeId, ExperimentId, Maybe } from '@nab/types'; export type Results = | { readonly status: 'loading' } | { readonly status: 'error' } | { readonly status: 'ready'; readonly isUnique: boolean; readonly views: number; readonly conversions: number; readonly currentLeader: Maybe< number >; readonly improvement: number; }; export const useResults = ( experimentId: ExperimentId ): Results => useSelect( ( select ): Results => { const isLoading = select( NAB_DATA ).isResolving( 'getExperiment', [ experimentId, ] ) || select( NAB_DATA ).isResolving( 'getExperimentResults', [ experimentId, ] ); if ( isLoading ) { return { status: 'loading' }; } const experiment = select( NAB_DATA ).getExperiment( experimentId ); const rawResults = select( NAB_DATA ).getExperimentResults( experimentId ); const isError = select( NAB_DATA ).hasResolutionFailed( 'getExperiment', [ experimentId, ] ) || select( NAB_DATA ).hasResolutionFailed( 'getExperimentResults', [ experimentId ] ); if ( ! experiment || isError || ! rawResults ) { return { status: 'error' }; } const isUnique = select( NAB_DATA ).areUniqueResultsVisible( experimentId ); const goalId = experiment.goals[ 0 ]?.id ?? ''; const alternatives = Object.values( rawResults.alternatives ?? {} ); const conversions = sum( alternatives.map( ( a ) => isUnique ? a.uniqueConversions[ goalId ] ?? 0 : a.conversions[ goalId ] ?? 0 ) ); type AlternativeSummary = { readonly id: AlternativeId; readonly index: number; readonly improvement: number; }; // eslint-disable-next-line @wordpress/no-unused-vars-before-return const [ _, ...alternativeIds ] = experiment.alternatives.map( ( a ) => a.id ); const bestAlternative = alternativeIds .map( ( id, index ): AlternativeSummary => ( { id, index: index + 1, improvement: isUnique ? rawResults.alternatives[ id ] ?.uniqueImprovementFactors[ goalId ] ?? 0 : rawResults.alternatives[ id ]?.improvementFactors[ goalId ] ?? 0, } ) ) .reduce( ( r, c ): AlternativeSummary => { if ( ! r ) { return c; } return c.improvement > r.improvement ? c : r; }, { id: 'control' as const, index: 0, improvement: 0 } ); const currentLeader = // eslint-disable-next-line no-nested-ternary bestAlternative.improvement > 0 ? bestAlternative.index : bestAlternative.improvement < 0 ? 0 : undefined; return { status: 'ready', isUnique, views: isUnique ? select( NAB_DATA ).getUniquePageViews( experimentId ) : select( NAB_DATA ).getPageViews( experimentId ), conversions, currentLeader, improvement: bestAlternative?.improvement ?? 0, }; }, [ experimentId ] );