From 1b3a95c69d5d1ad3b92d1830f611638d94fc7a2e Mon Sep 17 00:00:00 2001 From: Remi PLANEL <rplanel@pasteur.fr> Date: Wed, 20 Dec 2023 15:09:17 +0100 Subject: [PATCH] WIP: download data --- components/ServerDbTable.vue | 18 +++++++++++++++--- components/content/RefseqDb.vue | 8 +++----- composables/useCsvDownload.ts | 26 ++++++++++++-------------- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/components/ServerDbTable.vue b/components/ServerDbTable.vue index 48505838..cb80b6d8 100644 --- a/components/ServerDbTable.vue +++ b/components/ServerDbTable.vue @@ -51,7 +51,7 @@ const msFilter: Ref<string | undefined> = ref(undefined) const page = ref(1) let loading = ref(false) const expanded = ref([]) -const { height } = useDisplay(); +const { height, mobile } = useDisplay(); const minTableHeight = ref(400) const computedTableHeight = computed(() => { const computedHeight = height.value - 350 @@ -314,6 +314,7 @@ function clearSearch() { search.value = "" } +const { pending: pendingDownloadData, downloadCsv } = useCsvDownload(props.db) @@ -331,11 +332,11 @@ function clearSearch() { </v-card-text> <v-card-text> <v-row> - <v-col cols="5"> + <v-col :cols="mobile ? 12 : 5"> <v-text-field v-model="search" label="Search..." hide-details prepend-inner-icon="mdi-magnify" single-line clearable></v-text-field> </v-col> - <v-col> + <v-col :cols="mobile ? 12 : 6"> <v-autocomplete ref="autocompleteInput" hide-details v-model:model-value="filterOrSearch" auto-select-first chips clearable label="Filter results..." :items="autocompleteItems" single-line item-value="value" item-title="title" multiple return-object prepend-inner-icon="md:search" @@ -353,9 +354,17 @@ function clearSearch() { </template> </v-autocomplete> </v-col> + <v-col :cols="mobile ? 'auto' : 1"> + <v-badge :content="totalHits" color="primary"> + <v-btn icon="md:download" + @click="downloadCsv(props.db, toValue(search), { ...notPaginatedParams.value, filter: toValue(computedFilter), sort: msSortBy.value })"> + </v-btn> + </v-badge> + </v-col> </v-row> <v-row v-if="props.db === 'structure'"> <v-col> + <v-range-slider v-model="plddtRange" density="compact" hide-details="auto" label="pLDDT" step="0.1" @update:modelValue="throttleSearch()"> <template v-slot:prepend> @@ -371,11 +380,14 @@ function clearSearch() { </v-col> </v-row> </v-card-text> + <v-toolbar flat color="transparent"> </v-toolbar> <v-data-table-server v-if="!msError" v-model:page="page" color="primary" v-bind="dataTableServerProps" v-model:items-per-page="hitsPerPage" v-model:sortBy="sortByRef" v-model:expanded="expanded" fixed-header :loading="loading" :items="msResult?.hits ?? []" :items-length="totalHits" density="compact" :items-per-page-options="itemsPerPage" :height="computedTableHeight" class="elevation-1 mt-2"> + + <template v-for="(slot, index) of Object.keys(slots)" :key="index" v-slot:[slot]="data"> <slot :name="slot" v-bind="data"></slot> </template> diff --git a/components/content/RefseqDb.vue b/components/content/RefseqDb.vue index ee4e713b..fc3fa610 100644 --- a/components/content/RefseqDb.vue +++ b/components/content/RefseqDb.vue @@ -11,6 +11,8 @@ const itemValue = ref("id"); const { width } = useDisplay(); const scaleTransform: Ref<string[]> = ref([]) + + const facets = ref([ "replicon", "type", @@ -80,10 +82,7 @@ onMounted(async () => { async function getAllHits(params) { if (params.index === 'refseq') { - console.log(params.index) const { data, error } = await useAsyncMeiliSearch(params) - console.log(error.value) - console.log(data.value) allHits.value = data.value } } @@ -281,12 +280,11 @@ const scaleType = ref("linear") </v-expansion-panels> <ServerDbTable title="RefSeq" db="refseq" :sortBy="sortBy" :facets="facets" - :data-table-server-props="dataTableServerProps" @refresh:search="getAllHits"> + :data-table-server-props="dataTableServerProps"> <template #top> <v-toolbar><v-toolbar-title class="text-capitalize"> RefSeq </v-toolbar-title><v-spacer></v-spacer> - </v-toolbar> </template> <template #[`item.accession_in_sys`]="{ item }"> diff --git a/composables/useCsvDownload.ts b/composables/useCsvDownload.ts index 9534544a..88589b8f 100644 --- a/composables/useCsvDownload.ts +++ b/composables/useCsvDownload.ts @@ -2,31 +2,29 @@ import { ref } from 'vue'; import Papa from 'papaparse'; import { saveAs } from "file-saver"; -export function useCsvDownload(index: MaybeRef<string>, baseName: MaybeRef<string> = "df" +export function useCsvDownload(baseName: MaybeRef<string> = "df" ) { const pending = ref(false) - const { search: msSearch, result: msResult } = useMeiliSearch(toValue(index)) + + // const { search: msSearch, result: msResult } = useMeiliSearch(toValue(index)) const filename = ref(`${toValue(baseName)}-data.csv`) const downloadCsv = async ( - + index: MaybeRef<string>, query: MaybeRef<string>, - filter: MaybeRef<string>, - sortBy: MaybeRef<string[]>, params: MaybeRef<Record<string, any>>, ) => { - filename.value = `${toValue(baseName)}-${toValue(filter)}.csv` + filename.value = `${toValue(baseName)}-${toValue(params).filter}.csv` pending.value = true try { - await msSearch( - toValue(query), - { - ...toValue(params), - filter: toValue(filter), - sort: toValue(sortBy) - }) - const csvContent = Papa.unparse(toValue(msResult).hits); + const { data, error } = await useAsyncMeiliSearch({ + index: toValue(index), + params: toValue(params), + query: toValue(query) + }) + + const csvContent = Papa.unparse(toValue(data).hits); // console.log(csvContent) const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); saveAs(blob, `${toValue(filename)}`); -- GitLab