From d318ed72a4a05a9a31f2872d9fbbf8b550a2c305 Mon Sep 17 00:00:00 2001 From: Adrian Rudnik Date: Wed, 1 Nov 2023 01:59:56 +0100 Subject: [PATCH] Completed load more functionality on search results --- frontend/src/components/parts/QueryInput.vue | 148 +++++++++--------- .../parts/search/SearchExamples.vue | 26 +-- .../structure/InfiniteScrollTrigger.vue | 34 ++++ .../components/structure/SearchResultList.vue | 34 ++++ frontend/src/locales/en.yaml | 6 +- frontend/src/plugins/search/index.ts | 26 --- frontend/src/plugins/search/query/index.ts | 3 + frontend/src/stores/search.ts | 61 ++++++++ frontend/src/stores/tags.ts | 4 +- 9 files changed, 224 insertions(+), 118 deletions(-) create mode 100644 frontend/src/components/structure/InfiniteScrollTrigger.vue delete mode 100644 frontend/src/plugins/search/index.ts create mode 100644 frontend/src/stores/search.ts diff --git a/frontend/src/components/parts/QueryInput.vue b/frontend/src/components/parts/QueryInput.vue index 5f9912e8..d05e2b9e 100644 --- a/frontend/src/components/parts/QueryInput.vue +++ b/frontend/src/components/parts/QueryInput.vue @@ -2,33 +2,33 @@
diff --git a/frontend/src/components/parts/search/SearchExamples.vue b/frontend/src/components/parts/search/SearchExamples.vue index 4e5d40f9..73850380 100644 --- a/frontend/src/components/parts/search/SearchExamples.vue +++ b/frontend/src/components/parts/search/SearchExamples.vue @@ -36,13 +36,8 @@ @@ -76,7 +71,15 @@
  • - +type:AudioTrack + + +
  • @@ -119,10 +122,14 @@
  • + + @@ -151,6 +158,7 @@ const { t } = useI18n() code { white-space: nowrap; font-size: 0.9em; + margin-right: 0.20em; background-color: black; color: white; padding: 0.25rem; diff --git a/frontend/src/components/structure/InfiniteScrollTrigger.vue b/frontend/src/components/structure/InfiniteScrollTrigger.vue new file mode 100644 index 00000000..61e40c87 --- /dev/null +++ b/frontend/src/components/structure/InfiniteScrollTrigger.vue @@ -0,0 +1,34 @@ + + + diff --git a/frontend/src/components/structure/SearchResultList.vue b/frontend/src/components/structure/SearchResultList.vue index 147a015a..b7c3f928 100644 --- a/frontend/src/components/structure/SearchResultList.vue +++ b/frontend/src/components/structure/SearchResultList.vue @@ -6,6 +6,8 @@ :is="resolveComponent(result.type)" :result="result" /> + + diff --git a/frontend/src/locales/en.yaml b/frontend/src/locales/en.yaml index d13c2b3d..ec149edb 100644 --- a/frontend/src/locales/en.yaml +++ b/frontend/src/locales/en.yaml @@ -383,8 +383,8 @@ search-examples: Advanced search is possible via simple binary entries. Here are some examples to give ideas: list: 1: >- - {0} searches only for audio tracks, regardless of whether additional - search parameters have been specified. Other types are also 'MidiTrack' and 'LiveSet'. + {e1} searches only for audio tracks, regardless of whether additional + search parameters have been specified. Other types are also {e2} and {e3}. 2: >- {0} searches for all hits that are not MIDI tracks. 3: >- @@ -400,7 +400,7 @@ search-examples: absolute path of a file with {e2}. 7: >- {e1} without any further information searches all manual info field entries for - the word {e1}, which includes e.g. the word {e2}. + the word {e2}, which includes e.g. the word {e3}. live-set-result-item-component: header: '@:common.label.live-set.s' diff --git a/frontend/src/plugins/search/index.ts b/frontend/src/plugins/search/index.ts deleted file mode 100644 index d9f53444..00000000 --- a/frontend/src/plugins/search/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { SearchQuery } from './query' -import type { SearchResult } from './result' -import { useStatStore } from '@/stores/stats' - -export async function executeQuerySearch(query: SearchQuery): Promise { - const response = await fetch(import.meta.env.VITE_API_URL + '/search/query', { - credentials: 'include', - headers: { - Accept: 'application/json', - 'Content-Type': 'application/json' - }, - body: JSON.stringify(query), - method: 'POST' - }) - - if (!response.ok) { - throw new Error(response.statusText) - } - - const result: SearchResult = await response.json() - - // Extract global result information - useStatStore().searchResultCount = result.total_hits - - return result -} diff --git a/frontend/src/plugins/search/query/index.ts b/frontend/src/plugins/search/query/index.ts index d135a73f..62047beb 100644 --- a/frontend/src/plugins/search/query/index.ts +++ b/frontend/src/plugins/search/query/index.ts @@ -3,6 +3,9 @@ export interface SearchQuery { query: SearchQueryString facets?: SearchFacets fields?: string[] + sort?: string[] + search_after?: string[] + search_before?: string[] } export interface SearchFacets { diff --git a/frontend/src/stores/search.ts b/frontend/src/stores/search.ts new file mode 100644 index 00000000..274404ac --- /dev/null +++ b/frontend/src/stores/search.ts @@ -0,0 +1,61 @@ +import {defineStore} from "pinia"; +import {computed, ref, watch} from "vue"; +import type {SearchQuery} from "@/plugins/search/query"; +import type {SearchResult} from "@/plugins/search/result"; +import {useStatStore} from "@/stores/stats"; +import {useSearchResultStore} from "@/stores/results"; + +export const useSearchStore = defineStore('search', () => { + const currentQuery = ref() + const currentOffset = ref(0) + const lastSortKey = ref([]) + + const executeQuerySearch = async (query: SearchQuery): Promise=> { + const response = await fetch(import.meta.env.VITE_API_URL + '/search/query', { + credentials: 'include', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json' + }, + body: JSON.stringify(query), + method: 'POST' + }) + + if (!response.ok) { + throw new Error(response.statusText) + } + + const result: SearchResult = await response.json() + + // Extract global result information + useStatStore().searchResultCount = result.total_hits + + // Remember the query, in case we need to load more + currentQuery.value = query + + // Get the last result to retrieve the sort offset + const last = result.hits[result.hits.length - 1] + if (last) { + lastSortKey.value = [last.score.toString(), last.id] + } + + return result + } + + const clear = () => { + useSearchResultStore().clear() + useStatStore().searchResultCount = 0 + currentQuery.value = undefined + currentOffset.value = 0 + lastSortKey.value = [] + } + + return { + clear, + currentQuery, + currentOffset, + lastSortKey, + executeQuerySearch + } +}) + diff --git a/frontend/src/stores/tags.ts b/frontend/src/stores/tags.ts index e95a695f..de3e4faf 100644 --- a/frontend/src/stores/tags.ts +++ b/frontend/src/stores/tags.ts @@ -1,8 +1,8 @@ import { defineStore } from 'pinia' import { setupStore } from '@/stores/base' -import { executeQuerySearch } from '@/plugins/search' import i18n from '@/plugins/i18n' import { resolveColorByIndex } from '@/plugins/colors' +import {useSearchStore} from "@/stores/search"; const { t } = i18n.global @@ -54,7 +54,7 @@ export interface Tag { export const useTagStore = defineStore('tags', setupStore()) export const hydrateTags = async () => { - const r = await executeQuerySearch({ + const r = await useSearchStore().executeQuerySearch({ size: 4, query: { query: '*'