Add saved searches with CRUD API and UI sidebar

Add extension field to search results and display it
Add active filter badges and save button to search header
This commit is contained in:
2026-05-27 08:39:52 -04:00
parent aa2c05b05f
commit e3c25b5b09
6 changed files with 318 additions and 2 deletions
+28
View File
@@ -182,6 +182,7 @@ class AdvancedSearchResultItem(BaseModel):
score: float = Field(description="TF-IDF relevance score")
snippet: str = Field(description="Content excerpt with <mark> highlights")
modified: str = Field(description="ISO 8601 modification timestamp")
extension: str = Field(default="", description="File extension")
class SearchFacets(BaseModel):
@@ -561,6 +562,7 @@ from backend.secret_redactor import redact_file_content
from backend.pdf_export import generate_pdf, build_pdf_html
from backend.share import create_share, get_share_by_token, record_access, revoke_share, list_shares
from backend.webhooks import get_webhooks, create_webhook, update_webhook, delete_webhook, dispatch_webhooks
from backend.saved_searches import get_saved, save_search, delete_saved
app.include_router(auth_router)
@@ -1017,6 +1019,32 @@ async def api_toggle_bookmark(req: BookmarkToggleRequest, current_user=Depends(r
return {"bookmarked": is_now_bookmarked}
@app.get("/api/saved-searches")
async def api_saved_searches(current_user=Depends(require_auth)):
username = current_user.get("username")
if not username:
raise HTTPException(401)
return get_saved(username)
@app.post("/api/saved-searches")
async def api_save_search(body: dict = Body(...), current_user=Depends(require_auth)):
username = current_user.get("username")
if not username:
raise HTTPException(401)
return save_search(username, body)
@app.delete("/api/saved-searches/{search_id}")
async def api_delete_saved_search(search_id: str, current_user=Depends(require_auth)):
username = current_user.get("username")
if not username:
raise HTTPException(401)
if not delete_saved(username, search_id):
raise HTTPException(404, "Not found")
return {"status": "deleted"}
@app.get("/api/browse/{vault_name}", response_model=BrowseResponse)
async def api_browse(vault_name: str, path: str = "", current_user=Depends(require_auth)):
"""Browse directories and files in a vault at a given path level.