You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

116 lines
3.0 KiB

// copied from https://github.com/grafana/grafana/blob/3c6e0e8ef85048af952367751e478c08342e17b4/packages/grafana-ui/src/components/MatchersUI/utils.ts
import { useMemo } from 'react';
import { DataFrame, Field, getFieldDisplayName, SelectableValue } from '@grafana/data';
import { getFieldTypeIcon } from './types';
/**
* @internal
*/
export interface FrameFieldsDisplayNames {
// The display names
display: Set<string>;
// raw field names (that are explicitly not visible)
raw: Set<string>;
// Field mappings (duplicates are not supported)
fields: Map<string, Field>;
}
/**
* @internal
*/
export function frameHasName(name: string | undefined, names: FrameFieldsDisplayNames) {
if (!name) {
return false;
}
return names.display.has(name) || names.raw.has(name);
}
/**
* Retuns the distinct names in a set of frames
*/
function getFrameFieldsDisplayNames(data: DataFrame[], filter?: (field: Field) => boolean): FrameFieldsDisplayNames {
const names: FrameFieldsDisplayNames = {
display: new Set<string>(),
raw: new Set<string>(),
fields: new Map<string, Field>(),
};
for (const frame of data) {
for (const field of frame.fields) {
if (filter && !filter(field)) {
continue;
}
const disp = getFieldDisplayName(field, frame, data);
names.display.add(disp);
names.fields.set(disp, field);
if (field.name && disp !== field.name) {
names.raw.add(field.name);
names.fields.set(field.name, field);
}
}
}
return names;
}
/**
* @internal
*/
export function useFieldDisplayNames(data: DataFrame[], filter?: (field: Field) => boolean): FrameFieldsDisplayNames {
return useMemo(() => {
return getFrameFieldsDisplayNames(data, filter);
}, [data, filter]);
}
/**
* @internal
*/
export function useSelectOptions(
displayNames: FrameFieldsDisplayNames,
currentName?: string,
firstItem?: SelectableValue<string>,
fieldType?: string
): Array<SelectableValue<string>> {
return useMemo(() => {
let found = false;
const options: Array<SelectableValue<string>> = [];
if (firstItem) {
options.push(firstItem);
}
for (const name of displayNames.display) {
if (!found && name === currentName) {
found = true;
}
const field = displayNames.fields.get(name);
if (!fieldType || fieldType === field?.type) {
options.push({
value: name,
label: name,
icon: field ? getFieldTypeIcon(field) : undefined,
});
}
}
for (const name of displayNames.raw) {
if (!displayNames.display.has(name)) {
if (!found && name === currentName) {
found = true;
}
options.push({
value: name,
label: `${name} (base field name)`,
});
}
}
if (currentName && !found) {
options.push({
value: currentName,
label: `${currentName} (not found)`,
});
}
return options;
}, [displayNames, currentName, firstItem, fieldType]);
}