Untitled diff
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 );