Skip to content
Snippets Groups Projects
Unverified Commit 4be2b9ba authored by Ryan Laurie's avatar Ryan Laurie Committed by GitHub
Browse files

Allow small number and markdown cards (#29537)

* set different min and default dashcard sizes

* add defaultsize type

* adjust text card default size

* allow smaller scalar values

* don't show titles in question viz
parent e1b2b68b
No related branches found
No related tags found
No related merge requests found
Showing
with 60 additions and 59 deletions
......@@ -18,6 +18,7 @@ export default Object.assign(Action, {
canSavePng: false,
minSize: { width: 1, height: 1 },
defaultSize: { width: 3, height: 1 },
checkRenderable: () => true,
isSensible: () => false,
......
import _ from "underscore";
import { t } from "ttag";
import { createAction } from "metabase/lib/redux";
import { measureText } from "metabase/lib/measure-text";
import Questions from "metabase/entities/questions";
......@@ -35,8 +34,10 @@ export const addCardToDashboard =
const existingCards = dashboard.ordered_cards
.map(id => dashcards[id])
.filter(dc => !dc.isRemoved);
const { visualization } = getVisualizationRaw([{ card }]);
const createdCardSize = visualization.minSize || DEFAULT_CARD_SIZE;
const createdCardSize = visualization.defaultSize || DEFAULT_CARD_SIZE;
const dashcard = {
id: generateTemporaryDashcardId(),
dashboard_id: dashId,
......@@ -64,13 +65,21 @@ export const addDashCardToDashboard = function ({ dashId, dashcardOverrides }) {
const existingCards = dashboard.ordered_cards
.map(id => dashcards[id])
.filter(dc => !dc.isRemoved);
const { visualization } = getVisualizationRaw([dashcardOverrides]);
const createdCardSize = visualization.defaultSize || DEFAULT_CARD_SIZE;
const dashcard = {
id: generateTemporaryDashcardId(),
card_id: null,
card: null,
dashboard_id: dashId,
series: [],
...getPositionForNewDashCard(existingCards),
...getPositionForNewDashCard(
existingCards,
createdCardSize.width,
createdCardSize.height,
),
parameter_mappings: [],
visualization_settings: {},
};
......@@ -97,9 +106,6 @@ export const addTextDashCardToDashboard = function ({ dashId }) {
};
export const addLinkDashCardToDashboard = function ({ dashId }) {
const DEFAULT_HEIGHT = 1;
const DEFAULT_WIDTH = 3;
const virtualLinkCard = {
...createCard(),
display: "link",
......@@ -108,8 +114,6 @@ export const addLinkDashCardToDashboard = function ({ dashId }) {
const dashcardOverrides = {
card: virtualLinkCard,
size_x: DEFAULT_WIDTH,
size_y: DEFAULT_HEIGHT,
visualization_settings: {
virtual_card: virtualLinkCard,
},
......@@ -120,37 +124,6 @@ export const addLinkDashCardToDashboard = function ({ dashId }) {
});
};
const estimateCardSize = (displayType, action, buttonLabel) => {
const BASE_HEIGHT = 3;
const HEIGHT_PER_FIELD = 1.5;
const PIXELS_PER_BLOCK = 49;
const MAX_BUTTON_BLOCK_WIDTH = 18;
if (displayType === "button") {
const textWidth = measureText(buttonLabel, {
family: "Lato",
size: 14,
weight: 700,
});
return {
size_x: Math.min(
Math.ceil((textWidth + PIXELS_PER_BLOCK) / PIXELS_PER_BLOCK),
MAX_BUTTON_BLOCK_WIDTH,
),
size_y: 1,
};
}
return {
size_x: 6,
size_y: Math.round(
BASE_HEIGHT + action.parameters.length * HEIGHT_PER_FIELD,
),
};
};
export const addActionToDashboard =
async ({ dashId, action, displayType }) =>
dispatch => {
......@@ -168,7 +141,6 @@ export const addActionToDashboard =
action_id: action.id,
card_id: action.model_id,
card: virtualActionsCard,
...estimateCardSize(displayType, action, buttonLabel),
visualization_settings: {
actionDisplayType: displayType ?? "button",
virtual_card: virtualActionsCard,
......
......@@ -96,6 +96,7 @@ export default class ChoroplethMap extends Component {
static propTypes = {};
static minSize = { width: 4, height: 4 };
static defaultSize = { width: 4, height: 4 };
static isSensible({ cols }) {
return cols.filter(isString).length > 0 && cols.filter(isMetric).length > 0;
......
......@@ -82,6 +82,7 @@ export default class LineAreaBarChart extends Component {
static supportsSeries = true;
static minSize = { width: 4, height: 3 };
static defaultSize = { width: 4, height: 3 };
static isSensible({ cols, rows }) {
return (
......
......@@ -40,7 +40,7 @@ const ScalarValue = ({
fontWeight: 900,
unit: "rem",
step: 0.2,
min: 2.2,
min: 1,
max: gridSize ? getMaxFontSize(gridSize.width, totalNumGridCols) : 4,
}),
[fontFamily, gridSize, totalNumGridCols, value, width],
......
......@@ -6,7 +6,7 @@ const TITLE_MAX_LINES = 2;
const TITLE_LINE_HEIGHT_REM = 1.4;
export const ScalarRoot = styled.div`
padding-top: ${((TITLE_MAX_LINES - 1) * TITLE_LINE_HEIGHT_REM) / 2}rem;
// padding-top: ${((TITLE_MAX_LINES - 1) * TITLE_LINE_HEIGHT_REM) / 2}rem;
position: relative;
display: flex;
flex: 1;
......
......@@ -11,6 +11,10 @@ export type Visualization = {
width: number;
height: number;
};
defaultSize: {
width: number;
height: number;
};
isSensible: (data: DatasetData) => boolean;
isLiveResizable: (series: Series) => boolean;
......
......@@ -38,10 +38,8 @@ export default class Funnel extends Component {
static noHeader = true;
static minSize = {
width: 5,
height: 4,
};
static minSize = { width: 5, height: 4 };
static defaultSize = { width: 5, height: 4 };
static isSensible({ cols, rows }) {
return cols.length === 2;
......
......@@ -11,6 +11,7 @@ export const settings = {
hidden: true,
supportPreviewing: false,
minSize: { width: 1, height: 1 },
defaultSize: { width: 3, height: 1 },
checkRenderable: () => undefined,
settings: {
"card.title": {
......
......@@ -56,6 +56,7 @@ export default class PieChart extends Component {
static iconName = "pie";
static minSize = { width: 4, height: 4 };
static defaultSize = { width: 4, height: 4 };
static isSensible({ cols, rows }) {
return cols.length === 2;
......
......@@ -328,6 +328,7 @@ RowChartVisualization.noun = t`row chart`;
RowChartVisualization.noHeader = true;
RowChartVisualization.minSize = { width: 5, height: 4 };
RowChartVisualization.defaultSize = { width: 5, height: 4 };
RowChartVisualization.settings = {
...ROW_CHART_SETTINGS,
......
......@@ -13,7 +13,7 @@ import ScalarValue, {
ScalarTitle,
} from "metabase/visualizations/components/ScalarValue";
import { TYPE } from "metabase-lib/types/constants";
import { ScalarContainer } from "./Scalar.styled";
import { ScalarContainer, LabelIcon } from "./Scalar.styled";
// convert legacy `scalar.*` visualization settings to format options
function legacyScalarSettingsToFormatOptions(settings) {
......@@ -41,7 +41,8 @@ export default class Scalar extends Component {
static noHeader = true;
static supportsSeries = true;
static minSize = { width: 3, height: 3 };
static minSize = { width: 1, height: 1 };
static defaultSize = { width: 3, height: 3 };
static isSensible({ cols, rows }) {
return rows.length === 1 && cols.length === 1;
......@@ -214,6 +215,11 @@ export default class Scalar extends Component {
};
const isClickable = visualizationIsClickable(clicked);
const showSmallTitle =
!!settings["card.title"] &&
isDashboard &&
(gridSize?.width < 2 || gridSize?.height < 2);
return (
<ScalarWrapper>
<div className="Card-title absolute top right p1 px2">
......@@ -243,16 +249,24 @@ export default class Scalar extends Component {
/>
</span>
</ScalarContainer>
{isDashboard && (
<ScalarTitle
title={settings["card.title"]}
description={settings["card.description"]}
onClick={
onChangeCardAndRun &&
(() => onChangeCardAndRun({ nextCard: card }))
}
/>
)}
{isDashboard &&
(showSmallTitle ? (
<LabelIcon
name="ellipsis"
tooltip={settings["card.title"]}
size={10}
/>
) : (
<ScalarTitle
title={settings["card.title"]}
description={settings["card.description"]}
onClick={
onChangeCardAndRun &&
(() => onChangeCardAndRun({ nextCard: card }))
}
/>
))}
</ScalarWrapper>
);
}
......
......@@ -2,6 +2,7 @@ import styled from "@emotion/styled";
import { css } from "@emotion/react";
import Ellipsified from "metabase/core/components/Ellipsified";
import { color } from "metabase/lib/colors";
import Icon from "metabase/components/Icon";
export interface ScalarContainerProps {
isClickable: boolean;
......@@ -20,3 +21,8 @@ export const ScalarContainer = styled(Ellipsified)<ScalarContainerProps>`
}
`}
`;
export const LabelIcon = styled(Icon)`
color: ${color("text-light")};
margin-top: 0.2rem;
`;
......@@ -45,7 +45,8 @@ export default class Text extends Component {
static hidden = true;
static supportPreviewing = true;
static minSize = { width: 4, height: 1 };
static minSize = { width: 1, height: 1 };
static defaultSize = { width: 4, height: 4 };
static checkRenderable() {
// text can always be rendered, nothing needed here
......
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