Refactored the revoke functionality for firewall clients to be more accurately represented as a delete operation. Updated the corresponding API call to use the DELETE method and modified the UI components to reflect this change, including confirmation dialogs and success messages. Adjusted tests to ensure the new delete functionality works as intended.
101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { queryOptions, useMutation, useQueryClient } from '@tanstack/react-query'
|
|
import { toast } from 'sonner'
|
|
|
|
import { apiJSON } from '@/lib/api-client'
|
|
import type {
|
|
FirewallClient,
|
|
FirewallClientsResponse,
|
|
FirewallInstallContext,
|
|
FirewallRule,
|
|
FirewallRulesResponse,
|
|
} from '@/types/api'
|
|
|
|
export const firewallKeys = {
|
|
all: ['firewall'] as const,
|
|
clients: () => [...firewallKeys.all, 'clients'] as const,
|
|
installContext: () => [...firewallKeys.all, 'install-context'] as const,
|
|
rules: (scope: string, clientId?: string) =>
|
|
[...firewallKeys.all, 'rules', scope, clientId ?? ''] as const,
|
|
}
|
|
|
|
export function firewallInstallContextQueryOptions() {
|
|
return queryOptions<FirewallInstallContext>({
|
|
queryKey: firewallKeys.installContext(),
|
|
queryFn: () => apiJSON<FirewallInstallContext>('/v1/firewall/install-context'),
|
|
staleTime: 60_000,
|
|
retry: false,
|
|
})
|
|
}
|
|
|
|
export function firewallClientsQueryOptions() {
|
|
return queryOptions<FirewallClientsResponse>({
|
|
queryKey: firewallKeys.clients(),
|
|
queryFn: () => apiJSON<FirewallClientsResponse>('/v1/firewall/clients'),
|
|
staleTime: 15_000,
|
|
})
|
|
}
|
|
|
|
export function firewallRulesQueryOptions(scope: 'tenant' | 'client', clientId?: string) {
|
|
const qs =
|
|
scope === 'client' && clientId
|
|
? `?scope=client&client_id=${encodeURIComponent(clientId)}`
|
|
: '?scope=tenant'
|
|
return queryOptions<FirewallRulesResponse>({
|
|
queryKey: firewallKeys.rules(scope, clientId),
|
|
queryFn: () => apiJSON<FirewallRulesResponse>(`/v1/firewall/rules${qs}`),
|
|
staleTime: 15_000,
|
|
})
|
|
}
|
|
|
|
export function useApproveFirewallClient() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiJSON<FirewallClient>(`/v1/firewall/clients/${id}/approve`, { method: 'POST' }),
|
|
onSuccess: () => {
|
|
toast.success('Клиент одобрен')
|
|
void qc.invalidateQueries({ queryKey: firewallKeys.clients() })
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось одобрить'),
|
|
})
|
|
}
|
|
|
|
export function useDeleteFirewallClient() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiJSON<void>(`/v1/firewall/clients/${id}`, { method: 'DELETE' }),
|
|
onSuccess: () => {
|
|
toast.success('Клиент удалён')
|
|
void qc.invalidateQueries({ queryKey: firewallKeys.clients() })
|
|
},
|
|
onError: (e) => toast.error(e instanceof Error ? e.message : 'Не удалось удалить'),
|
|
})
|
|
}
|
|
|
|
export function useCreateFirewallRule() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (body: Record<string, unknown>) =>
|
|
apiJSON<FirewallRule>('/v1/firewall/rules', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body),
|
|
}),
|
|
onSuccess: () => {
|
|
void qc.invalidateQueries({ queryKey: firewallKeys.all })
|
|
},
|
|
})
|
|
}
|
|
|
|
export function useDeleteFirewallRule() {
|
|
const qc = useQueryClient()
|
|
return useMutation({
|
|
mutationFn: (id: string) =>
|
|
apiJSON<void>(`/v1/firewall/rules/${id}`, { method: 'DELETE' }),
|
|
onSuccess: () => {
|
|
void qc.invalidateQueries({ queryKey: firewallKeys.all })
|
|
},
|
|
})
|
|
}
|