mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
A logging query has a selector part and a regexp. The regexp matches are highlighted when results return. This change adds live preview to matches when modifying the regexp in a search field. - delegate retrieval of match query to datasource - datasource returns search expressions to be used to highlight a live preview of matches - logs row now takes preview highlights - logs row renders preview highlights with dotted line to distinguish from query run matches (solid line) - fix react-highlight-words version to ensure custom chunk matcher - custom chunk matcher can now also take incomplete regexps, eg, `(level` without inifinte looping - perf: debounce of live preview to 500ms - perf: only top 100 rows get the live preview - preview is only supported with one query row (multiple rows semantic makes this tricky: regexp for row n should only filter results for query n)
45 lines
1.2 KiB
TypeScript
45 lines
1.2 KiB
TypeScript
import { TextMatch } from 'app/types/explore';
|
|
|
|
/**
|
|
* Adapt findMatchesInText for react-highlight-words findChunks handler.
|
|
* See https://github.com/bvaughn/react-highlight-words#props
|
|
*/
|
|
export function findHighlightChunksInText({ searchWords, textToHighlight }) {
|
|
return findMatchesInText(textToHighlight, searchWords.join(' '));
|
|
}
|
|
|
|
const cleanNeedle = (needle: string): string => {
|
|
return needle.replace(/[[{(][\w,.-?:*+]+$/, '');
|
|
};
|
|
|
|
/**
|
|
* Returns a list of substring regexp matches.
|
|
*/
|
|
export function findMatchesInText(haystack: string, needle: string): TextMatch[] {
|
|
// Empty search can send re.exec() into infinite loop, exit early
|
|
if (!haystack || !needle) {
|
|
return [];
|
|
}
|
|
const matches = [];
|
|
const cleaned = cleanNeedle(needle);
|
|
let regexp;
|
|
try {
|
|
regexp = new RegExp(`(?:${cleaned})`, 'g');
|
|
} catch (error) {
|
|
return matches;
|
|
}
|
|
haystack.replace(regexp, (substring, ...rest) => {
|
|
if (substring) {
|
|
const offset = rest[rest.length - 2];
|
|
matches.push({
|
|
text: substring,
|
|
start: offset,
|
|
length: substring.length,
|
|
end: offset + substring.length,
|
|
});
|
|
}
|
|
return '';
|
|
});
|
|
return matches;
|
|
}
|