diff --git a/components/content/ArticleStructure.vue b/components/content/ArticleStructure.vue index bbbae0e6c8b549b6462b951f382263603f0f58ae..bd3192a5e73cc11f97f469d8d8216be82b2f8bd4 100644 --- a/components/content/ArticleStructure.vue +++ b/components/content/ArticleStructure.vue @@ -5,6 +5,7 @@ import MolstarPdbePlugin from './MolstarPdbePlugin.vue'; const { page } = useContent(); // get the structures +const structures = ref() const msIndexName = ref<string>("structure") const stuctureUrls = ref<string[] | undefined>(undefined) const headers = ref<Record<string, any>[]>([ @@ -29,6 +30,14 @@ const groupBy = ref([ ]) + +onBeforeMount(() => { + fetchStructures() +}) +onMounted(() => { + fetchStructures() +}) + function namesToCollapsibleChips(names: string[], systemDir: string, file: string | null = null) { if (file === null) { return names.filter((it) => it !== "").map(it => ({ title: it.split("__")[1] })) @@ -41,26 +50,41 @@ function pdbNameToCif(pdbPath: string) { return `${cifPath}.cif` } function displayStructure(item) { - stuctureUrls.value = [`/${item.System_name_ok}/${pdbNameToCif(item.pdb)}`, `/${item.System_name_ok}/${item.pdb}`] + stuctureUrls.value = item.structuresUrls + } +const sanitizedStructures = computed(() => { + const toValStructures = toValue(structures) + if (toValStructures?.hits?.length > 0) { -// ================================================================================== -// ASYNC PART -const { data: structures, error, refresh } = await useAsyncMeiliSearch({ - index: toValue(msIndexName), - query: "", - params: { - facets: ["*"], - filter: [`System='${toValue(page).title}'`, "completed='true'"], + return toValStructures.hits.map(item => { + return { ...item, structuresUrls: [`/${item.System_name_ok}/${pdbNameToCif(item.pdb)}`, `/${item.System_name_ok}/${item.pdb}`] } + }) } + return [] + }) -if (error.value) { - throw createError(`Cannot get structure for system: ${page.title}`) -} +// ================================================================================== +// ASYNC PART + +async function fetchStructures() { + const { data, error, refresh } = await useAsyncMeiliSearch({ + index: toValue(msIndexName), + query: "", + params: { + facets: ["*"], + filter: [`System='${toValue(page).title}'`, "completed='true'"], + } + }) + structures.value = data.value + if (error.value) { + throw createError(`Cannot get structure for system: ${page.title}`) + } +} // watch(page() => { @@ -68,10 +92,12 @@ if (error.value) { // refresh() // }) console.log(structures) + + </script> <template> <v-card flat> - <v-data-table :headers="headers" :items="structures.hits" :group-by="groupBy"> + <v-data-table :headers="headers" :items="sanitizedStructures" :group-by="groupBy"> <template #[`item.proteins_in_the_prediction`]="{ item }"> <CollapsibleChips :items="namesToCollapsibleChips(item.proteins_in_the_prediction, item.System_name_ok, item.fasta_file)"> @@ -92,8 +118,25 @@ console.log(structures) </tr> </template> <template #[`item.structure`]="{ item }"> - <v-row no-gutters align="center"> - <v-btn v-if="item?.pdb && item.pdb !== 'na'" @click="displayStructure(item)">view</v-btn> + <v-row justify="space-between" dense no-gutters align="center"> + <v-col> + <v-btn size="x-small" variant="text" icon="md:visibility" + @click="displayStructure(item)"></v-btn> + </v-col> + <v-col> + <v-menu> + <template v-slot:activator="{ props }"> + <v-btn :disabled="item.structuresUrls?.length < 1" size="x-small" variant="text" + icon="md:download" class="ml-1" v-bind="props"></v-btn> + </template> + <v-list> + <v-list-item v-for="(url, index) in item.structuresUrls" :key="index" :value="index" + :href="url"> + <v-list-item-title>{{ url.split('.').slice(-1)[0] }}</v-list-item-title> + </v-list-item> + </v-list> + </v-menu> + </v-col> </v-row> </template> </v-data-table>