/**
* WordPress dependencies
*/
import { Button, Dashicon } from '@safe-wordpress/components';
import { useDispatch, useSelect } from '@safe-wordpress/data';
import { createInterpolateElement } from '@safe-wordpress/element';
import { _x, sprintf } from '@safe-wordpress/i18n';
/**
* External dependencies
*/
import { ReusableEntitiesDialog } from '@nab/components';
import { store as NAB_DATA } from '@nab/data';
import { store as NAB_EDITOR } from '@nab/editor';
import { createSegmentationRule as createSegmentationRuleWithDefaults } from '@nab/segmentation-rules';
import { EMPTY_ARRAY, isDefined } from '@nab/utils';
import type {
Dict,
ReusableSegment,
SegmentationRuleId,
SegmentationRuleTypeName,
} from '@nab/types';
/**
* Internal dependencies
*/
import './style.scss';
import { SegmentationRule } from '../../../editor/components/segment/segmentation-rule';
import { SegmentationRuleTypeCategoryList } from '../../../editor/components/segment/segmentation-rule-type-category-list';
export const ParticipationSection = (): JSX.Element => (
);
// ============
// HELPER VIEWS
// ============
const Title = () => (
{ createInterpolateElement(
sprintf(
/* translators: %s: Dashicon. */
_x( '%s Participation', 'text', 'nelio-ab-testing' ),
' '
),
{
icon: (
),
}
) }
);
const ParticipationConditions = () => {
const { conditions, createCondition, updateCondition, removeCondition } =
useParticipationConditions();
const { openReusableDialog } = useDispatch( NAB_EDITOR );
const isImportEnabled = useIsImportEnabled();
return (
{ ! conditions.length
? _x(
'All visitors will contribute to this heatmap. If you want to limit participation to a subset of visitors, use the actions below:',
'text',
'nelio-ab-testing'
)
: _x(
'Only visitors who meet all the following criteria will contribute to this heatmap:',
'text',
'nelio-ab-testing'
) }
{ conditions.map( ( condition ) => (
updateCondition( condition.id, attrs )
}
remove={ () => removeCondition( condition.id ) }
/>
) ) }
{ isImportEnabled && ! conditions.length && (
openReusableDialog( 'manage-segments' )
}
>
{ _x(
'Import Segment',
'command',
'nelio-ab-testing'
) }
) }
);
};
function ReusableParticipationDialog(): JSX.Element | null {
const dialog = useReusableDialog();
const { closeReusableDialog: onClose } = useDispatch( NAB_EDITOR );
const { setHeatmapData } = useDispatch( NAB_EDITOR );
const { isSaving, reusableSegments } = useSelect(
( select ) => ( {
isSaving: select( NAB_DATA ).isSavingReusableEntities(),
reusableSegments: select( NAB_DATA ).getReusableSegments(),
} ),
[]
);
if ( 'manage-segments' !== dialog ) {
return null;
}
return (
mode="manage"
isSingular
labels={ {
title: _x( 'Reusable Segments', 'text', 'nelio-ab-testing' ),
replace: _x( 'Import Segment', 'text', 'nelio-ab-testing' ),
selectSingle: _x(
'Select a segment to import:',
'user',
'nelio-ab-testing'
),
} }
items={ reusableSegments }
saving={ isSaving }
onReplace={ ( selection ) => {
if ( ! selection[ 0 ] ) {
return;
}
void setHeatmapData( {
participationConditions: selection[ 0 ].segmentationRules
.map( ( sr ) => {
const newRule = createSegmentationRuleWithDefaults(
sr.type
);
if ( ! newRule ) {
return undefined;
}
return { ...sr, id: newRule.id };
} )
.filter( isDefined ),
} );
void onClose();
} }
onClose={ onClose }
/>
);
}
// =====
// HOOKS
// =====
const useParticipationConditions = () => {
const conditions = useSelect(
( select ) =>
select( NAB_EDITOR ).getHeatmapAttribute(
'participationConditions'
) ?? EMPTY_ARRAY,
[]
);
const { setHeatmapData } = useDispatch( NAB_EDITOR );
return {
conditions,
createCondition: ( type: SegmentationRuleTypeName ) => {
const rule = createSegmentationRuleWithDefaults( type );
if ( rule ) {
void setHeatmapData( {
participationConditions: [ ...conditions, rule ],
} );
}
},
updateCondition: ( id: SegmentationRuleId, attrs: Dict ) =>
void setHeatmapData( {
participationConditions: conditions.map( ( c ) =>
c.id === id
? { ...c, attributes: { ...c.attributes, ...attrs } }
: c
),
} ),
removeCondition: ( id: SegmentationRuleId ) =>
void setHeatmapData( {
participationConditions: conditions.filter(
( c ) => c.id !== id
),
} ),
};
};
const useReusableDialog = () =>
useSelect( ( select ) => select( NAB_EDITOR ).getReusableDialog(), [] );
const useIsImportEnabled = (): boolean =>
useSelect(
( select ) => !! select( NAB_DATA ).getReusableGoals().length,
[]
);