Esta documentación está en fase de desarrollo y puede contener errores.

Patrones de uso

Cookbook de DinaZen: cinco recetas de extremo a extremo para leer datos del SDK, pintarlos, elegir el selector correcto, montar diálogos y gestionar la carga.

Recetas que copias y adaptas, no referencia de props. Cada una resuelve un problema real de montar una app Blazor sobre el SDK .NET: traer datos con el Cliente Dinaup y pintarlos con DinaZen sin reinventar la UI.

El reparto es siempre el mismo: el cliente trae el dato, DinaZen lo pinta. Si una receta te pide un DinaupClientC, viene de crear y conectar el cliente.


De un informe a una tabla

Tienes un informe de Dinaup Flex (su GUID) y quieres pintar sus filas en una tabla con paginación, búsqueda, filtros y exportación a CSV. Sin escribir ni una columna a mano. DnzReportView ejecuta el informe contra la API con tu cliente y genera el DataGrid a partir de la definición del informe.

Crea y conecta el cliente

@code {
    private DinaupClientC _client;

    protected override async Task OnInitializedAsync()
    {
        _client = new DinaupClientC(endpoint, apiKey, secretKey, "*");
        await _client.InitializeAsync(3000);
    }
}

Pinta el informe inline

Pásale el cliente y el GUID del informe. Las columnas, los tipos y los formatos los deduce solo de la definición del informe.

@if (_client.IsNotNull())
{
    <div style="height:600px; overflow:auto;">
        <DnzReportView Client=@_client ReportId="guid-del-informe" Limit="50" />
    </div>
}

Reacciona al clic en una fila

Por defecto, al pulsar una fila el componente abre la ficha del registro. Si quieres tu propio comportamiento, captura OnItemSelect.

<DnzReportView Client=@_client ReportId="guid-del-informe" OnItemSelect=@AbrirDetalleAsync />

@code {
    private async Task AbrirDetalleAsync(DinaupDynamicRowDTO row)
    {
        // row.ID y row.SectionId vienen rellenos
        await HacerAlgoCon(row.ID);
    }
}

No necesitas leer las filas tú mismo: DnzReportView llama a Client.Report_GetAsync por dentro, gestiona la carga, los errores y la paginación del lado servidor. Tú solo pones cliente y GUID.

¿Lo quieres en un diálogo o en una ventana flotante en lugar de inline? El componente expone dos helpers estáticos.

@inject DialogService DialogService

@code {
    private async Task AbrirInformeAsync()
    {
        await DnzReportView.OpenAsync(DialogService, _client, "guid-del-informe", title: "Ventas del mes");
    }
}
@inject DnzWindowManagerService WindowManager

@code {
    private void AbrirInformeEnVentana()
    {
        DnzReportView.OpenAsWindow(WindowManager, _client, "guid-del-informe", title: "Ventas");
    }
}

Firmas de los helpers estáticos:

Task DnzReportView.OpenAsync(DialogService ds, DinaupClientC client, string reportId, Dictionary<string, string> vars = null, string title = "Informe", string width = "90%", string height = "80%")
string DnzReportView.OpenAsWindow(DnzWindowManagerService wm, DinaupClientC client, string reportId, Dictionary<string, string> vars = null, string title = "Informe", string icon = "analytics")

DnzReportView

Ejecuta un informe de Flex y lo pinta como tabla con búsqueda, filtros, paginación servidor y exportación a CSV.

<DnzReportView Client=@_client ReportId="guid-del-informe" Limit="50" Title="Ventas" />

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstring""Obligatorio. GUID del informe a ejecutar.
VariablesValuesDictionary<string, string>nullValores para las variables del informe.
QuerySearchstring""Búsqueda textual inicial.
AdvancedFilterList<FilterCondition>nullFiltros avanzados aplicados de entrada.
Limitint50Filas por página.
OrdenDictionary<string, bool>nullOrden inicial (clave = columna, valor = ascendente).
ShowTitlebooltrueMuestra la cabecera con título e icono de la sección.
Titlestring""Sobrescribe el título; si está vacío, usa el del informe.
ShowSearchbooltrueMuestra la caja de búsqueda.
FiltrablebooltruePermite filtrar las columnas.
ShowAddbooltrueMuestra el botón de añadir registro.
AdminModeboolfalseEjecuta el informe en modo administrador.
ToolBarTemplateRenderFragmentnullContenido extra en la barra de herramientas.
OnItemSelectEventCallback<DinaupDynamicRowDTO>Se dispara al seleccionar una fila (sustituye al comportamiento por defecto).
OnDataChangedEventCallbackSe dispara cuando los datos se recargan.

DnzReportProvider

Variante "headless": ejecuta el informe y expone las filas como CascadingValue, pero no pinta ninguna tabla. Úsalo cuando quieras los datos del informe pero con tu propio render (tarjetas, KPIs, una vista a medida). El ChildContent recibe el contexto con las filas ya cargadas.

<DnzReportProvider Client=@_client ReportId="guid-del-informe" Limite="500">
    <div class="d-flex flex-column gap-2">
        @* Aquí pintas las filas a tu manera, leyéndolas del CascadingValue *@
    </div>
</DnzReportProvider>

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstring""Obligatorio. GUID del informe a ejecutar.
VariablesValuesDictionary<string, string>nullValores para las variables del informe.
QuerySearchstring""Búsqueda textual inicial.
AdvancedFilterList<FilterCondition>nullFiltros avanzados aplicados de entrada.
Limiteint500Máximo de filas a traer.
OrdenDictionary<string, bool>nullOrden inicial (clave = columna, valor = ascendente).
AdminModeboolfalseEjecuta el informe en modo administrador.
ChildContentRenderFragmentnullTu render, que lee las filas del contexto en cascada.
OnDataLoadedEventCallbackSe dispara cuando las filas terminan de cargar.

Mostrar datos tipados

Tienes una fila con un importe, una fecha, unos minutos... y quieres pintarlos con el formato correcto (moneda local, fecha amigable, color según el signo) sin formatear a mano. La familia de Spans lo hace: cada uno sabe formatear su tipo según la región del cliente.

<div class="d-flex flex-column gap-2">
    <DnzSpanMoney Amount=@factura.Total Label="Total" Icon="payments" AutoColor=true />
    <DnzSpanDate Value=@factura.Vencimiento ShowStatus=true />
</div>

El truco de AutoColor. En DnzSpanMoney, AutoColor=true pinta el importe en verde si es positivo y en rojo si es negativo. Si solo quieres una de las dos reglas, usa AutoColorGreen o AutoColorRed por separado.

DnzSpanMoney

Pinta un importe con el formato de moneda de la región del cliente. Opcionalmente con etiqueta, icono y color por signo.

<DnzSpanMoney Amount=@total Label="Total" Icon="payments" AutoColor=true />

Parámetros

ParámetroTipoPor defectoQué hace
Amountdecimal?0Importe a mostrar. Si es nulo, no pinta nada.
Labelstring""Etiqueta encima del importe.
Iconstring""Icono Material a la izquierda (requiere Label).
AutoColorboolfalseVerde si positivo, rojo si negativo.
AutoColorGreenboolfalseSolo verde cuando es positivo.
AutoColorRedboolfalseSolo rojo cuando es negativo.
IsVisiblebooltrueOculta el componente si es false.
CssClassstring""Clases CSS extra en el span del importe.
FontSizestring"16px"Tamaño de fuente del importe.

DnzSpanDate

Pinta una fecha con el formato amigable de la región, con tooltip de la fecha exacta y un badge de estado opcional ("Hoy", "Mañana", "Ayer", "Pasado", "Futuro").

<DnzSpanDate Value=@pedido.Fecha ShowStatus=true />

Parámetros

ParámetroTipoPor defectoQué hace
ValueDateOnly?nullFecha a mostrar. Si es nula, no pinta nada.
FriendlyModebooltrueUsa el formato amigable de la región.
ShowBadgeboolfalsePinta la fecha dentro de un badge.
ShowStatusboolfalseAñade un badge de color con el estado relativo a hoy.
Classstring""Clases CSS extra en el contenedor.
FontSizestring"0.875rem"Tamaño de fuente.

Hay un Span por cada tipo de dato: DnzSpanDateTime, DnzSpanDecimal, DnzSpanInteger, DnzSpanPercent, DnzSpanMinutes, DnzSpanGrams, DnzSpanBytes, DnzSpanGigaBytes, DnzSpanKV. Todos siguen el mismo patrón: les pasas el valor crudo y ellos formatean.


Elegir el selector correcto

Necesitas un desplegable para que el usuario elija un valor. DinaZen tiene tres, y cada uno resuelve un caso distinto. La regla de los tres segundos:

  • ¿Es un enum?DnzEnumDropDown. Saca las opciones del propio tipo.
  • ¿La lista ya está en memoria? (la cargaste antes, son pocas) → DnzDataGridDropDown. Desplegable con búsqueda y columnas.
  • ¿Hay que buscar/crear una ficha remota? (clientes, productos, miles de registros) → DnzRowSelector. Busca contra un informe en el servidor mientras escribes.

El binding es @bind-Value sobre tu enum. Las opciones salen solas del tipo.

<DnzEnumDropDown TEnum="EstadoPedidoE" @bind-Value=@_estado Placeholder="Estado" />

@code {
    private EstadoPedidoE _estado;
}

El binding es @bind-Value sobre un objeto que implemente IDinaupRow. Le pasas la lista por Data y le dices qué propiedad mostrar con TextProperty.

<DnzDataGridDropDown T="ClienteRow" @bind-Value=@_cliente Data=@_clientes TextProperty="Label" Label="Cliente" Width="320px" />

@code {
    private ClienteRow _cliente;
    private List<ClienteRow> _clientes = new();
}

El binding es @bind-SelectedRow. Le pasas el cliente y el GUID del informe contra el que busca; el desplegable consulta el servidor según escribes.

<DnzRowSelector Client=@_client ReportId="guid-informe-clientes" @bind-SelectedRow=@_clienteSel Label="Cliente" Placeholder="Buscar cliente..." />

@code {
    private IDinaupRow _clienteSel;
}

DnzEnumDropDown

Desplegable cuyas opciones salen de un enum. La etiqueta de cada opción se toma del atributo [Display(Name = ...)] si existe; si no, del nombre del valor.

<DnzEnumDropDown TEnum="EstadoPedidoE" @bind-Value=@_estado />

Parámetros

ParámetroTipoPor defectoQué hace
ValueTEnumValor seleccionado. Usa @bind-Value.
Namestring""Nombre del campo (para formularios).
Stylestring"width:200px"Estilo CSS del desplegable.
Placeholderstring""Texto cuando no hay selección.
DisabledboolfalseDesactiva el control.

Acepta además atributos extra que se pasan tal cual al elemento raíz.

DnzDataGridDropDown

Desplegable con búsqueda y columnas para una lista que ya tienes en memoria. El tipo T debe implementar IDinaupRow.

<DnzDataGridDropDown T="ClienteRow" @bind-Value=@_cliente Data=@_clientes TextProperty="Label" Label="Cliente" />

Parámetros

ParámetroTipoPor defectoQué hace
ValueTElemento seleccionado. Usa @bind-Value.
DataIEnumerable<T>lista vacíaOrigen de datos en memoria.
TextPropertystringnullRequerido. Propiedad a mostrar como texto.
ColorPropertystringnullPropiedad que da color de badge a cada opción.
IconoPropertystringnullPropiedad que aporta el icono de cada opción.
LabelstringnullEtiqueta del campo.
IconstringnullIcono a la izquierda del campo.
Widthstring"280px"Ancho del control.
StylestringnullEstilo CSS extra.
VisiblebooltrueMuestra u oculta el control.
IsRequiredboolfalseMarca el campo como obligatorio.
DisabledboolfalseDesactiva el control.
OpenInWindowbooltrueEl botón de abrir lanza la ficha en una ventana.
ClientDinaupClientCnullCliente, necesario para abrir la ficha del valor.
ColumnsRenderFragmentnullColumnas personalizadas del desplegable.
ValueTemplateRenderFragment<dynamic>nullPlantilla del valor seleccionado.
IconTemplateRenderFragment<T>nullPlantilla del icono por elemento.
ColumnWidthstring""Ancho de las columnas.
OnAddEventCallbackClic en el botón de añadir.
OnRemoveEventCallback<T>Clic en limpiar la selección.
OnOpenEventCallback<T>Clic en abrir la ficha del valor.

Acepta además atributos extra que se pasan tal cual al elemento raíz.

DnzRowSelector

Selector que busca contra un informe remoto mientras escribes. Para fichas que viven en el servidor (clientes, productos) y son demasiadas para tener en memoria.

<DnzRowSelector Client=@_client ReportId="guid-informe-clientes" @bind-SelectedRow=@_clienteSel Label="Cliente" />

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstringnullGUID del informe contra el que busca.
SelectedRowIDinaupRownullFila seleccionada. Usa @bind-SelectedRow.
LabelstringnullEtiqueta del campo.
IconstringnullIcono a la izquierda.
PlaceholderstringnullTexto cuando no hay selección.
Widthstring"280px"Ancho del control.
Stylestring"flex:1"Estilo CSS extra.
Classstring""Clases CSS extra.
IsRequiredboolfalseMarca el campo como obligatorio.
DisabledboolfalseDesactiva el control.
AdminModeboolfalseBusca en modo administrador.
AdvancedFilterList<FilterCondition>nullFiltros aplicados a la búsqueda.
OpenInWindowbooltrueEl botón de abrir lanza la ficha en una ventana.
DefaultIDGuidGuid.EmptyPreselecciona una fila por su ID al cargar.
KeyboardShortcutstringnullAtajo de teclado para abrir el selector.
OnAddEventCallback<Guid>Clic en el botón de añadir.
OnOpenRecordEventCallback<IDinaupRow>Clic en abrir la ficha de la fila.

Acepta además atributos extra que se pasan tal cual al elemento raíz.


Quieres un diálogo con la estructura y los botones de Play: título arriba, contenido en medio, botones al pie con la convención de la casa (cancelar discreto a la izquierda, confirmar destacado a la derecha). DnzDialogLayout te da los tres huecos.

@inject DialogService DialogService

<DnzDialogLayout Title="Editar pedido" Icon="edit">
    <BodyContent>
        <div class="d-flex flex-column gap-3 p-3">
            <RadzenTextBox @bind-Value=@_nombre Placeholder="Nombre" />
        </div>
    </BodyContent>
    <FooterContent>
        <div class="d-flex gap-2 justify-content-end">
            <RadzenButton Text="Cancelar" Variant="Variant.Text" ButtonStyle="ButtonStyle.Danger" Click=@CancelarAsync />
            <RadzenButton Text="Guardar" ButtonStyle="ButtonStyle.Success" Click=@GuardarAsync IsBusy=@_guardando />
        </div>
    </FooterContent>
</DnzDialogLayout>

@code {
    private string _nombre = "";
    private bool _guardando;

    private void CancelarAsync() => DialogService.Close();

    private async Task GuardarAsync()
    {
        _guardando = true;
        await PersistirAsync();
        DialogService.Close(true);
    }
}

La convención del pie: Cancelar en Danger + Text (discreto), Aceptar en Success sólido. Marca el botón de confirmar con IsBusy=@_guardando mientras procesa: el botón muestra el spinner y bloquea el doble clic.

DnzDialogLayout

Estructura de diálogo con cabecera, cuerpo desplazable y pie. Si omites TitleContent, genera la cabecera con Title + Icon + botón de cerrar; si omites FooterContent, muestra un botón "Cerrar" por defecto.

Parámetros

ParámetroTipoPor defectoQué hace
TitlestringnullTítulo de la cabecera (si no usas TitleContent).
IconstringnullIcono Material de la cabecera.
TitleContentRenderFragmentnullCabecera personalizada completa.
BodyContentRenderFragmentnullContenido del cuerpo (desplazable).
FooterContentRenderFragmentnullPie personalizado (botones de acción).
ContentStylestringnullEstilo CSS del cuerpo.
HeaderStylestringnullEstilo CSS de la cabecera.
FlatboolfalseDiálogo plano sin degradados ni fondo gris.

DnzConfirmDialog

Para una acción destructiva (eliminar, vaciar), no montes un diálogo entero: abre la confirmación con el helper estático OpenAsync, que devuelve true si el usuario confirma.

@code {
    private async Task EliminarAsync()
    {
        var ok = await DnzConfirmDialog.OpenAsync(DialogService, "Esta acción no se puede deshacer. ¿Eliminar el pedido?", title: "Eliminar pedido", severity: DnzConfirmSeverity.Danger, okText: "Eliminar");
        if (ok == false) return;
        await BorrarPedidoAsync();
    }
}

Firma del helper estático:

Task<bool> DnzConfirmDialog.OpenAsync(DialogService dialogService, string message, string title = "Confirmar", DnzConfirmSeverity severity = DnzConfirmSeverity.Warning, string okText = "Confirmar", string cancelText = "Cancelar")

El severity (Info, Warning, Danger, Success) cambia el icono, el color de acento y el estilo del botón de confirmar. Para algo irreversible, usa DnzConfirmSeverity.Danger.


Estados de carga

Mostrar que algo está pasando es parte de la UX. DinaZen tiene tres piezas y cada una resuelve un momento distinto:

  • DnzLoader — estoy ejecutando una acción (guardar, calcular, llamar a la API). Spinner.
  • DnzSkeleton — la interfaz aún no está lista; muestro su silueta gris en su lugar.
  • DnzDeferredContent — quiero renderizar contenido pesado un poco más tarde, mostrando un esqueleto mientras tanto.
@if (_procesando)
{
    <DnzLoader />
}
@if (_cargando)
{
    <DnzSkeleton Lines="3" />
}
<DnzDeferredContent DelayMs="500">
    <GraficoPesado Data=@_datos />
</DnzDeferredContent>

DnzLoader

Spinner de "estoy procesando". Centrado por defecto; horizontal si lo necesitas en línea.

<DnzLoader />

Parámetros

ParámetroTipoPor defectoQué hace
HorizontalboolfalseVariante horizontal en lugar de centrada.

DnzSkeleton

Silueta gris animada que ocupa el sitio del contenido mientras carga.

<DnzSkeleton Lines="3" Height="1.2rem" />

Parámetros

ParámetroTipoPor defectoQué hace
Linesint1Número de líneas (rectángulos) a mostrar.
Heightstring"1rem"Altura de cada línea.
Radiusstring"0.25rem"Radio de las esquinas.
MaxWidthstring"100%"Ancho máximo del bloque.

DnzDeferredContent

Retrasa el render del contenido pesado un instante y muestra un esqueleto mientras tanto. Útil para que las subpáginas pesadas no bloqueen la primera pintura.

<DnzDeferredContent DelayMs="500">
    <SeccionPesada />
</DnzDeferredContent>

Parámetros

ParámetroTipoPor defectoQué hace
DelayMsint500Milisegundos antes de mostrar el contenido.
ChildContentRenderFragmentContenido que se renderiza tras el retardo.
LoadingContentRenderFragmentnullContenido de carga personalizado (por defecto, un DnzSkeleton).
Classstring""Clases CSS del contenedor de carga.

Relacionado

  • DinaZen — introducción, instalación y convenciones de la librería.
  • Cliente Dinaup — crear el DinaupClientC que alimenta estas recetas.
  • SDK .NET — conexión, lectura y escritura de datos.
  • Informes de Dinaup Flex — de dónde sale el GUID que pasas a DnzReportView.

On this page