Fix: Normalizar array de ubicaciones y agregar soporte para loading
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 48s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 48s
Problema identificado:
- El array de ubicaciones viene como array de strings simples,
no como objetos con {label, value}
- Ejemplo: ["breñales, la union, lempira", "buenos aires, ..."]
Solución implementada:
1. Normalización de datos:
- Crear computed normalizedUbicaciones que transforma el array
- Si el item es string: usa el string como label y value
- Si el item es objeto: usa sus propiedades label y value
- Filtrar null/undefined durante la transformación
2. Agregar prop loading:
- Agregada prop opcional loading?: boolean
- Pasar loading al UInputMenu para mostrar spinner
3. Simplificar lógica de filtrado:
- Usar normalizedUbicaciones como base
- Filtrar por query sin errores de toLowerCase
4. Mejorar selectedUbicacionesObjects:
- Usar normalizedUbicaciones para encontrar seleccionados
- Comparar con value normalizado
Ahora el componente:
- Muestra todas las ubicaciones correctamente
- Funciona con array de strings o array de objetos
- Muestra animación de loading cuando carga datos
- Búsqueda funciona sin errores
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<UInputMenu
|
||||
:model-value="selectedUbicacionesObjects"
|
||||
:items="filteredItems"
|
||||
:loading="loading"
|
||||
multiple
|
||||
label-key="label"
|
||||
value-key="value"
|
||||
@@ -62,7 +63,8 @@ interface UbicacionItem {
|
||||
|
||||
const props = defineProps<{
|
||||
selectedUbicaciones: string[]
|
||||
ubicaciones: UbicacionItem[]
|
||||
ubicaciones: UbicacionItem[] | string[]
|
||||
loading?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -72,24 +74,43 @@ const emit = defineEmits<{
|
||||
// State
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Computed - Normalize ubicaciones to InputMenuItem format
|
||||
const normalizedUbicaciones = computed((): InputMenuItem[] => {
|
||||
if (!Array.isArray(props.ubicaciones)) return []
|
||||
|
||||
return props.ubicaciones
|
||||
.filter(u => u) // Filter out null/undefined
|
||||
.map(u => {
|
||||
// If it's already an object with label and value, use it
|
||||
if (typeof u === 'object' && u.label && u.value) {
|
||||
return { label: u.label, value: u.value }
|
||||
}
|
||||
// If it's a string, use it as both label and value
|
||||
if (typeof u === 'string') {
|
||||
return { label: u, value: u }
|
||||
}
|
||||
return null
|
||||
})
|
||||
.filter((u): u is InputMenuItem => u !== null)
|
||||
})
|
||||
|
||||
// Computed - Get selected ubicaciones as objects for InputMenu
|
||||
const selectedUbicacionesObjects = computed(() => {
|
||||
return props.ubicaciones.filter(u => props.selectedUbicaciones.includes(u.value))
|
||||
return normalizedUbicaciones.value.filter(u =>
|
||||
props.selectedUbicaciones.includes(u.value as string)
|
||||
)
|
||||
})
|
||||
|
||||
// Computed - Filter items based on search
|
||||
const filteredItems = computed((): InputMenuItem[] => {
|
||||
const query = searchQuery.value.trim().toLowerCase()
|
||||
|
||||
// Filter out undefined/null items and ensure they have label and value
|
||||
const validUbicaciones = props.ubicaciones.filter(u => u && u.label && u.value)
|
||||
|
||||
if (!query) {
|
||||
return validUbicaciones
|
||||
return normalizedUbicaciones.value
|
||||
}
|
||||
|
||||
return validUbicaciones.filter(u =>
|
||||
u.label.toLowerCase().includes(query)
|
||||
return normalizedUbicaciones.value.filter(u =>
|
||||
u.label && typeof u.label === 'string' && u.label.toLowerCase().includes(query)
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user