core-components: highlight individual LogViewer search results

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-12-05 17:45:06 +01:00
committed by blam
parent 1407c0085a
commit be8e706462
4 changed files with 55 additions and 36 deletions
@@ -128,7 +128,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'BarBaz',
@@ -143,7 +143,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Bar',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'Baz',
@@ -158,7 +158,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Baz',
modifiers: {},
highlight: true,
highlight: 0,
},
]);
});
@@ -171,7 +171,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'BarBazBazBar',
@@ -180,7 +180,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: {},
highlight: true,
highlight: 1,
},
]);
expect(calculateHighlightedChunks(line, 'bar')).toEqual([
@@ -191,7 +191,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Bar',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'BazBaz',
@@ -200,7 +200,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Bar',
modifiers: {},
highlight: true,
highlight: 1,
},
{
text: 'Foo',
@@ -215,12 +215,12 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Baz',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'Baz',
modifiers: {},
highlight: true,
highlight: 1,
},
{
text: 'BarFoo',
@@ -237,7 +237,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: { bold: true },
highlight: true,
highlight: 0,
},
{
text: 'BarBazBazBar',
@@ -246,7 +246,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: { bold: true },
highlight: true,
highlight: 1,
},
]);
});
@@ -262,7 +262,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: { bold: true },
highlight: true,
highlight: 0,
},
{
text: 'BarBaz',
@@ -275,7 +275,7 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: { italic: true },
highlight: true,
highlight: 1,
},
]);
});
@@ -295,27 +295,27 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Fo',
modifiers: { bold: true },
highlight: true,
highlight: 0,
},
{
text: 'o',
modifiers: {},
highlight: true,
highlight: 0,
},
{
text: 'Foo',
modifiers: {},
highlight: true,
highlight: 1,
},
{
text: 'Fo',
modifiers: {},
highlight: true,
highlight: 2,
},
{
text: 'o',
modifiers: { italic: true },
highlight: true,
highlight: 2,
},
{
text: 'BarBaz',
@@ -324,32 +324,32 @@ describe('calculateHighlightedChunks', () => {
{
text: 'Foo',
modifiers: { foreground: 'blue' },
highlight: true,
highlight: 3,
},
{
text: 'Foo',
modifiers: { italic: true },
highlight: true,
highlight: 4,
},
{
text: 'Foo',
modifiers: { italic: true },
highlight: true,
highlight: 5,
},
{
text: 'F',
modifiers: { bold: true },
highlight: true,
highlight: 6,
},
{
text: 'o',
modifiers: {},
highlight: true,
highlight: 6,
},
{
text: 'o',
modifiers: { bold: true },
highlight: true,
highlight: 6,
},
]);
});
@@ -68,7 +68,7 @@ export function findSearchResults(text: string, searchText: string) {
}
export interface HighlightAnsiChunk extends AnsiChunk {
highlight?: boolean;
highlight?: number;
}
export function calculateHighlightedChunks(
@@ -83,23 +83,24 @@ export function calculateHighlightedChunks(
const chunks = new Array<HighlightAnsiChunk>();
let lineOffset = 0;
let nextResult = results.shift();
let resultIndex = 0;
let result = results[resultIndex];
for (const chunk of line.chunks) {
const { text, modifiers } = chunk;
if (!nextResult || lineOffset + text.length < nextResult.start) {
if (!result || lineOffset + text.length < result.start) {
chunks.push(chunk);
lineOffset += text.length;
continue;
}
let localOffset = 0;
while (nextResult) {
const localStart = Math.max(nextResult.start - lineOffset, 0);
while (result) {
const localStart = Math.max(result.start - lineOffset, 0);
if (localStart > text.length) {
break; // The next result is not in this chunk
}
const localEnd = Math.min(nextResult.end - lineOffset, text.length);
const localEnd = Math.min(result.end - lineOffset, text.length);
const hasTextBeforeResult = localStart > localOffset;
if (hasTextBeforeResult) {
@@ -109,16 +110,17 @@ export function calculateHighlightedChunks(
if (hasResultText) {
chunks.push({
modifiers,
highlight: true,
highlight: resultIndex,
text: text.slice(localStart, localEnd),
});
}
localOffset = localEnd;
const foundCompleteResult = nextResult.end - lineOffset === localEnd;
const foundCompleteResult = result.end - lineOffset === localEnd;
if (foundCompleteResult) {
nextResult = results.shift();
resultIndex += 1;
result = results[resultIndex];
} else {
break; // The rest of the result is in the following chunks
}
@@ -139,9 +141,15 @@ export interface LogLineProps {
line: AnsiLine;
classes: ReturnType<typeof useStyles>;
searchText: string;
highlightResultIndex?: number;
}
export function LogLine({ line, classes, searchText }: LogLineProps) {
export function LogLine({
line,
classes,
searchText,
highlightResultIndex,
}: LogLineProps) {
const chunks = calculateHighlightedChunks(line, searchText);
const elements = chunks.map(({ text, modifiers, highlight }, index) => (
@@ -149,7 +157,10 @@ export function LogLine({ line, classes, searchText }: LogLineProps) {
key={index}
className={clsx(
getModifierClasses(classes, modifiers),
highlight && classes.textHighlight,
highlight !== undefined &&
(highlight === highlightResultIndex
? classes.textSelectedHighlight
: classes.textHighlight),
)}
>
{text}
@@ -234,6 +234,11 @@ export function LogViewer(props: LogViewerProps) {
line={line}
classes={classes}
searchText={searchText}
highlightResultIndex={
searchResultLine === lineNumber
? searchResult!.lineIndex
: undefined
}
/>
</div>
);
@@ -55,7 +55,10 @@ export const useStyles = makeStyles(theme => ({
cursor: 'pointer',
},
textHighlight: {
background: alpha(theme.palette.primary.main, 0.3),
background: alpha(theme.palette.info.main, 0.15),
},
textSelectedHighlight: {
background: alpha(theme.palette.info.main, 0.4),
},
modifierBold: {
fontWeight: theme.typography.fontWeightBold,