Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/models-embed-feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@basedash/embed": minor
---

Add models as a first-class embed feature with `hideModels` and `<BasedashModels />`.
1 change: 1 addition & 0 deletions CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Source in the app repository:
| `hideDashboards` | `hide_dashboards` | boolean |
| `hideInsights` | `hide_insights` | boolean |
| `hideAutomations` | `hide_automations` | boolean |
| `hideModels` | `hide_models` | boolean |
| `hideSuggestedPrompts` | `hide_suggested_prompts` | boolean |

Sources in the app repository:
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ Embeds automations and hides all other primary features.

The organization must have automations enabled.

### `BasedashModels`

Embeds models and hides all other primary features.

```tsx
<BasedashModels />
```

The organization must have models enabled.

### `BasedashApp`

Embeds the complete Basedash app. Feature props map to the existing Basedash
Expand All @@ -135,12 +145,13 @@ embed configuration.
hideOrgName
hideInsights
hideAutomations
hideModels
hideSuggestedPrompts
/>
```

At least one of chat, dashboards, insights, or automations must remain visible.
Basedash falls back to chat if all four are hidden.
At least one of chat, dashboards, insights, automations, or models must remain visible.
Basedash falls back to chat if all five are hidden.

### `BasedashSharedDashboard`

Expand Down
21 changes: 21 additions & 0 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const EMBED_QUERY_PARAMS = {
hideDashboards: "hide_dashboards",
hideInsights: "hide_insights",
hideAutomations: "hide_automations",
hideModels: "hide_models",
hideSuggestedPrompts: "hide_suggested_prompts",
} as const;

Expand All @@ -32,6 +33,7 @@ export interface EmbedOptions {
hideDashboards?: boolean;
hideInsights?: boolean;
hideAutomations?: boolean;
hideModels?: boolean;
hideSuggestedPrompts?: boolean;
}

Expand Down Expand Up @@ -68,6 +70,7 @@ export const DEFAULT_EMBED_OPTIONS = {
hideDashboards: false,
hideInsights: false,
hideAutomations: false,
hideModels: false,
hideSuggestedPrompts: false,
} as const satisfies Required<EmbedOptions>;

Expand All @@ -77,6 +80,7 @@ export const CHAT_EMBED_OPTIONS = {
hideDashboards: true,
hideInsights: true,
hideAutomations: true,
hideModels: true,
} as const satisfies Required<EmbedOptions>;

export const DASHBOARDS_EMBED_OPTIONS = {
Expand All @@ -85,6 +89,7 @@ export const DASHBOARDS_EMBED_OPTIONS = {
hideChat: true,
hideInsights: true,
hideAutomations: true,
hideModels: true,
} as const satisfies Required<EmbedOptions>;

export const INSIGHTS_EMBED_OPTIONS = {
Expand All @@ -93,6 +98,7 @@ export const INSIGHTS_EMBED_OPTIONS = {
hideChat: true,
hideDashboards: true,
hideAutomations: true,
hideModels: true,
} as const satisfies Required<EmbedOptions>;

export const AUTOMATIONS_EMBED_OPTIONS = {
Expand All @@ -101,6 +107,16 @@ export const AUTOMATIONS_EMBED_OPTIONS = {
hideChat: true,
hideDashboards: true,
hideInsights: true,
hideModels: true,
} as const satisfies Required<EmbedOptions>;

export const MODELS_EMBED_OPTIONS = {
...DEFAULT_EMBED_OPTIONS,
hideOrgName: true,
hideChat: true,
hideDashboards: true,
hideInsights: true,
hideAutomations: true,
} as const satisfies Required<EmbedOptions>;

export function buildEmbedUrl({
Expand All @@ -122,6 +138,7 @@ export function buildEmbedUrl({
options?.hideInsights ?? DEFAULT_EMBED_OPTIONS.hideInsights,
hideAutomations:
options?.hideAutomations ?? DEFAULT_EMBED_OPTIONS.hideAutomations,
hideModels: options?.hideModels ?? DEFAULT_EMBED_OPTIONS.hideModels,
hideSuggestedPrompts:
options?.hideSuggestedPrompts ??
DEFAULT_EMBED_OPTIONS.hideSuggestedPrompts,
Expand Down Expand Up @@ -149,6 +166,10 @@ export function buildEmbedUrl({
EMBED_QUERY_PARAMS.hideAutomations,
String(resolvedOptions.hideAutomations),
);
url.searchParams.set(
EMBED_QUERY_PARAMS.hideModels,
String(resolvedOptions.hideModels),
);
url.searchParams.set(
EMBED_QUERY_PARAMS.hideSuggestedPrompts,
String(resolvedOptions.hideSuggestedPrompts),
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export {
DEFAULT_EMBED_OPTIONS,
EMBED_QUERY_PARAMS,
INSIGHTS_EMBED_OPTIONS,
MODELS_EMBED_OPTIONS,
buildEmbedUrl,
buildSharedDashboardUrl,
} from "./embed";
Expand Down
41 changes: 41 additions & 0 deletions src/react/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
DASHBOARDS_EMBED_OPTIONS,
DEFAULT_BASEDASH_URL,
INSIGHTS_EMBED_OPTIONS,
MODELS_EMBED_OPTIONS,
buildEmbedUrl,
buildSharedDashboardUrl,
} from "../embed";
Expand Down Expand Up @@ -242,6 +243,7 @@ export interface BasedashAppProps extends AuthenticatedEmbedProps {
hideDashboards?: boolean;
hideInsights?: boolean;
hideAutomations?: boolean;
hideModels?: boolean;
hideSuggestedPrompts?: boolean;
}

Expand Down Expand Up @@ -274,6 +276,13 @@ export interface BasedashAutomationsProps extends AuthenticatedEmbedProps {
hideOrgName?: boolean;
}

export interface BasedashModelsProps extends AuthenticatedEmbedProps {
/**
* @default true
*/
hideOrgName?: boolean;
}

export interface BasedashSharedDashboardProps extends BasedashFrameProps {
publicSharingLinkId: string;
/**
Expand All @@ -294,6 +303,7 @@ export const BasedashApp = forwardRef<HTMLIFrameElement, BasedashAppProps>(
hideDashboards,
hideInsights,
hideAutomations,
hideModels,
hideSuggestedPrompts,
title = "Basedash",
...frameProps
Expand All @@ -312,6 +322,7 @@ export const BasedashApp = forwardRef<HTMLIFrameElement, BasedashAppProps>(
hideDashboards,
hideInsights,
hideAutomations,
hideModels,
hideSuggestedPrompts,
}}
title={title}
Expand Down Expand Up @@ -445,6 +456,36 @@ export const BasedashAutomations = forwardRef<
);
});

export const BasedashModels = forwardRef<
HTMLIFrameElement,
BasedashModelsProps
>(function BasedashModels(
{
token,
instanceUrl,
theme,
hideOrgName,
title = "Basedash models",
...frameProps
},
ref,
) {
return (
<AuthenticatedBasedashFrame
ref={ref}
token={token}
instanceUrl={instanceUrl}
options={{
...MODELS_EMBED_OPTIONS,
theme: theme ?? MODELS_EMBED_OPTIONS.theme,
hideOrgName: hideOrgName ?? MODELS_EMBED_OPTIONS.hideOrgName,
}}
title={title}
{...frameProps}
/>
);
});

export const BasedashSharedDashboard = forwardRef<
HTMLIFrameElement,
BasedashSharedDashboardProps
Expand Down
13 changes: 13 additions & 0 deletions tests/embed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DASHBOARDS_EMBED_OPTIONS,
DEFAULT_BASEDASH_URL,
INSIGHTS_EMBED_OPTIONS,
MODELS_EMBED_OPTIONS,
buildEmbedUrl,
buildSharedDashboardUrl,
} from "../src";
Expand All @@ -24,6 +25,7 @@ describe("buildEmbedUrl", () => {
hide_dashboards: "false",
hide_insights: "false",
hide_automations: "false",
hide_models: "false",
hide_suggested_prompts: "false",
});
});
Expand Down Expand Up @@ -54,24 +56,35 @@ describe("buildEmbedUrl", () => {
hideDashboards: true,
hideInsights: true,
hideAutomations: true,
hideModels: true,
});
expect(DASHBOARDS_EMBED_OPTIONS).toMatchObject({
hideChat: true,
hideDashboards: false,
hideInsights: true,
hideAutomations: true,
hideModels: true,
});
expect(INSIGHTS_EMBED_OPTIONS).toMatchObject({
hideChat: true,
hideDashboards: true,
hideInsights: false,
hideAutomations: true,
hideModels: true,
});
expect(AUTOMATIONS_EMBED_OPTIONS).toMatchObject({
hideChat: true,
hideDashboards: true,
hideInsights: true,
hideAutomations: false,
hideModels: true,
});
expect(MODELS_EMBED_OPTIONS).toMatchObject({
hideChat: true,
hideDashboards: true,
hideInsights: true,
hideAutomations: true,
hideModels: false,
});
});

Expand Down
17 changes: 17 additions & 0 deletions tests/react.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
BasedashChat,
BasedashDashboards,
BasedashInsights,
BasedashModels,
BasedashProvider,
BasedashSharedDashboard,
} from "../src/react";
Expand All @@ -30,6 +31,7 @@ describe("authenticated React embeds", () => {
expect(src.searchParams.get("hide_dashboards")).toBe("true");
expect(src.searchParams.get("hide_insights")).toBe("true");
expect(src.searchParams.get("hide_automations")).toBe("true");
expect(src.searchParams.get("hide_models")).toBe("true");
});

it("renders a dashboards-only iframe and supports overrides", () => {
Expand Down Expand Up @@ -60,6 +62,7 @@ describe("authenticated React embeds", () => {
expect(src.searchParams.get("hide_dashboards")).toBe("true");
expect(src.searchParams.get("hide_insights")).toBe("false");
expect(src.searchParams.get("hide_automations")).toBe("true");
expect(src.searchParams.get("hide_models")).toBe("true");
});

it("renders an automations-only iframe", () => {
Expand All @@ -72,6 +75,20 @@ describe("authenticated React embeds", () => {
expect(src.searchParams.get("hide_dashboards")).toBe("true");
expect(src.searchParams.get("hide_insights")).toBe("true");
expect(src.searchParams.get("hide_automations")).toBe("false");
expect(src.searchParams.get("hide_models")).toBe("true");
});

it("renders a models-only iframe", () => {
const { getByTitle } = render(<BasedashModels token="token" />);
const src = new URL(
getByTitle("Basedash models").getAttribute("src") ?? "",
);

expect(src.searchParams.get("hide_chat")).toBe("true");
expect(src.searchParams.get("hide_dashboards")).toBe("true");
expect(src.searchParams.get("hide_insights")).toBe("true");
expect(src.searchParams.get("hide_automations")).toBe("true");
expect(src.searchParams.get("hide_models")).toBe("false");
});

it("fetches one token through BasedashProvider", async () => {
Expand Down