mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TestData: support raw results in the raw frames editor (#44609)
This commit is contained in:
parent
133e34d52a
commit
6a72d97265
@ -153,7 +153,6 @@ export function dataFrameFromJSON(dto: DataFrameJSON): DataFrame {
|
|||||||
|
|
||||||
// Find the longest field length
|
// Find the longest field length
|
||||||
const length = data ? data.values.reduce((max, vals) => Math.max(max, vals.length), 0) : 0;
|
const length = data ? data.values.reduce((max, vals) => Math.max(max, vals.length), 0) : 0;
|
||||||
|
|
||||||
const fields = schema.fields.map((f, index) => {
|
const fields = schema.fields.map((f, index) => {
|
||||||
let buffer = data ? data.values[index] : [];
|
let buffer = data ? data.values[index] : [];
|
||||||
let origLen = buffer.length;
|
let origLen = buffer.length;
|
||||||
|
@ -308,7 +308,7 @@ export const isDataFrame = (data: any): data is DataFrame => data && data.hasOwn
|
|||||||
export function toDataFrame(data: any): DataFrame {
|
export function toDataFrame(data: any): DataFrame {
|
||||||
if ('fields' in data) {
|
if ('fields' in data) {
|
||||||
// DataFrameDTO does not have length
|
// DataFrameDTO does not have length
|
||||||
if ('length' in data) {
|
if ('length' in data && data.fields[0]?.values?.get) {
|
||||||
return data as DataFrame;
|
return data as DataFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ Timestamps will line up evenly on timeStepSeconds (For example, 60 seconds means
|
|||||||
|
|
||||||
s.registerScenario(&Scenario{
|
s.registerScenario(&Scenario{
|
||||||
ID: string(rawFrameQuery),
|
ID: string(rawFrameQuery),
|
||||||
Name: "Raw Frame",
|
Name: "Raw Frames",
|
||||||
})
|
})
|
||||||
|
|
||||||
s.registerScenario(&Scenario{
|
s.registerScenario(&Scenario{
|
||||||
|
@ -1,21 +1,67 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { InlineField, TextArea } from '@grafana/ui';
|
import { Alert, CodeEditor } from '@grafana/ui';
|
||||||
import { EditorProps } from '../QueryEditor';
|
import { EditorProps } from '../QueryEditor';
|
||||||
|
import { isArray } from 'lodash';
|
||||||
|
import { toDataQueryResponse } from '@grafana/runtime';
|
||||||
|
import { dataFrameToJSON, toDataFrame, toDataFrameDTO } from '@grafana/data';
|
||||||
|
|
||||||
export const RawFrameEditor = ({ onChange, query }: EditorProps) => {
|
export const RawFrameEditor = ({ onChange, query }: EditorProps) => {
|
||||||
const onContent = (rawFrameContent: string) => {
|
const [error, setError] = useState<string>();
|
||||||
onChange({ ...query, rawFrameContent });
|
const [warning, setWarning] = useState<string>();
|
||||||
|
|
||||||
|
const onSaveFrames = (rawFrameContent: string) => {
|
||||||
|
try {
|
||||||
|
const json = JSON.parse(rawFrameContent);
|
||||||
|
if (isArray(json)) {
|
||||||
|
setError(undefined);
|
||||||
|
setWarning(undefined);
|
||||||
|
onChange({ ...query, rawFrameContent });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let data: any = undefined;
|
||||||
|
|
||||||
|
// Copy paste from panel json
|
||||||
|
if (isArray(json.series) && json.state) {
|
||||||
|
data = json.series.map((v: any) => toDataFrameDTO(toDataFrame(v)));
|
||||||
|
} else {
|
||||||
|
// Chek if it is a copy of the raw resuls
|
||||||
|
const v = toDataQueryResponse({ data: json });
|
||||||
|
if (v.data?.length && !v.error) {
|
||||||
|
data = v.data.map((f) => dataFrameToJSON(f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
console.log('Original', json);
|
||||||
|
console.log('Save', data);
|
||||||
|
setError(undefined);
|
||||||
|
setWarning('Converted to direct frame result');
|
||||||
|
onChange({ ...query, rawFrameContent: JSON.stringify(data, null, 2) });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setError('Unable to read dataframes in text');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Error parsing json', e);
|
||||||
|
setError('Enter JSON array of data frames (or raw query results body)');
|
||||||
|
setWarning(undefined);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InlineField label="Frames" labelWidth={14}>
|
<>
|
||||||
<TextArea
|
{error && <Alert title={error} severity="error" />}
|
||||||
width="100%"
|
{warning && <Alert title={warning} severity="warning" />}
|
||||||
rows={10}
|
<CodeEditor
|
||||||
onBlur={(e) => onContent(e.currentTarget.value)}
|
height={300}
|
||||||
placeholder="frames array (JSON)"
|
language="json"
|
||||||
defaultValue={query.rawFrameContent ?? '[]'}
|
value={query.rawFrameContent ?? '[]'}
|
||||||
|
onBlur={onSaveFrames}
|
||||||
|
onSave={onSaveFrames}
|
||||||
|
showMiniMap={true}
|
||||||
|
showLineNumbers={true}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
LoadingState,
|
LoadingState,
|
||||||
TimeRange,
|
TimeRange,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
|
toDataFrame,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { Scenario, TestDataQuery } from './types';
|
import { Scenario, TestDataQuery } from './types';
|
||||||
import { DataSourceWithBackend, getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
import { DataSourceWithBackend, getBackendSrv, getGrafanaLiveSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
@ -191,8 +192,12 @@ export class TestDataDataSource extends DataSourceWithBackend<TestDataQuery> {
|
|||||||
|
|
||||||
rawFrameQuery(target: TestDataQuery, options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
|
rawFrameQuery(target: TestDataQuery, options: DataQueryRequest<TestDataQuery>): Observable<DataQueryResponse> {
|
||||||
try {
|
try {
|
||||||
let data: any[] = JSON.parse(target.rawFrameContent || '[]');
|
const data = JSON.parse(target.rawFrameContent ?? '[]').map((v: any) => {
|
||||||
return of({ data }).pipe(delay(100));
|
const f = toDataFrame(v);
|
||||||
|
f.refId = target.refId;
|
||||||
|
return f;
|
||||||
|
});
|
||||||
|
return of({ data, state: LoadingState.Done }).pipe(delay(100));
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
return of({ data: [], error: ex }).pipe(delay(100));
|
return of({ data: [], error: ex }).pipe(delay(100));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user