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
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]); |
|
}
|
|
|