Skip to content

Commit

Permalink
feat: standardizes react-query methodology
Browse files Browse the repository at this point in the history
  • Loading branch information
aviemet committed Oct 3, 2024
1 parent 0d2e225 commit 777e8c3
Show file tree
Hide file tree
Showing 22 changed files with 355 additions and 240 deletions.
43 changes: 2 additions & 41 deletions app/frontend/queries/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,2 @@
import { useQuery, queryOptions } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { ComboboxData } from '@mantine/core'
import { type ReactQueryFunction } from '..'
import queryKeys from '../queryKeys'

export const useGetCommand: ReactQueryFunction<Schema.CommandsShow, {slug:string}> = ({ slug }, options) => {
return useQuery({
...queryOptions({
queryKey: queryKeys.commands.detail(slug),
queryFn: async () => {
const res = await axios.get(Routes.apiCommand(slug))
return res.data
},
}),
...options,
})
}

export const useGetCommands: ReactQueryFunction<Schema.CommandsOptions[]> = (options) => {
return useQuery({
queryKey: ['commands'],
queryFn: async () => {
const res = await axios.get(Routes.apiCommands())
return res.data
},
...options,
})
}

export const useGetCommandPayloadTypes: ReactQueryFunction<ComboboxData> = (options) => {
return useQuery({
queryKey: ['commandPayloadTypes'],
queryFn: async () => {
const res = await axios.get(Routes.apiCommandsPayloadTypes())
return res.data
},
...options,
})
}
export * from './queries'
export * from './mutations'
7 changes: 7 additions & 0 deletions app/frontend/queries/commands/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const queryRoot = 'commands'

export const queryKeys = {
commands: [queryRoot] as const,
command: (slug: string) => [queryRoot, slug] as const,
payloadTypes: [queryRoot, 'payloadTypes'] as const,
}
22 changes: 22 additions & 0 deletions app/frontend/queries/commands/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { type ReactMutationFunction } from ".."
import axios from 'axios';
import { Routes } from "@/lib";
import { queryKeys } from "./keys";

export const useCreateCommand: ReactMutationFunction<Schema.CommandsFormData, Schema.CommandsShow> = (options) => {
const queryClient = useQueryClient()

return useMutation({
mutationKey: queryKeys.commands,
mutationFn: async (data) => {
const res = await axios.post(Routes.apiCommands(), data)
return res.data
},
...options,
onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryKey: queryKeys.commands })
options?.onSuccess?.(data, variables)
},
})
}
38 changes: 38 additions & 0 deletions app/frontend/queries/commands/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { ComboboxData } from '@mantine/core'
import { type ReactQueryFunction } from '..'
import { queryKeys } from "./keys";
export const useGetCommands: ReactQueryFunction<Schema.CommandsOptions[]> = (options) => {
return useQuery({
queryKey: queryKeys.commands,
queryFn: async () => {
const res = await axios.get(Routes.apiCommands())
return res.data
},
...options,
})
}

export const useGetCommand: ReactQueryFunction<Schema.CommandsShow, { slug:string }> = ({ slug }, options) => {
return useQuery({
queryKey: queryKeys.command(slug),
queryFn: async () => {
const res = await axios.get(Routes.apiCommand(slug))
return res.data
},
...options,
})
}

export const useGetCommandPayloadTypes: ReactQueryFunction<ComboboxData> = (options) => {
return useQuery({
queryKey: queryKeys.payloadTypes,
queryFn: async () => {
const res = await axios.get(Routes.apiCommandsPayloadTypes())
return res.data
},
...options,
})
}
49 changes: 2 additions & 47 deletions app/frontend/queries/controls/index.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,2 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { ComboboxData } from '@mantine/core'
import { type ReactQueryFunction, type ReactMutationFunction } from '..'

export const useGetControl: ReactQueryFunction<Schema.ControlsShow, { slug: string }> = ({ slug }, options) => {
return useQuery({
queryKey: [`control/${slug}`],
queryFn: async () => {
const res = await axios.get(Routes.apiControl(slug))
return res.data
},
...options,
})
}

export const useGetControls: ReactQueryFunction<Schema.ControlsOptions[]> = (options) => {
return useQuery({
queryKey: ['controls'],
queryFn: async () => {
const res = await axios.get(Routes.apiControls())
return res.data
},
...options,
})
}

export const useCreateControl: ReactMutationFunction<
Schema.ControlsFormData & { type: string },
Schema.ControlsShow
> = ({ options }) => {
const queryClient = useQueryClient()

return useMutation({
mutationFn: async ({ type }) => {
const res = await axios.post(Routes.apiControls(), type)
return res.data
},
mutationKey: ['controls'],
...options,
onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryKey: ['controls'] })
options?.onSuccess?.(data, variables)
},
})
}
export * from './queries'
export * from './mutations'
6 changes: 6 additions & 0 deletions app/frontend/queries/controls/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const queryRoot = 'control'

export const queryKeys = {
controls: [queryRoot] as const,
control: (slug: string) => [queryRoot, slug] as const,
}
25 changes: 25 additions & 0 deletions app/frontend/queries/controls/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { type ReactMutationFunction } from ".."
import axios from 'axios';
import { Routes } from "@/lib";
import { queryKeys } from "./keys";

export const useCreateControl: ReactMutationFunction<
Schema.ControlsFormData,
Schema.ControlsShow
> = (options) => {
const queryClient = useQueryClient()

return useMutation({
mutationKey: queryKeys.controls,
mutationFn: async (data) => {
const res = await axios.post(Routes.apiControls(), data)
return res.data
},
...options,
onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryKey: queryKeys.controls })
options?.onSuccess?.(data, variables)
},
})
}
26 changes: 26 additions & 0 deletions app/frontend/queries/controls/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { type ReactQueryFunction } from '..'

export const useGetControl: ReactQueryFunction<Schema.ControlsShow, { slug: string }> = ({ slug }, options) => {
return useQuery({
queryKey: [`control/${slug}`],
queryFn: async () => {
const res = await axios.get(Routes.apiControl(slug))
return res.data
},
...options,
})
}

export const useGetControls: ReactQueryFunction<Schema.ControlsOptions[]> = (options) => {
return useQuery({
queryKey: ['controls'],
queryFn: async () => {
const res = await axios.get(Routes.apiControls())
return res.data
},
...options,
})
}
38 changes: 22 additions & 16 deletions app/frontend/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,50 @@ import {
* Query types
*/

interface LimitedQueryOptions<TData> extends Omit<UseQueryOptions<TData>, 'queryKey'|'queryFn'> {}
interface LimitedQueryOptions<TData> extends Omit<UseQueryOptions<TData>, 'queryKey' | 'queryFn'> {}

type ReactQueryFunctionBasic<TData> = (options?: LimitedQueryOptions<TData>) => UseQueryResult<TData, Error>
type ReactQueryFunctionWithParams<TData, TParams extends Record<string, string|number|string[]>> = (params: TParams, options?: LimitedQueryOptions<TData>) => UseQueryResult<TData, Error>

type ReactQueryFunctionWithParams<TData, TParams extends Record<string, string | number | string[]>> = (
params: TParams,
options?: LimitedQueryOptions<TData>
) => UseQueryResult<TData, Error>

export type ReactQueryFunction<TData, TParams = undefined> =
TParams extends undefined
? ReactQueryFunctionBasic<TData>
: TParams extends Record<string, string|number|string[]>
: TParams extends Record<string, string | number | string[]>
? ReactQueryFunctionWithParams<TData, TParams>
: never;

/**
* Mutation types
*/

interface LimitedMutationOptions<TReturnData, TVariables, TError = unknown> extends Omit<UseMutationOptions<TReturnData, TError, TVariables, unknown>, 'mutationKey'|'onSuccess'> {
interface LimitedMutationOptions<TReturnData, TVariables, TError = unknown> extends
Omit<UseMutationOptions<TReturnData, TError, TVariables, unknown>, 'mutationKey' | 'onSuccess'> {
onSuccess?: (data: TReturnData, variables: TVariables) => void
}

type ReactMutationFunctionBasic<TReturnData, TVariables, TError = unknown> = (
options?: LimitedMutationOptions<TReturnData, TVariables, TError>
) => UseMutationResult<TReturnData, TError, TVariables, unknown>

type ReactMutationFunctionWithParams<TReturnData, TVariables, TParams extends Record<string, string | number | string[]>, TError = unknown> = (
params: TParams,
options?: LimitedMutationOptions<TReturnData, TVariables, TError>
) => UseMutationResult<TReturnData, TError, TVariables, unknown>

export type ReactMutationFunction<
TMutationVariables,
TReturnData,
TParams = undefined,
TError = unknown
> = TParams extends undefined
? ({
options
}: {
options: LimitedMutationOptions<TReturnData, TMutationVariables, TError>
}) => UseMutationResult<TReturnData, TError, TMutationVariables, unknown>
: ({
params,
options,
}: {
params: TParams,
options?: LimitedMutationOptions<TReturnData, TMutationVariables, TError>
}) => UseMutationResult<TReturnData, TError, TMutationVariables, unknown>
? ReactMutationFunctionBasic<TReturnData, TMutationVariables, TError>
: TParams extends Record<string, string | number | string[]>
? ReactMutationFunctionWithParams<TReturnData, TMutationVariables, TParams, TError>
: never

/**
* Folder exports
Expand Down
28 changes: 2 additions & 26 deletions app/frontend/queries/protocols/index.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,2 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { type ReactQueryFunction } from '..'

export const useGetProtocol: ReactQueryFunction<Schema.ProtocolsShow, { slug: string }> = ({ slug }, options) => {
return useQuery({
queryKey: [`protocol/${slug}`],
queryFn: async () => {
const res = await axios.get(Routes.apiProtocol(slug))
return res.data
},
...options,
})
}

export const useGetProtocolOptions: ReactQueryFunction<Schema.ProtocolsOptions[]> = (options) => {
return useQuery({
queryKey: ['protocolOptions'],
queryFn: async () => {
const res = await axios.get(Routes.apiProtocolsOptions())
return res.data
},
...options,
})
}
export * from './queries'
export * from './mutations'
7 changes: 7 additions & 0 deletions app/frontend/queries/protocols/keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const queryRoot = 'protocols'

export const queryKeys = {
protocols: [queryRoot] as const,
protocol: (slug: string) => [queryRoot, slug] as const,
protocolOptions: [queryRoot, 'options'] as const,
}
25 changes: 25 additions & 0 deletions app/frontend/queries/protocols/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { type ReactMutationFunction } from ".."
import axios from 'axios';
import { Routes } from "@/lib";
import { queryKeys } from "./keys";

export const useCreateProtocol: ReactMutationFunction<
Schema.ProtocolsFormData,
Schema.ProtocolsShow
> = (options) => {
const queryClient = useQueryClient()

return useMutation({
mutationKey: queryKeys.protocols,
mutationFn: async (data) => {
const res = await axios.post(Routes.apiProtocols(), data)
return res.data
},
...options,
onSuccess: (data, variables) => {
queryClient.invalidateQueries({ queryKey: queryKeys.protocols })
options?.onSuccess?.(data, variables)
},
})
}
27 changes: 27 additions & 0 deletions app/frontend/queries/protocols/queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { type ReactQueryFunction } from '..'
import { queryKeys } from './keys'

export const useGetProtocol: ReactQueryFunction<Schema.ProtocolsShow, { slug: string }> = ({ slug }, options) => {
return useQuery({
queryKey: queryKeys.protocol(slug),
queryFn: async () => {
const res = await axios.get(Routes.apiProtocol(slug))
return res.data
},
...options,
})
}

export const useGetProtocolOptions: ReactQueryFunction<Schema.ProtocolsOptions[]> = (options) => {
return useQuery({
queryKey: queryKeys.protocolOptions,
queryFn: async () => {
const res = await axios.get(Routes.apiProtocolsOptions())
return res.data
},
...options,
})
}
Loading

0 comments on commit 777e8c3

Please sign in to comment.