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