mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Influxdb: Fix cascader when doing log query in explore (#21787)
* Fix cascader options and add tests * Add comment * Fix typo
This commit is contained in:
parent
b4570b4996
commit
85dad73e9d
@ -29,9 +29,11 @@ interface CascaderState {
|
||||
export interface CascaderOption {
|
||||
value: any;
|
||||
label: string;
|
||||
// Items will be just flattened into the main list of items recursively.
|
||||
items?: CascaderOption[];
|
||||
disabled?: boolean;
|
||||
title?: string;
|
||||
// Children will be shown in a submenu.
|
||||
children?: CascaderOption[];
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { pairsAreValid } from './InfluxLogsQueryField';
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { InfluxLogsQueryField, pairsAreValid } from './InfluxLogsQueryField';
|
||||
import { InfluxDatasourceMock } from '../datasource.mock';
|
||||
import InfluxDatasource from '../datasource';
|
||||
import { InfluxQuery } from '../types';
|
||||
import { ButtonCascader } from '@grafana/ui';
|
||||
|
||||
describe('pairsAreValid()', () => {
|
||||
describe('when all pairs are fully defined', () => {
|
||||
@ -51,3 +57,43 @@ describe('pairsAreValid()', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('InfluxLogsQueryField', () => {
|
||||
it('should load and show correct measurements and fields in cascader', async () => {
|
||||
const wrapper = getInfluxLogsQueryField();
|
||||
// Looks strange but we do async stuff in didMount and this will push the stack at the end of eval loop, effectively
|
||||
// waiting for the didMount to finish.
|
||||
await Promise.resolve();
|
||||
wrapper.update();
|
||||
const cascader = wrapper.find(ButtonCascader);
|
||||
expect(cascader.prop('options')).toEqual([
|
||||
{ label: 'logs', value: 'logs', children: [{ label: 'description', value: 'description', children: [] }] },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
function getInfluxLogsQueryField(props?: any) {
|
||||
const datasource: InfluxDatasource = new InfluxDatasourceMock(
|
||||
props?.measurements || {
|
||||
logs: [{ name: 'description', type: 'string' }],
|
||||
}
|
||||
) as any;
|
||||
|
||||
const defaultProps = {
|
||||
datasource,
|
||||
history: [] as any[],
|
||||
onRunQuery: () => {},
|
||||
onChange: (query: InfluxQuery) => {},
|
||||
query: {
|
||||
refId: '',
|
||||
} as InfluxQuery,
|
||||
};
|
||||
return mount(
|
||||
<InfluxLogsQueryField
|
||||
{...{
|
||||
...defaultProps,
|
||||
...props,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ export class InfluxLogsQueryField extends React.PureComponent<Props, State> {
|
||||
measurements.push({
|
||||
label: measurementObj.text,
|
||||
value: measurementObj.text,
|
||||
items: fields,
|
||||
children: fields,
|
||||
});
|
||||
}
|
||||
this.setState({ measurements });
|
||||
|
54
public/app/plugins/datasource/influxdb/datasource.mock.ts
Normal file
54
public/app/plugins/datasource/influxdb/datasource.mock.ts
Normal file
@ -0,0 +1,54 @@
|
||||
type FieldsDefinition = {
|
||||
name: string;
|
||||
// String type, usually something like 'string' or 'float'.
|
||||
type: string;
|
||||
};
|
||||
type Measurements = { [measurement: string]: FieldsDefinition[] };
|
||||
type FieldReturnValue = { text: string };
|
||||
|
||||
/**
|
||||
* Datasource mock for influx. At the moment this only works for queries that should return measurements or their
|
||||
* fields and no other functionality is implemented.
|
||||
*/
|
||||
export class InfluxDatasourceMock {
|
||||
constructor(private measurements: Measurements) {}
|
||||
metricFindQuery(query: string) {
|
||||
if (isMeasurementsQuery(query)) {
|
||||
return this.getMeasurements();
|
||||
} else {
|
||||
return this.getMeasurementFields(query);
|
||||
}
|
||||
}
|
||||
|
||||
private getMeasurements(): FieldReturnValue[] {
|
||||
return Object.keys(this.measurements).map(key => ({ text: key }));
|
||||
}
|
||||
|
||||
private getMeasurementFields(query: string): FieldReturnValue[] {
|
||||
const match = query.match(/SHOW FIELD KEYS FROM \"(.+)\"/);
|
||||
if (!match) {
|
||||
throw new Error(`Failed to match query="${query}"`);
|
||||
}
|
||||
const measurementName = match[1];
|
||||
if (!measurementName) {
|
||||
throw new Error(`Failed to match measurement name from query="${query}"`);
|
||||
}
|
||||
|
||||
const fields = this.measurements[measurementName];
|
||||
if (!fields) {
|
||||
throw new Error(
|
||||
`Failed to find measurement with name="${measurementName}" in measurements="[${Object.keys(
|
||||
this.measurements
|
||||
).join(', ')}]"`
|
||||
);
|
||||
}
|
||||
|
||||
return fields.map(field => ({
|
||||
text: field.name,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function isMeasurementsQuery(query: string) {
|
||||
return /SHOW MEASUREMENTS/.test(query);
|
||||
}
|
Loading…
Reference in New Issue
Block a user