| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import { IS_PLATFORM, useParams } from 'common'
- import saveAs from 'file-saver'
- import { ChevronDown, Copy, Download, Settings } from 'lucide-react'
- import Link from 'next/link'
- import { usePathname } from 'next/navigation'
- import { useMemo } from 'react'
- import { toast } from 'sonner'
- import {
- Button,
- copyToClipboard,
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
- KeyboardShortcut,
- } from 'ui'
- import {
- convertResultsToCSV,
- convertResultsToJSON,
- convertResultsToMarkdown,
- } from '@/components/interfaces/SQLEditor/UtilityPanel/Results.utils'
- import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
- import { useShortcut } from '@/state/shortcuts/useShortcut'
- interface DownloadResultsButtonProps {
- iconOnly?: boolean
- type?: 'text' | 'default'
- text?: string
- align?: 'start' | 'center' | 'end'
- results: any[]
- fileName: string
- enableCopyShortcuts?: boolean
- onDownloadAsCSV?: () => void
- onCopyAsMarkdown?: () => void
- onCopyAsJSON?: () => void
- onCopyAsCSV?: () => void
- }
- export const DownloadResultsButton = ({
- iconOnly = false,
- type = 'default',
- text = 'Export',
- align = 'start',
- results,
- fileName,
- enableCopyShortcuts = true,
- onDownloadAsCSV,
- onCopyAsMarkdown,
- onCopyAsJSON,
- onCopyAsCSV,
- }: DownloadResultsButtonProps) => {
- const { ref } = useParams()
- const pathname = usePathname()
- const isLogs = pathname?.includes?.('/logs') ?? false
- const isEmpty = useMemo(() => results.length === 0, [results])
- const downloadAsCSV = () => {
- const csv = convertResultsToCSV(results)
- if (!csv) {
- toast('Results are empty')
- return
- }
- const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
- saveAs(blob, `${fileName}.csv`)
- toast.success('Downloading results as CSV')
- onDownloadAsCSV?.()
- }
- const copyAsMarkdown = () => {
- const markdownData = convertResultsToMarkdown(results)
- if (!markdownData) {
- toast('Results are empty')
- return
- }
- copyToClipboard(markdownData, () => {
- toast.success('Copied Markdown to clipboard')
- onCopyAsMarkdown?.()
- })
- }
- const copyAsJSON = () => {
- const jsonData = convertResultsToJSON(results)
- if (!jsonData) {
- toast('Results are empty')
- return
- }
- copyToClipboard(jsonData, () => {
- toast.success('Copied JSON to clipboard')
- onCopyAsJSON?.()
- })
- }
- const copyAsCSV = () => {
- const csv = convertResultsToCSV(results)
- if (!csv) {
- toast('Results are empty')
- return
- }
- copyToClipboard(csv, () => {
- toast.success('Copied CSV to clipboard')
- onCopyAsCSV?.()
- })
- }
- useShortcut(SHORTCUT_IDS.RESULTS_COPY_MARKDOWN, copyAsMarkdown, {
- enabled: !isEmpty && enableCopyShortcuts,
- conflictBehavior: 'allow',
- registerInCommandMenu: true,
- })
- useShortcut(SHORTCUT_IDS.RESULTS_COPY_JSON, copyAsJSON, {
- enabled: !isEmpty && enableCopyShortcuts,
- conflictBehavior: 'allow',
- registerInCommandMenu: true,
- })
- useShortcut(SHORTCUT_IDS.RESULTS_COPY_CSV, copyAsCSV, {
- enabled: !isEmpty && enableCopyShortcuts,
- conflictBehavior: 'allow',
- registerInCommandMenu: true,
- })
- useShortcut(SHORTCUT_IDS.RESULTS_DOWNLOAD_CSV, downloadAsCSV, {
- enabled: !isEmpty,
- registerInCommandMenu: true,
- })
- return (
- <DropdownMenu>
- <DropdownMenuTrigger asChild>
- <Button
- type={type}
- icon={iconOnly ? <Download /> : undefined}
- iconRight={iconOnly ? undefined : <ChevronDown />}
- disabled={results.length === 0}
- className={iconOnly ? 'w-7' : ''}
- >
- {!iconOnly && text}
- </Button>
- </DropdownMenuTrigger>
- <DropdownMenuContent align={align} className="w-60">
- {isLogs && IS_PLATFORM && (
- <DropdownMenuItem asChild className="gap-x-2">
- <Link href={`/project/${ref}/settings/log-drains`}>
- <Settings size={14} />
- <p>Add a Log Drain</p>
- </Link>
- </DropdownMenuItem>
- )}
- <DropdownMenuItem onClick={copyAsMarkdown} className="gap-x-2">
- <Copy size={14} />
- <p>Copy as Markdown</p>
- <span className="ml-auto">
- <KeyboardShortcut keys={['Shift', 'Meta', 'm']} />
- </span>
- </DropdownMenuItem>
- <DropdownMenuItem onClick={copyAsJSON} className="gap-x-2">
- <Copy size={14} />
- <p>Copy as JSON</p>
- <span className="ml-auto">
- <KeyboardShortcut keys={['Shift', 'Meta', 'j']} />
- </span>
- </DropdownMenuItem>
- <DropdownMenuItem onClick={copyAsCSV} className="gap-x-2">
- <Copy size={14} />
- <p>Copy as CSV</p>
- <span className="ml-auto">
- <KeyboardShortcut keys={['Shift', 'Meta', 'c']} />
- </span>
- </DropdownMenuItem>
- <DropdownMenuItem className="gap-x-2" onClick={() => downloadAsCSV()}>
- <Download size={14} />
- <p>Download CSV</p>
- <span className="ml-auto">
- <KeyboardShortcut keys={['Shift', 'Meta', 'd']} />
- </span>
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- )
- }
|