Información del Panel

Acceder a Configuraciones de Panel del Dashboard

Ver y crear paneles de visualización en dashboards, incluyendo su diseño, posicionamiento y configuraciones.

Obtener Paneles del Dashboard

GET /api/{tenantId}/{projectId}/dashboard/{dashboardId}/panels

Recupera todos los paneles de visualización configurados en un dashboard, incluyendo tipos de panel, posiciones, dimensiones y configuraciones.

Parámetros de Ruta

Parámetro Tipo Requerido Descripción
tenantId GUID El identificador del tenant
projectId GUID El identificador del proyecto
dashboardId GUID El identificador del dashboard

Respuesta (200 OK)

{
  "dashboardId": "880e8400-e29b-41d4-a716-446655440000",
  "panels": [
    {
      "panelId": "990e8400-e29b-41d4-a716-446655440000",
      "name": "Process Flow Chart",
      "panelType": "DashboardPanelProcessMap",
      "position": "Row: 1, Col: 1",
      "width": 6,
      "height": 4,
      "configuration": "{\"dataSource\": \"MainProcess\", \"visualization\": \"flow\"}"
    },
    {
      "panelId": "aa0e8400-e29b-41d4-a716-446655440000",
      "name": "KPI Summary",
      "panelType": "DashboardPanelSingleValue",
      "position": "Row: 1, Col: 7",
      "width": 3,
      "height": 2,
      "configuration": "{\"metric\": \"avgCycleTime\", \"format\": \"duration\"}"
    }
  ]
}

Campos de Respuesta

Campo Tipo Descripción
dashboardId GUID El dashboard que contiene estos paneles
panels arreglo Lista de objetos panel

Campos del Objeto Panel

Campo Tipo Descripción
panelId GUID Identificador único del panel
name string Título para mostrar del panel
panelType string Tipo de visualización (ver sección Tipos de Panel)
position string Posición en la cuadrícula como "Row: X, Col: Y"
width entero Ancho del panel en unidades de cuadrícula
height entero Alto del panel en unidades de cuadrícula
configuration string Cadena JSON con configuraciones específicas del panel

Respuestas de Error

No Encontrado (404):

{
  "Error": "Dashboard not found",
  "DashboardId": "880e8400-e29b-41d4-a716-446655440000"
}

Crear Panel del Dashboard

POST /api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel

Crea un nuevo panel de visualización en un dashboard. La API genera automáticamente el bloque selector apropiado según el tipo de panel y la configuración proporcionada.

Parámetros de Ruta

Parámetro Tipo Requerido Descripción
tenantId GUID El identificador del tenant
projectId GUID El identificador del proyecto
dashboardId GUID El identificador del dashboard

Cuerpo de la Solicitud

{
  "title": "string (obligatorio)",
  "description": "string (opcional)",
  "panelType": "string (obligatorio)",
  "blockId": "GUID (obligatorio para paneles de datos)",
  "row": "integer (obligatorio, basado en 0)",
  "column": "integer (obligatorio, basado en 0)",
  "width": "integer (obligatorio, 1-12)",
  "height": "integer (obligatorio, 1-20)",
  "settings": "string (opcional, JSON para configuración del selector)"
}

Campos del Cuerpo de Solicitud

Campo Tipo Requerido Descripción
title string Título para mostrar del panel
description string No Descripción opcional
panelType string Nombre de la clase del tipo de panel (ver sección Tipos de Panel)
blockId GUID Sí* ID del bloque calculador para mostrar (*no requerido para DashboardPanelDashboardNote)
row entero Posición fila (basado en 0)
column entero Posición columna (basado en 0)
width entero Ancho del panel en unidades de cuadrícula (1-12)
height entero Alto del panel en unidades de cuadrícula (1-20)
settings string No Cadena JSON con configuración del selector

Respuesta (201 Creado)

{
  "panelId": "5b54172c-b15c-4dd9-bab6-6cfceb7389df",
  "title": "My KPI Panel",
  "dashboardPanelClassName": "DashboardPanelSingleValue",
  "row": 0,
  "column": 0,
  "width": 2,
  "height": 1,
  "blockId": "db0dd1b9-63b5-4754-92b1-2764f4a3fb68"
}

Nota: El blockId en la respuesta es el ID del bloque SELECTOR, no el ID original del bloque calculador. La API crea automáticamente un bloque selector que envuelve el calculador.

Respuestas de Error

Solicitud Incorrecta (400) - Falta Block:

{
  "Error": "VALIDATION_ERROR",
  "Message": "BlockId is required for panel type 'DashboardPanelSingleValue'"
}

Solicitud Incorrecta (400) - Tipo de Panel Inválido:

{
  "Error": "VALIDATION_ERROR",
  "Message": "Invalid panel type 'InvalidType'. Valid types: DashboardPanelSingleValue, DashboardPanelCalculator, ..."
}

Solicitud Incorrecta (400) - Bloque No Encontrado:

{
  "Error": "VALIDATION_ERROR",
  "Message": "Block 'guid' does not exist"
}

Tipos de Panel

Los dashboards mindzieStudio soportan los siguientes tipos de panel:

Clase Tipo de Panel Selector Creado Descripción
DashboardPanelCalculator SelectorFullCalculator Salida completa del calculador (mapas de proceso, tendencias, gráficos)
DashboardPanelSingleValue SelectorSingleValueFromLabel Valor único / tarjeta KPI
DashboardPanelHorizontalBarChart SelectorMultiColumns Gráfico de barras horizontal, listas clasificadas
DashboardPanelDataTable SelectorFullCalculator Visualización en tabla de datos
DashboardPanelProcessMap SelectorFullCalculator Visualización de mapa de proceso
DashboardPanelDashboardNote (ninguno) Panel de texto/nota (no requiere blockId)
DashboardPanelRecommendationSentence (ninguno) Visualización de recomendación AI

Configuraciones de Panel por Tipo

DashboardPanelSingleValue (Tarjetas KPI)

Cuando panelType es DashboardPanelSingleValue, la configuración especifica cómo extraer un valor único de la salida del calculador:

{
  "tableIndex": 0,
  "labelColumnName": "Name",
  "labelName": "Total Case Count",
  "valueColumnName": "Value",
  "formatText": "N0"
}
Configuración Tipo Descripción
tableIndex entero Qué tabla de salida usar (usualmente 0)
labelColumnName string Columna que contiene las etiquetas (usualmente "Name")
labelName string La etiqueta a encontrar (ej., "Total Case Count")
valueColumnName string Columna que contiene el valor (usualmente "Value")
formatText string Cadena de formato .NET (N0, F2, P0, etc.)

Mejor uso con: CalculatorDataInformation, CalculatorOverview

DashboardPanelHorizontalBarChart (Gráficos de Barras)

Cuando panelType es DashboardPanelHorizontalBarChart, incluya columnNames en settings para activar SelectorMultiColumns:

{
  "tableIndex": 0,
  "columnNames": ["ActivityName", "Count"],
  "sortColumnName": "Count",
  "sortAscending": false,
  "maxRows": 10
}
Configuración Tipo Descripción
tableIndex entero Qué tabla de salida usar
columnNames arreglo Columnas a incluir en el gráfico (DEBEN coincidir con la salida del calculador)
sortColumnName string Columna para ordenar
sortAscending booleano Dirección de ordenamiento
maxRows entero Máximo de filas a mostrar

IMPORTANTE: Los nombres de columna deben coincidir exactamente con las columnas de salida del calculador. Por ejemplo, CalculatorActivityFrequency usa el nombre de columna de actividad del conjunto de datos (ej., "ActivityName"), no un genérico "Activity".

Mejor uso con: CalculatorActivityFrequency, CalculatorResourceFrequency

DashboardPanelCalculator (Visualizaciones Completas)

Para salida completa del calculador (mapas de proceso, tendencias), no se requieren configuraciones especiales:

{}

O omita el parámetro settings por completo.

Arquitectura del Panel

Los paneles del dashboard no se conectan directamente con bloques calculadores. En su lugar, usan una arquitectura de tres capas:

Panel.InputBlockId -> Selector Block -> Calculator Block (via parent_id)

¿Por qué Selectores? Los bloques selector definen CÓMO mostrar la salida del calculador:

  • SelectorFullCalculator: Muestra toda la salida con configuraciones visuales
  • SelectorSingleValueFromLabel: Extrae un único valor buscando por etiqueta
  • SelectorMultiColumns: Extrae columnas específicas con orden y límite

La API crea automáticamente el bloque selector adecuado cuando creas un panel apuntando a un calculador.

Sistema de Diseño del Panel

Los paneles del dashboard usan un sistema de diseño basado en cuadrícula:

  • Unidades de cuadrícula: Sistema de 12 columnas
  • Posición: Coordenadas de fila y columna (basadas en 0)
  • Tamaño: Ancho (1-12 columnas), alto (1-20 filas)
  • Responsive: Escalado automático en diferentes tamaños de pantalla

Ejemplos de Implementación

Obtener Paneles del Dashboard

cURL

curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/87654321-4321-4321-4321-210987654321/dashboard/880e8400-e29b-41d4-a716-446655440000/panels" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Crear Panel KPI (Valor Único)

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Total Cases",
    "panelType": "DashboardPanelSingleValue",
    "blockId": "calculator-data-information-guid",
    "row": 0,
    "column": 0,
    "width": 2,
    "height": 1,
    "settings": "{\"tableIndex\":0,\"labelColumnName\":\"Name\",\"labelName\":\"Total Case Count\",\"valueColumnName\":\"Value\",\"formatText\":\"N0\"}"
  }'

Crear Gráfico de Barras Horizontal

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Activity Distribution",
    "panelType": "DashboardPanelHorizontalBarChart",
    "blockId": "calculator-activity-frequency-guid",
    "row": 1,
    "column": 0,
    "width": 6,
    "height": 3,
    "settings": "{\"tableIndex\":0,\"columnNames\":[\"ActivityName\",\"Count\"],\"sortColumnName\":\"Count\",\"sortAscending\":false,\"maxRows\":10}"
  }'

Crear Panel de Calculadora Completo

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Case Count",
    "panelType": "DashboardPanelCalculator",
    "blockId": "calculator-case-count-guid",
    "row": 0,
    "column": 2,
    "width": 2,
    "height": 1
  }'

JavaScript/Node.js

const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const PROJECT_ID = '87654321-4321-4321-4321-210987654321';
const BASE_URL = 'https://your-mindzie-instance.com';

async function getDashboardPanels(dashboardId, token) {
  const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dashboard/${dashboardId}/panels`;

  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  });

  if (response.ok) {
    return await response.json();
  } else if (response.status === 404) {
    throw new Error('Dashboard not found');
  } else {
    throw new Error(`Failed to get panels: ${response.status}`);
  }
}

async function createDashboardPanel(dashboardId, panelData, token) {
  const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dashboard/${dashboardId}/panel`;

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(panelData)
  });

  if (response.ok) {
    return await response.json();
  } else {
    const error = await response.json();
    throw new Error(error.Message || `Failed to create panel: ${response.status}`);
  }
}

// Uso - Obtener paneles
const panels = await getDashboardPanels('dashboard-guid', 'your-auth-token');
console.log(`Dashboard: ${panels.dashboardId}`);
console.log(`Paneles: ${panels.panels.length}`);

// Uso - Crear panel KPI
const newPanel = await createDashboardPanel('dashboard-guid', {
  title: 'Total Cases',
  panelType: 'DashboardPanelSingleValue',
  blockId: 'calculator-data-information-guid',
  row: 0,
  column: 0,
  width: 2,
  height: 1,
  settings: JSON.stringify({
    tableIndex: 0,
    labelColumnName: 'Name',
    labelName: 'Total Case Count',
    valueColumnName: 'Value',
    formatText: 'N0'
  })
}, 'your-auth-token');

console.log(`Panel creado: ${newPanel.panelId}`);

Python

import requests
import json

TENANT_ID = '12345678-1234-1234-1234-123456789012'
PROJECT_ID = '87654321-4321-4321-4321-210987654321'
BASE_URL = 'https://your-mindzie-instance.com'

def get_dashboard_panels(dashboard_id, token):
    """Obtener todos los paneles de un dashboard."""
    url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dashboard/{dashboard_id}/panels'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    response = requests.get(url, headers=headers)

    if response.ok:
        return response.json()
    elif response.status_code == 404:
        raise Exception('Dashboard no encontrado')
    else:
        raise Exception(f'Error al obtener paneles: {response.status_code}')


def create_dashboard_panel(dashboard_id, panel_data, token):
    """Crear un nuevo panel en un dashboard."""
    url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dashboard/{dashboard_id}/panel'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    response = requests.post(url, headers=headers, json=panel_data)

    if response.ok:
        return response.json()
    else:
        error = response.json()
        raise Exception(error.get('Message', f'Error al crear panel: {response.status_code}'))


# Uso - Obtener paneles
panels = get_dashboard_panels('dashboard-guid', 'your-auth-token')
print(f"Dashboard: {panels['dashboardId']}")
print(f"Cantidad de paneles: {len(panels['panels'])}")

# Uso - Crear panel KPI
settings = {
    'tableIndex': 0,
    'labelColumnName': 'Name',
    'labelName': 'Total Case Count',
    'valueColumnName': 'Value',
    'formatText': 'N0'
}

new_panel = create_dashboard_panel('dashboard-guid', {
    'title': 'Total Cases',
    'panelType': 'DashboardPanelSingleValue',
    'blockId': 'calculator-data-information-guid',
    'row': 0,
    'column': 0,
    'width': 2,
    'height': 1,
    'settings': json.dumps(settings)
}, 'your-auth-token')

print(f"Panel creado: {new_panel['panelId']}")

C#

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class DashboardPanelsResponse
{
    public Guid DashboardId { get; set; }
    public List<PanelInfo> Panels { get; set; }
}

public class PanelInfo
{
    public Guid PanelId { get; set; }
    public string Name { get; set; }
    public string PanelType { get; set; }
    public string Position { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public string Configuration { get; set; }
}

public class CreatePanelRequest
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string PanelType { get; set; }
    public Guid BlockId { get; set; }
    public int Row { get; set; }
    public int Column { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public string Settings { get; set; }
}

public class CreatePanelResponse
{
    public Guid PanelId { get; set; }
    public string Title { get; set; }
    public string DashboardPanelClassName { get; set; }
    public int Row { get; set; }
    public int Column { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public Guid BlockId { get; set; }
}

public class DashboardPanelClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;
    private readonly Guid _tenantId;
    private readonly Guid _projectId;
    private readonly JsonSerializerOptions _jsonOptions;

    public DashboardPanelClient(string baseUrl, Guid tenantId, Guid projectId, string accessToken)
    {
        _baseUrl = baseUrl;
        _tenantId = tenantId;
        _projectId = projectId;
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
        _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
    }

    public async Task<DashboardPanelsResponse> GetDashboardPanelsAsync(Guid dashboardId)
    {
        var url = $"{_baseUrl}/api/{_tenantId}/{_projectId}/dashboard/{dashboardId}/panels";
        var response = await _httpClient.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<DashboardPanelsResponse>(json, _jsonOptions);
        }
        else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            throw new Exception($"Dashboard {dashboardId} no encontrado");
        }

        throw new Exception($"Error al obtener paneles: {response.StatusCode}");
    }

    public async Task<CreatePanelResponse> CreatePanelAsync(Guid dashboardId, CreatePanelRequest request)
    {
        var url = $"{_baseUrl}/api/{_tenantId}/{_projectId}/dashboard/{dashboardId}/panel";
        var json = JsonSerializer.Serialize(request, _jsonOptions);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(url, content);

        if (response.IsSuccessStatusCode)
        {
            var responseJson = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<CreatePanelResponse>(responseJson, _jsonOptions);
        }

        var errorJson = await response.Content.ReadAsStringAsync();
        throw new Exception($"Error al crear panel: {errorJson}");
    }
}

// Uso
var client = new DashboardPanelClient(
    "https://your-mindzie-instance.com",
    Guid.Parse("12345678-1234-1234-1234-123456789012"),
    Guid.Parse("87654321-4321-4321-4321-210987654321"),
    "your-access-token");

// Obtener paneles
var panels = await client.GetDashboardPanelsAsync(Guid.Parse("dashboard-guid"));
Console.WriteLine($"Dashboard: {panels.DashboardId}");
foreach (var panel in panels.Panels)
{
    Console.WriteLine($"- {panel.Name} ({panel.PanelType})");
}

// Crear panel KPI
var newPanel = await client.CreatePanelAsync(Guid.Parse("dashboard-guid"), new CreatePanelRequest
{
    Title = "Total Cases",
    PanelType = "DashboardPanelSingleValue",
    BlockId = Guid.Parse("calculator-data-information-guid"),
    Row = 0,
    Column = 0,
    Width = 2,
    Height = 1,
    Settings = JsonSerializer.Serialize(new
    {
        tableIndex = 0,
        labelColumnName = "Name",
        labelName = "Total Case Count",
        valueColumnName = "Value",
        formatText = "N0"
    })
});

Console.WriteLine($"Panel creado: {newPanel.PanelId}");

Notas Importantes

Capacidades de la API

  • Acceso de Lectura: Usar endpoint GET para recuperar configuraciones de panel
  • Acceso de Creación: Usar endpoint POST para crear nuevos paneles con creación automática de bloque selector
  • Acceso de Modificación: La modificación de paneles se realiza actualmente a través de la interfaz mindzieStudio
  • Acceso de Eliminación: La eliminación de paneles se realiza actualmente a través de la interfaz mindzieStudio

Análisis de Configuración

El campo configuration contiene una cadena JSON que debe ser parseada para acceder a las configuraciones.

Sistema de Diseño

Las posiciones de los paneles usan un sistema de cuadrícula fila/columna con tamaño flexible. Los valores de fila y columna son basados en 0 al crear paneles.