diff --git a/.gitignore b/.gitignore index e0fda05d0d4f7..20e5436e62c3f 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,4 @@ node_modules *.ticky.modules yarn-error.log +frontend/package-lock.json diff --git a/frontend/libs/console/legacy-ce/src/lib/new-components/Toasts/hasuraToast.tsx b/frontend/libs/console/legacy-ce/src/lib/new-components/Toasts/hasuraToast.tsx index 53e9eb19de2a0..fdbb3fc662b32 100644 --- a/frontend/libs/console/legacy-ce/src/lib/new-components/Toasts/hasuraToast.tsx +++ b/frontend/libs/console/legacy-ce/src/lib/new-components/Toasts/hasuraToast.tsx @@ -1,8 +1,8 @@ import clsx from 'clsx'; import { deepmerge } from 'deepmerge-ts'; -import { MouseEventHandler, PropsWithChildren, ReactNode } from 'react'; +import React, { MouseEventHandler, PropsWithChildren, ReactNode } from 'react'; import { Toast, ToastOptions, toast } from 'react-hot-toast/headless'; -import { FaTimesCircle } from 'react-icons/fa'; +import { FaTimesCircle, FaCopy } from 'react-icons/fa'; import { HtmlAnalyticsAttributes } from '../../features/Analytics'; export type ToastType = 'error' | 'success' | 'info' | 'warning'; @@ -108,6 +108,50 @@ export const hasuraToast = ({ onRemove(); }; + const extractTextFromChildren = (node: ReactNode): string => { + if (typeof node === 'string' || typeof node === 'number') { + return String(node); + } + + if (React.isValidElement(node)) { + if (node.props.children) { + if (Array.isArray(node.props.children)) { + return node.props.children + .map((child) => extractTextFromChildren(child)) + .join(''); + } + return extractTextFromChildren(node.props.children); + } + } + + if (Array.isArray(node)) { + return node.map((child) => extractTextFromChildren(child)).join(''); + } + + return ''; + }; + + const handleCopy = () => { + if (!navigator.clipboard) { + console.warn('Clipboard API not available'); + return; + } + + let copyText = ''; + if (title) copyText += `${title}\n`; + if (message) copyText += `${message}\n`; + if (children) { + const childText = extractTextFromChildren(children); + if (childText.trim()) { + copyText += `${childText.trim()}\n`; + } + } + + navigator.clipboard.writeText(copyText.trim()).catch(err => { + console.error('Failed to copy notification:', err); + }); + }; + return toast.custom( t => (