563 lines
18 KiB
TypeScript
563 lines
18 KiB
TypeScript
|
|
'use client'
|
||
|
|
|
||
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||
|
|
import {
|
||
|
|
getEnterpriseClients,
|
||
|
|
getEnterpriseClient,
|
||
|
|
createEnterpriseClient,
|
||
|
|
updateEnterpriseClient,
|
||
|
|
deleteEnterpriseClient,
|
||
|
|
getClientServers,
|
||
|
|
getClientServer,
|
||
|
|
addClientServer,
|
||
|
|
updateClientServer,
|
||
|
|
removeClientServer,
|
||
|
|
testServerPortainerConnection,
|
||
|
|
performServerAction,
|
||
|
|
requestVerificationCode,
|
||
|
|
getErrorRules,
|
||
|
|
createErrorRule,
|
||
|
|
updateErrorRule,
|
||
|
|
deleteErrorRule,
|
||
|
|
getDetectedErrors,
|
||
|
|
acknowledgeError,
|
||
|
|
getClientStats,
|
||
|
|
getServerStats,
|
||
|
|
collectServerStats,
|
||
|
|
getServerContainers,
|
||
|
|
getContainer,
|
||
|
|
getContainerLogs,
|
||
|
|
performContainerAction,
|
||
|
|
removeContainer,
|
||
|
|
getErrorDashboard,
|
||
|
|
getContainerEvents,
|
||
|
|
acknowledgeContainerEvents,
|
||
|
|
getErrorSummary,
|
||
|
|
getNotificationSettings,
|
||
|
|
updateNotificationSettings,
|
||
|
|
} from '@/lib/api/admin'
|
||
|
|
import type { StatsRange, ContainerEventFilters, UpdateNotificationSettingsPayload } from '@/lib/api/admin'
|
||
|
|
import type {
|
||
|
|
CreateEnterpriseClientPayload,
|
||
|
|
UpdateEnterpriseClientPayload,
|
||
|
|
AddServerPayload,
|
||
|
|
UpdateServerPayload,
|
||
|
|
ServerActionPayload,
|
||
|
|
CreateErrorRulePayload,
|
||
|
|
UpdateErrorRulePayload,
|
||
|
|
ErrorFilters,
|
||
|
|
} from '@/types/api'
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Query Keys
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export const enterpriseClientKeys = {
|
||
|
|
all: ['enterprise-clients'] as const,
|
||
|
|
lists: () => [...enterpriseClientKeys.all, 'list'] as const,
|
||
|
|
list: () => [...enterpriseClientKeys.lists()] as const,
|
||
|
|
details: () => [...enterpriseClientKeys.all, 'detail'] as const,
|
||
|
|
detail: (id: string) => [...enterpriseClientKeys.details(), id] as const,
|
||
|
|
servers: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'servers'] as const,
|
||
|
|
server: (clientId: string, serverId: string) => [...enterpriseClientKeys.servers(clientId), serverId] as const,
|
||
|
|
serverStats: (clientId: string, serverId: string, range: StatsRange) =>
|
||
|
|
[...enterpriseClientKeys.server(clientId, serverId), 'stats', range] as const,
|
||
|
|
clientStats: (clientId: string, range: StatsRange) =>
|
||
|
|
[...enterpriseClientKeys.detail(clientId), 'stats', range] as const,
|
||
|
|
errorRules: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'error-rules'] as const,
|
||
|
|
errors: (clientId: string, filters?: ErrorFilters) => [...enterpriseClientKeys.detail(clientId), 'errors', filters] as const,
|
||
|
|
containers: (clientId: string, serverId: string) =>
|
||
|
|
[...enterpriseClientKeys.server(clientId, serverId), 'containers'] as const,
|
||
|
|
container: (clientId: string, serverId: string, containerId: string) =>
|
||
|
|
[...enterpriseClientKeys.containers(clientId, serverId), containerId] as const,
|
||
|
|
containerLogs: (clientId: string, serverId: string, containerId: string, tail: number) =>
|
||
|
|
[...enterpriseClientKeys.container(clientId, serverId, containerId), 'logs', tail] as const,
|
||
|
|
// Error tracking keys
|
||
|
|
errorDashboard: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'error-dashboard'] as const,
|
||
|
|
containerEvents: (clientId: string, filters?: ContainerEventFilters) =>
|
||
|
|
[...enterpriseClientKeys.detail(clientId), 'container-events', filters] as const,
|
||
|
|
errorSummary: () => [...enterpriseClientKeys.all, 'error-summary'] as const,
|
||
|
|
// Notification settings key
|
||
|
|
notifications: (clientId: string) => [...enterpriseClientKeys.detail(clientId), 'notifications'] as const,
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Client Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useEnterpriseClients() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.list(),
|
||
|
|
queryFn: getEnterpriseClients,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useEnterpriseClient(id: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.detail(id),
|
||
|
|
queryFn: () => getEnterpriseClient(id),
|
||
|
|
enabled: !!id,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCreateEnterpriseClient() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (data: CreateEnterpriseClientPayload) => createEnterpriseClient(data),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdateEnterpriseClient() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ id, data }: { id: string; data: UpdateEnterpriseClientPayload }) =>
|
||
|
|
updateEnterpriseClient(id, data),
|
||
|
|
onSuccess: (_, { id }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(id) })
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeleteEnterpriseClient() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (id: string) => deleteEnterpriseClient(id),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.lists() })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Server Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useClientServers(clientId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.servers(clientId),
|
||
|
|
queryFn: () => getClientServers(clientId),
|
||
|
|
enabled: !!clientId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useClientServer(clientId: string, serverId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.server(clientId, serverId),
|
||
|
|
queryFn: () => getClientServer(clientId, serverId),
|
||
|
|
enabled: !!clientId && !!serverId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useAddServerToClient() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, data }: { clientId: string; data: AddServerPayload }) =>
|
||
|
|
addClientServer(clientId, data),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdateClientServer() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
data,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
data: UpdateServerPayload
|
||
|
|
}) => updateClientServer(clientId, serverId, data),
|
||
|
|
onSuccess: (_, { clientId, serverId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.server(clientId, serverId) })
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useRemoveServerFromClient() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, serverId }: { clientId: string; serverId: string }) =>
|
||
|
|
removeClientServer(clientId, serverId),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useTestPortainerConnection() {
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
credentials,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
credentials: { portainerUrl: string; portainerUsername: string; portainerPassword: string }
|
||
|
|
}) => testServerPortainerConnection(clientId, serverId, credentials),
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Server Action Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useServerAction() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
action,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
action: ServerActionPayload
|
||
|
|
}) => performServerAction(clientId, serverId, action),
|
||
|
|
onSuccess: (_, { clientId, serverId }) => {
|
||
|
|
// Refresh server status after action
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.server(clientId, serverId) })
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.servers(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useRequestVerificationCode() {
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
action,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
action: 'WIPE' | 'REINSTALL'
|
||
|
|
}) => requestVerificationCode(clientId, serverId, action),
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Error Rule Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useErrorRules(clientId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.errorRules(clientId),
|
||
|
|
queryFn: () => getErrorRules(clientId),
|
||
|
|
enabled: !!clientId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCreateErrorRule() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, data }: { clientId: string; data: CreateErrorRulePayload }) =>
|
||
|
|
createErrorRule(clientId, data),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdateErrorRule() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
ruleId,
|
||
|
|
data,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
ruleId: string
|
||
|
|
data: UpdateErrorRulePayload
|
||
|
|
}) => updateErrorRule(clientId, ruleId, data),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useDeleteErrorRule() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, ruleId }: { clientId: string; ruleId: string }) =>
|
||
|
|
deleteErrorRule(clientId, ruleId),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.errorRules(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Detected Error Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useDetectedErrors(clientId: string, filters?: ErrorFilters) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.errors(clientId, filters),
|
||
|
|
queryFn: () => getDetectedErrors(clientId, filters),
|
||
|
|
enabled: !!clientId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useAcknowledgeError() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, errorId }: { clientId: string; errorId: string }) =>
|
||
|
|
acknowledgeError(clientId, errorId),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
// Invalidate all error queries for this client
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.detail(clientId),
|
||
|
|
predicate: (query) => {
|
||
|
|
const key = query.queryKey
|
||
|
|
return Array.isArray(key) && key.includes('errors')
|
||
|
|
},
|
||
|
|
})
|
||
|
|
// Also refresh the client detail to update error count
|
||
|
|
queryClient.invalidateQueries({ queryKey: enterpriseClientKeys.detail(clientId) })
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Stats Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useClientStatsOverview(clientId: string, range: StatsRange = '24h') {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.clientStats(clientId, range),
|
||
|
|
queryFn: () => getClientStats(clientId, range),
|
||
|
|
enabled: !!clientId,
|
||
|
|
refetchInterval: 60000, // Refresh every minute
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useServerStatsHistory(
|
||
|
|
clientId: string,
|
||
|
|
serverId: string,
|
||
|
|
range: StatsRange = '24h'
|
||
|
|
) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.serverStats(clientId, serverId, range),
|
||
|
|
queryFn: () => getServerStats(clientId, serverId, range),
|
||
|
|
enabled: !!clientId && !!serverId,
|
||
|
|
refetchInterval: 30000, // Refresh every 30 seconds
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useCollectServerStats() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, serverId }: { clientId: string; serverId: string }) =>
|
||
|
|
collectServerStats(clientId, serverId),
|
||
|
|
onSuccess: (_, { clientId, serverId }) => {
|
||
|
|
// Invalidate all stats queries for this server
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.server(clientId, serverId),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Container Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useServerContainers(clientId: string, serverId: string, all: boolean = true) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.containers(clientId, serverId),
|
||
|
|
queryFn: () => getServerContainers(clientId, serverId, all),
|
||
|
|
enabled: !!clientId && !!serverId,
|
||
|
|
refetchInterval: 10000, // Refresh every 10 seconds
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useContainer(clientId: string, serverId: string, containerId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.container(clientId, serverId, containerId),
|
||
|
|
queryFn: () => getContainer(clientId, serverId, containerId),
|
||
|
|
enabled: !!clientId && !!serverId && !!containerId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useContainerLogs(
|
||
|
|
clientId: string,
|
||
|
|
serverId: string,
|
||
|
|
containerId: string,
|
||
|
|
tail: number = 500
|
||
|
|
) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.containerLogs(clientId, serverId, containerId, tail),
|
||
|
|
queryFn: () => getContainerLogs(clientId, serverId, containerId, tail),
|
||
|
|
enabled: !!clientId && !!serverId && !!containerId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useContainerAction() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
containerId,
|
||
|
|
action,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
containerId: string
|
||
|
|
action: 'start' | 'stop' | 'restart'
|
||
|
|
}) => performContainerAction(clientId, serverId, containerId, action),
|
||
|
|
onSuccess: (_, { clientId, serverId }) => {
|
||
|
|
// Invalidate container list to refresh status
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.containers(clientId, serverId),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useRemoveContainer() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
serverId,
|
||
|
|
containerId,
|
||
|
|
force,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
serverId: string
|
||
|
|
containerId: string
|
||
|
|
force?: boolean
|
||
|
|
}) => removeContainer(clientId, serverId, containerId, force),
|
||
|
|
onSuccess: (_, { clientId, serverId }) => {
|
||
|
|
// Invalidate container list
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.containers(clientId, serverId),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Error Dashboard Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useErrorDashboard(clientId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.errorDashboard(clientId),
|
||
|
|
queryFn: () => getErrorDashboard(clientId),
|
||
|
|
enabled: !!clientId,
|
||
|
|
refetchInterval: 60000, // Refresh every minute
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Container Events Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useContainerEvents(clientId: string, filters?: ContainerEventFilters) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.containerEvents(clientId, filters),
|
||
|
|
queryFn: () => getContainerEvents(clientId, filters),
|
||
|
|
enabled: !!clientId,
|
||
|
|
refetchInterval: 30000, // Refresh every 30 seconds
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useAcknowledgeContainerEvents() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ clientId, eventIds }: { clientId: string; eventIds: string[] }) =>
|
||
|
|
acknowledgeContainerEvents(clientId, eventIds),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
// Invalidate container events queries for this client
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.detail(clientId),
|
||
|
|
predicate: (query) => {
|
||
|
|
const key = query.queryKey
|
||
|
|
return Array.isArray(key) && key.includes('container-events')
|
||
|
|
},
|
||
|
|
})
|
||
|
|
// Also refresh the error dashboard
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.errorDashboard(clientId),
|
||
|
|
})
|
||
|
|
// Also refresh the global error summary
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.errorSummary(),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// All Clients Error Summary Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useAllClientsErrorSummary() {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.errorSummary(),
|
||
|
|
queryFn: getErrorSummary,
|
||
|
|
refetchInterval: 60000, // Refresh every minute
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Notification Settings Hooks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
export function useNotificationSettings(clientId: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: enterpriseClientKeys.notifications(clientId),
|
||
|
|
queryFn: () => getNotificationSettings(clientId),
|
||
|
|
enabled: !!clientId,
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
export function useUpdateNotificationSettings() {
|
||
|
|
const queryClient = useQueryClient()
|
||
|
|
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({
|
||
|
|
clientId,
|
||
|
|
data,
|
||
|
|
}: {
|
||
|
|
clientId: string
|
||
|
|
data: UpdateNotificationSettingsPayload
|
||
|
|
}) => updateNotificationSettings(clientId, data),
|
||
|
|
onSuccess: (_, { clientId }) => {
|
||
|
|
queryClient.invalidateQueries({
|
||
|
|
queryKey: enterpriseClientKeys.notifications(clientId),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|