Feat: add file path sorting for document manager
- Add file_path sorting support to all database backends (JSON, Redis, PostgreSQL, MongoDB) - Implement smart column header switching between "ID" and "File Name" based on display mode - Add automatic sort field switching when toggling between ID and file name display - Create composite indexes for workspace+file_path in PostgreSQL and MongoDB for better query performance - Update frontend to maintain sort state when switching display modes - Add internationalization support for "fileName" in English and Chinese locales This enhancement improves user experience by providing intuitive file-based sorting while maintaining performance through optimized database indexes.
This commit is contained in:
parent
e60c26ea77
commit
0eac1a883a
9 changed files with 40 additions and 11 deletions
|
|
@ -510,7 +510,7 @@ class DocumentsRequest(BaseModel):
|
|||
page_size: int = Field(
|
||||
default=50, ge=10, le=200, description="Number of documents per page (10-200)"
|
||||
)
|
||||
sort_field: Literal["created_at", "updated_at", "id"] = Field(
|
||||
sort_field: Literal["created_at", "updated_at", "id", "file_path"] = Field(
|
||||
default="updated_at", description="Field to sort by"
|
||||
)
|
||||
sort_direction: Literal["asc", "desc"] = Field(
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ class JsonDocStatusStorage(DocStatusStorage):
|
|||
elif page_size > 200:
|
||||
page_size = 200
|
||||
|
||||
if sort_field not in ["created_at", "updated_at", "id"]:
|
||||
if sort_field not in ["created_at", "updated_at", "id", "file_path"]:
|
||||
sort_field = "updated_at"
|
||||
|
||||
if sort_direction.lower() not in ["asc", "desc"]:
|
||||
|
|
|
|||
|
|
@ -503,6 +503,7 @@ class MongoDocStatusStorage(DocStatusStorage):
|
|||
{"name": "updated_at", "keys": [("updated_at", -1)]},
|
||||
{"name": "created_at", "keys": [("created_at", -1)]},
|
||||
{"name": "id", "keys": [("_id", 1)]},
|
||||
{"name": "file_path", "keys": [("file_path", 1)]},
|
||||
]
|
||||
|
||||
# Check which indexes already exist
|
||||
|
|
@ -553,7 +554,7 @@ class MongoDocStatusStorage(DocStatusStorage):
|
|||
elif page_size > 200:
|
||||
page_size = 200
|
||||
|
||||
if sort_field not in ["created_at", "updated_at", "_id"]:
|
||||
if sort_field not in ["created_at", "updated_at", "_id", "file_path"]:
|
||||
sort_field = "updated_at"
|
||||
|
||||
if sort_direction.lower() not in ["asc", "desc"]:
|
||||
|
|
|
|||
|
|
@ -948,6 +948,11 @@ class PostgreSQLDB:
|
|||
"sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_lightrag_doc_status_workspace_id ON LIGHTRAG_DOC_STATUS (workspace, id)",
|
||||
"description": "Index for workspace + id sorting",
|
||||
},
|
||||
{
|
||||
"name": "idx_lightrag_doc_status_workspace_file_path",
|
||||
"sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_lightrag_doc_status_workspace_file_path ON LIGHTRAG_DOC_STATUS (workspace, file_path)",
|
||||
"description": "Index for workspace + file_path sorting",
|
||||
},
|
||||
]
|
||||
|
||||
for index in indexes:
|
||||
|
|
@ -2066,7 +2071,7 @@ class PGDocStatusStorage(DocStatusStorage):
|
|||
elif page_size > 200:
|
||||
page_size = 200
|
||||
|
||||
if sort_field not in ["created_at", "updated_at", "id"]:
|
||||
if sort_field not in ["created_at", "updated_at", "id", "file_path"]:
|
||||
sort_field = "updated_at"
|
||||
|
||||
if sort_direction.lower() not in ["asc", "desc"]:
|
||||
|
|
|
|||
|
|
@ -947,7 +947,7 @@ class RedisDocStatusStorage(DocStatusStorage):
|
|||
elif page_size > 200:
|
||||
page_size = 200
|
||||
|
||||
if sort_field not in ["created_at", "updated_at", "id"]:
|
||||
if sort_field not in ["created_at", "updated_at", "id", "file_path"]:
|
||||
sort_field = "updated_at"
|
||||
|
||||
if sort_direction.lower() not in ["asc", "desc"]:
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ export type DocumentsRequest = {
|
|||
status_filter?: DocStatus | null
|
||||
page: number
|
||||
page_size: number
|
||||
sort_field: 'created_at' | 'updated_at' | 'id'
|
||||
sort_field: 'created_at' | 'updated_at' | 'id' | 'file_path'
|
||||
sort_direction: 'asc' | 'desc'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ const pulseStyle = `
|
|||
`;
|
||||
|
||||
// Type definitions for sort field and direction
|
||||
type SortField = 'created_at' | 'updated_at' | 'id';
|
||||
type SortField = 'created_at' | 'updated_at' | 'id' | 'file_path';
|
||||
type SortDirection = 'asc' | 'desc';
|
||||
|
||||
export default function DocumentManager() {
|
||||
|
|
@ -234,9 +234,16 @@ export default function DocumentManager() {
|
|||
|
||||
// Handle sort column click
|
||||
const handleSort = (field: SortField) => {
|
||||
const newDirection = (sortField === field && sortDirection === 'desc') ? 'asc' : 'desc';
|
||||
let actualField = field;
|
||||
|
||||
setSortField(field);
|
||||
// When clicking the first column, determine the actual sort field based on showFileName
|
||||
if (field === 'id') {
|
||||
actualField = showFileName ? 'file_path' : 'id';
|
||||
}
|
||||
|
||||
const newDirection = (sortField === actualField && sortDirection === 'desc') ? 'asc' : 'desc';
|
||||
|
||||
setSortField(actualField);
|
||||
setSortDirection(newDirection);
|
||||
|
||||
// Reset page to 1 when sorting changes
|
||||
|
|
@ -600,6 +607,17 @@ export default function DocumentManager() {
|
|||
}, [fetchDocuments])
|
||||
|
||||
|
||||
// Handle showFileName change - switch sort field if currently sorting by first column
|
||||
useEffect(() => {
|
||||
// Only switch if currently sorting by the first column (id or file_path)
|
||||
if (sortField === 'id' || sortField === 'file_path') {
|
||||
const newSortField = showFileName ? 'file_path' : 'id';
|
||||
if (sortField !== newSortField) {
|
||||
setSortField(newSortField);
|
||||
}
|
||||
}
|
||||
}, [showFileName, sortField]);
|
||||
|
||||
// Central effect to handle all data fetching
|
||||
useEffect(() => {
|
||||
if (currentTab === 'documents') {
|
||||
|
|
@ -796,8 +814,11 @@ export default function DocumentManager() {
|
|||
className="cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-800 select-none"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
{t('documentPanel.documentManager.columns.id')}
|
||||
{sortField === 'id' && (
|
||||
{showFileName
|
||||
? t('documentPanel.documentManager.columns.fileName')
|
||||
: t('documentPanel.documentManager.columns.id')
|
||||
}
|
||||
{((sortField === 'id' && !showFileName) || (sortField === 'file_path' && showFileName)) && (
|
||||
<span className="ml-1">
|
||||
{sortDirection === 'asc' ? <ArrowUpIcon size={14} /> : <ArrowDownIcon size={14} />}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@
|
|||
"emptyDescription": "There are no uploaded documents yet.",
|
||||
"columns": {
|
||||
"id": "ID",
|
||||
"fileName": "File Name",
|
||||
"summary": "Summary",
|
||||
"status": "Status",
|
||||
"length": "Length",
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@
|
|||
"emptyDescription": "还没有上传任何文档",
|
||||
"columns": {
|
||||
"id": "ID",
|
||||
"fileName": "文件名",
|
||||
"summary": "摘要",
|
||||
"status": "状态",
|
||||
"length": "长度",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue