Save filters into query string (non-reactive way)

This commit is contained in:
Jan Zípek 2024-04-01 09:25:21 +02:00
parent 160764380b
commit 676fb24094
Signed by: kamen
GPG Key ID: A17882625B33AC31
4 changed files with 93 additions and 7 deletions

View File

@ -1,10 +1,10 @@
import { useAppContext } from '@/contexts/AppContext'
import { useHashLocation } from '@/utils/hooks/useHashLocation'
import { useHashRouterLocation } from '@/utils/hooks/useHashLocation'
import { Route, Router as Wouter } from 'wouter'
import { AlertsPage } from './alerts/AlertsPage'
import { NewDashboardPage } from './dashboard/NewDashboardPage'
import { LoginPage } from './login/LoginPage'
import { SensorsPage } from './sensors/SensorsPage'
import { AlertsPage } from './alerts/AlertsPage'
export const Router = () => {
const { loggedIn } = useAppContext()
@ -12,7 +12,7 @@ export const Router = () => {
return (
<>
{loggedIn && (
<Wouter hook={useHashLocation}>
<Wouter hook={useHashRouterLocation}>
<Route path="/">
<NewDashboardPage />
</Route>

View File

@ -18,8 +18,12 @@ import {
useState,
} from 'preact/hooks'
import { useQuery } from 'react-query'
import { FilterValue } from '../components/DashboardHeader/components/DashboardFilters'
import {
FilterInterval,
FilterValue,
} from '../components/DashboardHeader/components/DashboardFilters'
import { BoxDefinition } from '../types'
import { useQueryString } from '@/utils/hooks/useQueryString'
type DashboardContextType = {
filter: FilterValue
@ -48,6 +52,8 @@ export const DashboardContextProvider = ({
const dashboards = useQuery(['/dashboards'], getDashboards)
const { getValues: getQuery, setValues: setQuery } = useQueryString()
const dashboard = useQuery(
['/dashboards', dashboardId],
() => getDashboard(dashboardId),
@ -98,11 +104,40 @@ export const DashboardContextProvider = ({
}, [dashboards.data, isDashboardSelected, dashboards.isFetching])
const [filter, setFilter] = useState<FilterValue>(() => {
const range = intervalToRange('week', new Date(), new Date())
const query = getQuery()
const queryFilter = query.get('interval')
const queryFilterFrom = query.get('from')
const queryFilterTo = query.get('to')
return { interval: 'week', customFrom: range[0], customTo: range[1] }
const presetInterval =
queryFilter &&
['hour', 'day', 'week', 'month', 'year', 'custom'].includes(queryFilter)
? (queryFilter as FilterInterval)
: 'week'
const customFrom = queryFilterFrom ? new Date(queryFilterFrom) : new Date()
const customTo = queryFilterTo ? new Date(queryFilterTo) : new Date()
const range = intervalToRange(presetInterval, customFrom, customTo)
console.log({ presetInterval, range })
return {
interval: presetInterval,
customFrom: range[0],
customTo: range[1],
}
})
useEffect(() => {
setQuery({
interval: filter.interval,
...(filter.interval === 'custom' && {
from: filter.customFrom.toISOString(),
to: filter.customTo.toISOString(),
}),
})
}, [filter])
const verticalMode = viewport.width < 800
const value = useMemo(

View File

@ -21,5 +21,13 @@ export const useHashLocation = () => {
return () => window.removeEventListener('hashchange', handler)
}, [])
return [loc, navigate]
return [loc, navigate] as const
}
export const useHashRouterLocation = () => {
const [location, setLocation] = useHashLocation()
const locationWithoutQueryString = location.split('?')[0]
return [locationWithoutQueryString, setLocation] as const
}

View File

@ -0,0 +1,43 @@
import { useCallback, useMemo, useRef } from 'preact/hooks'
import { useHashLocation } from './useHashLocation'
export const useQueryString = () => {
const [location, setLocation] = useHashLocation()
const values = useMemo(() => {
const queryIndex = location.indexOf('?')
if (queryIndex === -1) {
return [location, new URLSearchParams()] as const
}
const search = location.slice(queryIndex + 1)
console.log('search', search)
return [location.slice(0, queryIndex), new URLSearchParams(search)] as const
}, [location])
const valuesRef = useRef(values)
valuesRef.current = values
const getValues = useCallback(() => {
const [, searchParams] = valuesRef.current
return searchParams
}, [])
const setValues = useCallback((values: Record<string, string>) => {
const [baseLocation] = valuesRef.current
const newParams = new URLSearchParams(values)
setLocation(`${baseLocation}?${newParams}`)
}, [])
const hookData = useMemo(
() => ({ getValues, setValues }),
[getValues, setValues]
)
return hookData
}