import React from "react" ;
import ReactDOM from "react-dom" ;
import "./SearchResults.css" ;
import { PublisherSearchResult } from "./PublisherSearchResult" ;
import { PublicationSearchResult } from "./PublicationSearchResult" ;
import { ArticleSearchResult } from "./ArticleSearchResult" ;
import { gAppRef } from "./App.js" ;
// --------------------------------------------------------------------
export class SearchResults extends React.Component
{
render() {
let results ;
if ( this.props.searchResults && this.props.searchResults.error !== undefined ) {
// show the error message
results = "ERROR: " + this.props.searchResults.error ;
} else if ( ! this.props.searchResults || this.props.searchResults.length === 0 ) {
// show that no search results were found
results = (this.props.seqNo === 0) ? null :
No results.
;
} else if ( this.props.searchResults === "(loading)" ) {
// show the loading spinner
results = (
) ;
setTimeout( function() {
let elem = document.getElementById( "loading" ) ;
if ( elem )
elem.style.display = "block" ;
}, 500 ) ;
} else {
// track articles
let articleRefs = {} ;
function scrollToArticle( article_id ) {
// NOTE: If the user has clicked on an article that has been listed as part of a publication,
// we just scroll to that article (since articles are also returned as part of the search results
// when searching for a publication).
// NOTE: We could do the same thing when clicking on a publication that has been listed as part
// of a publisher, but in this case, it's probably better UX to show the publication's page,
// along with its articles.
const node = ReactDOM.findDOMNode( articleRefs[article_id] ) ;
if ( node ) {
node.scrollIntoView() ;
return true ;
}
}
// render the search results
results = [] ;
this.props.searchResults.forEach( sr => {
if ( sr._type === "publisher" ) {
results.push( this.onDeleteSearchResult( n, v, i ) }
/> ) ;
} else if ( sr._type === "publication" ) {
results.push( this.onDeleteSearchResult( n, v, i ) }
onArticleClick = { (a) => scrollToArticle(a) }
/> ) ;
} else if ( sr._type === "article" ) {
results.push( this.onDeleteSearchResult( n, v, i ) }
ref = { r => articleRefs[sr.article_id] = r }
/> ) ;
} else {
gAppRef.logInternalError( "Unknown search result type.", "srType = "+sr._type ) ;
}
} ) ;
}
return {results}
;
}
onDeleteSearchResult( idName, idVal, ignoreNotFound ) {
// look for the specified search result
for ( let i=0 ; i < this.props.searchResults.length ; ++i ) {
const sr = this.props.searchResults[ i ] ;
if ( sr[idName] === idVal ) {
// found it - remove it the UI
this.props.searchResults.splice( i, 1 ) ;
this.forceUpdate() ;
return ;
}
}
// the search result wasn't found
// NOTE: This would normally indicate an internal coding error, but there is one case where
// it can happen: when a publisher or publication is deleted, we want to also delete all
// their child objects, but they may not necessarily be on-screen.
if ( ! ignoreNotFound ) {
gAppRef.logInternalError(
"Tried to delete an unknown search result.", idName+" = "+idVal
) ;
}
}
}