139 lines
6.0 KiB
Markdown
139 lines
6.0 KiB
Markdown
# Herramientas interactivas
|
|
|
|
Estado: primera versión funcional. Este documento conserva el contexto necesario para extender `DsSortableList` y `DsLogicTree` sin cambiar accidentalmente sus contratos públicos.
|
|
|
|
## Principios compartidos
|
|
|
|
- Los modelos son serializables y no contienen referencias DOM ni estado interno de Vue.
|
|
- Cada elemento o nodo necesita un `id` estable y único.
|
|
- Las actualizaciones reemplazan arreglos y nodos en lugar de mutar los objetos recibidos.
|
|
- La interacción con puntero siempre debe tener una alternativa de teclado.
|
|
- La lógica de negocio, persistencia y traducción a consultas pertenece a la aplicación consumidora o a adaptadores independientes.
|
|
- Cualquier ampliación debe actualizar tipos, API pública, pruebas, playground y documentación.
|
|
|
|
## `DsSortableList`
|
|
|
|
### Contrato actual
|
|
|
|
Recibe `v-model<DsSortableItem[]>`. Cada elemento contiene:
|
|
|
|
```ts
|
|
interface DsSortableItem {
|
|
id: string;
|
|
label: string;
|
|
description?: string;
|
|
disabled?: boolean;
|
|
}
|
|
```
|
|
|
|
El usuario puede arrastrar un elemento o utilizar los botones subir/bajar. Cada cambio reemplaza el arreglo y emite:
|
|
|
|
```ts
|
|
interface DsSortableChange {
|
|
item: DsSortableItem;
|
|
from: number;
|
|
to: number;
|
|
}
|
|
```
|
|
|
|
El slot predeterminado puede personalizar la representación, pero `id` y `label` continúan formando parte del contrato porque se utilizan para identidad y nombres accesibles.
|
|
|
|
### Decisiones
|
|
|
|
- Se usa drag-and-drop nativo del navegador para mantener pequeña la primera versión y evitar una dependencia runtime.
|
|
- Los botones subir/bajar son la alternativa accesible y también permiten operar la lista en pantallas táctiles.
|
|
- La nueva posición se anuncia mediante una región `status`.
|
|
- Un elemento `disabled` no puede iniciar un movimiento.
|
|
|
|
### Limitaciones conocidas
|
|
|
|
- Solo reordena elementos dentro de una misma lista.
|
|
- No tiene gesto táctil de arrastre; en móvil se usan los botones.
|
|
- No ofrece clonación, selección múltiple, grupos ni zonas de descarte.
|
|
- El destino corresponde al elemento sobre el que se suelta; todavía no existe un indicador entre filas.
|
|
- No administra persistencia ni historial para deshacer/rehacer.
|
|
|
|
### Próximas extensiones
|
|
|
|
1. Mejorar el indicador de inserción antes/después de una fila.
|
|
2. Evaluar Pointer Events para arrastre táctil sin eliminar la alternativa por botones.
|
|
3. Diseñar drag-and-drop entre listas. Antes de implementarlo hay que definir `sourceListId`, `targetListId`, copia frente a movimiento y el evento público resultante.
|
|
4. Añadir soporte opcional para deshacer/rehacer como composable independiente.
|
|
5. Incorporar pruebas visuales y de interacción en navegadores reales.
|
|
|
|
## `DsLogicTree`
|
|
|
|
### Contrato actual
|
|
|
|
Recibe `v-model<DsLogicGroup>`. El árbol utiliza una unión discriminada:
|
|
|
|
```ts
|
|
type DsLogicNode = DsLogicCondition | DsLogicGroup;
|
|
|
|
interface DsLogicGroup {
|
|
id: string;
|
|
type: "group";
|
|
operator: "and" | "or";
|
|
children: DsLogicNode[];
|
|
}
|
|
|
|
interface DsLogicCondition {
|
|
id: string;
|
|
type: "condition";
|
|
field: string;
|
|
comparison: string;
|
|
value: string;
|
|
}
|
|
```
|
|
|
|
`fields` y `comparisons` usan opciones `{ label, value, disabled? }`. La prop `labels` permite adaptar todos los textos del editor y `readonly` conserva la estructura sin permitir cambios. Cada edición actualiza el `v-model` y emite `change` con el árbol completo.
|
|
|
|
El render recursivo vive en `DsLogicTreeNode.vue`, que es una implementación interna y no forma parte de la API pública.
|
|
|
|
### Decisiones
|
|
|
|
- `AND` y `OR` se almacenan como `and` y `or`; los textos visibles son configurables.
|
|
- Las condiciones usan cadenas para que la primera versión sea neutral respecto al dominio.
|
|
- Los nodos nuevos reciben UUID y los nodos proporcionados por el consumidor deben conservar IDs estables.
|
|
- El árbol solamente describe reglas. No evalúa condiciones ni genera SQL, JSON Logic u otra sintaxis.
|
|
- Los controles nativos mantienen nombres accesibles y el anidamiento se representa con listas y grupos.
|
|
|
|
### Limitaciones conocidas
|
|
|
|
- Todos los valores se editan como texto, sin tipos `number`, `boolean`, fecha o selección múltiple.
|
|
- No existe validación de campos vacíos, operadores incompatibles o grupos sin condiciones.
|
|
- Los nodos no pueden reordenarse ni moverse entre grupos.
|
|
- No hay operadores unarios como `is-empty` ni condiciones que omitan `value`.
|
|
- No se muestran resúmenes en lenguaje natural.
|
|
- No se incluye un evaluador ni adaptadores para backends.
|
|
|
|
### Próximas extensiones
|
|
|
|
1. Añadir validación sin cambiar el modelo serializable; los errores deben asociarse al control correspondiente.
|
|
2. Diseñar definiciones de campo tipadas con un `valueType` y opciones de valor. Hay que conservar compatibilidad con el esquema actual o introducir el cambio en una versión mayor.
|
|
3. Permitir comparadores que no requieran valor y editores personalizados mediante slots.
|
|
4. Reordenar condiciones y mover nodos entre grupos reutilizando un contrato de drag-and-drop estable.
|
|
5. Crear adaptadores separados para evaluar el árbol o convertirlo a formatos como JSON Logic. Estos adaptadores no deben acoplar el componente visual a un backend.
|
|
6. Añadir colapsado de grupos, resumen legible y deshacer/rehacer cuando el árbol crezca.
|
|
|
|
## Checklist para futuras sesiones
|
|
|
|
Antes de modificar estas herramientas:
|
|
|
|
1. Revisa este documento, `src/types.ts` y las pruebas de `tests/data-tools.test.ts`.
|
|
2. Decide si el cambio es compatible con los modelos actuales y documenta cualquier migración.
|
|
3. Conserva una alternativa completa al arrastre para teclado y tecnologías asistivas.
|
|
4. Añade el caso nuevo al playground en `?section=tools`.
|
|
5. Actualiza `docs/components.md` si cambia la API pública.
|
|
6. Ejecuta `npm run check` y `npm run test:coverage`.
|
|
|
|
## Fuera de alcance actual
|
|
|
|
- Ejecución de reglas contra datos reales.
|
|
- Generación directa de SQL o llamadas a APIs.
|
|
- Colaboración en tiempo real.
|
|
- Persistencia automática.
|
|
- Un editor visual de flujos con nodos y conexiones libres.
|
|
|
|
Estas capacidades requieren contratos y análisis de seguridad propios; no deben incorporarse como comportamiento implícito de los componentes visuales.
|