<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-protein :protein="protein"> <template slot-scope="{ response, loading }"> <slot :response="response" :loading="loading"> <div v-if="loading">Loading...</div> <div v-else-if="response !== null"> <h2>{{ response.data.gene_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">Name</div> <div class="col-sm-9"> <b>Protein {{ response.data.name }}</b> </div> </div> <div class="row"> <div class="text col-sm-3">Species</div> <div class="col-sm-9"> {{ response.data.species_name + " (" + response.data.species_tax_id + ")" }} </div> </div> <div class="row"> <div class="text col-sm-3">Ensembl ID</div> <div class="col-sm-9"> <div v-if="response.data.ensembl_id"> <a :href=" 'https://www.ensembl.org/id/' + response.data.ensembl_id " class="uniprot-link" target="_blank" > {{ response.data.ensembl_id }} <i class="glyphicon glyphicon-link"></i ></a> </div> </div> </div> <div class="row"> <div class="text col-sm-3">Ensembl Gene ID</div> <div class="col-sm-9"> <div v-if="response.data.ensembl_gene_id"> <a :href=" 'https://www.ensembl.org/id/' + response.data.ensembl_gene_id " class="uniprot-link" target="_blank" > {{ response.data.ensembl_gene_id }} <i class="glyphicon glyphicon-link"></i ></a> </div> </div> </div> <div class="row"> <div class="text col-sm-3">UniProt</div> <div class="col-sm-9"> <div v-if="response.data.uniprot_id"> <a :href=" 'https://www.uniprot.org/uniprot/' + response.data.uniprot_id " class="uniprot-link" target="_blank" > {{ response.data.uniprot_id + " (" + response.data.uniprot_readable_id + ")" }} <i class="glyphicon glyphicon-link"></i ></a> </div> </div> </div> <div class="row"> <div class="text col-sm-3">Antibodies</div> <div class="col-sm-9"> <div v-if="response.data.uniprot_id"> <a :href="response.data.antibody_link" class="uniprot-link" target="_blank" > {{ response.data.uniprot_id }} <i class="glyphicon glyphicon-link"></i ></a> </div> </div> </div> <div class="row"> <div class="text col-sm-3"> Functional Type <a class="uniprot-link tooltipped tooltipped-e tooltipped-multiline" aria-label="- Driver: A protein that undergoes phase separation or self assembles to form liquid droplets independent of other proteins, induces the formation of a condensate, or is essential for the integrity of a condensate. This protein is known to be a driver in at least one of the known condensates. - Client: A protein that is part of a condensate, but is driven to the condensate by a driver protein. This protein is known to be a client in at least one of the known condensates, but never known to be a driver. - Regulator: A protein that biochemically or enzymatically regulates the formation of a condensate, but is not a part of the condensate. This protein is never known to be a driver or client. " > <span class="fa fa-info-circle" /> </a> </div> <div class="col-sm-9"> {{ response.data.functional_type }} <button v-if=" getUserData !== null && (getUserData === 'Maintainer' || getUserData === 'Contributor') " class="btn btn-primary btn-link" @click=" showUpdateFunctionType = !showUpdateFunctionType " > <font-awesome-icon icon="fa-solid fa-pen-to-square fa-xl" /> </button> <update-functional-type v-if="showUpdateFunctionType" :type="response.data.functional_type" :data="response.data" @close="closeUpdateFunctionalType" /> </div> </div> <div class="row"> <div class="text col-sm-3">Primary Datasource</div> <div class="col-sm-9"> {{ response.data.source_db_tags.join(", ") }} </div> </div> <div class="row" v-if="response.data.pubmed_ids"> <div class="text col-sm-3">Pubmed</div> <div class="col-sm-6"> <div> <span v-for="(item, index) in getPubMedIds( response.data.pubmed_ids )" v-bind:key="index" > <a :id="item" :href="'https://pubmed.ncbi.nlm.nih.gov/' + item" class="uniprot-link tooltipped tooltipped-n tooltipped-multiline" @mouseover="fetchPubMedId(item)" target="_blank" > {{ item }} <i class="glyphicon glyphicon-link"></i> </a> </span> <button v-if=" getUserData !== null && (getUserData === 'Maintainer' || getUserData === 'Contributor') " class="btn btn-primary btn-link" @click=" showAddOrDeletePubmedId = !showAddOrDeletePubmedId " > <font-awesome-icon icon="fa-solid fa-pen-to-square fa-xl" /> </button> <add-delete-pubmed v-if="showAddOrDeletePubmedId" :data="response.data" mode="protein" @cancel="cancelAddOrDeletePubmedId" /> </div> <div id="more" v-bind:class="{ active: response.data.pubmed_ids.length <= 7, }" > <span v-for="(item, index) in getMorePubIds( response.data.pubmed_ids )" v-bind:key="index" > <a :id="item" :href="'https://pubmed.ncbi.nlm.nih.gov/' + item" class="uniprot-link tooltipped tooltipped-n tooltipped-multiline" @mouseover="fetchPubMedId(item)" target="_blank" > {{ item }} <i class="glyphicon glyphicon-link"></i> </a> <br v-if="index % 7 === 6" /> </span> </div> </div> <div class="col-sm-2" v-show="response.data.pubmed_ids.length > 7" > <a class="uniprot-link" v-on:click="showMore('#more', 'pub', response.length)" v-show="!shownMore.pub" ><i class="fa fa-angle-double-down" aria-hidden="true" style="color: royalblue" ></i> Show more</a > <a class="uniprot-link" v-on:click="showLess('#more', 'pub')" v-show="shownMore.pub" ><i class="fa fa-angle-double-up" aria-hidden="true" style="color: royalblue" ></i> Show less</a > </div> </div> <!--<div class="row">--> <!--<div class="text col-sm-3">Evidence Stars</div>--> <!--<div class="col-sm-9">--> <!--<span v-for="(item, index) in getRating(response.data.condensates)" :class="item" v-bind:key="index"/>--> <!--</div>--> <!--</div>--> <div class="row"> <div class="text col-sm-3">Sequence</div> <div class="col-sm-9"> <input type="text" :value="response.data.sequence" /> <button class="copy-button" :name="'sequence'" :id="'sequence'" :data-clipboard-text="response.data.sequence" > <i class="glyphicon glyphicon-copy"></i> </button> </div> </div> </div> </div> </div> <div v-if="response.data.iupred_score !== null"> <iu-pred2-chart :x="response.data.sequence" :score="response.data.iupred_score" ></iu-pred2-chart> </div> <barcode-plot :x="response.data.sequence"></barcode-plot> <div v-show=" response.data.llps_ptms !== null && response.data.llps_ptms.length > 0 " > <h4 class="round">PTMs affecting condensate formation</h4> <div class="panel panel-default"> <table class="csi table table-hover table-responsive"> <thead> <tr class="active"> <th>Name</th> <th>Type</th> <th>Enzyme</th> <th>Position</th> <th>Description</th> </tr> </thead> <tbody> <tr v-for="(item, index) in response.data.llps_ptms" v-bind:key="index" > <td>{{ item.name }}</td> <td>{{ item.effect_type }}</td> <td class="text-nowrap">{{ item.enzyme }}</td> <td>{{ item.position }}</td> <td>{{ item.effect_description }}</td> </tr> </tbody> </table> </div> </div> <div v-show=" response.data.condensates !== null && response.data.condensates.length > 0 " > <h4 class="round">Condensates</h4> <div class="panel panel-default"> <table class="csi table table-hover table-responsive"> <thead> <tr class="active"> <th>Name</th> <!--<th>Data Sources</th>--> <th>No. of Proteins</th> <!--<th>Evidence Stars</th>--> <th>Species</th> </tr> </thead> <tbody> <tr v-for="(item, index) in response.data.condensates" v-bind:key="index" > <td> <a :href="'/condensate/' + item.canonical_id" class="uniprot-link" target="_blank" >{{ item.name }}</a > </td> <!--<td>{{getDbNames(item.data_sources)}}</td>--> <td>{{ item.protein_count }}</td> <!--<td>--> <!--<span v-for="(item, index) in getSingleRating(item.data_sources)" :class="item" v-bind:key="index"/>--> <!--</td>--> <td>{{ item.species_name }}</td> </tr> </tbody> </table> </div> </div> </div> </slot> </template> </fetch-protein> </div> </div> <!-- /#wrapper --> </template> <script> import fetchProtein from "@/components/DDCODE/fetchProtein.vue"; import IuPred2Chart from "@/components/IUPred2Chart"; import BarcodePlot from "@/components/BarcodePlot"; import UpdateFunctionalType from "./CMS/updateFunctionalType.vue"; import AddDeletePubmed from "./CMS/addDeletePubmed.vue"; const $ = (window.jQuery = require("jquery")); const _ = require("lodash"); require("./js/clipboard"); export default { name: "LandingPage", components: { fetchProtein, IuPred2Chart, BarcodePlot, UpdateFunctionalType, AddDeletePubmed, }, props: ["proteinId"], data() { return { showUpdateFunctionType: false, showAddOrDeletePubmedId: false, shownMore: { pub: false, }, protein: this.$route.params.protein ? this.$route.params.protein : this.proteinId, dbNames: require("./js/const").db, }; }, computed: { getUserData() { const userRole = this.$store.getters["User/userRole"]; console.log("role is", userRole); return userRole; }, }, methods: { closeUpdateFunctionalType() { this.showUpdateFunctionType = false; }, cancelAddOrDeletePubmedId() { this.showAddOrDeletePubmedId = false; }, getPubMedIds(ids) { let outIds = []; ids.forEach((i, idx) => { outIds.push(`${i}`); }); return outIds.slice(0, 7); }, getMorePubIds(ids) { let outIds = []; ids.forEach((i) => { outIds.push(`${i}`); }); return outIds.slice(7); }, showLess(id, clazz) { let $rows = $(id); $rows.removeClass("active"); this.shownMore[clazz] = false; }, showMore(id, clazz) { let $rows = $(id); $rows.addClass("active"); this.shownMore[clazz] = true; }, getDbNames(names) { return _.map(names, (i) => this.dbNames[i]).join(", "); }, getTitleAuthors(title, data) { return `${title}\n\n${_.map(data, (a) => a.name).join(", ")}`; }, fetchPubMedId(item) { const vm = this; // console.log(item) const url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&retmode=json&id="; const request = url + item; let $row = $("#" + item); if (!$row.attr("aria-label")) { fetch(request) .then((response) => response.json()) .then((response) => { setTimeout(() => { const res = response.result[item]; $row.attr( "aria-label", vm.getTitleAuthors(res.title, res.authors) ); }, 0); }); } }, getRating(data) { const scoreMap = { hungarian: 5, blue: 5, pink: 1, grey: 1 }; let r = []; _.each(data, (c) => { r.push(_.max(_.map(c.data_sources, (i) => scoreMap[i]))); }); const rating = _.max(r); 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; }, getSingleRating(data) { const scoreMap = { hungarian: 5, blue: 5, pink: 1, grey: 1 }; const rating = _.max(_.map(data, (i) => scoreMap[i])); let 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; } .shape { border-radius: 50%; } h3 { margin: 40px 0 0; } a { color: #42b983; } #wrapper { overflow-x: hidden; } #sidebar-wrapper { min-height: 100vh; margin-left: -15rem; -webkit-transition: margin 0.25s ease-out; -moz-transition: margin 0.25s ease-out; -o-transition: margin 0.25s ease-out; transition: margin 0.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; } } .uniprot-link { font-weight: bold; color: #0065b9; } .checked { color: orange; } .d-flex { display: -ms-flexbox !important; display: flex !important; } .panel { font-size: 1.2rem; } #more { display: none; } #more.active { display: table-row; } </style>