From d7b1fd75e367dc775c8de7bf2c423d7028170a72 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 7 Mar 2019 16:52:20 -0800 Subject: [PATCH] move to grafana/ui --- .../src/components/DataTable/DataTable.tsx | 186 ++++++++++ .../components/DataTable}/renderer.test.ts | 327 +++++++++--------- .../src/components/DataTable}/renderer.tsx | 62 ++-- .../grafana-ui/src/utils/processTimeSeries.ts | 23 +- public/app/plugins/panel/table/renderer.ts | 8 +- .../app/plugins/panel/table2/TablePanel.tsx | 121 +------ .../plugins/panel/table2/TablePanelEditor.tsx | 11 +- public/app/plugins/panel/table2/sortable.tsx | 25 -- public/app/plugins/panel/table2/types.ts | 28 +- 9 files changed, 409 insertions(+), 382 deletions(-) create mode 100644 packages/grafana-ui/src/components/DataTable/DataTable.tsx rename {public/app/plugins/panel/table2/specs => packages/grafana-ui/src/components/DataTable}/renderer.test.ts (67%) rename {public/app/plugins/panel/table2 => packages/grafana-ui/src/components/DataTable}/renderer.tsx (83%) delete mode 100644 public/app/plugins/panel/table2/sortable.tsx diff --git a/packages/grafana-ui/src/components/DataTable/DataTable.tsx b/packages/grafana-ui/src/components/DataTable/DataTable.tsx new file mode 100644 index 00000000000..a14522fd10f --- /dev/null +++ b/packages/grafana-ui/src/components/DataTable/DataTable.tsx @@ -0,0 +1,186 @@ +// Libraries +import React, { Component, ReactNode } from 'react'; +import { + Table, + SortDirectionType, + SortIndicator, + Column, + TableHeaderProps, + TableCellProps, + Index, +} from 'react-virtualized'; +import { Themeable } from '../../types/theme'; + +import { sortTableData } from '../../utils/processTimeSeries'; + +// Types +import { TableData, InterpolateFunction } from '../../types/index'; +import { TableRenderer } from './renderer'; + +// Made to match the existing (untyped) settings in the angular table +export interface ColumnStyle { + pattern?: string; + + alias?: string; + colorMode?: string; + colors?: any[]; + decimals?: number; + thresholds?: any[]; + type?: 'date' | 'number' | 'string' | 'hidden'; + unit?: string; + dateFormat?: string; + sanitize?: boolean; + mappingType?: any; + valueMaps?: any; + rangeMaps?: any; + + link?: any; + linkUrl?: any; + linkTooltip?: any; + linkTargetBlank?: boolean; + + preserveFormat?: boolean; +} + +interface Props extends Themeable { + data?: TableData; + showHeader: boolean; + styles: ColumnStyle[]; + replaceVariables: InterpolateFunction; + width: number; + height: number; +} + +interface State { + sortBy?: number; + sortDirection?: SortDirectionType; + data?: TableData; +} + +export class DataTable extends Component { + renderer: TableRenderer; + + static defaultProps = { + showHeader: true, + }; + + constructor(props: Props) { + super(props); + + this.state = { + data: props.data, + }; + + this.renderer = this.createRenderer(); + } + + componentDidUpdate(prevProps: Props, prevState: State) { + const { data, styles } = this.props; + const { sortBy, sortDirection } = this.state; + const dataChanged = data !== prevProps.data; + + // Update the renderer if options change + if (dataChanged || styles !== prevProps.styles) { + this.renderer = this.createRenderer(); + } + + // Update the data when data or sort changes + if (dataChanged || sortBy !== prevState.sortBy || sortDirection !== prevState.sortDirection) { + this.setState({ data: sortTableData(data, sortBy, sortDirection === 'DESC') }); + } + } + + // styles: ColumnStyle[], + // schema: Column[], + // rowGetter: (info: Index) => any[], // matches the table rowGetter + // replaceVariables: InterpolateFunction, + // isUTC?: boolean, // TODO? get UTC from props? + // theme?: GrafanaThemeType | undefined, + + createRenderer(): TableRenderer { + const { styles, replaceVariables, theme } = this.props; + const { data } = this.state; + + return new TableRenderer({ + styles, + schema: data ? data.columns : [], + rowGetter: this.rowGetter, + replaceVariables, + isUTC: false, + theme: theme.type, + }); + } + + rowGetter = ({ index }: Index) => { + return this.state.data!.rows[index]; + }; + + doSort = (info: any) => { + let dir = info.sortDirection; + let sort = info.sortBy; + if (sort !== this.state.sortBy) { + dir = 'DESC'; + } else if (dir === 'DESC') { + dir = 'ASC'; + } else { + sort = null; + } + this.setState({ sortBy: sort, sortDirection: dir }); + }; + + headerRenderer = (header: TableHeaderProps): ReactNode => { + const dataKey = header.dataKey as any; // types say string, but it is number! + const { data, sortBy, sortDirection } = this.state; + const col = data!.columns[dataKey]; + + return ( +
+ {col.text} {sortBy === dataKey && } +
+ ); + }; + + cellRenderer = (cell: TableCellProps) => { + const { columnIndex, rowIndex } = cell; + const row = this.state.data!.rows[rowIndex]; + const val = row[columnIndex]; + return this.renderer.renderCell(columnIndex, rowIndex, val); + }; + + render() { + const { width, height, showHeader } = this.props; + const { data } = this.props; + if (!data) { + return
NO Data
; + } + return ( + + {data.columns.map((col, index) => { + return ( + + ); + })} +
+ ); + } +} + +export default DataTable; diff --git a/public/app/plugins/panel/table2/specs/renderer.test.ts b/packages/grafana-ui/src/components/DataTable/renderer.test.ts similarity index 67% rename from public/app/plugins/panel/table2/specs/renderer.test.ts rename to packages/grafana-ui/src/components/DataTable/renderer.test.ts index bbc57d99f2f..fdb7dc49e4d 100644 --- a/public/app/plugins/panel/table2/specs/renderer.test.ts +++ b/packages/grafana-ui/src/components/DataTable/renderer.test.ts @@ -2,10 +2,11 @@ import _ from 'lodash'; import TableModel from 'app/core/table_model'; import { getColorDefinitionByName } from '@grafana/ui'; -import { Options } from '../types'; -import { PanelProps, LoadingState } from '@grafana/ui/src/types'; +import { ScopedVars } from '@grafana/ui/src/types'; import moment from 'moment'; -import { TableRenderer } from '../renderer'; +import { TableRenderer } from './renderer'; +import { Index } from 'react-virtualized'; +import { ColumnStyle } from './DataTable'; // TODO: this is commented out with *x* describe! // Essentially all the elements need to replace the with
@@ -33,179 +34,161 @@ xdescribe('when rendering table', () => { [1388556366666, 1230, 40, undefined, '', '', 'my.host.com', 'host1', ['value1', 'value2'], 1, 2, 1, 2], ]; - const panel: Options = { - showHeader: true, - pageSize: 10, - styles: [ - { - pattern: 'Time', - type: 'date', - alias: 'Timestamp', - }, - { - pattern: '/(Val)ue/', - type: 'number', - unit: 'ms', - decimals: 3, - alias: '$1', - }, - { - pattern: 'Colored', - type: 'number', - unit: 'none', - decimals: 1, - colorMode: 'value', - thresholds: [50, 80], - colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], - }, - { - pattern: 'String', - type: 'string', - }, - { - pattern: 'String', - type: 'string', - }, - { - pattern: 'United', - type: 'number', - unit: 'ms', - decimals: 2, - }, - { - pattern: 'Sanitized', - type: 'string', - sanitize: true, - }, - { - pattern: 'Link', - type: 'string', - link: true, - linkUrl: '/dashboard?param=$__cell¶m_1=$__cell_1¶m_2=$__cell_2', - linkTooltip: '$__cell $__cell_1 $__cell_6', - linkTargetBlank: true, - }, - { - pattern: 'Array', - type: 'number', - unit: 'ms', - decimals: 3, - }, - { - pattern: 'Mapping', - type: 'string', - mappingType: 1, - valueMaps: [ - { - value: '1', - text: 'on', - }, - { - value: '0', - text: 'off', - }, - { - value: 'HELLO WORLD', - text: 'HELLO GRAFANA', - }, - { - value: 'value1, value2', - text: 'value3, value4', - }, - ], - }, - { - pattern: 'RangeMapping', - type: 'string', - mappingType: 2, - rangeMaps: [ - { - from: '1', - to: '3', - text: 'on', - }, - { - from: '3', - to: '6', - text: 'off', - }, - ], - }, - { - pattern: 'MappingColored', - type: 'string', - mappingType: 1, - valueMaps: [ - { - value: '1', - text: 'on', - }, - { - value: '0', - text: 'off', - }, - ], - colorMode: 'value', - thresholds: [1, 2], - colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], - }, - { - pattern: 'RangeMappingColored', - type: 'string', - mappingType: 2, - rangeMaps: [ - { - from: '1', - to: '3', - text: 'on', - }, - { - from: '3', - to: '6', - text: 'off', - }, - ], - colorMode: 'value', - thresholds: [2, 5], - colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], - }, - ], - }; + const styles: ColumnStyle[] = [ + { + pattern: 'Time', + type: 'date', + alias: 'Timestamp', + }, + { + pattern: '/(Val)ue/', + type: 'number', + unit: 'ms', + decimals: 3, + alias: '$1', + }, + { + pattern: 'Colored', + type: 'number', + unit: 'none', + decimals: 1, + colorMode: 'value', + thresholds: [50, 80], + colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], + }, + { + pattern: 'String', + type: 'string', + }, + { + pattern: 'String', + type: 'string', + }, + { + pattern: 'United', + type: 'number', + unit: 'ms', + decimals: 2, + }, + { + pattern: 'Sanitized', + type: 'string', + sanitize: true, + }, + { + pattern: 'Link', + type: 'string', + link: true, + linkUrl: '/dashboard?param=$__cell¶m_1=$__cell_1¶m_2=$__cell_2', + linkTooltip: '$__cell $__cell_1 $__cell_6', + linkTargetBlank: true, + }, + { + pattern: 'Array', + type: 'number', + unit: 'ms', + decimals: 3, + }, + { + pattern: 'Mapping', + type: 'string', + mappingType: 1, + valueMaps: [ + { + value: '1', + text: 'on', + }, + { + value: '0', + text: 'off', + }, + { + value: 'HELLO WORLD', + text: 'HELLO GRAFANA', + }, + { + value: 'value1, value2', + text: 'value3, value4', + }, + ], + }, + { + pattern: 'RangeMapping', + type: 'string', + mappingType: 2, + rangeMaps: [ + { + from: '1', + to: '3', + text: 'on', + }, + { + from: '3', + to: '6', + text: 'off', + }, + ], + }, + { + pattern: 'MappingColored', + type: 'string', + mappingType: 1, + valueMaps: [ + { + value: '1', + text: 'on', + }, + { + value: '0', + text: 'off', + }, + ], + colorMode: 'value', + thresholds: [1, 2], + colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], + }, + { + pattern: 'RangeMappingColored', + type: 'string', + mappingType: 2, + rangeMaps: [ + { + from: '1', + to: '3', + text: 'on', + }, + { + from: '3', + to: '6', + text: 'off', + }, + ], + colorMode: 'value', + thresholds: [2, 5], + colors: ['#00ff00', SemiDarkOrange.name, 'rgb(1,0,0)'], + }, + ]; // const sanitize = value => { // return 'sanitized'; // }; - const props: PanelProps = { - panelData: { - tableData: table, - }, - width: 100, - height: 100, - timeRange: { - from: moment(), - to: moment(), - raw: { - from: moment(), - to: moment(), - }, - }, - loading: LoadingState.Done, - replaceVariables: (value, scopedVars) => { - if (scopedVars) { - // For testing variables replacement in link - _.each(scopedVars, (val, key) => { - value = value.replace('$' + key, val.value); - }); - } - return value; - }, - renderCounter: 1, - options: panel, + const replaceVariables = (value: any, scopedVars: ScopedVars | undefined) => { + if (scopedVars) { + // For testing variables replacement in link + _.each(scopedVars, (val, key) => { + value = value.replace('$' + key, val.value); + }); + } + return value; }; - const rowGetter = ({ index }) => table.rows[index]; - const renderer = new TableRenderer(panel.styles, table.columns, rowGetter, props.replaceVariables); - renderer.setTheme(null); + const rowGetter = ({ index }: Index) => table.rows[index]; + const renderer = new TableRenderer({ + styles, + schema: table.columns, + rowGetter, + replaceVariables, + }); it('time column should be formated', () => { const html = renderer.renderCell(0, 0, 1388556366666); @@ -314,7 +297,7 @@ xdescribe('when rendering table', () => { `; - expect(normalize(html)).toBe(normalize(expectedHtml)); + expect(normalize(html + '')).toBe(normalize(expectedHtml)); }); it('Array column should not use number as formatter', () => { @@ -404,6 +387,6 @@ xdescribe('when rendering table', () => { }); }); -function normalize(str) { +function normalize(str: string) { return str.replace(/\s+/gm, ' ').trim(); } diff --git a/public/app/plugins/panel/table2/renderer.tsx b/packages/grafana-ui/src/components/DataTable/renderer.tsx similarity index 83% rename from public/app/plugins/panel/table2/renderer.tsx rename to packages/grafana-ui/src/components/DataTable/renderer.tsx index f05ada55645..fb6263fd4d7 100644 --- a/public/app/plugins/panel/table2/renderer.tsx +++ b/packages/grafana-ui/src/components/DataTable/renderer.tsx @@ -8,33 +8,35 @@ import { sanitize } from 'app/core/utils/text'; // Types import kbn from 'app/core/utils/kbn'; import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType, InterpolateFunction, Column } from '@grafana/ui'; -import { Style } from './types'; import { Index } from 'react-virtualized'; +import { ColumnStyle } from './DataTable'; -type CellFormatter = (v: any, style: Style) => string; +type CellFormatter = (v: any, style?: ColumnStyle) => string | undefined; interface ColumnInfo { header: string; accessor: string; // the field name - style?: Style; + style?: ColumnStyle; hidden?: boolean; formatter: CellFormatter; filterable?: boolean; } -export class TableRenderer { - isUTC: false; // TODO? get UTC from props? +interface RendererOptions { + styles: ColumnStyle[]; + schema: Column[]; + rowGetter: (info: Index) => any[]; // matches the table rowGetter + replaceVariables: InterpolateFunction; + isUTC?: boolean; // TODO? get UTC from props? + theme?: GrafanaThemeType | undefined; +} +export class TableRenderer { columns: ColumnInfo[]; colorState: any; - theme?: GrafanaThemeType; - constructor( - styles: Style[], - schema: Column[], - private rowGetter: (info: Index) => any[], // matches the table rowGetter - private replaceVariables: InterpolateFunction - ) { + constructor(private options: RendererOptions) { + const { schema, styles } = options; this.colorState = {}; if (!schema) { @@ -42,10 +44,11 @@ export class TableRenderer { return; } - this.columns = schema.map((col, index) => { + this.columns = options.schema.map((col, index) => { let title = col.text; - let style: Style = null; + let style; // ColumnStyle + // Find the style based on the text for (let i = 0; i < styles.length; i++) { const s = styles[i]; const regex = kbn.stringToJsRegex(s.pattern); @@ -62,28 +65,24 @@ export class TableRenderer { header: title, accessor: col.text, // unique? style: style, - formatter: this.createColumnFormatter(style, col), + formatter: this.createColumnFormatter(col, style), }; }); } - setTheme(theme: GrafanaThemeType) { - this.theme = theme; - } - - getColorForValue(value, style: Style) { + getColorForValue(value: any, style: ColumnStyle) { if (!style.thresholds) { return null; } for (let i = style.thresholds.length; i > 0; i--) { if (value >= style.thresholds[i - 1]) { - return getColorFromHexRgbOrName(style.colors[i], this.theme); + return getColorFromHexRgbOrName(style.colors![i], this.options.theme); } } - return getColorFromHexRgbOrName(_.first(style.colors), this.theme); + return getColorFromHexRgbOrName(_.first(style.colors), this.options.theme); } - defaultCellFormatter(v: any, style: Style): string { + defaultCellFormatter(v: any, style?: ColumnStyle): string { if (v === null || v === void 0 || v === undefined) { return ''; } @@ -99,7 +98,7 @@ export class TableRenderer { } } - createColumnFormatter(style: Style, header: any): CellFormatter { + createColumnFormatter(header: Column, style?: ColumnStyle): CellFormatter { if (!style) { return this.defaultCellFormatter; } @@ -120,7 +119,7 @@ export class TableRenderer { v = v[0]; } let date = moment(v); - if (this.isUTC) { + if (this.options.isUTC) { date = date.utc(); } return date.format(style.dateFormat); @@ -203,7 +202,7 @@ export class TableRenderer { }; } - setColorState(value: any, style: Style) { + setColorState(value: any, style: ColumnStyle) { if (!style.colorMode) { return; } @@ -220,8 +219,8 @@ export class TableRenderer { } renderRowVariables(rowIndex: number) { - const scopedVars = {}; - const row = this.rowGetter({ index: rowIndex }); + const scopedVars: any = {}; + const row = this.options.rowGetter({ index: rowIndex }); for (let i = 0; i < row.length; i++) { scopedVars[`__cell_${i}`] = { value: row[i] }; } @@ -261,11 +260,12 @@ export class TableRenderer { let columnHtml: JSX.Element; if (column.style && column.style.link) { // Render cell as link + const { replaceVariables } = this.options; const scopedVars = this.renderRowVariables(rowIndex); scopedVars['__cell'] = { value: value }; - const cellLink = this.replaceVariables(column.style.linkUrl, scopedVars, encodeURIComponent); - const cellLinkTooltip = this.replaceVariables(column.style.linkTooltip, scopedVars); + const cellLink = replaceVariables(column.style.linkUrl, scopedVars, encodeURIComponent); + const cellLinkTooltip = replaceVariables(column.style.linkTooltip, scopedVars); const cellTarget = column.style.linkTargetBlank ? '_blank' : ''; cellClasses.push('table-panel-cell-link'); @@ -284,7 +284,7 @@ export class TableRenderer { columnHtml = {value}; } - let filterLink: JSX.Element; + let filterLink: JSX.Element | null = null; if (column.filterable) { cellClasses.push('table-panel-cell-filterable'); filterLink = ( diff --git a/packages/grafana-ui/src/utils/processTimeSeries.ts b/packages/grafana-ui/src/utils/processTimeSeries.ts index f5e9f96efba..08872648f44 100644 --- a/packages/grafana-ui/src/utils/processTimeSeries.ts +++ b/packages/grafana-ui/src/utils/processTimeSeries.ts @@ -4,7 +4,7 @@ import isNumber from 'lodash/isNumber'; import { colors } from './colors'; // Types -import { TimeSeries, TimeSeriesVMs, NullValueMode, TimeSeriesValue } from '../types'; +import { TimeSeries, TableData, TimeSeriesVMs, NullValueMode, TimeSeriesValue } from '../types'; interface Options { timeSeries: TimeSeries[]; @@ -173,3 +173,24 @@ export function processTimeSeries({ timeSeries, nullValueMode }: Options): TimeS return vmSeries; } + +export function sortTableData(data?: TableData, sortIndex?: number, reverse = false): TableData { + if (data && isNumber(sortIndex)) { + const copy = { + ...data, + rows: [...data.rows].sort((a, b) => { + a = a[sortIndex]; + b = b[sortIndex]; + // Sort null or undefined separately from comparable values + return +(a == null) - +(b == null) || +(a > b) || -(a < b); + }), + }; + + if (reverse) { + copy.rows.reverse(); + } + + return copy; + } + return data; +} diff --git a/public/app/plugins/panel/table/renderer.ts b/public/app/plugins/panel/table/renderer.ts index b77bea5bd46..ffb8f89b972 100644 --- a/public/app/plugins/panel/table/renderer.ts +++ b/public/app/plugins/panel/table/renderer.ts @@ -2,7 +2,7 @@ import _ from 'lodash'; import moment from 'moment'; import kbn from 'app/core/utils/kbn'; import { getValueFormat, getColorFromHexRgbOrName, GrafanaThemeType } from '@grafana/ui'; -import { Style } from '../table2/types'; +import { ColumnStyle } from '@grafana/ui/src/components/DataTable/DataTable'; export class TableRenderer { formatters: any[]; @@ -52,7 +52,7 @@ export class TableRenderer { } } - getColorForValue(value, style: Style) { + getColorForValue(value, style: ColumnStyle) { if (!style.thresholds) { return null; } @@ -64,7 +64,7 @@ export class TableRenderer { return getColorFromHexRgbOrName(_.first(style.colors), this.theme); } - defaultCellFormatter(v, style: Style) { + defaultCellFormatter(v, style: ColumnStyle) { if (v === null || v === void 0 || v === undefined) { return ''; } @@ -191,7 +191,7 @@ export class TableRenderer { }; } - setColorState(value, style: Style) { + setColorState(value, style: ColumnStyle) { if (!style.colorMode) { return; } diff --git a/public/app/plugins/panel/table2/TablePanel.tsx b/public/app/plugins/panel/table2/TablePanel.tsx index bca3c350bbb..de4648f2c8b 100644 --- a/public/app/plugins/panel/table2/TablePanel.tsx +++ b/public/app/plugins/panel/table2/TablePanel.tsx @@ -1,136 +1,29 @@ // Libraries import _ from 'lodash'; -import React, { Component, ReactNode } from 'react'; +import React, { Component } from 'react'; // Types -import { PanelProps, ThemeContext, TableData } from '@grafana/ui'; +import { PanelProps, ThemeContext } from '@grafana/ui'; import { Options } from './types'; -import { Table, SortDirectionType, SortIndicator, Column, TableHeaderProps, TableCellProps } from 'react-virtualized'; - -import { TableRenderer } from './renderer'; -import { sortTableData } from './sortable'; +import DataTable from '@grafana/ui/src/components/DataTable/DataTable'; interface Props extends PanelProps {} -interface State { - sortBy?: number; - sortDirection?: SortDirectionType; - data: TableData; -} - -export class TablePanel extends Component { - renderer: TableRenderer; - +export class TablePanel extends Component { constructor(props: Props) { super(props); - - const { panelData, options, replaceVariables } = this.props; - - this.state = { - data: panelData.tableData, - }; - - this.renderer = new TableRenderer(options.styles, this.state.data.columns, this.rowGetter, replaceVariables); } - componentDidUpdate(prevProps: Props, prevState: State) { - const { panelData, options } = this.props; - const { sortBy, sortDirection } = this.state; - - // Update the renderer if options change - if (options !== prevProps.options) { - this.renderer = new TableRenderer( - options.styles, - this.state.data.columns, - this.rowGetter, - this.props.replaceVariables - ); - } - - // Update the data when data or sort changes - if (panelData !== prevProps.panelData || sortBy !== prevState.sortBy || sortDirection !== prevState.sortDirection) { - const data = sortTableData(panelData.tableData, sortBy, sortDirection === 'DESC'); - this.setState({ data }); - } - } - - rowGetter = ({ index }) => { - return this.state.data.rows[index]; - }; - - doSort = ({ sortBy }) => { - let sortDirection = this.state.sortDirection; - if (sortBy !== this.state.sortBy) { - sortDirection = 'DESC'; - } else if (sortDirection === 'DESC') { - sortDirection = 'ASC'; - } else { - sortBy = null; - } - - this.setState({ sortBy, sortDirection }); - }; - - headerRenderer = (header: TableHeaderProps): ReactNode => { - const dataKey = header.dataKey as any; // types say string, but it is number! - const { data, sortBy, sortDirection } = this.state; - const col = data.columns[dataKey]; - - return ( -
- {col.text} {sortBy === dataKey && } -
- ); - }; - - cellRenderer = (cell: TableCellProps) => { - const { columnIndex, rowIndex } = cell; - const row = this.state.data.rows[rowIndex]; - const val = row[columnIndex]; - return this.renderer.renderCell(columnIndex, rowIndex, val); - }; - render() { - const { width, height, options } = this.props; - const { showHeader } = options; - // const { sortBy, sortDirection } = this.state; - const { data } = this.state; + const { panelData, options } = this.props; - if (!data) { + if (!panelData || !panelData.tableData) { return
No Table Data...
; } return ( - {( - theme // ??? { this.renderer.setTheme(theme) } - ) => ( - - {data.columns.map((col, index) => { - return ( - - ); - })} -
- )} + {theme => }
); } diff --git a/public/app/plugins/panel/table2/TablePanelEditor.tsx b/public/app/plugins/panel/table2/TablePanelEditor.tsx index fc899bd22d2..60d2eff9b85 100644 --- a/public/app/plugins/panel/table2/TablePanelEditor.tsx +++ b/public/app/plugins/panel/table2/TablePanelEditor.tsx @@ -3,7 +3,7 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; // Types -import { PanelEditorProps, Switch, FormField } from '@grafana/ui'; +import { PanelEditorProps, Switch } from '@grafana/ui'; import { Options } from './types'; export class TablePanelEditor extends PureComponent> { @@ -11,10 +11,8 @@ export class TablePanelEditor extends PureComponent> { this.props.onOptionsChange({ ...this.props.options, showHeader: !this.props.options.showHeader }); }; - onRowsPerPageChange = ({ target }) => this.props.onOptionsChange({ ...this.props.options, pageSize: target.value }); - render() { - const { showHeader, pageSize } = this.props.options; + const { showHeader } = this.props.options; return (
@@ -22,11 +20,6 @@ export class TablePanelEditor extends PureComponent> {
Header
- -
-
Paging
- -
); } diff --git a/public/app/plugins/panel/table2/sortable.tsx b/public/app/plugins/panel/table2/sortable.tsx deleted file mode 100644 index 24253b54708..00000000000 --- a/public/app/plugins/panel/table2/sortable.tsx +++ /dev/null @@ -1,25 +0,0 @@ -// Libraries -import isNumber from 'lodash/isNumber'; - -import { TableData } from '@grafana/ui'; - -export function sortTableData(data: TableData, sortIndex?: number, reverse = false): TableData { - if (isNumber(sortIndex)) { - const copy = { - ...data, - rows: [...data.rows].sort((a, b) => { - a = a[sortIndex]; - b = b[sortIndex]; - // Sort null or undefined separately from comparable values - return +(a == null) - +(b == null) || +(a > b) || -(a < b); - }), - }; - - if (reverse) { - copy.rows.reverse(); - } - - return copy; - } - return data; -} diff --git a/public/app/plugins/panel/table2/types.ts b/public/app/plugins/panel/table2/types.ts index c0a3b2c8561..0935a0878c9 100644 --- a/public/app/plugins/panel/table2/types.ts +++ b/public/app/plugins/panel/table2/types.ts @@ -1,31 +1,8 @@ -// Made to match the existing (untyped) settings in the angular table -export interface Style { - alias?: string; - colorMode?: string; - colors?: any[]; - decimals?: number; - pattern?: string; - thresholds?: any[]; - type?: 'date' | 'number' | 'string' | 'hidden'; - unit?: string; - dateFormat?: string; - sanitize?: boolean; - mappingType?: any; - valueMaps?: any; - rangeMaps?: any; - - link?: any; - linkUrl?: any; - linkTooltip?: any; - linkTargetBlank?: boolean; - - preserveFormat?: boolean; -} +import { ColumnStyle } from '@grafana/ui/src/components/DataTable/DataTable'; export interface Options { showHeader: boolean; - styles: Style[]; - pageSize: number; + styles: ColumnStyle[]; } export const defaults: Options = { @@ -48,5 +25,4 @@ export const defaults: Options = { thresholds: [], }, ], - pageSize: 100, };