| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import { ExternalLink } from 'lucide-react'
- import { useTheme } from 'next-themes'
- import Image from 'next/image'
- import { useState } from 'react'
- import { cn, HoverCard, HoverCardContent, HoverCardTrigger, InfoIcon } from 'ui'
- import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
- import { getErrorCodeInfo } from './ErrorCodeTooltip.utils'
- import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
- import { AiAssistantDropdown } from '@/components/ui/AiAssistantDropdown'
- import { useErrorCodesQuery } from '@/data/content-api/docs-error-codes-query'
- import { Service } from '@/data/graphql/graphql'
- import { BASE_PATH } from '@/lib/constants'
- import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
- import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
- interface ErrorCodeTooltipProps {
- errorCode: string
- service?: Service
- children: React.ReactNode
- }
- export const ErrorCodeTooltip = ({ errorCode, service, children }: ErrorCodeTooltipProps) => {
- const [isOpen, setIsOpen] = useState(false)
- const { resolvedTheme } = useTheme()
- const snap = useAiAssistantStateSnapshot()
- const { openSidebar } = useSidebarManagerSnapshot()
- const { definition, docsUrl: sharedDocsUrl } = getErrorCodeInfo(errorCode, service)
- const { data, isPending } = useErrorCodesQuery(
- { code: errorCode, service },
- { enabled: isOpen && !definition }
- )
- const errors = data?.errors?.nodes?.filter((e) => !!e.message) ?? []
- const description = definition?.description ?? errors[0]?.message
- const docsUrl = sharedDocsUrl
- const buildPrompt = () => {
- const servicePart = service ? ` in Briven ${service}` : ''
- const descriptionPart = description ? `\n\nError description: ${description}` : ''
- return `I'm encountering error code \`${errorCode}\`${servicePart}.${descriptionPart}\n\nCan you explain what this error means and suggest steps to fix it?`
- }
- const handleOpenAssistant = () => {
- openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
- snap.newChat({
- name: `Fix error ${errorCode}`,
- initialMessage: buildPrompt(),
- })
- }
- return (
- <HoverCard open={isOpen} onOpenChange={setIsOpen} openDelay={200} closeDelay={100}>
- <HoverCardTrigger asChild>
- <span className="inline-flex items-center gap-1 cursor-default">
- {children}
- <InfoIcon hideBackground className="w-3.5 h-3.5 shrink-0 fill-foreground-muted" />
- </span>
- </HoverCardTrigger>
- <HoverCardContent side="top" align="center" className="w-[360px] p-0 overflow-hidden">
- <div className="flex flex-col">
- <div className="px-4 pt-3 pb-2.5 border-b border-border">
- <p className="font-mono text-xs uppercase text-foreground-light truncate max-w-[40ch]">
- {errorCode}
- </p>
- </div>
- <div className="px-4 py-3 space-y-2">
- {isPending && !definition ? (
- <div className="space-y-1.5">
- <ShimmeringLoader className="w-full" />
- <ShimmeringLoader className="w-4/5" />
- <ShimmeringLoader className="w-3/5" />
- </div>
- ) : !description ? (
- <p className="text-sm text-foreground-lighter">
- No description available for this error code.
- </p>
- ) : (
- <p className="text-sm text-foreground leading-relaxed">{description}</p>
- )}
- </div>
- <div
- className={cn(
- 'border-t border-border px-4 py-2.5 flex items-center',
- docsUrl ? 'justify-between' : 'justify-end'
- )}
- >
- {docsUrl && (
- <div className="flex items-center gap-1.5">
- <Image
- src={
- resolvedTheme?.includes('dark')
- ? `${BASE_PATH}/img/briven-dark.svg`
- : `${BASE_PATH}/img/briven-light.svg`
- }
- alt="Briven"
- height={14}
- width={72}
- />
- <span className="font-mono text-[11px] font-semibold text-brand tracking-wide">
- DOCS
- </span>
- </div>
- )}
- <AiAssistantDropdown
- showExternalAI
- label="Fix with AI"
- buildPrompt={buildPrompt}
- onOpenAssistant={handleOpenAssistant}
- telemetrySource="error_code"
- copyLabel="Copy Markdown"
- additionalDropdownItems={[
- {
- label: 'Go to Docs',
- icon: <ExternalLink size={14} />,
- href: docsUrl,
- },
- ]}
- />
- </div>
- </div>
- </HoverCardContent>
- </HoverCard>
- )
- }
|