From 5f3c7c3491954e245d7adb741f8dc8a9d57a7398 Mon Sep 17 00:00:00 2001 From: Benoit Vinay <ben@benoitvinay.com> Date: Tue, 7 Jun 2022 08:48:35 +0200 Subject: [PATCH] Convert mode to typescript (#22915) * Mode moved into its own package * Misc code clena up * Comment added back in * modes set to TS * getMode method WIP * getMode clean up * ObjectLiteral type added * Fix types for Mode * ObjectLiteral replaced where necessary * FilterPopover commit issue Please enter the commit message for your changes. Lines starting * ObjectLiteral replaced with TS Record * ObjectLiteral removed --- .../src/metabase-lib/lib/{ => Mode}/Mode.ts | 16 +++--- .../src/metabase-lib/lib/Mode/constants.ts | 17 +++++++ frontend/src/metabase-lib/lib/Mode/index.ts | 2 + frontend/src/metabase-lib/lib/Mode/types.ts | 3 ++ .../lib/Mode/utils.ts} | 39 +++++++++------ frontend/src/metabase-types/types/Database.ts | 4 +- .../src/metabase-types/types/Visualization.ts | 6 ++- frontend/src/metabase-types/types/index.ts | 6 +-- frontend/src/metabase/modes/lib/modes.ts | 49 +++++++++++++++++++ frontend/src/metabase/static-viz/lib/dates.ts | 2 +- .../components/ObjectDetail/ObjectDetail.tsx | 2 +- 11 files changed, 110 insertions(+), 36 deletions(-) rename frontend/src/metabase-lib/lib/{ => Mode}/Mode.ts (78%) create mode 100644 frontend/src/metabase-lib/lib/Mode/constants.ts create mode 100644 frontend/src/metabase-lib/lib/Mode/index.ts create mode 100644 frontend/src/metabase-lib/lib/Mode/types.ts rename frontend/src/{metabase/modes/lib/modes.js => metabase-lib/lib/Mode/utils.ts} (65%) create mode 100644 frontend/src/metabase/modes/lib/modes.ts diff --git a/frontend/src/metabase-lib/lib/Mode.ts b/frontend/src/metabase-lib/lib/Mode/Mode.ts similarity index 78% rename from frontend/src/metabase-lib/lib/Mode.ts rename to frontend/src/metabase-lib/lib/Mode/Mode.ts index 0bae53dff72..f92ade62aa6 100644 --- a/frontend/src/metabase-lib/lib/Mode.ts +++ b/frontend/src/metabase-lib/lib/Mode/Mode.ts @@ -1,5 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck import Question from "metabase-lib/lib/Question"; import { getMode } from "metabase/modes/lib/modes"; import { @@ -7,6 +5,7 @@ import { ClickObject, QueryMode, } from "metabase-types/types/Visualization"; + export default class Mode { _question: Question; _queryMode: QueryMode; @@ -16,15 +15,14 @@ export default class Mode { this._queryMode = queryMode; } - static forQuestion(question: Question): Mode | null | undefined { + static forQuestion(question: Question): Mode | null { // TODO Atte Keinänen 6/22/17: Move getMode here and refactor it after writing tests const queryMode = getMode(question); - if (queryMode) { return new Mode(question, queryMode); - } else { - return null; } + + return null; } queryMode() { @@ -36,9 +34,9 @@ export default class Mode { } actionsForClick( - clicked: ClickObject | null | undefined, - settings, - extraData, + clicked: ClickObject | undefined, + settings: Record<string, any>, + extraData: Record<string, any>, ): ClickAction[] { return this._queryMode.drills().flatMap(actionCreator => actionCreator({ diff --git a/frontend/src/metabase-lib/lib/Mode/constants.ts b/frontend/src/metabase-lib/lib/Mode/constants.ts new file mode 100644 index 00000000000..7f853f7377e --- /dev/null +++ b/frontend/src/metabase-lib/lib/Mode/constants.ts @@ -0,0 +1,17 @@ +export const MODE_TYPE_DEFAULT = "default"; +export const MODE_TYPE_NATIVE = "native"; +export const MODE_TYPE_SEGMENT = "segment"; +export const MODE_TYPE_METRIC = "metric"; +export const MODE_TYPE_TIMESERIES = "timeseries"; +export const MODE_TYPE_GEO = "geo"; +export const MODE_TYPE_PIVOT = "pivot"; + +export const MODES_TYPES = [ + MODE_TYPE_NATIVE, + MODE_TYPE_SEGMENT, + MODE_TYPE_METRIC, + MODE_TYPE_TIMESERIES, + MODE_TYPE_GEO, + MODE_TYPE_PIVOT, + MODE_TYPE_DEFAULT, +] as const; diff --git a/frontend/src/metabase-lib/lib/Mode/index.ts b/frontend/src/metabase-lib/lib/Mode/index.ts new file mode 100644 index 00000000000..e42afab4d3d --- /dev/null +++ b/frontend/src/metabase-lib/lib/Mode/index.ts @@ -0,0 +1,2 @@ +export { default } from "./Mode"; +export { getMode } from "./utils"; diff --git a/frontend/src/metabase-lib/lib/Mode/types.ts b/frontend/src/metabase-lib/lib/Mode/types.ts new file mode 100644 index 00000000000..6dff0cb96bb --- /dev/null +++ b/frontend/src/metabase-lib/lib/Mode/types.ts @@ -0,0 +1,3 @@ +import { MODES_TYPES } from "./constants"; + +export type ModeType = typeof MODES_TYPES[number]; diff --git a/frontend/src/metabase/modes/lib/modes.js b/frontend/src/metabase-lib/lib/Mode/utils.ts similarity index 65% rename from frontend/src/metabase/modes/lib/modes.js rename to frontend/src/metabase-lib/lib/Mode/utils.ts index 73cb7f321cb..5722f0cf983 100644 --- a/frontend/src/metabase/modes/lib/modes.js +++ b/frontend/src/metabase-lib/lib/Mode/utils.ts @@ -1,15 +1,18 @@ -import SegmentMode from "../components/modes/SegmentMode"; -import MetricMode from "../components/modes/MetricMode"; -import TimeseriesMode from "../components/modes/TimeseriesMode"; -import GeoMode from "../components/modes/GeoMode"; -import PivotMode from "../components/modes/PivotMode"; -import NativeMode from "../components/modes/NativeMode"; -import DefaultMode from "../components/modes/DefaultMode"; - +import Question from "metabase-lib/lib/Question"; import StructuredQuery from "metabase-lib/lib/queries/StructuredQuery"; import NativeQuery from "metabase-lib/lib/queries/NativeQuery"; +import { ModeType } from "./types"; +import { + MODE_TYPE_NATIVE, + MODE_TYPE_SEGMENT, + MODE_TYPE_METRIC, + MODE_TYPE_TIMESERIES, + MODE_TYPE_GEO, + MODE_TYPE_PIVOT, + MODE_TYPE_DEFAULT, +} from "metabase-lib/lib/Mode/constants"; -export function getMode(question) { +export function getMode(question: Question): ModeType | null { if (!question) { return null; } @@ -17,7 +20,7 @@ export function getMode(question) { const query = question.query(); if (query instanceof NativeQuery) { - return NativeMode; + return MODE_TYPE_NATIVE; } if (query instanceof StructuredQuery) { @@ -25,11 +28,13 @@ export function getMode(question) { const breakouts = query.breakouts(); if (aggregations.length === 0 && breakouts.length === 0) { - return SegmentMode; + return MODE_TYPE_SEGMENT; } + if (aggregations.length > 0 && breakouts.length === 0) { - return MetricMode; + return MODE_TYPE_METRIC; } + if (aggregations.length > 0 && breakouts.length > 0) { const breakoutFields = breakouts.map(b => b.field()); if ( @@ -38,21 +43,23 @@ export function getMode(question) { breakoutFields[0].isDate() && breakoutFields[1].isCategory()) ) { - return TimeseriesMode; + return MODE_TYPE_TIMESERIES; } + if (breakoutFields.length === 1 && breakoutFields[0].isAddress()) { - return GeoMode; + return MODE_TYPE_GEO; } + if ( (breakoutFields.length === 1 && breakoutFields[0].isCategory()) || (breakoutFields.length === 2 && breakoutFields[0].isCategory() && breakoutFields[1].isCategory()) ) { - return PivotMode; + return MODE_TYPE_PIVOT; } } } - return DefaultMode; + return MODE_TYPE_DEFAULT; } diff --git a/frontend/src/metabase-types/types/Database.ts b/frontend/src/metabase-types/types/Database.ts index 60cda7f51b2..3ddd49f3aed 100644 --- a/frontend/src/metabase-types/types/Database.ts +++ b/frontend/src/metabase-types/types/Database.ts @@ -16,9 +16,7 @@ export type DatabaseFeature = | "case-sensitivity-string-filter-options" | "binning"; -export type DatabaseDetails = { - [key: string]: any; -}; +export type DatabaseDetails = Record<string, any>; export type DatabaseEngine = string; diff --git a/frontend/src/metabase-types/types/Visualization.ts b/frontend/src/metabase-types/types/Visualization.ts index de62082172a..257190104b5 100644 --- a/frontend/src/metabase-types/types/Visualization.ts +++ b/frontend/src/metabase-types/types/Visualization.ts @@ -35,12 +35,12 @@ export type ClickObject = { event?: MouseEvent; element?: HTMLElement; seriesIndex?: number; - settings?: { [key: string]: any }; + settings?: Record<string, any>; origin?: { row: Row; cols: Column[]; }; - extraData?: { [key: string]: any }; + extraData?: Record<string, any>; }; export type ClickAction = { @@ -59,6 +59,8 @@ export type ClickAction = { export type ClickActionProps = { question: Question; clicked?: ClickObject; + settings?: VisualizationSettings; + extraData?: Record<string, any>; }; export type OnChangeCardAndRun = ({ diff --git a/frontend/src/metabase-types/types/index.ts b/frontend/src/metabase-types/types/index.ts index c7e847db720..0978d8bba20 100644 --- a/frontend/src/metabase-types/types/index.ts +++ b/frontend/src/metabase-types/types/index.ts @@ -15,13 +15,11 @@ export type LocationDescriptor = { hash: string; pathname: string; search?: string; - query?: { [key: string]: string }; + query?: Record<string, any>; }; /* Map of query string names to string values */ -export type QueryParams = { - [key: string]: string; -}; +export type QueryParams = Record<string, any>; /* Metabase API error object returned by the backend */ export type ApiError = { diff --git a/frontend/src/metabase/modes/lib/modes.ts b/frontend/src/metabase/modes/lib/modes.ts new file mode 100644 index 00000000000..1bc3bf784dc --- /dev/null +++ b/frontend/src/metabase/modes/lib/modes.ts @@ -0,0 +1,49 @@ +import SegmentMode from "../components/modes/SegmentMode"; +import MetricMode from "../components/modes/MetricMode"; +import TimeseriesMode from "../components/modes/TimeseriesMode"; +import GeoMode from "../components/modes/GeoMode"; +import PivotMode from "../components/modes/PivotMode"; +import NativeMode from "../components/modes/NativeMode"; +import DefaultMode from "../components/modes/DefaultMode"; +import { QueryMode } from "metabase-types/types/Visualization"; + +import Question from "metabase-lib/lib/Question"; +import { getMode as getModeFromLib } from "metabase-lib/lib/Mode"; +import { + MODE_TYPE_NATIVE, + MODE_TYPE_SEGMENT, + MODE_TYPE_METRIC, + MODE_TYPE_TIMESERIES, + MODE_TYPE_GEO, + MODE_TYPE_PIVOT, +} from "metabase-lib/lib/Mode/constants"; + +export function getMode(question: Question): QueryMode | any | null { + const mode = getModeFromLib(question); + if (!mode) { + return null; + } + + switch (mode) { + case MODE_TYPE_NATIVE: + return NativeMode; + + case MODE_TYPE_SEGMENT: + return SegmentMode; + + case MODE_TYPE_METRIC: + return MetricMode; + + case MODE_TYPE_TIMESERIES: + return TimeseriesMode; + + case MODE_TYPE_GEO: + return GeoMode; + + case MODE_TYPE_PIVOT: + return PivotMode; + + default: + return DefaultMode; + } +} diff --git a/frontend/src/metabase/static-viz/lib/dates.ts b/frontend/src/metabase/static-viz/lib/dates.ts index 9f3bc2a55d9..451ad2e965a 100644 --- a/frontend/src/metabase/static-viz/lib/dates.ts +++ b/frontend/src/metabase/static-viz/lib/dates.ts @@ -14,7 +14,7 @@ const DEFAULT_OPTIONS = { time_enabled: false, }; -const DATE_FORMATS: { [key: string]: Intl.DateTimeFormat } = { +const DATE_FORMATS: Record<string, Intl.DateTimeFormat> = { YY: new Intl.DateTimeFormat("en", { year: "2-digit" }), YYYY: new Intl.DateTimeFormat("en", { year: "numeric" }), M: new Intl.DateTimeFormat("en", { month: "numeric" }), diff --git a/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx b/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx index 285664a9b01..a5a1f182a58 100644 --- a/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx +++ b/frontend/src/metabase/visualizations/components/ObjectDetail/ObjectDetail.tsx @@ -203,7 +203,7 @@ export function ObjectDetailFn({ ); const onKeyDown = (event: KeyboardEvent) => { - const capturedKeys: { [key: string]: () => void } = { + const capturedKeys: Record<string, () => void> = { ArrowUp: viewPreviousObjectDetail, ArrowDown: viewNextObjectDetail, Escape: closeObjectDetail, -- GitLab