diff --git a/composables/useFetchMsDocument.ts b/composables/useFetchMsDocument.ts index 814b2976467845818440be14cfdcbdc85017968a..d5b981e18fb98a8422e93efcd89b25ad19ce0c72 100644 --- a/composables/useFetchMsDocument.ts +++ b/composables/useFetchMsDocument.ts @@ -8,7 +8,8 @@ export function useFetchMsDocument( limit: Ref<number> = ref(1000), hitsPerPage: Ref<number> = ref(25), page: Ref<number> = ref(1), - facets: Ref<string[]> = ref([]) + facets: Ref<string[]> = ref([]), + sort: Ref<string[]> = ref([]), ) { const runtimeConfig = useRuntimeConfig(); @@ -34,13 +35,16 @@ export function useFetchMsDocument( watchEffect(async () => { try { pending.value = true - const res = await client.index(toValue(index)).search(toValue(search), { - limit: toValue(limit), - filter: toValue(filter), - hitsPerPage: toValue(hitsPerPage), - page: toValue(page), - facets: toValue(facets) - }) + const res = await client + .index(toValue(index)) + .search(toValue(search), { + limit: toValue(limit), + filter: toValue(filter), + hitsPerPage: toValue(hitsPerPage), + page: toValue(page), + facets: toValue(facets), + sort: toValue(sort), + }) filterError.value = null const { hits: resHits, totalHits: resTotalHits, totalPages: resTotalPages, facetDistribution: facetD } = res totalHits.value = resTotalHits diff --git a/packages/df-wiki-cli/df_wiki_cli/meilisearch/__init__.py b/packages/df-wiki-cli/df_wiki_cli/meilisearch/__init__.py index e0a1b97a587247306800c272db5628341d08e189..c979cf9afd0c3b0ed2d7e55a144854809200fc1d 100644 --- a/packages/df-wiki-cli/df_wiki_cli/meilisearch/__init__.py +++ b/packages/df-wiki-cli/df_wiki_cli/meilisearch/__init__.py @@ -96,6 +96,18 @@ def update_refseq( "species", ] ) + index.update_sortable_attributes( + [ + "type", + "subtype", + "Superkingdom", + "phylum", + "order", + "family", + "genus", + "species", + ] + ) def update_structure( @@ -131,6 +143,13 @@ def update_structure( ] ) print(attr_task) + index.update_sortable_attributes( + [ + "system", + "completed", + "plddts", + ] + ) def split_on_comma(str_val: str) -> List[str]: diff --git a/pages/predicted-structure.vue b/pages/predicted-structure.vue index 3776e4bc144b1bfcdb34b24bd6cf8e374c2b25dd..3ca0f1420d474c8be66c12e22bd96ccb09b5e296 100644 --- a/pages/predicted-structure.vue +++ b/pages/predicted-structure.vue @@ -3,18 +3,41 @@ import { useRuntimeConfig, useFetch, type MaybeRefOrGetter, ref, computed, toVal import JsonCSV from 'vue-json-csv' import { useDisplay } from "vuetify"; +import { useFacetsStore, type Facets } from '~~/stores/facets' + + +const facetStore = useFacetsStore() const { height } = useDisplay(); const minTableHeight = ref(400) const computedTableHeight = computed(() => { - const computedHeight = height.value - 400 + const computedHeight = height.value - 500 return computedHeight > minTableHeight.value ? computedHeight : minTableHeight.value }) + +// SORTING +const sortBy: Ref<{ key: string, order: string }[]> = ref([{ key: 'system', order: "asc" }]) +const msSortBy = computed(() => { + if (sortBy.value.length > 0) { + return sortBy.value.map((curr) => { + if (curr?.key && curr?.order) { + return `${curr.key}:${curr.order}` + } + else { return "" } + }) + } else { return [""] } +}) + + + const itemValue = ref("id"); const search: Ref<string> = ref(""); -const filter: Ref<string | null> = ref(null) +const filter: Ref<string> = ref('') +const hitsPerPage: Ref<number> = ref(25) const limit: Ref<number> = ref(500000) +const facets = ref(["system"]) +const page = ref(1) const headers: Ref<Object[]> = ref([ { title: "System", key: "system" }, { title: "Completed", key: "completed" }, @@ -24,14 +47,18 @@ const headers: Ref<Object[]> = ref([ { title: "Type", key: "type" } ]) const { - hits, + hits: items, pending, - totalHits, - filterError + totalHits: itemsLength, + filterError, + facetDistribution } = useFetchMsDocument( - "structure", search, filter, limit) + "structure", search, filter, limit, hitsPerPage, page, facets, msSortBy) +watch(facetDistribution, (facetDistri) => { + facetStore.setFacets({ facetDistribution: facetDistri, facetStat: undefined }) +}) </script> @@ -39,12 +66,12 @@ const { <v-card flat> <v-toolbar color="primary" density="compact"> <v-app-bar-nav-icon></v-app-bar-nav-icon> - <v-toolbar-title>Predicted Structures summary ({{ totalHits }}) + <v-toolbar-title>Predicted Structures summary ({{ itemsLength }}) </v-toolbar-title> - <JsonCSV :data="hits" name="predicted-structures-summary-defense-system.csv"> + <JsonCSV :data="items" name="predicted-structures-summary-defense-system.csv"> <v-btn icon> <v-icon icon="md:download"></v-icon> - <v-tooltip activator="parent" location="bottom">Download {{ hits.length }} entries</v-tooltip> + <v-tooltip activator="parent" location="bottom">Download {{ itemsLength }} entries</v-tooltip> </v-btn> </JsonCSV> </v-toolbar> @@ -55,8 +82,9 @@ const { <v-col cols="auto"> <v-text-field v-model="filter" prepend-inner-icon="mdi-magnify" label="Filter" hide-details="auto" class="mx-2" clearable :error-messages="filterError"></v-text-field></v-col> - <v-data-table-virtual ref="datatable" fixed-header :loading="pending" :headers="headers" :items="hits" - :item-value="itemValue" density="compact" :height="computedTableHeight" class="elevation-1 mt-2"> + <v-data-table-server v-model:page="page" v-model:items-per-page="hitsPerPage" v-model:sortBy="sortBy" + ref="datatable" fixed-header :loading="pending" :headers="headers" :items="items" :item-value="itemValue" + :items-length="itemsLength" multi-sort density="compact" :height="computedTableHeight" class="elevation-1 mt-2"> <!-- <template v-if="refseqData?.length >= 10000" #top> <v-alert type="warning" variant="tonal" title="Results table" text="Results won't be displayed since there is over 10000 hits"></v-alert> @@ -66,6 +94,6 @@ const { <v-icon v-if="item.completed" color="success" icon="md:check"></v-icon> <v-icon v-else color="warning" icon="md:dangerous"></v-icon> </template> - </v-data-table-virtual> + </v-data-table-server> </v-card> </template> \ No newline at end of file diff --git a/pages/refseq.vue b/pages/refseq.vue index 692eb59da44eb931e4295b3905bedf6bf7a68e81..baa3a224d9f6a4fbe69ab1f8e36feb8026703cd3 100644 --- a/pages/refseq.vue +++ b/pages/refseq.vue @@ -15,7 +15,22 @@ const computedTableHeight = computed(() => { }) -const facetDistriSystem = ref(false); + +// SORTING +const sortBy: Ref<{ key: string, order: string }[]> = ref([{ key: 'type', order: "asc" }]) +const msSortBy = computed(() => { + if (sortBy.value.length > 0) { + return sortBy.value.map((curr) => { + if (curr?.key && curr?.order) { + return `${curr.key}:${curr.order}` + } + else { return "" } + }) + } else { return [""] } +}) + + + const availableTaxo: Ref<string[]> = ref(["species", "genus", "family", "order", "phylum", "Superkingdom"]); @@ -67,10 +82,25 @@ const computedFacets = computed(() => { }) -const { hits: items, pending, totalHits: itemsLength, filterError, facetDistribution } = useFetchMsDocument("refseq", search, filter, limit, hitsPerPage, page, computedFacets) -watch(facetDistribution, (facetDistri) => { +const { + hits: items, + pending, + totalHits: itemsLength, + filterError, + facetDistribution } + = useFetchMsDocument( + "refseq", + search, + filter, + limit, + hitsPerPage, + page, + computedFacets, + msSortBy + ) +watch(facetDistribution, (facetDistri) => { facetStore.setFacets({ facetDistribution: facetDistri, facetStat: undefined }) }) const computedSystemDistribution = computed(() => { @@ -197,9 +227,9 @@ watch(hasToGenerateDownload, (val) => { <v-col cols="auto"> <v-text-field v-model="filter" prepend-inner-icon="mdi-magnify" label="Filter" hide-details="auto" class="mx-2" clearable :error-messages="filterError"></v-text-field></v-col> - <v-data-table-server v-model:page="page" v-model:items-per-page="hitsPerPage" fixed-header :loading="pending" - :headers="computedHeaders" :items="items" :items-length="itemsLength" :item-value="itemValue" density="compact" - :height="computedTableHeight" class="elevation-1 mt-2"> + <v-data-table-server v-model:page="page" v-model:items-per-page="hitsPerPage" v-model:sortBy="sortBy" fixed-header + :loading="pending" :headers="computedHeaders" :items="items" :items-length="itemsLength" :item-value="itemValue" + multi-sort density="compact" :height="computedTableHeight" class="elevation-1 mt-2"> <template #[`item.${key}`]="{ item }" v-for="key in itemFilterKeys" :key="key"> <v-chip @click="filter = itemToFilter(item, key)">{{ item[key] }}</v-chip> </template>