mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TableCell: show JSON rather than [object Object] (#23683)
This commit is contained in:
parent
229176f1b0
commit
9464115fc0
43
packages/grafana-ui/src/components/Table/JSONViewCell.tsx
Normal file
43
packages/grafana-ui/src/components/Table/JSONViewCell.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
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 {
|
||||
ColorBackground = 'color-background',
|
||||
GradientGauge = 'gradient-gauge',
|
||||
LcdGauge = 'lcd-gauge',
|
||||
JSONView = 'json-view',
|
||||
}
|
||||
|
||||
export type FieldTextAlignment = 'auto' | 'left' | 'right' | 'center';
|
||||
|
@ -7,6 +7,7 @@ import { TableCellDisplayMode, TableCellProps, TableFieldOptions } from './types
|
||||
import { css, cx } from 'emotion';
|
||||
import { withTableStyles } from './withTableStyles';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import { JSONViewCell } from './JSONViewCell';
|
||||
|
||||
export function getTextAlign(field?: Field): TextAlignProperty {
|
||||
if (!field) {
|
||||
@ -46,7 +47,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid
|
||||
fieldCountWithoutWidth -= 1;
|
||||
}
|
||||
|
||||
const Cell = getCellComponent(fieldTableOptions.displayMode);
|
||||
const Cell = getCellComponent(fieldTableOptions.displayMode, field);
|
||||
|
||||
columns.push({
|
||||
Cell,
|
||||
@ -71,7 +72,7 @@ export function getColumns(data: DataFrame, availableWidth: number, columnMinWid
|
||||
return columns;
|
||||
}
|
||||
|
||||
function getCellComponent(displayMode: TableCellDisplayMode) {
|
||||
function getCellComponent(displayMode: TableCellDisplayMode, field: Field) {
|
||||
switch (displayMode) {
|
||||
case TableCellDisplayMode.ColorText:
|
||||
return withTableStyles(DefaultCell, getTextColorStyle);
|
||||
@ -80,9 +81,15 @@ function getCellComponent(displayMode: TableCellDisplayMode) {
|
||||
case TableCellDisplayMode.LcdGauge:
|
||||
case TableCellDisplayMode.GradientGauge:
|
||||
return BarGaugeCell;
|
||||
default:
|
||||
return DefaultCell;
|
||||
case TableCellDisplayMode.JSONView:
|
||||
return JSONViewCell;
|
||||
}
|
||||
|
||||
// Default or Auto
|
||||
if (field.type === FieldType.other) {
|
||||
return JSONViewCell;
|
||||
}
|
||||
return DefaultCell;
|
||||
}
|
||||
|
||||
function getTextColorStyle(props: TableCellProps) {
|
||||
|
@ -266,6 +266,15 @@ func init() {
|
||||
},
|
||||
})
|
||||
|
||||
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",
|
||||
Name: "Table Static",
|
||||
|
@ -7,6 +7,8 @@ import {
|
||||
MetricFindValue,
|
||||
TableData,
|
||||
TimeSeries,
|
||||
LoadingState,
|
||||
ArrayDataFrame,
|
||||
} from '@grafana/data';
|
||||
import { Scenario, TestDataQuery } from './types';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
@ -34,6 +36,8 @@ export class TestDataDataSource extends DataSourceApi<TestDataQuery> {
|
||||
}
|
||||
if (target.scenarioId === 'streaming_client') {
|
||||
streams.push(runStream(target, options));
|
||||
} else if (target.scenarioId === 'grafana_api') {
|
||||
streams.push(runGrafanaAPI(target, options));
|
||||
} else {
|
||||
queries.push({
|
||||
...target,
|
||||
@ -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 @@
|
||||
</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 -->
|
||||
<div class="gf-form-inline" ng-if="ctrl.scenario.id === 'predictable_pulse'">
|
||||
<div class="gf-form">
|
||||
|
@ -115,6 +115,12 @@ export class TestDataQueryCtrl extends QueryCtrl {
|
||||
delete this.target.csvWave;
|
||||
}
|
||||
|
||||
if (this.target.scenarioId === 'grafana_api') {
|
||||
this.target.stringInput = 'datasources';
|
||||
} else {
|
||||
delete this.target.stringInput;
|
||||
}
|
||||
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ import { PanelPlugin } from '@grafana/data';
|
||||
import { TablePanel } from './TablePanel';
|
||||
import { CustomFieldConfig, Options } from './types';
|
||||
import { tablePanelChangedHandler, tableMigrationHandler } from './migrations';
|
||||
import { TableCellDisplayMode } from '@grafana/ui/src/components/Table/types';
|
||||
|
||||
export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
.setPanelChangeHandler(tablePanelChangedHandler)
|
||||
@ -39,11 +40,12 @@ export const plugin = new PanelPlugin<Options, CustomFieldConfig>(TablePanel)
|
||||
description: 'Color text, background, show as gauge, etc',
|
||||
settings: {
|
||||
options: [
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
{ value: 'color-text', label: 'Color text' },
|
||||
{ value: 'color-background', label: 'Color background' },
|
||||
{ value: 'gradient-gauge', label: 'Gradient gauge' },
|
||||
{ value: 'lcd-gauge', label: 'LCD gauge' },
|
||||
{ value: TableCellDisplayMode.Auto, label: 'Auto' },
|
||||
{ value: TableCellDisplayMode.ColorText, label: 'Color text' },
|
||||
{ value: TableCellDisplayMode.ColorBackground, label: 'Color background' },
|
||||
{ value: TableCellDisplayMode.GradientGauge, label: 'Gradient gauge' },
|
||||
{ value: TableCellDisplayMode.LcdGauge, label: 'LCD gauge' },
|
||||
{ value: TableCellDisplayMode.JSONView, label: 'JSON View' },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user