feat: unified search panel — progressive keyword+semantic results (#80)
* feat: unify search panel — remove keyword/semantic toggle, progressive results Replace separate keyword/semantic mode toggle with a unified search that streams results progressively: keyword results appear first (<500ms), then hybrid results augment the list (~1-2s). Loading spinner shows in the input field while semantic search runs. Stale requests are discarded via generation counter for safe rapid typing. - Extract search logic into useUnifiedSearch hook (code health 9.26+) - 300ms debounce, 5s timeout on hybrid, graceful fallback on errors - 15 tests covering progressive search, spinner, stale results, failures Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add design wireframes for unified search panel Two frames showing the search panel states: - "keyword results loaded, semantic loading" (with spinner) - "all results loaded" (no spinner, more results including semantic) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: coverage artifacts --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,30 +23,30 @@
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">19.67% </span>
|
||||
<span class="strong">88.23% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>12/61</span>
|
||||
<span class='fraction'>15/17</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">22.85% </span>
|
||||
<span class="strong">80% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>8/35</span>
|
||||
<span class='fraction'>12/15</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">16.07% </span>
|
||||
<span class="strong">84.61% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>9/56</span>
|
||||
<span class='fraction'>11/13</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">19.67% </span>
|
||||
<span class="strong">88.23% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>12/61</span>
|
||||
<span class='fraction'>15/17</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='status-line low'></div>
|
||||
<div class='status-line high'></div>
|
||||
<div class="pad1">
|
||||
<table class="coverage-summary">
|
||||
<thead>
|
||||
@@ -79,18 +79,18 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr>
|
||||
<td class="file low" data-value="badge.tsx"><a href="badge.tsx.html">badge.tsx</a></td>
|
||||
<td data-value="33.33" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 33%"></div><div class="cover-empty" style="width: 67%"></div></div>
|
||||
<td class="file high" data-value="badge.tsx"><a href="badge.tsx.html">badge.tsx</a></td>
|
||||
<td data-value="100" class="pic high">
|
||||
<div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
|
||||
</td>
|
||||
<td data-value="33.33" class="pct low">33.33%</td>
|
||||
<td data-value="3" class="abs low">1/3</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="4" class="abs low">0/4</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="1" class="abs low">0/1</td>
|
||||
<td data-value="33.33" class="pct low">33.33%</td>
|
||||
<td data-value="3" class="abs low">1/3</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="3" class="abs high">3/3</td>
|
||||
<td data-value="75" class="pct medium">75%</td>
|
||||
<td data-value="4" class="abs medium">3/4</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="1" class="abs high">1/1</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="3" class="abs high">3/3</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -109,48 +109,18 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="card.tsx"><a href="card.tsx.html">card.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
<td class="file high" data-value="dialog.tsx"><a href="dialog.tsx.html">dialog.tsx</a></td>
|
||||
<td data-value="80" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 80%"></div><div class="cover-empty" style="width: 20%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="7" class="abs low">0/7</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="0" class="abs high">0/0</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="7" class="abs low">0/7</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="7" class="abs low">0/7</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file medium" data-value="dialog.tsx"><a href="dialog.tsx.html">dialog.tsx</a></td>
|
||||
<td data-value="70" class="pic medium">
|
||||
<div class="chart"><div class="cover-fill" style="width: 70%"></div><div class="cover-empty" style="width: 30%"></div></div>
|
||||
</td>
|
||||
<td data-value="70" class="pct medium">70%</td>
|
||||
<td data-value="10" class="abs medium">7/10</td>
|
||||
<td data-value="66.66" class="pct medium">66.66%</td>
|
||||
<td data-value="6" class="abs medium">4/6</td>
|
||||
<td data-value="70" class="pct medium">70%</td>
|
||||
<td data-value="10" class="abs medium">7/10</td>
|
||||
<td data-value="70" class="pct medium">70%</td>
|
||||
<td data-value="10" class="abs medium">7/10</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="dropdown-menu.tsx"><a href="dropdown-menu.tsx.html">dropdown-menu.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="15" class="abs low">0/15</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="15" class="abs low">0/15</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="15" class="abs low">0/15</td>
|
||||
<td data-value="80" class="pct high">80%</td>
|
||||
<td data-value="10" class="abs high">8/10</td>
|
||||
<td data-value="83.33" class="pct high">83.33%</td>
|
||||
<td data-value="6" class="abs high">5/6</td>
|
||||
<td data-value="80" class="pct high">80%</td>
|
||||
<td data-value="10" class="abs high">8/10</td>
|
||||
<td data-value="80" class="pct high">80%</td>
|
||||
<td data-value="10" class="abs high">8/10</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -168,81 +138,6 @@
|
||||
<td data-value="1" class="abs high">1/1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="scroll-area.tsx"><a href="scroll-area.tsx.html">scroll-area.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="5" class="abs low">0/5</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="select.tsx"><a href="select.tsx.html">select.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="10" class="abs low">0/10</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="7" class="abs low">0/7</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="10" class="abs low">0/10</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="10" class="abs low">0/10</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="separator.tsx"><a href="separator.tsx.html">separator.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="1" class="abs low">0/1</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="1" class="abs low">0/1</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="1" class="abs low">0/1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="tabs.tsx"><a href="tabs.tsx.html">tabs.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="5" class="abs low">0/5</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="4" class="abs low">0/4</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="5" class="abs low">0/5</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file low" data-value="tooltip.tsx"><a href="tooltip.tsx.html">tooltip.tsx</a></td>
|
||||
<td data-value="0" class="pic low">
|
||||
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
|
||||
</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="4" class="abs low">0/4</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="2" class="abs low">0/2</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="4" class="abs low">0/4</td>
|
||||
<td data-value="0" class="pct low">0%</td>
|
||||
<td data-value="4" class="abs low">0/4</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -251,7 +146,7 @@
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-02-22T09:10:55.587Z
|
||||
at 2026-02-25T20:19:25.575Z
|
||||
</div>
|
||||
<script src="../../../prettify.js"></script>
|
||||
<script>
|
||||
|
||||
Reference in New Issue
Block a user