@ -1,6 +1,7 @@
import React from "react" ;
import Select from "react-select" ;
import CreatableSelect from "react-select/creatable" ;
import ReactDragListView from "react-drag-listview/lib/index.js" ;
import { gAppRef } from "./index.js" ;
import { ImageFileUploader } from "./FileUploader.js" ;
import { sortSelectableOptions , unloadCreatableSelect } from "./utils.js" ;
@ -10,111 +11,148 @@ import { sortSelectableOptions, unloadCreatableSelect } from "./utils.js" ;
export class PublicationSearchResult2
{
static _doEditPublication ( vals , notify ) {
static _doEditPublication ( vals , articles , notify ) {
// initialize
let refs = { } ;
// initialize the image
let imageFilename = null , imageData = null ;
let imageRef = null , uploadImageRef = null , removeImageRef = null ;
let imageUrl = gAppRef . makeFlaskUrl ( "/images/publication/" + vals . pub _id ) ;
imageUrl += "?foo=" + Math . random ( ) ; // FUDGE! To bypass the cache :-/
let onMissingImage = ( evt ) => {
imageRef . src = "/images/placeholder.png" ;
removeImageRef . style . display = "none" ;
} ;
let onUploadImage = ( evt ) => {
if ( evt === null && ! gAppRef . isFakeUploads ( ) ) {
// nb: the publication image was clicked - trigger an upload request
uploadImageRef . click ( ) ;
return ;
function doRender ( ) {
// initialize the image
let imageRef = null , uploadImageRef = null , removeImageRef = null ;
let imageUrl = gAppRef . makeFlaskUrl ( "/images/publication/" + vals . pub _id ) ;
imageUrl += "?foo=" + Math . random ( ) ; // FUDGE! To bypass the cache :-/
let onMissingImage = ( evt ) => {
imageRef . src = "/images/placeholder.png" ;
removeImageRef . style . display = "none" ;
} ;
let onUploadImage = ( evt ) => {
if ( evt === null && ! gAppRef . isFakeUploads ( ) ) {
// nb: the publication image was clicked - trigger an upload request
uploadImageRef . click ( ) ;
return ;
}
let fileUploader = new ImageFileUploader ( ) ;
fileUploader . getFile ( evt , imageRef , removeImageRef , ( fname , data ) => {
imageFilename = fname ;
imageData = data ;
} ) ;
} ;
let onRemoveImage = ( ) => {
imageData = "{remove}" ;
imageRef . src = "/images/placeholder.png" ;
removeImageRef . style . display = "none" ;
} ;
// initialize the publishers
let publishers = [ { value : null , label : < i > ( none ) < / i > } ] ;
let currPubl = 0 ;
for ( let p of Object . entries ( gAppRef . caches . publishers ) ) {
publishers . push ( {
value : p [ 1 ] . publ _id ,
label : < span dangerouslySetInnerHTML = { { _ _html : p [ 1 ] . publ _name } } / >
} ) ;
if ( p [ 1 ] . publ _id === vals . publ _id )
currPubl = publishers . length - 1 ;
}
let fileUploader = new ImageFileUploader ( ) ;
fileUploader . getFile ( evt , imageRef , removeImageRef , ( fname , data ) => {
imageFilename = fname ;
imageData = data ;
} ) ;
} ;
let onRemoveImage = ( ) => {
imageData = "{remove}" ;
imageRef . src = "/images/placeholder.png" ;
removeImageRef . style . display = "none" ;
} ;
sortSelectableOptions ( publishers ) ;
// initialize the publishers
let publishers = [ { value : null , label : < i > ( none ) < / i > } ] ;
let currPubl = 0 ;
for ( let p of Object . entries ( gAppRef . caches . publishers ) ) {
publishers . push ( {
value : p [ 1 ] . publ _id ,
label : < span dangerouslySetInnerHTML = { { _ _html : p [ 1 ] . publ _name } } / >
} ) ;
if ( p [ 1 ] . publ _id === vals . publ _id )
currPubl = publishers . length - 1 ;
}
sortSelectableOptions ( publishers ) ;
// initialize the publications
// NOTE: As a convenience, we provide a droplist of known publication names (without edition #'s),
// to make it easier to add a new edition of an existing publication.
let publications = { } ;
for ( let p of Object . entries ( gAppRef . caches . publications ) )
publications [ p [ 1 ] . pub _name ] = p [ 1 ] ;
let publications2 = [ ] ;
for ( let pub _name in publications ) {
const pub = publications [ pub _name ] ;
publications2 . push ( { value : pub . pub _id , label : pub . pub _name } ) ;
}
sortSelectableOptions ( publications2 ) ;
let currPub = null ;
for ( let pub of publications2 ) {
if ( pub . label === vals . pub _name ) {
currPub = pub ;
break ;
// initialize the publications
// NOTE: As a convenience, we provide a droplist of known publication names (without edition #'s),
// to make it easier to add a new edition of an existing publication.
let publications = { } ;
for ( let p of Object . entries ( gAppRef . caches . publications ) )
publications [ p [ 1 ] . pub _name ] = p [ 1 ] ;
let publications2 = [ ] ;
for ( let pub _name in publications ) {
const pub = publications [ pub _name ] ;
publications2 . push ( { value : pub . pub _id , label : pub . pub _name } ) ;
}
sortSelectableOptions ( publications2 ) ;
let currPub = null ;
for ( let pub of publications2 ) {
if ( pub . label === vals . pub _name ) {
currPub = pub ;
break ;
}
}
}
// initialize the tags
const tags = gAppRef . makeTagLists ( vals . pub _tags ) ;
// prepare the form content
/* eslint-disable jsx-a11y/img-redundant-alt */
const content = < div >
< div className = "image-container" >
< div className = "row image" >
< img src = { imageUrl } className = "image" onError = { onMissingImage } onClick = { ( ) => onUploadImage ( null ) } ref = { r => imageRef = r } alt = "Click to upload an image for this publication." / >
< img src = "/images/delete.png" className = "remove-image" onClick = { onRemoveImage } ref = { r => removeImageRef = r } alt = "Remove the publication's image." / >
< input type = "file" accept = "image/*" onChange = { onUploadImage } style = { { display : "none" } } ref = { r => uploadImageRef = r } / >
// initialize the tags
const tags = gAppRef . makeTagLists ( vals . pub _tags ) ;
// initialize the articles
function make _article _display _name ( article ) {
let pageno = null ;
if ( article . article _pageno ) {
pageno = ( < span className = "pageno" >
{ article . article _pageno . substr ( 0 , 1 ) === "p" || "p" }
{ article . article _pageno }
< / s p a n > ) ;
}
return < span > { article . article _title } { pageno && < span className = "pageno" > ( { pageno } ) < / s p a n > } < / s p a n > ;
}
const dragProps = {
onDragEnd ( fromIndex , toIndex ) {
const item = articles . splice ( fromIndex , 1 ) [ 0 ] ;
articles . splice ( toIndex , 0 , item ) ;
gAppRef . _modalFormRef . current . forceUpdate ( ) ;
} ,
nodeSelector : "li" ,
lineClassName : "dragLine" ,
} ;
// prepare the form content
/* eslint-disable jsx-a11y/img-redundant-alt */
const content = < div >
< div className = "image-container" >
< div className = "row image" >
< img src = { imageUrl } className = "image" onError = { onMissingImage } onClick = { ( ) => onUploadImage ( null ) } ref = { r => imageRef = r } alt = "Click to upload an image for this publication." / >
< img src = "/images/delete.png" className = "remove-image" onClick = { onRemoveImage } ref = { r => removeImageRef = r } alt = "Remove the publication's image." / >
< input type = "file" accept = "image/*" onChange = { onUploadImage } style = { { display : "none" } } ref = { r => uploadImageRef = r } / >
< / d i v >
< / d i v >
< div className = "row name" > < label className = "select top" > Name : < / l a b e l >
< CreatableSelect className = "react-select" classNamePrefix = "react-select" options = { publications2 } autoFocus
defaultValue = { currPub }
ref = { r => refs . pub _name = r }
/ >
< / d i v >
< div className = "row edition" > < label className = "top" > Edition : < / l a b e l >
< input type = "text" defaultValue = { vals . pub _edition } ref = { r => refs . pub _edition = r } / >
< / d i v >
< div className = "row publisher" > < label className = "select top" > Publisher : < / l a b e l >
< Select className = "react-select" classNamePrefix = "react-select" options = { publishers } isSearchable = { true }
defaultValue = { publishers [ currPubl ] }
ref = { r => refs . publ _id = r }
/ >
< / d i v >
< / d i v >
< div className = "row name" > < label className = "select top" > Name : < / l a b e l >
< CreatableSelect className = "react-select" classNamePrefix = "react-select" options = { publications2 } autoFocus
defaultValue = { currPub }
ref = { r => refs . pub _name = r }
/ >
< / d i v >
< div className = "row edition" > < label className = "top" > Edition : < / l a b e l >
< input type = "text" defaultValue = { vals . pub _edition } ref = { r => refs . pub _edition = r } / >
< / d i v >
< div className = "row publisher" > < label className = "select top" > Publisher : < / l a b e l >
< Select className = "react-select" classNamePrefix = "react-select" options = { publishers } isSearchable = { true }
defaultValue = { publishers [ currPubl ] }
ref = { r => refs . publ _id = r }
/ >
< / d i v >
< div className = "row description" > < label > Description : < / l a b e l >
< textarea defaultValue = { vals . pub _description } ref = { r => refs . pub _description = r } / >
< / d i v >
< div className = "row tags" > < label className = "select" > Tags : < / l a b e l >
< CreatableSelect className = "react-select" classNamePrefix = "react-select" options = { tags [ 1 ] } isMulti
defaultValue = { tags [ 0 ] }
ref = { r => refs . pub _tags = r }
/ >
< / d i v >
< div className = "row url" > < label > Web : < / l a b e l >
< input type = "text" defaultValue = { vals . pub _url } ref = { r => refs . pub _url = r } / >
< / d i v >
< / d i v > ;
< div className = "row description" > < label > Description : < / l a b e l >
< textarea defaultValue = { vals . pub _description } ref = { r => refs . pub _description = r } / >
< / d i v >
< div className = "row tags" > < label className = "select" > Tags : < / l a b e l >
< CreatableSelect className = "react-select" classNamePrefix = "react-select" options = { tags [ 1 ] } isMulti
defaultValue = { tags [ 0 ] }
ref = { r => refs . pub _tags = r }
/ >
< / d i v >
< div className = "row url" > < label > Web : < / l a b e l >
< input type = "text" defaultValue = { vals . pub _url } ref = { r => refs . pub _url = r } / >
< / d i v >
{ articles && articles . length > 0 &&
< fieldset className = "articles" > < legend > Articles < / l e g e n d >
< ReactDragListView { ... dragProps } > < ul >
{ articles . map ( a => (
< li key = { a . article _id } className = "draggable" > { make _article _display _name ( a ) } < / l i >
) ) }
< / u l > < / R e a c t D r a g L i s t V i e w >
< / f i e l d s e t >
}
< / d i v > ;
return content ;
}
// prepare the form buttons
const buttons = {
@ -149,7 +187,11 @@ export class PublicationSearchResult2
// show the form
const isNew = Object . keys ( vals ) . length === 0 ;
gAppRef . showModalForm ( "publication-form" , isNew ? "New publication" : "Edit publication" , "#e5f700" , content , buttons ) ;
gAppRef . showModalForm ( "publication-form" ,
isNew ? "New publication" : "Edit publication" , "#e5f700" ,
doRender ,
buttons
) ;
}
}