Skip to content
Snippets Groups Projects
LandingPage.vue 9.87 KiB
<template>
  <div
    id="page-content-wrapper"
    class="main"
  >
    <h2>
      Dresden Condensate Database and Encyclopedia
      {{ 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="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"
                >
                  <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>
      </div>
      <div class="form-group">
        <label
          class="control-label col-sm-2"
          for="keyword"
        >Search</label>
        <div class="col-sm-4">
          <vue-simple-suggest
            v-model="selected"
            :list="getSuggestionList"
          >
            <!-- 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"
            >
          </vue-simple-suggest>
        </div>
      </div>
      <div class="form-group">
        <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>
          <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>
            <button
              class="
                text-white
                bg-blue-600
                hover:bg-blue-700
                focus:ring-2 focus:ring-blue-300
                rounded-lg
                inline-flex
                items-center
                px-5
                py-3
                text-center
                font-bold
                text-2xl
                mt-2
              "
              type="submit"
              @click="searchWithKeyword"
            >
              Search
            </button>
          </div>
        </div>
      </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...
          </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>
  </div>
</template>

<script>
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';

const _ = require('lodash');
const apikey = require('./js/const').apikey;

export default {
  name: 'LandingPage',
  components: {
    Search,
    FetchSpecies,
    DataTable,
    VueSimpleSuggest,
  },
  props: {
    msg: String,
  },
  data() {
    return {
      selected: '',
      keyword: '',
      species: 'All',
      speciesOption: '',
      speciesOptions: undefined,
      searchKeyword: '',
      pick: 'protein',
      searchPick: '',
      placeholder: 'Enter Uniprot ID, gene name, or protein name',
      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
        );
        this.$store.dispatch('Param/removeProtein', idx);
        obj.deleteTag();
        // console.log(this.$store.getters['Param/proteinList'])
      },
    },
  },
  watch: {
    selected: {
      handler: function (key) {
        this.keyword = key;
      },
      deep: true,
    },
    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';
        }
      },
    }
  },
  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)
  },
  methods: {
    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;
    },
    getSuggestionList() {
      const vm = this;

      const query = vm.keyword;

      let host = vm.isDev
        ? require('./js/const').devHost
        : require('./js/const').host;
      const taxId =
        vm.species === 'All' ? 'all' : /\((\d+)\)$/gm.exec(vm.species)[1];
      let url =
        vm.species === 'All'
          ? `${host}/${vm.pick}s?query=${query}&size=10000`
          : `${host}/${vm.pick}s?query=${query}&species_tax_id=${taxId}&size=10000`;

      // console.log(process.env.VUE_APP_TITLE)
      // console.log(process.env.VUE_APP_API_KEY)

      return fetch(url, {
        method: 'GET',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
          Authorization: `Bearer ${apikey}`,
        },
      })
        .then((response) => response.json())
        .then((json) => _.uniq(_.map(json.data, (c) => c.gene_name || c.name)));
    },
    searchWithKeyword() {
      const vm = this;

      // console.log(/\((\d+)\)$/gm.exec(vm.species))
      // console.log(vm.species);
      const taxId =
        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}`)
      vm.searchKeyword = vm.keyword;
      // 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;
      }

      // console.log(vm.pick)

      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 -->
<style>
@import url("~@/assets/bootstrap.css");
@import url("~@/assets/datatable.css");
@import url("~@/assets/vue-simple-suggest-styles.css");

.main {
  margin: 1.5rem;
}

h3 {
  margin: 40px 0 0;
}

a {
  color: #42b983;
}

input[type="radio"] {
  margin: 2px;
}

.radio-label {
  margin-left: 0px;
  margin-right: 5px;
}
</style>