[READ-ONLY] a fast, modern browser for the npm registry

fix: local filter on user & org page are now back to work (#472)

authored by

jyc.dev and committed by
GitHub
2dc73cf1 192c398f

+43 -30
+11
app/components/SearchBox.vue
··· 26 26 // Local input value (updates immediately as user types) 27 27 const searchQuery = ref((route.query.q as string) ?? '') 28 28 29 + // Pages that have their own local filter using ?q 30 + const pagesWithLocalFilter = new Set(['~username', 'org']) 31 + 29 32 // Debounced URL update for search query 30 33 const updateUrlQuery = debounce((value: string) => { 34 + // Don't navigate away from pages that use ?q for local filtering 35 + if (pagesWithLocalFilter.has(route.name as string)) { 36 + return 37 + } 31 38 if (route.name === 'search') { 32 39 router.replace({ query: { q: value || undefined } }) 33 40 return ··· 53 60 watch( 54 61 () => route.query.q, 55 62 urlQuery => { 63 + // Don't sync from pages that use ?q for local filtering 64 + if (pagesWithLocalFilter.has(route.name as string)) { 65 + return 66 + } 56 67 const value = (urlQuery as string) ?? '' 57 68 if (searchQuery.value !== value) { 58 69 searchQuery.value = value
+15 -14
app/pages/@[org].vue
··· 139 139 <main class="container flex-1 py-8 sm:py-12 w-full"> 140 140 <!-- Header --> 141 141 <header class="mb-8 pb-8 border-b border-border"> 142 - <div class="flex items-center gap-4 mb-4"> 142 + <div class="flex items-end gap-4"> 143 143 <!-- Org avatar placeholder --> 144 144 <div 145 145 class="w-16 h-16 rounded-lg bg-bg-muted border border-border flex items-center justify-center" ··· 155 155 {{ $t('org.public_packages', { count: formatNumber(packageCount) }, packageCount) }} 156 156 </p> 157 157 </div> 158 + 159 + <!-- Link to npmjs.com org page --> 160 + <nav aria-label="External links" class="ms-auto"> 161 + <a 162 + :href="`https://www.npmjs.com/org/${orgName}`" 163 + target="_blank" 164 + rel="noopener noreferrer" 165 + class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 166 + :title="$t('common.view_on_npm')" 167 + > 168 + <span class="i-carbon:logo-npm w-4 h-4" aria-hidden="true" /> 169 + npm 170 + </a> 171 + </nav> 158 172 </div> 159 - 160 - <!-- Link to npmjs.com org page --> 161 - <nav aria-label="External links"> 162 - <a 163 - :href="`https://www.npmjs.com/org/${orgName}`" 164 - target="_blank" 165 - rel="noopener noreferrer" 166 - class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 167 - > 168 - <span class="i-carbon-cube w-4 h-4" /> 169 - {{ $t('common.view_on_npm') }} 170 - </a> 171 - </nav> 172 173 </header> 173 174 174 175 <!-- Admin panels (when connected) -->
+16 -15
app/pages/~[username]/index.vue
··· 169 169 <main class="container flex-1 py-8 sm:py-12 w-full"> 170 170 <!-- Header --> 171 171 <header class="mb-8 pb-8 border-b border-border"> 172 - <div class="flex items-center gap-4 mb-4"> 172 + <div class="flex items-end gap-4"> 173 173 <!-- Avatar placeholder --> 174 174 <div 175 175 class="w-16 h-16 rounded-full bg-bg-muted border border-border flex items-center justify-center" ··· 185 185 {{ $t('org.public_packages', { count: formatNumber(results.total) }, results.total) }} 186 186 </p> 187 187 </div> 188 + 189 + <!-- Link to npmjs.com profile --> 190 + <nav aria-label="External links" class="ms-auto"> 191 + <a 192 + :href="`https://www.npmjs.com/~${username}`" 193 + target="_blank" 194 + rel="noopener noreferrer" 195 + class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 196 + :title="$t('common.view_on_npm')" 197 + > 198 + <span class="i-carbon:logo-npm w-4 h-4" aria-hidden="true" /> 199 + npm 200 + </a> 201 + </nav> 188 202 </div> 189 - 190 - <!-- Link to npmjs.com profile --> 191 - <nav aria-label="External links"> 192 - <a 193 - :href="`https://www.npmjs.com/~${username}`" 194 - target="_blank" 195 - rel="noopener noreferrer" 196 - class="link-subtle font-mono text-sm inline-flex items-center gap-1.5" 197 - > 198 - <span class="i-carbon-cube w-4 h-4" /> 199 - {{ $t('common.view_on_npm') }} 200 - </a> 201 - </nav> 202 203 </header> 203 204 204 205 <!-- Loading state --> ··· 233 234 <PackageListControls 234 235 v-model:filter="filterText" 235 236 v-model:sort="sortOption" 236 - :placeholder="$t('user.page.filter_placeholder', { count: packageCount })" 237 + :placeholder="$t('user.page.filter_placeholder', { count: results.total })" 237 238 :total-count="packageCount" 238 239 :filtered-count="filteredCount" 239 240 />
+1 -1
tests/interactions.spec.ts
··· 41 41 const searchInput = page.locator('input[type="search"]') 42 42 await searchInput.fill('vue') 43 43 44 - await page.waitForLoadState('domcontentloaded') 44 + await page.waitForURL(/\/search/) 45 45 46 46 await expect(page.locator('text=/found \\d+/i')).toBeVisible() 47 47