feat: implement URL state persistence for dashboard

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.
This commit is contained in:
ccbikai 2025-03-02 14:19:40 +08:00
parent 1eb22503e6
commit dd7b898a11
3 changed files with 67 additions and 1 deletions

View file

@ -1,5 +1,7 @@
<script setup>
import { now, startOfMonth, startOfWeek } from '@internationalized/date'
import { useUrlSearchParams } from '@vueuse/core'
import { safeDestr } from 'destr'
const emit = defineEmits(['update:dateRange'])
@ -61,6 +63,28 @@ watch(dateRange, (newValue) => {
break
}
})
function restoreDateRange() {
try {
const searchParams = useUrlSearchParams('history')
if (searchParams.time) {
const time = safeDestr(searchParams.time)
emit('update:dateRange', [time.startAt, time.endAt])
dateRange.value = 'custom'
nextTick(() => {
openCustomDateRange.value = false
customDateRange.value = undefined
})
}
}
catch (error) {
console.error('restore searchParams error', error)
}
}
onBeforeMount(() => {
restoreDateRange()
})
</script>
<template>

View file

@ -1,4 +1,6 @@
<script setup>
import { useUrlSearchParams } from '@vueuse/core'
import { safeDestr } from 'destr'
import { Check, ChevronsUpDown } from 'lucide-vue-next'
const emit = defineEmits(['change'])
@ -18,6 +20,20 @@ onMounted(() => {
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>

View file

@ -1,5 +1,7 @@
<script setup>
import { now } from '@internationalized/date'
import { useUrlSearchParams } from '@vueuse/core'
import { safeDestr } from 'destr'
defineProps({
link: {
@ -8,6 +10,8 @@ defineProps({
},
})
const searchParams = useUrlSearchParams('history')
const time = ref({
startAt: date2unix(now().subtract({ days: 7 })),
endAt: date2unix(now()),
@ -20,6 +24,8 @@ function changeDate(dateRange) {
// console.log('dashboard date', new Date(time[0] * 1000), new Date(time[1] * 1000))
time.value.startAt = dateRange[0]
time.value.endAt = dateRange[1]
searchParams.time = JSON.stringify(time.value)
}
const filters = ref({})
@ -29,7 +35,27 @@ provide('filters', filters)
function changeFilter(type, value) {
console.log('changeFilter', type, value)
filters.value[type] = value
searchParams.filters = JSON.stringify(filters.value)
}
function restoreSearchParams() {
try {
if (searchParams.time) {
time.value = safeDestr(searchParams.time)
}
if (searchParams.filters) {
filters.value = safeDestr(searchParams.filters)
}
}
catch (error) {
console.error('restore searchParams error', error)
}
}
onBeforeMount(() => {
restoreSearchParams()
})
</script>
<template>
@ -46,7 +72,7 @@ function changeFilter(type, value) {
</template>
<DashboardDatePicker @update:date-range="changeDate" />
</DashboardNav>
<DashboardFilter v-if="!link" @change="changeFilter" />
<DashboardFilters v-if="!link" @change="changeFilter" />
</div>
<DashboardCounters />
<DashboardViews />