Skip to content
Snippets Groups Projects
Unverified Commit d843973a authored by Phoomparin Mano's avatar Phoomparin Mano Committed by GitHub
Browse files

feat(sdk): option to hide dashboard card title (#43859)


* expose card title settings

* Add dashboard test skeleton

* add a sample dashcard to the test

* dashboard grid should have card title by default

* add unit test for card title

* remove unused delay in unit test

* fix width and height being smaller than min values

* flip grid layout condition

---------

Co-authored-by: default avatarOisin Coveney <oisin@metabase.com>
parent c7e46dc9
Branches
Tags
No related merge requests found
Showing
with 144 additions and 6 deletions
......@@ -16,10 +16,11 @@ import { PublicOrEmbeddedDashboard } from "metabase/public/containers/PublicOrEm
import { Box } from "metabase/ui";
import type { DashboardId } from "metabase-types/api";
type StaticDashboardProps = {
export type StaticDashboardProps = {
dashboardId: DashboardId;
initialParameterValues?: Query;
withTitle?: boolean;
withCardTitle?: boolean;
withDownloads?: boolean;
hiddenParameters?: string[];
};
......@@ -28,6 +29,7 @@ const _StaticDashboard = ({
dashboardId,
initialParameterValues: parameterQueryParams = {},
withTitle: titled = true,
withCardTitle = true,
withDownloads = true,
hiddenParameters = [],
}: StaticDashboardProps) => {
......@@ -72,6 +74,7 @@ const _StaticDashboard = ({
isNightMode={isNightMode}
onNightModeChange={onNightModeChange}
titled={options.titled}
cardTitled={withCardTitle}
theme={theme}
isFullscreen={isFullscreen}
onFullscreenChange={onFullscreenChange}
......
import { Box } from "@mantine/core";
import { indexBy } from "underscore";
import {
setupDashboardEndpoints,
setupDashboardQueryMetadataEndpoint,
} from "__support__/server-mocks";
import { screen, renderWithProviders } from "__support__/ui";
import { createMockConfig } from "embedding-sdk/test/mocks/config";
import { setupSdkState } from "embedding-sdk/test/server-mocks/sdk-init";
import {
createMockCard,
createMockDashboard,
createMockDashboardCard,
createMockDashboardQueryMetadata,
createMockStructuredDatasetQuery,
createMockUser,
} from "metabase-types/api/mocks";
import {
createSampleDatabase,
ORDERS_ID,
} from "metabase-types/api/mocks/presets";
import { createMockDashboardState } from "metabase-types/store/mocks";
import { StaticDashboard, type StaticDashboardProps } from "./StaticDashboard";
const TEST_DASHBOARD_ID = 1;
interface SetupOptions {
props?: Partial<StaticDashboardProps>;
}
const setup = (options: SetupOptions = {}) => {
const { props } = options;
const database = createSampleDatabase();
const dataset_query = createMockStructuredDatasetQuery({
query: { "source-table": ORDERS_ID },
});
const tableCard = createMockCard({
id: 1,
dataset_query,
name: "Here is a card title",
});
const tableDashcard = createMockDashboardCard({
id: 1,
card_id: tableCard.id,
card: tableCard,
});
const dashcards = [tableDashcard];
const dashboard = createMockDashboard({
id: TEST_DASHBOARD_ID,
dashcards,
});
setupDashboardEndpoints(dashboard);
setupDashboardQueryMetadataEndpoint(
dashboard,
createMockDashboardQueryMetadata({
databases: [database],
}),
);
const user = createMockUser();
const state = setupSdkState({
currentUser: user,
dashboard: createMockDashboardState({
dashboardId: dashboard.id,
dashboards: {
[dashboard.id]: {
...dashboard,
dashcards: dashcards.map(dc => dc.id),
},
},
dashcards: indexBy(dashcards, "id"),
}),
});
renderWithProviders(
<Box h="500px">
<StaticDashboard dashboardId={TEST_DASHBOARD_ID} {...props} />
</Box>,
{
mode: "sdk",
sdkConfig: createMockConfig({
jwtProviderUri: "http://TEST_URI/sso/metabase",
}),
storeInitialState: state,
},
);
};
describe("StaticDashboard", () => {
it("shows a dashboard card question title by default", async () => {
setup();
expect(await screen.findByTestId("dashboard-grid")).toBeInTheDocument();
expect(await screen.findByText("Here is a card title")).toBeInTheDocument();
});
it("hides the dashboard card question title when withCardTitle is false", async () => {
setup({ props: { withCardTitle: false } });
expect(await screen.findByTestId("dashboard-grid")).toBeInTheDocument();
expect(screen.queryByText("Here is a card title")).not.toBeInTheDocument();
});
});
......@@ -33,7 +33,7 @@ export const setupSdkState = ({
}),
...stateOpts
}: {
currentUser: User;
currentUser?: User;
settingValues?: EnterpriseSettings;
tokenFeatures?: TokenFeatures;
settingDefinitions?: SettingDefinition[];
......
......@@ -64,6 +64,7 @@ export interface DashCardProps {
/** If public sharing or static/public embed */
isPublicOrEmbedded?: boolean;
isXray?: boolean;
withTitle?: boolean;
onAddSeries: (dashcard: StoreDashcard) => void;
onReplaceCard: (dashcard: StoreDashcard) => void;
......@@ -99,6 +100,7 @@ function DashCardInner({
isXray = false,
isEditingParameter,
clickBehaviorSidebarDashcard,
withTitle = true,
onAddSeries,
onReplaceCard,
onRemove,
......@@ -335,6 +337,7 @@ function DashCardInner({
isNightMode={isNightMode}
isMobile={isMobile}
isPublicOrEmbedded={isPublicOrEmbedded}
withTitle={withTitle}
showClickBehaviorSidebar={showClickBehaviorSidebar}
onUpdateVisualizationSettings={onUpdateVisualizationSettings}
onChangeCardAndRun={
......
......@@ -71,6 +71,7 @@ interface DashCardVisualizationProps {
/** If public sharing or static/public embed */
isPublicOrEmbedded?: boolean;
isXray?: boolean;
withTitle?: boolean;
error?: { message?: string; icon?: IconName };
headerIcon?: IconProps;
......@@ -113,6 +114,7 @@ export function DashCardVisualization({
isFullscreen = false,
isMobile = false,
isEditingParameter,
withTitle = true,
onChangeCardAndRun,
showClickBehaviorSidebar,
onChangeLocation,
......@@ -250,7 +252,7 @@ export function DashCardVisualization({
expectedDuration={expectedDuration}
error={error?.message}
errorIcon={error?.icon}
showTitle
showTitle={withTitle}
isAction={isAction}
isDashboard
isSlow={isSlow}
......
......@@ -133,6 +133,7 @@ type OwnProps = {
isXray?: boolean;
isFullscreen: boolean;
isNightMode: boolean;
withCardTitle?: boolean;
clickBehaviorSidebarDashcard: DashboardCard | null;
mode?: Mode;
// public dashboard passes it explicitly
......@@ -174,6 +175,7 @@ class DashboardGrid extends Component<DashboardGridProps, DashboardGridState> {
width: 0,
isEditing: false,
isEditingParameter: false,
withCardTitle: true,
};
componentDidMount() {
......@@ -301,12 +303,24 @@ class DashboardGrid extends Component<DashboardGridProps, DashboardGridState> {
minW = minSize.width;
minH = minSize.height;
}
const w = dashcard.size_x || initialSize.width;
const h = dashcard.size_y || initialSize.height;
if (w < minW) {
minW = w;
}
if (h < minH) {
minH = h;
}
return {
i: String(dashcard.id),
x: dashcard.col || 0,
y: dashcard.row || 0,
w: dashcard.size_x || initialSize.width,
h: dashcard.size_y || initialSize.height,
w,
h,
dashcard: dashcard,
minW,
minH,
......@@ -498,6 +512,7 @@ class DashboardGrid extends Component<DashboardGridProps, DashboardGridState> {
isMobile={isMobile}
isPublicOrEmbedded={this.props.isPublicOrEmbedded}
isXray={this.props.isXray}
withTitle={this.props.withCardTitle}
onRemove={this.onDashCardRemove}
onAddSeries={this.onDashCardAddSeries}
onReplaceCard={this.onReplaceCard}
......@@ -598,6 +613,7 @@ class DashboardGrid extends Component<DashboardGridProps, DashboardGridState> {
render() {
const { dashboard, width } = this.props;
return (
<DashboardGridContainer
data-testid="dashboard-grid"
......
......@@ -9,6 +9,7 @@ import type { EmbedDisplayControls, EmbedDisplayParams } from "../types";
export const DEFAULT_EMBED_DISPLAY_OPTIONS: EmbedDisplayParams = {
bordered: false,
titled: true,
cardTitled: true,
hideDownloadButton: null,
hideParameters: null,
font: null,
......
......@@ -41,6 +41,7 @@ export type EmbedBorderControls = {
export type EmbedDisplayParams = {
bordered: EmbedBordered;
titled: EmbedTitle;
cardTitled: EmbedTitle;
hideDownloadButton: EmbedHideDownloadButton;
hideParameters: EmbedHideParameters;
font: EmbedFont;
......
......@@ -273,8 +273,8 @@ class PublicOrEmbeddedDashboardInner extends Component<PublicOrEmbeddedDashboard
isXray={false}
isFullscreen={isFullscreen}
isNightMode={isNightMode}
withCardTitle={this.props.cardTitled}
clickBehaviorSidebarDashcard={null}
width={0}
/>
</DashboardContainer>
) : null
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment