diff --git a/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx b/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx index abb33d98a60..99ba69f3759 100644 --- a/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx +++ b/packages/grafana-ui/src/components/Table/BarGaugeCell.tsx @@ -18,11 +18,7 @@ const defaultScale: ThresholdsConfig = { }; export const BarGaugeCell: FC = props => { - const { field, column, tableStyles, cell } = props; - - if (!field.display) { - return null; - } + const { field, column, tableStyles, cell, cellProps } = props; let { config } = field; if (!config.thresholds) { @@ -32,7 +28,7 @@ export const BarGaugeCell: FC = props => { }; } - const displayValue = field.display(cell.value); + const displayValue = field.display!(cell.value); let barGaugeMode = BarGaugeDisplayMode.Gradient; if (field.config.custom && field.config.custom.displayMode === TableCellDisplayMode.LcdGauge) { @@ -49,7 +45,7 @@ export const BarGaugeCell: FC = props => { } return ( -
+
= props => { - const { field, cell, tableStyles, row } = props; - let link: LinkModel | undefined; + const { field, cell, tableStyles, row, cellProps } = props; - const displayValue = field.display ? field.display(cell.value) : cell.value; + const displayValue = field.display!(cell.value); + const value = formattedValueToString(displayValue); + const cellStyle = getCellStyle(tableStyles, field, displayValue); + const showFilters = field.config.filterable; + + let link: LinkModel | undefined; + let onClick: MouseEventHandler | undefined; if (field.getLinks) { link = field.getLinks({ valueRowIndex: row.index, })[0]; } - const value = field.display ? formattedValueToString(displayValue) : `${displayValue}`; - if (!link) { - return
{value}
; + if (link && link.onClick) { + onClick = event => { + // Allow opening in new tab + if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) { + event.preventDefault(); + link!.onClick(event); + } + }; } return ( -
- { - // Allow opening in new tab - if (!(event.ctrlKey || event.metaKey || event.shiftKey) && link!.onClick) { - event.preventDefault(); - link!.onClick(event); - } - } - : undefined - } - target={link.target} - title={link.title} - className={tableStyles.tableCellLink} - > - {value} - +
+ {!link &&
{value}
} + {link && ( + + {value} + + )} + {showFilters && cell.value && }
); }; + +function getCellStyle(tableStyles: TableStyles, field: Field, displayValue: DisplayValue) { + if (field.config.custom?.displayMode === TableCellDisplayMode.ColorText) { + return tableStyles.buildCellContainerStyle(displayValue.color); + } + + if (field.config.custom?.displayMode === TableCellDisplayMode.ColorBackground) { + const themeFactor = tableStyles.theme.isDark ? 1 : -0.7; + const bgColor2 = tinycolor(displayValue.color) + .darken(10 * themeFactor) + .spin(5) + .toRgbString(); + + return tableStyles.buildCellContainerStyle('white', `linear-gradient(120deg, ${bgColor2}, ${displayValue.color})`); + } + + return tableStyles.cellContainer; +} diff --git a/packages/grafana-ui/src/components/Table/FilterActions.tsx b/packages/grafana-ui/src/components/Table/FilterActions.tsx new file mode 100644 index 00000000000..21dc07dab90 --- /dev/null +++ b/packages/grafana-ui/src/components/Table/FilterActions.tsx @@ -0,0 +1,31 @@ +import React, { FC, useCallback } from 'react'; +import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableCellProps } from './types'; +import { Icon, Tooltip } from '..'; + +export const FilterActions: FC = ({ cell, field, tableStyles, onCellFilterAdded }) => { + const onFilterFor = useCallback( + (event: React.MouseEvent) => + onCellFilterAdded({ key: field.name, operator: FILTER_FOR_OPERATOR, value: cell.value }), + [cell, field, onCellFilterAdded] + ); + const onFilterOut = useCallback( + (event: React.MouseEvent) => + onCellFilterAdded({ key: field.name, operator: FILTER_OUT_OPERATOR, value: cell.value }), + [cell, field, onCellFilterAdded] + ); + + return ( +
+
+ + + +
+
+ + + +
+
+ ); +}; diff --git a/packages/grafana-ui/src/components/Table/FilterableTableCell.tsx b/packages/grafana-ui/src/components/Table/FilterableTableCell.tsx deleted file mode 100644 index b15d98a8d13..00000000000 --- a/packages/grafana-ui/src/components/Table/FilterableTableCell.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { FC, useCallback, useState } from 'react'; -import { TableCellProps } from 'react-table'; -import { GrafanaTheme } from '@grafana/data'; -import { css } from 'emotion'; - -import { stylesFactory, useTheme } from '../../themes'; -import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableFilterActionCallback } from './types'; -import { Icon, Tooltip } from '..'; -import { Props, renderCell } from './TableCell'; - -interface FilterableTableCellProps extends Pick { - onCellFilterAdded: TableFilterActionCallback; - cellProps: TableCellProps; -} - -export const FilterableTableCell: FC = ({ - cell, - field, - tableStyles, - onCellFilterAdded, - cellProps, -}) => { - const [showFilters, setShowFilter] = useState(false); - const onMouseOver = useCallback((event: React.MouseEvent) => setShowFilter(true), [setShowFilter]); - const onMouseLeave = useCallback((event: React.MouseEvent) => setShowFilter(false), [setShowFilter]); - const onFilterFor = useCallback( - (event: React.MouseEvent) => - onCellFilterAdded({ key: field.name, operator: FILTER_FOR_OPERATOR, value: cell.value }), - [cell, field, onCellFilterAdded] - ); - const onFilterOut = useCallback( - (event: React.MouseEvent) => - onCellFilterAdded({ key: field.name, operator: FILTER_OUT_OPERATOR, value: cell.value }), - [cell, field, onCellFilterAdded] - ); - const theme = useTheme(); - const styles = getFilterableTableCellStyles(theme); - - return ( -
- {renderCell(cell, field, tableStyles)} - {showFilters && cell.value && ( -
-
- - - -
-
- - - -
-
- )} -
- ); -}; - -const getFilterableTableCellStyles = stylesFactory((theme: GrafanaTheme) => ({ - filterWrapper: css` - label: filterWrapper; - display: inline-flex; - justify-content: space-around; - cursor: pointer; - `, - filterItem: css` - label: filterItem; - color: ${theme.colors.textSemiWeak}; - padding: 0 ${theme.spacing.xxs}; - `, -})); diff --git a/packages/grafana-ui/src/components/Table/ImageCell.tsx b/packages/grafana-ui/src/components/Table/ImageCell.tsx new file mode 100644 index 00000000000..6ddfb318d02 --- /dev/null +++ b/packages/grafana-ui/src/components/Table/ImageCell.tsx @@ -0,0 +1,12 @@ +import React, { FC } from 'react'; +import { TableCellProps } from './types'; + +export const ImageCell: FC = props => { + const { cell, tableStyles, cellProps } = props; + + return ( +
+ +
+ ); +}; diff --git a/packages/grafana-ui/src/components/Table/JSONViewCell.tsx b/packages/grafana-ui/src/components/Table/JSONViewCell.tsx index 5e685e1f1eb..b93a44321ed 100644 --- a/packages/grafana-ui/src/components/Table/JSONViewCell.tsx +++ b/packages/grafana-ui/src/components/Table/JSONViewCell.tsx @@ -8,11 +8,7 @@ import { TableCellProps } from './types'; import { GrafanaTheme } from '@grafana/data'; export const JSONViewCell: FC = props => { - const { field, cell, tableStyles } = props; - - if (!field.display) { - return null; - } + const { cell, tableStyles, cellProps } = props; const txt = css` cursor: pointer; @@ -21,6 +17,7 @@ export const JSONViewCell: FC = props => { let value = cell.value; let displayValue = value; + if (isString(value)) { try { value = JSON.parse(value); @@ -28,11 +25,13 @@ export const JSONViewCell: FC = props => { } else { displayValue = JSON.stringify(value); } + const content = ; + return ( -
+
-
{displayValue}
+
{displayValue}
); diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index b46786631da..4dcdf18d632 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -14,7 +14,7 @@ import { useTable, } from 'react-table'; import { FixedSizeList } from 'react-window'; -import { getColumns, getHeaderAlign } from './utils'; +import { getColumns } from './utils'; import { useTheme } from '../../themes'; import { TableColumnResizeActionCallback, @@ -23,10 +23,10 @@ import { TableSortByFieldState, } from './types'; import { getTableStyles, TableStyles } from './styles'; -import { TableCell } from './TableCell'; import { Icon } from '../Icon/Icon'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { Filter } from './Filter'; +import { TableCell } from './TableCell'; const COLUMN_MIN_WIDTH = 150; @@ -229,7 +229,7 @@ function renderHeaderCell(column: any, tableStyles: TableStyles, field?: Field) } headerProps.style.position = 'absolute'; - headerProps.style.justifyContent = getHeaderAlign(field); + headerProps.style.justifyContent = (column as any).justifyContent; return (
diff --git a/packages/grafana-ui/src/components/Table/TableCell.tsx b/packages/grafana-ui/src/components/Table/TableCell.tsx index ae9796c4d8d..8a089fc3c51 100644 --- a/packages/grafana-ui/src/components/Table/TableCell.tsx +++ b/packages/grafana-ui/src/components/Table/TableCell.tsx @@ -1,11 +1,8 @@ import React, { FC } from 'react'; import { Cell } from 'react-table'; import { Field } from '@grafana/data'; - -import { getTextAlign } from './utils'; import { TableFilterActionCallback } from './types'; import { TableStyles } from './styles'; -import { FilterableTableCell } from './FilterableTableCell'; export interface Props { cell: Cell; @@ -15,31 +12,25 @@ export interface Props { } export const TableCell: FC = ({ cell, field, tableStyles, onCellFilterAdded }) => { - const filterable = field.config.filterable; const cellProps = cell.getCellProps(); - if (cellProps.style) { - cellProps.style.textAlign = getTextAlign(field); + if (!field.display) { + return null; } - if (filterable && onCellFilterAdded) { - return ( - - ); + if (cellProps.style) { + cellProps.style.minWidth = cellProps.style.width; + cellProps.style.justifyContent = (cell.column as any).justifyContent; } return ( -
- {renderCell(cell, field, tableStyles)} -
+ <> + {cell.render('Cell', { + field, + tableStyles, + onCellFilterAdded, + cellProps, + })} + ); }; - -export const renderCell = (cell: Cell, field: Field, tableStyles: TableStyles) => - cell.render('Cell', { field, tableStyles }); diff --git a/packages/grafana-ui/src/components/Table/styles.ts b/packages/grafana-ui/src/components/Table/styles.ts index 87b08c76d9d..6f17b7400dc 100644 --- a/packages/grafana-ui/src/components/Table/styles.ts +++ b/packages/grafana-ui/src/components/Table/styles.ts @@ -1,140 +1,163 @@ -import { css } from 'emotion'; +import { css, cx } from 'emotion'; import { GrafanaTheme } from '@grafana/data'; import { styleMixins, stylesFactory } from '../../themes'; import { getScrollbarWidth } from '../../utils'; -export interface TableStyles { - cellHeight: number; - cellHeightInner: number; - cellPadding: number; - rowHeight: number; - table: string; - thead: string; - headerCell: string; - headerCellLabel: string; - headerFilter: string; - tableCell: string; - tableCellWrapper: string; - tableCellLink: string; - row: string; - theme: GrafanaTheme; - resizeHandle: string; - overflow: string; -} +export const getTableStyles = stylesFactory((theme: GrafanaTheme) => { + const { palette, colors } = theme; + const headerBg = theme.colors.bg2; + const borderColor = theme.colors.border1; + const resizerColor = theme.isLight ? palette.blue95 : palette.blue77; + const cellPadding = 6; + const lineHeight = theme.typography.lineHeight.md; + const bodyFontSize = 14; + const cellHeight = cellPadding * 2 + bodyFontSize * lineHeight; + const rowHoverBg = styleMixins.hoverColor(theme.colors.bg1, theme); + const scollbarWidth = getScrollbarWidth(); -export const getTableStyles = stylesFactory( - (theme: GrafanaTheme): TableStyles => { - const { palette, colors } = theme; - const headerBg = theme.colors.bg2; - const borderColor = theme.colors.border1; - const resizerColor = theme.isLight ? palette.blue95 : palette.blue77; - const padding = 6; - const lineHeight = theme.typography.lineHeight.md; - const bodyFontSize = 14; - const cellHeight = padding * 2 + bodyFontSize * lineHeight; - const rowHoverBg = styleMixins.hoverColor(theme.colors.bg1, theme); - const scollbarWidth = getScrollbarWidth(); + const buildCellContainerStyle = (color?: string, background?: string) => { + return css` + padding: ${cellPadding}px; + width: 100%; + height: 100%; + display: flex; + align-items: center; + border-right: 1px solid ${borderColor}; - return { - theme, - cellHeight, - cellPadding: padding, - cellHeightInner: bodyFontSize * lineHeight, - rowHeight: cellHeight + 2, - table: css` - height: 100%; - width: 100%; - overflow: auto; - display: flex; - `, - thead: css` - label: thead; - height: ${cellHeight}px; - overflow-y: auto; - overflow-x: hidden; - background: ${headerBg}; - position: relative; - `, - headerCell: css` - padding: ${padding}px; - overflow: hidden; - white-space: nowrap; - color: ${colors.textBlue}; - border-right: 1px solid ${theme.colors.panelBg}; - display: flex; + ${color ? `color: ${color};` : ''}; + ${background ? `background: ${background};` : ''}; - &:last-child { - border-right: none; + &:last-child { + border-right: none; + + > div { + padding-right: ${scollbarWidth + cellPadding}px; } - `, - headerCellLabel: css` - cursor: pointer; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: flex; - margin-right: ${theme.spacing.xs}; - `, - headerFilter: css` - label: headerFilter; - cursor: pointer; - `, - row: css` - label: row; - border-bottom: 1px solid ${borderColor}; + } - &:hover { - background-color: ${rowHoverBg}; + &:hover { + overflow: visible; + width: auto !important; + box-shadow: 0 0 2px ${theme.colors.formFocusOutline}; + background: ${background ?? rowHoverBg}; + z-index: 1; + + .cell-filter-actions  { + display: inline-flex; } - `, - tableCellWrapper: css` - border-right: 1px solid ${borderColor}; - display: inline-flex; - align-items: center; - height: 100%; + } + `; + }; - &:last-child { - border-right: none; + return { + theme, + cellHeight, + buildCellContainerStyle, + cellPadding, + cellHeightInner: bodyFontSize * lineHeight, + rowHeight: cellHeight + 2, + table: css` + height: 100%; + width: 100%; + overflow: auto; + display: flex; + `, + thead: css` + label: thead; + height: ${cellHeight}px; + overflow-y: auto; + overflow-x: hidden; + background: ${headerBg}; + position: relative; + `, + headerCell: css` + padding: ${cellPadding}px; + overflow: hidden; + white-space: nowrap; + color: ${colors.textBlue}; + border-right: 1px solid ${theme.colors.panelBg}; + display: flex; - > div { - padding-right: ${scollbarWidth + padding}px; - } - } - `, - tableCellLink: css` - text-decoration: underline; - `, - tableCell: css` - padding: ${padding}px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - flex: 1; - `, - overflow: css` - overflow: hidden; - text-overflow: ellipsis; - `, - resizeHandle: css` - label: resizeHandle; - cursor: col-resize !important; - display: inline-block; - background: ${resizerColor}; - opacity: 0; - transition: opacity 0.2s ease-in-out; - width: 8px; - height: 100%; - position: absolute; - right: -4px; - border-radius: 3px; - top: 0; - z-index: ${theme.zIndex.dropdown}; - touch-action: none; + &:last-child { + border-right: none; + } + `, + headerCellLabel: css` + cursor: pointer; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: flex; + margin-right: ${theme.spacing.xs}; + `, + cellContainer: buildCellContainerStyle(), + cellText: css` + cursor: text; + overflow: hidden; + text-overflow: ellipsis; + user-select: text; + white-space: nowrap; + `, + cellLink: css` + cursor: pointer; + overflow: hidden; + text-overflow: ellipsis; + user-select: text; + white-space: nowrap; + text-decoration: underline; + `, + headerFilter: css` + label: headerFilter; + cursor: pointer; + `, + row: css` + label: row; + border-bottom: 1px solid ${borderColor}; - &:hover { - opacity: 1; - } + &:hover { + background-color: ${rowHoverBg}; + } + `, + imageCell: css` + height: 100%; + `, + resizeHandle: css` + label: resizeHandle; + cursor: col-resize !important; + display: inline-block; + background: ${resizerColor}; + opacity: 0; + transition: opacity 0.2s ease-in-out; + width: 8px; + height: 100%; + position: absolute; + right: -4px; + border-radius: 3px; + top: 0; + z-index: ${theme.zIndex.dropdown}; + touch-action: none; + + &:hover { + opacity: 1; + } + `, + filterWrapper: cx( + css` + label: filterWrapper; + display: none; + justify-content: flex-end; + flex-grow: 1; + opacity: 0.6; + padding-left: ${theme.spacing.xxs}; `, - }; - } -); + 'cell-filter-actions' + ), + filterItem: css` + label: filterItem; + cursor: pointer; + padding: 0 ${theme.spacing.xxs}; + `, + }; +}); + +export type TableStyles = ReturnType; diff --git a/packages/grafana-ui/src/components/Table/types.ts b/packages/grafana-ui/src/components/Table/types.ts index 0a60c52b4f2..8fc7702c8ea 100644 --- a/packages/grafana-ui/src/components/Table/types.ts +++ b/packages/grafana-ui/src/components/Table/types.ts @@ -1,7 +1,7 @@ import { CellProps } from 'react-table'; import { Field } from '@grafana/data'; import { TableStyles } from './styles'; -import { FC } from 'react'; +import { CSSProperties, FC } from 'react'; export interface TableFieldOptions { width: number; @@ -18,6 +18,7 @@ export enum TableCellDisplayMode { LcdGauge = 'lcd-gauge', JSONView = 'json-view', BasicGauge = 'basic', + Image = 'image', } export type FieldTextAlignment = 'auto' | 'left' | 'right' | 'center'; @@ -41,7 +42,9 @@ export interface TableSortByFieldState { export interface TableCellProps extends CellProps { tableStyles: TableStyles; + cellProps: CSSProperties; field: Field; + onCellFilterAdded: TableFilterActionCallback; } export type CellComponent = FC; diff --git a/packages/grafana-ui/src/components/Table/utils.test.ts b/packages/grafana-ui/src/components/Table/utils.test.ts index 5a7353b4ace..8885f32e412 100644 --- a/packages/grafana-ui/src/components/Table/utils.test.ts +++ b/packages/grafana-ui/src/components/Table/utils.test.ts @@ -66,7 +66,7 @@ describe('Table utils', () => { it('Should set textAlign to right for number values', () => { const data = getData(); const textAlign = getTextAlign(data.fields[1]); - expect(textAlign).toBe('right'); + expect(textAlign).toBe('flex-end'); }); }); diff --git a/packages/grafana-ui/src/components/Table/utils.ts b/packages/grafana-ui/src/components/Table/utils.ts index 0e0e3beae50..bf9686fcefa 100644 --- a/packages/grafana-ui/src/components/Table/utils.ts +++ b/packages/grafana-ui/src/components/Table/utils.ts @@ -1,8 +1,6 @@ import { Column, Row } from 'react-table'; import memoizeOne from 'memoize-one'; -import { css, cx } from 'emotion'; -import tinycolor from 'tinycolor2'; -import { ContentPosition, TextAlignProperty } from 'csstype'; +import { ContentPosition } from 'csstype'; import { DataFrame, Field, @@ -14,13 +12,13 @@ import { import { DefaultCell } from './DefaultCell'; import { BarGaugeCell } from './BarGaugeCell'; -import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types'; -import { withTableStyles } from './withTableStyles'; +import { TableCellDisplayMode, TableFieldOptions } from './types'; import { JSONViewCell } from './JSONViewCell'; +import { ImageCell } from './ImageCell'; -export function getTextAlign(field?: Field): TextAlignProperty { +export function getTextAlign(field?: Field): ContentPosition { if (!field) { - return 'left'; + return 'flex-start'; } if (field.config.custom) { @@ -28,19 +26,19 @@ export function getTextAlign(field?: Field): TextAlignProperty { switch (custom.align) { case 'right': - return 'right'; + return 'flex-end'; case 'left': - return 'left'; + return 'flex-start'; case 'center': return 'center'; } } if (field.type === FieldType.number) { - return 'right'; + return 'flex-end'; } - return 'left'; + return 'flex-start'; } export function getColumns(data: DataFrame, availableWidth: number, columnMinWidth: number): Column[] { @@ -68,6 +66,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid return 'alphanumeric'; } }; + const Cell = getCellComponent(fieldTableOptions.displayMode, field); columns.push({ Cell, @@ -80,6 +79,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid width: fieldTableOptions.width, minWidth: 50, filter: memoizeOne(filterByValue), + justifyContent: getTextAlign(field), }); } @@ -97,9 +97,10 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid function getCellComponent(displayMode: TableCellDisplayMode, field: Field) { switch (displayMode) { case TableCellDisplayMode.ColorText: - return withTableStyles(DefaultCell, getTextColorStyle); case TableCellDisplayMode.ColorBackground: - return withTableStyles(DefaultCell, getBackgroundColorStyle); + return DefaultCell; + case TableCellDisplayMode.Image: + return ImageCell; case TableCellDisplayMode.LcdGauge: case TableCellDisplayMode.BasicGauge: case TableCellDisplayMode.GradientGauge: @@ -115,58 +116,6 @@ function getCellComponent(displayMode: TableCellDisplayMode, field: Field) { return DefaultCell; } -function getTextColorStyle(props: TableCellProps) { - const { field, cell, tableStyles } = props; - - if (!field.display) { - return tableStyles; - } - - const displayValue = field.display(cell.value); - if (!displayValue.color) { - return tableStyles; - } - - const extendedStyle = css` - color: ${displayValue.color}; - `; - - return { - ...tableStyles, - tableCell: cx(tableStyles.tableCell, extendedStyle), - }; -} - -function getBackgroundColorStyle(props: TableCellProps) { - const { field, cell, tableStyles } = props; - if (!field.display) { - return tableStyles; - } - - const displayValue = field.display(cell.value); - if (!displayValue.color) { - return tableStyles; - } - - const themeFactor = tableStyles.theme.isDark ? 1 : -0.7; - const bgColor2 = tinycolor(displayValue.color) - .darken(10 * themeFactor) - .spin(5) - .toRgbString(); - - const extendedStyle = css` - background: linear-gradient(120deg, ${bgColor2}, ${displayValue.color}); - color: white; - height: ${tableStyles.cellHeight}px; - padding: ${tableStyles.cellPadding}px; - `; - - return { - ...tableStyles, - tableCell: cx(tableStyles.tableCell, extendedStyle), - }; -} - export function filterByValue(rows: Row[], id: string, filterValues?: SelectableValue[]) { if (rows.length === 0) { return rows; @@ -186,20 +135,6 @@ export function filterByValue(rows: Row[], id: string, filterValues?: Selectable }); } -export function getHeaderAlign(field?: Field): ContentPosition { - const align = getTextAlign(field); - - if (align === 'right') { - return 'flex-end'; - } - - if (align === 'center') { - return align; - } - - return 'flex-start'; -} - export function calculateUniqueFieldValues(rows: any[], field?: Field) { if (!field || rows.length === 0) { return {}; diff --git a/packages/grafana-ui/src/components/Table/withTableStyles.tsx b/packages/grafana-ui/src/components/Table/withTableStyles.tsx deleted file mode 100644 index 9dbf13bc697..00000000000 --- a/packages/grafana-ui/src/components/Table/withTableStyles.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { CellComponent, TableCellProps } from './types'; -import { TableStyles } from './styles'; - -export const withTableStyles = ( - CellComponent: CellComponent, - getExtendedStyles: (props: TableCellProps) => TableStyles -): CellComponent => { - function WithTableStyles(props: TableCellProps) { - return CellComponent({ ...props, tableStyles: getExtendedStyles(props) }); - } - - WithTableStyles.displayName = CellComponent.displayName || CellComponent.name; - return WithTableStyles; -}; diff --git a/public/app/plugins/panel/table/module.tsx b/public/app/plugins/panel/table/module.tsx index 274f7935187..1bc85d87888 100644 --- a/public/app/plugins/panel/table/module.tsx +++ b/public/app/plugins/panel/table/module.tsx @@ -47,6 +47,7 @@ export const plugin = new PanelPlugin(TablePanel) { value: TableCellDisplayMode.LcdGauge, label: 'LCD gauge' }, { value: TableCellDisplayMode.BasicGauge, label: 'Basic gauge' }, { value: TableCellDisplayMode.JSONView, label: 'JSON View' }, + { value: TableCellDisplayMode.Image, label: 'Image' }, ], }, })