Skip to content

Commit 4787909

Browse files
authored
improvement(kb): removed zustand cache syncing in kb, added chunk text tokenizer (#2647)
* improvement(kb): removed zustand cache syncing in kb, added chunk text tokenizer * removed dead code * removed redundant hook * remove unused hook * remove alert notification and use simple error * added more popover actions * removed debug instrumentation * remove extraneous comments * removed unused handler
1 parent 776f82c commit 4787909

File tree

43 files changed

+1158
-1974
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1158
-1974
lines changed

apps/sim/app/resume/[workflowId]/[executionId]/resume-page-client.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,9 +1134,9 @@ export default function ResumeExecutionPage({
11341134
)}
11351135
</div>
11361136
{entry.failureReason && (
1137-
<div className='mt-[8px] rounded-[4px] border border-[var(--text-error)]/20 bg-[var(--text-error)]/10 p-[8px] text-[11px] text-[var(--text-error)]'>
1137+
<p className='mt-[8px] text-[11px] text-[var(--text-error)]'>
11381138
{entry.failureReason}
1139-
</div>
1139+
</p>
11401140
)}
11411141
</div>
11421142
)
@@ -1229,9 +1229,9 @@ export default function ResumeExecutionPage({
12291229
</p>
12301230
)}
12311231
{selectedDetail.activeResumeEntry.failureReason && (
1232-
<div className='mt-[8px] rounded-[4px] border border-[var(--text-error)]/30 bg-[var(--text-error)]/10 p-[12px] text-[13px] text-[var(--text-error)]'>
1232+
<p className='mt-[8px] text-[12px] text-[var(--text-error)]'>
12331233
{selectedDetail.activeResumeEntry.failureReason}
1234-
</div>
1234+
</p>
12351235
)}
12361236
</div>
12371237
</div>
@@ -1363,11 +1363,7 @@ export default function ResumeExecutionPage({
13631363
)}
13641364

13651365
{/* Error/Success Messages */}
1366-
{error && (
1367-
<div className='rounded-[6px] border border-[var(--text-error)]/30 bg-[var(--text-error)]/10 p-[16px]'>
1368-
<p className='text-[13px] text-[var(--text-error)]'>{error}</p>
1369-
</div>
1370-
)}
1366+
{error && <p className='text-[12px] text-[var(--text-error)]'>{error}</p>}
13711367

13721368
{message && (
13731369
<div className='rounded-[6px] border border-[var(--text-success)]/30 bg-[var(--text-success)]/10 p-[16px]'>
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
'use client'
2+
3+
import { Popover, PopoverAnchor, PopoverContent, PopoverItem } from '@/components/emcn'
4+
5+
interface ChunkContextMenuProps {
6+
isOpen: boolean
7+
position: { x: number; y: number }
8+
menuRef: React.RefObject<HTMLDivElement | null>
9+
onClose: () => void
10+
/**
11+
* Chunk-specific actions (shown when right-clicking on a chunk)
12+
*/
13+
onOpenInNewTab?: () => void
14+
onEdit?: () => void
15+
onCopyContent?: () => void
16+
onToggleEnabled?: () => void
17+
onDelete?: () => void
18+
/**
19+
* Empty space action (shown when right-clicking on empty space)
20+
*/
21+
onAddChunk?: () => void
22+
/**
23+
* Whether the chunk is currently enabled
24+
*/
25+
isChunkEnabled?: boolean
26+
/**
27+
* Whether a chunk is selected (vs empty space)
28+
*/
29+
hasChunk: boolean
30+
/**
31+
* Whether toggle enabled is disabled
32+
*/
33+
disableToggleEnabled?: boolean
34+
/**
35+
* Whether delete is disabled
36+
*/
37+
disableDelete?: boolean
38+
/**
39+
* Whether add chunk is disabled
40+
*/
41+
disableAddChunk?: boolean
42+
}
43+
44+
/**
45+
* Context menu for chunks table.
46+
* Shows chunk actions when right-clicking a row, or "Create chunk" when right-clicking empty space.
47+
*/
48+
export function ChunkContextMenu({
49+
isOpen,
50+
position,
51+
menuRef,
52+
onClose,
53+
onOpenInNewTab,
54+
onEdit,
55+
onCopyContent,
56+
onToggleEnabled,
57+
onDelete,
58+
onAddChunk,
59+
isChunkEnabled = true,
60+
hasChunk,
61+
disableToggleEnabled = false,
62+
disableDelete = false,
63+
disableAddChunk = false,
64+
}: ChunkContextMenuProps) {
65+
return (
66+
<Popover open={isOpen} onOpenChange={onClose} variant='secondary' size='sm'>
67+
<PopoverAnchor
68+
style={{
69+
position: 'fixed',
70+
left: `${position.x}px`,
71+
top: `${position.y}px`,
72+
width: '1px',
73+
height: '1px',
74+
}}
75+
/>
76+
<PopoverContent ref={menuRef} align='start' side='bottom' sideOffset={4}>
77+
{hasChunk ? (
78+
<>
79+
{onOpenInNewTab && (
80+
<PopoverItem
81+
onClick={() => {
82+
onOpenInNewTab()
83+
onClose()
84+
}}
85+
>
86+
Open in new tab
87+
</PopoverItem>
88+
)}
89+
{onEdit && (
90+
<PopoverItem
91+
onClick={() => {
92+
onEdit()
93+
onClose()
94+
}}
95+
>
96+
Edit
97+
</PopoverItem>
98+
)}
99+
{onCopyContent && (
100+
<PopoverItem
101+
onClick={() => {
102+
onCopyContent()
103+
onClose()
104+
}}
105+
>
106+
Copy content
107+
</PopoverItem>
108+
)}
109+
{onToggleEnabled && (
110+
<PopoverItem
111+
disabled={disableToggleEnabled}
112+
onClick={() => {
113+
onToggleEnabled()
114+
onClose()
115+
}}
116+
>
117+
{isChunkEnabled ? 'Disable' : 'Enable'}
118+
</PopoverItem>
119+
)}
120+
{onDelete && (
121+
<PopoverItem
122+
disabled={disableDelete}
123+
onClick={() => {
124+
onDelete()
125+
onClose()
126+
}}
127+
>
128+
Delete
129+
</PopoverItem>
130+
)}
131+
</>
132+
) : (
133+
onAddChunk && (
134+
<PopoverItem
135+
disabled={disableAddChunk}
136+
onClick={() => {
137+
onAddChunk()
138+
onClose()
139+
}}
140+
>
141+
Create chunk
142+
</PopoverItem>
143+
)
144+
)}
145+
</PopoverContent>
146+
</Popover>
147+
)
148+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { ChunkContextMenu } from './chunk-context-menu'

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/create-chunk-modal/create-chunk-modal.tsx

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { useRef, useState } from 'react'
44
import { createLogger } from '@sim/logger'
5-
import { AlertCircle } from 'lucide-react'
5+
import { useQueryClient } from '@tanstack/react-query'
66
import {
77
Button,
88
Label,
@@ -13,7 +13,8 @@ import {
1313
ModalHeader,
1414
Textarea,
1515
} from '@/components/emcn'
16-
import type { ChunkData, DocumentData } from '@/stores/knowledge/store'
16+
import type { DocumentData } from '@/lib/knowledge/types'
17+
import { knowledgeKeys } from '@/hooks/queries/knowledge'
1718

1819
const logger = createLogger('CreateChunkModal')
1920

@@ -22,16 +23,15 @@ interface CreateChunkModalProps {
2223
onOpenChange: (open: boolean) => void
2324
document: DocumentData | null
2425
knowledgeBaseId: string
25-
onChunkCreated?: (chunk: ChunkData) => void
2626
}
2727

2828
export function CreateChunkModal({
2929
open,
3030
onOpenChange,
3131
document,
3232
knowledgeBaseId,
33-
onChunkCreated,
3433
}: CreateChunkModalProps) {
34+
const queryClient = useQueryClient()
3535
const [content, setContent] = useState('')
3636
const [isCreating, setIsCreating] = useState(false)
3737
const [error, setError] = useState<string | null>(null)
@@ -77,9 +77,9 @@ export function CreateChunkModal({
7777
if (result.success && result.data) {
7878
logger.info('Chunk created successfully:', result.data.id)
7979

80-
if (onChunkCreated) {
81-
onChunkCreated(result.data)
82-
}
80+
await queryClient.invalidateQueries({
81+
queryKey: knowledgeKeys.detail(knowledgeBaseId),
82+
})
8383

8484
onClose()
8585
} else {
@@ -96,7 +96,6 @@ export function CreateChunkModal({
9696

9797
const onClose = () => {
9898
onOpenChange(false)
99-
// Reset form state when modal closes
10099
setContent('')
101100
setError(null)
102101
setShowUnsavedChangesAlert(false)
@@ -126,13 +125,7 @@ export function CreateChunkModal({
126125
<form>
127126
<ModalBody className='!pb-[16px]'>
128127
<div className='flex flex-col gap-[8px]'>
129-
{/* Error Display */}
130-
{error && (
131-
<div className='flex items-center gap-2 rounded-md border border-[var(--text-error)]/50 bg-[var(--text-error)]/10 p-3'>
132-
<AlertCircle className='h-4 w-4 text-[var(--text-error)]' />
133-
<p className='text-[var(--text-error)] text-sm'>{error}</p>
134-
</div>
135-
)}
128+
{error && <p className='text-[12px] text-[var(--text-error)]'>{error}</p>}
136129

137130
{/* Content Input Section */}
138131
<Label htmlFor='content'>Chunk</Label>

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/delete-chunk-modal/delete-chunk-modal.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import { useState } from 'react'
44
import { createLogger } from '@sim/logger'
5+
import { useQueryClient } from '@tanstack/react-query'
56
import { Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader } from '@/components/emcn'
6-
import type { ChunkData } from '@/stores/knowledge/store'
7+
import type { ChunkData } from '@/lib/knowledge/types'
8+
import { knowledgeKeys } from '@/hooks/queries/knowledge'
79

810
const logger = createLogger('DeleteChunkModal')
911

@@ -13,7 +15,6 @@ interface DeleteChunkModalProps {
1315
documentId: string
1416
isOpen: boolean
1517
onClose: () => void
16-
onChunkDeleted?: () => void
1718
}
1819

1920
export function DeleteChunkModal({
@@ -22,8 +23,8 @@ export function DeleteChunkModal({
2223
documentId,
2324
isOpen,
2425
onClose,
25-
onChunkDeleted,
2626
}: DeleteChunkModalProps) {
27+
const queryClient = useQueryClient()
2728
const [isDeleting, setIsDeleting] = useState(false)
2829

2930
const handleDeleteChunk = async () => {
@@ -47,16 +48,17 @@ export function DeleteChunkModal({
4748

4849
if (result.success) {
4950
logger.info('Chunk deleted successfully:', chunk.id)
50-
if (onChunkDeleted) {
51-
onChunkDeleted()
52-
}
51+
52+
await queryClient.invalidateQueries({
53+
queryKey: knowledgeKeys.detail(knowledgeBaseId),
54+
})
55+
5356
onClose()
5457
} else {
5558
throw new Error(result.error || 'Failed to delete chunk')
5659
}
5760
} catch (err) {
5861
logger.error('Error deleting chunk:', err)
59-
// You might want to show an error state here
6062
} finally {
6163
setIsDeleting(false)
6264
}

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/document-tags-modal/document-tags-modal.tsx

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import {
1818
import { cn } from '@/lib/core/utils/cn'
1919
import { ALL_TAG_SLOTS, type AllTagSlot, MAX_TAG_SLOTS } from '@/lib/knowledge/constants'
2020
import type { DocumentTag } from '@/lib/knowledge/tags/types'
21+
import type { DocumentData } from '@/lib/knowledge/types'
2122
import {
2223
type TagDefinition,
2324
useKnowledgeBaseTagDefinitions,
2425
} from '@/hooks/use-knowledge-base-tag-definitions'
2526
import { useNextAvailableSlot } from '@/hooks/use-next-available-slot'
2627
import { type TagDefinitionInput, useTagDefinitions } from '@/hooks/use-tag-definitions'
27-
import { type DocumentData, useKnowledgeStore } from '@/stores/knowledge/store'
2828

2929
const logger = createLogger('DocumentTagsModal')
3030

@@ -93,8 +93,6 @@ export function DocumentTagsModal({
9393
documentData,
9494
onDocumentUpdate,
9595
}: DocumentTagsModalProps) {
96-
const { updateDocument: updateDocumentInStore } = useKnowledgeStore()
97-
9896
const documentTagHook = useTagDefinitions(knowledgeBaseId, documentId)
9997
const kbTagHook = useKnowledgeBaseTagDefinitions(knowledgeBaseId)
10098
const { getNextAvailableSlot: getServerNextSlot } = useNextAvailableSlot(knowledgeBaseId)
@@ -171,23 +169,14 @@ export function DocumentTagsModal({
171169
throw new Error('Failed to update document tags')
172170
}
173171

174-
updateDocumentInStore(knowledgeBaseId, documentId, tagData as Record<string, string>)
175172
onDocumentUpdate?.(tagData as Record<string, string>)
176-
177173
await fetchTagDefinitions()
178174
} catch (error) {
179175
logger.error('Error updating document tags:', error)
180176
throw error
181177
}
182178
},
183-
[
184-
documentData,
185-
knowledgeBaseId,
186-
documentId,
187-
updateDocumentInStore,
188-
fetchTagDefinitions,
189-
onDocumentUpdate,
190-
]
179+
[documentData, knowledgeBaseId, documentId, fetchTagDefinitions, onDocumentUpdate]
191180
)
192181

193182
const handleRemoveTag = async (index: number) => {

0 commit comments

Comments
 (0)