feat(metabase): expansion cards y documents — export, model, ProseMirror validation, copy nativo
Cards: export_card (CSV/XLSX/JSON), create_model (type=model para fuentes MBQL). Documents: prosemirror_card_embed helper (resizeNode envolviendo cardEmbed), validacion automatica contra whitelist TipTap antes de enviar, copy_document refactorizado al endpoint nativo POST /api/document/:id/copy. Docs: dataset_query legacy vs MBQL5, template-tags, whitelist de nodos. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: prosemirror_card_embed
|
||||
kind: function
|
||||
lang: py
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def prosemirror_card_embed(card_id: int, height: int = 400) -> dict"
|
||||
description: "Genera un nodo ProseMirror cardEmbed envuelto en resizeNode con altura adecuada. Un cardEmbed desnudo renderiza con ~50px — este helper produce el formato que Metabase espera para que la card se vea bien."
|
||||
tags: [metabase, document, prosemirror, cardEmbed, resizeNode, pure, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [uuid]
|
||||
params:
|
||||
- name: card_id
|
||||
desc: "ID de la card/pregunta de Metabase a embeber"
|
||||
- name: height
|
||||
desc: "altura en pixeles del embed (default 400). minHeight se fija en 280"
|
||||
output: "dict ProseMirror: nodo resizeNode > cardEmbed, insertable en el array content de un document"
|
||||
tested: false
|
||||
tests: []
|
||||
test_file_path: ""
|
||||
file_path: "python/functions/metabase/documents.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from metabase.documents import metabase_create_document, prosemirror_card_embed
|
||||
|
||||
doc = metabase_create_document(client, "Reporte", {
|
||||
"type": "doc",
|
||||
"content": [
|
||||
{"type": "heading", "attrs": {"level": 2},
|
||||
"content": [{"type": "text", "text": "Revenue"}]},
|
||||
prosemirror_card_embed(7711, height=500),
|
||||
{"type": "paragraph",
|
||||
"content": [{"type": "text", "text": "Datos actualizados."}]},
|
||||
]
|
||||
})
|
||||
```
|
||||
|
||||
## Por qué existe este helper
|
||||
|
||||
```python
|
||||
# MAL — cardEmbed desnudo: renderiza con ~50px de alto, ilegible
|
||||
{"type": "cardEmbed", "attrs": {"id": 42}}
|
||||
|
||||
# BIEN — prosemirror_card_embed: envuelto en resizeNode
|
||||
prosemirror_card_embed(42, height=450)
|
||||
# → {"type": "resizeNode", "attrs": {"height": 450, "minHeight": 280},
|
||||
# "content": [{"type": "cardEmbed", "attrs": {"id": 42, "_id": "uuid...", "name": null}}]}
|
||||
```
|
||||
|
||||
El formato con `resizeNode` es el que usa el editor de Metabase cuando un usuario inserta una card manualmente — sin él, la card se renderiza diminuta.
|
||||
Reference in New Issue
Block a user