From 33be80ab7c340bfd4747a63733a21cccc7a38b87 Mon Sep 17 00:00:00 2001 From: LUIS NOVO Date: Mon, 1 Dec 2025 20:46:49 -0300 Subject: [PATCH] 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 --- frontend/src/app/(dashboard)/search/page.tsx | 73 +++++++++++++++++--- 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/(dashboard)/search/page.tsx b/frontend/src/app/(dashboard)/search/page.tsx index d9c2522..c84ad6e 100644 --- a/frontend/src/app/(dashboard)/search/page.tsx +++ b/frontend/src/app/(dashboard)/search/page.tsx @@ -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 (

Ask and Search

- + setActiveTab(v as 'ask' | 'search')} className="w-full space-y-6">

Choose a mode