refresh on upload

This commit is contained in:
phact 2025-08-29 17:04:12 -04:00
parent d58f721edc
commit 168ebc7ae5
2 changed files with 29 additions and 7 deletions

View file

@ -67,6 +67,10 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => { const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files const files = e.target.files
if (files && files.length > 0) { if (files && files.length > 0) {
// Close dropdown and disable button immediately after file selection
setIsOpen(false)
setFileUploading(true)
// Trigger the same file upload event as the chat page // Trigger the same file upload event as the chat page
window.dispatchEvent(new CustomEvent('fileUploadStart', { window.dispatchEvent(new CustomEvent('fileUploadStart', {
detail: { filename: files[0].name } detail: { filename: files[0].name }
@ -87,6 +91,8 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
window.dispatchEvent(new CustomEvent('fileUploaded', { window.dispatchEvent(new CustomEvent('fileUploaded', {
detail: { file: files[0], result } detail: { file: files[0], result }
})) }))
// Trigger search refresh after successful upload
window.dispatchEvent(new CustomEvent('knowledgeUpdated'))
} else { } else {
window.dispatchEvent(new CustomEvent('fileUploadError', { window.dispatchEvent(new CustomEvent('fileUploadError', {
detail: { filename: files[0].name, error: result.error || 'Upload failed' } detail: { filename: files[0].name, error: result.error || 'Upload failed' }
@ -98,6 +104,7 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
})) }))
} finally { } finally {
window.dispatchEvent(new CustomEvent('fileUploadComplete')) window.dispatchEvent(new CustomEvent('fileUploadComplete'))
setFileUploading(false)
} }
} }
@ -105,13 +112,13 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
if (fileInputRef.current) { if (fileInputRef.current) {
fileInputRef.current.value = '' fileInputRef.current.value = ''
} }
setIsOpen(false)
} }
const handleFolderUpload = async () => { const handleFolderUpload = async () => {
if (!folderPath.trim()) return if (!folderPath.trim()) return
setFolderLoading(true) setFolderLoading(true)
setShowFolderDialog(false)
try { try {
const response = await fetch("/api/upload_path", { const response = await fetch("/api/upload_path", {
@ -133,11 +140,12 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
addTask(taskId) addTask(taskId)
setFolderPath("") setFolderPath("")
setShowFolderDialog(false) // Trigger search refresh after successful folder processing starts
window.dispatchEvent(new CustomEvent('knowledgeUpdated'))
} else if (response.ok) { } else if (response.ok) {
setFolderPath("") setFolderPath("")
setShowFolderDialog(false) window.dispatchEvent(new CustomEvent('knowledgeUpdated'))
} else { } else {
console.error("Folder upload failed:", result.error) console.error("Folder upload failed:", result.error)
} }
@ -152,6 +160,7 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
if (!bucketUrl.trim()) return if (!bucketUrl.trim()) return
setS3Loading(true) setS3Loading(true)
setShowS3Dialog(false)
try { try {
const response = await fetch("/api/upload_bucket", { const response = await fetch("/api/upload_bucket", {
@ -173,7 +182,8 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
addTask(taskId) addTask(taskId)
setBucketUrl("s3://") setBucketUrl("s3://")
setShowS3Dialog(false) // Trigger search refresh after successful S3 processing starts
window.dispatchEvent(new CustomEvent('knowledgeUpdated'))
} else { } else {
console.error("S3 upload failed:", result.error) console.error("S3 upload failed:", result.error)
} }
@ -220,11 +230,12 @@ export function KnowledgeDropdown({ active, variant = 'navigation' }: KnowledgeD
<> <>
<div ref={dropdownRef} className="relative"> <div ref={dropdownRef} className="relative">
<button <button
onClick={() => setIsOpen(!isOpen)} onClick={() => !(fileUploading || folderLoading || s3Loading) && setIsOpen(!isOpen)}
disabled={fileUploading || folderLoading || s3Loading}
className={cn( className={cn(
variant === 'button' variant === 'button'
? "rounded-lg h-12 px-4 flex items-center gap-2 bg-primary text-primary-foreground hover:bg-primary/90 transition-colors" ? "rounded-lg h-12 px-4 flex items-center gap-2 bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
: "text-sm group flex p-3 w-full justify-start font-medium cursor-pointer hover:bg-accent hover:text-accent-foreground rounded-lg transition-all", : "text-sm group flex p-3 w-full justify-start font-medium cursor-pointer hover:bg-accent hover:text-accent-foreground rounded-lg transition-all disabled:opacity-50 disabled:cursor-not-allowed",
variant === 'navigation' && active variant === 'navigation' && active
? "bg-accent text-accent-foreground shadow-sm" ? "bg-accent text-accent-foreground shadow-sm"
: variant === 'navigation' ? "text-foreground hover:text-accent-foreground" : "", : variant === 'navigation' ? "text-foreground hover:text-accent-foreground" : "",

View file

@ -280,6 +280,17 @@ function SearchPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) // Only run once on mount - ignore handleSearch dependency }, []) // Only run once on mount - ignore handleSearch dependency
// Listen for knowledge updates and refresh search
useEffect(() => {
const handleKnowledgeUpdate = () => {
console.log("Knowledge updated, refreshing search")
handleSearch()
}
window.addEventListener('knowledgeUpdated', handleKnowledgeUpdate)
return () => window.removeEventListener('knowledgeUpdated', handleKnowledgeUpdate)
}, [handleSearch])