diff options
Diffstat (limited to 'client/table/citations.table.js')
| -rw-r--r-- | client/table/citations.table.js | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/client/table/citations.table.js b/client/table/citations.table.js new file mode 100644 index 00000000..178cc65b --- /dev/null +++ b/client/table/citations.table.js @@ -0,0 +1,130 @@ +import React, { Component } from 'react' +import { bindActionCreators } from 'redux' +import { connect } from 'react-redux' +import { ReactTabulator } from 'react-tabulator' +import { saveAs } from 'file-saver' + +import { Loader } from '../common' +import { toArray, toTuples, domainFromUrl } from '../util' + +export const citationsColumns = [ + { title: 'Title', field: 'title', sorter: 'string' }, + { title: 'Institution', field: 'institution', sorter: 'string', }, + { title: 'Country', field: 'country', sorter: 'string', width: 140, }, + { title: 'Year', field: 'year', sorter: 'number', width: 70 }, + { title: 'PDF', field: 'pdf_text', formatter: 'link', + formatterParams: { target: "_blank", urlField: 'pdf_link', }, + sorter: 'string', width: 100 }, +] + +class CitationsTable extends Component { + state = { + q: '', + formattedCitations: [], + filteredCitations: [], + } + + componentDidMount(){ + this.updateCitations() + } + componentDidUpdate(oldProps){ + if (this.props.payload.data.citations !== oldProps.payload.data.citations) { + this.updateCitations() + } + } + updateCitations(){ + const { paper, citations } = this.props.payload.data + if (!citations.length) this.setState({ formattedCitations: [] }) + console.log(citations.filter(a => a.title.match('Coarse'))) + const formattedCitations = citations.sort((a,b) => a.title.localeCompare(b.title)).map(citation => { + const pdf_link = (citation.pdf && citation.pdf.length) + ? citation.pdf[0] + : (citation.doi && citation.doi.length) + ? citation.doi[0] + : 'https://www.semanticscholar.org/paper/' + citation.id + let pdf_text = domainFromUrl(pdf_link) + return { + title: citation.title, + institution: citation.addresses.map(a => a.name).sort().join('; '), + country: Array.from(new Set(citation.addresses.map(a => a.country))).sort().join('; '), + year: citation.year, + pdf_link, pdf_text, + } + }) + this.setState({ + formattedCitations, + filteredCitations: formattedCitations, + }) + } + + updateFilter(q) { + const { formattedCitations } = this.state + if (!q.length) { + this.setState({ q, filteredCitations: formattedCitations }) + } else { + let q_re = new RegExp('(' + q.replace(/\s+/g, ' ').trim().replace(' ', '|') + ')', 'gi') + let filteredCitations = formattedCitations.filter(citation => ( + citation.title.match(q_re) || + citation.institution.match(q_re) || + citation.country.match(q_re) + )) + this.setState({ q, filteredCitations }) + } + } + + download() { + const { formattedCitations } = this.state + const fn = this.props.payload.data.paper.key + '.csv' + const titles = citationsColumns.map(c => c.title) + const fields = citationsColumns.map(c => c.formatterParams ? c.formatterParams.urlField : c.field) + const rows = formattedCitations.map(citation => { + const row = fields.map(field => citation[field]).map(data => { + switch (typeof data) { + case 'number': + return String(data) + default: + return '\"' + String(data) + '\"' + } + }) + return row.join(",") + }) + + const blob = new Blob([ + [ + titles.join(','), + ...rows, + ].join('\n') + ], {type: "text/csv;charset=utf-8"}); + saveAs(blob, fn); + } + + render() { + const { formattedCitations, filteredCitations } = this.state + if (!formattedCitations.length) return <Loader /> + return ( + <div className='citationBrowser'> + <div className='citationHeader'> + <input + type="text" + value={this.state.q} + onChange={e => this.updateFilter(e.target.value)} + className='q' + placeholder='Enter text to search citations...' + /> + <span className='download' onClick={() => this.download()}>Download CSV</span> + </div> + <ReactTabulator + columns={citationsColumns} + data={filteredCitations} + options={{ + height: Math.max(104, Math.min(37 * formattedCitations.length + 29, 311)), + layout: 'fitColumns', + placeholder: formattedCitations.length ? '' : 'Nothing matches your query', + }} + /> + </div> + ) + } +} + +export default CitationsTable |
