This repository has been archived on 2024-02-08. You can view files and clone it, but cannot push or open issues or pull requests.
frontend/src/composables/useRouteFilter.ts

43 lines
1.2 KiB
TypeScript

import {reactive, watch, type Ref} from 'vue'
import {useRouter, type RouteLocationNormalized, type RouteLocationRaw} from 'vue-router'
import cloneDeep from 'lodash.clonedeep'
export type Filter = Record<string, any>
export function useRouteFilter<F extends Filter = Filter>(
route: Ref<RouteLocationNormalized>,
routeToFilter: (route: RouteLocationNormalized) => F,
filterToRoute: (filter: F) => RouteLocationRaw,
) {
const router = useRouter()
const filters: F = reactive(routeToFilter(route.value))
watch(() => cloneDeep(route.value), (route, oldRoute) => {
if (route.name !== oldRoute.name) {
return
}
const filterFullPath = router.resolve(filterToRoute(filters)).fullPath
if (filterFullPath === route.fullPath) {
return
}
Object.assign(filters, routeToFilter(route))
})
watch(
filters,
async () => {
const newRouteFullPath = router.resolve(filterToRoute(filters)).fullPath
if (newRouteFullPath !== route.value.fullPath) {
await router.push(newRouteFullPath)
}
},
// only apply new route after all filters have changed in component cycle
{flush: 'post'},
)
return {
filters,
}
}