import React, { Component } from 'react'; import _ from 'underscore'; import HSPOverview from './kablammo'; import downloadFASTA from './download_fasta'; import AlignmentExporter from './alignment_exporter'; // to download textual alignment /** * Component for each hit. Receives props from Report. Has no state. */ export default class extends Component { constructor(props) { super(props); this.accession = this.accession.bind(this); this.sequenceID = this.sequenceID.bind(this); this.hitLength = this.hitLength.bind(this); this.numHSPs = this.numHSPs.bind(this); this.domID = this.domID.bind(this); this.databaseIDs = this.databaseIDs.bind(this); this.showSequenceViewer = this.showSequenceViewer.bind(this); this.viewSequenceLink = this.viewSequenceLink.bind(this); this.downloadFASTA = this.downloadFASTA.bind(this); this.downloadAlignment = this.downloadAlignment.bind(this); this.headerJSX = this.headerJSX.bind(this); this.contentJSX = this.contentJSX.bind(this); this.hitLinks = this.hitLinks.bind(this); this.viewSequenceButton = this.viewSequenceButton.bind(this); this.downloadFASTAButton = this.downloadFASTAButton.bind(this); } shouldComponentUpdate() { return !this.props.hit; } /** * Returns accession number of the hit sequence. */ accession() { return this.props.hit.accession; } /** * Returns id of the hit sequence. */ sequenceID() { return this.props.hit.id; } /** * Returns length of the hit sequence. */ hitLength() { return this.props.hit.length; } numHSPs() { return this.props.hit.hsps.length; } // Internal helpers. // /** * Returns id that will be used for the DOM node corresponding to the hit. */ domID() { return 'Query_' + this.props.query.number + '_hit_' + this.props.hit.number; } databaseIDs() { return _.map(this.props.querydb, _.iteratee('id')); } showSequenceViewer() { this.props.showSequenceModal(this.viewSequenceLink()); } viewSequenceLink() { var sequenceIDs = encodeURIComponent(this.sequenceID()); var databaseIDs = encodeURIComponent(this.databaseIDs()); return `get_sequence/?sequence_ids=${sequenceIDs}&database_ids=${databaseIDs}`; } downloadFASTA(event) { var sequenceIDs = [this.sequenceID()]; downloadFASTA(sequenceIDs, this.databaseIDs()); } // Event-handler for exporting alignments. // Calls relevant method on AlignmentExporter defined in alignment_exporter.js. downloadAlignment(event) { var hsps = _.map(this.props.hit.hsps, _.bind(function (hsp) { hsp.query_id = this.props.query.id; hsp.hit_id = this.props.hit.id; return hsp; }, this)); var aln_exporter = new AlignmentExporter(); aln_exporter.export_alignments(hsps, this.props.query.id + '_' + this.props.hit.id); } headerJSX() { var meta = `length: ${this.hitLength().toLocaleString()}`; if (this.props.showQueryCrumbs && this.props.showHitCrumbs) { // Multiper queries, multiple hits meta = `hit ${this.props.hit.number} of query ${this.props.query.number}, ` + meta; } else if (this.props.showQueryCrumbs && !this.props.showHitCrumbs) { // Multiple queries, single hit meta = `the only hit of query ${this.props.query.number}, ` + meta; } else if (!this.props.showQueryCrumbs && this.props.showHitCrumbs) { // Single query, multiple hits meta = `hit ${this.props.hit.number}, ` + meta; } return

  {this.props.hit.id}  {this.props.hit.title}

{meta}
; } contentJSX() { return
{this.hitLinks()} 1 && this.numHSPs() < 27} collapsed={this.props.veryBig} />
; } hitLinks() { var btns = []; if (!(this.props.imported_xml || this.props.non_parse_seqids)) { btns = btns.concat([ this.viewSequenceButton(), this.downloadFASTAButton() ]); } btns.push(this.downloadAlignmentButton()); return (
{ btns.map((btn, index) => { return [|, this.button(Object.assign(btn, { key: index }))]; }) } { this.props.hit.links.map((link, index) => { return [|, this.a(link, index)]; }) }
); } // Return JSX for view sequence button. viewSequenceButton() { if (this.hitLength() > 10000) { return { text: 'Sequence', icon: 'fa-eye', className: 'view-sequence', title: 'Sequence too long', }; } else { return { text: 'Sequence', icon: 'fa-eye', className: 'view-sequence', onClick: () => this.showSequenceViewer() }; } } downloadFASTAButton() { return { text: 'FASTA', icon: 'fa-download', className: 'download-fa', onClick: () => this.downloadFASTA() }; } downloadAlignmentButton() { return { text: 'Alignment', icon: 'fa-download', className: 'download-aln', onClick: () => this.downloadAlignment() }; } button({ text, icon, title, className, onClick, key }) { if (onClick) { return ; } else { return ; } } /** * Render URL for sequence-viewer. */ a(link, key) { if (!link.title || !link.url) return; let className = 'btn btn-link'; if (link.class) className = `${className} ${link.class}`; return {link.icon && } {' ' + link.title + ' '} ; } render() { return (
{this.headerJSX()} {this.contentJSX()}
); } }