84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
import { useMemo } from 'react';
|
|
import { FileText } from 'lucide-react';
|
|
import ReactMarkdown from 'react-markdown';
|
|
import { Separator } from '@librechat/client';
|
|
import type { ExtendedFile } from '~/common';
|
|
import AttachFileButton from '~/components/Prompts/Files/AttachFileButton';
|
|
import PromptFile from '~/components/Prompts/PromptFile';
|
|
import { useLocalize } from '~/hooks';
|
|
|
|
const PromptFiles = ({
|
|
files,
|
|
onFilesChange,
|
|
handleFileChange,
|
|
disabled,
|
|
onFileChange,
|
|
}: {
|
|
files: ExtendedFile[];
|
|
onFilesChange?: (files: ExtendedFile[]) => void;
|
|
handleFileChange?: (event: React.ChangeEvent<HTMLInputElement>, toolResource?: string) => void;
|
|
disabled?: boolean;
|
|
onFileChange?: (files: ExtendedFile[]) => void;
|
|
}) => {
|
|
const localize = useLocalize();
|
|
|
|
const filesMap = useMemo(() => {
|
|
const map = new Map<string, ExtendedFile>();
|
|
files.forEach((file) => {
|
|
const key = file.file_id || file.temp_file_id || '';
|
|
if (key) {
|
|
map.set(key, file);
|
|
}
|
|
});
|
|
return map;
|
|
}, [files]);
|
|
|
|
return (
|
|
<div className="flex h-full flex-col rounded-xl border border-border-light bg-transparent p-4 shadow-md">
|
|
<h3 className="flex items-center gap-2 py-2 text-lg font-semibold text-text-primary">
|
|
<FileText className="icon-sm" aria-hidden="true" />
|
|
{localize('com_ui_files')}
|
|
</h3>
|
|
<div className="flex flex-1 flex-col space-y-4">
|
|
<div className="flex-1">
|
|
{!files.length && (
|
|
<>
|
|
<div className="text-sm text-text-secondary">
|
|
<ReactMarkdown className="markdown prose dark:prose-invert">
|
|
{localize('com_ui_files_info')}
|
|
</ReactMarkdown>
|
|
</div>
|
|
<Separator className="my-3 text-text-primary" />
|
|
</>
|
|
)}
|
|
|
|
{files.length > 0 && (
|
|
<div className="mb-3">
|
|
<PromptFile
|
|
files={filesMap}
|
|
setFiles={(newMapOrUpdater) => {
|
|
const newMap =
|
|
typeof newMapOrUpdater === 'function'
|
|
? newMapOrUpdater(filesMap)
|
|
: newMapOrUpdater;
|
|
const newFiles = Array.from(newMap.values()) as ExtendedFile[];
|
|
onFilesChange?.(newFiles);
|
|
}}
|
|
setFilesLoading={() => {}}
|
|
onFileChange={onFileChange}
|
|
Wrapper={({ children }) => <div className="flex flex-wrap gap-2">{children}</div>}
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex justify-start text-text-secondary">
|
|
<AttachFileButton handleFileChange={handleFileChange} disabled={disabled} />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PromptFiles;
|