Adds URL search params synchronization for dashboard filters and date range - Stores selected date range in URL for restoration on page reload - Removes old Filter component in favor of new implementation - Preserves filter state across page navigation This change improves user experience by maintaining dashboard state through browser navigation and page reloads.
79 lines
2.1 KiB
Vue
79 lines
2.1 KiB
Vue
<script setup>
|
|
import { useUrlSearchParams } from '@vueuse/core'
|
|
import { safeDestr } from 'destr'
|
|
import { Check, ChevronsUpDown } from 'lucide-vue-next'
|
|
|
|
const emit = defineEmits(['change'])
|
|
|
|
const links = ref([])
|
|
const isOpen = ref(false)
|
|
const selectedLinks = ref([])
|
|
|
|
async function getLinks() {
|
|
links.value = await useAPI('/api/link/search')
|
|
}
|
|
|
|
onMounted(() => {
|
|
getLinks()
|
|
})
|
|
|
|
watch(selectedLinks, (value) => {
|
|
emit('change', 'slug', value.join(','))
|
|
})
|
|
|
|
function restoreFilters() {
|
|
const searchParams = useUrlSearchParams('history')
|
|
if (searchParams.filters) {
|
|
const filters = safeDestr(searchParams.filters)
|
|
if (filters.slug) {
|
|
selectedLinks.value = filters.slug.split(',')
|
|
}
|
|
}
|
|
}
|
|
|
|
onBeforeMount(() => {
|
|
restoreFilters()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<Popover v-model:open="isOpen">
|
|
<PopoverTrigger as-child>
|
|
<Button
|
|
variant="outline"
|
|
role="combobox"
|
|
:aria-expanded="isOpen"
|
|
class="flex justify-between w-full sm:w-48"
|
|
>
|
|
<div class="flex-1 font-normal text-left truncate" :class="selectedLinks.length ? 'text-foreground' : 'text-muted-foreground'">
|
|
{{ selectedLinks.length ? selectedLinks.join(', ') : 'Filter Links...' }}
|
|
</div>
|
|
<ChevronsUpDown class="ml-2 w-4 h-4 opacity-50 shrink-0" />
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent class="p-0 w-full sm:w-48">
|
|
<Command v-model="selectedLinks" multiple>
|
|
<CommandInput placeholder="Filter Links..." />
|
|
<CommandEmpty>No link found.</CommandEmpty>
|
|
<CommandList>
|
|
<CommandGroup>
|
|
<CommandItem
|
|
v-for="link in links"
|
|
:key="link.slug"
|
|
:value="link.slug"
|
|
@select="isOpen = false"
|
|
>
|
|
<Check
|
|
:class="cn(
|
|
'mr-2 h-4 w-4',
|
|
selectedLinks.includes(link.slug) ? 'opacity-100' : 'opacity-0',
|
|
)"
|
|
/>
|
|
{{ link.slug }}
|
|
</CommandItem>
|
|
</CommandGroup>
|
|
</CommandList>
|
|
</Command>
|
|
</PopoverContent>
|
|
</Popover>
|
|
</template>
|