fix(ui): handle URL params in search page for command palette navigation
The search page now reads `q` and `mode` query parameters from the URL, enabling proper integration with the command palette's search/ask actions. Changes: - Read URL params using useSearchParams hook - Initialize form fields and active tab from URL params - Auto-trigger search/ask when arriving with URL params - Handle subsequent navigations while on the search page
This commit is contained in:
parent
728f036eeb
commit
33be80ab7c
1 changed files with 65 additions and 8 deletions
|
|
@ -1,6 +1,7 @@
|
|||
'use client'
|
||||
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useSearchParams } from 'next/navigation'
|
||||
import { AppShell } from '@/components/layout/AppShell'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { Input } from '@/components/ui/input'
|
||||
|
|
@ -23,14 +24,24 @@ import { AdvancedModelsDialog } from '@/components/search/AdvancedModelsDialog'
|
|||
import { SaveToNotebooksDialog } from '@/components/search/SaveToNotebooksDialog'
|
||||
|
||||
export default function SearchPage() {
|
||||
// URL params
|
||||
const searchParams = useSearchParams()
|
||||
const urlQuery = searchParams.get('q') || ''
|
||||
const urlMode = searchParams.get('mode') || 'ask'
|
||||
|
||||
// Tab state (controlled)
|
||||
const [activeTab, setActiveTab] = useState<'ask' | 'search'>(
|
||||
urlMode === 'search' ? 'search' : 'ask'
|
||||
)
|
||||
|
||||
// Search state
|
||||
const [searchQuery, setSearchQuery] = useState('')
|
||||
const [searchQuery, setSearchQuery] = useState(urlMode === 'search' ? urlQuery : '')
|
||||
const [searchType, setSearchType] = useState<'text' | 'vector'>('text')
|
||||
const [searchSources, setSearchSources] = useState(true)
|
||||
const [searchNotes, setSearchNotes] = useState(true)
|
||||
|
||||
// Ask state
|
||||
const [askQuestion, setAskQuestion] = useState('')
|
||||
const [askQuestion, setAskQuestion] = useState(urlMode === 'ask' ? urlQuery : '')
|
||||
|
||||
// Advanced models dialog
|
||||
const [showAdvancedModels, setShowAdvancedModels] = useState(false)
|
||||
|
|
@ -64,7 +75,11 @@ export default function SearchPage() {
|
|||
|
||||
const hasEmbeddingModel = !!modelDefaults?.default_embedding_model
|
||||
|
||||
const handleSearch = () => {
|
||||
// Track if we've already auto-triggered from URL params
|
||||
const hasAutoTriggeredRef = useRef(false)
|
||||
const lastUrlParamsRef = useRef({ q: '', mode: '' })
|
||||
|
||||
const handleSearch = useCallback(() => {
|
||||
if (!searchQuery.trim()) return
|
||||
|
||||
searchMutation.mutate({
|
||||
|
|
@ -75,7 +90,7 @@ export default function SearchPage() {
|
|||
search_notes: searchNotes,
|
||||
minimum_score: 0.2
|
||||
})
|
||||
}
|
||||
}, [searchQuery, searchType, searchSources, searchNotes, searchMutation])
|
||||
|
||||
const handleKeyPress = (e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
|
|
@ -83,7 +98,7 @@ export default function SearchPage() {
|
|||
}
|
||||
}
|
||||
|
||||
const handleAsk = () => {
|
||||
const handleAsk = useCallback(() => {
|
||||
if (!askQuestion.trim() || !modelDefaults?.default_chat_model) return
|
||||
|
||||
const models = customModels || {
|
||||
|
|
@ -93,14 +108,56 @@ export default function SearchPage() {
|
|||
}
|
||||
|
||||
ask.sendAsk(askQuestion, models)
|
||||
}
|
||||
}, [askQuestion, modelDefaults, customModels, ask])
|
||||
|
||||
// Auto-trigger search/ask when arriving with URL params
|
||||
useEffect(() => {
|
||||
// Skip if already triggered or no query
|
||||
if (hasAutoTriggeredRef.current || !urlQuery) return
|
||||
|
||||
// Wait for models to load before triggering ask
|
||||
if (urlMode === 'ask' && modelsLoading) return
|
||||
|
||||
hasAutoTriggeredRef.current = true
|
||||
|
||||
if (urlMode === 'search') {
|
||||
handleSearch()
|
||||
} else if (urlMode === 'ask' && modelDefaults?.default_chat_model) {
|
||||
handleAsk()
|
||||
}
|
||||
}, [urlQuery, urlMode, modelsLoading, modelDefaults, handleSearch, handleAsk])
|
||||
|
||||
// Handle URL param changes while on page (e.g., from command palette again)
|
||||
useEffect(() => {
|
||||
const currentQ = searchParams.get('q') || ''
|
||||
const currentMode = searchParams.get('mode') || 'ask'
|
||||
|
||||
// Check if URL params have changed
|
||||
if (currentQ !== lastUrlParamsRef.current.q || currentMode !== lastUrlParamsRef.current.mode) {
|
||||
lastUrlParamsRef.current = { q: currentQ, mode: currentMode }
|
||||
|
||||
if (currentQ) {
|
||||
// Update state based on mode
|
||||
if (currentMode === 'search') {
|
||||
setSearchQuery(currentQ)
|
||||
setActiveTab('search')
|
||||
// Reset trigger flag so we auto-trigger with new params
|
||||
hasAutoTriggeredRef.current = false
|
||||
} else {
|
||||
setAskQuestion(currentQ)
|
||||
setActiveTab('ask')
|
||||
hasAutoTriggeredRef.current = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [searchParams])
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
<div className="p-4 md:p-6">
|
||||
<h1 className="text-xl md:text-2xl font-bold mb-4 md:mb-6">Ask and Search</h1>
|
||||
|
||||
<Tabs defaultValue="ask" className="w-full space-y-6">
|
||||
<Tabs value={activeTab} onValueChange={(v) => setActiveTab(v as 'ask' | 'search')} className="w-full space-y-6">
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Choose a mode</p>
|
||||
<TabsList aria-label="Ask or search your knowledge base" className="w-full max-w-xl">
|
||||
|
|
|
|||
Loading…
Reference in a new issue