fix: Update private key field in chat integration documentation
- Change the private key field name from "prvkey" to "prvkey_hex" in the CHAT_INTEGRATION.md file for clarity and consistency with expected data formats. feat: Add Fuzzy Search Component and Composable - Introduce a new FuzzySearch component for Vue 3, leveraging Fuse.js for intelligent search capabilities. - Implement a useFuzzySearch composable for flexible search functionality, allowing configuration of search options. - Create demo and README files to showcase usage and features of the fuzzy search implementation. - Update package.json and package-lock.json to include @vueuse/integrations version 13.6.0 for enhanced performance.
This commit is contained in:
parent
37a539bc2d
commit
3d1bc94183
8 changed files with 783 additions and 1 deletions
116
src/components/ui/fuzzy-search/FuzzySearchDemo.vue
Normal file
116
src/components/ui/fuzzy-search/FuzzySearchDemo.vue
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { FuzzySearch, useFuzzySearch } from './index'
|
||||
|
||||
// Sample data for demonstration
|
||||
interface Product {
|
||||
id: number
|
||||
name: string
|
||||
description: string
|
||||
category: string
|
||||
price: number
|
||||
}
|
||||
|
||||
const products = ref<Product[]>([
|
||||
{ id: 1, name: 'Laptop', description: 'High-performance laptop for work and gaming', category: 'Electronics', price: 1200 },
|
||||
{ id: 2, name: 'Smartphone', description: 'Latest smartphone with advanced features', category: 'Electronics', price: 800 },
|
||||
{ id: 3, name: 'Headphones', description: 'Wireless noise-cancelling headphones', category: 'Audio', price: 200 },
|
||||
{ id: 4, name: 'Coffee Maker', description: 'Automatic coffee maker for home use', category: 'Kitchen', price: 150 },
|
||||
{ id: 5, name: 'Running Shoes', description: 'Comfortable running shoes for athletes', category: 'Sports', price: 120 },
|
||||
{ id: 6, name: 'Backpack', description: 'Durable backpack for travel and daily use', category: 'Travel', price: 80 },
|
||||
{ id: 7, name: 'Tablet', description: 'Portable tablet for entertainment and work', category: 'Electronics', price: 500 },
|
||||
{ id: 8, name: 'Blender', description: 'High-speed blender for smoothies and shakes', category: 'Kitchen', price: 100 },
|
||||
])
|
||||
|
||||
// Fuzzy search configuration
|
||||
const searchOptions = {
|
||||
fuseOptions: {
|
||||
keys: ['name', 'description', 'category'],
|
||||
threshold: 0.3,
|
||||
distance: 100,
|
||||
ignoreLocation: true,
|
||||
useExtendedSearch: false,
|
||||
minMatchCharLength: 1,
|
||||
shouldSort: true,
|
||||
findAllMatches: false,
|
||||
location: 0,
|
||||
isCaseSensitive: false,
|
||||
},
|
||||
resultLimit: 10,
|
||||
matchAllWhenSearchEmpty: true,
|
||||
minSearchLength: 1,
|
||||
}
|
||||
|
||||
// Use the fuzzy search composable
|
||||
const {
|
||||
searchQuery,
|
||||
results,
|
||||
filteredItems,
|
||||
isSearching,
|
||||
resultCount,
|
||||
clearSearch
|
||||
} = useFuzzySearch(products, searchOptions)
|
||||
|
||||
// Handle search results
|
||||
const handleSearchResults = (results: Product[]) => {
|
||||
console.log('Search results:', results)
|
||||
}
|
||||
|
||||
const handleSearch = (query: string) => {
|
||||
console.log('Search query:', query)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-6 max-w-4xl mx-auto">
|
||||
<h1 class="text-3xl font-bold mb-6">Fuzzy Search Demo</h1>
|
||||
|
||||
<!-- Fuzzy Search Component -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4">Search Products</h2>
|
||||
<FuzzySearch
|
||||
:data="products"
|
||||
:options="searchOptions"
|
||||
placeholder="Search products by name, description, or category..."
|
||||
@search="handleSearch"
|
||||
@results="handleSearchResults"
|
||||
class="max-w-md"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Search Results -->
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-semibold mb-4">
|
||||
Results ({{ resultCount }} found)
|
||||
<span v-if="isSearching" class="text-sm font-normal text-muted-foreground">
|
||||
- Searching for "{{ searchQuery }}"
|
||||
</span>
|
||||
</h2>
|
||||
|
||||
<div v-if="filteredItems.length === 0 && isSearching" class="text-center py-8 text-muted-foreground">
|
||||
No products found matching your search.
|
||||
</div>
|
||||
|
||||
<div v-else class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div
|
||||
v-for="product in filteredItems"
|
||||
:key="product.id"
|
||||
class="border rounded-lg p-4 hover:shadow-md transition-shadow"
|
||||
>
|
||||
<h3 class="font-semibold text-lg">{{ product.name }}</h3>
|
||||
<p class="text-sm text-muted-foreground mb-2">{{ product.description }}</p>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm bg-secondary px-2 py-1 rounded">{{ product.category }}</span>
|
||||
<span class="font-semibold">${{ product.price }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Raw Results (for debugging) -->
|
||||
<div v-if="isSearching" class="mt-8 p-4 bg-muted rounded-lg">
|
||||
<h3 class="font-semibold mb-2">Raw Search Results (with scoring)</h3>
|
||||
<pre class="text-xs overflow-auto">{{ JSON.stringify(results, null, 2) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Loading…
Add table
Add a link
Reference in a new issue