Action Dialog
DyonaActionDialog captura los parámetros de una acción con un DyonaForm antes de que Action Engine la ejecute. Es la capa de captura de parámetros sobre Action Engine.
Flujo
DyonaAction
requiresParameters: true
↓
DyonaActionDialog
↓
DyonaForm
↓
submit válido
↓
context.parameters
↓
executeDyonaAction()
↓
executor consumidor
Rechazar pedido con motivo
Esta acción de record necesita un motivo de rechazo antes de poder ejecutarse.
const rejectAction: DyonaAction = {
id: 'reject-order',
label: 'Reject order',
scope: 'record',
requiresParameters: true,
};
const context: DyonaActionContext = {
sourceId: 'orders',
record: {
id: 1024,
customer: 'Acme Corp',
status: 'pending',
},
};
El formulario del diálogo solicita un select obligatorio rejectionReason y un textarea opcional comments. Luego de un submit válido, sus valores normalizados se asignan a context.parameters en el contexto de ejecución que recibe el executor.
DyonaActionDialogConfig
schema: elDyonaFormSchemaque se renderiza dentro del diálogo.initialValues: valores opcionales deDyonaFormpara precargar el formulario.maxWidth: ancho opcional del diálogo:xs,sm,md,lg,xlofalse.fullWidth: permite que el diálogo use el ancho disponible hastamaxWidth.
Props principales
opencontrola si el diálogo es visible.actiones laDyonaActionque se ejecutará.contextes el contexto de la acción; los valores del formulario se agregan comocontext.parametersen el contexto de ejecución.configentrega el formulario y la configuración de layout del diálogo.executorejecuta la acción mediante Action Engine.dataSourceExecutorresuelve datos del formulario cuando un field necesita datos de autocomplete remoto.onClosecierra el diálogo en el componente consumidor.onResultrecibe un resultado de la acción.onExecutionErrorrecibe una excepción producida al ejecutar la acción.
executor y dataSourceExecutor tienen responsabilidades distintas: el primero ejecuta la acción de negocio; el segundo resuelve datos requeridos por el formulario, como opciones de autocomplete remoto.
Comportamiento
- El componente solo se renderiza cuando
action.requiresParametersestrue. - Un submit inválido no ejecuta la acción.
- Un submit válido asigna valores normalizados del formulario a
context.parametersen el contexto de ejecución. - Evita una segunda ejecución mientras haya una en curso.
- Mientras ejecuta, Cancelar, Escape y el cierre por backdrop quedan bloqueados.
- Un resultado con
success: truese informa medianteonResulty cierra el diálogo. - Un resultado con
success: falsese informa medianteonResulty mantiene abierto el diálogo. - Una excepción del executor llama a
onExecutionErrory mantiene abierto el diálogo.
Ejemplo completo
import {useState} from 'react';
import {
DyonaActionDialog,
type DyonaAction,
type DyonaActionContext,
type DyonaActionExecutor,
type DyonaActionResult,
} from '@typhonsoftware/dyona-form';
const rejectAction: DyonaAction = {
id: 'reject-order',
label: 'Rechazar pedido',
scope: 'record',
requiresParameters: true,
};
const context: DyonaActionContext = {
sourceId: 'orders',
record: {
id: 1024,
customer: 'Acme Corp',
status: 'pending',
},
};
const dialogConfig = {
schema: {
title: 'Rechazar pedido',
hideSingleTab: true,
tabs: [
{
id: 'rejection',
title: 'Detalle del rechazo',
rows: [
{
columns: [
{
name: 'rejectionReason',
label: 'Motivo del rechazo',
type: 'select' as const,
required: true,
options: [
{value: 'out-of-stock', label: 'Sin stock'},
{value: 'pricing-error', label: 'Error de precio'},
{value: 'customer-request', label: 'Solicitud del cliente'},
],
fullWidth: true,
},
],
},
{
columns: [
{
name: 'comments',
label: 'Comentarios',
type: 'textarea' as const,
fullWidth: true,
},
],
},
],
},
],
},
initialValues: {comments: ''},
maxWidth: 'sm' as const,
fullWidth: true,
};
const rejectOrder: DyonaActionExecutor = async ({context}) => {
const result: DyonaActionResult = {
success: true,
message: `Pedido ${context.record?.id} rechazado`,
data: {
rejectionReason: context.parameters?.rejectionReason,
comments: context.parameters?.comments,
},
refresh: [{sourceId: 'orders'}],
};
return result;
};
export function RejectOrderAction() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => setOpen(true)}>Rechazar pedido</button>
<DyonaActionDialog
locale="es"
open={open}
action={rejectAction}
context={context}
config={dialogConfig}
executor={rejectOrder}
onClose={() => setOpen(false)}
onResult={(result) => console.log(result.message)}
onExecutionError={(error) => console.error(error)}
/>
</>
);
}