Commit 9464115f by Ryan McKinley Committed by GitHub

TableCell: show JSON rather than [object Object] (#23683)

parent 229176f1
import React, { FC } from 'react';
import { css, cx } from 'emotion';
import { TableCellProps } from './types';
import { Tooltip } from '../Tooltip/Tooltip';
import { JSONFormatter } from '../JSONFormatter/JSONFormatter';
export const JSONViewCell: FC<TableCellProps> = props => {
const { field, cell, tableStyles } = props;
if (!field.display) {
return null;
}
const txt = css`
cursor: pointer;
font-family: monospace;
`;
const displayValue = JSON.stringify(cell.value);
const content = <JSONTooltip value={cell.value} />;
return (
<div className={cx(txt, tableStyles.tableCell)}>
<Tooltip placement="auto" content={content} theme={'info'}>
<span>{displayValue}</span>
</Tooltip>
</div>
);
};
interface PopupProps {
value: any;
}
const JSONTooltip: FC<PopupProps> = props => {
const clazz = css`
padding: 10px;
`;
return (
<div className={clazz}>
<JSONFormatter json={props.value} open={4} />
</div>
);
};
...@@ -15,6 +15,7 @@ export enum TableCellDisplayMode { ...@@ -15,6 +15,7 @@ export enum TableCellDisplayMode {
ColorBackground = 'color-background', ColorBackground = 'color-background',
GradientGauge = 'gradient-gauge', GradientGauge = 'gradient-gauge',
LcdGauge = 'lcd-gauge', LcdGauge = 'lcd-gauge',
JSONView = 'json-view',
} }
export type FieldTextAlignment = 'auto' | 'left' | 'right' | 'center'; export type FieldTextAlignment = 'auto' | 'left' | 'right' | 'center';
......
...@@ -7,6 +7,7 @@ import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types ...@@ -7,6 +7,7 @@ import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types
import { css, cx } from 'emotion'; import { css, cx } from 'emotion';
import { withTableStyles } from './withTableStyles'; import { withTableStyles } from './withTableStyles';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { JSONViewCell } from './JSONViewCell';
export function getTextAlign(field?: Field): TextAlignProperty { export function getTextAlign(field?: Field): TextAlignProperty {
if (!field) { if (!field) {
...@@ -46,7 +47,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid ...@@ -46,7 +47,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid
fieldCountWithoutWidth -= 1; fieldCountWithoutWidth -= 1;
} }
const Cell = getCellComponent(fieldTableOptions.displayMode); const Cell = getCellComponent(fieldTableOptions.displayMode, field);
columns.push({ columns.push({
Cell, Cell,
...@@ -71,7 +72,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid ...@@ -71,7 +72,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid
return columns; return columns;
} }
function getCellComponent(displayMode: TableCellDisplayMode) { function getCellComponent(displayMode: TableCellDisplayMode, field: Field) {
switch (displayMode) { switch (displayMode) {
case TableCellDisplayMode.ColorText: case TableCellDisplayMode.ColorText:
return withTableStyles(DefaultCell, getTextColorStyle); return withTableStyles(DefaultCell, getTextColorStyle);
...@@ -80,9 +81,15 @@ function getCellComponent(displayMode: TableCellDisplayMode) { ...@@ -80,9 +81,15 @@ function getCellComponent(displayMode: TableCellDisplayMode) {
case TableCellDisplayMode.LcdGauge: case TableCellDisplayMode.LcdGauge:
case TableCellDisplayMode.GradientGauge: case TableCellDisplayMode.GradientGauge:
return BarGaugeCell; return BarGaugeCell;
default: case TableCellDisplayMode.JSONView:
return DefaultCell; return JSONViewCell;
}
// Default or Auto
if (field.type === FieldType.other) {
return JSONViewCell;
} }
return DefaultCell;
} }
function getTextColorStyle(props: TableCellProps) { function getTextColorStyle(props: TableCellProps) {
......
...@@ -267,6 +267,15 @@ func init() { ...@@ -267,6 +267,15 @@ func init() {
}) })
registerScenario(&Scenario{ registerScenario(&Scenario{
Id: "grafana_api",
Name: "Grafana API",
Handler: func(query *tsdb.Query, context *tsdb.TsdbQuery) *tsdb.QueryResult {
// Real work is in javascript client
return tsdb.NewQueryResult()
},
})
registerScenario(&Scenario{
Id: "table_static", Id: "table_static",
Name: "Table Static", Name: "Table Static",
......
...@@ -7,6 +7,8 @@ import { ...@@ -7,6 +7,8 @@ import {
MetricFindValue, MetricFindValue,
TableData, TableData,
TimeSeries, TimeSeries,
LoadingState,
ArrayDataFrame,
} from '@grafana/data'; } from '@grafana/data';
import { Scenario, TestDataQuery } from './types'; import { Scenario, TestDataQuery } from './types';
import { getBackendSrv } from '@grafana/runtime'; import { getBackendSrv } from '@grafana/runtime';
...@@ -34,6 +36,8 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> { ...@@ -34,6 +36,8 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
} }
if (target.scenarioId === 'streaming_client') { if (target.scenarioId === 'streaming_client') {
streams.push(runStream(target, options)); streams.push(runStream(target, options));
} else if (target.scenarioId === 'grafana_api') {
streams.push(runGrafanaAPI(target, options));
} else { } else {
queries.push({ queries.push({
...target, ...target,
...@@ -145,3 +149,18 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> { ...@@ -145,3 +149,18 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
}); });
} }
} }
function runGrafanaAPI(target: TestDataQuery, req: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
const url = `/api/${target.stringInput}`;
return from(
getBackendSrv()
.get(url)
.then(res => {
const frame = new ArrayDataFrame(res);
return {
state: LoadingState.Done,
data: [frame],
};
})
);
}
...@@ -188,6 +188,21 @@ ...@@ -188,6 +188,21 @@
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-if="ctrl.scenario.id === 'grafana_api'">
<div class="gf-form gf-form">
<label class="gf-form-label query-keyword width-7">Endpoint</label>
<div class="gf-form-select-wrapper">
<select
ng-model="ctrl.target.stringInput"
class="gf-form-input"
ng-options="type for type in ['datasources', 'search', 'annotations']"
ng-change="ctrl.refresh()" />
</select>
</div>
</div>
</div>
<!-- Predictable Pulse Scenario Options Form --> <!-- Predictable Pulse Scenario Options Form -->
<div class="gf-form-inline" ng-if="ctrl.scenario.id === 'predictable_pulse'"> <div class="gf-form-inline" ng-if="ctrl.scenario.id === 'predictable_pulse'">
<div class="gf-form"> <div class="gf-form">
......
...@@ -115,6 +115,12 @@ export class TestDataQueryCtrl extends QueryCtrl { ...@@ -115,6 +115,12 @@ export class TestDataQueryCtrl extends QueryCtrl {
delete this.target.csvWave; delete this.target.csvWave;
} }
if (this.target.scenarioId === 'grafana_api') {
this.target.stringInput = 'datasources';
} else {
delete this.target.stringInput;
}
this.refresh(); this.refresh();
} }
......
...@@ -2,6 +2,7 @@ import { PanelPlugin } from '@grafana/data'; ...@@ -2,6 +2,7 @@ import { PanelPlugin } from '@grafana/data';
import { TablePanel } from './TablePanel'; import { TablePanel } from './TablePanel';
import { CustomFieldConfig, Options } from './types'; import { CustomFieldConfig, Options } from './types';
import { tablePanelChangedHandler, tableMigrationHandler } from './migrations'; import { tablePanelChangedHandler, tableMigrationHandler } from './migrations';
import { TableCellDisplayMode } from '@grafana/ui/src/components/Table/types';
export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel) export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
.setPanelChangeHandler(tablePanelChangedHandler) .setPanelChangeHandler(tablePanelChangedHandler)
...@@ -39,11 +40,12 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel) ...@@ -39,11 +40,12 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
description: 'Color text, background, show as gauge, etc', description: 'Color text, background, show as gauge, etc',
settings: { settings: {
options: [ options: [
{ value: 'auto', label: 'Auto' }, { value: TableCellDisplayMode.Auto, label: 'Auto' },
{ value: 'color-text', label: 'Color text' }, { value: TableCellDisplayMode.ColorText, label: 'Color text' },
{ value: 'color-background', label: 'Color background' }, { value: TableCellDisplayMode.ColorBackground, label: 'Color background' },
{ value: 'gradient-gauge', label: 'Gradient gauge' }, { value: TableCellDisplayMode.GradientGauge, label: 'Gradient gauge' },
{ value: 'lcd-gauge', label: 'LCD gauge' }, { value: TableCellDisplayMode.LcdGauge, label: 'LCD gauge' },
{ value: TableCellDisplayMode.JSONView, label: 'JSON View' },
], ],
}, },
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment