Skip to content
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

Keeps preview across different tabs #38271

Merged
merged 16 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ export const DashboardControls = ComposedComponent =>
};
setValue("refresh", this.state.refreshPeriod);
setValue("fullscreen", this.state.isFullscreen);
setValue("theme", this.state.theme);
const normalizedTheme = options.theme ?? null;
if (normalizedTheme !== this.state.theme) {
this.setTheme(normalizedTheme);
}

delete options.night; // DEPRECATED: options.night

Expand Down Expand Up @@ -224,7 +227,6 @@ export const DashboardControls = ComposedComponent =>
hasNightModeToggle={this.state.theme !== "transparent"}
setRefreshElapsedHook={this.setRefreshElapsedHook}
loadDashboardParams={this.loadDashboardParams}
updateDashboardParams={this.updateDashboardParams}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was unused. You can verify by using a text search of updateDashboardParams, and no file except this file uses this function.

onNightModeChange={this.setNightMode}
onFullscreenChange={this.setFullscreen}
onRefreshPeriodChange={this.setRefreshPeriod}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ReactNode } from "react";
import { useState } from "react";
import { useEffect, useState } from "react";

import { withRouter } from "react-router";
import { connect } from "react-redux";
import cx from "classnames";
Expand All @@ -24,6 +25,8 @@ import type {
} from "metabase-types/api";
import type { State } from "metabase-types/store";

import { useDispatch } from "metabase/lib/redux";
import { setOptions } from "metabase/redux/embed";
import type Question from "metabase-lib/Question";
import { getValuePopulatedParameters } from "metabase-lib/parameters/utils/parameter-values";

Expand Down Expand Up @@ -102,6 +105,11 @@ function EmbedFrame({
initializeIframeResizer(() => setInnerScroll(false));
});

const dispatch = useDispatch();
useEffect(() => {
dispatch(setOptions(location));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed for the font change to work, since font is being get from the selector which reads store.embed.options.

This essentially works the same way when we first load the embedding

store.dispatch(setOptions(window.location));

}, [dispatch, location]);

const {
bordered = isWithinIframe(),
titled = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { jt, t } from "ttag";
import type { ChangeEvent, ReactNode } from "react";
import type { ChangeEvent } from "react";
import { Divider, SegmentedControl, Stack, Switch, Text } from "metabase/ui";
import { useSelector } from "metabase/lib/redux";
import {
Expand All @@ -18,13 +18,7 @@ import type {
} from "metabase/public/lib/types";
import { getPlan } from "metabase/common/utils/plan";

import { PreviewModeSelector } from "./PreviewModeSelector";
import type { ActivePreviewPane } from "./types";
import PreviewPane from "./PreviewPane";
import {
DisplayOptionSection,
SettingsTabLayout,
} from "./StaticEmbedSetupPane.styled";
import { DisplayOptionSection } from "./StaticEmbedSetupPane.styled";
import { StaticEmbedSetupPaneSettingsContentSection } from "./StaticEmbedSetupPaneSettingsContentSection";

const THEME_OPTIONS = [
Expand All @@ -35,25 +29,15 @@ const THEME_OPTIONS = [
const DEFAULT_THEME = THEME_OPTIONS[0].value;

export interface AppearanceSettingsProps {
activePane: ActivePreviewPane;

resourceType: EmbedResourceType;
iframeUrl: string;
displayOptions: EmbeddingDisplayOptions;
serverEmbedCodeSlot: ReactNode;

onChangePane: (pane: ActivePreviewPane) => void;
onChangeDisplayOptions: (displayOptions: EmbeddingDisplayOptions) => void;
}

export const AppearanceSettings = ({
activePane,
resourceType,
iframeUrl,
displayOptions,
serverEmbedCodeSlot,

onChangePane,
onChangeDisplayOptions,
}: AppearanceSettingsProps): JSX.Element => {
const docsUrl = useSelector(state =>
Expand All @@ -77,159 +61,137 @@ export const AppearanceSettings = ({
const fontControlLabelId = useUniqueId("display-option");

return (
<SettingsTabLayout
settingsSlot={
<>
<StaticEmbedSetupPaneSettingsContentSection
title={t`Customizing your embed’s appearance`}
>
<Text>{jt`These cosmetic options requiring changing the server code. You can play around with and preview the options here, and check out the ${(
<ExternalLink
key="doc"
href={`${docsUrl}${utmTags}#customizing-the-appearance-of-static-embeds`}
>{t`documentation`}</ExternalLink>
)} for more.`}</Text>
</StaticEmbedSetupPaneSettingsContentSection>
<StaticEmbedSetupPaneSettingsContentSection
title={t`Playing with appearance options`}
mt="2rem"
>
<Stack spacing="1rem">
<DisplayOptionSection title={t`Background`}>
<SegmentedControl
value={displayOptions.theme || DEFAULT_THEME}
data={THEME_OPTIONS}
fullWidth
bg={color("bg-light")}
onChange={value => {
const newValue = value === DEFAULT_THEME ? null : value;
<>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I did was:

  1. Leave stuff inside settingsSlot in the return of the component
  2. Move elements inside previewSlot outside.

<StaticEmbedSetupPaneSettingsContentSection
title={t`Customizing your embed’s appearance`}
>
<Text>{jt`These cosmetic options requiring changing the server code. You can play around with and preview the options here, and check out the ${(
<ExternalLink
key="doc"
href={`${docsUrl}${utmTags}#customizing-the-appearance-of-static-embeds`}
>{t`documentation`}</ExternalLink>
)} for more.`}</Text>
</StaticEmbedSetupPaneSettingsContentSection>
<StaticEmbedSetupPaneSettingsContentSection
title={t`Playing with appearance options`}
mt="2rem"
>
<Stack spacing="1rem">
<DisplayOptionSection title={t`Background`}>
<SegmentedControl
value={displayOptions.theme || DEFAULT_THEME}
data={THEME_OPTIONS}
fullWidth
bg={color("bg-light")}
onChange={value => {
const newValue = value === DEFAULT_THEME ? null : value;

onChangeDisplayOptions({
...displayOptions,
theme: newValue,
});
}}
/>
</DisplayOptionSection>
onChangeDisplayOptions({
...displayOptions,
theme: newValue,
});
}}
/>
</DisplayOptionSection>

<Switch
label={t`Dashboard title`}
labelPosition="left"
size="sm"
variant="stretch"
checked={displayOptions.titled}
onChange={e =>
<Switch
label={t`Dashboard title`}
labelPosition="left"
size="sm"
variant="stretch"
checked={displayOptions.titled}
onChange={e =>
onChangeDisplayOptions({
...displayOptions,
titled: e.target.checked,
})
}
/>

<Switch
label={t`Border`}
labelPosition="left"
size="sm"
variant="stretch"
checked={displayOptions.bordered}
onChange={e =>
onChangeDisplayOptions({
...displayOptions,
bordered: e.target.checked,
})
}
/>

<DisplayOptionSection title={t`Font`} titleId={fontControlLabelId}>
{canWhitelabel ? (
<Select
value={displayOptions.font}
options={[
{
name: t`Use instance font`,
value: null,
},
...availableFonts?.map(font => ({
name: font,
value: font,
})),
]}
buttonProps={{
"aria-labelledby": fontControlLabelId,
}}
onChange={(e: ChangeEvent<HTMLSelectElement>) => {
onChangeDisplayOptions({
...displayOptions,
titled: e.target.checked,
})
}
font: e.target.value,
});
}}
/>
) : (
<Text>{jt`You can change the font with ${(
<ExternalLink
key="fontPlan"
href={upgradePageUrl}
>{t`a paid plan`}</ExternalLink>
)}.`}</Text>
)}
</DisplayOptionSection>

{canWhitelabel && resourceType === "question" && (
// We only show the "Download Data" toggle if the users are pro/enterprise
// and they're sharing a question metabase#23477
<DisplayOptionSection title={t`Download data`}>
<Switch
label={t`Border`}
label={t`Enable users to download data from this embed`}
labelPosition="left"
size="sm"
variant="stretch"
checked={displayOptions.bordered}
checked={!displayOptions.hide_download_button}
onChange={e =>
onChangeDisplayOptions({
...displayOptions,
bordered: e.target.checked,
hide_download_button: !e.target.checked ? true : null,
})
}
/>

<DisplayOptionSection
title={t`Font`}
titleId={fontControlLabelId}
>
{canWhitelabel ? (
<Select
value={displayOptions.font}
options={[
{
name: t`Use instance font`,
value: null,
},
...availableFonts?.map(font => ({
name: font,
value: font,
})),
]}
buttonProps={{
"aria-labelledby": fontControlLabelId,
}}
onChange={(e: ChangeEvent<HTMLSelectElement>) => {
onChangeDisplayOptions({
...displayOptions,
font: e.target.value,
});
}}
/>
) : (
<Text>{jt`You can change the font with ${(
<ExternalLink
key="fontPlan"
href={upgradePageUrl}
>{t`a paid plan`}</ExternalLink>
)}.`}</Text>
)}
</DisplayOptionSection>

{canWhitelabel && resourceType === "question" && (
// We only show the "Download Data" toggle if the users are pro/enterprise
// and they're sharing a question metabase#23477
<DisplayOptionSection title={t`Download data`}>
<Switch
label={t`Enable users to download data from this embed`}
labelPosition="left"
size="sm"
variant="stretch"
checked={!displayOptions.hide_download_button}
onChange={e =>
onChangeDisplayOptions({
...displayOptions,
hide_download_button: !e.target.checked ? true : null,
})
}
/>
</DisplayOptionSection>
)}
</Stack>
</StaticEmbedSetupPaneSettingsContentSection>
{!canWhitelabel && (
<>
<Divider my="2rem" />
<StaticEmbedSetupPaneSettingsContentSection
title={t`Removing the “Powered by Metabase” banner`}
>
<Text>{jt`This banner appears on all static embeds created with the Metabase open source version. You’ll need to upgrade to ${(
<ExternalLink
key="bannerPlan"
href={upgradePageUrl}
>{t`a paid plan`}</ExternalLink>
)} to remove the banner.`}</Text>
</StaticEmbedSetupPaneSettingsContentSection>
</>
</DisplayOptionSection>
)}
</>
}
previewSlot={
</Stack>
</StaticEmbedSetupPaneSettingsContentSection>
{!canWhitelabel && (
<>
<PreviewModeSelector value={activePane} onChange={onChangePane} />

{activePane === "preview" ? (
<PreviewPane
className="flex-full"
previewUrl={iframeUrl}
isTransparent={displayOptions.theme === "transparent"}
/>
) : activePane === "code" ? (
serverEmbedCodeSlot
) : null}
<Divider my="2rem" />
<StaticEmbedSetupPaneSettingsContentSection
title={t`Removing the “Powered by Metabase” banner`}
>
<Text>{jt`This banner appears on all static embeds created with the Metabase open source version. You’ll need to upgrade to ${(
<ExternalLink
key="bannerPlan"
href={upgradePageUrl}
>{t`a paid plan`}</ExternalLink>
)} to remove the banner.`}</Text>
</StaticEmbedSetupPaneSettingsContentSection>
</>
}
/>
)}
</>
);
};