Skip to content

Commit aeeec6b

Browse files
committed
fix(chunks): add server-side sort to document chunks API
Chunk sort was previously done client-side on a single page of server-paginated data, which only reordered the current page. Now sort params (sortBy, sortOrder) flow through the full stack: types → service → API route → query hook → useDocumentChunks → document.tsx.
1 parent 71794bb commit aeeec6b

File tree

10 files changed

+213
-187
lines changed

10 files changed

+213
-187
lines changed

apps/sim/app/api/knowledge/[id]/documents/[documentId]/chunks/route.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const GetChunksQuerySchema = z.object({
1515
enabled: z.enum(['true', 'false', 'all']).optional().default('all'),
1616
limit: z.coerce.number().min(1).max(100).optional().default(50),
1717
offset: z.coerce.number().min(0).optional().default(0),
18+
sortBy: z.enum(['chunkIndex', 'tokenCount', 'enabled']).optional().default('chunkIndex'),
19+
sortOrder: z.enum(['asc', 'desc']).optional().default('asc'),
1820
})
1921

2022
const CreateChunkSchema = z.object({
@@ -88,6 +90,8 @@ export async function GET(
8890
enabled: searchParams.get('enabled') || undefined,
8991
limit: searchParams.get('limit') || undefined,
9092
offset: searchParams.get('offset') || undefined,
93+
sortBy: searchParams.get('sortBy') || undefined,
94+
sortOrder: searchParams.get('sortOrder') || undefined,
9195
})
9296

9397
const result = await queryChunks(documentId, queryParams, requestId)

apps/sim/app/workspace/[workspaceId]/home/components/user-input/user-input.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -571,19 +571,19 @@ export function UserInput({
571571
const items = e.clipboardData?.items
572572
if (!items) return
573573

574-
const imageFiles: File[] = []
574+
const pastedFiles: File[] = []
575575
for (const item of Array.from(items)) {
576-
if (item.kind === 'file' && item.type.startsWith('image/')) {
576+
if (item.kind === 'file') {
577577
const file = item.getAsFile()
578-
if (file) imageFiles.push(file)
578+
if (file) pastedFiles.push(file)
579579
}
580580
}
581581

582-
if (imageFiles.length === 0) return
582+
if (pastedFiles.length === 0) return
583583

584584
e.preventDefault()
585585
const dt = new DataTransfer()
586-
for (const file of imageFiles) {
586+
for (const file of pastedFiles) {
587587
dt.items.add(file)
588588
}
589589
filesRef.current.processFiles(dt.files)

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/document.tsx

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,21 @@ export function Document({
175175
refreshChunks: initialRefreshChunks,
176176
updateChunk: initialUpdateChunk,
177177
isFetching: isFetchingChunks,
178-
} = useDocumentChunks(knowledgeBaseId, documentId, currentPageFromURL, '', enabledFilterParam)
178+
} = useDocumentChunks(
179+
knowledgeBaseId,
180+
documentId,
181+
currentPageFromURL,
182+
'',
183+
enabledFilterParam,
184+
activeSort?.column === 'tokens'
185+
? 'tokenCount'
186+
: activeSort?.column === 'status'
187+
? 'enabled'
188+
: activeSort
189+
? 'chunkIndex'
190+
: undefined,
191+
activeSort?.direction
192+
)
179193

180194
const { data: searchResults = [], error: searchQueryError } = useDocumentChunkSearchQuery(
181195
{
@@ -241,25 +255,7 @@ export function Document({
241255

242256
const rawDisplayChunks = showingSearch ? paginatedSearchResults : initialChunks
243257

244-
const displayChunks = useMemo(() => {
245-
if (!activeSort || !rawDisplayChunks) return rawDisplayChunks ?? []
246-
const { column, direction } = activeSort
247-
return [...rawDisplayChunks].sort((a, b) => {
248-
let cmp = 0
249-
switch (column) {
250-
case 'index':
251-
cmp = a.chunkIndex - b.chunkIndex
252-
break
253-
case 'tokens':
254-
cmp = (a.tokenCount ?? 0) - (b.tokenCount ?? 0)
255-
break
256-
case 'status':
257-
cmp = (a.enabled ? 1 : 0) - (b.enabled ? 1 : 0)
258-
break
259-
}
260-
return direction === 'asc' ? cmp : -cmp
261-
})
262-
}, [rawDisplayChunks, activeSort])
258+
const displayChunks = rawDisplayChunks ?? []
263259

264260
const currentPage = showingSearch ? searchCurrentPage : initialPage
265261
const totalPages = showingSearch ? searchTotalPages : initialTotalPages
@@ -871,10 +867,16 @@ export function Document({
871867
{ id: 'status', label: 'Status' },
872868
],
873869
active: activeSort,
874-
onSort: (column, direction) => setActiveSort({ column, direction }),
875-
onClear: () => setActiveSort(null),
870+
onSort: (column, direction) => {
871+
setActiveSort({ column, direction })
872+
void goToPage(1)
873+
},
874+
onClear: () => {
875+
setActiveSort(null)
876+
void goToPage(1)
877+
},
876878
}),
877-
[activeSort]
879+
[activeSort, goToPage]
878880
)
879881

880882
const chunkRows: ResourceRow[] = useMemo(() => {

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/base.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ export function KnowledgeBase({
957957
content: (
958958
<Tooltip.Root>
959959
<Tooltip.Trigger asChild>
960-
<div style={{ cursor: 'help' }}>{getStatusBadge(doc)}</div>
960+
<div className='cursor-help'>{getStatusBadge(doc)}</div>
961961
</Tooltip.Trigger>
962962
<Tooltip.Content side='top' className='max-w-xs'>
963963
{doc.processingError}

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/collapsed-sidebar-menu/collapsed-sidebar-menu.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,6 @@ export function CollapsedTaskFlyoutItem({
245245
title={task.name}
246246
isActive={!!task.isActive}
247247
isUnread={!!task.isUnread}
248-
statusIndicatorClassName={
249-
!(isCurrentRoute || isMenuOpen) ? 'group-hover:hidden' : undefined
250-
}
251248
/>
252249
</Link>
253250
{showActions && (

0 commit comments

Comments
 (0)