Files
vt-fe/src/features/Projects/queries.ts

249 lines
6.1 KiB
TypeScript

import {
infiniteQueryOptions,
keepPreviousData,
queryOptions,
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
} from '@tanstack/react-query'
import { fetchWithAuth, getOidc } from '@/lib/oidc'
import { getBackendURI } from '@/routes'
const projectKeys = {
all: ['projects'] as const,
lists: () => [...projectKeys.all, 'list'] as const,
getAll: (fetchSize: number, sorting: any) =>
[...projectKeys.lists(), 'all', fetchSize, sorting] as const,
get: (id: number) => [...projectKeys.all, 'get', id] as const,
}
const timelineKeys = {
all: ['timeline'] as const,
lists: () => [...timelineKeys.all, 'list'] as const,
getAll: (fetchSize: number, sorting: any) =>
[...timelineKeys.lists(), 'all', fetchSize, sorting] as const,
get: (id: number) => [...timelineKeys.all, 'get', id] as const,
}
const todoKeys = {
all: ['todos'] as const,
lists: () => [...todoKeys.all, 'list'] as const,
getAll: (fetchSize: number, sorting: any) =>
[...todoKeys.lists(), 'all', fetchSize, sorting] as const,
get: (id: number) => [...todoKeys.all, 'get', id] as const,
}
export type Paginated<TData> = {
data: Array<TData>
meta: {
totalCount: number
}
}
export type Project = {
ID: number
name: string
description: string
icon: string
MandantID: number
}
export type TimelineEntry = {
ID: number
name: string
from: Date
manualFrom: boolean
thru: Date
manualThru: boolean
}
export function getProjectQueryObject(id: number) {
return queryOptions<Project>({
queryKey: projectKeys.get(id),
queryFn: async () => {
const data = await fetchWithAuth(
(await getBackendURI()) + '/v1/projects/' + id,
{
credentials: 'include',
},
)
return await data.json()
},
})
}
export function useProject(id: number) {
return useQuery<Project>(getProjectQueryObject(id))
}
export function getAllProjectsQueryObject({ fetchSize, sorting }: any) {
return infiniteQueryOptions<Paginated<Project>>({
queryKey: projectKeys.getAll(fetchSize, sorting),
queryFn: async ({ pageParam = 0 }) => {
const start = (pageParam as number) * fetchSize
const { id, desc } = sorting[0]
const searchParams = new URLSearchParams()
searchParams.append('id', id)
searchParams.append('desc', desc)
searchParams.append('per-page', fetchSize)
searchParams.append('offset', start.toString())
const url = (await getBackendURI()) + '/v1/projects/all?' + searchParams
const data = await fetchWithAuth(url)
return await data.json()
},
initialPageParam: 0,
getNextPageParam: (_lastGroup, groups) => groups.length,
refetchOnWindowFocus: false,
placeholderData: keepPreviousData,
})
}
export function useAllProjects({
fetchSize,
sorting,
}: {
fetchSize: number
sorting: any
}) {
return useInfiniteQuery<Paginated<Project>>(
getAllProjectsQueryObject({ fetchSize, sorting }),
)
}
export function useAllTimelineEntries({
projectId,
fetchSize,
sorting,
}: {
projectId: number
fetchSize: number
sorting: any
}) {
return useInfiniteQuery<Paginated<TimelineEntry>>({
queryKey: timelineKeys.getAll(fetchSize, sorting),
queryFn: ({ pageParam = 0 }) => {
return {
data: Array(25).fill({
ID: projectId,
name: 'Aufbau',
from: new Date('2005-11-13'),
thru: new Date('2005-11-14'),
manualFrom: false,
manualThru: false,
}),
meta: {
totalCount: 75,
},
}
// const data = await setTimeout<Array<Paginated<Project>>>(() => {}, 2500)
// return data
},
initialPageParam: 0,
getNextPageParam: (_lastGroup, groups) => groups.length,
refetchOnWindowFocus: false,
placeholderData: keepPreviousData,
})
}
export function useAllProjectTodos({
projectId,
fetchSize,
sorting,
}: {
projectId: number
fetchSize: number
sorting: any
}) {
return useInfiniteQuery<Paginated<TimelineEntry>>({
queryKey: todoKeys.getAll(fetchSize, sorting),
queryFn: async ({ pageParam = 0 }) => {
const start = (pageParam as number) * fetchSize
const { id, desc } = sorting[0]
const searchParams = new URLSearchParams()
searchParams.append('id', id)
searchParams.append('desc', desc)
searchParams.append('per-page', fetchSize.toString())
searchParams.append('offset', start.toString())
const url =
(await getBackendURI()) +
'/v1/todos/project/' +
projectId +
'?' +
searchParams
const data = await fetchWithAuth(url)
return await data.json()
},
initialPageParam: 0,
getNextPageParam: (_lastGroup, groups) => groups.length,
refetchOnWindowFocus: false,
placeholderData: keepPreviousData,
})
}
export function useProjectEdit(id: number) {
return useMutation({
mutationFn: async (project: Project) => {
const oidc = await getOidc()
if (!oidc.isUserLoggedIn) {
throw Error('Logical error in our application flow')
}
const accessToken = await oidc.getAccessToken()
await fetchWithAuth(
(await getBackendURI()) + '/v1/projects/' + id + '/edit',
{
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
method: 'POST',
body: JSON.stringify(project),
credentials: 'include',
},
)
},
})
}
export function useProjectCreate() {
const queryClient = useQueryClient()
return useMutation({
mutationFn: async (project: Project) => {
const res = await fetchWithAuth(
(await getBackendURI()) + '/v1/projects/new',
{
headers: {
'content-type': 'application/json',
},
method: 'POST',
body: JSON.stringify(project),
credentials: 'include',
},
)
const newCurrentMandant = await res.json()
queryClient.invalidateQueries({ queryKey: projectKeys.lists() })
queryClient.setQueryData(
projectKeys.get(newCurrentMandant.id),
(_: Project) => newCurrentMandant,
)
},
})
}