diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/GeoCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/GeoCell.tsx new file mode 100644 index 00000000000..40e5bc04778 --- /dev/null +++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/GeoCell.tsx @@ -0,0 +1,43 @@ +import { css } from '@emotion/css'; +import WKT from 'ol/format/WKT'; +import { Geometry } from 'ol/geom'; + +import { useStyles2 } from '../../../../themes'; +import { GeoCellProps } from '../types'; + +export function GeoCell({ value, justifyContent, height }: GeoCellProps) { + const styles = useStyles2(getStyles); + + let disp = ''; + + if (value instanceof Geometry) { + disp = new WKT().writeGeometry(value, { + featureProjection: 'EPSG:3857', + dataProjection: 'EPSG:4326', + }); + } else if (value != null) { + disp = `${value}`; + } + + return ( +
+
+ {disp} +
+
+ ); +} + +const getStyles = () => ({ + cell: css({ + height: '100%', + display: 'flex', + alignItems: 'center', + padding: '0 8px', + }), + cellText: css({ + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + }), +}); diff --git a/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellNG.tsx index 1a1c3bbca5a..f9a91fa226c 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/Cells/TableCellNG.tsx @@ -1,12 +1,15 @@ import { css } from '@emotion/css'; +import { WKT } from 'ol/format'; +import { Geometry } from 'ol/geom'; import { ReactNode, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; +import { FieldType, GrafanaTheme2, isDataFrame, isTimeSeriesFrame } from '@grafana/data'; import { TableAutoCellOptions, TableCellDisplayMode } from '@grafana/schema'; import { useStyles2 } from '../../../../themes'; import { t } from '../../../../utils/i18n'; import { IconButton } from '../../../IconButton/IconButton'; +// import { GeoCell } from '../../Cells/GeoCell'; import { TableCellInspectorMode } from '../../TableCellInspector'; import { CellColors, @@ -21,6 +24,7 @@ import { ActionsCell } from './ActionsCell'; import AutoCell from './AutoCell'; import { BarGaugeCell } from './BarGaugeCell'; import { DataLinksCell } from './DataLinksCell'; +import { GeoCell } from './GeoCell'; import { ImageCell } from './ImageCell'; import { JSONCell } from './JSONCell'; import { SparklineCell } from './SparklineCell'; @@ -78,52 +82,31 @@ export function TableCellNG(props: TableCellNGProps) { } }, [divWidthRef.current]); // eslint-disable-line react-hooks/exhaustive-deps + // Common props for all cells + const commonProps = { + value, + field, + rowIdx, + justifyContent, + }; + // Get the correct cell type let cell: ReactNode = null; switch (cellType) { case TableCellDisplayMode.Sparkline: - cell = ( - - ); + cell = ; break; case TableCellDisplayMode.Gauge: case TableCellDisplayMode.BasicGauge: case TableCellDisplayMode.GradientGauge: case TableCellDisplayMode.LcdGauge: - cell = ( - - ); + cell = ; break; case TableCellDisplayMode.Image: - cell = ( - - ); + cell = ; break; case TableCellDisplayMode.JSONView: - cell = ; + cell = ; break; case TableCellDisplayMode.DataLinks: cell = ; @@ -137,15 +120,22 @@ export function TableCellNG(props: TableCellNGProps) { break; case TableCellDisplayMode.Auto: default: - cell = ( - - ); + // Handle auto cell type detection + if (field.type === FieldType.geo) { + cell = ; + } else if (field.type === FieldType.frame) { + const firstValue = field.values[0]; + if (isDataFrame(firstValue) && isTimeSeriesFrame(firstValue)) { + cell = ; + } else { + cell = ; + } + } else if (field.type === FieldType.other) { + cell = ; + } else { + cell = ; + } + break; } const handleMouseEnter = () => { @@ -200,12 +190,22 @@ export function TableCellNG(props: TableCellNGProps) { name="eye" tooltip={t('grafana-ui.table.cell-inspect-tooltip', 'Inspect value')} onClick={() => { + let inspectValue = value; + let mode = TableCellInspectorMode.text; + + if (field.type === FieldType.geo && value instanceof Geometry) { + inspectValue = new WKT().writeGeometry(value, { + featureProjection: 'EPSG:3857', + dataProjection: 'EPSG:4326', + }); + mode = TableCellInspectorMode.code; + } else if (cellType === TableCellDisplayMode.JSONView) { + mode = TableCellInspectorMode.code; + } + setContextMenuProps({ - value: String(value ?? ''), - mode: - cellType === TableCellDisplayMode.JSONView - ? TableCellInspectorMode.code - : TableCellInspectorMode.text, + value: String(inspectValue ?? ''), + mode, }); setIsInspecting(true); }} diff --git a/packages/grafana-ui/src/components/Table/TableNG/types.ts b/packages/grafana-ui/src/components/Table/TableNG/types.ts index 994409a6a4d..c2a760b4f49 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/types.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/types.ts @@ -207,6 +207,12 @@ export interface DataLinksCellProps { rowIdx: number; } +export interface GeoCellProps { + value: TableCellValue; + justifyContent: Property.JustifyContent; + height: number; +} + export interface ActionCellProps { actions?: ActionModel[]; }