feat: use ref for filters

This commit is contained in:
Dominik Pschenitschni 2022-10-19 16:48:26 +02:00
parent 94e2a7d001
commit 9235fabaa9
Signed by: dpschen
GPG Key ID: B257AC0149F43A77
4 changed files with 42 additions and 27 deletions

View File

@ -1,4 +1,4 @@
import {reactive, watch, type Ref} from 'vue'
import {computed, ref, watch, type Ref} from 'vue'
import {useRouter, type RouteLocationNormalized, type RouteLocationRaw} from 'vue-router'
import cloneDeep from 'lodash.clonedeep'
@ -11,26 +11,26 @@ export function useRouteFilter<F extends Filter = Filter>(
) {
const router = useRouter()
const filters: F = reactive(routeToFilter(route.value))
const filters = ref<F>(routeToFilter(route.value))
const routeFromFiltersFullPath = computed(() => router.resolve(filterToRoute(filters.value)).fullPath)
watch(() => cloneDeep(route.value), (route, oldRoute) => {
if (route.name !== oldRoute.name) {
return
}
const filterFullPath = router.resolve(filterToRoute(filters)).fullPath
if (filterFullPath === route.fullPath) {
if (
route.name !== oldRoute.name ||
routeFromFiltersFullPath.value === route.fullPath
) {
return
}
Object.assign(filters, routeToFilter(route))
filters.value = routeToFilter(route)
})
watch(
filters,
async () => {
const newRouteFullPath = router.resolve(filterToRoute(filters)).fullPath
if (newRouteFullPath !== route.value.fullPath) {
await router.push(newRouteFullPath)
if (routeFromFiltersFullPath.value !== route.value.fullPath) {
await router.push(routeFromFiltersFullPath.value)
}
},
// only apply new route after all filters have changed in component cycle

View File

@ -87,7 +87,7 @@ const defaultTaskEndDate: DateISO = new Date(today.getFullYear(), today.getMonth
async function addGanttTask(title: ITask['title']) {
return await addTask({
title,
listId: filters.listId,
listId: filters.value.listId,
startDate: defaultTaskStartDate,
endDate: defaultTaskEndDate,
})
@ -96,8 +96,8 @@ async function addGanttTask(title: ITask['title']) {
const flatPickerEl = ref<typeof Foo | null>(null)
const flatPickerDateRange = computed<Date[]>({
get: () => ([
new Date(filters.dateFrom),
new Date(filters.dateTo),
new Date(filters.value.dateFrom),
new Date(filters.value.dateTo),
]),
set(newVal) {
const [dateFrom, dateTo] = newVal.map((date) => date?.toISOString())
@ -105,11 +105,11 @@ const flatPickerDateRange = computed<Date[]>({
// only set after whole range has been selected
if (!dateTo) return
Object.assign(filters, {dateFrom, dateTo})
Object.assign(filters.value, {dateFrom, dateTo})
},
})
const initialDateRange = [filters.dateFrom, filters.dateTo]
const initialDateRange = [filters.value.dateFrom, filters.value.dateTo]
const {t} = useI18n({useScope: 'global'})
const authStore = useAuthStore()

View File

@ -36,7 +36,8 @@ function getDefaultDateTo() {
return new Date(now.getFullYear(), now.getMonth(), now.getDate() + DEFAULT_DATETO_DAY_OFFSET).toISOString()
}
function routeToFilter(route: RouteLocationNormalized): GanttFilter {
// FIXME: use zod for this
function ganttRouteToFilter(route: RouteLocationNormalized): GanttFilter {
return {
listId: Number(route.params.listId as string),
dateFrom: parseDateProp(route.query.dateFrom as DateKebab) || getDefaultDateFrom(),
@ -45,7 +46,8 @@ function routeToFilter(route: RouteLocationNormalized): GanttFilter {
}
}
function filterToRoute(filters: GanttFilter): RouteLocationRaw {
// FIXME: use zod for this
function ganttFilterToRoute(filters: GanttFilter): RouteLocationRaw {
let query: Record<string, string> = {}
if (
filters.dateFrom !== getDefaultDateFrom() ||
@ -80,8 +82,8 @@ function ganttFiltersToApiParams(filters: GanttFilter): GetAllTasksParams {
}
}
export function useGanttFilter(route: Ref<RouteLocationNormalized>) {
const {filters} = useRouteFilter<GanttFilter>(route, routeToFilter, filterToRoute)
export function useGanttFilter(route: Ref<RouteLocationNormalized>): ReturnType<typeof useRouteFilter> & ReturnType<typeof useGanttTaskList> {
const {filters} = useRouteFilter<GanttFilter>(route, ganttRouteToFilter, ganttFilterToRoute)
const {
tasks,

View File

@ -1,10 +1,10 @@
import {computed, ref, shallowReactive, watchEffect} from 'vue'
import {computed, ref, shallowReactive, watch, type Ref} from 'vue'
import cloneDeep from 'lodash.clonedeep'
import type {Filter} from '@/composables/useRouteFilter'
import type {ITask, ITaskPartialWithId} from '@/modelTypes/ITask'
import TaskCollectionService, { type GetAllTasksParams } from '@/services/taskCollection'
import TaskCollectionService, {type GetAllTasksParams} from '@/services/taskCollection'
import TaskService from '@/services/task'
import TaskModel from '@/models/task'
@ -12,7 +12,7 @@ import {error, success} from '@/message'
// FIXME: unify with general `useTaskList`
export function useGanttTaskList<F extends Filter>(
filters: F,
filters: Ref<F>,
filterToApiParams: (filters: F) => GetAllTasksParams,
options: {
loadAll?: boolean,
@ -27,7 +27,7 @@ export function useGanttTaskList<F extends Filter>(
const tasks = ref<Map<ITask['id'], ITask>>(new Map())
async function fetchTasks(params: GetAllTasksParams, page = 1): Promise<ITask[]> {
const tasks = await taskCollectionService.getAll({listId: filters.listId}, params, page) as ITask[]
const tasks = await taskCollectionService.getAll({listId: filters.value.listId}, params, page) as ITask[]
if (options.loadAll && page < taskCollectionService.totalPages) {
const nextTasks = await fetchTasks(params, page + 1)
return tasks.concat(nextTasks)
@ -35,15 +35,26 @@ export function useGanttTaskList<F extends Filter>(
return tasks
}
async function loadTasks(filters: F) {
const params: GetAllTasksParams = filterToApiParams(filters)
/**
* Load and assign new tasks
* Normally there is no need to trigger this manually
*/
async function loadTasks() {
const params: GetAllTasksParams = filterToApiParams(filters.value)
const loadedTasks = await fetchTasks(params)
tasks.value = new Map()
loadedTasks.forEach(t => tasks.value.set(t.id, t))
}
watchEffect(() => loadTasks(filters))
/**
* Load tasks when filters change
*/
watch(
filters,
() => loadTasks(),
{immediate: true, deep: true},
)
async function addTask(task: Partial<ITask>) {
const newTask = await taskService.create(new TaskModel({...task}))
@ -83,6 +94,8 @@ export function useGanttTaskList<F extends Filter>(
tasks,
isLoading,
loadTasks,
addTask,
updateTask,
}