feat(front): [WIP] couple tagsList to query
This commit is contained in:
parent
c2c0a2aa79
commit
e9e42c53b9
|
@ -48,8 +48,9 @@ const props = withDefaults(defineProps<Props>(), {
|
||||||
|
|
||||||
const page = usePage()
|
const page = usePage()
|
||||||
|
|
||||||
const tags = useRouteQuery<string[]>('tag', [])
|
const tags = useRouteQuery<string[]>('tag', [], { transform: (param: string | string[] | null) => (param === null ? [] : Array.isArray(param) ? param : [param]).filter(p => p.trim() !== '') })
|
||||||
const tagList = useTags().model(tags.value)
|
|
||||||
|
const tagList = useTags(tags)
|
||||||
|
|
||||||
const q = useRouteQuery('query', '')
|
const q = useRouteQuery('query', '')
|
||||||
const query = ref(q.value ?? '')
|
const query = ref(q.value ?? '')
|
||||||
|
@ -152,6 +153,7 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
||||||
autofocus
|
autofocus
|
||||||
:placeholder="labels.searchPlaceholder"
|
:placeholder="labels.searchPlaceholder"
|
||||||
/>
|
/>
|
||||||
|
{{ tagList }}
|
||||||
<Pills
|
<Pills
|
||||||
v-model="tagList"
|
v-model="tagList"
|
||||||
:label="t('components.library.Albums.label.tags')"
|
:label="t('components.library.Albums.label.tags')"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { paths } from '~/generated/types.ts'
|
import type { paths } from '~/generated/types.ts'
|
||||||
|
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref, type Ref } from 'vue'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
|
@ -8,19 +8,15 @@ type Item = { type: 'custom' | 'preset', label: string }
|
||||||
type Model = { currents: Item[], others?: Item[] }
|
type Model = { currents: Item[], others?: Item[] }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load and cache all tags
|
* Load and cache all tags.
|
||||||
|
* - Two-way binding with store (any change to the store will be reflected in `others`)
|
||||||
|
* - Two-way binding with ref
|
||||||
|
* @param currents Selected tags
|
||||||
|
* @returns an object with `currents` and `others`, ready to be used inside
|
||||||
*/
|
*/
|
||||||
export const useTags = <T> () => {
|
export const useTags = (currents: Ref<string[], string[]>) => {
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
// Two-way bind with store
|
|
||||||
const tags = computed({
|
|
||||||
get: () => store.state.ui.tags || [],
|
|
||||||
set: function(value) {
|
|
||||||
store.commit('ui/tags', value)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Ignore quick successive fetch triggers
|
// Ignore quick successive fetch triggers
|
||||||
const ignorePeriod = 500
|
const ignorePeriod = 500
|
||||||
|
|
||||||
|
@ -30,11 +26,13 @@ export const useTags = <T> () => {
|
||||||
// Wait after changing a tag before re-fetching
|
// Wait after changing a tag before re-fetching
|
||||||
const refetchInterval = 6000
|
const refetchInterval = 6000
|
||||||
|
|
||||||
|
// Number of tags to load on one page
|
||||||
const maxTags = 100000
|
const maxTags = 100000
|
||||||
|
|
||||||
const lastFetched = ref<number>(0)
|
const lastFetched = ref<number>(0)
|
||||||
|
|
||||||
const fetch = async () => {
|
const fetch = async () => {
|
||||||
|
// console.log('FETCH TAGS')
|
||||||
// Ignore subsequent fetch commands triggered in quick succession
|
// Ignore subsequent fetch commands triggered in quick succession
|
||||||
if (lastFetched.value + ignorePeriod > Date.now())
|
if (lastFetched.value + ignorePeriod > Date.now())
|
||||||
return
|
return
|
||||||
|
@ -50,40 +48,48 @@ export const useTags = <T> () => {
|
||||||
{ params: { page: 1, page_size: maxTags } }
|
{ params: { page: 1, page_size: maxTags } }
|
||||||
)
|
)
|
||||||
|
|
||||||
tags.value = response.data.results
|
// console.log('TAGS RESPONSE.data.results', response.data.results)
|
||||||
|
store.commit('ui/tags', response.data.results)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({
|
fetch();
|
||||||
/**
|
|
||||||
* @param currents Initial selected tags
|
|
||||||
* @returns v-model for `Pills` component
|
|
||||||
*/
|
|
||||||
model: (currents: string[] = []) => {
|
|
||||||
fetch();
|
|
||||||
return computed({
|
|
||||||
|
|
||||||
// Get currents initially from parameter. Get others from backend.
|
/**
|
||||||
get: (): Model => ({
|
* @returns v-model for `Pills` component
|
||||||
currents: currents.map(tag => ({
|
*/
|
||||||
label: tag,
|
return computed({
|
||||||
type: tags.value.some(({ name }) => tag === name) ? 'preset' : 'custom'
|
get () {
|
||||||
})),
|
// console.log("GET TAGS")
|
||||||
others: tags.value
|
return ({
|
||||||
.filter(({ name }) => !currents.includes(name))
|
// Get `currents` from parameter
|
||||||
.map(({ name }) => ({
|
currents: currents.value.map(tag => ({
|
||||||
label: name,
|
label: tag,
|
||||||
type: 'preset'
|
type: (store.state.ui.tags || []).some(({ name }) => tag === name) ? 'preset' : 'custom'
|
||||||
}))
|
} as const)),
|
||||||
}),
|
|
||||||
|
|
||||||
// Re-fetch after each new setting
|
// Get `others` from cache
|
||||||
set: function (_) {
|
others: (store.state.ui.tags || [])
|
||||||
window.setTimeout(fetch, refetchInterval)
|
.filter(({ name }) => !currents.value.includes(name))
|
||||||
// TODO: Broadcast new custom tags so that other pills components can use them
|
.map(({ name }) => ({
|
||||||
}
|
label: name,
|
||||||
})
|
type: 'preset'
|
||||||
|
} as const))
|
||||||
|
})},
|
||||||
|
|
||||||
|
set (model) {
|
||||||
|
// console.log('SET TAGS', response.data.results)
|
||||||
|
|
||||||
|
// Set parameter `currents` from `model.currents`
|
||||||
|
currents.value = model.currents.map(({ label }) => label)
|
||||||
|
|
||||||
|
// Set runtime-only options from `model.others` and `model.current`
|
||||||
|
// TODO: Broadcast new custom tags so that other pills components can use them
|
||||||
|
|
||||||
|
// Re-fetch after each new setting
|
||||||
|
window.setTimeout(fetch, refetchInterval)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// alternative ways to generate tags
|
// alternative ways to generate tags
|
||||||
|
// ...
|
||||||
|
|
Loading…
Reference in New Issue