Skip to content

feat: Filtros de múltiple selección con combo desplegable (IMP-17) - #128

Open
konami12 wants to merge 17 commits into
developmentfrom
feat/120-filter-combo-multiselect
Open

feat: Filtros de múltiple selección con combo desplegable (IMP-17)#128
konami12 wants to merge 17 commits into
developmentfrom
feat/120-filter-combo-multiselect

Conversation

@konami12

Copy link
Copy Markdown
Contributor

📋 Descripción

Implementación de componentes Web Component para transformar los filtros de Prioridad y Etiquetas en combos desplegables de múltiple selección, resolviendo el issue #120 (IMP-17).

Problema resuelto: Los filtros actuales ocupan demasiado espacio vertical/horizontal, especialmente en dispositivos móviles.

🎯 Cambios implementados

Componentes creados

1. filter-combo.ts (Molécula)

Componente reutilizable de combo desplegable para múltiple selección:

  • ✅ Dropdown colapsable con checkboxes
  • ✅ Resumen dinámico (ej: "Prioridad ▼ (2 seleccionadas)")
  • ✅ Cambios en tiempo real (sin botón "Aplicar")
  • ✅ Botón "Limpiar" integrado
  • ✅ Cierre automático al hacer clic fuera
  • ✅ Soporte para íconos customizables
  • ✅ Accesibilidad ARIA completa

Atributos:

  • label — Etiqueta visible (ej: "Prioridad")
  • placeholder — Texto cuando no hay selección (default: "(Ninguno)")

API:

combo.options = [
  { id: 'low', label: 'Baja', icon: '⬇️' },
  { id: 'high', label: 'Alta', icon: '⬆️' },
];
combo.selectedIds      // Set<string>
combo.selectedIdsList  // string[]
combo.clear()          // Limpiar selección
combo.toggle()         // Expandir/contraer

Eventos:

  • dojo:filter-changed — Detalle: { selectedIds: string[] }
  • dojo:filter-cleared — Al limpiar

2. filter-bar.ts (Organismo)

Barra de filtros que integra componentes combo:

  • ✅ Input de búsqueda con debounce (300ms)
  • ✅ filter-combo para Prioridad (Baja, Media, Alta, Urgente)
  • ✅ filter-combo para Etiquetas (dinámico)
  • ✅ Botón "Limpiar todos"
  • ✅ API pública para controlar filtros programáticamente

Uso:

const bar = document.querySelector('dojo-filter-bar');
bar.setLabels([...labels]);
bar.selectedPriorities = new Set(['high']);
bar.clearAll();

Eventos:

  • dojo:filter-changed — Detalle: { type: 'priority'|'labels', selectedIds: string[] }
  • dojo:search-changed — Detalle: { searchText: string } (con debounce)
  • dojo:filter-cleared — Todos los filtros limpiados

Archivos creados

src/components/organisms/dojo-filter-bar/
├── filter-combo.ts          (442 líneas)
├── filter-bar.ts            (359 líneas)
└── index.ts                 (Exportaciones)

docs/
└── TECH-filter-combo-filter-bar.md  (Documentación técnica completa)

✅ Criterios de aceptación (Issue #120)

  • El combo de Prioridad muestra "Prioridad ▼ (Ninguno)" cuando no hay filtros
  • Al hacer clic en el combo se despliega la lista con checkboxes
  • Al marcar opciones, el combo actualiza el resumen y filtra las tareas
  • Existe botón/acción "Limpiar filtro" que resetea la selección
  • El combo se cierra automáticamente al hacer clic fuera
  • Se usan atributos ARIA (aria-expanded, aria-label, etc.)
  • El dropdown respeta responsive design (max-height: 60vh en móvil)

🏗️ Arquitectura

Patrones aplicados

  • Web Components nativos — Sin librerías externas (React, Lit, etc.)
  • Shadow DOM — Encapsulación total de estilos
  • TypeScript — Tipado estricto
  • Custom Eventsdojo:filter-changed, dojo:filter-cleared, etc.
  • CSS Custom Properties — Soporte para theming

Compilación

npm run build  # ✅ Compila sin errores

📱 Características técnicas

Accesibilidad

  • aria-haspopup="listbox" en botón toggle
  • aria-expanded indica estado abierto/cerrado
  • aria-label en todos los controles
  • role="listbox" en dropdown
  • role="option" en checkboxes
  • Navegación por teclado (Tab, Enter, Escape)

Responsive

  • Mobile-first design
  • Dropdown con max-height: 60vh en pantallas pequeñas
  • Flexbox adaptable

Personalización

Todas las propiedades CSS customizables:

--dojo-bg                  /* Color fondo */
--dojo-surface             /* Superficie (botones) */
--dojo-border              /* Bordes */
--dojo-text-primary        /* Texto principal */
--dojo-text-secondary      /* Texto secundario */
--dojo-primary             /* Color primario (hover, selected) */
--dojo-radius-sm           /* Radio de esquina */

🔗 Referencias

🚀 Próximos pasos (fuera de este PR)

  1. Integrar dojo-filter-bar en dojo-list-view
  2. Escuchar eventos dojo:filter-changed y dojo:search-changed
  3. Eliminar la barra de filtros antigua del dojo-list-view
  4. Testing manual de filtrado en tiempo real

💡 Notas de implementación

  • ✅ TypeScript compilado sin errores
  • ✅ Shadow DOM para aislamiento total de estilos
  • ✅ Sin dependencias externas (zero deps)
  • ✅ Mobile-first y responsive
  • ✅ ARIA attributes para a11y
  • ✅ Custom Events con bubbles: true, composed: true
  • ✅ Documentación técnica incluida

Closes #120

konami12 and others added 15 commits June 12, 2026 10:03
…ndependiente

- Agrega formulario de creación de etiquetas (nombre + color + vista previa)
  directamente en el panel dojo-label-manager, sin necesidad de crear una tarea.
- Agrupa el listado en secciones "En uso (N)" y "Sin usar (N)" (colapsable),
  mostrando el conteo de tareas junto a cada etiqueta en uso.
- Despacha dojo:label-created; dojo-kanban-board expone addLabel() público
  (refactor de _handleLabelCreated) y dojo-app lo conecta al evento del panel.

Ref: requirements/improvements-19-label-manager.md (IMP-19)
…a init

- Nuevo workflow .github/workflows/release.yml: se dispara con pull_request
  (types: closed) sobre la rama init, y solo corre el job si el PR fue
  efectivamente mergeado (github.event.pull_request.merged == true).
- Ejecuta npm run release (standard-version): bump de versión, actualización
  de CHANGELOG.md, commit chore(release) y tag; luego hace push --follow-tags
  a init con el GITHUB_TOKEN por defecto.
- Se añade standard-version a devDependencies (faltaba en package.json aunque
  ya se usaba en los scripts release/release:beta/pre:release) y se regenera
  package-lock.json en consecuencia.
…e.json

Sin estos scripts, el workflow release.yml (PR #126) fallaría con
'Missing script: release' al ejecutar npm run release.
Badge dinámico de shields.io que lee la versión desde package.json
en la rama init, para que se actualice automáticamente con cada
release generado por el workflow release.yml (PR #126).
feat: Gestión independiente de etiquetas — crear y agrupar por uso (IMP-19)
docs: agregar badge de versión del aplicativo en el README
ci: ejecutar standard-version automáticamente al mergear PR a init
…(IMP-17)

- Crear filter-combo.ts: componente de combo desplegable para múltiple selección
  * Dropdown colapsable con checkboxes
  * Estado colapsado muestra resumen de selección
  * Soporte para íconos customizables
  * Accesibilidad ARIA (aria-expanded, aria-label, etc.)
  * Eventos personalizados: dojo:filter-changed, dojo:filter-cleared
  * Botón "Limpiar filtro" integrado
  * Responsive design con max-height: 60vh en móvil

- Crear filter-bar.ts: organismo que integra filter-combo
  * Barra de filtros moderna con búsqueda y combos
  * Combo de Prioridad (Baja, Media, Alta, Urgente)
  * Combo de Etiquetas (dinámico)
  * Búsqueda con debounce (300ms)
  * Botón "Limpiar todos" que resetea todos los filtros
  * API pública para controlar filtros programáticamente
  * Eventos agregados: dojo:filter-changed, dojo:search-changed

- Seguir patrones de Web Components nativos
- Sin dependencias externas
- Tipado estricto con TypeScript
- Estilos encapsulados con Shadow DOM
- Soporte para CSS Custom Properties para theming

Closes #120
@konami12
konami12 requested a lite review from Copilot August 21, 2026 20:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

- Reemplazar barra de filtros manual en dojo-list-view
- Importar DojoFilterBar desde componente nuevo
- Conectar eventos dojo:filter-changed y dojo:search-changed
- Actualizar _rebuildLabelFilterChips() para usar el nuevo componente
- Simplificar _updateClearAllVisibility() y _clearAllFilters()
- Componentes filter-combo y dojo-filter-bar ahora visibles en la UI
- Compilación exitosa sin errores
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants