import { forwardRef, useEffect, useMemo, useState } from 'react'; import { Box, Flex, Alert, Tooltip, ButtonGroup, AccordionItem, AccordionPanel, AccordionButton, } from '@chakra-ui/react'; import { BsLightningFill } from '@meronex/icons/bs'; import useAxios from 'axios-hooks'; import { startCase } from 'lodash'; import { BGPTable, Countdown, CopyButton, RequeryButton, TextOutput, If } from '~/components'; import { useColorValue, useConfig, useMobile } from '~/context'; import { useStrf, useTableToString } from '~/hooks'; import { FormattedError } from './error'; import { ResultHeader } from './header'; import type { TAccordionHeaderWrapper, TResult } from './types'; type TErrorLevels = 'success' | 'warning' | 'error'; const AccordionHeaderWrapper = (props: TAccordionHeaderWrapper) => { const { hoverBg, ...rest } = props; return ( ); }; export const Result = forwardRef((props, ref) => { const { index, device, timeout, queryVrf, queryType, queryTarget, setComplete, queryLocation, resultsComplete, } = props; const { web, cache, messages } = useConfig(); const isMobile = useMobile(); const color = useColorValue('black', 'white'); const scrollbar = useColorValue('blackAlpha.300', 'whiteAlpha.300'); const scrollbarHover = useColorValue('blackAlpha.400', 'whiteAlpha.400'); const scrollbarBg = useColorValue('blackAlpha.50', 'whiteAlpha.50'); let [{ data, loading, error }, refetch] = useAxios( { url: '/api/query/', method: 'post', data: { query_vrf: queryVrf, query_type: queryType, query_target: queryTarget, query_location: queryLocation, }, timeout, }, { useCache: false }, ); const cacheLabel = useStrf(web.text.cache_icon, { time: data?.timestamp }, [data?.timestamp]); const [isOpen, setOpen] = useState(false); const [hasOverride, setOverride] = useState(false); const handleToggle = () => { setOpen(!isOpen); setOverride(true); }; const errorKw = (error && error.response?.data?.keywords) || []; let errorMsg; if (error && error.response?.data?.output) { errorMsg = error.response.data.output; } else if (error && error.message.startsWith('timeout')) { errorMsg = messages.request_timeout; } else if (error?.response?.statusText) { errorMsg = startCase(error.response.statusText); } else if (error && error.message) { errorMsg = startCase(error.message); } else { errorMsg = messages.general; } error && console.error(error); const getErrorLevel = (): TErrorLevels => { const statusMap = { success: 'success', warning: 'warning', error: 'warning', danger: 'error', } as { [k in TResponseLevel]: 'success' | 'warning' | 'error' }; let e: TErrorLevels = 'error'; if (error?.response?.data?.level) { const idx = error.response.data.level as TResponseLevel; e = statusMap[idx]; } return e; }; const errorLevel = useMemo(() => getErrorLevel(), [error]); const tableComponent = useMemo(() => typeof queryType.match(/^bgp_\w+$/) !== null, [queryType]); let copyValue = data?.output; const formatData = useTableToString(queryTarget, data, [data.format]); if (data?.format === 'application/json') { copyValue = formatData(); } if (error) { copyValue = errorMsg; } useEffect(() => { !loading && resultsComplete === null && setComplete(index); }, [loading, resultsComplete]); useEffect(() => { resultsComplete === index && !hasOverride && setOpen(true); }, [resultsComplete, index]); return ( {data?.output} {data?.output} {error && ( )} ); });