--- name: metabase_dashboard_next_row kind: function lang: py domain: infra version: "1.0.0" purity: impure signature: "def metabase_dashboard_next_row(client: MetabaseClient, *, dashboard_id: int, tab_id: int = 0) -> int" description: "Calcula la primera fila libre al final de una tab de dashboard: max(dc.row + dc.size_y) entre las dashcards de esa tab. Retorna 0 si la tab esta vacia. Evita el boilerplate manual de max() al colocar nuevas cards al final del dashboard." tags: [metabase, dashboard, layout, dashcard, row, tab, api, python] uses_functions: - metabase_get_dashboard_py_infra uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: [] params: - name: client desc: "MetabaseClient autenticado con sesion activa" - name: dashboard_id desc: "ID del dashboard cuyas filas se calculan" - name: tab_id desc: "ID de la tab cuya fila final se calcula. 0 (default) = dashcards sin dashboard_tab_id (dashboard sin pestanas o tab raiz)" output: "int: indice de fila (0-indexed) donde colocar la siguiente card. 0 si la tab no tiene dashcards." tested: false tests: [] test_file_path: "" file_path: "python/functions/metabase/metabase_dashboard_next_row.py" --- ## Ejemplo ```python from metabase import MetabaseClient, metabase_dashboard_next_row client = MetabaseClient("https://metabase.example.com", "token...") # Dashboard sin tabs: siguiente fila libre en la raiz next_row = metabase_dashboard_next_row(client, dashboard_id=10) new_dashcard = { "id": -1, "card_id": 99, "col": 0, "row": next_row, "size_x": 6, "size_y": 4, "parameter_mappings": [], "visualization_settings": {}, } # Dashboard con tabs: siguiente fila libre en tab 3 next_row = metabase_dashboard_next_row(client, dashboard_id=10, tab_id=3) ``` ## Notas - Cuando `tab_id == 0` se filtran dashcards donde `dashboard_tab_id` es falsy (None, 0 o ausente). Esto cubre dashboards sin tabs y la "tab raiz". - Requiere 1 request HTTP (GET dashboard). Si ya tienes el objeto dashboard en memoria, es mas eficiente calcular directamente: `max((dc["row"] + dc["size_y"] for dc in dashcards), default=0)`. - La fila retornada es la inmediatamente disponible — no reserva espacio ni verifica solapamiento de columnas.