Feat: Implementar selección múltiple y filtrado de subcategorías
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 1m5s

- Cambiar subcategoriaActiva a subcategoriasActivas (array) para permitir selección múltiple
- Agregar flex-wrap a barra de subcategorías en lugar de scroll horizontal
- Implementar toggleSubcategoria para agregar/quitar subcategorías
- Pasar subcategoriasActivas a FormularioMuestra como prop
- Agregar helpers deberMostrarSeccion para filtrar inputs
- Aplicar v-if a todas las secciones según subcategorías activas
- Botón Limpiar Todo para resetear filtros
This commit is contained in:
2025-10-18 14:47:38 -06:00
parent b639aa24bb
commit 8cf62f0057
3 changed files with 66 additions and 22 deletions

View File

@@ -7,7 +7,7 @@
</h4>
<!-- Selector de Familia de Fragancia/Aroma -->
<div class="form-section">
<div v-if="mostrarFraganciaAroma" class="form-section">
<CataSelectorFamilia
tipo="fragancia-aroma"
label="Familia de Fragancia y Aroma"
@@ -17,7 +17,7 @@
</div>
<!-- Selector de Familia de Sabor -->
<div class="form-section">
<div v-if="mostrarSaborOrganoleptica" class="form-section">
<CataSelectorFamilia
tipo="sabor"
label="Familia de Sabor"
@@ -34,7 +34,7 @@
</h4>
<!-- Sliders de Fragancia -->
<div class="form-section">
<div v-if="mostrarFraganciaSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('fragancia') }">Fragancia</h5>
<div class="flex gap-2">
@@ -63,7 +63,7 @@
</div>
<!-- Sliders de Aroma -->
<div class="form-section">
<div v-if="mostrarAromaSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('aroma') }">Aroma</h5>
<div class="flex gap-2">
@@ -92,7 +92,7 @@
</div>
<!-- Sliders de Sabor -->
<div class="form-section">
<div v-if="mostrarSaborSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('sabor') }">Sabor</h5>
<div class="flex gap-2">
@@ -121,7 +121,7 @@
</div>
<!-- Sliders de Sabor Residual -->
<div class="form-section">
<div v-if="mostrarSaborResidualSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('saborResidual') }">Sabor Residual</h5>
<div class="flex gap-2">
@@ -150,7 +150,7 @@
</div>
<!-- Sliders de Acidez -->
<div class="form-section">
<div v-if="mostrarAcidezSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('acidez') }">Acidez</h5>
<div class="flex gap-2">
@@ -179,7 +179,7 @@
</div>
<!-- Sliders de Dulzor -->
<div class="form-section">
<div v-if="mostrarDulzorSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('dulzor') }">Dulzor</h5>
<div class="flex gap-2">
@@ -208,7 +208,7 @@
</div>
<!-- Sliders de Sensación en Boca -->
<div class="form-section">
<div v-if="mostrarSensacionBocaSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('sensacionBoca') }">Sensación en la Boca</h5>
<div class="flex gap-2">
@@ -237,7 +237,7 @@
</div>
<!-- Sliders de Impresión Global -->
<div class="form-section">
<div v-if="mostrarImpresionGlobalSlider" class="form-section">
<div class="flex items-center justify-between mb-3">
<h5 class="form-section-title cata-text" :style="{ color: getCategoryColor('impresionGlobal') }">Impresión Global</h5>
<div class="flex gap-2">
@@ -707,7 +707,7 @@
<script setup lang="ts">
import type { Muestra, NotaSeleccionada, TipoDefecto, SensacionBoca, GustoPredominante } from '~/types/catacion'
import type { TabCatacion } from '~/composables/useCatacion'
import type { TabCatacion, Subcategoria } from '~/composables/useCatacion'
import { SENSACIONES_BOCA, GUSTOS_PREDOMINANTES, TIPOS_DEFECTOS } from '~/types/catacion'
interface FormularioMuestraProps {
@@ -715,9 +715,13 @@ interface FormularioMuestraProps {
muestra: Muestra
/** Tab activa */
tabActiva: TabCatacion
/** Subcategorías activas (filtros) */
subcategoriasActivas?: Subcategoria[]
}
const props = defineProps<FormularioMuestraProps>()
const props = withDefaults(defineProps<FormularioMuestraProps>(), {
subcategoriasActivas: () => [],
})
const { actualizarIntensidad: actualizarIntensidadCatacion } = useCatacion()
const { getCategoryColor } = useCategoryColors()
@@ -727,6 +731,31 @@ const sensacionesBoca = SENSACIONES_BOCA
const gustosPredominantes = GUSTOS_PREDOMINANTES
const tiposDefectos = TIPOS_DEFECTOS
// Helpers para filtrado por subcategorías
const deberMostrarSeccion = (subcategorias: Subcategoria[]): boolean => {
// Si no hay filtros activos, mostrar todo
if (!props.subcategoriasActivas || props.subcategoriasActivas.length === 0) return true
// Si hay filtros, verificar si alguno coincide
return subcategorias.some(sub => props.subcategoriasActivas?.includes(sub))
}
// Para Organoléptica
const mostrarFraganciaAroma = computed(() => deberMostrarSeccion(['fragancia-aroma']))
const mostrarSaborOrganoleptica = computed(() => deberMostrarSeccion(['sabor']))
const mostrarSensacionBocaOrganoleptica = computed(() => deberMostrarSeccion(['sensacion-boca']))
const mostrarGustosPredominantes = computed(() => deberMostrarSeccion(['gustos-predominantes']))
// Para Descriptiva/Afectiva
const mostrarFraganciaSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'fragancia']))
const mostrarAromaSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'aroma']))
const mostrarSaborSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'sabor']))
const mostrarSaborResidualSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'sabor-residual']))
const mostrarAcidezSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'acidez']))
const mostrarDulzorSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'dulzor']))
const mostrarSensacionBocaSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'sensacion-boca']))
const mostrarImpresionGlobalSlider = computed(() => deberMostrarSeccion(['descriptiva', 'afectiva', 'impresion-global']))
// Estado local para otras notas
const otrasNotasLocal = ref(props.muestra.otrasNotas)