feat: use ref for filters
This commit is contained in:
parent
acb3ddc73f
commit
51dc123d89
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user