From 5adbe81364a8b6c7171b85ababa99dfa7ef4356e Mon Sep 17 00:00:00 2001 From: David Date: Sun, 4 Oct 2026 15:46:39 +0200 Subject: [PATCH] feat: enhance access management with quick create functionality and improved forms - Added QuickCreateDialog for creating systems and environments quickly. - Implemented quickCreatePlan to handle creation logic based on context. - Updated AccessForm to support quick creation and related modals. - Enhanced i18n support for new quick add features in both English and Spanish. - Refactored AssignmentForm to allow department creation directly from the form. - Introduced SelectWithAction component for better user interaction with selections. - Added tests for new components and functionalities to ensure reliability. --- docs/componentes-de-interfaz.md | 23 ++ .../src/web/access/access-field-control.tsx | 129 ++++---- .../companies/src/web/access/access-form.tsx | 276 ++++++++++++++---- .../companies/src/web/access/access.test.tsx | 133 +++++++++ modules/companies/src/web/access/i18n.ts | 26 ++ .../src/web/access/quick-create-dialog.tsx | 151 ++++++++++ .../src/web/access/quick-create-plan.ts | 120 ++++++++ .../src/web/components/assignment-form.tsx | 162 ++++++---- .../web/components/companies-page.test.tsx | 49 ++++ .../src/web/components/department-section.tsx | 23 +- .../src/web/components/people-section.tsx | 5 +- .../src/web/components/person-form.tsx | 3 + modules/companies/src/web/i18n.ts | 4 +- packages/shadcn-ui/package.json | 3 +- .../shadcn-ui/src/components/button-group.tsx | 77 +++++ .../src/components/select-with-action.tsx | 86 ++++++ .../shadcn-ui/src/components/separator.tsx | 18 ++ .../shadcn-ui/src/select-with-action.test.tsx | 52 ++++ packages/shadcn-ui/tsconfig.json | 3 +- 19 files changed, 1166 insertions(+), 177 deletions(-) create mode 100644 modules/companies/src/web/access/quick-create-dialog.tsx create mode 100644 modules/companies/src/web/access/quick-create-plan.ts create mode 100644 packages/shadcn-ui/src/components/button-group.tsx create mode 100644 packages/shadcn-ui/src/components/select-with-action.tsx create mode 100644 packages/shadcn-ui/src/components/separator.tsx create mode 100644 packages/shadcn-ui/src/select-with-action.test.tsx diff --git a/docs/componentes-de-interfaz.md b/docs/componentes-de-interfaz.md index eb87546..fbc493c 100644 --- a/docs/componentes-de-interfaz.md +++ b/docs/componentes-de-interfaz.md @@ -62,3 +62,26 @@ ContextHelp muestra una explicación breve y permite desplegar ejemplos y recome El botón Ayuda de Cuentas y accesos y Catálogos informáticos permite consultar la explicación de la sección sin abrir un alta. La misma ayuda aparece dentro de los modales de alta y edición. FormDialog utiliza una variante amplia para personas y formularios con más campos; el número de campos no cambia la navegación a una página propia. La ayuda de los formularios se coloca en su parte inferior, inmediatamente antes de FormActions. Este pie compartido reúne Guardar y Cancelar dentro del formulario, conservando el envío y el cierre accesible del diálogo. Los diálogos de consulta mantienen únicamente Cerrar. + +## SelectWithAction: desplegable con acción integrada + +El componente compartido vive en `@repo/shadcn-ui/components/select-with-action`. Compone Select, Button y ButtonGroup de shadcn/ui (Base UI, Vega). Presenta selección y botón «+» como un único grupo visual, manteniendo controles separados para teclado y lectores de pantalla. ButtonGroup utiliza fieldset para expresar semánticamente la agrupación. + +Su contrato recibe id, etiqueta, opciones, placeholder, valor controlado y callback de selección. La acción es opcional y contiene etiqueta accesible, callback y estado deshabilitado. Admite opciones deshabilitadas, estado inválido, descripción accesible y obligatoriedad. Deshabilitar el selector también deshabilita la acción. El botón usa type=button y no envía el formulario. + +No conoce compañías, HTTP, formularios ni modales: esas responsabilidades pertenecen al consumidor. No contiene textos propios que deban traducirse. + +### Formularios que permiten alta rápida + +Sistema permite crear un sistema propio de la compañía mediante un modal adicional. Entorno permite crear un entorno para el sistema activo seleccionado; su acción no aparece antes de elegir un sistema. Los campos fijos en edición no ofrecen alta rápida. Uso y otros valores cerrados tampoco ofrecen altas. + +QuickCreateDialog conserva los valores del formulario principal, actualiza el catálogo y selecciona el nuevo UUID después de guardar. Usa las rutas, protección CSRF y reglas de negocio existentes. Un nombre activo ya existente permite usar ese registro sin duplicarlo. Cancelar el modal adicional conserva la cuenta sin cambios. El elemento creado permanece en el catálogo aunque se cancele después la cuenta. + +La ayuda aparece antes del pie con Guardar y seleccionar / Cancelar. Solo hay un nivel de alta adicional; el nuevo formulario no vuelve a ofrecer altas rápidas. + + +La revisión de los formularios extiende este patrón a personas, departamentos, cuentas, grupos, recursos, tipos de recurso, permisos y plantillas. Las asignaciones de departamento permiten añadir el primero sin abandonar el formulario. Se reutilizan los formularios y rutas existentes, manteniendo su validación y ayuda inferior. + +Los entornos necesitan un sistema activo seleccionado. Los permisos nuevos heredan el tipo del recurso elegido. Al crear un grupo desde una pertenencia, sistema y entorno quedan fijados a los de la cuenta. Las plantillas siguen siendo globales; el modal lo explica y carga únicamente sus opciones globales. Los elementos creados desde un selector están activos para poder seleccionarlos. + +Uso de cuenta, estado de configuración e idioma son listas cerradas. Las referencias históricas de cobertura (necesidad, autorización, titularidad y pertenencia) conservan sus operaciones propias. Los campos inmutables en edición no ofrecen altas. Los permisos múltiples de una necesidad continúan como casillas. diff --git a/modules/companies/src/web/access/access-field-control.tsx b/modules/companies/src/web/access/access-field-control.tsx index 76ad424..cf00cf9 100644 --- a/modules/companies/src/web/access/access-field-control.tsx +++ b/modules/companies/src/web/access/access-field-control.tsx @@ -1,13 +1,8 @@ import { Checkbox } from "@repo/shadcn-ui/components/checkbox"; import { Input } from "@repo/shadcn-ui/components/input"; import { Label } from "@repo/shadcn-ui/components/label"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@repo/shadcn-ui/components/select"; +import type { SelectAction } from "@repo/shadcn-ui/components/select-with-action"; +import { SelectWithAction } from "@repo/shadcn-ui/components/select-with-action"; import { Textarea } from "@repo/shadcn-ui/components/textarea"; import type { UseFormReturn } from "react-hook-form"; import { useTranslation } from "react-i18next"; @@ -24,6 +19,9 @@ export function AccessFieldControl({ options, disabled, onSelected, + onCreate, + createDisabled = false, + createLabel, }: { field: AccessField; id: string; @@ -32,6 +30,9 @@ export function AccessFieldControl({ options: readonly Option[]; disabled: boolean; onSelected: (value: string) => void; + onCreate?: (() => void) | undefined; + createDisabled?: boolean; + createLabel?: string | undefined; }) { const { t } = useTranslation("access"); if (field.type === "boolean") { @@ -39,6 +40,7 @@ export function AccessFieldControl({
form.setValue(field.key, checked === true)} /> @@ -48,28 +50,13 @@ export function AccessFieldControl({ } if (field.type === "permissions") { return ( -
- {t(field.key)} - {options.map((option) => ( -
- { - const values = Array.isArray(value) ? value : []; - form.setValue( - field.key, - checked - ? [...values, option.value] - : values.filter((item) => item !== option.value) - ); - }} - /> - -
- ))} - {!options.length &&

{t("noPermissions")}

} -
+ ); } return ( @@ -81,28 +68,20 @@ export function AccessFieldControl({ {field.type === "note" ? (