Refactor: Migrar filtros de Informe Ingresos a UCheckboxGroup
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 49s

- Reemplazar checkboxes individuales por UCheckboxGroup en filtros de:
  * Ubicaciones (con scroll vertical para listas largas)
  * Tipos de Café (Uva, Mojado, Oreado, Verde)
  * Estados (Pagado, Pendiente)
  * Calidades (orientación horizontal)

- Simplificar modelo de datos:
  * Eliminar filterTipos y filterEstados (objetos con booleanos)
  * Usar directamente selectedTipos y selectedEstados (arrays)
  * Eliminar computed tiposArray y estadosArray (innecesarios)

- Beneficios:
  * Código más limpio y mantenible
  * Mejor consistencia con Nuxt UI
  * UI más compacta y profesional
  * Menos lógica de conversión de datos
This commit is contained in:
2025-10-30 13:21:18 -06:00
parent 3b0d21dd02
commit 6e4da65d63

View File

@@ -73,51 +73,58 @@
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Ubicaciones -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Ubicaciones</label>
<div class="space-y-2 max-h-40 overflow-y-auto">
<UCheckbox
v-for="ubicacion in opcionesFiltros.ubicaciones"
:key="ubicacion"
v-model="selectedUbicaciones"
:value="ubicacion"
:label="ubicacion"
/>
</div>
<UCheckboxGroup
v-model="selectedUbicaciones"
legend="Ubicaciones"
:items="opcionesFiltros.ubicaciones"
color="primary"
variant="list"
orientation="vertical"
size="sm"
:ui="{
fieldset: 'max-h-40 overflow-y-auto'
}"
/>
</div>
<!-- Tipos de Café -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Tipos de Café</label>
<div class="space-y-2">
<UCheckbox v-model="filterTipos.uva" label="Uva" />
<UCheckbox v-model="filterTipos.mojado" label="Mojado" />
<UCheckbox v-model="filterTipos.oreado" label="Oreado" />
<UCheckbox v-model="filterTipos.verde" label="Verde" />
</div>
<UCheckboxGroup
v-model="selectedTipos"
legend="Tipos de Café"
:items="tiposItems"
color="primary"
variant="list"
orientation="vertical"
size="sm"
/>
</div>
<!-- Estados -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Estados</label>
<div class="space-y-2">
<UCheckbox v-model="filterEstados.pagado" label="Pagado" />
<UCheckbox v-model="filterEstados.pendiente" label="Pendiente" />
</div>
<UCheckboxGroup
v-model="selectedEstados"
legend="Estados"
:items="estadosItems"
color="primary"
variant="list"
orientation="vertical"
size="sm"
/>
</div>
</div>
<!-- Calidades -->
<div v-if="opcionesFiltros.calidades.length > 0">
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Calidades</label>
<div class="flex flex-wrap gap-2">
<UCheckbox
v-for="calidad in opcionesFiltros.calidades"
:key="calidad"
v-model="selectedCalidades"
:value="calidad"
:label="calidad"
/>
</div>
<UCheckboxGroup
v-model="selectedCalidades"
legend="Calidades"
:items="opcionesFiltros.calidades"
color="primary"
variant="list"
orientation="horizontal"
size="sm"
/>
</div>
</div>
@@ -239,51 +246,58 @@
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Ubicaciones -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Ubicaciones</label>
<div class="space-y-2 max-h-40 overflow-y-auto">
<UCheckbox
v-for="ubicacion in opcionesFiltros.ubicaciones"
:key="ubicacion"
v-model="selectedUbicaciones"
:value="ubicacion"
:label="ubicacion"
/>
</div>
<UCheckboxGroup
v-model="selectedUbicaciones"
legend="Ubicaciones"
:items="opcionesFiltros.ubicaciones"
color="primary"
variant="list"
orientation="vertical"
size="sm"
:ui="{
fieldset: 'max-h-40 overflow-y-auto'
}"
/>
</div>
<!-- Tipos de Café -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Tipos de Café</label>
<div class="space-y-2">
<UCheckbox v-model="filterTipos.uva" label="Uva" />
<UCheckbox v-model="filterTipos.mojado" label="Mojado" />
<UCheckbox v-model="filterTipos.oreado" label="Oreado" />
<UCheckbox v-model="filterTipos.verde" label="Verde" />
</div>
<UCheckboxGroup
v-model="selectedTipos"
legend="Tipos de Café"
:items="tiposItems"
color="primary"
variant="list"
orientation="vertical"
size="sm"
/>
</div>
<!-- Estados -->
<div>
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Estados</label>
<div class="space-y-2">
<UCheckbox v-model="filterEstados.pagado" label="Pagado" />
<UCheckbox v-model="filterEstados.pendiente" label="Pendiente" />
</div>
<UCheckboxGroup
v-model="selectedEstados"
legend="Estados"
:items="estadosItems"
color="primary"
variant="list"
orientation="vertical"
size="sm"
/>
</div>
</div>
<!-- Calidades -->
<div v-if="opcionesFiltros.calidades.length > 0">
<label class="block text-sm font-medium mb-2 text-[var(--brand-text)]">Calidades</label>
<div class="flex flex-wrap gap-2">
<UCheckbox
v-for="calidad in opcionesFiltros.calidades"
:key="calidad"
v-model="selectedCalidades"
:value="calidad"
:label="calidad"
/>
</div>
<UCheckboxGroup
v-model="selectedCalidades"
legend="Calidades"
:items="opcionesFiltros.calidades"
color="primary"
variant="list"
orientation="horizontal"
size="sm"
/>
</div>
</div>
@@ -423,23 +437,12 @@ const selectedPreset = ref<PresetValue>('cosecha-25-26')
const fechaDesde = ref<string | null>(null)
const fechaHasta = ref<string | null>(null)
// Filtros avanzados - clientes y ubicaciones
// Filtros avanzados - todos usando arrays para CheckboxGroup
const selectedClienteIds = ref<number[]>([])
const selectedUbicaciones = ref<string[]>([])
const selectedCalidades = ref<string[]>([])
// Filtros avanzados - usando checkboxes separados
const filterTipos = ref({
uva: false,
mojado: false,
oreado: false,
verde: false
})
const filterEstados = ref({
pagado: false,
pendiente: false
})
const selectedTipos = ref<string[]>([])
const selectedEstados = ref<string[]>([])
// Opciones de filtros disponibles (desde Metabase)
const opcionesFiltros = ref({
@@ -449,22 +452,19 @@ const opcionesFiltros = ref({
estados: [] as string[]
})
// Convertir checkboxes a arrays para el API
const tiposArray = computed(() => {
const tipos: string[] = []
if (filterTipos.value.uva) tipos.push('uva')
if (filterTipos.value.mojado) tipos.push('mojado')
if (filterTipos.value.oreado) tipos.push('oreado')
if (filterTipos.value.verde) tipos.push('verde')
return tipos
})
// Items para CheckboxGroup de Tipos
const tiposItems = computed(() => [
{ label: 'Uva', value: 'uva' },
{ label: 'Mojado', value: 'mojado' },
{ label: 'Oreado', value: 'oreado' },
{ label: 'Verde', value: 'verde' }
])
const estadosArray = computed(() => {
const estados: string[] = []
if (filterEstados.value.pagado) estados.push('pagado')
if (filterEstados.value.pendiente) estados.push('pendiente')
return estados
})
// Items para CheckboxGroup de Estados
const estadosItems = computed(() => [
{ label: 'Pagado', value: 'pagado' },
{ label: 'Pendiente', value: 'pendiente' }
])
// Filtros aplicados (los que se usaron en la última carga de datos)
const appliedFilters = ref<{
@@ -499,8 +499,8 @@ const hasPendingChanges = computed(() => {
JSON.stringify(selectedClienteIds.value) !== JSON.stringify(appliedFilters.value.clienteIds) ||
JSON.stringify(selectedUbicaciones.value) !== JSON.stringify(appliedFilters.value.ubicaciones) ||
JSON.stringify(selectedCalidades.value) !== JSON.stringify(appliedFilters.value.calidades) ||
JSON.stringify(tiposArray.value) !== JSON.stringify(appliedFilters.value.tipos) ||
JSON.stringify(estadosArray.value) !== JSON.stringify(appliedFilters.value.estados)
JSON.stringify(selectedTipos.value) !== JSON.stringify(appliedFilters.value.tipos) ||
JSON.stringify(selectedEstados.value) !== JSON.stringify(appliedFilters.value.estados)
)
})
@@ -521,8 +521,8 @@ async function loadData() {
fecha_hasta: fechaHasta.value,
incluir_anulados: includeAnulados.value,
cliente_ids: selectedClienteIds.value,
tipos: tiposArray.value,
estados: estadosArray.value,
tipos: selectedTipos.value,
estados: selectedEstados.value,
ubicaciones: selectedUbicaciones.value,
calidades: selectedCalidades.value,
granularidad: 'dia' // Default granularity
@@ -551,8 +551,8 @@ async function loadData() {
clienteIds: [...selectedClienteIds.value],
ubicaciones: [...selectedUbicaciones.value],
calidades: [...selectedCalidades.value],
tipos: [...tiposArray.value],
estados: [...estadosArray.value]
tipos: [...selectedTipos.value],
estados: [...selectedEstados.value]
}
console.log('[Informe] Datos cargados:', result)