grafana/public/app/plugins/datasource/testdata/metricTree.ts
Hugo Häggmark 083a2ce220
Templating: fixes filtering options with more than 1000 entries (#24614)
* Templating: fixes filtering options with more then 1000 entries

* Chore: reduces strict null errors by 2
2020-05-14 08:09:21 +02:00

80 lines
1.8 KiB
TypeScript

export interface TreeNode {
name: string;
children: TreeNode[];
}
/*
* Builds a nested tree like
* [
* {
* name: 'A',
* children: [
* { name: 'AA', children: [] },
* { name: 'AB', children: [] },
* ]
* }
* ]
*/
function buildMetricTree(parent: string, depth: number): TreeNode[] {
const chars = ['A', 'B', 'C'];
const children: TreeNode[] = [];
if (depth > 5) {
return [];
}
for (const letter of chars) {
const nodeName = `${parent}${letter}`;
children.push({
name: nodeName,
children: buildMetricTree(nodeName, depth + 1),
});
}
return children;
}
function queryTree(children: TreeNode[], query: string[], queryIndex: number): TreeNode[] {
if (queryIndex >= query.length) {
return children;
}
if (query[queryIndex] === '*') {
return children;
}
const nodeQuery = query[queryIndex];
let result: TreeNode[] = [];
let namesToMatch = [nodeQuery];
// handle glob queries
if (nodeQuery.startsWith('{')) {
namesToMatch = nodeQuery.replace(/\{|\}/g, '').split(',');
}
for (const node of children) {
for (const nameToMatch of namesToMatch) {
if (nameToMatch.indexOf('*') !== -1) {
const pattern = nameToMatch.replace('*', '');
const regex = new RegExp(`^${pattern}.*`, 'gi');
if (regex.test(node.name)) {
result = result.concat(queryTree([node], query, queryIndex + 1));
}
} else if (node.name === nameToMatch) {
result = result.concat(queryTree(node.children, query, queryIndex + 1));
}
}
}
return result;
}
export function queryMetricTree(query: string): TreeNode[] {
if (query.indexOf('value') === 0) {
return [{ name: query, children: [] }];
}
const children = buildMetricTree('', 0);
return queryTree(children, query.split('.'), 0);
}