| import { Artifact } from '@/components/create-artifact'; | |
| import { | |
| CopyIcon, | |
| LineChartIcon, | |
| RedoIcon, | |
| SparklesIcon, | |
| UndoIcon, | |
| } from '@/components/icons'; | |
| import { SpreadsheetEditor } from '@/components/sheet-editor'; | |
| import { parse, unparse } from 'papaparse'; | |
| import { toast } from 'sonner'; | |
| type Metadata = any; | |
| export const sheetArtifact = new Artifact<'sheet', Metadata>({ | |
| kind: 'sheet', | |
| description: 'Useful for working with spreadsheets', | |
| initialize: async () => {}, | |
| onStreamPart: ({ setArtifact, streamPart }) => { | |
| if (streamPart.type === 'data-sheetDelta') { | |
| setArtifact((draftArtifact) => ({ | |
| ...draftArtifact, | |
| content: streamPart.data, | |
| isVisible: true, | |
| status: 'streaming', | |
| })); | |
| } | |
| }, | |
| content: ({ | |
| content, | |
| currentVersionIndex, | |
| isCurrentVersion, | |
| onSaveContent, | |
| status, | |
| }) => { | |
| return ( | |
| <SpreadsheetEditor | |
| content={content} | |
| currentVersionIndex={currentVersionIndex} | |
| isCurrentVersion={isCurrentVersion} | |
| saveContent={onSaveContent} | |
| status={status} | |
| /> | |
| ); | |
| }, | |
| actions: [ | |
| { | |
| icon: <UndoIcon size={18} />, | |
| description: 'View Previous version', | |
| onClick: ({ handleVersionChange }) => { | |
| handleVersionChange('prev'); | |
| }, | |
| isDisabled: ({ currentVersionIndex }) => { | |
| if (currentVersionIndex === 0) { | |
| return true; | |
| } | |
| return false; | |
| }, | |
| }, | |
| { | |
| icon: <RedoIcon size={18} />, | |
| description: 'View Next version', | |
| onClick: ({ handleVersionChange }) => { | |
| handleVersionChange('next'); | |
| }, | |
| isDisabled: ({ isCurrentVersion }) => { | |
| if (isCurrentVersion) { | |
| return true; | |
| } | |
| return false; | |
| }, | |
| }, | |
| { | |
| icon: <CopyIcon />, | |
| description: 'Copy as .csv', | |
| onClick: ({ content }) => { | |
| const parsed = parse<string[]>(content, { skipEmptyLines: true }); | |
| const nonEmptyRows = parsed.data.filter((row) => | |
| row.some((cell) => cell.trim() !== ''), | |
| ); | |
| const cleanedCsv = unparse(nonEmptyRows); | |
| navigator.clipboard.writeText(cleanedCsv); | |
| toast.success('Copied csv to clipboard!'); | |
| }, | |
| }, | |
| ], | |
| toolbar: [ | |
| { | |
| description: 'Format and clean data', | |
| icon: <SparklesIcon />, | |
| onClick: ({ sendMessage }) => { | |
| sendMessage({ | |
| role: 'user', | |
| parts: [ | |
| { type: 'text', text: 'Can you please format and clean the data?' }, | |
| ], | |
| }); | |
| }, | |
| }, | |
| { | |
| description: 'Analyze and visualize data', | |
| icon: <LineChartIcon />, | |
| onClick: ({ sendMessage }) => { | |
| sendMessage({ | |
| role: 'user', | |
| parts: [ | |
| { | |
| type: 'text', | |
| text: 'Can you please analyze and visualize the data by creating a new code artifact in python?', | |
| }, | |
| ], | |
| }); | |
| }, | |
| }, | |
| ], | |
| }); | |