diff --git a/frontend/src/components/DocumentChunks.tsx b/frontend/src/components/DocumentChunks.tsx index 3b2881ed..c96ea9d8 100644 --- a/frontend/src/components/DocumentChunks.tsx +++ b/frontend/src/components/DocumentChunks.tsx @@ -8,12 +8,10 @@ import ArrowLeft from '../assets/arrow-left.svg'; import NoFilesIcon from '../assets/no-files.svg'; import NoFilesDarkIcon from '../assets/no-files-dark.svg'; import OutlineSource from '../assets/outline-source.svg'; -import Spinner from '../components/Spinner'; -import ChunkModal from '../modals/ChunkModal'; +import SkeletonLoader from './SkeletonLoader'; import ConfirmationModal from '../modals/ConfirmationModal'; import { ActiveState } from '../models/misc'; import { ChunkType } from '../settings/types'; -import EditIcon from '../assets/edit.svg'; import Pagination from './DocumentPagination'; interface LineNumberedTextareaProps { @@ -271,10 +269,10 @@ const DocumentChunks: React.FC = ({ const renderPathNavigation = () => { return ( -
+
- {editingChunk && ( -
- {!isEditing ? ( +
+ {editingChunk ? ( + !isEditing ? ( - )} -
- )} - - {isAddingChunk && ( -
- - -
- )} + ) + ) : isAddingChunk ? ( + <> + + + + ) : null} +
); }; @@ -436,11 +432,11 @@ const DocumentChunks: React.FC = ({
{loading ? ( -
- +
+
) : ( -
+
{filteredChunks.length === 0 ? (
= ({ filteredChunks.map((chunk, index) => (
{ setEditingChunk(chunk); setEditingTitle(chunk.metadata?.title || ''); @@ -467,7 +463,7 @@ const DocumentChunks: React.FC = ({ {chunk.metadata.token_count ? chunk.metadata.token_count.toLocaleString() : '-'} {t('settings.documents.tokensUnit')}
-
+

{chunk.text}

@@ -480,7 +476,6 @@ const DocumentChunks: React.FC = ({ )} ) : isAddingChunk ? ( - // Add new chunk view
= ({ setItemToDelete(null); }; - const manageSource = async (operation: 'add' | 'remove', files?: FileList | null, filePath?: string) => { + const manageSource = async (operation: 'add' | 'remove' | 'remove_directory', files?: FileList | null, filePath?: string, directoryPath?: string) => { setIsUploading(true); - + try { const formData = new FormData(); formData.append('source_id', docId); formData.append('operation', operation); - + if (operation === 'add' && files) { formData.append('parent_dir', currentPath.join('/')); - + for (let i = 0; i < files.length; i++) { formData.append('file', files[i]); } } else if (operation === 'remove' && filePath) { const filePaths = JSON.stringify([filePath]); formData.append('file_paths', filePaths); + } else if (operation === 'remove_directory' && directoryPath) { + formData.append('directory_path', directoryPath); } const response = await userService.manageSourceFiles(formData, token); const result = await response.json(); if (result.success && result.reingest_task_id) { - console.log(`Files ${operation === 'add' ? 'uploaded' : 'deleted'} successfully:`, - operation === 'add' ? result.added_files : result.removed_files); + if (operation === 'add') { + console.log('Files uploaded successfully:', result.added_files); + } else if (operation === 'remove') { + console.log('Files deleted successfully:', result.removed_files); + } else if (operation === 'remove_directory') { + console.log('Directory deleted successfully:', result.removed_directory); + } console.log('Reingest task started:', result.reingest_task_id); const maxAttempts = 30; @@ -299,11 +306,13 @@ const FileTreeComponent: React.FC = ({ } } } else { - throw new Error(`Failed to ${operation} file(s)`); + throw new Error(`Failed to ${operation} ${operation === 'remove_directory' ? 'directory' : 'file(s)'}`); } } catch (error) { - console.error(`Error ${operation === 'add' ? 'uploading' : 'deleting'} file(s):`, error); - setError(`Failed to ${operation === 'add' ? 'upload' : 'delete'} file(s)`); + const actionText = operation === 'add' ? 'uploading' : operation === 'remove_directory' ? 'deleting directory' : 'deleting file(s)'; + const errorText = operation === 'add' ? 'upload' : operation === 'remove_directory' ? 'delete directory' : 'delete file(s)'; + console.error(`Error ${actionText}:`, error); + setError(`Failed to ${errorText}`); } finally { setIsUploading(false); } @@ -328,14 +337,21 @@ const FileTreeComponent: React.FC = ({ }; const handleDeleteFile = async (name: string, isFile: boolean) => { - // Construct the full path to the file - const filePath = [...currentPath, name].join('/'); - await manageSource('remove', null, filePath); + // Construct the full path to the file or directory + const itemPath = [...currentPath, name].join('/'); + + if (isFile) { + // Delete individual file + await manageSource('remove', null, itemPath); + } else { + // Delete entire directory + await manageSource('remove_directory', null, undefined, itemPath); + } }; const renderPathNavigation = () => { return ( -
+
@@ -544,7 +560,7 @@ const FileTreeComponent: React.FC = ({ options={getActionOptions(name, true, itemId)} anchorRef={menuRef} position="bottom-left" - offset={{ x: 0, y: 8 }} + offset={{ x: -8, y: 8 }} />
@@ -659,7 +675,7 @@ const FileTreeComponent: React.FC = ({
{selectedFile ? (
-
+
= ({
)} = ({ @@ -182,6 +184,51 @@ const SkeletonLoader: React.FC = ({ ); + const renderChunkCards = () => ( + <> + {Array.from({ length: count }).map((_, index) => ( +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))} + + ); + + const renderSourceCards = () => ( + <> + {Array.from({ length: count }).map((_, idx) => ( +
+
+
+
+
+
+
+
+
+
+ ))} + + ); + const componentMap = { table: renderTable, chatbot: renderChatbot, @@ -189,8 +236,11 @@ const SkeletonLoader: React.FC = ({ logs: renderLogs, default: renderDefault, analysis: renderAnalysis, + chunkCards: renderChunkCards, + sourceCards: renderSourceCards, }; + const render = componentMap[component] || componentMap.default; return <>{render()}; diff --git a/frontend/src/settings/Documents.tsx b/frontend/src/settings/Documents.tsx index 30f71f26..899092af 100644 --- a/frontend/src/settings/Documents.tsx +++ b/frontend/src/settings/Documents.tsx @@ -315,7 +315,9 @@ export default function Documents({
{loading ? ( - +
+ +
) : !currentDocuments?.length ? (
)} @@ -391,7 +393,7 @@ export default function Documents({ > {t('convTile.menu')} @@ -423,7 +425,7 @@ export default function Documents({ options={getActionOptions(index, document)} anchorRef={getMenuRef(docId)} position="bottom-left" - offset={{ x: 48, y: 0 }} + offset={{ x: -8, y: 8 }} className="z-50" />
@@ -434,22 +436,24 @@ export default function Documents({
-
- { - setCurrentPage(page); - refreshDocs(undefined, page, rowsPerPage); - }} - onRowsPerPageChange={(rows) => { - setRowsPerPage(rows); - setCurrentPage(1); - refreshDocs(undefined, 1, rows); - }} - /> -
+ {currentDocuments.length > 0 && totalPages > 1 && ( +
+ { + setCurrentPage(page); + refreshDocs(undefined, page, rowsPerPage); + }} + onRowsPerPageChange={(rows) => { + setRowsPerPage(rows); + setCurrentPage(1); + refreshDocs(undefined, 1, rows); + }} + /> +
+ )} {modalState === 'ACTIVE' && (