Przejdź do głównej zawartości

React SDK

@concepttocloud/saiku-embed-react to typowany wrapper React wokół istniejącego custom elementu <saiku-embed>. Element już działa w Reakcie — React 18+ przekazuje nieznane atrybuty prosto do DOM — ale zespoły Reactowe oceniają względem npm install + typowanych importów, nie tagów <script>. To SDK zamyka tę lukę bez zmiany bazowego runtime.

Dostarczane w saiku v4.7 jako saiku#1432.

Instalacja

Okno terminala
npm install @concepttocloud/saiku-embed-react react

Pakiet peer-zależy od React 18+. Bazowe @concepttocloud/saiku-embed jest zależnością runtime i jest wciągane automatycznie.

Użycie

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"
/>
);
}

Import pakietu ma efekt uboczny w postaci rejestracji bazowego custom elementu — nie potrzebujesz osobnego import "@concepttocloud/saiku-embed", chyba że chcesz też, aby tag był dostępny poza drzewem React.

Propsy

PropTypDomyślnieUwagi
serverstringopcjonalnyOrigin launchera Saiku. Pomiń dla embedów tego samego origin.
pathstringwymaganyŚcieżka zapytania / ścieżka dashboardu / referencja kostki zależnie od kind.
kind"query" | "dashboard" | "ai""query"Wybiera odmianę embedu.
tokenstringopcjonalnyToken embedu wybity po stronie serwera. Pomiń dla publicznych grantów.
render"table" | "matrix" | "chart""table"Ma znaczenie tylko dla kind="query".
mode"bar" | "line" | "pie""bar"Ma znaczenie tylko dla render="chart".
heightstring"400px"Wysokość CSS renderowanej powierzchni.
styleReact.CSSPropertiesopcjonalnyStandardowy prop style Reacta.
classNamestringopcjonalnyStandardowy prop className Reacta.
idstringopcjonalnyPrzekazywany dla selektorów e2e.
data-testidstringopcjonalnyPrzekazywany do węzła DOM.

Pełne deklaracje typów dostarczane są w pliku index.d.ts pakietu.

Rodzaje

Zapisane zapytanie jako tabela

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

Wykres

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

Macierz

Tryb macierzy zachowuje strukturę osi wierszy / kolumn — miary na kolumnach, członkowie wymiaru na wierszach — zamiast spłaszczać do pojedynczej mapy klucz-wiersza jak robi to render="table". Przydatne dla raportów w stylu pivota.

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

Widżet AI ask

Wskaż token na kostkę (zamiast na zapisane zapytanie) i wrzuć pole ask w prostym języku. Wymaga tokenu embedu rodzaju AI i launchera ze skonfigurowanym dostawcą LLM.

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

Zapisany dashboard

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

Anonimowy publiczny embed

Jeśli zasób jest oznaczony jako publicznie osadzalny na serwerze (zobacz Publiczne embedy), pomiń token całkowicie:

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

Wybijanie tokenu z twojego serwera

mintEmbedToken() to pomocnik Node / edge-function dla bardzo częstego przypadku wybijania tokenu embedu w imieniu użytkownika końcowego przed wyrenderowaniem <SaikuEmbed>.

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 });
}

Po stronie klienta token ląduje w propsie token:

"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" />;
}

Opcje mintEmbedToken

OpcjaTypUwagi
serverstringBazowy URL launchera.
authorizationstringWartość nagłówka Authorization (Basic … lub Bearer …).
resourceKind"query" | "dashboard" | "ai"Rodzaj zasobu, do którego token jest przypięty.
resourcePathstringŚcieżka (dla query/dashboard) lub referencja kostki (dla ai).
ttlHoursnumber (opcjonalne)Czas życia tokenu; domyślnie serwera to 72h.
labelstring (opcjonalne)Czytelna etykieta, którą UI admina pokazuje obok tokenu.
fetchtypeof fetch (opcjonalne)Nadpisywalne dla testów + runtime’ów spoza przeglądarki (np. Cloudflare Workers).

Zwraca { token, expiresAt }. Rzuca wyjątek, jeśli serwer zwróci non-2xx lub ciało odpowiedzi nie jest kopertą tokenu.

Autouzupełnianie na surowym tagu

Pakiet rozszerza zarówno globalne JSX.IntrinsicElements (React 17/18), jak i React.JSX.IntrinsicElements (React 19+), więc surowy custom element dostaje ten sam typowany zbiór propsów co <SaikuEmbed>. Użyj, którego wolisz:

// 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" />

Motywy (theming)

Embed żyje wewnątrz shadow root, więc CSS strony hosta nie może przeciekać do środka. Przekoloruj przez niestandardowe właściwości CSS na wrapperze:

<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}
/>

Pełna lista zmiennych do motywowania jest na stronie bazowego embedu.

Przypinanie wersji

Wersja React SDK śledzi wydanie bazowego @concepttocloud/saiku-embed jeden-do-jednego. 3.19.0 SDK używa 3.19.0 bazowego runtime — zależność runtime jest przypięta w czasie wydania, więc konsument nigdy nie może przypadkowo pomieszać wersji major między tymi dwoma.

Rozmiar bundle

  • Wrapper: ~1 KB po gzip (cały runtime to pojedyncze wywołanie React.createElement).
  • Bazowy custom element: ~213 KB po gzip (runtime CE Svelte 5 + ECharts + renderery embedu).
  • React: peer dep — nie liczony przeciwko żadnemu z pakietów.

Nie-cele dla v1

  • Hooki React dla wyników zapytań (useSaikuQuery) — custom element obsługuje własny stan; typowany hook danych duplikuje powierzchnię AI Query API. Kontynuacja, jeśli ktoś poprosi.
  • Wariant server-component<SaikuEmbed> działa tylko w przeglądarce (renderuje shadow root). Server-renderowane dane początkowe do hydracji to kontynuacja, jeśli wzorzec okaże się bolesny.
  • Rozdzielanie bundle per rodzaj — obecny wrapper zawsze wciąga pełny bazowy bundle. Tree-shaking według rodzaju to zmiana pakietu bazowego, nie zmiana wrappera.

Dokąd dalej