diff --git a/.changeset/models-embed-feature.md b/.changeset/models-embed-feature.md new file mode 100644 index 0000000..85952d1 --- /dev/null +++ b/.changeset/models-embed-feature.md @@ -0,0 +1,5 @@ +--- +"@basedash/embed": minor +--- + +Add models as a first-class embed feature with `hideModels` and ``. diff --git a/CONTRACT.md b/CONTRACT.md index dd9211f..ecc4ec7 100644 --- a/CONTRACT.md +++ b/CONTRACT.md @@ -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: diff --git a/README.md b/README.md index 478c509..ecc1ead 100644 --- a/README.md +++ b/README.md @@ -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 + +``` + +The organization must have models enabled. + ### `BasedashApp` Embeds the complete Basedash app. Feature props map to the existing Basedash @@ -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` diff --git a/src/embed.ts b/src/embed.ts index 3e98952..3e3b48c 100644 --- a/src/embed.ts +++ b/src/embed.ts @@ -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; @@ -32,6 +33,7 @@ export interface EmbedOptions { hideDashboards?: boolean; hideInsights?: boolean; hideAutomations?: boolean; + hideModels?: boolean; hideSuggestedPrompts?: boolean; } @@ -68,6 +70,7 @@ export const DEFAULT_EMBED_OPTIONS = { hideDashboards: false, hideInsights: false, hideAutomations: false, + hideModels: false, hideSuggestedPrompts: false, } as const satisfies Required; @@ -77,6 +80,7 @@ export const CHAT_EMBED_OPTIONS = { hideDashboards: true, hideInsights: true, hideAutomations: true, + hideModels: true, } as const satisfies Required; export const DASHBOARDS_EMBED_OPTIONS = { @@ -85,6 +89,7 @@ export const DASHBOARDS_EMBED_OPTIONS = { hideChat: true, hideInsights: true, hideAutomations: true, + hideModels: true, } as const satisfies Required; export const INSIGHTS_EMBED_OPTIONS = { @@ -93,6 +98,7 @@ export const INSIGHTS_EMBED_OPTIONS = { hideChat: true, hideDashboards: true, hideAutomations: true, + hideModels: true, } as const satisfies Required; export const AUTOMATIONS_EMBED_OPTIONS = { @@ -101,6 +107,16 @@ export const AUTOMATIONS_EMBED_OPTIONS = { hideChat: true, hideDashboards: true, hideInsights: true, + hideModels: true, +} as const satisfies Required; + +export const MODELS_EMBED_OPTIONS = { + ...DEFAULT_EMBED_OPTIONS, + hideOrgName: true, + hideChat: true, + hideDashboards: true, + hideInsights: true, + hideAutomations: true, } as const satisfies Required; export function buildEmbedUrl({ @@ -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, @@ -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), diff --git a/src/index.ts b/src/index.ts index d805ed0..ae608ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export { DEFAULT_EMBED_OPTIONS, EMBED_QUERY_PARAMS, INSIGHTS_EMBED_OPTIONS, + MODELS_EMBED_OPTIONS, buildEmbedUrl, buildSharedDashboardUrl, } from "./embed"; diff --git a/src/react/index.tsx b/src/react/index.tsx index f2529e8..da83556 100644 --- a/src/react/index.tsx +++ b/src/react/index.tsx @@ -15,6 +15,7 @@ import { DASHBOARDS_EMBED_OPTIONS, DEFAULT_BASEDASH_URL, INSIGHTS_EMBED_OPTIONS, + MODELS_EMBED_OPTIONS, buildEmbedUrl, buildSharedDashboardUrl, } from "../embed"; @@ -242,6 +243,7 @@ export interface BasedashAppProps extends AuthenticatedEmbedProps { hideDashboards?: boolean; hideInsights?: boolean; hideAutomations?: boolean; + hideModels?: boolean; hideSuggestedPrompts?: boolean; } @@ -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; /** @@ -294,6 +303,7 @@ export const BasedashApp = forwardRef( hideDashboards, hideInsights, hideAutomations, + hideModels, hideSuggestedPrompts, title = "Basedash", ...frameProps @@ -312,6 +322,7 @@ export const BasedashApp = forwardRef( hideDashboards, hideInsights, hideAutomations, + hideModels, hideSuggestedPrompts, }} title={title} @@ -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 ( + + ); +}); + export const BasedashSharedDashboard = forwardRef< HTMLIFrameElement, BasedashSharedDashboardProps diff --git a/tests/embed.test.ts b/tests/embed.test.ts index f888bc0..de61286 100644 --- a/tests/embed.test.ts +++ b/tests/embed.test.ts @@ -6,6 +6,7 @@ import { DASHBOARDS_EMBED_OPTIONS, DEFAULT_BASEDASH_URL, INSIGHTS_EMBED_OPTIONS, + MODELS_EMBED_OPTIONS, buildEmbedUrl, buildSharedDashboardUrl, } from "../src"; @@ -24,6 +25,7 @@ describe("buildEmbedUrl", () => { hide_dashboards: "false", hide_insights: "false", hide_automations: "false", + hide_models: "false", hide_suggested_prompts: "false", }); }); @@ -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, }); }); diff --git a/tests/react.test.tsx b/tests/react.test.tsx index c423936..eb2eb71 100644 --- a/tests/react.test.tsx +++ b/tests/react.test.tsx @@ -9,6 +9,7 @@ import { BasedashChat, BasedashDashboards, BasedashInsights, + BasedashModels, BasedashProvider, BasedashSharedDashboard, } from "../src/react"; @@ -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", () => { @@ -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", () => { @@ -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(); + 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 () => {