/**
* WordPress dependencies
*/
import {
BaseControl,
ExternalLink,
SelectControl,
TextControl,
ToggleControl,
} from '@safe-wordpress/components';
import { useInstanceId } from '@safe-wordpress/compose';
import { useSelect } from '@safe-wordpress/data';
import {
createInterpolateElement,
useCallback,
useEffect,
} from '@safe-wordpress/element';
import { _x } from '@safe-wordpress/i18n';
/**
* External dependencies
*/
import clsx from 'clsx';
import { sortBy, trim } from 'lodash';
import { ErrorText, PostSearcher } from '@nab/components';
import { store as NAB_DATA } from '@nab/data';
import { EMPTY_ARRAY } from '@nab/utils';
import type { CAEditProps, EntityId, EntityKindName } from '@nab/types';
/**
* Internal dependencies
*/
import type { Attributes } from './types';
export const Edit = ( props: CAEditProps< Attributes > ): JSX.Element => (
<>
{ props.attributes.mode === 'id' ? (
) : (
) }
{
props.setAttributes( { mode: enabled ? 'url' : 'id' } );
props.setScope(
enabled
? { type: 'urls', regexes: [ props.attributes.url ] }
: { type: 'post-ids', ids: [ props.attributes.postId ] }
);
} }
/>
>
);
// ============
// HELPER VIEWS
// ============
const EditPostId = ( {
attributes: { postId, postType },
setAttributes,
setScope,
errors,
}: CAEditProps< Attributes > ): JSX.Element | null => {
const instanceId = useInstanceId( Edit );
const { value: postTypes, isLoading } = usePostTypes();
const currentPostType = postType || postTypes[ 0 ]?.value;
const setAttributesAndScope = useCallback(
( attrs: Partial< Attributes > ) => {
setAttributes( attrs );
setScope( {
type: 'post-ids',
ids: attrs.postType && attrs.postId ? [ attrs.postId ] : [],
} );
},
[ setAttributes, setScope ]
);
const hasPostType = postTypes.map( ( t ) => t.value ).includes( postType );
useEffect( () => {
if ( isLoading || hasPostType ) {
return;
}
setAttributesAndScope( { postType: 'page', postId: 0 } );
}, [ postType, hasPostType, isLoading, setAttributesAndScope ] );
if ( isLoading ) {
return null;
}
return (
<>
{ postTypes.length > 1 && (
setAttributesAndScope( {
postType: newPostType,
postId: undefined,
} )
}
/>
) }
}
help={ }
>
setAttributesAndScope( {
postId: newPostId,
postType: currentPostType,
} )
}
/>
>
);
};
const EditUrl = ( {
attributes: { url },
setAttributes,
setScope,
errors,
}: CAEditProps< Attributes > ): JSX.Element => (
<>
{
setAttributes( { url: trim( value ) } );
setScope( {
type: 'urls',
regexes: trim( value ) ? [ trim( value ) ] : [],
} );
} }
help={ }
/>
>
);
const Label = ( {
postType,
postId,
}: {
postType: EntityKindName;
postId: EntityId;
} ) => {
const permalink = usePostPermalink( postType, postId );
if ( ! permalink ) {
return (
{ _x( 'Actual Content', 'text', 'nelio-ab-testing' ) }
);
}
return (
{ createInterpolateElement(
_x(
'Actual Content (View)',
'text',
'nelio-ab-testing'
),
{
a: permalink ? (
// @ts-expect-error children prop is set by createInterpolateComponent.
) : (
),
}
) }
);
};
// =====
// HOOKS
// =====
const EXCLUDED_POST_TYPES = [ 'attachment', 'product_variation' ];
const usePostTypes = () => {
const { entities, isLoading } = useSelect(
( select ) => ( {
entities: select( NAB_DATA ).getKindEntities() || EMPTY_ARRAY,
isLoading:
! select( NAB_DATA ).hasFinishedResolution(
'getKindEntities'
) &&
! select( NAB_DATA ).hasResolutionFailed( 'getKindEntities' ),
} ),
[]
);
const postTypes = entities
.filter(
( pt ) =>
'entity' === pt.kind &&
! EXCLUDED_POST_TYPES.includes( pt.name )
)
.map( ( pt ) => ( {
value: pt.name,
label: pt.labels.singular_name,
} ) );
return {
value: sortBy( postTypes, 'label' ),
isLoading,
};
};
const usePostPermalink = ( postType: EntityKindName, postId: EntityId ) =>
useSelect(
( select ) =>
select( NAB_DATA ).getEntityRecord( postType, postId )?.link,
[ postType, postId ]
);