Pular para o conteúdo

Incorporando o Saiku

O Web Component <saiku-embed/> permite incorporar uma consulta ou dashboard salvo do Saiku dentro de qualquer página HTML — seu site de marketing, um blog, um portal de cliente, uma wiki ou um dashboard em React / Vue. O mesmo custom element funciona em qualquer host: JSX do React, templates do Vue, Svelte, HTML puro.

É um Web Component de verdade, não um wrapper de framework, então a página host não precisa saber nada sobre o funcionamento interno do Saiku.

Instalação

Duas maneiras equivalentes de carregar o bundle. Escolha a que se encaixar na sua página host.

Sem etapa de build — aponte uma tag <script> para o bundle que o seu Saiku já serve:

<script src="https://YOUR-WORKSPACE.saiku.bi/ui/saiku-embed.js"></script>

O download tem cerca de 213 KB gzipados. Os navegadores fazem cache, então a segunda página na mesma origem o recebe instantaneamente.

Um exemplo prático

O embed mínimo viável — uma consulta salva, renderizada como tabela:

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
token="tx-..."
path="homes/admin/Examples/Trend.saiku"
height="400px"
></saiku-embed>

Os três atributos essenciais são server (origem do seu Saiku), path (caminho do repositório da consulta salva) e token (o token de embed — veja Gerar um token abaixo). Todo o resto tem defaults sensatos.

Gerar um token

Os tokens são gerados por um usuário autenticado que pode ler o recurso. O token é opaco e tem escopo: ele concede acesso somente leitura a uma consulta ou dashboard salvo, expira após o TTL que você especifica e pode ser revogado a qualquer momento.

Gerar um token
curl -X POST 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/tokens' \
-u admin:admin \
-H 'Content-Type: application/json' \
-d '{
"resourceKind": "query",
"resourcePath": "homes/admin/Examples/Trend.saiku",
"ttlHours": 72,
"label": "Marketing landing page"
}'
# Response:
# {
# "status": "OK",
# "token": "tx-...",
# "resourceKind": "query",
# "resourcePath": "homes/admin/Examples/Trend.saiku",
# "expiresAt": 1739102400000
# }

Cole o token no <saiku-embed token="..."> da sua página host.

Limites de TTL. O default é 72 horas. O máximo é 30 dias (720 horas). Um TTL curto é o default mais seguro para um token que trafega por páginas host arbitrárias.

Limite por usuário. Cada usuário pode manter até 200 tokens ativos ao mesmo tempo. Revogue tokens não usados para liberar o orçamento.

Listar seus tokens

Terminal window
curl 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/tokens' \
-u admin:admin

Admins podem listar todos os tokens do sistema com ?all=true.

Revogar um token

Terminal window
curl -X DELETE 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/tokens/<token>' \
-u admin:admin

A revogação tem efeito na próxima requisição — não há sessão de convidado para sequestrar.

Embeds públicos (anônimos)

Se um recurso deve ser legível sem um token — um gráfico público na sua landing page, um dashboard aberto em um blog — torne-o publicamente incorporável:

Terminal window
curl -X POST 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/public' \
-u admin:admin \
-H 'Content-Type: application/json' \
-d '{
"resourceKind": "query",
"resourcePath": "shared/public-chart.saiku",
"label": "Homepage chart"
}'

Então a página host omite o token completamente:

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
path="shared/public-chart.saiku"
render="chart"
></saiku-embed>

Listar + revogar concessões públicas

Terminal window
# Liste suas concessões públicas
curl 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/public' \
-u admin:admin
# Revogar
curl -X DELETE 'https://YOUR-WORKSPACE.saiku.bi/rest/saiku/api/embed/public?kind=query&path=shared/public-chart.saiku' \
-u admin:admin

Referência de atributos

AtributoDefaultObservações
serverobrigatórioOrigem do seu launcher do Saiku, ex.: https://YOUR-WORKSPACE.saiku.bi
pathobrigatórioCaminho no repositório. Termina em .saiku para consultas, .saikudash para dashboards
kindqueryquery ou dashboard
token(nenhum)Token de embed de POST /saiku/api/embed/tokens. Omita para leituras públicas anônimas
rendertablePara kind="query": table ou chart
modebarPara render="chart": bar, line ou pie
height400pxAltura em CSS (uma min-height na superfície renderizada)

Os atributos são reativos — o componente re-renderiza sempre que qualquer um deles muda. Em React, Vue ou Svelte, vincular estado a essas props simplesmente funciona.

Exemplos

Consulta salva como tabela

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
token="tx-..."
path="homes/admin/Examples/Trend.saiku"
></saiku-embed>

Consulta salva como gráfico

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
token="tx-..."
path="homes/admin/Examples/Sales.saiku"
render="chart"
mode="bar"
height="500px"
></saiku-embed>

Modos de gráfico:

  • bar (default) — barras categóricas; a primeira coluna não numérica é a categoria, cada coluna numérica vira uma série própria
  • line — mesmo layout, séries de linha
  • pie — apenas a primeira coluna numérica; cai para “No numeric series” se o resultado for apenas texto

Tooltips mostram as strings de células formatadas pelo servidor ($1,234, 12.3%, etc.) para que a página host veja as mesmas legendas que o workbench do Saiku veria.

Dashboard salvo

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
token="tx-..."
kind="dashboard"
path="homes/admin/exec.saikudash"
height="700px"
></saiku-embed>

O componente busca o layout do dashboard uma vez e então executa uma consulta por tile para cada tile de gráfico / KPI em paralelo sob o escopo de dados do dono do dashboard. Tipos de tile na v1:

Tipo de tileO que é renderizado
textO texto do tile, como um parágrafo
chartUm gráfico ECharts (usa tile.chartType como modo)
kpiUm único número grande da medida do tile
filterIgnorado — widgets de filtro são apenas do workbench na v1
outroPlaceholder “Unsupported tile”

Embed público anônimo

Quando o recurso tem uma concessão pública, omita o token:

<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
path="shared/public.saiku"
render="chart"
mode="pie"
></saiku-embed>

Dentro do React

import "@concepttocloud/saiku-embed";
export function SalesEmbed({ token }: { token: string }) {
return (
<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
token={token}
path="homes/admin/Examples/Sales.saiku"
render="chart"
mode="line"
height="500px"
/>
);
}

Dentro do Vue

<template>
<saiku-embed
server="https://YOUR-WORKSPACE.saiku.bi"
:token="token"
path="homes/admin/Examples/Sales.saiku"
render="chart"
/>
</template>
<script setup lang="ts">
import "@concepttocloud/saiku-embed";
defineProps<{ token: string }>();
</script>

Temas

O embed é renderizado dentro de uma shadow root aberta, então o CSS da página host não vaza para dentro e o CSS do embed não vaza para fora. Para recolorir, defina variáveis CSS no seletor saiku-embed da página host:

saiku-embed {
--saiku-embed-fg: #0f172a;
--saiku-embed-bg: transparent;
--saiku-embed-border: #cbd5e1;
--saiku-embed-header-bg: #f1f5f9;
--saiku-embed-tile-bg: #ffffff;
--saiku-embed-row-hover: #e2e8f0;
--saiku-embed-negative: #b91c1c;
--saiku-embed-error: #b91c1c;
--saiku-embed-muted: #64748b;
}

O modo escuro é só uma media query que vira as mesmas variáveis:

@media (prefers-color-scheme: dark) {
saiku-embed {
--saiku-embed-fg: #f1f5f9;
--saiku-embed-bg: #0f172a;
--saiku-embed-border: #334155;
--saiku-embed-header-bg: #1e293b;
--saiku-embed-tile-bg: #1e293b;
--saiku-embed-row-hover: #334155;
}
}

Modelo de segurança

A superfície de embed é projetada para páginas host hostis — sua consulta salva pode acabar em um site de terceiros que você não controla. Os defaults refletem isso.

Tokens são opacos, autoritativos no servidor, revogáveis

  • Tokens são ids aleatórios de 256 bits, codificados em Base64-URL — não adivinháveis.
  • Eles não carregam nenhuma claim embutida: o servidor mantém o registro autoritativo (tipo de recurso + caminho, snapshot do dono, expiração, flag de revogado) e o consulta em cada requisição. A revogação tem efeito na próxima requisição — sem “esperar a assinatura expirar” no estilo JWT.
  • Cada token fixa exatamente um recurso. Repetir um token contra qualquer outro recurso (caminho errado, tipo errado, expirado, revogado) retorna o mesmo EMBED_INVALID opaco 401 — sondas não conseguem enumerar.

Transporte apenas por header

O token trafega como header HTTP X-Saiku-Embed-Token. Nós deliberadamente não aceitamos parâmetros de query ?token=… porque parâmetros de URL vazam para:

  • logs de acesso do servlet
  • logs do proxy reverso
  • histórico do navegador
  • o header Referer enviado em cada asset externo na página host

O JS empacotado lê o token do seu atributo <saiku-embed token="…"> e o envia como header em cada fetch.

Isolamento de cookies cross-origin

O embed faz fetch com credentials: "omit". Se o usuário da página host estiver logado no Saiku em outra aba, esse cookie de sessão não trafega com as leituras de embed. O token É o único portador de auth nesta superfície.

Escopo de dados do dono

Tanto tokens quanto concessões públicas tiram um snapshot da lista de roles do dono no momento da geração / concessão e executam a consulta do embed sob essa identidade via sessionService.runAs. Uma consulta incorporada publicamente que usa filtros injetados na sessão renderiza sob a perspectiva do outorgante, não sob o default anônimo (vazio) — o que você autorizou no momento da concessão é exatamente o que o público vê.

Headers de resposta defense-in-depth

Toda resposta de embed carrega:

  • X-Content-Type-Options: nosniff — navegadores não devem fazer MIME-sniff em um body JSON (que pode carregar HTML de tile de texto ou legendas de membros) e executá-lo como HTML
  • Referrer-Policy: no-referrer — nunca vazar o token via Referer em assets externos
  • Cache-Control: no-store, max-age=0 — dados de negócio incorporados nunca são cacheados por proxies ou histórico do navegador

Erros amigáveis

Quando um fetch falha (token expirado, token revogado, caminho errado, sem concessão pública), a página host vê um genérico “This embed is unavailable.” — não o body bruto EMBED_INVALID. A página host é um terceiro e não precisa saber se a falha foi um token expirado ou uma revogação.

Tamanho do bundle

Cerca de 213 KB gzipados no momento desta escrita — runtime do custom element do Svelte 5 + ECharts (core + bar / line / pie + quatro componentes comuns, tree-shaken modular) + os renderers do embed. O bundle é cacheado agressivamente pelo navegador; o segundo embed na mesma origem o recebe instantaneamente.

Limitações

  • Apenas formato records. O formato de cellset matrix não é renderizado na v1.
  • Tiles de filtro são ignorados em dashboards. O embed renderiza os dados autorados como estão, sem uma barra de filtro interativa.
  • Markdown em tiles de texto renderiza como texto puro. Não empacotamos marked para manter o tamanho baixo.
  • Resultados de AI Query (/ai/query) ainda não estão ligados como fonte de embed. Acompanhe em saiku — uma PR de follow-up adicionará kind="ai".

Veja também

  • Autenticação — gerar API keys para acesso programático ao Saiku Cloud (diferente dos tokens de embed)
  • MCP — conectar LLMs aos seus cubos