diff --git a/frontend/src/composables/useRouteFilters.test.ts b/frontend/src/composables/useRouteFilters.test.ts new file mode 100644 index 000000000..8723f0c96 --- /dev/null +++ b/frontend/src/composables/useRouteFilters.test.ts @@ -0,0 +1,11 @@ +import {describe, it, expectTypeOf} from 'vitest' +import {useRouteFilters, type UseRouteFiltersReturn} from './useRouteFilters' + +interface DummyFilters {foo: string} + +describe('useRouteFilters type inference', () => { + it('should infer return types based on filter interface', () => { + type Result = ReturnType> + expectTypeOf().toEqualTypeOf>() + }) +}) diff --git a/frontend/src/composables/useRouteFilters.ts b/frontend/src/composables/useRouteFilters.ts index 65d9f8245..c1849f315 100644 --- a/frontend/src/composables/useRouteFilters.ts +++ b/frontend/src/composables/useRouteFilters.ts @@ -5,13 +5,19 @@ import equal from 'fast-deep-equal/es6' // eslint-disable-next-line @typescript-eslint/no-explicit-any export type Filters = Record +export interface UseRouteFiltersReturn { + filters: Ref + hasDefaultFilters: Ref + setDefaultFilters: () => void +} + export function useRouteFilters( route: Ref, getDefaultFilters: (route: RouteLocationNormalized) => CurrentFilters, routeToFilters: (route: RouteLocationNormalized) => CurrentFilters, filtersToRoute: (filters: CurrentFilters) => RouteLocationRaw, routeAllowList: RouteRecordName[] = [], -) { +) : UseRouteFiltersReturn { const router = useRouter() const filters = ref(routeToFilters(route.value)) diff --git a/frontend/src/views/project/helpers/useGanttFilters.ts b/frontend/src/views/project/helpers/useGanttFilters.ts index 450a35f98..5a211b523 100644 --- a/frontend/src/views/project/helpers/useGanttFilters.ts +++ b/frontend/src/views/project/helpers/useGanttFilters.ts @@ -4,8 +4,8 @@ import type {RouteLocationNormalized, RouteLocationRaw} from 'vue-router' import {isoToKebabDate} from '@/helpers/time/isoToKebabDate' import {parseDateProp} from '@/helpers/time/parseDateProp' import {parseBooleanProp} from '@/helpers/time/parseBooleanProp' -import {useRouteFilters} from '@/composables/useRouteFilters' -import {useGanttTaskList} from './useGanttTaskList' +import {useRouteFilters, type UseRouteFiltersReturn} from '@/composables/useRouteFilters' +import {useGanttTaskList, type UseGanttTaskListReturn} from './useGanttTaskList' import type {IProject} from '@/modelTypes/IProject' import type {TaskFilterParams} from '@/services/taskCollection' @@ -94,8 +94,8 @@ function ganttFiltersToApiParams(filters: GanttFilters): TaskFilterParams { } export type UseGanttFiltersReturn = - ReturnType> & - ReturnType> + UseRouteFiltersReturn & + UseGanttTaskListReturn export function useGanttFilters(route: Ref, viewId: Ref): UseGanttFiltersReturn { const { diff --git a/frontend/src/views/project/helpers/useGanttTaskList.test.ts b/frontend/src/views/project/helpers/useGanttTaskList.test.ts new file mode 100644 index 000000000..df010762d --- /dev/null +++ b/frontend/src/views/project/helpers/useGanttTaskList.test.ts @@ -0,0 +1,14 @@ +import {describe, it, expectTypeOf} from 'vitest' +import {useGanttTaskList, type UseGanttTaskListReturn} from './useGanttTaskList' +import type {Filters} from '@/composables/useRouteFilters' + +interface TestFilters extends Filters { + projectId: number +} + +describe('useGanttTaskList return type', () => { + it('should match interface', () => { + type Result = ReturnType> + expectTypeOf().toEqualTypeOf() + }) +}) diff --git a/frontend/src/views/project/helpers/useGanttTaskList.ts b/frontend/src/views/project/helpers/useGanttTaskList.ts index 443106310..3fe2bf3c2 100644 --- a/frontend/src/views/project/helpers/useGanttTaskList.ts +++ b/frontend/src/views/project/helpers/useGanttTaskList.ts @@ -1,4 +1,4 @@ -import {computed, ref, type Ref, shallowReactive, watch} from 'vue' +import {computed, ref, type Ref, shallowReactive, watch, type ComputedRef} from 'vue' import {klona} from 'klona/lite' import type {Filters} from '@/composables/useRouteFilters' @@ -12,13 +12,21 @@ import {error, success} from '@/message' import {useAuthStore} from '@/stores/auth' import type {IProjectView} from '@/modelTypes/IProjectView' +export interface UseGanttTaskListReturn { + tasks: Ref> + isLoading: ComputedRef + loadTasks: () => Promise + addTask: (task: Partial) => Promise + updateTask: (task: ITaskPartialWithId) => Promise +} + // FIXME: unify with general `useTaskList` export function useGanttTaskList( filters: Ref, filterToApiParams: (filters: F) => TaskFilterParams, viewId: Ref, loadAll: boolean = true, -) { +) : UseGanttTaskListReturn { const taskCollectionService = shallowReactive(new TaskCollectionService()) const taskService = shallowReactive(new TaskService()) const authStore = useAuthStore()