import { type RefObject } from 'react' import { Admonition } from 'ui-patterns/admonition' import CopyButton from '@/components/ui/CopyButton' import { BASE_PATH } from '@/lib/constants' interface CopyPromptAdmonitionProps { stepsContainerRef: RefObject } export function CopyPromptAdmonition({ stepsContainerRef }: CopyPromptAdmonitionProps) { const normalizeTextLines = (value: string) => { return value .split('\n') .map((line) => line.trim()) .filter(Boolean) .join('\n') } const getStepTextContent = (contentElement: HTMLElement) => { const clone = contentElement.cloneNode(true) as HTMLElement clone .querySelectorAll('pre, button, svg, input, textarea, select, [aria-hidden="true"]') .forEach((element) => { element.remove() }) clone.querySelectorAll('p, div').forEach((el) => { el.appendChild(document.createTextNode('\n')) }) const text = clone.textContent ?? '' return normalizeTextLines(text) } const getStepCodeSnippets = (contentElement: HTMLElement) => { const snippets: Array<{ label: string; snippet: string }> = [] const seen = new Set() const addSnippet = (label: string, snippet: string) => { if (!snippet || seen.has(snippet)) return seen.add(snippet) snippets.push({ label, snippet }) } const tabContents = Array.from( contentElement.querySelectorAll('[data-connect-tab-content]') ) as HTMLElement[] tabContents.forEach((tabContent) => { const label = tabContent.getAttribute('data-tab-label') || 'Code' const tabSnippets = Array.from(tabContent.querySelectorAll('pre')) .map((pre) => pre.textContent?.trim()) .filter((snippet): snippet is string => Boolean(snippet)) if (tabSnippets.length === 0) { const inlineSnippets = Array.from(tabContent.querySelectorAll('code')) .filter((code) => !code.closest('pre') && code.closest('.font-mono')) .map((code) => code.textContent?.trim()) .filter((snippet): snippet is string => Boolean(snippet)) inlineSnippets.forEach((snippet, index) => { const inlineLabel = inlineSnippets.length > 1 ? `${label} (part ${index + 1})` : label addSnippet(inlineLabel, snippet) }) return } tabSnippets.forEach((snippet, index) => { const tabLabel = tabSnippets.length > 1 ? `${label} (part ${index + 1})` : label addSnippet(tabLabel, snippet) }) }) contentElement.querySelectorAll('pre').forEach((pre) => { if (pre.closest('[data-connect-tab-content]')) return const snippet = pre.textContent?.trim() if (snippet) addSnippet('Code', snippet) }) contentElement.querySelectorAll('code').forEach((code) => { if (code.closest('pre')) return if (code.closest('[data-connect-tab-content]')) return if (!code.closest('.font-mono')) return const snippet = code.textContent?.trim() if (snippet) addSnippet('Code', snippet) }) return snippets } const handleCopyPrompt = () => { const stepElements = stepsContainerRef.current?.querySelectorAll('[data-connect-step]') if (!stepElements?.length) return '' const promptContent = Array.from(stepElements) .map((stepElement, index) => { const title = stepElement.getAttribute('data-step-title') ?? `Step ${index + 1}` const description = stepElement.getAttribute('data-step-description') ?? '' const contentElement = stepElement.querySelector( '[data-step-content]' ) as HTMLElement | null const details = contentElement ? getStepTextContent(contentElement) : '' const codeSnippets = contentElement ? getStepCodeSnippets(contentElement) : [] const sections = [ `${index + 1}. ${title}`, description, details ? `Details:\n${details}` : null, codeSnippets.length ? `Code:\n${codeSnippets .map(({ label, snippet }) => `File: ${label}\n\`\`\`\n${snippet}\n\`\`\``) .join('\n\n')}` : null, ].filter(Boolean) return sections.join('\n') }) .join('\n\n') return promptContent } return ( } >
Briven Grafana Briven Grafana

Give your agent everything it needs

) }