CondensateDetailPage.vue 14.60 KiB
<template>
<div class="d-flex" id="wrapper">
<!-- Sidebar -->
<!--<div class="bg-light border-right" id="sidebar-wrapper">-->
<!--<!–<div class="sidebar-heading">Menu </div>–>-->
<!--<div class="list-group list-group-flush">-->
<!--<a href="#" class="list-group-item list-group-item-action bg-light">Search</a>-->
<!--<a href="#" class="list-group-item list-group-item-action bg-light">Columns</a>-->
<!--<a href="#" class="list-group-item list-group-item-action bg-light">Filters</a>-->
<!--<a href="#" class="list-group-item list-group-item-action bg-light">Download</a>-->
<!--<a href="#" class="list-group-item list-group-item-action bg-light">Contacts</a>-->
<!--</div>-->
<!--</div>-->
<!-- /#sidebar-wrapper -->
<div id="page-content-wrapper" class="main">
<fetch-condensate :condensate="condensate">
<template slot-scope="{response, loading}">
<slot :response="response" :loading="loading">
<div v-if="loading || response === null">Loading...</div>
<div v-else>
<h2>{{response.data.name}}</h2>
<h4 class="round">General Information</h4>
<div class="panel panel-default">
<div class="panel-body">
<div class="container-fluid col-md-12">
<div class="row">
<div class="text col-sm-3">Canonical ID</div>
<div class="col-sm-9">
{{response.data.canonical_id}}
</div>
</div>
<div class="row">
<div class="text col-sm-3">Species</div>
<div class="col-sm-9">
{{response.data.species_name}}
</div>
</div>
<div class="row">
<div class="text col-sm-3">Description</div>
<div class="col-sm-9">
{{response.data.description}}
</div>
</div>
<!--<div class="row">-->
<!--<div class="text col-sm-3">Evidence Stars</div>-->
<!--<div class="col-sm-9 tooltipped tooltipped-w"-->
<!--:aria-label="getDbNames(response.data.data_sources)">-->
<!--<span v-for="(item, index) in getRating(response.data.data_sources)" :class="item" v-bind:key="index"/>-->
<!--</div>-->
<!--</div>-->
<div class="row" v-show="response.data.synonyms">
<div class="text col-sm-3">Also Known As</div>
<div class="col-sm-9">
{{response.data.synonyms ? response.data.synonyms.map(a => a.replace('-', ' ').replace(/\b\w/g, l => l.toUpperCase())).join(', ') : ''}}
</div>
</div>
<div class="row" v-show="response.data.biomarkers">
<div class="text col-sm-3">Markers
<a class="uniprot-link tooltipped tooltipped-e" aria-label="Proteins which can help in unique identification of the condensate organelle">
<span class="fa fa-info-circle"/>
</a>
</div>
<div class="col-sm-9">
<span v-html="getProteinLinks(response.data.biomarkers)"></span>
</div>
</div>
<div class="row">
<div class="text col-sm-3">No. of Proteins</div>
<div class="col-sm-9">
{{response.data.protein_count}}
</div>
</div>
</div>
</div>
</div>
<div v-show="response.data.experiments.length > 0">
<h4 class="round">Experiments</h4>
<div class="panel panel-default">
<table class="csi table table-hover table-responsive">
<thead>
<tr class="active">
<!-- <th>Exp. ID</th>-->
<th>Method</th>
<th>Phase Separated</th>
<th>pH value</th>
<th>Morphology</th>
<th>PubMed</th>
<th>Solute Concentration</th>
<th>Temperature</th>
<th>Salts</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in response.data.experiments" v-bind:key="index">
<!-- <td>{{item.exp_id}}</td>-->
<td class="text-nowrap">{{item.detection_method}}</td>
<td>{{item.is_phase_separated}}</td>
<td>{{item.ph_value}}</td>
<td>{{item.morphology}}</td>
<td>
<fetch-pub-med :link="item.publication_link">
<template slot-scope="{response, loading}">
<slot :response="response" :loading="loading">
<div v-if="loading"></div>
<div v-else>
<a :href="item.publication_link" class="uniprot-link tooltipped tooltipped-n tooltipped-multiline" :aria-label="getTitleAuthors(response.title, response.authors)" target="_blank">
PubMed
<i class="glyphicon glyphicon-link"></i>
</a>
</div>
</slot>
</template>
</fetch-pub-med>
</td>
<td v-html="tokenize(item.solute_concentrations, ';')">
</td>
<td>
{{item.temperature}}
</td>
<td>
<ul v-for="(item, index) in item.salts" v-bind:key="index">
<li v-for="(value, key, index) in item" v-bind:key="index">
{{key}} : {{value}}
</li>
</ul>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h4 class="round">Proteins</h4>
<llps-table id="protein-table" :data="response.data.proteins"
:map="response.data.protein_confidence_score" :is-experimental="response.data.is_experimental"
:pubmed="response.data.protein_pubmed_ids" :db-tags="response.data.protein_source_db_tags">
</llps-table>
<!-- {{response.data.experiments}}-->
<!--<div class="panel panel-default">-->
<!--<table class="csi table table-hover table-responsive">-->
<!--<thead>-->
<!--<tr class="active">-->
<!--<th>Name</th>-->
<!--<th>Species</th>-->
<!--<th>Uniprot</th>-->
<!--<th>Sequence</th>-->
<!--</tr>-->
<!--</thead>-->
<!--<tbody>-->
<!--<tr v-for="(item, index) in response.data.llps_ptms" v-bind:key="index">-->
<!--<td class="col-sm-6">{{item.name}}</td>-->
<!--<td>{{item.species_name}}</td>-->
<!--<td>{{item.uniprot_id}}</td>-->
<!--<td>-->
<!--<input type="text" :value="item.sequence">-->
<!--<button class="copy-button" :name="'item.uniprot_id'" :id="'item.uniprot_id'" :data-clipboard-text="item.sequence">Copy</button>-->
<!--</td>-->
<!--</tr>-->
<!--</tbody>-->
<!--</table>-->
<!--</div>-->
<!--<h4 class="round">Additional Information</h4>-->
<!--<div class="panel panel-default">-->
<!--<div class="panel-body">-->
<!--<div class="row">-->
<!--<div class="text col-sm-3">Proteins</div>-->
<!--<div class="col-sm-9">-->
<!--{{response.data.proteins}}-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
</slot>
</template>
</fetch-condensate>
</div>
</div>
<!-- /#wrapper -->
</template>
<script>
import fetchCondensate from '@/components/DDCODE/fetchCondensate.vue'
import llpsTable from '@/components/LlpsTable.vue'
import fetchPubMed from "@/components/DDCODE/fetchPubMed";
const _ = require('lodash')
require('./js/clipboard')
export default {
name: 'CondensateDetailPage',
components: {
fetchCondensate, llpsTable, fetchPubMed
},
props: ['condensateId'],
data() {
return {
condensate: this.$route.params.condensate ? this.$route.params.condensate : this.condensateId,
dbNames: require('./js/const').db
}
},
computed: {
},
methods: {
getProteinLinks(uniprots) {
if(uniprots)
return uniprots.map(a => `<a href='/protein/${a}' target='_blank'>${a}</a>`).join(', ')
else return ''
},
getDbNames(names) {
return _.map(names, i => this.dbNames[i]).join(', ')
},
getTitleAuthors(title, data) {
return `${title}\n\n${_.map(data, a => a.name).join(', ')}`
},
tokenize(input, token) {
return input.replaceAll(token, '<br/>')
},
getRating(data) {
const scoreMap = {'hungarian': 5, 'blue': 5, 'pink': 1, 'grey': 1}
const rating = _.max(_.map(data, i => scoreMap[i]));
const r = []
for (let i = 0; i < 5; i++) {
if (i < rating) {
r.push('fa fa-star checked')
} else {
r.push('fa fa-star')
}
}
return r;
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
@import url('~@/assets/bootstrap.css');
@import url('~@/assets/datatable.css');
@import url('~@/assets/tooltip.css');
.main {
/*margin-left: 200px;*/
margin-left: 20px;
}
h3 {
margin: 40px 0 0;
}
a {
color: #42b983;
}
#wrapper {
overflow-x: hidden;
}
.checked {
color: orange;
}
#sidebar-wrapper {
min-height: 100vh;
margin-left: -15rem;
-webkit-transition: margin .25s ease-out;
-moz-transition: margin .25s ease-out;
-o-transition: margin .25s ease-out;
transition: margin .25s ease-out;
position: absolute;
z-index: 1; /* Stay on top */
left: 0;
}
#sidebar-wrapper .sidebar-heading {
padding: 0.875rem 1.25rem;
font-size: 1.2rem;
}
#sidebar-wrapper .list-group {
position: -webkit-sticky;
position: sticky;
top: 0;
width: 15rem;
}
#page-content-wrapper {
min-width: 100vw;
}
#wrapper.toggled #sidebar-wrapper {
margin-left: 0;
}
@media (min-width: 768px) {
#sidebar-wrapper {
margin-left: 0;
}
#page-content-wrapper {
min-width: 0;
width: 100%;
}
#wrapper.toggled #sidebar-wrapper {
margin-left: -15rem;
}
}
.d-flex {
display: -ms-flexbox !important;
display: flex !important;
}
.panel {
font-size: 1.2rem;
}
.table-dark {
color: #fff;
background-color: #212529;
}
</style>