Zum Inhalt springen

React SDK

@concepttocloud/saiku-embed-react ist ein typisierter React-Wrapper um das bestehende <saiku-embed>-Custom-Element. Das Element funktioniert bereits in React — React 18+ leitet unbekannte Attribute direkt an das DOM durch — aber React-Teams bewerten anhand von npm install + typisierten Imports, nicht <script>-Tags. Dieses SDK schließt diese Lücke, ohne die zugrundeliegende Runtime zu ändern.

Ausgeliefert in saiku v4.7 als saiku#1432.

Installation

Terminal-Fenster
npm install @concepttocloud/saiku-embed-react react

Das Paket hat eine Peer-Abhängigkeit von React 18+. Das Basis-Paket @concepttocloud/saiku-embed ist eine Runtime-Abhängigkeit und wird automatisch mit hereingezogen.

Verwendung

import { SaikuEmbed } from "@concepttocloud/saiku-embed-react";
function Dashboard({ token }: { token: string }) {
return (
<SaikuEmbed
server="https://YOUR-WORKSPACE.saiku.bi"
token={token}
path="homes/admin/Sales.saiku"
render="chart"
mode="bar"
height="480px"
/>
);
}

Der Import des Pakets hat den Nebeneffekt, dass das zugrundeliegende Custom-Element registriert wird — Sie brauchen keinen separaten import "@concepttocloud/saiku-embed", es sei denn, Sie möchten das Tag auch außerhalb des React-Baums verfügbar haben.

Props

PropTypStandardAnmerkungen
serverstringoptionalOrigin des Saiku-Launchers. Weglassen für Same-Origin-Embeds.
pathstringerforderlichQuery-Pfad / Dashboard-Pfad / Cube-Ref, abhängig von kind.
kind"query" | "dashboard" | "ai""query"Wählt die Embed-Variante.
tokenstringoptionalServerseitig geminteter Embed-Token. Weglassen für öffentliche Grants.
render"table" | "matrix" | "chart""table"Nur bei kind="query" bedeutsam.
mode"bar" | "line" | "pie""bar"Nur bei render="chart" bedeutsam.
heightstring"400px"CSS-Höhe der gerenderten Oberfläche.
styleReact.CSSPropertiesoptionalStandard-React-Style-Prop.
classNamestringoptionalStandard-React-className-Prop.
idstringoptionalDurchgereicht für e2e-Selektoren.
data-testidstringoptionalDurchgereicht an den DOM-Knoten.

Vollständige Typdeklarationen werden in der index.d.ts des Pakets ausgeliefert.

Kinds

Gespeicherte Query als Tabelle

<SaikuEmbed
server="https://saiku.example.com"
token={token}
path="homes/admin/Sales.saiku"
height="400px"
/>

Chart

<SaikuEmbed
server="https://saiku.example.com"
token={token}
path="homes/admin/Sales.saiku"
render="chart"
mode="bar"
height="500px"
/>

Matrix

Der Matrix-Modus bewahrt die Zeilen- / Spaltenachsen-Struktur — Measures auf Spalten, Dimension-Members auf Zeilen — statt zu einer einzelnen Row-Key-Map zu flatten, wie es render="table" tut. Nützlich für Pivot-Style-Reports.

<SaikuEmbed
server="https://saiku.example.com"
token={token}
path="homes/admin/Sales.saiku"
render="matrix"
height="500px"
/>

AI-Ask-Widget

Zeigen Sie den Token auf einen Cube (statt auf eine gespeicherte Query) und setzen Sie eine natürlichsprachliche Ask-Box hinein. Erfordert einen AI-kind-Embed-Token und einen Launcher mit einem konfigurierten LLM-Provider.

<SaikuEmbed
server="https://saiku.example.com"
token={aiToken}
kind="ai"
path="foodmart/FoodMart/FoodMart/Sales"
height="240px"
/>

Gespeichertes Dashboard

<SaikuEmbed
server="https://saiku.example.com"
token={token}
kind="dashboard"
path="homes/admin/exec.saikudash"
height="700px"
/>

Anonymes öffentliches Embed

Wenn die Ressource auf dem Server als öffentlich einbettbar markiert ist (siehe Öffentliche Embeds), lassen Sie den Token ganz weg:

<SaikuEmbed
server="https://saiku.example.com"
path="shared/public-chart.saiku"
render="chart"
/>

Einen Token von Ihrem Server minten

mintEmbedToken() ist ein Node- / Edge-Function-Helfer für den sehr gängigen Fall, im Namen eines Endnutzers einen Embed-Token zu minten, bevor <SaikuEmbed> gerendert wird.

app/api/embed-token/route.ts
import { mintEmbedToken } from "@concepttocloud/saiku-embed-react";
export async function POST(request: Request) {
const auth = "Basic " + Buffer.from(
`${process.env.SAIKU_USER}:${process.env.SAIKU_PASS}`,
).toString("base64");
const { token, expiresAt } = await mintEmbedToken({
server: process.env.SAIKU_URL!,
authorization: auth,
resourceKind: "query",
resourcePath: "homes/admin/Sales.saiku",
ttlHours: 24,
label: "Public marketing page",
});
return Response.json({ token, expiresAt });
}

Clientseitig landet der Token im token-Prop:

"use client";
import useSWR from "swr";
import { SaikuEmbed } from "@concepttocloud/saiku-embed-react";
export default function EmbedTile() {
const { data } = useSWR("/api/embed-token", (u) => fetch(u, { method: "POST" }).then((r) => r.json()));
if (!data?.token) return <div>Loading…</div>;
return <SaikuEmbed server="" token={data.token} path="homes/admin/Sales.saiku" />;
}

mintEmbedToken-Optionen

OptionTypAnmerkungen
serverstringBasis-URL des Launchers.
authorizationstringWert für den Authorization-Header (Basic … oder Bearer …).
resourceKind"query" | "dashboard" | "ai"Art der Ressource, die der Token anpinnt.
resourcePathstringPfad (für query/dashboard) oder Cube-Ref (für ai).
ttlHoursnumber (optional)Token-Lebensdauer; Server-Standard ist 72 h.
labelstring (optional)Menschenlesbares Label, das die Admin-UI neben dem Token zeigt.
fetchtypeof fetch (optional)Überschreibbar für Tests + Nicht-Browser-Runtimes (z. B. Cloudflare Workers).

Gibt { token, expiresAt } zurück. Wirft, wenn der Server Nicht-2xx zurückgibt oder der Antwort-Body kein Token-Umschlag ist.

Autocomplete auf dem rohen Tag

Das Paket erweitert sowohl das globale JSX.IntrinsicElements (React 17/18) als auch React.JSX.IntrinsicElements (React 19+), sodass das rohe Custom-Element denselben typisierten Prop-Satz wie <SaikuEmbed> bekommt. Verwenden Sie, was Sie bevorzugen:

// Typed React component
<SaikuEmbed server="" token={token} path="" render="chart" />
// Or the raw custom element (also typed)
<saiku-embed server="" token={token} path="" render="chart" />

Theming

Das Embed lebt innerhalb eines Shadow-Roots, sodass CSS der Host-Seite nicht hineinlecken kann. Farbanpassung über CSS-Custom-Properties auf dem Wrapper:

<SaikuEmbed
server=""
token={token}
path=""
style={{
"--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",
} as React.CSSProperties}
/>

Die vollständige Liste der themebaren Variablen ist auf der Basis-Embed-Seite.

Version-Pinning

Die Version des React-SDK folgt der Basis-Release von @concepttocloud/saiku-embed eins zu eins. 3.19.0 des SDK verwendet 3.19.0 der Basis-Runtime — die Runtime-Abhängigkeit wird zum Release-Zeitpunkt gepinnt, sodass ein Konsument niemals versehentlich Majors über die beiden hinweg mischen kann.

Bundle-Größe

  • Wrapper: ~1 KB gzipped (die gesamte Runtime ist ein einzelner React.createElement-Aufruf).
  • Basis-Custom-Element: ~213 KB gzipped (Svelte-5-CE-Runtime + ECharts + die Embed-Renderer).
  • React: Peer-Dependency — wird gegen keines der beiden Pakete gezählt.

Nicht-Ziele für v1

  • React-Hooks für Query-Ergebnisse (useSaikuQuery) — das Custom-Element verwaltet seinen eigenen State; ein typisierter Data-Hook dupliziert die AI Query API-Oberfläche. Follow-up, falls jemand fragt.
  • Server-Component-Variante<SaikuEmbed> ist nur im Browser (es rendert einen Shadow-Root). Serverseitig gerenderte initiale Daten für Hydration sind ein Follow-up, falls sich das Muster als schmerzhaft erweist.
  • Bundle-Splitting pro Kind — der aktuelle Wrapper zieht immer das volle Basis-Bundle. Tree-Shaking nach Kind ist eine Änderung im Basis-Paket, keine Wrapper-Änderung.

Wohin als Nächstes