Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

Untitled diff

Created Diff never expires
27 removals
482 lines
20 additions
481 lines
// Based on gutenberg/packages/editor/src/components/post-taxonomies/hierarchical-term-selector.js

/**
/**
* External dependencies
* External dependencies
*/
*/
import { get, unescape as unescapeString, without, find, some, invoke } from 'lodash';
import { get, unescape as unescapeString, find, some, invoke } from 'lodash';


/**
/**
* WordPress dependencies
* WordPress dependencies
*/
*/
import { __, _x, _n, sprintf } from '@wordpress/i18n';
import { __, _x, _n, sprintf } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { Component } from '@wordpress/element';
import { TreeSelect, withSpokenMessages, withFilters, Button } from '@wordpress/components';
import { TreeSelect, withSpokenMessages, Button } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';
import { withSelect, withDispatch } from '@wordpress/data';
import { withInstanceId, compose } from '@wordpress/compose';
import { withInstanceId, compose } from '@wordpress/compose';
import apiFetch from '@wordpress/api-fetch';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';
import { addQueryArgs } from '@wordpress/url';


/**
/**
* Internal dependencies
* Internal dependencies
*/
*/
import { buildTermsTree } from './terms';
import { buildTermsTree } from './utils/terms';


/**
/**
* Module Constants
* Module Constants
*/
*/
const DEFAULT_QUERY = {
const DEFAULT_QUERY = {
per_page: -1,
per_page: -1,
orderby: 'name',
orderby: 'name',
order: 'asc',
order: 'asc',
_fields: 'id,name,parent',
_fields: 'id,name,parent',
};
};


const MIN_TERMS_COUNT_FOR_FILTER = 8;
const MIN_TERMS_COUNT_FOR_FILTER = 8;


class RadioTermSelector extends Component {
// Note: We're always passing just one term ID to the onUpdateTerms
class HierarchicalTermSelector extends Component {
constructor() {
constructor() {
super( ...arguments );
super( ...arguments );
this.findTerm = this.findTerm.bind( this );
this.findTerm = this.findTerm.bind( this );
this.onChange = this.onChange.bind( this );
this.onChange = this.onChange.bind( this );
this.onChangeFormName = this.onChangeFormName.bind( this );
this.onChangeFormName = this.onChangeFormName.bind( this );
this.onChangeFormParent = this.onChangeFormParent.bind( this );
this.onChangeFormParent = this.onChangeFormParent.bind( this );
this.onAddTerm = this.onAddTerm.bind( this );
this.onAddTerm = this.onAddTerm.bind( this );
this.onToggleForm = this.onToggleForm.bind( this );
this.onToggleForm = this.onToggleForm.bind( this );
this.setFilterValue = this.setFilterValue.bind( this );
this.setFilterValue = this.setFilterValue.bind( this );
this.sortBySelected = this.sortBySelected.bind( this );
this.sortBySelected = this.sortBySelected.bind( this );
this.state = {
this.state = {
loading: true,
loading: true,
availableTermsTree: [],
availableTermsTree: [],
availableTerms: [],
availableTerms: [],
adding: false,
adding: false,
formName: '',
formName: '',
formParent: '',
formParent: '',
showForm: false,
showForm: false,
filterValue: '',
filterValue: '',
filteredTermsTree: [],
filteredTermsTree: [],
};
};
}
}


onChange( event ) {
onChange( event ) {
const { onUpdateTerms, terms = [], taxonomy } = this.props;
const { onUpdateTerms, taxonomy } = this.props;
const termId = parseInt( event.target.value, 10 );
const termId = parseInt( event.target.value, 10 );
const hasTerm = terms.indexOf( termId ) !== -1;
onUpdateTerms( [ termId ], taxonomy.rest_base );
const newTerms = hasTerm ?
without( terms, termId ) :
[ ...terms, termId ];
onUpdateTerms( newTerms, taxonomy.rest_base );
}
}


onChangeFormName( event ) {
onChangeFormName( event ) {
const newValue = event.target.value.trim() === '' ? '' : event.target.value;
const newValue = event.target.value.trim() === '' ? '' : event.target.value;
this.setState( { formName: newValue } );
this.setState( { formName: newValue } );
}
}


onChangeFormParent( newParent ) {
onChangeFormParent( newParent ) {
this.setState( { formParent: newParent } );
this.setState( { formParent: newParent } );
}
}


onToggleForm() {
onToggleForm() {
this.setState( ( state ) => ( {
this.setState( ( state ) => ( {
showForm: ! state.showForm,
showForm: ! state.showForm,
} ) );
} ) );
}
}


findTerm( terms, parent, name ) {
findTerm( terms, parent, name ) {
return find( terms, ( term ) => {
return find( terms, ( term ) => {
return ( ( ! term.parent && ! parent ) || parseInt( term.parent ) === parseInt( parent ) ) &&
return ( ( ! term.parent && ! parent ) || parseInt( term.parent ) === parseInt( parent ) ) &&
term.name.toLowerCase() === name.toLowerCase();
term.name.toLowerCase() === name.toLowerCase();
} );
} );
}
}


onAddTerm( event ) {
onAddTerm( event ) {
event.preventDefault();
event.preventDefault();
const { onUpdateTerms, taxonomy, terms, slug } = this.props;
const { onUpdateTerms, taxonomy, terms, slug } = this.props;
const { formName, formParent, adding, availableTerms } = this.state;
const { formName, formParent, adding, availableTerms } = this.state;
if ( formName === '' || adding ) {
if ( formName === '' || adding ) {
return;
return;
}
}


// check if the term we are adding already exists
// check if the term we are adding already exists
const existingTerm = this.findTerm( availableTerms, formParent, formName );
const existingTerm = this.findTerm( availableTerms, formParent, formName );
if ( existingTerm ) {
if ( existingTerm ) {
// if the term we are adding exists but is not selected select it
// if the term we are adding exists but is not selected select it
if ( ! some( terms, ( term ) => term === existingTerm.id ) ) {
if ( ! some( terms, ( term ) => term === existingTerm.id ) ) {
onUpdateTerms( [ ...terms, existingTerm.id ], taxonomy.rest_base );
onUpdateTerms( [ existingTerm.id ], taxonomy.rest_base );
}
}
this.setState( {
this.setState( {
formName: '',
formName: '',
formParent: '',
formParent: '',
} );
} );
return;
return;
}
}


this.setState( {
this.setState( {
adding: true,
adding: true,
} );
} );
this.addRequest = apiFetch( {
this.addRequest = apiFetch( {
path: `/wp/v2/${ taxonomy.rest_base }`,
path: `/wp/v2/${ taxonomy.rest_base }`,
method: 'POST',
method: 'POST',
data: {
data: {
name: formName,
name: formName,
parent: formParent ? formParent : undefined,
parent: formParent ? formParent : undefined,
},
},
} );
} );
// Tries to create a term or fetch it if it already exists
// Tries to create a term or fetch it if it already exists
const findOrCreatePromise = this.addRequest
const findOrCreatePromise = this.addRequest
.catch( ( error ) => {
.catch( ( error ) => {
const errorCode = error.code;
const errorCode = error.code;
if ( errorCode === 'term_exists' ) {
if ( errorCode === 'term_exists' ) {
// search the new category created since last fetch
// search the new category created since last fetch
this.addRequest = apiFetch( {
this.addRequest = apiFetch( {
path: addQueryArgs(
path: addQueryArgs(
`/wp/v2/${ taxonomy.rest_base }`,
`/wp/v2/${ taxonomy.rest_base }`,
{ ...DEFAULT_QUERY, parent: formParent || 0, search: formName }
{ ...DEFAULT_QUERY, parent: formParent || 0, search: formName }
),
),
} );
} );
return this.addRequest
return this.addRequest
.then( ( searchResult ) => {
.then( ( searchResult ) => {
return this.findTerm( searchResult, formParent, formName );
return this.findTerm( searchResult, formParent, formName );
} );
} );
}
}
return Promise.reject( error );
return Promise.reject( error );
} );
} );
findOrCreatePromise
findOrCreatePromise
.then( ( term ) => {
.then( ( term ) => {
const hasTerm = !! find( this.state.availableTerms, ( availableTerm ) => availableTerm.id === term.id );
const hasTerm = !! find( this.state.availableTerms, ( availableTerm ) => availableTerm.id === term.id );
const newAvailableTerms = hasTerm ? this.state.availableTerms : [ term, ...this.state.availableTerms ];
const newAvailableTerms = hasTerm ? this.state.availableTerms : [ term, ...this.state.availableTerms ];
const termAddedMessage = sprintf(
const termAddedMessage = sprintf(
_x( '%s added', 'term' ),
_x( '%s added', 'term' ),
get(
get(
this.props.taxonomy,
this.props.taxonomy,
[ 'labels', 'singular_name' ],
[ 'labels', 'singular_name' ],
slug === 'category' ? __( 'Category' ) : __( 'Term' )
slug === 'category' ? __( 'Category' ) : __( 'Term' )
)
)
);
);
this.props.speak( termAddedMessage, 'assertive' );
this.props.speak( termAddedMessage, 'assertive' );
this.addRequest = null;
this.addRequest = null;
this.setState( {
this.setState( {
adding: false,
adding: false,
formName: '',
formName: '',
formParent: '',
formParent: '',
availableTerms: newAvailableTerms,
availableTerms: newAvailableTerms,
availableTermsTree: this.sortBySelected( buildTermsTree( newAvailableTerms ) ),
availableTermsTree: this.sortBySelected( buildTermsTree( newAvailableTerms ) ),
} );
} );
onUpdateTerms( [ ...terms, term.id ], taxonomy.rest_base );
onUpdateTerms( [ term.id ], taxonomy.rest_base );
}, ( xhr ) => {
}, ( xhr ) => {
if ( xhr.statusText === 'abort' ) {
if ( xhr.statusText === 'abort' ) {
return;
return;
}
}
this.addRequest = null;
this.addRequest = null;
this.setState( {
this.setState( {
adding: false,
adding: false,
} );
} );
} );
} );
}
}


componentDidMount() {
componentDidMount() {
this.fetchTerms();
this.fetchTerms();
}
}


componentWillUnmount() {
componentWillUnmount() {
invoke( this.fetchRequest, [ 'abort' ] );
invoke( this.fetchRequest, [ 'abort' ] );
invoke( this.addRequest, [ 'abort' ] );
invoke( this.addRequest, [ 'abort' ] );
}
}


componentDidUpdate( prevProps ) {
componentDidUpdate( prevProps ) {
if ( this.props.taxonomy !== prevProps.taxonomy ) {
if ( this.props.taxonomy !== prevProps.taxonomy ) {
this.fetchTerms();
this.fetchTerms();
}
}
}
}


fetchTerms() {
fetchTerms() {
const { taxonomy } = this.props;
const { taxonomy } = this.props;
if ( ! taxonomy ) {
if ( ! taxonomy ) {
return;
return;
}
}
this.fetchRequest = apiFetch( {
this.fetchRequest = apiFetch( {
path: addQueryArgs( `/wp/v2/${ taxonomy.rest_base }`, DEFAULT_QUERY ),
path: addQueryArgs( `/wp/v2/${ taxonomy.rest_base }`, DEFAULT_QUERY ),
} );
} );
this.fetchRequest.then(
this.fetchRequest.then(
( terms ) => { // resolve
( terms ) => { // resolve
const availableTermsTree = this.sortBySelected( buildTermsTree( terms ) );
const availableTermsTree = this.sortBySelected( buildTermsTree( terms ) );


this.fetchRequest = null;
this.fetchRequest = null;
this.setState( {
this.setState( {
loading: false,
loading: false,
availableTermsTree,
availableTermsTree,
availableTerms: terms,
availableTerms: terms,
} );
} );
},
},
( xhr ) => { // reject
( xhr ) => { // reject
if ( xhr.statusText === 'abort' ) {
if ( xhr.statusText === 'abort' ) {
return;
return;
}
}
this.fetchRequest = null;
this.fetchRequest = null;
this.setState( {
this.setState( {
loading: false,
loading: false,
} );
} );
}
}
);
);
}
}


sortBySelected( termsTree ) {
sortBySelected( termsTree ) {
const { terms } = this.props;
const { terms } = this.props;
const treeHasSelection = ( termTree ) => {
const treeHasSelection = ( termTree ) => {
if ( terms.indexOf( termTree.id ) !== -1 ) {
if ( terms.indexOf( termTree.id ) !== -1 ) {
return true;
return true;
}
}
if ( undefined === termTree.children ) {
if ( undefined === termTree.children ) {
return false;
return false;
}
}
const anyChildIsSelected = termTree.children.map( treeHasSelection ).filter( ( child ) => child ).length > 0;
const anyChildIsSelected = termTree.children.map( treeHasSelection ).filter( ( child ) => child ).length > 0;
if ( anyChildIsSelected ) {
if ( anyChildIsSelected ) {
return true;
return true;
}
}
return false;
return false;
};
};
const termOrChildIsSelected = ( termA, termB ) => {
const termOrChildIsSelected = ( termA, termB ) => {
const termASelected = treeHasSelection( termA );
const termASelected = treeHasSelection( termA );
const termBSelected = treeHasSelection( termB );
const termBSelected = treeHasSelection( termB );


if ( termASelected === termBSelected ) {
if ( termASelected === termBSelected ) {
return 0;
return 0;
}
}


if ( termASelected && ! termBSelected ) {
if ( termASelected && ! termBSelected ) {
return -1;
return -1;
}
}


if ( ! termASelected && termBSelected ) {
if ( ! termASelected && termBSelected ) {
return 1;
return 1;
}
}


return 0;
return 0;
};
};
termsTree.sort( termOrChildIsSelected );
termsTree.sort( termOrChildIsSelected );
return termsTree;
return termsTree;
}
}


setFilterValue( event ) {
setFilterValue( event ) {
const { availableTermsTree } = this.state;
const { availableTermsTree } = this.state;
const filterValue = event.target.value;
const filterValue = event.target.value;
const filteredTermsTree = availableTermsTree.map( this.getFilterMatcher( filterValue ) ).filter( ( term ) => term );
const filteredTermsTree = availableTermsTree.map( this.getFilterMatcher( filterValue ) ).filter( ( term ) => term );
const getResultCount = ( terms ) => {
const getResultCount = ( terms ) => {
let count = 0;
let count = 0;
for ( let i = 0; i < terms.length; i++ ) {
for ( let i = 0; i < terms.length; i++ ) {
count++;
count++;
if ( undefined !== terms[ i ].children ) {
if ( undefined !== terms[ i ].children ) {
count += getResultCount( terms[ i ].children );
count += getResultCount( terms[ i ].children );
}
}
}
}
return count;
return count;
};
};
this.setState(
this.setState(
{
{
filterValue,
filterValue,
filteredTermsTree,
filteredTermsTree,
}
}
);
);


const resultCount = getResultCount( filteredTermsTree );
const resultCount = getResultCount( filteredTermsTree );
const resultsFoundMessage = sprintf(
const resultsFoundMessage = sprintf(
_n( '%d result found.', '%d results found.', resultCount ),
_n( '%d result found.', '%d results found.', resultCount ),
resultCount
resultCount
);
);
this.props.debouncedSpeak( resultsFoundMessage, 'assertive' );
this.props.debouncedSpeak( resultsFoundMessage, 'assertive' );
}
}


getFilterMatcher( filterValue ) {
getFilterMatcher( filterValue ) {
const matchTermsForFilter = ( originalTerm ) => {
const matchTermsForFilter = ( originalTerm ) => {
if ( '' === filterValue ) {
if ( '' === filterValue ) {
return originalTerm;
return originalTerm;
}
}


// Shallow clone, because we'll be filtering the term's children and
// Shallow clone, because we'll be filtering the term's children and
// don't want to modify the original term.
// don't want to modify the original term.
const term = { ...originalTerm };
const term = { ...originalTerm };


// Map and filter the children, recursive so we deal with grandchildren
// Map and filter the children, recursive so we deal with grandchildren
// and any deeper levels.
// and any deeper levels.
if ( term.children.length > 0 ) {
if ( term.children.length > 0 ) {
term.children = term.children.map( matchTermsForFilter ).filter( ( child ) => child );
term.children = term.children.map( matchTermsForFilter ).filter( ( child ) => child );
}
}


// If the term's name contains the filterValue, or it has children
// If the term's name contains the filterValue, or it has children
// (i.e. some child matched at some point in the tree) then return it.
// (i.e. some child matched at some point in the tree) then return it.
if ( -1 !== term.name.toLowerCase().indexOf( filterValue ) || term.children.length > 0 ) {
if ( -1 !== term.name.toLowerCase().indexOf( filterValue ) || term.children.length > 0 ) {
return term;
return term;
}
}


// Otherwise, return false. After mapping, the list of terms will need
// Otherwise, return false. After mapping, the list of terms will need
// to have false values filtered out.
// to have false values filtered out.
return false;
return false;
};
};
return matchTermsForFilter;
return matchTermsForFilter;
}
}


renderTerms( renderedTerms ) {
renderTerms( renderedTerms ) {
const { terms = [] } = this.props;
const { terms = [], taxonomy } = this.props;
const klass = taxonomy.hierarchical ? 'hierarchical' : 'non-hierarchical';
return renderedTerms.map( ( term ) => {
return renderedTerms.map( ( term ) => {
const id = `editor-post-taxonomies-hierarchical-term-${ term.id }`;
const id = `editor-post-taxonomies-${ klass }-term-${ term.id }`;
return (
return (
<div key={ term.id } className="editor-post-taxonomies__hierarchical-terms-choice">
<div key={ term.id } className="editor-post-taxonomies__hierarchical-terms-choice">
<input
<input
id={ id }
id={ id }
className="editor-post-taxonomies__hierarchical-terms-input"
className="editor-post-taxonomies__hierarchical-terms-input"
type="radio" // @helgatheviking
type="radio"
name={ 'radio_tax_input-' + this.props.slug } // @helgatheviking
checked={ terms.indexOf( term.id ) !== -1 }
checked={ terms.indexOf( term.id ) !== -1 }
value={ term.id }
value={ term.id }
onChange={ this.onChange }
onChange={ this.onChange }
name={ 'radio_tax_input-' + this.props.slug }
/>
/>
<label htmlFor={ id }>{ unescapeString( term.name ) }</label>
<label htmlFor={ id }>{ unescapeString( term.name ) }</label>
{ !! term.children.length && (
{ !! term.children.length && (
<div className="editor-post-taxonomies__hierarchical-terms-subchoices">
<div className="editor-post-taxonomies__hierarchical-terms-subchoices">
{ this.renderTerms( term.children ) }
{ this.renderTerms( term.children ) }
</div>
</div>
) }
) }
</div>
</div>
);
);
} );
} );
}
}


render() {
render() {
const { slug, taxonomy, instanceId, hasCreateAction, hasAssignAction } = this.props;
const { slug, taxonomy, instanceId, hasCreateAction, hasAssignAction } = this.props;
const klass = taxonomy.hierarchical ? 'hierarchical' : 'non-hierarchical';


if ( ! hasAssignAction ) {
if ( ! hasAssignAction ) {
return null;
return null;
}
}


const { availableTermsTree, availableTerms, filteredTermsTree, formName, formParent, loading, showForm, filterValue } = this.state;
const { availableTermsTree, availableTerms, filteredTermsTree, formName, formParent, loading, showForm, filterValue } = this.state;
const labelWithFallback = ( labelProperty, fallbackIsCategory, fallbackIsNotCategory ) => get(
const labelWithFallback = ( labelProperty, fallbackIsCategory, fallbackIsNotCategory ) => get(
taxonomy,
taxonomy,
[ 'labels', labelProperty ],
[ 'labels', labelProperty ],
slug === 'category' ? fallbackIsCategory : fallbackIsNotCategory
slug === 'category' ? fallbackIsCategory : fallbackIsNotCategory
);
);
const newTermButtonLabel = labelWithFallback(
const newTermButtonLabel = labelWithFallback(
'add_new_item',
'add_new_item',
__( 'Add new category' ),
__( 'Add new category' ),
__( 'Add new term' )
__( 'Add new term' )
);
);
const newTermLabel = labelWithFallback(
const newTermLabel = labelWithFallback(
'new_item_name',
'new_item_name',
__( 'Add new category' ),
__( 'Add new category' ),
__( 'Add new term' )
__( 'Add new term' )
);
);
const parentSelectLabel = labelWithFallback(
const parentSelectLabel = labelWithFallback(
'parent_item',
'parent_item',
__( 'Parent Category' ),
__( 'Parent Category' ),
__( 'Parent Term' )
__( 'Parent Term' )
);
);
const noParentOption = `— ${ parentSelectLabel } —`;
const noParentOption = `— ${ parentSelectLabel } —`;
const newTermSubmitLabel = newTermButtonLabel;
const newTermSubmitLabel = newTermButtonLabel;
const inputId = `editor-post-taxonomies__hierarchical-terms-input-${ instanceId }`;
const inputId = `editor-post-taxonomies__${ klass }-terms-input-${ instanceId }`;
const filterInputId = `editor-post-taxonomies__hierarchical-terms-filter-${ instanceId }`;
const filterInputId = `editor-post-taxonomies__${ klass }-terms-filter-${ instanceId }`;
const filterLabel = get(
const filterLabel = get(
this.props.taxonomy,
this.props.taxonomy,
[ 'labels', 'search_items' ],
[ 'labels', 'search_items' ],
__( 'Search Terms' )
__( 'Search Terms' )
);
);
const groupLabel = get(
const groupLabel = get(
this.props.taxonomy,
this.props.taxonomy,
[ 'name' ],
[ 'name' ],
__( 'Terms' )
__( 'Terms' )
);
);
const showFilter = availableTerms.length >= MIN_TERMS_COUNT_FOR_FILTER;
const showFilter = availableTerms.length >= MIN_TERMS_COUNT_FOR_FILTER;


const showParentSelect = this.props.taxonomy.hierarchical; // @helgatheviking

return [
return [
showFilter && <label
showFilter && <label
key="filter-label"
key="filter-label"
htmlFor={ filterInputId }>
htmlFor={ filterInputId }>
{ filterLabel }
{ filterLabel }
</label>,
</label>,
showFilter && <input
showFilter && <input
type="search"
type="search"
id={ filterInputId }
id={ filterInputId }
value={ filterValue }
value={ filterValue }
onChange={ this.setFilterValue }
onChange={ this.setFilterValue }
className="editor-post-taxonomies__hierarchical-terms-filter"
className="editor-post-taxonomies__hierarchical-terms-filter"
key="term-filter-input"
key="term-filter-input"
/>,
/>,
<div
<div
className="editor-post-taxonomies__hierarchical-terms-list"
className="editor-post-taxonomies__hierarchical-terms-list"
key="term-list"
key="term-list"
tabIndex="0"
tabIndex="0"
role="group"
role="group"
aria-label={ groupLabel }
aria-label={ groupLabel }
>
>
{ this.renderTerms( '' !== filterValue ? filteredTermsTree : availableTermsTree ) }
{ this.renderTerms( '' !== filterValue ? filteredTermsTree : availableTermsTree ) }
</div>,
</div>,
! loading && hasCreateAction && (
! loading && hasCreateAction && (
<Button
<Button
key="term-add-button"
key="term-add-button"
onClick={ this.onToggleForm }
onClick={ this.onToggleForm }
className="editor-post-taxonomies__hierarchical-terms-add"
className="editor-post-taxonomies__hierarchical-terms-add"
aria-expanded={ showForm }
aria-expanded={ showForm }
isLink
isLink
>
>
{ newTermButtonLabel }
{ newTermButtonLabel }
</Button>
</Button>
),
),
showForm && (
showForm && (
<form onSubmit={ this.onAddTerm } key="hierarchical-terms-form">
<form onSubmit={ this.onAddTerm } key={ klass + '-terms-form' }>
<label
<label
htmlFor={ inputId }
htmlFor={ inputId }
className="editor-post-taxonomies__hierarchical-terms-label"
className="editor-post-taxonomies__hierarchical-terms-label"
>
>
{ newTermLabel }
{ newTermLabel }
</label>
</label>
<input
<input
type="text"
type="text"
id={ inputId }
id={ inputId }
className="editor-post-taxonomies__hierarchical-terms-input"
className="editor-post-taxonomies__hierarchical-terms-input"
value={ formName }
value={ formName }
onChange={ this.onChangeFormName }
onChange={ this.onChangeFormName }
required
required
/>
/>
{ showParentSelect && !! availableTerms.length && // @helgatheviking
{ taxonomy.hierarchical && !! availableTerms.length &&
<TreeSelect
<TreeSelect
label={ parentSelectLabel }
label={ parentSelectLabel }
noOptionLabel={ noParentOption }
noOptionLabel={ noParentOption }
onChange={ this.onChangeFormParent }
onChange={ this.onChangeFormParent }
selectedId={ formParent }
selectedId={ formParent }
tree={ availableTermsTree }
tree={ availableTermsTree }
/>
/>
}
}
<Button
<Button
isDefault
isDefault
type="submit"
type="submit"
className="editor-post-taxonomies__hierarchical-terms-submit"
className="editor-post-taxonomies__hierarchical-terms-submit"
>
>
{ newTermSubmitLabel }
{ newTermSubmitLabel }
</Button>
</Button>
</form>
</form>
),
),
];
];
/* eslint-enable jsx-a11y/no-onchange */
/* eslint-enable jsx-a11y/no-onchange */
}
}
}
}


export default compose( [
export default compose( [
withSelect( ( select, { slug } ) => {
withSelect( ( select, { slug } ) => {
const { getCurrentPost } = select( 'core/editor' );
const { getCurrentPost } = select( 'core/editor' );
const { getTaxonomy } = select( 'core' );
const { getTaxonomy } = select( 'core' );
const taxonomy = getTaxonomy( slug );
const taxonomy = getTaxonomy( slug );
return {
return {
hasCreateAction: taxonomy ? get( getCurrentPost(), [ '_links', 'wp:action-create-' + taxonomy.rest_base ], false ) : false,
hasCreateAction: taxonomy ? get( getCurrentPost(), [ '_links', 'wp:action-create-' + taxonomy.rest_base ], false ) : false,
hasAssignAction: taxonomy ? get( getCurrentPost(), [ '_links', 'wp:action-assign-' + taxonomy.rest_base ], false ) : false,
hasAssignAction: taxonomy ? get( getCurrentPost(), [ '_links', 'wp:action-assign-' + taxonomy.rest_base ], false ) : false,
terms: taxonomy ? select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base ) : [],
terms: taxonomy ? select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base ) : [],
taxonomy,
taxonomy,
};
};
} ),
} ),
withDispatch( ( dispatch ) => ( {
withDispatch( ( dispatch ) => ( {
onUpdateTerms( terms, restBase ) {
onUpdateTerms( terms, restBase ) {
dispatch( 'core/editor' ).editPost( { [ restBase ]: terms } );
dispatch( 'core/editor' ).editPost( { [ restBase ]: terms } );
},
},
} ) ),
} ) ),
withSpokenMessages,
withSpokenMessages,
withInstanceId,
withInstanceId,
//withFilters( 'editor.PostTaxonomyType' ), // intionally commented out
//withFilters( 'editor.PostTaxonomyType' ), // Purposely commented out!
] )( RadioTermSelector );
] )( HierarchicalTermSelector );