d110aa40f9
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
125 lines
4.5 KiB
Python
125 lines
4.5 KiB
Python
"""Añade N cards como fila horizontal al final de una tab de dashboard."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .client import MetabaseClient
|
|
from .metabase_dashboard_next_row import metabase_dashboard_next_row
|
|
from .metabase_copy_dashcard_mappings import metabase_copy_dashcard_mappings
|
|
from .metabase_update_dashboard_safe import metabase_update_dashboard_safe
|
|
|
|
|
|
def metabase_dashboard_append_row(
|
|
client: MetabaseClient,
|
|
*,
|
|
dashboard_id: int,
|
|
tab_id: int,
|
|
card_ids: list[int],
|
|
height: int = 4,
|
|
donor_card_id: int = 0,
|
|
grid_width: int = 24,
|
|
) -> dict:
|
|
"""Añade N cards como fila horizontal al final de una tab de dashboard.
|
|
|
|
Calcula la primera fila libre de la tab indicada, distribuye las cards
|
|
horizontalmente con ancho uniforme (``grid_width // len(card_ids)``) y
|
|
opcionalmente copia los ``parameter_mappings`` de una card donante a cada
|
|
nueva card. Internamente delega en ``metabase_dashboard_next_row``,
|
|
``metabase_copy_dashcard_mappings`` y ``metabase_update_dashboard_safe``.
|
|
|
|
Args:
|
|
client: MetabaseClient autenticado con sesion activa.
|
|
dashboard_id: ID del dashboard donde se añaden las cards.
|
|
tab_id: ID de la tab donde se insertan las cards. Usar ``0`` para
|
|
dashboards sin tabs o para la tab raiz.
|
|
card_ids: Lista de IDs de cards a colocar como fila. El orden de
|
|
la lista determina el orden de izquierda a derecha.
|
|
height: Altura en filas del grid para cada card. Default ``4``.
|
|
donor_card_id: Si distinto de ``0``, copia los ``parameter_mappings``
|
|
de esa card (que debe existir ya en el dashboard) a cada nueva
|
|
card. Util para replicar los 18 filtros de dashboard sin configurar
|
|
manualmente cada mapping. Default ``0`` (sin mappings).
|
|
grid_width: Anchura total del grid de Metabase. Default ``24``
|
|
(estandar de Metabase). Cada card recibe
|
|
``grid_width // len(card_ids)`` columnas.
|
|
|
|
Returns:
|
|
Dict con el resumen de la operacion devuelto por
|
|
``metabase_update_dashboard_safe``::
|
|
|
|
{
|
|
"added": [lista de IDs negativos asignados],
|
|
"updated": int, # dashcards existentes conservados
|
|
"removed": int, # dashcards eliminados (0 en este caso)
|
|
"response": dict, # respuesta raw de PUT /api/dashboard/:id
|
|
}
|
|
|
|
Raises:
|
|
ValueError: Si ``card_ids`` esta vacio, o si ``donor_card_id != 0``
|
|
y esa card no existe en el dashboard.
|
|
httpx.HTTPStatusError: Si la API de Metabase devuelve 4xx/5xx.
|
|
|
|
Example:
|
|
>>> # Añadir 4 KPIs al final de la tab 7, copiando filtros de card 42
|
|
>>> result = metabase_dashboard_append_row(
|
|
... client,
|
|
... dashboard_id=10,
|
|
... tab_id=7,
|
|
... card_ids=[101, 102, 103, 104],
|
|
... height=4,
|
|
... donor_card_id=42,
|
|
... )
|
|
>>> print(result["added"]) # [-1, -2, -3, -4]
|
|
|
|
>>> # Sin filtros, 2 cards en dashboard sin tabs
|
|
>>> result = metabase_dashboard_append_row(
|
|
... client,
|
|
... dashboard_id=10,
|
|
... tab_id=0,
|
|
... card_ids=[200, 201],
|
|
... height=6,
|
|
... )
|
|
"""
|
|
if not card_ids:
|
|
raise ValueError("card_ids no puede estar vacio")
|
|
|
|
# 1. Calcular siguiente fila libre
|
|
next_row = metabase_dashboard_next_row(
|
|
client, dashboard_id=dashboard_id, tab_id=tab_id
|
|
)
|
|
|
|
# 2. Ancho de cada card
|
|
size_x = grid_width // len(card_ids)
|
|
|
|
# 3. Construir dashcards
|
|
new_dashcards: list[dict] = []
|
|
for i, cid in enumerate(card_ids):
|
|
# Copiar mappings del donor si se especifico
|
|
if donor_card_id != 0:
|
|
mappings = metabase_copy_dashcard_mappings(
|
|
client,
|
|
dashboard_id=dashboard_id,
|
|
source_card_id=donor_card_id,
|
|
dest_card_id=cid,
|
|
)
|
|
else:
|
|
mappings = []
|
|
|
|
dashcard: dict = {
|
|
"card_id": cid,
|
|
"dashboard_tab_id": tab_id,
|
|
"row": next_row,
|
|
"col": i * size_x,
|
|
"size_x": size_x,
|
|
"size_y": height,
|
|
"parameter_mappings": mappings,
|
|
"visualization_settings": {},
|
|
}
|
|
new_dashcards.append(dashcard)
|
|
|
|
# 4. Actualizar el dashboard
|
|
return metabase_update_dashboard_safe(
|
|
client,
|
|
dashboard_id,
|
|
dashcards_add=new_dashcards,
|
|
)
|