mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
🚀 feat: Artifact Editing & Downloads (#5428)
* refactor: expand container * chore: bump @codesandbox/sandpack-react to latest * WIP: first pass, show editor * feat: implement ArtifactCodeEditor and ArtifactTabs components for enhanced artifact management * refactor: fileKey * refactor: auto scrolling code editor and add messageId to artifact * feat: first pass, editing artifact * feat: first pass, robust artifact replacement * fix: robust artifact replacement & re-render when expected * feat: Download Artifacts * refactor: improve artifact editing UX * fix: layout shift of new download button * fix: enhance missing output checks and logging in StreamRunManager
This commit is contained in:
parent
87383fec27
commit
ed57bb4711
34 changed files with 1156 additions and 237 deletions
54
client/src/components/Artifacts/DownloadArtifact.tsx
Normal file
54
client/src/components/Artifacts/DownloadArtifact.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Download } from 'lucide-react';
|
||||
import type { Artifact } from '~/common';
|
||||
import useArtifactProps from '~/hooks/Artifacts/useArtifactProps';
|
||||
import { useEditorContext } from '~/Providers';
|
||||
import { CheckMark } from '~/components/svg';
|
||||
import { useLocalize } from '~/hooks';
|
||||
|
||||
const DownloadArtifact = ({
|
||||
artifact,
|
||||
className = '',
|
||||
}: {
|
||||
artifact: Artifact;
|
||||
className?: string;
|
||||
}) => {
|
||||
const localize = useLocalize();
|
||||
const { currentCode } = useEditorContext();
|
||||
const [isDownloaded, setIsDownloaded] = useState(false);
|
||||
const { fileKey: fileName } = useArtifactProps({ artifact });
|
||||
|
||||
const handleDownload = () => {
|
||||
try {
|
||||
const content = currentCode ?? artifact.content ?? '';
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
const blob = new Blob([content], { type: 'text/plain' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
setIsDownloaded(true);
|
||||
setTimeout(() => setIsDownloaded(false), 3000);
|
||||
} catch (error) {
|
||||
console.error('Download failed:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
className={`mr-2 text-text-secondary ${className}`}
|
||||
onClick={handleDownload}
|
||||
aria-label={localize('com_ui_download_artifact')}
|
||||
>
|
||||
{isDownloaded ? <CheckMark className="h-4 w-4" /> : <Download className="h-4 w-4" />}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default DownloadArtifact;
|
||||
Loading…
Add table
Add a link
Reference in a new issue