Skip to content
Snippets Groups Projects
Unverified Commit 594cdb01 authored by Anton Kulyk's avatar Anton Kulyk Committed by GitHub
Browse files

Convert `Table` viz and `TableSimple` to TypeScript (#38099)


* Convert `TableSimple` to TypeScript

* Convert `Table` viz to TypeScript

* Update frontend/src/metabase/visualizations/components/TableSimple/TableCell.tsx

Co-authored-by: default avatarKamil Mielnik <kamil@kamilmielnik.com>

* Update frontend/src/metabase/visualizations/components/TableSimple/TableSimple.tsx

Co-authored-by: default avatarKamil Mielnik <kamil@kamilmielnik.com>

---------

Co-authored-by: default avatarKamil Mielnik <kamil@kamilmielnik.com>
parent 221ca042
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,7 @@ export interface OptionsType extends TimeOnlyOptions { ...@@ -9,6 +9,7 @@ export interface OptionsType extends TimeOnlyOptions {
click_behavior?: any; click_behavior?: any;
clicked?: any; clicked?: any;
column?: any; column?: any;
column_title?: string;
compact?: boolean; compact?: boolean;
date_abbreviate?: boolean; date_abbreviate?: boolean;
date_format?: string; date_format?: string;
...@@ -30,6 +31,7 @@ export interface OptionsType extends TimeOnlyOptions { ...@@ -30,6 +31,7 @@ export interface OptionsType extends TimeOnlyOptions {
removeDay?: boolean; removeDay?: boolean;
removeYear?: boolean; removeYear?: boolean;
rich?: boolean; rich?: boolean;
show_mini_bar?: boolean;
suffix?: string; suffix?: string;
type?: string; type?: string;
view_as?: string | null; view_as?: string | null;
......
/* eslint-disable react/prop-types */ import { useCallback, useMemo, isValidElement } from "react";
import { useCallback, useMemo } from "react";
import cx from "classnames"; import cx from "classnames";
import ExternalLink from "metabase/core/components/ExternalLink"; import ExternalLink from "metabase/core/components/ExternalLink";
import type { OptionsType } from "metabase/lib/formatting/types";
import { formatValue } from "metabase/lib/formatting"; import { formatValue } from "metabase/lib/formatting";
import { import {
getTableCellClickedObject, getTableCellClickedObject,
...@@ -11,11 +11,31 @@ import { ...@@ -11,11 +11,31 @@ import {
isColumnRightAligned, isColumnRightAligned,
} from "metabase/visualizations/lib/table"; } from "metabase/visualizations/lib/table";
import { getColumnExtent } from "metabase/visualizations/lib/utils"; import { getColumnExtent } from "metabase/visualizations/lib/utils";
import type {
DatasetColumn,
DatasetData,
RowValue,
RowValues,
Series,
VisualizationSettings,
} from "metabase-types/api";
import type { ClickObject } from "metabase-lib";
import { isID, isFK } from "metabase-lib/types/utils/isa"; import { isID, isFK } from "metabase-lib/types/utils/isa";
import MiniBar from "../MiniBar"; import MiniBar from "../MiniBar";
import { CellRoot, CellContent } from "./TableCell.styled"; import { CellRoot, CellContent } from "./TableCell.styled";
type GetCellDataOpts = {
value: RowValue;
clicked: ClickObject;
extraData: Record<string, unknown>;
cols: DatasetColumn[];
rows: RowValues[];
columnIndex: number;
columnSettings: OptionsType;
};
function getCellData({ function getCellData({
value, value,
clicked, clicked,
...@@ -24,7 +44,7 @@ function getCellData({ ...@@ -24,7 +44,7 @@ function getCellData({
rows, rows,
columnIndex, columnIndex,
columnSettings, columnSettings,
}) { }: GetCellDataOpts) {
if (value == null) { if (value == null) {
return "-"; return "-";
} }
...@@ -46,7 +66,25 @@ function getCellData({ ...@@ -46,7 +66,25 @@ function getCellData({
}); });
} }
function TableCell({ interface TableCellProps {
value: RowValue;
data: DatasetData;
series: Series;
settings: VisualizationSettings;
rowIndex: number;
columnIndex: number;
isPivoted: boolean;
getCellBackgroundColor: (
value: RowValue,
rowIndex: number,
columnName: string,
) => string | undefined;
getExtraDataForClick: (clickObject: ClickObject) => Record<string, unknown>;
checkIsVisualizationClickable: (clickObject: ClickObject) => boolean;
onVisualizationClick?: (clickObject: ClickObject) => void;
}
export function TableCell({
value, value,
data, data,
series, series,
...@@ -58,7 +96,7 @@ function TableCell({ ...@@ -58,7 +96,7 @@ function TableCell({
getExtraDataForClick, getExtraDataForClick,
checkIsVisualizationClickable, checkIsVisualizationClickable,
onVisualizationClick, onVisualizationClick,
}) { }: TableCellProps) {
const { rows, cols } = data; const { rows, cols } = data;
const column = cols[columnIndex]; const column = cols[columnIndex];
const columnSettings = settings.column(column); const columnSettings = settings.column(column);
...@@ -66,6 +104,7 @@ function TableCell({ ...@@ -66,6 +104,7 @@ function TableCell({
const clickedRowData = useMemo( const clickedRowData = useMemo(
() => () =>
getTableClickedObjectRowData( getTableClickedObjectRowData(
// @ts-expect-error -- visualizations/lib/table should be typed
series, series,
rowIndex, rowIndex,
columnIndex, columnIndex,
...@@ -107,13 +146,13 @@ function TableCell({ ...@@ -107,13 +146,13 @@ function TableCell({
[value, clicked, extraData, cols, rows, columnIndex, columnSettings], [value, clicked, extraData, cols, rows, columnIndex, columnSettings],
); );
const isLink = cellData && cellData.type === ExternalLink; const isLink = isValidElement(cellData) && cellData.type === ExternalLink;
const isClickable = !isLink; const isClickable = !isLink;
const onClick = useCallback( const onClick = useCallback(
e => { e => {
if (checkIsVisualizationClickable(clicked)) { if (checkIsVisualizationClickable(clicked)) {
onVisualizationClick({ onVisualizationClick?.({
...clicked, ...clicked,
element: e.currentTarget, element: e.currentTarget,
extraData, extraData,
...@@ -155,5 +194,3 @@ function TableCell({ ...@@ -155,5 +194,3 @@ function TableCell({
</CellRoot> </CellRoot>
); );
} }
export default TableCell;
/* eslint-disable react/prop-types */
import { useCallback, useLayoutEffect, useMemo, useState, useRef } from "react"; import { useCallback, useLayoutEffect, useMemo, useState, useRef } from "react";
import { getIn } from "icepick"; import { getIn } from "icepick";
import _ from "underscore"; import _ from "underscore";
...@@ -8,9 +7,19 @@ import { Ellipsified } from "metabase/core/components/Ellipsified"; ...@@ -8,9 +7,19 @@ import { Ellipsified } from "metabase/core/components/Ellipsified";
import { isPositiveInteger } from "metabase/lib/number"; import { isPositiveInteger } from "metabase/lib/number";
import { isColumnRightAligned } from "metabase/visualizations/lib/table"; import { isColumnRightAligned } from "metabase/visualizations/lib/table";
import type {
Card,
DatasetColumn,
DatasetData,
RowValue,
Series,
VisualizationSettings,
} from "metabase-types/api";
import type { ClickObject } from "metabase-lib";
import { isID } from "metabase-lib/types/utils/isa"; import { isID } from "metabase-lib/types/utils/isa";
import TableCell from "./TableCell"; import { TableCell } from "./TableCell";
import TableFooter from "./TableFooter"; import TableFooter from "./TableFooter";
import { import {
Root, Root,
...@@ -21,11 +30,13 @@ import { ...@@ -21,11 +30,13 @@ import {
SortIcon, SortIcon,
} from "./TableSimple.styled"; } from "./TableSimple.styled";
function getBoundingClientRectSafe(ref) { function getBoundingClientRectSafe(ref: {
current?: HTMLElement | null;
}): Partial<DOMRect> {
return ref.current?.getBoundingClientRect?.() ?? {}; return ref.current?.getBoundingClientRect?.() ?? {};
} }
function formatCellValueForSorting(value, column) { function formatCellValueForSorting(value: RowValue, column: DatasetColumn) {
if (typeof value === "string") { if (typeof value === "string") {
if (isID(column) && isPositiveInteger(value)) { if (isID(column) && isPositiveInteger(value)) {
return parseInt(value, 10); return parseInt(value, 10);
...@@ -39,7 +50,23 @@ function formatCellValueForSorting(value, column) { ...@@ -39,7 +50,23 @@ function formatCellValueForSorting(value, column) {
return value; return value;
} }
function TableSimple({ interface TableSimpleProps {
card: Card;
data: DatasetData;
series: Series;
settings: VisualizationSettings;
height: number;
isDashboard?: boolean;
isEditing?: boolean;
isPivoted: boolean;
className?: string;
getColumnTitle: (colIndex: number) => string;
getExtraDataForClick: (clickObject: ClickObject) => Record<string, unknown>;
onVisualizationClick?: (clickObject: ClickObject) => void;
visualizationIsClickable?: (clickObject: ClickObject) => boolean;
}
function TableSimpleInner({
card, card,
data, data,
series, series,
...@@ -51,7 +78,7 @@ function TableSimple({ ...@@ -51,7 +78,7 @@ function TableSimple({
visualizationIsClickable, visualizationIsClickable,
getColumnTitle, getColumnTitle,
getExtraDataForClick, getExtraDataForClick,
}) { }: TableSimpleProps) {
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
const [pageSize, setPageSize] = useState(1); const [pageSize, setPageSize] = useState(1);
const [sortColumn, setSortColumn] = useState(null); const [sortColumn, setSortColumn] = useState(null);
...@@ -62,7 +89,7 @@ function TableSimple({ ...@@ -62,7 +89,7 @@ function TableSimple({
const firstRowRef = useRef(null); const firstRowRef = useRef(null);
useLayoutEffect(() => { useLayoutEffect(() => {
const { height: headerHeight } = getBoundingClientRectSafe(headerRef); const { height: headerHeight = 0 } = getBoundingClientRectSafe(headerRef);
const { height: footerHeight = 0 } = getBoundingClientRectSafe(footerRef); const { height: footerHeight = 0 } = getBoundingClientRectSafe(footerRef);
const { height: rowHeight = 0 } = getBoundingClientRectSafe(firstRowRef); const { height: rowHeight = 0 } = getBoundingClientRectSafe(firstRowRef);
const currentPageSize = Math.floor( const currentPageSize = Math.floor(
...@@ -87,10 +114,10 @@ function TableSimple({ ...@@ -87,10 +114,10 @@ function TableSimple({
const checkIsVisualizationClickable = useCallback( const checkIsVisualizationClickable = useCallback(
clickedItem => { clickedItem => {
return ( return Boolean(
onVisualizationClick && onVisualizationClick &&
visualizationIsClickable && visualizationIsClickable &&
visualizationIsClickable(clickedItem) visualizationIsClickable(clickedItem),
); );
}, },
[onVisualizationClick, visualizationIsClickable], [onVisualizationClick, visualizationIsClickable],
...@@ -217,7 +244,7 @@ function TableSimple({ ...@@ -217,7 +244,7 @@ function TableSimple({
); );
} }
export default ExplicitSize({ export const TableSimple = ExplicitSize<TableSimpleProps>({
refreshMode: props => refreshMode: props =>
props.isDashboard && !props.isEditing ? "debounceLeading" : "throttle", props.isDashboard && !props.isEditing ? "debounceLeading" : "throttle",
})(TableSimple); })(TableSimpleInner);
// eslint-disable-next-line import/no-default-export -- deprecated usage export * from "./TableSimple";
export { default } from "./TableSimple";
import type { import type {
Card, Card,
DatasetColumn,
DatasetData, DatasetData,
RawSeries, RawSeries,
Series, Series,
...@@ -10,6 +11,8 @@ import type { ClickObject } from "metabase/visualizations/types"; ...@@ -10,6 +11,8 @@ import type { ClickObject } from "metabase/visualizations/types";
import type { ColorGetter } from "metabase/static-viz/lib/colors"; import type { ColorGetter } from "metabase/static-viz/lib/colors";
import type { OptionsType } from "metabase/lib/formatting/types"; import type { OptionsType } from "metabase/lib/formatting/types";
import type { IconName, IconProps } from "metabase/ui"; import type { IconName, IconProps } from "metabase/ui";
import type Metadata from "metabase-lib/metadata/Metadata";
import type Query from "metabase-lib/queries/Query"; import type Query from "metabase-lib/queries/Query";
import type { HoveredObject } from "./hover"; import type { HoveredObject } from "./hover";
...@@ -46,6 +49,7 @@ export interface VisualizationProps { ...@@ -46,6 +49,7 @@ export interface VisualizationProps {
series: Series; series: Series;
card: Card; card: Card;
data: DatasetData; data: DatasetData;
metadata: Metadata;
rawSeries: RawSeries; rawSeries: RawSeries;
settings: ComputedVisualizationSettings; settings: ComputedVisualizationSettings;
headerIcon: IconProps; headerIcon: IconProps;
...@@ -88,6 +92,24 @@ export interface VisualizationProps { ...@@ -88,6 +92,24 @@ export interface VisualizationProps {
onUpdateWarnings?: any; onUpdateWarnings?: any;
} }
export type ColumnSettingDefinition<TValue, TProps = unknown> = {
title?: string;
hint?: string;
widget?: string | React.ComponentType<any>;
default?: TValue;
props?: TProps;
inline?: boolean;
readDependencies?: string[];
getDefault?: (col: DatasetColumn) => TValue;
getHidden?: (col: DatasetColumn, settings: OptionsType) => boolean;
getProps?: (
col: DatasetColumn,
settings: OptionsType,
onChange: (value: TValue) => void,
extra: { series: Series },
) => TProps;
};
export type VisualizationSettingDefinition<TValue, TProps = void> = { export type VisualizationSettingDefinition<TValue, TProps = void> = {
section?: string; section?: string;
title?: string; title?: string;
......
/* eslint-disable react/prop-types */
import { Component } from "react"; import { Component } from "react";
import { t } from "ttag"; import { t } from "ttag";
import _ from "underscore"; import _ from "underscore";
import cx from "classnames"; import cx from "classnames";
import * as DataGrid from "metabase/lib/data_grid";
import { getOptionFromColumn } from "metabase/visualizations/lib/settings/utils";
import { formatColumn } from "metabase/lib/formatting"; import { formatColumn } from "metabase/lib/formatting";
import * as DataGrid from "metabase/lib/data_grid";
import ChartSettingLinkUrlInput from "metabase/visualizations/components/settings/ChartSettingLinkUrlInput"; import ChartSettingLinkUrlInput from "metabase/visualizations/components/settings/ChartSettingLinkUrlInput";
import ChartSettingsTableFormatting, { import ChartSettingsTableFormatting, {
...@@ -20,12 +18,19 @@ import { ...@@ -20,12 +18,19 @@ import {
getTitleForColumn, getTitleForColumn,
isPivoted as _isPivoted, isPivoted as _isPivoted,
} from "metabase/visualizations/lib/settings/column"; } from "metabase/visualizations/lib/settings/column";
import { getOptionFromColumn } from "metabase/visualizations/lib/settings/utils";
import { getDefaultPivotColumn } from "metabase/visualizations/lib/utils";
import { import {
getDefaultSize, getDefaultSize,
getMinSize, getMinSize,
} from "metabase/visualizations/shared/utils/sizes"; } from "metabase/visualizations/shared/utils/sizes";
import { getDefaultPivotColumn } from "metabase/visualizations/lib/utils";
import type {
DatasetColumn,
DatasetData,
Series,
VisualizationSettings,
} from "metabase-types/api";
import * as Lib from "metabase-lib"; import * as Lib from "metabase-lib";
import Question from "metabase-lib/Question"; import Question from "metabase-lib/Question";
import { import {
...@@ -40,10 +45,20 @@ import { ...@@ -40,10 +45,20 @@ import {
import { findColumnIndexForColumnSetting } from "metabase-lib/queries/utils/dataset"; import { findColumnIndexForColumnSetting } from "metabase-lib/queries/utils/dataset";
import * as Q_DEPRECATED from "metabase-lib/queries/utils"; import * as Q_DEPRECATED from "metabase-lib/queries/utils";
import TableSimple from "../components/TableSimple"; import type { ColumnSettingDefinition, VisualizationProps } from "../types";
import { TableSimple } from "../components/TableSimple";
import TableInteractive from "../components/TableInteractive/TableInteractive.jsx"; import TableInteractive from "../components/TableInteractive/TableInteractive.jsx";
export default class Table extends Component { interface TableProps extends VisualizationProps {
isShowingDetailsOnlyColumns?: boolean;
}
interface TableState {
data: Pick<DatasetData, "cols" | "rows" | "results_timezone"> | null;
question: Question | null;
}
class Table extends Component<TableProps, TableState> {
static uiName = t`Table`; static uiName = t`Table`;
static identifier = "table"; static identifier = "table";
static iconName = "table"; static iconName = "table";
...@@ -52,19 +67,15 @@ export default class Table extends Component { ...@@ -52,19 +67,15 @@ export default class Table extends Component {
static minSize = getMinSize("table"); static minSize = getMinSize("table");
static defaultSize = getDefaultSize("table"); static defaultSize = getDefaultSize("table");
static isSensible({ cols, rows }) { static isSensible() {
return true; return true;
} }
static isLiveResizable(series) { static isLiveResizable() {
return false; return false;
} }
static checkRenderable([ static checkRenderable() {
{
data: { cols, rows },
},
]) {
// scalar can always be rendered, nothing needed here // scalar can always be rendered, nothing needed here
} }
...@@ -77,8 +88,8 @@ export default class Table extends Component { ...@@ -77,8 +88,8 @@ export default class Table extends Component {
title: t`Pivot table`, title: t`Pivot table`,
widget: "toggle", widget: "toggle",
inline: true, inline: true,
getHidden: ([{ card, data }]) => data && data.cols.length !== 3, getHidden: ([{ data }]: Series) => data && data.cols.length !== 3,
getDefault: ([{ card, data }]) => { getDefault: ([{ card, data }]: Series) => {
if ( if (
!data || !data ||
data.cols.length !== 3 || data.cols.length !== 3 ||
...@@ -100,20 +111,18 @@ export default class Table extends Component { ...@@ -100,20 +111,18 @@ export default class Table extends Component {
{ {
data: { cols, rows }, data: { cols, rows },
}, },
]) => { ]: Series) => {
return getDefaultPivotColumn(cols, rows)?.name; return getDefaultPivotColumn(cols, rows)?.name;
}, },
getProps: ( getProps: ([
[ {
{ data: { cols },
data: { cols }, },
}, ]: Series) => ({
],
settings,
) => ({
options: cols.filter(isDimension).map(getOptionFromColumn), options: cols.filter(isDimension).map(getOptionFromColumn),
}), }),
getHidden: (series, settings) => !settings["table.pivot"], getHidden: (series: Series, settings: VisualizationSettings) =>
!settings["table.pivot"],
readDependencies: ["table.pivot"], readDependencies: ["table.pivot"],
persistDefault: true, persistDefault: true,
}, },
...@@ -121,7 +130,10 @@ export default class Table extends Component { ...@@ -121,7 +130,10 @@ export default class Table extends Component {
section: t`Columns`, section: t`Columns`,
title: t`Cell column`, title: t`Cell column`,
widget: "field", widget: "field",
getDefault: ([{ data }], { "table.pivot_column": pivotCol }) => { getDefault: (
[{ data }]: Series,
{ "table.pivot_column": pivotCol }: VisualizationSettings,
) => {
// We try to show numeric values in pivot cells, but if none are // We try to show numeric values in pivot cells, but if none are
// available, we fall back to the last column in the unpivoted table // available, we fall back to the last column in the unpivoted table
const nonPivotCols = data.cols.filter(c => c.name !== pivotCol); const nonPivotCols = data.cols.filter(c => c.name !== pivotCol);
...@@ -129,24 +141,15 @@ export default class Table extends Component { ...@@ -129,24 +141,15 @@ export default class Table extends Component {
const { name } = nonPivotCols.find(isMetric) || lastCol || {}; const { name } = nonPivotCols.find(isMetric) || lastCol || {};
return name; return name;
}, },
getProps: ( getProps: ([
[ {
{ data: { cols },
data: { cols }, },
}, ]: Series) => ({
],
settings,
) => ({
options: cols.map(getOptionFromColumn), options: cols.map(getOptionFromColumn),
}), }),
getHidden: ( getHidden: (series: Series, settings: VisualizationSettings) =>
[ !settings["table.pivot"],
{
data: { cols },
},
],
settings,
) => !settings["table.pivot"],
readDependencies: ["table.pivot", "table.pivot_column"], readDependencies: ["table.pivot", "table.pivot_column"],
persistDefault: true, persistDefault: true,
}, },
...@@ -156,19 +159,16 @@ export default class Table extends Component { ...@@ -156,19 +159,16 @@ export default class Table extends Component {
section: t`Conditional Formatting`, section: t`Conditional Formatting`,
widget: ChartSettingsTableFormatting, widget: ChartSettingsTableFormatting,
default: [], default: [],
getProps: (series, settings) => ({ getProps: (series: Series, settings: VisualizationSettings) => ({
cols: series[0].data.cols.filter(isFormattable), cols: series[0].data.cols.filter(isFormattable),
isPivoted: settings["table.pivot"], isPivoted: settings["table.pivot"],
}), }),
getHidden: ( getHidden: ([
[ {
{ data: { cols },
data: { cols }, },
}, ]: Series) => cols.filter(isFormattable).length === 0,
],
settings,
) => cols.filter(isFormattable).length === 0,
readDependencies: ["table.pivot"], readDependencies: ["table.pivot"],
}, },
"table._cell_background_getter": { "table._cell_background_getter": {
...@@ -177,8 +177,8 @@ export default class Table extends Component { ...@@ -177,8 +177,8 @@ export default class Table extends Component {
{ {
data: { rows, cols }, data: { rows, cols },
}, },
], ]: Series,
settings, settings: VisualizationSettings,
) { ) {
return makeCellBackgroundGetter( return makeCellBackgroundGetter(
rows, rows,
...@@ -191,8 +191,11 @@ export default class Table extends Component { ...@@ -191,8 +191,11 @@ export default class Table extends Component {
}, },
}; };
static columnSettings = column => { static columnSettings = (column: DatasetColumn) => {
const settings = { const settings: Record<
string,
ColumnSettingDefinition<unknown, unknown>
> = {
column_title: { column_title: {
title: t`Column title`, title: t`Column title`,
widget: "input", widget: "input",
...@@ -200,6 +203,7 @@ export default class Table extends Component { ...@@ -200,6 +203,7 @@ export default class Table extends Component {
}, },
click_behavior: {}, click_behavior: {},
}; };
if (isNumber(column)) { if (isNumber(column)) {
settings["show_mini_bar"] = { settings["show_mini_bar"] = {
title: t`Show a mini bar chart`, title: t`Show a mini bar chart`,
...@@ -250,7 +254,7 @@ export default class Table extends Component { ...@@ -250,7 +254,7 @@ export default class Table extends Component {
settings["view_as"] !== "link" && settings["view_as"] !== "email_link", settings["view_as"] !== "link" && settings["view_as"] !== "email_link",
readDependencies: ["view_as"], readDependencies: ["view_as"],
getProps: ( getProps: (
col, column,
settings, settings,
onChange, onChange,
{ {
...@@ -276,7 +280,7 @@ export default class Table extends Component { ...@@ -276,7 +280,7 @@ export default class Table extends Component {
getHidden: (_, settings) => settings["view_as"] !== "link", getHidden: (_, settings) => settings["view_as"] !== "link",
readDependencies: ["view_as"], readDependencies: ["view_as"],
getProps: ( getProps: (
col, column,
settings, settings,
onChange, onChange,
{ {
...@@ -297,19 +301,16 @@ export default class Table extends Component { ...@@ -297,19 +301,16 @@ export default class Table extends Component {
return settings; return settings;
}; };
constructor(props) { state: TableState = {
super(props); data: null,
question: null,
this.state = { };
data: null,
};
}
UNSAFE_componentWillMount() { UNSAFE_componentWillMount() {
this._updateData(this.props); this._updateData(this.props);
} }
UNSAFE_componentWillReceiveProps(newProps) { UNSAFE_componentWillReceiveProps(newProps: VisualizationProps) {
if ( if (
newProps.series !== this.props.series || newProps.series !== this.props.series ||
!_.isEqual(newProps.settings, this.props.settings) !_.isEqual(newProps.settings, this.props.settings)
...@@ -318,7 +319,7 @@ export default class Table extends Component { ...@@ -318,7 +319,7 @@ export default class Table extends Component {
} }
} }
_updateData({ series, settings, metadata }) { _updateData({ series, settings, metadata }: VisualizationProps) {
const [{ card, data }] = series; const [{ card, data }] = series;
if (Table.isPivoted(series, settings)) { if (Table.isPivoted(series, settings)) {
...@@ -335,18 +336,12 @@ export default class Table extends Component { ...@@ -335,18 +336,12 @@ export default class Table extends Component {
(col, index) => index !== pivotIndex && index !== cellIndex, (col, index) => index !== pivotIndex && index !== cellIndex,
); );
this.setState({ this.setState({
data: DataGrid.pivot( data: DataGrid.pivot(data, normalIndex, pivotIndex, cellIndex),
data,
normalIndex,
pivotIndex,
cellIndex,
settings,
),
}); });
} else { } else {
const { cols, rows, results_timezone } = data; const { cols, rows, results_timezone } = data;
const columnSettings = settings["table.columns"]; const columnSettings = settings["table.columns"];
const columnIndexes = columnSettings const columnIndexes = (columnSettings || [])
.filter( .filter(
columnSetting => columnSetting =>
columnSetting.enabled || this.props.isShowingDetailsOnlyColumns, columnSetting.enabled || this.props.isShowingDetailsOnlyColumns,
...@@ -362,6 +357,7 @@ export default class Table extends Component { ...@@ -362,6 +357,7 @@ export default class Table extends Component {
rows: rows.map(row => columnIndexes.map(i => row[i])), rows: rows.map(row => columnIndexes.map(i => row[i])),
results_timezone, results_timezone,
}, },
// construct a Question that is in-sync with query results // construct a Question that is in-sync with query results
// cache it here for performance reasons // cache it here for performance reasons
question: new Question(card, metadata), question: new Question(card, metadata),
...@@ -371,7 +367,7 @@ export default class Table extends Component { ...@@ -371,7 +367,7 @@ export default class Table extends Component {
// shared helpers for table implementations // shared helpers for table implementations
getColumnTitle = columnIndex => { getColumnTitle = (columnIndex: number) => {
const cols = this.state.data && this.state.data.cols; const cols = this.state.data && this.state.data.cols;
if (!cols) { if (!cols) {
return null; return null;
...@@ -380,7 +376,7 @@ export default class Table extends Component { ...@@ -380,7 +376,7 @@ export default class Table extends Component {
return getTitleForColumn(cols[columnIndex], series, settings); return getTitleForColumn(cols[columnIndex], series, settings);
}; };
getColumnSortDirection = columnIndex => { getColumnSortDirection = (columnIndex: number) => {
const { question, data } = this.state; const { question, data } = this.state;
if (!question || !data) { if (!question || !data) {
return; return;
...@@ -410,7 +406,7 @@ export default class Table extends Component { ...@@ -410,7 +406,7 @@ export default class Table extends Component {
const { series, isDashboard, settings } = this.props; const { series, isDashboard, settings } = this.props;
const { data } = this.state; const { data } = this.state;
const isPivoted = Table.isPivoted(series, settings); const isPivoted = Table.isPivoted(series, settings);
const areAllColumnsHidden = data.cols.length === 0; const areAllColumnsHidden = data?.cols.length === 0;
const TableComponent = isDashboard ? TableSimple : TableInteractive; const TableComponent = isDashboard ? TableSimple : TableInteractive;
if (!data) { if (!data) {
...@@ -450,3 +446,6 @@ export default class Table extends Component { ...@@ -450,3 +446,6 @@ export default class Table extends Component {
); );
} }
} }
// eslint-disable-next-line import/no-default-export
export default Table;
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