CI / changes (push) Successful in 9s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 52s
CI / go (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / release (push) Successful in 4m16s
Updated multiple components to replace DataGridShell with DataGridSection, integrating search functionality and improved data handling. This change enhances user experience by providing a consistent interface across various grids, including AccessApiKeysGrid, DashboardRecentJobsGrid, and others. Additionally, introduced global filtering capabilities to streamline data retrieval and presentation, ensuring a more efficient user interaction with the data grids.
132 lines
4.1 KiB
TypeScript
132 lines
4.1 KiB
TypeScript
import { queryOptions, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
import { toast } from 'sonner'
|
|
|
|
import { apiJSON, apiMutate } from '@/lib/api-client'
|
|
import type {
|
|
BgpPeerCreate,
|
|
BgpPeerPatch,
|
|
BgpSpeakerCreate,
|
|
BgpSpeakerPatch,
|
|
BirdStatus,
|
|
PeerRow,
|
|
PeersResponse,
|
|
SpeakerRow,
|
|
SpeakersResponse,
|
|
} from '@/types/api'
|
|
|
|
export const NETWORK_AUTO_REFRESH_MS = 30_000
|
|
|
|
export const networkKeys = {
|
|
all: ['network'] as const,
|
|
peers: () => [...networkKeys.all, 'peers'] as const,
|
|
speakers: () => [...networkKeys.all, 'speakers'] as const,
|
|
bird: () => [...networkKeys.all, 'bird'] as const,
|
|
}
|
|
|
|
export function networkPeersQueryOptions() {
|
|
return queryOptions<PeersResponse>({
|
|
queryKey: networkKeys.peers(),
|
|
queryFn: () => apiJSON<PeersResponse>('/v1/peers?limit=200&live=1'),
|
|
staleTime: 15_000,
|
|
})
|
|
}
|
|
|
|
export function networkSpeakersQueryOptions() {
|
|
return queryOptions<SpeakersResponse>({
|
|
queryKey: networkKeys.speakers(),
|
|
queryFn: () => apiJSON<SpeakersResponse>('/v1/speakers?limit=200&live=1'),
|
|
staleTime: 15_000,
|
|
})
|
|
}
|
|
|
|
export function networkBirdQueryOptions() {
|
|
return queryOptions<BirdStatus>({
|
|
queryKey: networkKeys.bird(),
|
|
queryFn: () => apiJSON<BirdStatus>('/v1/bird/status'),
|
|
staleTime: 15_000,
|
|
})
|
|
}
|
|
|
|
function invalidateNetwork(qc: ReturnType<typeof useQueryClient>) {
|
|
void qc.invalidateQueries({ queryKey: networkKeys.all })
|
|
void qc.invalidateQueries({ queryKey: ['overview'] })
|
|
}
|
|
|
|
export function useCreatePeerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (body: BgpPeerCreate) =>
|
|
apiMutate<PeerRow>('/v1/peers', 'POST', body, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Пир создан')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось создать пира'),
|
|
})
|
|
}
|
|
|
|
export function useUpdatePeerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: ({ id, body }: { id: string; body: BgpPeerPatch }) =>
|
|
apiMutate<PeerRow>(`/v1/peers/${id}`, 'PATCH', body, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Пир обновлён')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось обновить пира'),
|
|
})
|
|
}
|
|
|
|
export function useDeletePeerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiMutate(`/v1/peers/${id}`, 'DELETE', undefined, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Пир удалён')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось удалить пира'),
|
|
})
|
|
}
|
|
|
|
export function useCreateSpeakerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (body: BgpSpeakerCreate) =>
|
|
apiMutate<SpeakerRow>('/v1/speakers', 'POST', body, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Спикер создан')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось создать спикера'),
|
|
})
|
|
}
|
|
|
|
export function useUpdateSpeakerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: ({ id, body }: { id: string; body: BgpSpeakerPatch }) =>
|
|
apiMutate<SpeakerRow>(`/v1/speakers/${id}`, 'PATCH', body, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Спикер обновлён')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось обновить спикера'),
|
|
})
|
|
}
|
|
|
|
export function useDeleteSpeakerMutation() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiMutate(`/v1/speakers/${id}`, 'DELETE', undefined, { idempotent: false }),
|
|
onSuccess: () => {
|
|
toast.success('Спикер удалён')
|
|
invalidateNetwork(qc)
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось удалить спикера'),
|
|
})
|
|
}
|