From fe834a37a499da446f24cc2f612ec3c184f5eb9b Mon Sep 17 00:00:00 2001 From: timmy Date: Fri, 7 Aug 2026 13:34:26 +0000 Subject: [PATCH] feat: preview global search results in dashboard (#197) --- README.md | 9 ++- frontend/index.html | 139 ++++++++++++++++++++++++++++++++-- frontend/search-preview.js | 48 ++++++++++++ src/gitea_proxy.py | 39 ++++++++++ src/main.py | 21 +++++ tests/test_command_palette.py | 74 ++++++++++++++++++ tests/test_global_search.py | 96 +++++++++++++++++++++++ tests/test_views.py | 14 ++++ 8 files changed, 432 insertions(+), 8 deletions(-) create mode 100644 frontend/search-preview.js diff --git a/README.md b/README.md index 9430840..e922b6a 100644 --- a/README.md +++ b/README.md @@ -48,8 +48,13 @@ Gitea connection directly, request `user`, `repos`, `issues`, and `pull_requests`. Press `Ctrl/Cmd+K` in the dashboard to search commands plus issues and pull requests across every repository visible to the configured Gitea token. Remote search starts after two characters, is debounced, -and keeps local commands usable if Gitea search is unavailable. The bounded API is -also available at `GET /api/v1/search?q=&limit=<1-25>`. Never commit the token +and keeps local commands usable if Gitea search is unavailable. Selecting a remote +result opens a mobile-safe, read-only preview without discarding the search query; +open unassigned issues can be claimed in place and handed into My Work after Gitea +confirms the assignment. Closed work and pull requests remain read-only with a safe +canonical Gitea link. The bounded APIs are available at +`GET /api/v1/search?q=&limit=<1-25>` and +`GET /api/v1/repos///issues//preview?kind=issue|pull`. Never commit the token or place it in a tracked configuration file. For service monitoring, GET `/healthz` is a liveness check that confirms the diff --git a/frontend/index.html b/frontend/index.html index 10c457d..c2871f4 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -176,6 +176,14 @@ textarea { resize: vertical; min-height: 120px; } .find-work-detail { min-width:0; display:grid; gap:10px; padding:10px; border-radius:10px; background:#0b1526; } .find-work-description { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; } .find-work-detail a { display:flex; align-items:center; justify-content:center; border:1px solid #60a5fa; border-radius:10px; font-weight:700; } +.search-preview { position:fixed; inset:0; z-index:60; display:none; justify-content:flex-end; background:rgba(5,12,21,.72); backdrop-filter:blur(4px); } +.search-preview.open { display:flex; } +.search-preview-panel { box-sizing:border-box; width:min(560px,100%); height:100dvh; overflow:auto; display:grid; align-content:start; gap:12px; padding:18px; padding-bottom:calc(18px + env(safe-area-inset-bottom)); background:#0b1526; border-left:1px solid #2a496e; overflow-wrap:anywhere; } +.search-preview-header { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; } +.search-preview-header button, .search-preview-actions button, .search-preview-actions a { min-height:44px; } +.search-preview-body { margin:0; white-space:pre-wrap; overflow-wrap:anywhere; } +.search-preview-actions { position:sticky; bottom:0; display:grid; gap:8px; padding:10px 0; padding-bottom:calc(10px + env(safe-area-inset-bottom)); background:#0b1526; } +.search-preview-actions a { display:flex; align-items:center; justify-content:center; border:1px solid #60a5fa; border-radius:10px; font-weight:700; } @media(max-width:320px) { .find-work-panel { padding:12px; overflow-x:hidden; } .find-work-card { min-width:0; } .my-work-actions { width:100%; } .my-work-actions button { flex:1 1 100%; } } .create-issue-sheet { position:fixed; inset:0; z-index:57; display:none; justify-content:flex-end; background:rgba(5,12,21,.72); backdrop-filter:blur(4px); } .create-issue-sheet.open { display:flex; } @@ -221,6 +229,7 @@ textarea { resize: vertical; min-height: 120px; } .review-sheet-panel { width:100%; border-left:0; padding:14px; } .update-sheet-panel { width:100%; border-left:0; padding:14px; } .issue-sheet-panel { width:100%; border-left:0; padding:14px; } + .search-preview-panel { width:100%; border-left:0; padding:14px; padding-bottom:calc(14px + env(safe-area-inset-bottom)); overflow-x:hidden; } .create-issue-panel { width:100%; border-left:0; padding:14px; } .pull-sheet-panel { width:100%; border-left:0; padding:14px; } } @@ -339,6 +348,25 @@ textarea { resize: vertical; min-height: 120px; }
+ +