Skip to content
Snippets Groups Projects
Unverified Commit 381bc822 authored by metabase-bot[bot]'s avatar metabase-bot[bot] Committed by GitHub
Browse files

Add utm_media, utm_source, and utm_users to upgrade urls (#28738) (#28832)

parent 28a9de1f
No related branches found
No related tags found
No related merge requests found
Showing
with 202 additions and 42 deletions
......@@ -2,7 +2,7 @@ import { restore, isOSS } from "e2e/support/helpers";
const embeddingPage = "/admin/settings/embedding-in-other-applications";
const licensePage = "/admin/settings/premium-embedding-license";
const upgradeUrl = "https://www.metabase.com/upgrade/";
const upgradeUrl = "https://www.metabase.com/upgrade";
// A random embedding token with valid format
const embeddingToken =
......@@ -135,5 +135,5 @@ function stubTokenResponses() {
function assertLinkMatchesUrl(text, url) {
cy.findByRole("link", { name: text })
.should("have.attr", "href")
.and("eq", url);
.and("contain", url);
}
......@@ -9,7 +9,7 @@ import {
const embeddingPage = "/admin/settings/embedding-in-other-applications";
const licenseUrl = "https://metabase.com/license/embedding";
const upgradeUrl = "https://www.metabase.com/upgrade/";
const upgradeUrl = "https://www.metabase.com/upgrade";
const learnEmbeddingUrl =
"https://www.metabase.com/learn/embedding/embedding-charts-and-dashboards.html";
......@@ -235,7 +235,7 @@ function enableSharing() {
function assertLinkMatchesUrl(text, url) {
cy.findByRole("link", { name: text })
.should("have.attr", "href")
.and("eq", url);
.and("contain", url);
}
function ensureEmbeddingIsDisabled() {
......
......@@ -8,7 +8,7 @@ import LoadingSpinner from "metabase/components/LoadingSpinner";
import MetabaseSettings from "metabase/lib/settings";
import { getSettings } from "metabase/selectors/settings";
import { getUpgradeUrl } from "metabase/selectors/settings";
import { showLicenseAcceptedToast } from "metabase-enterprise/license/actions";
......@@ -25,6 +25,8 @@ import {
} from "metabase/admin/settings/components/SettingsLicense";
import { LicenseInput } from "metabase/admin/settings/components/LicenseInput";
import { ExplorePlansIllustration } from "metabase/admin/settings/components/SettingsLicense/ExplorePlansIllustration";
import { SettingDefinition } from "metabase-types/api";
import { State } from "metabase-types/store";
const HOSTING_FEATURE_KEY = "hosting";
const STORE_MANAGED_FEATURE_KEY = "metabase-store-managed";
......@@ -58,20 +60,20 @@ const getDescription = (tokenStatus?: TokenStatus, hasToken?: boolean) => {
return t`Your license is active until ${validUntil}! Hope you’re enjoying it.`;
};
interface LicenseAndBillingSettingsProps {
settings: Record<string, any>;
settingValues: {
key: string;
value: any;
is_env_setting: boolean;
env_name: string;
}[];
interface StateProps {
settingValues: SettingDefinition[];
upgradeUrl: string;
}
interface DispatchProps {
showLicenseAcceptedToast: () => void;
}
type LicenseAndBillingSettingsProps = DispatchProps & StateProps;
const LicenseAndBillingSettings = ({
settingValues,
settings,
upgradeUrl,
showLicenseAcceptedToast,
}: LicenseAndBillingSettingsProps) => {
const {
......@@ -150,7 +152,7 @@ const LicenseAndBillingSettings = ({
invalid={isInvalid}
loading={isUpdating}
error={error}
token={token}
token={token ? String(token) : undefined}
onUpdate={updateToken}
/>
</>
......@@ -161,7 +163,7 @@ const LicenseAndBillingSettings = ({
<SectionHeader>{t`Looking for more?`}</SectionHeader>
<SectionDescription>
{jt`You can get priority support, more tools to help you share your insights with your teams and powerful options to help you create seamless, interactive data experiences for your customers with ${(
<ExternalLink key="plans" href={MetabaseSettings.upgradeUrl()}>
<ExternalLink key="plans" href={upgradeUrl}>
{t`our other paid plans.`}
</ExternalLink>
)}`}
......@@ -176,9 +178,9 @@ const LicenseAndBillingSettings = ({
};
export default connect(
(state: any) => ({
(state: State): StateProps => ({
settingValues: state.admin.settings.settings,
settings: getSettings(state),
upgradeUrl: getUpgradeUrl(state, { utm_media: "license" }),
}),
{
showLicenseAcceptedToast,
......
......@@ -21,6 +21,7 @@ export * from "./segment";
export * from "./settings";
export * from "./slack";
export * from "./snippets";
export * from "./store";
export * from "./table";
export * from "./timeline";
export * from "./user";
......
......@@ -16,4 +16,5 @@ export * from "./table";
export * from "./timeline";
export * from "./settings";
export * from "./snippets";
export * from "./store";
export * from "./user";
import { StoreTokenStatus } from "metabase-types/api";
export const createMockStoreTokenStatus = (
opts?: Partial<StoreTokenStatus>,
): StoreTokenStatus => ({
...opts,
valid: false,
trial: false,
});
......@@ -153,6 +153,7 @@ export interface SettingDefinition {
}
export interface Settings {
"active-users-count"?: number;
"admin-email": string;
"anon-tracking-enabled": boolean;
"application-font": string;
......@@ -221,4 +222,3 @@ export interface Settings {
}
export type SettingKey = keyof Settings;
0;
export interface StoreTokenStatus {
valid: boolean;
trial: boolean;
}
import React from "react";
import { connect } from "react-redux";
import { jt, t } from "ttag";
import PopoverWithTrigger from "metabase/components/PopoverWithTrigger";
import ExternalLink from "metabase/core/components/ExternalLink";
import MetabaseSettings from "metabase/lib/settings";
import { getUpgradeUrl } from "metabase/selectors/settings";
import { State } from "metabase-types/store";
import { ToolbarButton } from "../ToolbarButton";
import { UpsellContent } from "./ToolbarUpsell.styled";
export const ToolbarUpsell = () => {
interface StateProps {
upgradeUrl: string;
}
type ToolbarUpsellProps = StateProps;
const mapStateToProps = (state: State): StateProps => ({
upgradeUrl: getUpgradeUrl(state, { utm_media: "permissions_top" }),
});
const ToolbarUpsell = ({ upgradeUrl }: ToolbarUpsellProps) => {
return (
<PopoverWithTrigger
triggerElement={<ToolbarButton text={t`Get more control`} icon="bolt" />}
......@@ -16,7 +29,7 @@ export const ToolbarUpsell = () => {
>
<UpsellContent>
{jt`${(
<ExternalLink href={MetabaseSettings.upgradeUrl()}>
<ExternalLink href={upgradeUrl}>
{t`Upgrade to Pro or Enterprise`}
</ExternalLink>
)} and disable download results, control access to the data model, promote group managers, ${(
......@@ -28,3 +41,5 @@ export const ToolbarUpsell = () => {
</PopoverWithTrigger>
);
};
export default connect(mapStateToProps)(ToolbarUpsell);
import React from "react";
import userEvent from "@testing-library/user-event";
import { renderWithProviders, screen } from "__support__/ui";
import ToolbarUpsell from "./ToolbarUpsell";
const setup = () => {
renderWithProviders(<ToolbarUpsell />);
};
describe("ToolbarUpsell", () => {
it("should add utm_media to the upgrade link", () => {
setup();
userEvent.click(screen.getByText("Get more control"));
expect(
screen.getByRole("link", { name: "Upgrade to Pro or Enterprise" }),
).toHaveAttribute("href", expect.stringContaining("permissions_top"));
});
});
export * from "./ToolbarUpsell";
export { default } from "./ToolbarUpsell";
......@@ -15,7 +15,7 @@ import {
} from "../../permissions";
import PermissionsPageLayout from "../../components/PermissionsPageLayout/PermissionsPageLayout";
import { DataPermissionsHelp } from "../../components/DataPermissionsHelp";
import { ToolbarUpsell } from "../../components/ToolbarUpsell";
import ToolbarUpsell from "../../components/ToolbarUpsell";
export const DATA_PERMISSIONS_TOOLBAR_CONTENT = [
<ToolbarUpsell key="upsell" />,
......
import React from "react";
import { connect } from "react-redux";
import { t } from "ttag";
import Button from "metabase/core/components/Button";
import ExternalLink from "metabase/core/components/ExternalLink";
import MetabaseSettings from "metabase/lib/settings";
import { getUpgradeUrl } from "metabase/selectors/settings";
import { State } from "metabase-types/store";
import { ExplorePlansIllustration } from "./ExplorePlansIllustration";
import {
ExplorePaidPlansContainer,
SectionDescription,
......@@ -10,29 +13,33 @@ import {
SettingsLicenseContainer,
SubHeader,
} from "./SettingsLicense.styled";
import { ExplorePlansIllustration } from "./ExplorePlansIllustration";
const description = t`Metabase is open source and will be free forever – but by upgrading you can have priority support, more tools to help you share your insights with your teams and powerful options to help you create seamless, interactive data experiences for your customers.`;
interface StateProps {
upgradeUrl: string;
}
type SettingsLicenseProps = StateProps;
const mapStateToProps = (state: State): StateProps => ({
upgradeUrl: getUpgradeUrl(state, { utm_media: "license" }),
});
const SettingsLicense = () => {
const SettingsLicense = ({ upgradeUrl }: SettingsLicenseProps) => {
return (
<SettingsLicenseContainer>
<SectionHeader>{t`Looking for more?`}</SectionHeader>
<SectionDescription>{description}</SectionDescription>
<SectionDescription>
{t`Metabase is open source and will be free forever – but by upgrading you can have priority support, more tools to help you share your insights with your teams and powerful options to help you create seamless, interactive data experiences for your customers.`}
</SectionDescription>
<SubHeader>{t`Want to know more?`}</SubHeader>
<ExplorePaidPlansContainer>
<ExternalLink
className="Button Button--primary"
href={MetabaseSettings.upgradeUrl()}
>{t`Explore our paid plans`}</ExternalLink>
<Button as={ExternalLink} primary href={upgradeUrl}>
{t`Explore our paid plans`}
</Button>
<ExplorePlansIllustration />
</ExplorePaidPlansContainer>
</SettingsLicenseContainer>
);
};
export default SettingsLicense;
export default connect(mapStateToProps)(SettingsLicense);
import React from "react";
import { renderWithProviders, screen } from "__support__/ui";
import SettingsLicense from "./SettingsLicense";
const setup = () => {
renderWithProviders(<SettingsLicense />);
};
describe("SettingsLicense", () => {
it("should add utm_media to the upgrade link", () => {
setup();
expect(
screen.getByRole("link", { name: "Explore our paid plans" }),
).toHaveAttribute("href", expect.stringContaining("license"));
});
});
import React from "react";
import { connect } from "react-redux";
import { t, jt } from "ttag";
import MetabaseSettings from "metabase/lib/settings";
import ExternalLink from "metabase/core/components/ExternalLink";
import SettingHeader from "../SettingHeader";
import { getUpgradeUrl } from "metabase/selectors/settings";
import { State } from "metabase-types/store";
import SettingHeader from "../../SettingHeader";
export const EmbeddingCustomizationInfo = () => {
interface StateProps {
upgradeUrl: string;
}
type EmbeddingCustomizationInfoProps = StateProps;
const mapStateToProps = (state: State): StateProps => ({
upgradeUrl: getUpgradeUrl(state, { utm_media: "embed_standalone" }),
});
const EmbeddingCustomizationInfo = ({
upgradeUrl,
}: EmbeddingCustomizationInfoProps) => {
const setting = {
description: jt`In order to remove the Metabase logo from embeds, you can always upgrade to ${(
<ExternalLink key="upgrade-link" href={MetabaseSettings.upgradeUrl()}>
<ExternalLink key="upgrade-link" href={upgradeUrl}>
{t`one of our paid plans.`}
</ExternalLink>
)}`,
......@@ -15,3 +29,5 @@ export const EmbeddingCustomizationInfo = () => {
return <SettingHeader id="embedding-customization-info" setting={setting} />;
};
export default connect(mapStateToProps)(EmbeddingCustomizationInfo);
import React from "react";
import { renderWithProviders, screen } from "__support__/ui";
import EmbeddingCustomizationInfo from "./EmbeddingCustomizationInfo";
const setup = () => {
renderWithProviders(<EmbeddingCustomizationInfo />);
};
describe("EmbeddingCustomizationInfo", () => {
it("should add utm_media to the upgrade link", () => {
setup();
expect(
screen.getByRole("link", { name: "one of our paid plans." }),
).toHaveAttribute("href", expect.stringContaining("embed_standalone"));
});
});
export { default } from "./EmbeddingCustomizationInfo";
import React from "react";
import { connect } from "react-redux";
import { jt, t } from "ttag";
import MetabaseSettings from "metabase/lib/settings";
import ExternalLink from "metabase/core/components/ExternalLink";
import { getUpgradeUrl } from "metabase/selectors/settings";
import { State } from "metabase-types/store";
import SettingHeader from "../../SettingHeader";
export const PremiumEmbeddingLinkWidget = () => {
interface StateProps {
upgradeUrl: string;
}
type FullAppEmbeddingLinkWidgetProps = StateProps;
const mapStateToProps = (state: State): StateProps => ({
upgradeUrl: getUpgradeUrl(state, { utm_media: "embed_fullapp" }),
});
const FullAppEmbeddingLinkWidget = ({
upgradeUrl,
}: FullAppEmbeddingLinkWidgetProps) => {
const setting = {
display_name: t`embedding the entire metabase app`,
description: jt`With ${(
<ExternalLink key="upgrade-link" href={MetabaseSettings.upgradeUrl()}>
<ExternalLink key="upgrade-link" href={upgradeUrl}>
{t`some of our paid plans,`}
</ExternalLink>
)} you can embed the full Metabase app and enable your users to drill-through to charts, browse collections, and use the graphical query builder. You can also get priority support, more tools to help you share your insights with your teams and powerful options to help you create seamless, interactive data experiences for your customers.`,
......@@ -17,3 +30,5 @@ export const PremiumEmbeddingLinkWidget = () => {
return <SettingHeader id="embedding-customization-info" setting={setting} />;
};
export default connect(mapStateToProps)(FullAppEmbeddingLinkWidget);
import React from "react";
import { renderWithProviders, screen } from "__support__/ui";
import FullAppEmbeddingLinkWidget from "./FullAppEmbeddingLinkWidget";
const setup = () => {
renderWithProviders(<FullAppEmbeddingLinkWidget />);
};
describe("FullAppEmbeddingLinkWidget", () => {
it("should add utm_media to the upgrade link", () => {
setup();
expect(
screen.getByRole("link", { name: "some of our paid plans," }),
).toHaveAttribute("href", expect.stringContaining("embed_fullapp"));
});
});
export { default } from "./FullAppEmbeddingLinkWidget";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment