Download client/src/components/Nav/ExportConversation/ExportModal.tsx from Zhitomir/chat: direct link, hf CLI and curl.
- Browser
- Download file 7.82 kB
-
https://huggingface.co/spaces/Zhitomir/chat/resolve/main/client/src/components/Nav/ExportConversation/ExportModal.tsx
- Command line
-
hf download hf://spaces/Zhitomir/chat/client/src/components/Nav/ExportConversation/ExportModal.tsx
-
curl -L -o ExportModal.tsx https://huggingface.co/spaces/Zhitomir/chat/resolve/main/client/src/components/Nav/ExportConversation/ExportModal.tsx
7.82 kB
| import filenamify from 'filenamify'; | |
| import { useEffect, useState } from 'react'; | |
| import type { TConversation } from 'librechat-data-provider'; | |
| import { Dialog, DialogButton, Input, Label, Checkbox, Dropdown } from '~/components/ui'; | |
| import { useLocalize, useExportConversation } from '~/hooks'; | |
| import DialogTemplate from '~/components/ui/DialogTemplate'; | |
| import { cn, defaultTextProps } from '~/utils'; | |
| export default function ExportModal({ | |
| open, | |
| onOpenChange, | |
| conversation, | |
| }: { | |
| open: boolean; | |
| onOpenChange: (open: boolean) => void; | |
| conversation: TConversation | null; | |
| }) { | |
| const localize = useLocalize(); | |
| const [filename, setFileName] = useState(''); | |
| const [type, setType] = useState('Select a file type'); | |
| const [includeOptions, setIncludeOptions] = useState<boolean | 'indeterminate'>(true); | |
| const [exportBranches, setExportBranches] = useState<boolean | 'indeterminate'>(false); | |
| const [recursive, setRecursive] = useState<boolean | 'indeterminate'>(true); | |
| const typeOptions = [ | |
| { value: 'screenshot', display: 'screenshot (.png)' }, | |
| { value: 'text', display: 'text (.txt)' }, | |
| { value: 'markdown', display: 'markdown (.md)' }, | |
| { value: 'json', display: 'json (.json)' }, | |
| { value: 'csv', display: 'csv (.csv)' }, | |
| ]; | |
| useEffect(() => { | |
| setFileName(filenamify(String(conversation?.title || 'file'))); | |
| setType('screenshot'); | |
| setIncludeOptions(true); | |
| setExportBranches(false); | |
| setRecursive(true); | |
| }, [conversation?.title, open]); | |
| const _setType = (newType: string) => { | |
| const exportBranchesSupport = newType === 'json' || newType === 'csv' || newType === 'webpage'; | |
| const exportOptionsSupport = newType !== 'csv' && newType !== 'screenshot'; | |
| setExportBranches(exportBranchesSupport); | |
| setIncludeOptions(exportOptionsSupport); | |
| setType(newType); | |
| }; | |
| const exportBranchesSupport = type === 'json' || type === 'csv' || type === 'webpage'; | |
| const exportOptionsSupport = type !== 'csv' && type !== 'screenshot'; | |
| const { exportConversation } = useExportConversation({ | |
| conversation, | |
| filename, | |
| type, | |
| includeOptions, | |
| exportBranches, | |
| recursive, | |
| }); | |
| return ( | |
| <Dialog open={open} onOpenChange={onOpenChange}> | |
| <DialogTemplate | |
| title={localize('com_nav_export_conversation')} | |
| className="max-w-full sm:max-w-2xl" | |
| main={ | |
| <div className="flex w-full flex-col items-center gap-6"> | |
| <div className="grid w-full gap-6 sm:grid-cols-2"> | |
| <div className="col-span-1 flex flex-col items-start justify-start gap-2"> | |
| <Label htmlFor="filename" className="text-left text-sm font-medium"> | |
| {localize('com_nav_export_filename')} | |
| </Label> | |
| <Input | |
| id="filename" | |
| value={filename} | |
| onChange={(e) => setFileName(filenamify(e.target.value || ''))} | |
| placeholder={localize('com_nav_export_filename_placeholder')} | |
| className={cn( | |
| defaultTextProps, | |
| 'flex h-10 max-h-10 w-full resize-none px-3 py-2', | |
| )} | |
| /> | |
| </div> | |
| <div className="col-span-1 flex w-full flex-col items-start justify-start gap-2"> | |
| <Label htmlFor="type" className="text-left text-sm font-medium"> | |
| {localize('com_nav_export_type')} | |
| </Label> | |
| <Dropdown value={type} onChange={_setType} options={typeOptions} /> | |
| </div> | |
| </div> | |
| <div className="grid w-full gap-6 sm:grid-cols-2"> | |
| <div className="col-span-1 flex flex-col items-start justify-start gap-2"> | |
| <div className="grid w-full items-center gap-2"> | |
| <Label htmlFor="includeOptions" className="text-left text-sm font-medium"> | |
| {localize('com_nav_export_include_endpoint_options')} | |
| </Label> | |
| <div className="flex h-[40px] w-full items-center space-x-3"> | |
| <Checkbox | |
| id="includeOptions" | |
| disabled={!exportOptionsSupport} | |
| checked={includeOptions} | |
| className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0" | |
| onCheckedChange={setIncludeOptions} | |
| /> | |
| <label | |
| htmlFor="includeOptions" | |
| className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50" | |
| > | |
| {exportOptionsSupport | |
| ? localize('com_nav_enabled') | |
| : localize('com_nav_not_supported')} | |
| </label> | |
| </div> | |
| </div> | |
| </div> | |
| <div className="grid w-full items-center gap-2"> | |
| <Label htmlFor="exportBranches" className="text-left text-sm font-medium"> | |
| {localize('com_nav_export_all_message_branches')} | |
| </Label> | |
| <div className="flex h-[40px] w-full items-center space-x-3"> | |
| <Checkbox | |
| id="exportBranches" | |
| disabled={!exportBranchesSupport} | |
| checked={exportBranches} | |
| className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0" | |
| onCheckedChange={setExportBranches} | |
| /> | |
| <label | |
| htmlFor="exportBranches" | |
| className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50" | |
| > | |
| {exportBranchesSupport | |
| ? localize('com_nav_enabled') | |
| : localize('com_nav_not_supported')} | |
| </label> | |
| </div> | |
| </div> | |
| {type === 'json' ? ( | |
| <div className="grid w-full items-center gap-2"> | |
| <Label htmlFor="recursive" className="text-left text-sm font-medium"> | |
| {localize('com_nav_export_recursive_or_sequential')} | |
| </Label> | |
| <div className="flex h-[40px] w-full items-center space-x-3"> | |
| <Checkbox | |
| id="recursive" | |
| checked={recursive} | |
| className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0" | |
| onCheckedChange={setRecursive} | |
| /> | |
| <label | |
| htmlFor="recursive" | |
| className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-50" | |
| > | |
| {localize('com_nav_export_recursive')} | |
| </label> | |
| </div> | |
| </div> | |
| ) : null} | |
| </div> | |
| </div> | |
| } | |
| buttons={ | |
| <> | |
| <DialogButton | |
| onClick={exportConversation} | |
| className="dark:hover:gray-400 border-gray-700 bg-green-500 text-white hover:bg-green-600 dark:hover:bg-green-600" | |
| > | |
| {localize('com_endpoint_export')} | |
| </DialogButton> | |
| </> | |
| } | |
| selection={undefined} | |
| /> | |
| </Dialog> | |
| ); | |
| } | |