Log Context: Add highlighted words to log rows (#80119)

* Log Context: Add highlighted words to log rows

* Update public/app/features/logs/components/log-context/LogRowContextModal.tsx

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>

---------

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
This commit is contained in:
Sven Grossmann 2024-01-09 11:56:48 +01:00 committed by GitHub
parent 40e4d3deb5
commit 0f8d4db934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 115 additions and 1 deletions

View File

@ -292,6 +292,117 @@ describe('LogRowContextModal', () => {
});
});
it('should highlight the same `foo123` searchwords', async () => {
const dfBeforeNs = createDataFrame({
fields: [
{
name: 'time',
type: FieldType.time,
values: [1, 1],
},
{
name: 'message',
type: FieldType.string,
values: ['this contains foo123', 'this contains foo123'],
},
{
name: 'tsNs',
type: FieldType.string,
values: ['1', '2'],
},
],
});
const dfNowNs = createDataFrame({
fields: [
{
name: 'time',
type: FieldType.time,
values: [1],
},
{
name: 'message',
type: FieldType.string,
values: ['this contains foo123'],
},
{
name: 'tsNs',
type: FieldType.string,
values: ['2'],
},
],
});
const dfAfterNs = createDataFrame({
fields: [
{
name: 'time',
type: FieldType.time,
values: [1, 1],
},
{
name: 'message',
type: FieldType.string,
values: ['this contains foo123', 'this contains foo123'],
},
{
name: 'tsNs',
type: FieldType.string,
values: ['2', '3'],
},
],
});
let uniqueRefIdCounter = 1;
const logs = dataFrameToLogsModel([dfNowNs]);
const row = logs.rows[0];
row.searchWords = ['foo123'];
const getRowContext = jest.fn().mockImplementation(async (_, options) => {
uniqueRefIdCounter += 1;
const refId = `refid_${uniqueRefIdCounter}`;
if (uniqueRefIdCounter === 2) {
return {
data: [
{
refId,
...dfBeforeNs,
},
],
};
} else if (uniqueRefIdCounter === 3) {
return {
data: [
{
refId,
...dfAfterNs,
},
],
};
}
return { data: [] };
});
render(
<LogRowContextModal
row={row}
open={true}
onClose={() => {}}
getRowContext={getRowContext}
timeZone={timeZone}
logsSortOrder={LogsSortOrder.Descending}
/>
);
// there need to be 3 lines with that message, all `foo123` should be highlighted
await waitFor(() => {
expect(screen.getAllByText('foo123').length).toBe(3);
for (const el of screen.getAllByText('foo123')) {
// highlights are done in `<mark>` tags
expect(el.tagName).toBe('MARK');
}
// test that the rest is not in a MARK
expect(screen.getAllByText('this contains')[0].tagName).not.toBe('MARK');
});
});
it('should show a split view button', async () => {
const getRowContextQuery = jest.fn().mockResolvedValue({ datasource: { uid: 'test-uid' } });

View File

@ -363,7 +363,10 @@ export const LogRowContextModal: React.FunctionComponent<LogRowContextModalProps
// this way this array of rows will never be empty
const allRows = [...above.rows, row, ...below.rows];
const newRows = await loadMore(place, allRows);
const newRows = (await loadMore(place, allRows)).map((r) =>
// apply the original row's searchWords to all the rows for highlighting
!r.searchWords || !r.searchWords?.length ? { ...r, searchWords: row.searchWords } : r
);
const [older, newer] = partition(newRows, (newRow) => newRow.timeEpochNs > row.timeEpochNs);
const newAbove = logsSortOrder === LogsSortOrder.Ascending ? newer : older;
const newBelow = logsSortOrder === LogsSortOrder.Ascending ? older : newer;