import React from "react" ; import { Link } from "react-router-dom" ; import { Menu, MenuList, MenuButton, MenuItem } from "@reach/menu-button" ; import "./PublicationSearchResult.css" ; import { PublicationSearchResult2 } from "./PublicationSearchResult2.js" ; import { PreviewableImage } from "./PreviewableImage.js" ; import { PUBLICATION_EXCESS_ARTICLE_THRESHOLD } from "./constants.js" ; import { gAppRef } from "./App.js" ; import { makeCollapsibleList, pluralString, updateRecord } from "./utils.js" ; const axios = require( "axios" ) ; // -------------------------------------------------------------------- export class PublicationSearchResult extends React.Component { render() { // prepare the basic details const display_description = PreviewableImage.adjustHtmlForPreviewableImages( this.props.data[ "pub_description!" ] || this.props.data.pub_description ) ; const parent_publ = this.props.data._parent_publ ; const image_url = PublicationSearchResult._makeImageUrl( this.props.data ) ; // prepare the publication's URL let pub_url = this.props.data.pub_url ; if ( pub_url ) pub_url = gAppRef.makeExternalDocUrl( pub_url ) ; // prepare the tags let tags = [] ; if ( this.props.data[ "tags!" ] ) { // the backend has provided us with a list of tags (possibly highlighted) - use them directly // NOTE: We don't normally show HTML in tags, but in this case we need to, in order to be able to highlight // matching search terms. This will have the side-effect of rendering any HTML that may be in the tag, // but we can live with that. for ( let i=0 ; i < this.props.data["tags!"].length ; ++i ) { const tag = this.props.data.pub_tags[ i ] ; // nb: this is the actual tag (without highlights) tags.push( ) ; } } else { if ( this.props.data.pub_tags ) { this.props.data.pub_tags.map( tag => tags.push( {tag} ) ) ; } } // prepare the articles let articles = [] ; if ( this.props.data.articles ) { for ( let i=0 ; i < this.props.data.articles.length ; ++i ) { const article = this.props.data.articles[ i ] ; let onArticleClick = (evt) => { // NOTE: We let the parent take a look at clicks first, so that they can scroll // to the article if it's already on-screen. if ( this.props.onArticleClick && this.props.onArticleClick( article.article_id ) ) evt.preventDefault() ; } ; articles.push( ) ; } } // prepare the menu const menu = ( this.onEditPublication() } > Edit. Edit this.onDeletePublication() } > Delete. Delete ) ; return (
gAppRef.setTestAttribute( r, "pub_id", this.props.data.pub_id ) } >
{menu} { parent_publ && } { pub_url && Open publication. }
{ image_url && }
{ makeCollapsibleList( "Articles", articles, PUBLICATION_EXCESS_ARTICLE_THRESHOLD, {float:"left",marginBottom:"0.25em"} ) }
{ this.props.data.pub_date &&
{this.props.data.pub_date}
} { tags.length > 0 &&
{tags}
}
) ; } componentDidMount() { PreviewableImage.activatePreviewableImages( this ) ; } static onNewPublication() { gAppRef.dataCache.get( [ "publishers", "publications", "tags" ], () => { PublicationSearchResult2._doEditPublication( {}, null, (newVals,refs) => { axios.post( gAppRef.makeFlaskUrl( "/publication/create" ), newVals ).then( resp => { gAppRef.dataCache.refresh( [ "publications", "tags" ], () => { // update the UI const newPub = resp.data.record ; gAppRef.prependSearchResult( newPub ) ; if ( newPub._parent_publ ) gAppRef.updatePublisher( newPub._parent_publ.publ_id ) ; // update the UI if ( resp.data.warnings ) gAppRef.showWarnings( "The new publication was created OK.", resp.data.warnings ) ; else gAppRef.showInfoToast(
The new publication was created OK.
) ; gAppRef.closeModalForm() ; } ) ; } ).catch( err => { gAppRef.showErrorMsg(
Couldn't create the publication:
{err.toString()}
) ; } ) ; } ) ; } ) ; } onEditPublication() { gAppRef.dataCache.get( [ "publishers", "publications", "tags" ], () => { // get the articles for this publication let articles = this.props.data.articles ; // nb: _doEditPublication() might change the order of this list PublicationSearchResult2._doEditPublication( this.props.data, articles, (newVals,refs) => { // send the updated details to the server newVals.pub_id = this.props.data.pub_id ; if ( articles ) newVals.article_order = articles.map( a => a.article_id ) ; axios.post( gAppRef.makeFlaskUrl( "/publication/update" ), newVals ).then( resp => { // update the UI gAppRef.dataCache.refresh( [ "publications", "tags" ], () => { // update the UI const pub = resp.data.record ; const orig_parent_publ = this.props.data._parent_publ ; updateRecord( this.props.data, pub ) ; if ( pub._parent_publ ) gAppRef.updatePublisher( pub._parent_publ.publ_id ) ; if ( orig_parent_publ ) gAppRef.updatePublisher( orig_parent_publ.publ_id ) ; // update the UI if ( newVals.imageData ) gAppRef.forceFlaskImageReload( "publication", newVals.pub_id ) ; this.forceUpdate() ; PreviewableImage.activatePreviewableImages( this ) ; // update the UI if ( resp.data.warnings ) gAppRef.showWarnings( "The publication was updated OK.", resp.data.warnings ) ; else gAppRef.showInfoToast(
The publication was updated OK.
) ; gAppRef.closeModalForm() ; } ) ; } ).catch( err => { gAppRef.showErrorMsg(
Couldn't update the publication:
{err.toString()}
) ; } ) ; } ) ; } ) ; } onDeletePublication() { let doDelete = ( nArticles ) => { // confirm the operation let warning ; if ( typeof nArticles === "number" ) { if ( nArticles === 0 ) warning =
No articles will be deleted.
; else warning =
{ pluralString(nArticles,"associated article") + " will also be deleted." }
; } else { warning = (
Error. WARNING: Couldn't check if any associated articles will be deleted:
{nArticles.toString()}
) ; } const content = (
Delete this publication?
{warning}
) ; gAppRef.ask( content, "ask", { "OK": () => { // delete the publication on the server axios.get( gAppRef.makeFlaskUrl( "/publication/delete/" + this.props.data.pub_id ) ).then( resp => { gAppRef.dataCache.refresh( [ "publications", "tags" ] ) ; // update the UI this.props.onDelete( "pub_id", this.props.data.pub_id ) ; resp.data.deletedArticles.forEach( article_id => { this.props.onDelete( "article_id", article_id, true ) ; } ) ; if ( this.props.data._parent_publ ) gAppRef.updatePublisher( this.props.data._parent_publ.publ_id ) ; // update the UI if ( resp.data.warnings ) gAppRef.showWarnings( "The publication was deleted.", resp.data.warnings ) ; else gAppRef.showInfoToast(
The publication was deleted.
) ; } ).catch( err => { gAppRef.showErrorToast(
Couldn't delete the publication:
{err.toString()}
) ; } ) ; }, "Cancel": null, } ) ; } // get the publication details axios.get( gAppRef.makeFlaskUrl( "/publication/" + this.props.data.pub_id ) ).then( resp => { doDelete( resp.data.nArticles ) ; } ).catch( err => { doDelete( err ) ; } ) ; } static makeDisplayName( vals, allowAlternateContent ) { let pub_name = null ; if ( allowAlternateContent && vals["pub_name!"] ) pub_name = vals[ "pub_name!" ] ; if ( ! pub_name ) pub_name = vals.pub_name ; if ( vals.pub_edition ) return pub_name + " (" + vals.pub_edition + ")" ; else return pub_name ; } _makeDisplayName( allowAlternateContent ) { return PublicationSearchResult.makeDisplayName( this.props.data, allowAlternateContent ) ; } static _makeImageUrl( vals ) { let image_url = gAppRef.makeFlaskImageUrl( "publication", vals.pub_image_id ) ; if ( ! image_url ) { // check if the parent publisher has an image const parent_publ = vals._parent_publ ; if ( parent_publ ) image_url = gAppRef.makeFlaskImageUrl( "publisher", parent_publ.publ_image_id ) ; } return image_url ; } }