Skip to content
Snippets Groups Projects
ProteinDetailPage.vue 22.49 KiB
<template>
  <div
    
    class="flex flex-wrap justify-center"
  >
    <!-- Sidebar -->
    <!--<div class="bg-light border-right" id="sidebar-wrapper">-->
    <!--&lt;!&ndash;<div class="sidebar-heading">Menu </div>&ndash;&gt;-->
    <!--<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
      
      class="w-5/6"
    >
      <!-- <base-toaster @close="hideDialog" :open="toasterIsOpen">
        <p>This is a test roaster</p>
        <button class="btn btn-outline" @click="hideDialog">Close</button>
        </base-toaster> -->
      
     
      <fetch-protein :protein="protein">
        <template slot-scope="{ response, loading }">
          <slot
            :response="response"
            :loading="loading"
          >
            <div v-if="loading">
              <base-spinner v-if="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" /></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" /></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" /></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" /></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"
                          @update-key="updatedKey += 1"
                          @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
                      v-if="response.data.pubmed_ids"
                      class="row"
                    >
                      <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
                            )"
                            :key="index"
                          >
                            <a
                              :id="item"
                              :href="'https://pubmed.ncbi.nlm.nih.gov/' + item"
                              class="
                                uniprot-link
                                tooltipped tooltipped-n tooltipped-multiline
                              "
                              target="_blank"
                              @mouseover="fetchPubMedId(item)"
                            >
                              {{ item }}
                              <i class="glyphicon glyphicon-link" />
                            </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"
                            @update-key="updatedKey += 1"
                            @cancel="cancelAddOrDeletePubmedId"
                          />
                        </div>
                        <div
                          id="more"
                          :class="{
                            active: response.data.pubmed_ids.length <= 7,
                          }"
                        >
                          <span
                            v-for="(item, index) in getMorePubIds(
                              response.data.pubmed_ids
                            )"
                            :key="index"
                          >
                            <a
                              :id="item"
                              :href="'https://pubmed.ncbi.nlm.nih.gov/' + item"
                              class="
                                uniprot-link
                                tooltipped tooltipped-n tooltipped-multiline
                              "
                              target="_blank"
                              @mouseover="fetchPubMedId(item)"
                            >
                              {{ item }}
                              <i class="glyphicon glyphicon-link" />
                            </a>
                            <br v-if="index % 7 === 6">
                          </span>
                        </div>
                      </div>
                      <div
                        v-show="response.data.pubmed_ids.length > 7"
                        class="col-sm-2"
                      >
                        <a
                          v-show="!shownMore.pub"
                          class="uniprot-link"
                          @click="showMore('#more', 'pub', response.length)"
                        ><i
                          class="fa fa-angle-double-down"
                          aria-hidden="true"
                          style="color: royalblue"
                        />
                          Show more</a>
                        <a
                          v-show="shownMore.pub"
                          class="uniprot-link"
                          @click="showLess('#more', 'pub')"
                        ><i
                          class="fa fa-angle-double-up"
                          aria-hidden="true"
                          style="color: royalblue"
                        />
                          Show less</a>
                      </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
                          :id="'sequence'"
                          class="copy-button"
                          :name="'sequence'"
                          :data-clipboard-text="response.data.sequence"
                        >
                          <i class="glyphicon glyphicon-copy" />
                        </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"
                />
              </div>
              <barcode-plot :x="response.data.sequence" />

              <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"
                        :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
                "
                class="my-14 border border-gray-300 rounded-lg p-8"
              >
                <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"
                        :key="index"
                      >
                        <td>
                          <a
                            :href="'/condensate/' + item.canonical_id"
                            class="uniprot-link"
                          >{{ 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
                v-if="getUserData"
                class="my-14 border border-gray-300 rounded-lg p-8"
              >
                <h4 class="round mb-8">
                  All submitted changes for this protein
                </h4>
                <protein-update-item-table
                  id="proteinUpdateTable"
                  :key="updatedKey"
                  :data="protein"
                />
              </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';
//import FetchUserSpecificUpdateItems from './CMS/fetchUserSpecificUpdateItems.vue';
import ProteinUpdateItemTable from './ProteinUpdateItemTable.vue';
import BaseSpinner from './UI/BaseSpinner.vue';
//import BaseToaster from "./UI/BaseToaster.vue";

const $ = (window.jQuery = require('jquery'));
const _ = require('lodash');
require('./js/clipboard');

export default {
  name: 'LandingPage',
  components: {
    fetchProtein,
    IuPred2Chart,
    BarcodePlot,
    UpdateFunctionalType,
    AddDeletePubmed,

    ProteinUpdateItemTable,
    BaseSpinner,
    
  },
  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,
      toasterIsOpen: false,
      updatedKey: 0,
    };
  },
  computed: {
    getUserData() {
      const userRole = this.$store.getters['User/userRole'];
      // console.log('role is', userRole);
      return userRole;
    },
  },
  methods: {
    showDialog() {
      this.toasterIsOpen = true;
    },
    hideDialog() {
      this.toasterIsOpen = false;
    },
    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);
          });
      }
    },
  },
};
</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");

/* Vue transition classes */
/* enter classes */

.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;

}


.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>