86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useMemo, useState } from 'react'
|
|
|
|
import type { AwoooPStatusChain } from '@/components/awooop/status-chain'
|
|
import { API_V1_URL } from '@/lib/config'
|
|
|
|
interface UseIncidentStatusChainsOptions {
|
|
incidentIds: string[]
|
|
limit?: number
|
|
projectId?: string
|
|
refreshKey?: string | number | Date | null
|
|
timeoutMs?: number
|
|
}
|
|
|
|
interface UseIncidentStatusChainsResult {
|
|
statusChains: Record<string, AwoooPStatusChain | null>
|
|
requestedIncidentIds: string[]
|
|
isLoading: boolean
|
|
}
|
|
|
|
export function useIncidentStatusChains({
|
|
incidentIds,
|
|
limit = 25,
|
|
projectId = 'awoooi',
|
|
refreshKey = null,
|
|
timeoutMs = 12000,
|
|
}: UseIncidentStatusChainsOptions): UseIncidentStatusChainsResult {
|
|
const incidentIdsKey = incidentIds.filter(Boolean).join('|')
|
|
const requestedIncidentIds = useMemo(() => {
|
|
return Array.from(new Set(incidentIdsKey ? incidentIdsKey.split('|') : [])).slice(0, limit)
|
|
}, [incidentIdsKey, limit])
|
|
const incidentKey = requestedIncidentIds.join('|')
|
|
const [statusChains, setStatusChains] = useState<Record<string, AwoooPStatusChain | null>>({})
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
|
|
useEffect(() => {
|
|
if (requestedIncidentIds.length === 0) {
|
|
setStatusChains({})
|
|
setIsLoading(false)
|
|
return
|
|
}
|
|
|
|
let active = true
|
|
const controller = new AbortController()
|
|
const timeout = window.setTimeout(() => controller.abort(), timeoutMs)
|
|
setIsLoading(true)
|
|
|
|
Promise.all(
|
|
requestedIncidentIds.map(async (incidentId): Promise<[string, AwoooPStatusChain | null]> => {
|
|
const params = new URLSearchParams({ project_id: projectId, incident_id: incidentId })
|
|
try {
|
|
const response = await fetch(`${API_V1_URL}/platform/status-chain?${params.toString()}`, {
|
|
cache: 'no-store',
|
|
signal: controller.signal,
|
|
})
|
|
if (!response.ok) return [incidentId, null]
|
|
return [incidentId, await response.json() as AwoooPStatusChain]
|
|
} catch {
|
|
return [incidentId, null]
|
|
}
|
|
})
|
|
)
|
|
.then(entries => {
|
|
if (active) setStatusChains(Object.fromEntries(entries))
|
|
})
|
|
.catch(() => {
|
|
if (active) setStatusChains({})
|
|
})
|
|
.finally(() => {
|
|
window.clearTimeout(timeout)
|
|
if (active) setIsLoading(false)
|
|
})
|
|
|
|
return () => {
|
|
active = false
|
|
window.clearTimeout(timeout)
|
|
controller.abort()
|
|
}
|
|
}, [incidentKey, projectId, requestedIncidentIds, refreshKey, timeoutMs])
|
|
|
|
return { statusChains, requestedIncidentIds, isLoading }
|
|
}
|
|
|
|
export type { UseIncidentStatusChainsOptions, UseIncidentStatusChainsResult }
|