import React, { Component } from 'react'; import apiFetch from '@wordpress/api-fetch'; import { __ } from '@wordpress/i18n'; import { PanelBody, SelectControl, TextControl } from '@wordpress/components'; import { select } from '@wordpress/data'; interface GoalSelectorProps { value: string; type: string; onChange: (value: string) => void; onTypeChange: (type: string) => void; } interface GoalPostType { name: string; label: string; itemName: string; help: string; placeholder?: string; text?: boolean; } interface GoalExternalPost { post_title: string; ID: number; } interface GoalSelectorState { loading: boolean; posts: GoalExternalPost[]; types: GoalPostType[]; } function findCurrentType(types: GoalPostType[], type: string): GoalPostType { return types.find((t) => t.name === type) || { itemName: '', help: '', name: '', label: '', }; } class GoalSelector extends Component { constructor(props: GoalSelectorProps) { super(props); this.state = { loading: true, posts: [], types: [], }; } componentDidMount(): void { const { value, type, onTypeChange } = this.props; const resolvePostType = !type && value ? apiFetch({ path: `ab-testing-for-wp/v1/get-post-type?post_id=${value}` }) : Promise.resolve(type); const resolveTypes = apiFetch({ path: 'ab-testing-for-wp/v1/get-goal-types' }); Promise.all([ resolvePostType, resolveTypes, ]).then(([postType, types]) => { // auto select first result const selectedType = postType === '' ? types[0].name : postType.toString(); if (type !== selectedType) { onTypeChange(selectedType); } const currentType = findCurrentType(types, selectedType); this.setState({ types, loading: !currentType.text, }); if (!currentType.text) { this.getPostsOfType(selectedType); } }); } getPostsOfType(type: string): void { const { types } = this.state; const currentType = findCurrentType(types, type); if (currentType.text) return; const postId = select('core/editor').getCurrentPostId(); apiFetch({ path: `ab-testing-for-wp/v1/get-posts-by-type?type=${type}&&exclude=${postId}` }) .then((posts) => { this.setState({ posts, loading: false, }); }); } changePostType = (selectedType: string): void => { const { onChange, onTypeChange } = this.props; onChange(''); onTypeChange(selectedType); this.getPostsOfType(selectedType); }; targetInput(): React.ReactElement { const { posts, types } = this.state; const { onChange, value, type } = this.props; const currentType = findCurrentType(types, type); if (currentType.text) { return ( ); } return ( ({ label: post.post_title, value: post.ID.toString() })), ]} help={currentType.help} onChange={onChange} /> ); } render(): React.ReactNode { const { loading, types, } = this.state; const { type } = this.props; const currentType = findCurrentType(types, type); if (!loading && !currentType) { return null; } return ( {!loading && (
({ label: t.label, value: t.name, }))} onChange={this.changePostType} /> {this.targetInput()}
)}
); } } export default GoalSelector;