mirror of https://github.com/grafana/grafana
Chore: Remove MetricCategoryCascader from Explore Metrics (#91039)
remove MetricCategoryCascaderpull/91169/head
parent
8323b688c6
commit
2536049ffd
@ -1,62 +0,0 @@ |
||||
import { useMemo } from 'react'; |
||||
|
||||
import { Cascader, CascaderOption } from '@grafana/ui'; |
||||
|
||||
import { useMetricCategories } from './useMetricCategories'; |
||||
|
||||
type Props = { |
||||
metricNames: string[]; |
||||
onSelect: (prefix: string | undefined) => void; |
||||
disabled?: boolean; |
||||
initialValue?: string; |
||||
}; |
||||
|
||||
export function MetricCategoryCascader({ metricNames, onSelect, disabled, initialValue }: Props) { |
||||
const categoryTree = useMetricCategories(metricNames); |
||||
const options = useMemo(() => createCasaderOptions(categoryTree), [categoryTree]); |
||||
|
||||
return ( |
||||
<Cascader |
||||
displayAllSelectedLevels={true} |
||||
width={40} |
||||
separator="_" |
||||
hideActiveLevelLabel={false} |
||||
placeholder={'No filter'} |
||||
isClearable |
||||
onSelect={(prefix) => { |
||||
onSelect(prefix); |
||||
}} |
||||
{...{ options, disabled, initialValue }} |
||||
/> |
||||
); |
||||
} |
||||
|
||||
function createCasaderOptions(tree: ReturnType<typeof useMetricCategories>, currentPrefix = '') { |
||||
const categories = Object.entries(tree.children); |
||||
|
||||
const options = categories.map(([metricPart, node]) => { |
||||
let subcategoryEntries = Object.entries(node.children); |
||||
|
||||
while (subcategoryEntries.length === 1 && !node.isMetric) { |
||||
// There is only one subcategory, so we will join it with the current metricPart to reduce depth
|
||||
const [subMetricPart, subNode] = subcategoryEntries[0]; |
||||
metricPart = `${metricPart}_${subMetricPart}`; |
||||
// Extend the metric part name, because there is only one subcategory
|
||||
node = subNode; |
||||
subcategoryEntries = Object.entries(node.children); |
||||
} |
||||
|
||||
const value = currentPrefix + metricPart; |
||||
const subOptions = createCasaderOptions(node, value + '_'); |
||||
|
||||
const option: CascaderOption = { |
||||
value: value, |
||||
label: metricPart, |
||||
items: subOptions, |
||||
}; |
||||
|
||||
return option; |
||||
}); |
||||
|
||||
return options; |
||||
} |
||||
@ -1,43 +0,0 @@ |
||||
import { useMemo } from 'react'; |
||||
|
||||
export function useMetricCategories(metrics: string[]) { |
||||
return useMemo(() => processMetrics(metrics), [metrics]); |
||||
} |
||||
|
||||
interface MetricPartNode { |
||||
isMetric?: boolean; |
||||
children: Record<string, MetricPartNode>; |
||||
} |
||||
|
||||
function processMetrics(metrics: string[]) { |
||||
const categoryTree: MetricPartNode = { children: {} }; |
||||
|
||||
function insertMetric(metric: string) { |
||||
if (metric.indexOf(':') !== -1) { |
||||
// Ignore recording rules.
|
||||
return; |
||||
} |
||||
|
||||
const metricParts = metric.split('_'); |
||||
|
||||
let cursor = categoryTree; |
||||
for (const metricPart of metricParts) { |
||||
let node = cursor.children[metricPart]; |
||||
if (!node) { |
||||
// Create new node
|
||||
node = { |
||||
children: {}, |
||||
}; |
||||
// Insert it
|
||||
cursor.children[metricPart] = node; |
||||
} |
||||
cursor = node; |
||||
} |
||||
// We know this node is a metric because it was for the last metricPart
|
||||
cursor.isMetric = true; |
||||
} |
||||
|
||||
metrics.forEach((metric) => insertMetric(metric)); |
||||
|
||||
return categoryTree; |
||||
} |
||||
Loading…
Reference in new issue