-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
connect settings to the embed homepage and show it #40528
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
import { useMemo } from "react"; | ||
|
||
import { useSetting } from "metabase/common/hooks"; | ||
import { getPlan } from "metabase/common/utils/plan"; | ||
import { useSelector } from "metabase/lib/redux"; | ||
import { getDocsUrl } from "metabase/selectors/settings"; | ||
import { isEEBuild } from "metabase/lib/utils"; | ||
import { getDocsUrl, getSetting } from "metabase/selectors/settings"; | ||
|
||
import { EmbedHomepageView } from "./EmbedHomepageView"; | ||
|
||
|
@@ -30,12 +34,25 @@ export const EmbedHomepage = () => { | |
getDocsUrl(state, { page: "embedding/static-embedding" }), | ||
); | ||
|
||
const plan = useSelector(state => | ||
getPlan(getSetting(state, "token-features")), | ||
); | ||
|
||
const defaultTab = useMemo(() => { | ||
// we want to show the interactive tab for EE builds | ||
// unless it's a starter cloud plan, which is EE build but doesn't have interactive embedding | ||
if (isEEBuild()) { | ||
return plan === "starter" ? "static" : "interactive"; | ||
} | ||
return "static"; | ||
}, [plan]); | ||
|
||
return ( | ||
<EmbedHomepageView | ||
exampleDashboardId={exampleDashboardId} | ||
embeddingAutoEnabled={embeddingAutoEnabled} | ||
licenseActiveAtSetup={licenseActiveAtSetup} | ||
plan="oss-starter" | ||
defaultTab={defaultTab} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed the prop here, I think the extra abstraction wasn't worth it, the plan was only used to determine the default tab |
||
interactiveEmbeddingQuickstartUrl={interactiveEmbeddingQuickStartUrl} | ||
embeddingDocsUrl={embeddingDocsUrl} | ||
// eslint-disable-next-line no-unconditional-metabase-links-render -- only visible to admins | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ export type EmbedHomepageViewProps = { | |
embeddingAutoEnabled: boolean; | ||
exampleDashboardId?: number; | ||
licenseActiveAtSetup: boolean; | ||
plan: "oss-starter" | "pro-ee"; | ||
defaultTab: "interactive" | "static"; | ||
// links | ||
interactiveEmbeddingQuickstartUrl: string; | ||
embeddingDocsUrl: string; | ||
|
@@ -21,8 +21,12 @@ export type EmbedHomepageViewProps = { | |
}; | ||
|
||
export const EmbedHomepageView = (props: EmbedHomepageViewProps) => { | ||
const { embeddingAutoEnabled, plan, embeddingDocsUrl, analyticsDocsUrl } = | ||
props; | ||
const { | ||
embeddingAutoEnabled, | ||
defaultTab, | ||
embeddingDocsUrl, | ||
analyticsDocsUrl, | ||
} = props; | ||
return ( | ||
<Stack maw={550}> | ||
<Group> | ||
|
@@ -32,7 +36,7 @@ export const EmbedHomepageView = (props: EmbedHomepageViewProps) => { | |
<Card px="xl" py="lg"> | ||
{/* eslint-disable-next-line no-literal-metabase-strings -- only visible to admins */} | ||
<Title order={2} mb="md">{t`Embedding Metabase`}</Title> | ||
<Tabs defaultValue={plan === "oss-starter" ? "static" : "interactive"}> | ||
<Tabs defaultValue={defaultTab}> | ||
<Tabs.List> | ||
<Tabs.Tab value="interactive">{t`Interactive`}</Tabs.Tab> | ||
<Tabs.Tab value="static">{t`Static`}</Tabs.Tab> | ||
|
@@ -57,14 +61,14 @@ export const EmbedHomepageView = (props: EmbedHomepageViewProps) => { | |
<Text color="text-light" size="sm"> | ||
{/* eslint-disable-next-line no-literal-metabase-strings -- only visible to admins */} | ||
{jt`Because you expressed interest in embedding Metabase, we took this step for you so that you can more easily try it out. You can turn it off anytime in ${( | ||
<Link | ||
to="admin/settings/embedding-in-other-applications" | ||
<Anchor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed from |
||
size="sm" | ||
component={Link} | ||
to="/admin/settings/embedding-in-other-applications" | ||
key="link" | ||
> | ||
<Anchor size="sm"> | ||
admin/settings/embedding-in-other-applications | ||
</Anchor> | ||
</Link> | ||
admin/settings/embedding-in-other-applications | ||
</Anchor> | ||
)}.`} | ||
</Text> | ||
</Card> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,22 +32,22 @@ export const InteractiveTabContent = ({ | |
style={{ listStyleType: "decimal" }} | ||
> | ||
{!licenseActiveAtSetup && ( | ||
<> | ||
<List.Item> | ||
<Link to="/admin/settings/license"> | ||
<Anchor size="sm">{t`Activate your commercial license`}</Anchor> | ||
</Link> | ||
</List.Item> | ||
</> | ||
<List.Item> | ||
<Anchor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is to avoid the warning about nested tags, same for following |
||
size="sm" | ||
component={Link} | ||
to="/admin/settings/license" | ||
>{t`Activate your commercial license`}</Anchor> | ||
</List.Item> | ||
)} | ||
{embeddingAutoEnabled === false && ( | ||
<> | ||
<List.Item> | ||
<Link to="/admin/settings/embedding-in-other-applications"> | ||
<Anchor size="sm">{t`Enable embedding in the settings`}</Anchor> | ||
</Link> | ||
</List.Item> | ||
</> | ||
<List.Item> | ||
<Anchor | ||
size="sm" | ||
component={Link} | ||
to="/admin/settings/embedding-in-other-applications" | ||
>{t`Enable embedding in the settings`}</Anchor> | ||
</List.Item> | ||
)} | ||
{exampleDashboardId === undefined && ( | ||
<List.Item>{t`Create a dashboard to be embedded`}</List.Item> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { screen } from "__support__/ui"; | ||
|
||
import { setup } from "./setup"; | ||
|
||
describe("EmbedHomepage (OSS)", () => { | ||
it("should default to the static tab for OSS builds", () => { | ||
setup(); | ||
expect( | ||
screen.getByText("Use static embedding", { exact: false }), | ||
).toBeInTheDocument(); | ||
|
||
// making sure Tabs isn't just rendering both tabs, making the test always pass | ||
expect( | ||
screen.queryByText("Use interactive embedding", { exact: false }), | ||
).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("should link to the docs", () => { | ||
setup(); | ||
expect(screen.getByText("Learn more")).toHaveAttribute( | ||
"href", | ||
"https://www.metabase.com/docs/latest/embedding/static-embedding.html", | ||
); | ||
}); | ||
|
||
it("should prompt to enable embedding if it wasn't auto enabled", () => { | ||
setup({ settings: { "setup-embedding-autoenabled": false } }); | ||
|
||
expect( | ||
screen.getByText("Enable embedding in the settings"), | ||
).toBeInTheDocument(); | ||
|
||
expect( | ||
screen.queryByText("Embedding has been automatically enabled for you"), | ||
).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("should not prompt to enable embedding if it was auto enabled", () => { | ||
setup({ settings: { "setup-embedding-autoenabled": true } }); | ||
|
||
expect( | ||
screen.queryByText("Enable embedding in the settings"), | ||
).not.toBeInTheDocument(); | ||
|
||
expect( | ||
screen.getByText("Embedding has been automatically enabled for you"), | ||
).toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { screen } from "__support__/ui"; | ||
|
||
import type { SetupOpts } from "./setup"; | ||
import { setup } from "./setup"; | ||
|
||
const setupEnterprise = (opts?: SetupOpts) => { | ||
setup({ | ||
...opts, | ||
hasEnterprisePlugins: true, | ||
}); | ||
}; | ||
|
||
describe("EmbedHomepage (EE, no token)", () => { | ||
it("should default to the interactive tab for EE builds", () => { | ||
setupEnterprise(); | ||
expect( | ||
screen.getByText("Use interactive embedding", { exact: false }), | ||
).toBeInTheDocument(); | ||
|
||
// making sure Tabs isn't just rendering both tabs, making the test always pass | ||
expect( | ||
screen.queryByText("Use static embedding", { exact: false }), | ||
).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("should prompt to activate the license if it wasn't found at the end of the setup", () => { | ||
setupEnterprise(); | ||
|
||
expect( | ||
screen.getByText("Activate your commercial license"), | ||
).toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { screen } from "__support__/ui"; | ||
|
||
import type { SetupOpts } from "./setup"; | ||
import { setup } from "./setup"; | ||
|
||
const setupPremium = (opts?: SetupOpts) => { | ||
setup({ | ||
...opts, | ||
hasEnterprisePlugins: true, | ||
tokenFeatures: { | ||
embedding: true, | ||
}, | ||
}); | ||
}; | ||
|
||
describe("EmbedHomepage (EE, with features)", () => { | ||
it("should default to the interactive tab for EE builds", () => { | ||
setupPremium(); | ||
expect( | ||
screen.getByText("Use interactive embedding", { exact: false }), | ||
).toBeInTheDocument(); | ||
|
||
// making sure Tabs isn't just rendering both tabs, making the test always pass | ||
expect( | ||
screen.queryByText("Use static embedding", { exact: false }), | ||
).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("should prompt to activate the license if it wasn't found at the end of the setup", () => { | ||
setupPremium(); | ||
|
||
expect( | ||
screen.getByText("Activate your commercial license"), | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it("should not prompt to activate the license if a license was found at the end of the setup", () => { | ||
setupPremium({ | ||
settings: { "setup-license-active-at-setup": true }, | ||
}); | ||
|
||
expect( | ||
screen.queryByText("Activate your commercial license"), | ||
).not.toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { setupEnterprisePlugins } from "__support__/enterprise"; | ||
import { renderWithProviders } from "__support__/ui"; | ||
import type { Settings, TokenFeatures } from "metabase-types/api"; | ||
import { createMockTokenFeatures } from "metabase-types/api/mocks"; | ||
import { | ||
createMockSettingsState, | ||
createMockState, | ||
} from "metabase-types/store/mocks"; | ||
|
||
import { EmbedHomepage } from "../EmbedHomepage"; | ||
|
||
export interface SetupOpts { | ||
tokenFeatures?: Partial<TokenFeatures>; | ||
hasEnterprisePlugins?: boolean; | ||
settings?: Partial<Settings>; | ||
} | ||
|
||
export async function setup({ | ||
tokenFeatures = createMockTokenFeatures(), | ||
hasEnterprisePlugins = false, | ||
settings = {}, | ||
}: SetupOpts = {}) { | ||
jest.clearAllMocks(); | ||
|
||
const state = createMockState({ | ||
settings: createMockSettingsState({ | ||
"token-features": createMockTokenFeatures(tokenFeatures), | ||
...settings, | ||
}), | ||
}); | ||
|
||
if (hasEnterprisePlugins) { | ||
setupEnterprisePlugins(); | ||
} | ||
|
||
renderWithProviders(<EmbedHomepage />, { storeInitialState: state }); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small note: we want to show interactive even if there is no license active, the content of the card will prompt to activate the license. That's why I'm checking if it's a ee build and not if the plan is ee on line 44