feat(search) : add server-side search on name + reference in PieceSelect, ProductSelect and ComposantSelect

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-03-24 17:03:01 +01:00
parent d0dc01deb1
commit 5485bac339
3 changed files with 27 additions and 6 deletions

View File

@@ -11,6 +11,7 @@
option-label="name"
:disabled="disabled"
@update:modelValue="updateValue"
@search="handleSearch"
>
<template #option-description="{ option }">
<span class="text-xs text-base-content/60">
@@ -60,11 +61,11 @@ const loading = computed(() => localLoading.value || globalLoading.value)
const composantOptions = computed(() => localComposants.value)
const loadFilteredComposants = async () => {
const loadFilteredComposants = async (search = '') => {
if (!props.typeComposantId) return
localLoading.value = true
try {
const result = await loadComposants({ typeComposantId: props.typeComposantId, itemsPerPage: 500, force: true })
const result = await loadComposants({ typeComposantId: props.typeComposantId, search, itemsPerPage: 200, force: true })
if (result.success && result.data?.items) {
localComposants.value = result.data.items
}
@@ -77,6 +78,12 @@ const loadFilteredComposants = async () => {
}
}
let searchDebounce: ReturnType<typeof setTimeout> | null = null
const handleSearch = (term: string) => {
if (searchDebounce) clearTimeout(searchDebounce)
searchDebounce = setTimeout(() => loadFilteredComposants(term.trim()), 300)
}
onMounted(() => {
loadFilteredComposants()
})

View File

@@ -11,6 +11,7 @@
option-label="name"
:disabled="disabled"
@update:modelValue="updateValue"
@search="handleSearch"
>
<template #option-description="{ option }">
<span class="text-xs text-base-content/60">
@@ -60,11 +61,11 @@ const loading = computed(() => localLoading.value || globalLoading.value)
const pieceOptions = computed(() => localPieces.value)
const loadFilteredPieces = async () => {
const loadFilteredPieces = async (search = '') => {
if (!props.typePieceId) return
localLoading.value = true
try {
const result = await loadPieces({ typePieceId: props.typePieceId, itemsPerPage: 500, force: true })
const result = await loadPieces({ typePieceId: props.typePieceId, search, itemsPerPage: 200, force: true })
if (result.success && result.data?.items) {
localPieces.value = result.data.items
}
@@ -77,6 +78,12 @@ const loadFilteredPieces = async () => {
}
}
let searchDebounce: ReturnType<typeof setTimeout> | null = null
const handleSearch = (term: string) => {
if (searchDebounce) clearTimeout(searchDebounce)
searchDebounce = setTimeout(() => loadFilteredPieces(term.trim()), 300)
}
onMounted(() => {
loadFilteredPieces()
})

View File

@@ -11,6 +11,7 @@
option-label="name"
:disabled="disabled"
@update:modelValue="updateValue"
@search="handleSearch"
>
<template #option-description="{ option }">
<span class="text-xs text-base-content/60">
@@ -60,11 +61,11 @@ const loading = computed(() => localLoading.value || globalLoading.value)
const productOptions = computed(() => localProducts.value)
const loadFilteredProducts = async () => {
const loadFilteredProducts = async (search = '') => {
if (!props.typeProductId) return
localLoading.value = true
try {
const result = await loadProducts({ typeProductId: props.typeProductId, itemsPerPage: 500, force: true })
const result = await loadProducts({ typeProductId: props.typeProductId, search, itemsPerPage: 200, force: true })
if (result.success && result.data?.items) {
localProducts.value = result.data.items
}
@@ -77,6 +78,12 @@ const loadFilteredProducts = async () => {
}
}
let searchDebounce: ReturnType<typeof setTimeout> | null = null
const handleSearch = (term: string) => {
if (searchDebounce) clearTimeout(searchDebounce)
searchDebounce = setTimeout(() => loadFilteredProducts(term.trim()), 300)
}
onMounted(() => {
loadFilteredProducts()
})