[backport rh-test] add fuzzy searching to assets dialog (#6287)

Backport of #6286 to `rh-test`

Automatically created by backport workflow.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6287-backport-rh-test-add-fuzzy-searching-to-assets-dialog-2976d73d365081c5bb2cf6ea67cfd59e)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Christian Byrne <cbyrne@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Comfy Org PR Bot
2025-10-26 06:15:57 +09:00
committed by GitHub
parent 718655ae65
commit 088a57a43c
2 changed files with 141 additions and 27 deletions

View File

@@ -1,3 +1,5 @@
import { useFuse } from '@vueuse/integrations/useFuse'
import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
import { computed, ref } from 'vue'
import type { Ref } from 'vue'
@@ -15,19 +17,6 @@ function filterByCategory(category: string) {
}
}
function filterByQuery(query: string) {
return (asset: AssetItem) => {
if (!query) return true
const lowerQuery = query.toLowerCase()
const description = getAssetDescription(asset)
return (
asset.name.toLowerCase().includes(lowerQuery) ||
(description && description.toLowerCase().includes(lowerQuery)) ||
asset.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))
)
}
}
function filterByFileFormats(formats: string[]) {
return (asset: AssetItem) => {
if (formats.length === 0) return true
@@ -160,9 +149,31 @@ export function useAssetBrowser(
return assets.value.filter(filterByCategory(selectedCategory.value))
})
const fuseOptions: UseFuseOptions<AssetItem> = {
fuseOptions: {
keys: [
{ name: 'name', weight: 0.4 },
{ name: 'tags', weight: 0.3 }
],
threshold: 0.4, // Higher threshold for typo tolerance (0.0 = exact, 1.0 = match all)
ignoreLocation: true, // Search anywhere in the string, not just at the beginning
includeScore: true
},
matchAllWhenSearchEmpty: true
}
const { results: fuseResults } = useFuse(
searchQuery,
categoryFilteredAssets,
fuseOptions
)
const searchFiltered = computed(() =>
fuseResults.value.map((result) => result.item)
)
const filteredAssets = computed(() => {
const filtered = categoryFilteredAssets.value
.filter(filterByQuery(searchQuery.value))
const filtered = searchFiltered.value
.filter(filterByFileFormats(filters.value.fileFormats))
.filter(filterByBaseModels(filters.value.baseModels))