/** * WordPress dependencies */ import apiFetch from '@safe-wordpress/api-fetch'; import { dispatch, resolveSelect, select } from '@safe-wordpress/data'; import { _x } from '@safe-wordpress/i18n'; /** * External dependencies */ import { keyBy } from 'lodash'; import { createErrorNotice } from '@nab/utils'; import type { Alternative, AlternativeId, Experiment, Maybe } from '@nab/types'; /** * Internal dependencies */ import { store as NAB_DATA } from '../../../store'; /** * Stops the experiment in the database. */ export async function stopExperiment(): Promise< void > { const experimentId = select( NAB_DATA ).getPageAttribute( 'editor/activeExperiment' ); if ( ! experimentId ) { return; } await dispatch( NAB_DATA ).setPageAttribute( 'editor/isExperimentBeingStopped', true ); let experiment: Maybe< Experiment >; try { experiment = await resolveSelect( NAB_DATA ).getExperiment( experimentId ); if ( ! experiment ) { return; } } catch ( e ) { await createErrorNotice( e ); return; } let stoppedExperiment: Experiment; try { stoppedExperiment = await apiFetch< Experiment >( { path: `/nab/v1/experiment/${ experimentId }/stop`, method: 'PUT', } ); } catch ( e ) { await createErrorNotice( e, _x( 'Test can’t be stopped', 'text', 'nelio-ab-testing' ) ); await dispatch( NAB_DATA ).setPageAttribute( 'editor/isExperimentBeingStopped', false ); return; } const newAlternatives = keyBy( stoppedExperiment.alternatives || [], 'id' ); const newExperiment: Experiment = { ...stoppedExperiment, links: { ...stoppedExperiment.links, ...experiment.links, }, alternatives: ( experiment.alternatives || [] ).map( ( alternative ) => ( { ...alternative, links: updateLinksKeepingPreviewAndHeatmap( alternative, newAlternatives[ alternative.id ] ), } ) // eslint-disable-next-line @typescript-eslint/no-explicit-any ) as any as Experiment[ 'alternatives' ], }; await dispatch( NAB_DATA ).receiveExperiment( experiment.id, newExperiment ); await dispatch( NAB_DATA ).setPageAttribute( 'editor/isExperimentBeingStopped', false ); } /** * Pauses the experiment in the database. */ export async function pauseExperiment(): Promise< void > { const experimentId = select( NAB_DATA ).getPageAttribute( 'editor/activeExperiment' ); if ( ! experimentId ) { return; } await dispatch( NAB_DATA ).setPageAttribute( 'editor/isExperimentBeingPaused', true ); try { await apiFetch( { path: `/nab/v1/experiment/${ experimentId }/pause`, method: 'PUT', } ); } catch ( e ) { await createErrorNotice( e, _x( 'Test can’t be paused', 'text', 'nelio-ab-testing' ) ); await dispatch( NAB_DATA ).setPageAttribute( 'editor/isExperimentBeingPaused', false ); return; } window.location.href = select( NAB_DATA ).getAdminUrl( 'admin.php', { page: 'nelio-ab-testing-experiment-edit', experiment: experimentId, } ); } /** * Applies the given alternative. * * @param {string} alternativeId the alternative to apply. */ export async function applyAlternative( alternativeId: AlternativeId ): Promise< void > { const experimentId = select( NAB_DATA ).getPageAttribute( 'editor/activeExperiment' ); if ( ! experimentId ) { return; } await dispatch( NAB_DATA ).setPageAttribute( 'editor/alternativeBeingApplied', alternativeId ); let experiment: Experiment; try { experiment = await apiFetch( { path: `/nab/v1/experiment/${ experimentId }/apply/${ alternativeId }`, method: 'PUT', } ); } catch ( e ) { await createErrorNotice( e, _x( 'Alternative can’t be applied', 'text', 'nelio-ab-testing' ) ); await dispatch( NAB_DATA ).setPageAttribute( 'editor/alternativeBeingApplied', false ); return; } await dispatch( NAB_DATA ).changeLastAppliedAlternative( experiment.id, alternativeId ); await dispatch( NAB_DATA ).setPageAttribute( 'editor/alternativeBeingApplied', false ); } /** * Changes the public result status of the experiment in the database. * @param status */ export async function setPublicResultStatus( status: boolean ): Promise< void > { const experimentId = select( NAB_DATA ).getPageAttribute( 'editor/activeExperiment' ); if ( ! experimentId ) { return; } await dispatch( NAB_DATA ).setPageAttribute( 'isLocked', true ); let changedStatus = status; try { changedStatus = await apiFetch< boolean >( { path: `/nab/v1/experiment/${ experimentId }/public-result-status`, method: 'PUT', data: { status }, } ); } catch ( e ) { await createErrorNotice( e, _x( 'Public result’s status can’t be changed', 'text', 'nelio-ab-testing' ) ); await dispatch( NAB_DATA ).setPageAttribute( 'isLocked', false ); return; } await dispatch( NAB_DATA ).setPageAttribute( 'isLocked', false ); await dispatch( NAB_DATA ).setPageAttribute( 'results/isReadOnlyActive', changedStatus ); } // ======= // HELPERS // ======= function updateLinksKeepingPreviewAndHeatmap( oldAlternative?: Alternative, newAlternative?: Alternative ): Maybe< Alternative[ 'links' ] > { if ( ! oldAlternative?.links ) { return; } if ( ! newAlternative?.links ) { return oldAlternative.links; } return { ...newAlternative.links, heatmap: oldAlternative.links.heatmap, preview: oldAlternative.links.preview, }; }