mirror of
https://github.com/grafana/grafana.git
synced 2025-02-14 17:43:35 -06:00
Field overrides: added matcher to match all fields within frame/query. (#28872)
This commit is contained in:
parent
3c229c6bee
commit
cbb2c0a5d8
@ -23,6 +23,7 @@ export enum FieldMatcherID {
|
||||
byNames = 'byNames',
|
||||
byRegexp = 'byRegexp',
|
||||
byRegexpOrNames = 'byRegexpOrNames',
|
||||
byFrameRefID = 'byFrameRefID',
|
||||
// byIndex = 'byIndex',
|
||||
// byLabel = 'byLabel',
|
||||
}
|
||||
|
@ -306,3 +306,31 @@ describe('Field Regexp or Names Matcher', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Fields returned by query with refId', () => {
|
||||
it('Match all fields in frame with refId: A', () => {
|
||||
const data = [
|
||||
toDataFrame({
|
||||
refId: 'A',
|
||||
fields: [{ name: 'field_1' }, { name: 'field_2' }],
|
||||
}),
|
||||
toDataFrame({
|
||||
refId: 'B',
|
||||
fields: [{ name: 'field_1' }, { name: 'field_2' }],
|
||||
}),
|
||||
];
|
||||
|
||||
const matcher = getFieldMatcher({
|
||||
id: FieldMatcherID.byFrameRefID,
|
||||
options: 'A',
|
||||
});
|
||||
|
||||
const frameA = data[0];
|
||||
expect(matcher(frameA.fields[0], frameA, data)).toBe(true);
|
||||
expect(matcher(frameA.fields[1], frameA, data)).toBe(true);
|
||||
|
||||
const frameB = data[1];
|
||||
expect(matcher(frameB.fields[0], frameB, data)).toBe(false);
|
||||
expect(matcher(frameB.fields[1], frameB, data)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
@ -66,6 +66,28 @@ const regexpFieldNameMatcher: FieldMatcherInfo<string> = {
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Field matcher that will match all fields that exists in a
|
||||
* data frame with configured refId.
|
||||
* @public
|
||||
*/
|
||||
const fieldsInFrameMatcher: FieldMatcherInfo<string> = {
|
||||
id: FieldMatcherID.byFrameRefID,
|
||||
name: 'Fields by frame refId',
|
||||
description: 'match all fields returned in data frame with refId.',
|
||||
defaultOptions: '',
|
||||
|
||||
get: (refId: string): FieldMatcher => {
|
||||
return (field: Field, frame: DataFrame, allFrames: DataFrame[]) => {
|
||||
return frame.refId === refId;
|
||||
};
|
||||
},
|
||||
|
||||
getOptionsDisplayText: (refId: string): string => {
|
||||
return `Math all fields returned by query with reference ID: ${refId}`;
|
||||
},
|
||||
};
|
||||
|
||||
const regexpOrMultipleNamesMatcher: FieldMatcherInfo<RegexpOrNamesMatcherOptions> = {
|
||||
id: FieldMatcherID.byRegexpOrNames,
|
||||
name: 'Field Name by Regexp or Names',
|
||||
@ -127,7 +149,13 @@ const frameNameMatcher: FrameMatcherInfo<string> = {
|
||||
* Registry Initialization
|
||||
*/
|
||||
export function getFieldNameMatchers(): FieldMatcherInfo[] {
|
||||
return [fieldNameMatcher, regexpFieldNameMatcher, multipleFieldNamesMatcher, regexpOrMultipleNamesMatcher];
|
||||
return [
|
||||
fieldNameMatcher,
|
||||
regexpFieldNameMatcher,
|
||||
multipleFieldNamesMatcher,
|
||||
regexpOrMultipleNamesMatcher,
|
||||
fieldsInFrameMatcher,
|
||||
];
|
||||
}
|
||||
|
||||
export function getFrameNameMatchers(): FrameMatcherInfo[] {
|
||||
|
@ -0,0 +1,63 @@
|
||||
import React, { memo, useMemo, useCallback } from 'react';
|
||||
import { MatcherUIProps, FieldMatcherUIRegistryItem } from './types';
|
||||
import { FieldMatcherID, fieldMatchers, SelectableValue, DataFrame } from '@grafana/data';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
/**
|
||||
* UI to configure "fields by frame refId"-matcher.
|
||||
* @public
|
||||
*/
|
||||
export const FieldsByFrameRefIdMatcher = memo<MatcherUIProps<string>>(props => {
|
||||
const { data, options, onChange: onChangeFromProps } = props;
|
||||
const referenceIDs = useFrameRefIds(data);
|
||||
const selectOptions = useSelectOptions(referenceIDs);
|
||||
|
||||
const onChange = useCallback(
|
||||
(selection: SelectableValue<string>) => {
|
||||
if (!selection.value || !referenceIDs.has(selection.value)) {
|
||||
return;
|
||||
}
|
||||
return onChangeFromProps(selection.value);
|
||||
},
|
||||
[referenceIDs, onChangeFromProps]
|
||||
);
|
||||
|
||||
const selectedOption = selectOptions.find(v => v.value === options);
|
||||
return <Select value={selectedOption} options={selectOptions} onChange={onChange} />;
|
||||
});
|
||||
|
||||
/**
|
||||
* Registry item for UI to configure "fields by frame refId"-matcher.
|
||||
* @public
|
||||
*/
|
||||
export const fieldsByFrameRefIdItem: FieldMatcherUIRegistryItem<string> = {
|
||||
id: FieldMatcherID.byFrameRefID,
|
||||
component: FieldsByFrameRefIdMatcher,
|
||||
matcher: fieldMatchers.get(FieldMatcherID.byFrameRefID),
|
||||
name: 'Fields returned by query',
|
||||
description: 'Set properties for fields from a specific query',
|
||||
optionsToLabel: options => options,
|
||||
};
|
||||
|
||||
const useFrameRefIds = (data: DataFrame[]): Set<string> => {
|
||||
return useMemo(() => {
|
||||
const refIds: Set<string> = new Set();
|
||||
|
||||
for (const frame of data) {
|
||||
if (frame.refId) {
|
||||
refIds.add(frame.refId);
|
||||
}
|
||||
}
|
||||
|
||||
return refIds;
|
||||
}, [data]);
|
||||
};
|
||||
|
||||
const useSelectOptions = (displayNames: Set<string>): Array<SelectableValue<string>> => {
|
||||
return useMemo(() => {
|
||||
return Array.from(displayNames).map(n => ({
|
||||
value: n,
|
||||
label: n,
|
||||
}));
|
||||
}, [displayNames]);
|
||||
};
|
@ -3,7 +3,8 @@ import { FieldMatcherUIRegistryItem } from './types';
|
||||
import { fieldNameMatcherItem } from './FieldNameMatcherEditor';
|
||||
import { fieldNameByRegexMatcherItem } from './FieldNameByRegexMatcherEditor';
|
||||
import { fieldTypeMatcherItem } from './FieldTypeMatcherEditor';
|
||||
import { fieldsByFrameRefIdItem } from './FieldsByFrameRefIdMatcher';
|
||||
|
||||
export const fieldMatchersUI = new Registry<FieldMatcherUIRegistryItem<any>>(() => {
|
||||
return [fieldNameMatcherItem, fieldNameByRegexMatcherItem, fieldTypeMatcherItem];
|
||||
return [fieldNameMatcherItem, fieldNameByRegexMatcherItem, fieldTypeMatcherItem, fieldsByFrameRefIdItem];
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user