From 3e569eb76abcad1c37d165e931d2db3709c4ce5b Mon Sep 17 00:00:00 2001 From: Jorge Date: Tue, 9 Jan 2018 22:38:54 +0000 Subject: [PATCH] Fixed errors when adding duplicate categories. Now before issuing requests to the server, we verify if the category being added already exists. If yes we try to select it (if it is not already select). If the category does exist we issue a request to the server, if we get an error saying we have a duplicate category (category may have been added by other used since last time we fetched), we search the server for the new category and we add it to our list. --- .../hierarchical-term-selector.js | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/editor/components/post-taxonomies/hierarchical-term-selector.js b/editor/components/post-taxonomies/hierarchical-term-selector.js index b6a9841e7396b..1f0113eff5456 100644 --- a/editor/components/post-taxonomies/hierarchical-term-selector.js +++ b/editor/components/post-taxonomies/hierarchical-term-selector.js @@ -2,7 +2,7 @@ * External dependencies */ import { connect } from 'react-redux'; -import { unescape as unescapeString, without, map, repeat, find } from 'lodash'; +import { unescape as unescapeString, without, map, repeat, find, some } from 'lodash'; /** * WordPress dependencies @@ -28,6 +28,7 @@ const DEFAULT_QUERY = { class HierarchicalTermSelector extends Component { constructor() { super( ...arguments ); + this.findTerm = this.findTerm.bind( this ); this.onChange = this.onChange.bind( this ); this.onChangeFormName = this.onChangeFormName.bind( this ); this.onChangeFormParent = this.onChangeFormParent.bind( this ); @@ -69,12 +70,35 @@ class HierarchicalTermSelector extends Component { } ) ); } + findTerm( terms, parent, name ) { + return find( terms, term => { + return ( ( ! term.parent && ! parent ) || parseInt( term.parent ) === parseInt( parent ) ) && + term.name === name; + } ); + } + onAddTerm( event ) { event.preventDefault(); - const { formName, formParent, adding } = this.state; + const { onUpdateTerms, restBase, terms, slug } = this.props; + const { formName, formParent, adding, availableTerms } = this.state; if ( formName === '' || adding ) { return; } + + // check if the term we are adding already exists + const existingTerm = this.findTerm( availableTerms, formParent, formName ); + 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 ], restBase ); + } + this.setState( { + formName: '', + formParent: '', + } ); + return; + } + const findOrCreatePromise = new Promise( ( resolve, reject ) => { this.setState( { adding: true, @@ -89,8 +113,13 @@ class HierarchicalTermSelector extends Component { .then( resolve, ( xhr ) => { const errorCode = xhr.responseJSON && xhr.responseJSON.code; if ( errorCode === 'term_exists' ) { - this.addRequest = new Model( { id: xhr.responseJSON.data } ).fetch(); - return this.addRequest.then( resolve, reject ); + // search the new category created since last fetch + this.addRequest = new Model().fetch( + { data: { ...DEFAULT_QUERY, parent: formParent || 0, search: formName } } + ); + return this.addRequest.then( searchResult => { + resolve( this.findTerm( searchResult, formParent, formName ) ); + }, reject ); } reject( xhr ); } ); @@ -99,7 +128,6 @@ class HierarchicalTermSelector extends Component { .then( ( term ) => { const hasTerm = !! find( this.state.availableTerms, ( availableTerm ) => availableTerm.id === term.id ); const newAvailableTerms = hasTerm ? this.state.availableTerms : [ term, ...this.state.availableTerms ]; - const { onUpdateTerms, restBase, terms, slug } = this.props; const termAddedMessage = slug === 'category' ? __( 'Category added' ) : __( 'Term added' ); this.props.speak( termAddedMessage, 'assertive' ); this.setState( {