mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 20:24:18 -06:00
Explore: Fixes so Show context shows results again (#18675)
* Fix: Fixes so Show context shows results again Fixes: #18656 * Refactor: Removes unused import that made it thrugh the pre-commit somehow
This commit is contained in:
parent
0ea3444d1b
commit
774b7267df
@ -1,4 +1,4 @@
|
||||
import { FieldType, DataFrameDTO, FieldDTO } from '../types/index';
|
||||
import { DataFrameDTO, FieldDTO, FieldType } from '../types';
|
||||
import { DataFrameHelper } from './dataFrameHelper';
|
||||
|
||||
describe('dataFrameHelper', () => {
|
||||
@ -87,3 +87,29 @@ describe('FieldCache', () => {
|
||||
expect(fieldCache.getFieldByName('null')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse', () => {
|
||||
describe('when called with a DataFrame', () => {
|
||||
it('then it should reverse the order of values in all fields', () => {
|
||||
const frame: DataFrameDTO = {
|
||||
fields: [
|
||||
{ name: 'time', type: FieldType.time, values: [100, 200, 300] },
|
||||
{ name: 'name', type: FieldType.string, values: ['a', 'b', 'c'] },
|
||||
{ name: 'value', type: FieldType.number, values: [1, 2, 3] },
|
||||
],
|
||||
};
|
||||
|
||||
const helper = new DataFrameHelper(frame);
|
||||
|
||||
expect(helper.getFieldByName('time')!.values.toArray()).toEqual([100, 200, 300]);
|
||||
expect(helper.getFieldByName('name')!.values.toArray()).toEqual(['a', 'b', 'c']);
|
||||
expect(helper.getFieldByName('value')!.values.toArray()).toEqual([1, 2, 3]);
|
||||
|
||||
helper.reverse();
|
||||
|
||||
expect(helper.getFieldByName('time')!.values.toArray()).toEqual([300, 200, 100]);
|
||||
expect(helper.getFieldByName('name')!.values.toArray()).toEqual(['c', 'b', 'a']);
|
||||
expect(helper.getFieldByName('value')!.values.toArray()).toEqual([3, 2, 1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -44,10 +44,7 @@ export class DataFrameHelper implements DataFrame {
|
||||
*/
|
||||
reverse() {
|
||||
for (const f of this.fields) {
|
||||
if (isArray(f.values)) {
|
||||
const arr = f.values as any[];
|
||||
arr.reverse();
|
||||
}
|
||||
f.values.toArray().reverse();
|
||||
}
|
||||
}
|
||||
|
||||
|
74
public/app/features/explore/LogRowContextProvider.test.ts
Normal file
74
public/app/features/explore/LogRowContextProvider.test.ts
Normal file
@ -0,0 +1,74 @@
|
||||
import { DataFrameHelper, FieldType, LogRowModel } from '@grafana/data';
|
||||
import { getRowContexts } from './LogRowContextProvider';
|
||||
|
||||
describe('getRowContexts', () => {
|
||||
describe('when called with a DataFrame and results are returned', () => {
|
||||
it('then the result should be in correct format', async () => {
|
||||
const firstResult = new DataFrameHelper({
|
||||
refId: 'B',
|
||||
labels: {},
|
||||
fields: [
|
||||
{ name: 'ts', type: FieldType.time, values: [3, 2, 1] },
|
||||
{ name: 'line', type: FieldType.string, values: ['3', '2', '1'] },
|
||||
],
|
||||
});
|
||||
const secondResult = new DataFrameHelper({
|
||||
refId: 'B',
|
||||
labels: {},
|
||||
fields: [
|
||||
{ name: 'ts', type: FieldType.time, values: [6, 5, 4] },
|
||||
{ name: 'line', type: FieldType.string, values: ['6', '5', '4'] },
|
||||
],
|
||||
});
|
||||
const row: LogRowModel = {
|
||||
entry: '4',
|
||||
labels: null,
|
||||
hasAnsi: false,
|
||||
raw: '4',
|
||||
logLevel: null,
|
||||
timeEpochMs: 4,
|
||||
timeFromNow: '',
|
||||
timeLocal: '',
|
||||
timeUtc: '',
|
||||
timestamp: '4',
|
||||
};
|
||||
|
||||
const getRowContext = jest
|
||||
.fn()
|
||||
.mockResolvedValueOnce({ data: [firstResult] })
|
||||
.mockResolvedValueOnce({ data: [secondResult] });
|
||||
|
||||
const result = await getRowContexts(getRowContext, row, 10);
|
||||
|
||||
expect(result).toEqual({ data: [[['3', '2', '1']], [['6', '5', '4']]], errors: [null, null] });
|
||||
});
|
||||
});
|
||||
|
||||
describe('when called with a DataFrame and errors occur', () => {
|
||||
it('then the result should be in correct format', async () => {
|
||||
const firstError = new Error('Error 1');
|
||||
const secondError = new Error('Error 2');
|
||||
const row: LogRowModel = {
|
||||
entry: '4',
|
||||
labels: null,
|
||||
hasAnsi: false,
|
||||
raw: '4',
|
||||
logLevel: null,
|
||||
timeEpochMs: 4,
|
||||
timeFromNow: '',
|
||||
timeLocal: '',
|
||||
timeUtc: '',
|
||||
timestamp: '4',
|
||||
};
|
||||
|
||||
const getRowContext = jest
|
||||
.fn()
|
||||
.mockRejectedValueOnce(firstError)
|
||||
.mockRejectedValueOnce(secondError);
|
||||
|
||||
const result = await getRowContexts(getRowContext, row, 10);
|
||||
|
||||
expect(result).toEqual({ data: [[], []], errors: ['Error 1', 'Error 2'] });
|
||||
});
|
||||
});
|
||||
});
|
@ -1,5 +1,5 @@
|
||||
import { DataQueryResponse, DataQueryError } from '@grafana/ui';
|
||||
import { LogRowModel } from '@grafana/data';
|
||||
import { LogRowModel, toDataFrame, Field } from '@grafana/data';
|
||||
import { useState, useEffect } from 'react';
|
||||
import flatten from 'lodash/flatten';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
@ -47,19 +47,39 @@ export const getRowContexts = async (
|
||||
const results: Array<DataQueryResponse | DataQueryError> = await Promise.all(promises.map(p => p.catch(e => e)));
|
||||
|
||||
return {
|
||||
data: results.map((result, index) => {
|
||||
data: results.map(result => {
|
||||
const dataResult: DataQueryResponse = result as DataQueryResponse;
|
||||
if (!dataResult.data) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// We need to filter out the row we're basing our search from because of how start/end params work in Loki API
|
||||
// see https://github.com/grafana/loki/issues/597#issuecomment-506408980
|
||||
// the alternative to create our own add 1 nanosecond method to the a timestamp string would be quite complex
|
||||
return dataResult.data.map(series => {
|
||||
const filteredRows = series.rows.filter((r: any) => r[0] !== row.timestamp);
|
||||
return filteredRows.map((row: any) => row[1]);
|
||||
});
|
||||
const data: any[] = [];
|
||||
for (let index = 0; index < dataResult.data.length; index++) {
|
||||
const dataFrame = toDataFrame(dataResult.data[index]);
|
||||
const timestampField: Field<string> = dataFrame.fields.filter(field => field.name === 'ts')[0];
|
||||
|
||||
for (let fieldIndex = 0; fieldIndex < timestampField.values.length; fieldIndex++) {
|
||||
const timestamp = timestampField.values.get(fieldIndex);
|
||||
|
||||
// We need to filter out the row we're basing our search from because of how start/end params work in Loki API
|
||||
// see https://github.com/grafana/loki/issues/597#issuecomment-506408980
|
||||
// the alternative to create our own add 1 nanosecond method to the a timestamp string would be quite complex
|
||||
if (timestamp === row.timestamp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const lineField: Field<string> = dataFrame.fields.filter(field => field.name === 'line')[0];
|
||||
const line = lineField.values.get(fieldIndex); // assuming that both fields have same length
|
||||
|
||||
if (data.length === 0) {
|
||||
data[0] = [line];
|
||||
} else {
|
||||
data[0].push(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}),
|
||||
errors: results.map(result => {
|
||||
const errorResult: DataQueryError = result as DataQueryError;
|
||||
|
Loading…
Reference in New Issue
Block a user