DownloadSnippetModal.tsx133 lines · main
| 1 | import type { ModalProps } from '@ui/components/Modal/Modal' |
| 2 | import { snakeCase } from 'lodash' |
| 3 | import { ExternalLink } from 'lucide-react' |
| 4 | import Link from 'next/link' |
| 5 | import { useState } from 'react' |
| 6 | import { Button, Modal, Tabs } from 'ui' |
| 7 | import { CodeBlock } from 'ui-patterns/CodeBlock' |
| 8 | |
| 9 | import { Markdown } from '../Markdown' |
| 10 | import { |
| 11 | generateFileCliCommand, |
| 12 | generateMigrationCliCommand, |
| 13 | generateSeedCliCommand, |
| 14 | } from './SQLEditor.utils' |
| 15 | import { TwoOptionToggle } from '@/components/ui/TwoOptionToggle' |
| 16 | import { DOCS_URL } from '@/lib/constants' |
| 17 | import { useSqlEditorV2StateSnapshot } from '@/state/sql-editor-v2' |
| 18 | |
| 19 | export interface DownloadSnippetModalProps extends ModalProps { |
| 20 | id: string |
| 21 | } |
| 22 | |
| 23 | const DownloadSnippetModal = ({ id, ...props }: DownloadSnippetModalProps) => { |
| 24 | const snapV2 = useSqlEditorV2StateSnapshot() |
| 25 | |
| 26 | const snippet = snapV2.snippets[id]?.snippet |
| 27 | const migrationName = snakeCase(snippet?.name) |
| 28 | |
| 29 | const [selectedView, setSelectedView] = useState<'CLI' | 'NPM'>('CLI') |
| 30 | |
| 31 | const SNIPPETS = [ |
| 32 | { |
| 33 | id: 'migration', |
| 34 | label: 'Migration', |
| 35 | title: 'Download as migration', |
| 36 | description: `Download the snippet in a new migration named \`${migrationName}\``, |
| 37 | cli: generateMigrationCliCommand(id, migrationName), |
| 38 | npm: generateMigrationCliCommand(id, migrationName, true), |
| 39 | }, |
| 40 | { |
| 41 | id: 'seed', |
| 42 | label: 'Seed file', |
| 43 | title: 'Download as seed file', |
| 44 | description: |
| 45 | 'If your query consists of sample data, append the snippet to the end of `briven/seed.sql`', |
| 46 | cli: generateSeedCliCommand(id), |
| 47 | npm: generateSeedCliCommand(id, true), |
| 48 | }, |
| 49 | { |
| 50 | id: 'sql', |
| 51 | label: 'SQL file', |
| 52 | title: 'Download as SQL file', |
| 53 | description: `Download the snippet directly into a new SQL file named \`${migrationName}.sql\``, |
| 54 | cli: generateFileCliCommand(id, migrationName), |
| 55 | npm: generateFileCliCommand(id, migrationName, true), |
| 56 | }, |
| 57 | ] |
| 58 | |
| 59 | return ( |
| 60 | <Modal |
| 61 | hideFooter |
| 62 | showCloseButton |
| 63 | size="xlarge" |
| 64 | header={<p>Download snippet as local migration file via the Briven CLI.</p>} |
| 65 | {...props} |
| 66 | > |
| 67 | <div className="flex flex-col items-start justify-between gap-4 relative pt-2"> |
| 68 | <Tabs type="underlined" listClassNames="pl-5"> |
| 69 | {SNIPPETS.map((snippet) => { |
| 70 | return ( |
| 71 | <Tabs.Panel key={snippet.id} id={snippet.id} label={snippet.label}> |
| 72 | <Modal.Content className="py-0!"> |
| 73 | <div className="flex items-center justify-between mb-3"> |
| 74 | <div className="flex flex-col gap-y-1"> |
| 75 | <p className="text-base">{snippet.title}</p> |
| 76 | <Markdown |
| 77 | className="text-sm text-scale-1000 [&>p>code]:break-normal!" |
| 78 | content={snippet.description} |
| 79 | /> |
| 80 | </div> |
| 81 | <TwoOptionToggle |
| 82 | width={50} |
| 83 | options={['CLI', 'NPM']} |
| 84 | activeOption={selectedView} |
| 85 | borderOverride="border-muted" |
| 86 | onClickOption={() => |
| 87 | selectedView === 'CLI' ? setSelectedView('NPM') : setSelectedView('CLI') |
| 88 | } |
| 89 | /> |
| 90 | </div> |
| 91 | <pre> |
| 92 | <CodeBlock |
| 93 | language="bash" |
| 94 | className="language-bash prose dark:prose-dark max-w-none" |
| 95 | > |
| 96 | {selectedView === 'CLI' ? snippet.cli : snippet.npm} |
| 97 | </CodeBlock> |
| 98 | </pre> |
| 99 | </Modal.Content> |
| 100 | </Tabs.Panel> |
| 101 | ) |
| 102 | })} |
| 103 | </Tabs> |
| 104 | <Modal.Content className="w-full flex items-center justify-between pt-0"> |
| 105 | <p className="text-xs text-lighter">Run this command from your project directory</p> |
| 106 | <div className="flex justify-between items-center gap-x-2"> |
| 107 | <Button asChild type="default" icon={<ExternalLink strokeWidth={1.5} />}> |
| 108 | <Link |
| 109 | href={`${DOCS_URL}/guides/deployment/database-migrations`} |
| 110 | target="_blank" |
| 111 | rel="noreferrer" |
| 112 | > |
| 113 | About migrations |
| 114 | </Link> |
| 115 | </Button> |
| 116 | |
| 117 | <Button asChild type="default" icon={<ExternalLink strokeWidth={1.5} />}> |
| 118 | <Link |
| 119 | href={`${DOCS_URL}/guides/cli/local-development`} |
| 120 | target="_blank" |
| 121 | rel="noreferrer" |
| 122 | > |
| 123 | About CLI |
| 124 | </Link> |
| 125 | </Button> |
| 126 | </div> |
| 127 | </Modal.Content> |
| 128 | </div> |
| 129 | </Modal> |
| 130 | ) |
| 131 | } |
| 132 | |
| 133 | export default DownloadSnippetModal |