Skip to content
Snippets Groups Projects
LandingPage.vue 12.2 KiB
Newer Older
<template>
moon's avatar
moon committed
  <div
    id="page-content-wrapper"
    class="flex flex-wrap justify-center"
moon's avatar
moon committed
  >
moon's avatar
moon committed
    <div class="w-5/6">
      <h2>
        Dresden Condensate Database and  Encyclopedia
moon's avatar
moon committed
        {{ isDev ? "(Dev version)" : "" }}
      </h2>
      <p>
        <b>
          DD-CODE is a comprehensive, manually curated database of biomolecular
          condensates and an encyclopedia of the scientific terms used to describe
          and characterize those condensates.
        </b>
        <br>
        <br>
      </p>
      <form
        class="form-horizontal"
        autocomplete="off"
        onSubmit="return false;"
      >
        <div class="row mb-2">
          <label class="control-label col-sm-2" />
          <div class="col-sm-4 input-sm">
            <input
              id="protein"
              v-model="pick"
              class="radio-inline"
              type="radio"
              value="protein"
            >
            <label
              class="radio-label"
              for="protein"
            >Protein</label>
            <input
              id="condensate"
              v-model="pick"
              class="radio-inline"
              type="radio"
              value="condensate"
            >
            <label
              class="radio-label"
              for="condensate"
            >Condensate</label>
          </div>
        <div class="form-group">
          <label
            class="control-label col-sm-2"
            for="species"
          >Species</label>
          <div class="col-sm-4">
            <fetch-species>
              <template slot-scope="{ response, loading }">
                <div v-if="loading">
                  Loading...
                </div>
                <div v-else>
                  <select
                    id="species"
                    v-model="species"
                    class="form-control input-sm"
moon's avatar
moon committed
                  >
                    <option
                      v-for="item in removeNullItems(response.data)"
                      :key="item.tax_id"
                    >
                      {{
                        item._id && item._id !== 0
                          ? `${item._id} (${item.tax_id})`
                          : "All"
                      }}
                    </option>
                  </select>
                </div>
              </template>
            </fetch-species>
          </div>
moon's avatar
moon committed
        </div>
        <div class="row">
          <label
            class="control-label col-sm-2"
            for="keyword"
          >Search</label>
          <div class="col-sm-4">
            <vue-simple-suggest
              v-model="selected"
              :list="getSuggestionList"
              display-attribute="name"
              @select="onSelect"
moon's avatar
moon committed
            >
              <!-- Filter by input text to only show the matching results -->
              <input
                id="keyword"
                v-model="keyword"
                class="form-control input-sm"
                type="text"
                :placeholder="placeholder"
              >
              <div
                slot="suggestion-item"
                slot-scope="{ suggestion : suggestionItem }"
                <span v-if="suggestionItem.type === 'protein'">{{ suggestionItem.gene_name }} ({{ suggestionItem.id }}): {{ suggestionItem.species_name }}</span>
                <span v-else-if="suggestionItem.type === 'condensate'">{{ suggestionItem.id }}: {{ suggestionItem.species_name }}</span>
                <span v-else-if="suggestionItem.type === 'search'">Search for <b>{{ suggestionItem.id.replace(/\#/g, '') }}</b></span>
              </div>
            </vue-simple-suggest>
          </div>
          <div class="col-sm-3">
            <button
              class="
                text-white
                bg-blue-600
                hover:bg-blue-700
                focus:ring-2 focus:ring-blue-300
              type="submit"
              @click="searchWithKeyword"
            >
              Search
            </button>
          </div>
moon's avatar
moon committed
        </div>
        <div class="form-group">
          <label class="col-sm-2" />
          <div class="col-sm-4 input-sm">
            <span style="float: right">
              Examples:
              <router-link to="/protein_example">UNE6</router-link>,&nbsp;&nbsp;
              <router-link to="/condensate_example">nucleolus__3702</router-link>
            </span>
          </div>
      </form>
      <!--<div>{{require('lodash').map(this.$store.getters['Param/proteinList'], d => d.proteinName)}}</div>-->
      <!--<tags-input v-model="proteinNameList"/>-->
      <!--<div>-->
      <!--<router-link to="/endo2" tag="button">Overview</router-link>-->
      <!--<router-link to="/pheno_profile" tag="button">Phenotype Profiles</router-link>-->
      <!--</div>-->
      <div class="mt-20">
        <Search ref="search">
          <template slot-scope="{ response, loading }">
            <div v-if="loading">
              Loading...
moon's avatar
moon committed
            </div>
            <div v-else-if="response">
              <div v-show="response.count === 0">
                No results!
              </div>
              <data-table
                v-show="response.count > 0"
                id="dataTable"
                :category="searchPick"
                :data="response.data"
                :keyword="keyword"
              />
            </div>
          </template>
        </Search>
      </div>
moon's avatar
moon committed
  </div>
</template>

<script>
moon's avatar
moon committed
import Search from '@/components/Search.vue';
import DataTable from '@/components/DataTable.vue';
import FetchSpecies from '@/components/DDCODE/fetchSpecies.vue';
import VueSimpleSuggest from 'vue-simple-suggest';
moon's avatar
moon committed
const _ = require('lodash');
const apikey = require('./js/const').apikey;
moon's avatar
moon committed
  name: 'LandingPage',
  components: {
    Search,
    FetchSpecies,
    DataTable,
    VueSimpleSuggest,
  },
  props: {
    msg: String,
  },
  data() {
    return {
moon's avatar
moon committed
      selected: '',
      keyword: '',
      speciesOption: '',
      speciesOptions: undefined,
moon's avatar
moon committed
      searchKeyword: '',
      pick: 'protein',
      searchPick: '',
      placeholder: 'Enter Uniprot ID, gene name, or protein name',
moon's avatar
moon committed
      isDev: process.env.NODE_ENV === 'development',
    };
  },
  computed: {
    proteinNameList: {
      get() {
        return _.map(this.proteinList, (d) => {
          return { text: d.proteinName };
        });
      },
      set(obj) {
        const idx = this.proteinList.findIndex(
          (d) => d.proteinName === obj.tag.text
        );
moon's avatar
moon committed
        this.$store.dispatch('Param/removeProtein', idx);
        obj.deleteTag();
        // console.log(this.$store.getters['Param/proteinList'])
  },
  watch: {
    selected: {
      handler: function (key) {
        this.keyword = key;
        // console.log(key);
        // this.searchWithKeyword();
    pick: {
      handler: function (val) {
        if(val === 'protein') {
          this.placeholder = 'Enter Uniprot ID, gene name, or protein name';
        } else if(val === 'condensate') {
          this.placeholder = 'Enter condensate name';
        }
      },
    },
    suggestion: {
      handler: function (val) {
        console.log(val);
        // this.searchWithKeyword();
      },
    },
  mounted() {
    // console.log(this.keyword)
    // console.log(this.$route)
    // console.log(this.$route.query)
    // console.log(this.$route.query.q)
    this.search(this.$route.query.q, this.$route.query.t, this.$route.query.s)
  },
      if (item.type === 'protein') {
        this.keyword = '(' + item.id + ')';
moon's avatar
moon committed
      } else if (item.type === 'search') {
        this.keyword = item.id.replace(/\#/g, '');
    removeNullItems(data) {
      const vm = this

      if(!vm.speciesOptions) {
        const options = _.filter(data, (d) => d._id !== null);

        if(vm.speciesOption) {
          options.forEach(item => {
            if (item.tax_id === vm.speciesOption) {
              vm.species = item._id && item._id !== 0
                  ? `${item._id} (${item.tax_id})`
                  : 'All';
            }
          })
        }

        vm.speciesOptions = options
      }

      return vm.speciesOptions;
moon's avatar
moon committed
        ? require('./js/const').devHost
        : require('./js/const').host;
moon's avatar
moon committed
        vm.species === 'All' ? 'all' : /\((\d+)\)$/gm.exec(vm.species)[1];
moon's avatar
moon committed
        vm.species === 'All'
          ? `${host}/${vm.pick}s?fields=gene_name,name,uniprot_id,species_name&query=${query}&size=20000`
          : `${host}/${vm.pick}s?fields=gene_name,name,uniprot_id,species_name&query=${query}&species_tax_id=${taxId}&size=10000`;
      // console.log(process.env.VUE_APP_TITLE)
      // console.log(process.env.VUE_APP_API_KEY)
moon's avatar
moon committed
        method: 'GET',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
          Authorization: `Bearer ${apikey}`,
        },
      })
        .then((response) => response.json())
moon's avatar
moon committed
          // console.log(json.data);
          const ret = _.uniqBy(_.map(json.data, (c) => {
              // console.log(c)
              return {id: c.uniprot_id, species_name: c.species_name, gene_name: c.gene_name, name: c.name, type: 'protein'}
              return {id: c.name, species_name: c.species_name, type: 'condensate'}
moon's avatar
moon committed
          if (ret.length > 9) {
            ret.splice(9, 0, {id: '#' + query, type: 'search'})
          } else {
            ret.push({id: '#' + query, type: 'search'})
          }

      // console.log(/\((\d+)\)$/gm.exec(vm.species))
      // console.log(vm.species);
      const taxId =
moon's avatar
moon committed
        vm.species === 'All'
          ? 'all'
          : vm.species === 'Chimeras'
          ? 'null'
          : /\((\d+)\)$/gm.exec(vm.species)[1];
      const page = 1;
      // console.log(`http://${host}/proteins?query=${vm.keyword}&species_tax_id=${taxId}&page=${page}`)
      // console.log(vm.pick)
      // vm.searchPick = vm.pick;

      vm.$router.replace({
        name: 'home',
        query: {
          q: vm.keyword,
          t: vm.pick,
          s: taxId,
        }})

      vm.$router.push({
        name: 'search',
        query: {
          q: vm.keyword,
          t: vm.pick,
          s: taxId,
        }})

      // vm.search(this.$route.query.q, this.$route.query.t, this.$route.query.s)
      // /* eslint-disable no-console */
      // console.log(this.searchKeyword)
    },
    search(q, t, s) {
      const vm = this;
      // const page = 1;
      // console.log(`http://${host}/proteins?query=${vm.keyword}&species_tax_id=${taxId}&page=${page}`)
      if(q) {
        vm.keyword = q;
        vm.searchKeyword = vm.keyword;
      }

      if(s) {
        vm.speciesOption = s;
      }

      if(t) {
        vm.searchPick = t;
        vm.pick = t;
      // if (t === 'protein') {
      //   vm.$refs.search.fetchProteinList(q, s);
      // } else if (t === 'condensate') {
      //   vm.$refs.search.fetchCondensateList(q, s);
      // }
      // /* eslint-disable no-console */
      // console.log(this.searchKeyword)
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
@import url("~@/assets/bootstrap.css");
@import url("~@/assets/datatable.css");
@import url("~@/assets/vue-simple-suggest-styles.css");
.radio-label {
  margin-left: 0px;
  margin-right: 5px;
}
</style>