feat: [TESIS-150] choose the category of a product when creating or editing it - #66
Conversation
…r editing it The API stores and validates the category since TESIS-102 and exposes its vocabulary at GET /products/categories, but both product modals still showed a disabled field saying the backend had no category. No product could get a category from the app, so the catalog column and filter had nothing to show. Both modals now offer the categories of the API plus "no category", through a shared controlled CategoryField. An empty choice travels as null. A category the product already has but the list does not include is still offered, so saving never clears it by accident. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Revisado. Lo veo bien para implementar. Es barato y saca un cartel que hoy es mentira: los dos modales de producto muestran un campo deshabilitado que dice «Pendiente de backend: el producto todavía no tiene categoría», cuando la API guarda y valida la categoría desde TESIS-102 y expone el vocabulario en Lo que verifiqué
Antes de mergear El PR está CONFLICTING contra Nota aparte: proyecto-web#67 (filtro del catálogo por categoría) está apilado sobre esta rama. Ese no lo mergearía para esta entrega, así que si #67 queda afuera conviene que este deje de depender de aquel orden. |
TomasMartin2004
left a comment
There was a problem hiding this comment.
Revisión del diff completo. El código es idéntico al que leí cuando los PRs estaban en draft —ningún commit nuevo—, así que lo que sigue es el veredicto formal.
✅ Aprobado
Barato y saca un cartel que hoy es mentira: los dos modales de producto muestran un campo deshabilitado que dice «Pendiente de backend: el producto todavía no tiene categoría», cuando la API la guarda y valida desde TESIS-102 y expone el vocabulario en GET /api/v1/products/categories justamente «para que el modal de alta y el filtro del listado no repitan la lista».
Lo que verifiqué
categoryOf('')→nulles el detalle que importa y está resuelto donde corresponde (enutils/payload.ts, no en el componente). Confirmé contra el modelo:validates :category, inclusion: { in: CATEGORIES }, allow_nil: true, así que elnulles válido y el string vacío no lo sería.- Se aplica a los dos caminos, alta y edición, con el mismo helper. Era la forma obvia de que uno quedara distinto del otro.
CategoryFieldsale como componente propio, y el vocabulario se lee conuseCategoriesen vez de una lista repetida en el front.
⚠️ Antes de mergear
- CONFLICTING por el merge de TESIS-139, que también toca
inventory. Hay que rebasar. - proyecto-web#67 está apilado sobre esta rama. Si #67 queda afuera, conviene desapilarlo para que no quede colgando de una rama ya mergeada.
- Roce menor con mi proyecto-web#79, que muestra la categoría en el detalle. Son archivos distintos, pero conviene mergear una y rebasar la otra.
…t-category-in-modals Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ticket de Jira
https://proyectofinalfrlp.atlassian.net/browse/TESIS-150
Descripción
La API guarda y valida la categoría de un producto desde TESIS-102 y expone el vocabulario en
GET /api/v1/products/categories, pero los dos modales de producto seguían mostrando un campo deshabilitado con «Pendiente de backend: el producto todavía no tiene categoría». Resultado: ningún producto podía recibir una categoría desde la app, y la columna Categoría del catálogo sólo mostraba lo que venía de los seeds. Este PR habilita el campo en el alta y en la edición.Decisiones que conviene mirar:
El vocabulario sale de la API.
useCategoriespideGET /products/categoriesuna vez por sesión (staleTimeinfinito). Sumar una categoría sigue siendo una línea enProduct::CATEGORIESy aparece en los selects sin tocar el front.Un solo campo para los dos modales (Regla de Dos):
CategoryField, controlado. El modal de edición se rellena conresetal abrir; con un select registrado (no controlado), al reabrir seguiría mostrando lo que tenía antes. ConController, lo que se ve es siempre el valor del formulario.No borrar por accidente. Si el producto tiene una categoría que la lista no incluye (la lista todavía no respondió, o la categoría salió del vocabulario), se ofrece igual: sin eso el select la mostraría vacía y guardar la borraría sin que nadie lo haya pedido.
''en el formulario,nullen la API. Un<select>no tienenull: «Sin categoría» es''en el schema y viaja comonull, que es lo que la columna admite.fetchCategories,inventoryKeys.categories()yuseCategories.components/CategoryField/y lo usa enCreateProductModalyEditProductModal.categorya los schemas, aCreateProductPayload/UpdateProductPayloady aProduct/ApiProduct;buildCreatePayloadybuildUpdatePayloadla mandan.InventoryPageyProductDetailPagepasan las categorías a sus modales.Evidencia visual
Pendiente de captura con la API levantada.
Cómo probar
Precondición: API de
master,bin/rails db:seed, login con un usuario de Norte.Verificación:
npm run test(683 tests, 0 fallas),npm run lint,npm run format:checkynpm run buildlimpios.Impacto y consideraciones
¿Introduce breaking changes?
No
¿Requiere nuevas variables de entorno?
No
¿Afecta la arquitectura o genera un nuevo patrón?
No.
Conflicto esperable con proyecto-web#60 (card 002): esa rama también agrega
categoryaProductyApiProduct(junto con otros campos del detalle) y toca los mismos fixtures de tests. Se resuelve quedándose con la unión de los dos. Los comentarios y el copy del detalle que todavía dicen que la categoría no existe (buildSpecs,detail.specs.pendingBackend) los corrige #60, por eso no se tocan acá.🤖 Generated with Claude Code