Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert refactoring hierarchical term selector using the data module #11395

Merged
merged 1 commit into from
Nov 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions docs/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -1769,15 +1769,6 @@ Returns an action object used to signal that post saving is unlocked.

* lockName: The lock name.

### addTermToEditedPost

Returns an action object signaling that a new term is added to the edited post.

*Parameters*

* slug: Taxonomy slug.
* term: Term object.

### createNotice

### fetchReusableBlocks
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { get, unescape as unescapeString, without, find, some } from 'lodash';
import { get, unescape as unescapeString, without, find, some, invoke } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -11,6 +11,8 @@ import { Component } from '@wordpress/element';
import { TreeSelect, withSpokenMessages, withFilters, Button } from '@wordpress/components';
import { withSelect, withDispatch } from '@wordpress/data';
import { withInstanceId, compose } from '@wordpress/compose';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
Expand All @@ -24,6 +26,7 @@ const DEFAULT_QUERY = {
per_page: -1,
orderby: 'name',
order: 'asc',
_fields: 'id,name,parent',
};

const MIN_TERMS_COUNT_FOR_FILTER = 8;
Expand All @@ -38,7 +41,12 @@ class HierarchicalTermSelector extends Component {
this.onAddTerm = this.onAddTerm.bind( this );
this.onToggleForm = this.onToggleForm.bind( this );
this.setFilterValue = this.setFilterValue.bind( this );
this.sortBySelected = this.sortBySelected.bind( this );
this.state = {
loading: true,
availableTermsTree: [],
availableTerms: [],
adding: false,
formName: '',
formParent: '',
showForm: false,
Expand All @@ -48,13 +56,13 @@ class HierarchicalTermSelector extends Component {
}

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

onChangeFormName( event ) {
Expand All @@ -81,9 +89,9 @@ class HierarchicalTermSelector extends Component {

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

Expand All @@ -92,7 +100,7 @@ class HierarchicalTermSelector extends Component {
if ( existingTerm ) {
// if the term we are adding exists but is not selected select it
if ( ! some( terms, ( term ) => term === existingTerm.id ) ) {
onUpdateTerms( [ ...terms, existingTerm.id ] );
onUpdateTerms( [ ...terms, existingTerm.id ], taxonomy.rest_base );
}
this.setState( {
formName: '',
Expand All @@ -101,14 +109,113 @@ class HierarchicalTermSelector extends Component {
return;
}

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

componentDidMount() {
this.fetchTerms();
}

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

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

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

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

sortBySelected( termsTree ) {
Expand Down Expand Up @@ -149,7 +256,7 @@ class HierarchicalTermSelector extends Component {
}

setFilterValue( event ) {
const { availableTermsTree } = this.props;
const { availableTermsTree } = this.state;
const filterValue = event.target.value;
const filteredTermsTree = availableTermsTree.map( this.getFilterMatcher( filterValue ) ).filter( ( term ) => term );
const getResultCount = ( terms ) => {
Expand All @@ -162,10 +269,12 @@ class HierarchicalTermSelector extends Component {
}
return count;
};
this.setState( {
filterValue,
filteredTermsTree,
} );
this.setState(
{
filterValue,
filteredTermsTree,
}
);

const resultCount = getResultCount( filteredTermsTree );
const resultsFoundMessage = sprintf(
Expand Down Expand Up @@ -230,21 +339,13 @@ class HierarchicalTermSelector extends Component {
}

render() {
const {
slug,
taxonomy,
instanceId,
hasCreateAction,
hasAssignAction,
availableTermsTree,
availableTerms,
} = this.props;
const { slug, taxonomy, instanceId, hasCreateAction, hasAssignAction } = this.props;

if ( ! hasAssignAction ) {
return null;
}

const { filteredTermsTree, formName, formParent, isRequestingTerms, showForm, filterValue } = this.state;
const { availableTermsTree, availableTerms, filteredTermsTree, formName, formParent, loading, showForm, filterValue } = this.state;
const labelWithFallback = ( labelProperty, fallbackIsCategory, fallbackIsNotCategory ) => get(
taxonomy,
[ 'labels', labelProperty ],
Expand Down Expand Up @@ -285,7 +386,7 @@ class HierarchicalTermSelector extends Component {
slug === 'category' ? __( 'Categories' ) : __( 'Terms' )
)
);
const showFilter = availableTerms && ( availableTerms.length >= MIN_TERMS_COUNT_FOR_FILTER );
const showFilter = availableTerms.length >= MIN_TERMS_COUNT_FOR_FILTER;

return [
showFilter && <label
Expand All @@ -308,9 +409,9 @@ class HierarchicalTermSelector extends Component {
role="group"
aria-label={ groupLabel }
>
{ this.renderTerms( '' !== filterValue ? filteredTermsTree : this.sortBySelected( availableTermsTree ) ) }
{ this.renderTerms( '' !== filterValue ? filteredTermsTree : availableTermsTree ) }
</div>,
! isRequestingTerms && hasCreateAction && (
! loading && hasCreateAction && (
<Button
key="term-add-button"
onClick={ this.onToggleForm }
Expand Down Expand Up @@ -363,27 +464,18 @@ class HierarchicalTermSelector extends Component {
export default compose( [
withSelect( ( select, { slug } ) => {
const { getCurrentPost } = select( 'core/editor' );
const { getTaxonomy, getEntityRecords } = select( 'core' );
const { isResolving } = select( 'core/data' );
const { getTaxonomy } = select( 'core' );
const taxonomy = getTaxonomy( slug );
const availableTerms = getEntityRecords( 'taxonomy', slug, DEFAULT_QUERY );
const availableTermsTree = buildTermsTree( availableTerms );
return {
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,
terms: taxonomy ? select( 'core/editor' ).getEditedPostAttribute( taxonomy.rest_base ) : [],
isRequestingTerms: isResolving( 'core', 'getEntityRecords', [ 'taxonomy', slug, DEFAULT_QUERY ] ),
taxonomy,
availableTerms,
availableTermsTree,
};
} ),
withDispatch( ( dispatch, { slug, taxonomy } ) => ( {
onUpdateTerms( terms ) {
dispatch( 'core/editor' ).editPost( { [ taxonomy.rest_base ]: terms } );
},
addTermToEditedPost( term ) {
return dispatch( 'core/editor' ).addTermToEditedPost( slug, term );
withDispatch( ( dispatch ) => ( {
onUpdateTerms( terms, restBase ) {
dispatch( 'core/editor' ).editPost( { [ restBase ]: terms } );
},
} ) ),
withSpokenMessages,
Expand Down
16 changes: 0 additions & 16 deletions packages/editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -779,22 +779,6 @@ export function unlockPostSaving( lockName ) {
};
}

/**
* Returns an action object signaling that a new term is added to the edited post.
*
* @param {string} slug Taxonomy slug.
* @param {Object} term Term object.
*
* @return {Object} Action object.
*/
export function addTermToEditedPost( slug, term ) {
return {
type: 'ADD_TERM_TO_EDITED_POST',
slug,
term,
};
}

//
// Deprecated
//
Expand Down
6 changes: 0 additions & 6 deletions packages/editor/src/store/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ import {
trashPostFailure,
refreshPost,
} from './effects/posts';
import {
addTermToEditedPost,
} from './effects/terms';

/**
* Block validity is a function of blocks state (at the point of a
Expand Down Expand Up @@ -261,7 +258,4 @@ export default {
REPLACE_BLOCKS: [
ensureDefaultBlock,
],
ADD_TERM_TO_EDITED_POST: ( action ) => {
addTermToEditedPost( action );
},
};
39 changes: 0 additions & 39 deletions packages/editor/src/store/effects/terms.js

This file was deleted.