Skip to content
Snippets Groups Projects
Unverified Commit 8e111abc authored by Romeo Van Snick's avatar Romeo Van Snick Committed by GitHub
Browse files

Static extract examples (#41778)

* Add subTitle to ClickActions

* Add examples to column extractions

* Add test for examples

* Add test for examples

* Use rem helper

* Use JSDoc for todo

* Disambiguate between ColumnExtraction and ColumnExtractionInfo

* Update type of getExample

* Use rem helper
parent 0da81005
No related branches found
No related tags found
No related merge requests found
......@@ -19,26 +19,32 @@ const DATE_CASES = [
{
option: "Hour of day",
value: "21",
example: "0, 1",
},
{
option: "Day of month",
value: "11",
example: "1, 2",
},
{
option: "Day of week",
value: "Tuesday",
example: "Monday, Tuesday",
},
{
option: "Month of year",
value: "Feb",
example: "Jan, Feb",
},
{
option: "Quarter of year",
value: "Q1",
example: "Q1, Q2",
},
{
option: "Year",
value: "2,025",
example: "2023, 2024",
},
];
......@@ -67,13 +73,14 @@ describe("extract action", () => {
describe("date columns", () => {
describe("should add a date expression for each option", () => {
DATE_CASES.forEach(({ option, value }) => {
DATE_CASES.forEach(({ option, value, example }) => {
it(option, () => {
openOrdersTable({ limit: 1 });
extractColumnAndCheck({
column: "Created At",
option,
value,
example,
});
});
});
......@@ -230,12 +237,23 @@ describe("extract action", () => {
});
});
function extractColumnAndCheck({ column, option, newColumn = option, value }) {
function extractColumnAndCheck({
column,
option,
newColumn = option,
value,
example,
}) {
const requestAlias = _.uniqueId("dataset");
cy.intercept("POST", "/api/dataset").as(requestAlias);
cy.findByRole("columnheader", { name: column }).click();
popover().findByText("Extract day, month…").click();
cy.wait(1);
if (example) {
popover().findByText(option).should("contain", example);
}
popover().findByText(option).click();
cy.wait(`@${requestAlias}`);
......
......@@ -16,6 +16,8 @@ import type {
Clause,
ClauseDisplayInfo,
ColumnDisplayInfo,
ColumnExtraction,
ColumnExtractionInfo,
ColumnGroup,
ColumnGroupDisplayInfo,
ColumnMetadata,
......@@ -142,6 +144,11 @@ declare function DisplayInfoFn(
stageIndex: number,
segment: SegmentMetadata,
): SegmentDisplayInfo;
declare function DisplayInfoFn(
query: Query,
stageIndex: number,
extraction: ColumnExtraction,
): ColumnExtractionInfo;
// x can be any sort of opaque object, e.g. a clause or metadata map. Values returned depend on what you pass in, but it
// should always have display_name... see :metabase.lib.metadata.calculation/display-info schema
......
......@@ -446,20 +446,20 @@ export type DrillThruType =
export type BaseDrillThruInfo<Type extends DrillThruType> = { type: Type };
export type ColumnExtraction = {
tag: ColumnExtractionKey;
displayName: string;
declare const ColumnExtraction: unique symbol;
export type ColumnExtraction = unknown & {
_opaque: typeof ColumnExtraction;
};
declare const ColumnExtractionKey: unique symbol;
export type ColumnExtractionKey = unknown & {
_opaque: typeof ColumnExtractionKey;
export type ColumnExtractionInfo = {
tag: string;
displayName: string;
};
export type ColumnExtractDrillThruInfo =
BaseDrillThruInfo<"drill-thru/column-extract"> & {
displayName: string;
extractions: ColumnExtraction[];
extractions: ColumnExtractionInfo[];
};
export type QuickFilterDrillThruOperator =
......
......@@ -17,6 +17,7 @@ export const columnExtractDrill: Drill<Lib.ColumnExtractDrillThruInfo> = ({
extraction => ({
name: `extract.${extraction.displayName}`,
title: extraction.displayName,
subTitle: getExample(extraction),
section: "extract-popover",
buttonType: "horizontal",
question: () => applyDrill(drill, extraction.tag),
......@@ -44,3 +45,32 @@ export const columnExtractDrill: Drill<Lib.ColumnExtractDrillThruInfo> = ({
},
];
};
export function getExample(info: Lib.ColumnExtractionInfo) {
/**
* @todo this should eventually be moved into Lib.displayInfo
* to avoid the keys going out of sync with the MLv2-defined extractions.
*/
switch (info.tag) {
case "hour-of-day":
return "0, 1";
case "day-of-month":
return "1, 2";
case "day-of-week":
return "Monday, Tuesday";
case "month-of-year":
return "Jan, Feb";
case "quarter-of-year":
return "Q1, Q2";
case "year":
return "2023, 2024";
case "domain":
return "example.com, online.com";
case "host":
return "example, online";
case "subdomain":
return "www, maps";
}
return undefined;
}
......@@ -2,7 +2,7 @@ import styled from "@emotion/styled";
import Button from "metabase/core/components/Button";
import { alpha, color } from "metabase/lib/colors";
import { Icon } from "metabase/ui";
import { Icon, rem } from "metabase/ui";
export const ClickActionButtonIcon = styled(Icon)`
margin-right: 0.2rem;
......@@ -11,7 +11,7 @@ export const ClickActionButtonIcon = styled(Icon)`
`;
export const ClickActionButtonTextIcon = styled.span`
margin-right: 0.25rem;
margin-right: ${rem(4)};
width: 0.875rem;
text-align: center;
font-weight: 700;
......@@ -20,6 +20,13 @@ export const ClickActionButtonTextIcon = styled.span`
transition: all 200ms linear;
`;
export const Subtitle = styled.div`
color: ${color("text-light")};
font-weight: normal;
text-align: start;
margin-top: ${rem(4)};
`;
export const HorizontalClickActionButton = styled(Button)`
display: flex;
flex: auto;
......@@ -27,6 +34,7 @@ export const HorizontalClickActionButton = styled(Button)`
border-radius: 8px;
border: none;
text-align: start;
padding: 0.5rem;
margin: 0 -0.5rem;
......@@ -46,6 +54,10 @@ export const HorizontalClickActionButton = styled(Button)`
${ClickActionButtonTextIcon} {
color: ${color("white")};
}
${Subtitle} {
color: ${color("white")};
}
}
`;
......
......@@ -19,6 +19,7 @@ import {
SortControl,
TokenActionButton,
TokenFilterActionButton,
Subtitle,
} from "./ClickActionControl.styled";
interface Props {
......@@ -115,6 +116,7 @@ export const ClickActionControl = ({
onClick={handleClick}
>
{action.title}
{action.subTitle && <Subtitle>{action.subTitle}</Subtitle>}
</HorizontalClickActionButton>
);
......
......@@ -45,6 +45,7 @@ export type ClickActionSectionDirection = "row" | "column";
export type ClickActionBase = {
name: string;
title?: React.ReactNode;
subTitle?: React.ReactNode;
section: ClickActionSection;
sectionTitle?: string;
sectionDirection?: ClickActionSectionDirection;
......
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