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:
parent
1eb22503e6
commit
dd7b898a11
3 changed files with 67 additions and 1 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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 />
|
||||
|
|
|
|||
Loading…
Reference in a new issue