From 09a6337c6f6957f49a0b72be50d660f6119a81e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:18:28 +0000 Subject: [PATCH] fix(ui): prevent search input from clearing on each keystroke and add dedicated /search page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The debounceSearch() function in files.html called clearFullTextSearch() when the query was shorter than 2 characters. Since clearFullTextSearch() sets input.value = '', every single keystroke was immediately erased — users could paste text but not type. Fix: debounceSearch now only hides the results panel for short queries without touching the input value. Also adds a dedicated /search page with Google-style results showing content previews (document title, filename, type badges, tag badges, sender, and OCR text snippets with highlighted matches). Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- app/views/__init__.py | 2 + app/views/search.py | 38 ++++++ frontend/templates/base.html | 2 + frontend/templates/files.html | 5 +- frontend/templates/search.html | 241 +++++++++++++++++++++++++++++++++ tests/test_views_search.py | 41 ++++++ 6 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 app/views/search.py create mode 100644 frontend/templates/search.html create mode 100644 tests/test_views_search.py diff --git a/app/views/__init__.py b/app/views/__init__.py index 12057a41..e979f101 100644 --- a/app/views/__init__.py +++ b/app/views/__init__.py @@ -9,6 +9,7 @@ from app.views.filemanager import router as filemanager_router # Import all the view routers from app.views.general import router as general_router +from app.views.search import router as search_router from app.views.google_drive import router as google_drive_router from app.views.license_routes import router as license_router # Add the license router from app.views.onedrive import router as onedrive_router @@ -27,3 +28,4 @@ router.include_router(google_drive_router) router.include_router(license_router) # Include the license router router.include_router(settings_router) router.include_router(filemanager_router) +router.include_router(search_router) diff --git a/app/views/search.py b/app/views/search.py new file mode 100644 index 00000000..092658b4 --- /dev/null +++ b/app/views/search.py @@ -0,0 +1,38 @@ +""" +Search view for dedicated full-text document search page. + +Provides a Google-style search experience with content previews, +powered by Meilisearch via the existing ``/api/search`` backend. +""" + +import logging +from typing import Optional + +from fastapi import Query, Request + +from app.views.base import APIRouter, require_login, templates + +logger = logging.getLogger(__name__) + +router = APIRouter() + + +@router.get("/search") +@require_login +def search_page( + request: Request, + q: Optional[str] = Query(None, max_length=512, description="Full-text search query"), +): + """Render the dedicated search page. + + The page loads with an empty search box (or pre-filled when *q* is given). + Actual searching is performed client-side via ``fetch('/api/search')`` so + that results stream in without a full page reload. + """ + return templates.TemplateResponse( + "search.html", + { + "request": request, + "query": q or "", + }, + ) diff --git a/frontend/templates/base.html b/frontend/templates/base.html index d39e6e44..ebe09847 100644 --- a/frontend/templates/base.html +++ b/frontend/templates/base.html @@ -59,6 +59,7 @@ Home Upload Files + Search