Skip to content

Commit

Permalink
Merge pull request #6 from aviemet/query
Browse files Browse the repository at this point in the history
React Query
  • Loading branch information
aviemet authored Oct 3, 2024
2 parents 99780a0 + 777e8c3 commit 6bd7b40
Show file tree
Hide file tree
Showing 22 changed files with 371 additions and 193 deletions.
2 changes: 1 addition & 1 deletion app/frontend/Layouts/Providers/QueryProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface QueryProviderProps {

const queryClient = new QueryClient()

const isDev = process.env.NODE_ENV && process?.env?.NODE_ENV === 'development'
const isDev = false // process.env.NODE_ENV && process?.env?.NODE_ENV === 'development'

const QueryProvider = ({ children }: QueryProviderProps) => {
return (
Expand Down
40 changes: 2 additions & 38 deletions app/frontend/queries/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,2 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { ComboboxData } from '@mantine/core'
import { type ReactQueryFunction } from '..'

export const useGetCommand: ReactQueryFunction<Schema.CommandsShow, {slug:string}> = ({ slug }, options) => {
return useQuery({
queryKey: [`command/${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,
})
}
29 changes: 2 additions & 27 deletions app/frontend/queries/controls/index.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,2 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { ComboboxData } from '@mantine/core'
import { type ReactQueryFunction } from '..'

export const useGetControl: ReactQueryFunction<Schema.ControlsShow, { slug: string }> = ({ slug }, options) => {
return useQuery({
queryKey: [`command/${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: ['commands'],
queryFn: async () => {
const res = await axios.get(Routes.apiControls())
return res.data
},
...options,
})
}
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,
})
}
54 changes: 37 additions & 17 deletions app/frontend/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,54 @@ import {
type UseMutationResult,
} from '@tanstack/react-query'

interface LimitedQueryOptions<T> extends Omit<UseQueryOptions<T>, 'queryKey'|'queryFn'> {}
/**
* Query types
*/

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

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

export type ReactQueryFunction<T, P = undefined> =
P extends undefined
? ReactQueryFunctionBasic<T>
: P extends Record<string, string|number|string[]>
? ReactQueryFunctionWithParams<T, P>
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[]>
? ReactQueryFunctionWithParams<TData, TParams>
: never;

/**
* Mutation types
*/

interface LimitedMutationOptions<T, P> extends Omit<UseMutationOptions<T, unknown, P, unknown>, 'mutationKey'|'onSuccess'> {
onSuccess?: (data: T, variables: P) => void
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<
T,
P extends Record<string, unknown>,
M extends Record<string, unknown>
> = (
params: P,
options?: LimitedMutationOptions<T, M>
) => UseMutationResult<T, unknown, M, unknown>;
TMutationVariables,
TReturnData,
TParams = undefined,
TError = unknown
> = TParams extends undefined
? 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,
})
}
17 changes: 2 additions & 15 deletions app/frontend/queries/servers/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,2 @@
import { useQuery } from '@tanstack/react-query'
import { Routes } from '@/lib'
import axios from 'axios'
import { type ReactQueryFunction } from '..'

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

export const queryKeys = {
servers: [queryRoot] as const,
server: (slug: string) => [queryRoot, slug] as const,
}
Loading

0 comments on commit 6bd7b40

Please sign in to comment.