[Logs UI] Add filter as a link-to parameter for logs (#31531)

* Fixes #23316 - Add filter as a link-to parameter for logs

* Add unit test case
This commit is contained in:
Chris Cowan 2019-02-20 09:31:56 -07:00 committed by GitHub
parent b48e56fc88
commit 2ac5cf087b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 121 additions and 2 deletions

View file

@ -13,6 +13,11 @@ export const getTimeFromLocation = (location: Location) => {
return timeParam ? parseFloat(timeParam) : NaN;
};
export const getFilterFromLocation = (location: Location) => {
const param = getParamFromQueryString(getQueryStringFromLocation(location), 'filter');
return param ? param : '';
};
export const getToFromLocation = (location: Location) => {
const timeParam = getParamFromQueryString(getQueryStringFromLocation(location), 'to');
return timeParam ? parseFloat(timeParam) : NaN;

View file

@ -0,0 +1,110 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { createLocation } from 'history';
import React from 'react';
import { matchPath } from 'react-router-dom';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { RedirectToNodeLogs } from './redirect_to_node_logs';
describe('RedirectToNodeLogs component', () => {
it('renders a redirect with the correct host filter', () => {
const component = shallowWithIntl(
<RedirectToNodeLogs {...createRouteComponentProps('/host-logs/HOST_NAME')} />
).dive();
const withSourceChildFunction = component.prop('children') as any;
expect(withSourceChildFunction(testSourceChildArgs)).toMatchInlineSnapshot(`
<Redirect
push={false}
to="/logs?logFilter=(expression:'HOST_FIELD:%20HOST_NAME',kind:kuery)"
/>
`);
});
it('renders a redirect with the correct container filter', () => {
const component = shallowWithIntl(
<RedirectToNodeLogs {...createRouteComponentProps('/container-logs/CONTAINER_ID')} />
).dive();
const withSourceChildFunction = component.prop('children') as any;
expect(withSourceChildFunction(testSourceChildArgs)).toMatchInlineSnapshot(`
<Redirect
push={false}
to="/logs?logFilter=(expression:'CONTAINER_FIELD:%20CONTAINER_ID',kind:kuery)"
/>
`);
});
it('renders a redirect with the correct pod filter', () => {
const component = shallowWithIntl(
<RedirectToNodeLogs {...createRouteComponentProps('/pod-logs/POD_ID')} />
).dive();
const withSourceChildFunction = component.prop('children') as any;
expect(withSourceChildFunction(testSourceChildArgs)).toMatchInlineSnapshot(`
<Redirect
push={false}
to="/logs?logFilter=(expression:'POD_FIELD:%20POD_ID',kind:kuery)"
/>
`);
});
it('renders a redirect with the correct position', () => {
const component = shallowWithIntl(
<RedirectToNodeLogs
{...createRouteComponentProps('/host-logs/HOST_NAME?time=1550671089404')}
/>
).dive();
const withSourceChildFunction = component.prop('children') as any;
expect(withSourceChildFunction(testSourceChildArgs)).toMatchInlineSnapshot(`
<Redirect
push={false}
to="/logs?logFilter=(expression:'HOST_FIELD:%20HOST_NAME',kind:kuery)&logPosition=(position:(tiebreaker:0,time:1550671089404))"
/>
`);
});
it('renders a redirect with the correct user-defined filter', () => {
const component = shallowWithIntl(
<RedirectToNodeLogs
{...createRouteComponentProps(
'/host-logs/HOST_NAME?time=1550671089404&filter=FILTER_FIELD:FILTER_VALUE'
)}
/>
).dive();
const withSourceChildFunction = component.prop('children') as any;
expect(withSourceChildFunction(testSourceChildArgs)).toMatchInlineSnapshot(`
<Redirect
push={false}
to="/logs?logFilter=(expression:'(HOST_FIELD:%20HOST_NAME)%20and%20(FILTER_FIELD:FILTER_VALUE)',kind:kuery)&logPosition=(position:(tiebreaker:0,time:1550671089404))"
/>
`);
});
});
const testSourceChildArgs = {
configuration: {
fields: {
container: 'CONTAINER_FIELD',
host: 'HOST_FIELD',
pod: 'POD_FIELD',
},
},
isLoading: false,
};
const createRouteComponentProps = (path: string) => {
const location = createLocation(path);
return {
match: matchPath(location.pathname, { path: '/:nodeType-logs/:nodeId' }) as any,
history: null as any,
location,
};
};

View file

@ -14,7 +14,7 @@ import { replaceLogFilterInQueryString } from '../../containers/logs/with_log_fi
import { replaceLogPositionInQueryString } from '../../containers/logs/with_log_position';
import { WithSource } from '../../containers/with_source';
import { InfraNodeType } from '../../graphql/types';
import { getTimeFromLocation } from './query_params';
import { getFilterFromLocation, getTimeFromLocation } from './query_params';
type RedirectToNodeLogsType = RouteComponentProps<{
nodeId: string;
@ -55,8 +55,12 @@ export const RedirectToNodeLogs = injectI18n(
return null;
}
const nodeFilter = `${configuration.fields[nodeType]}: ${nodeId}`;
const userFilter = getFilterFromLocation(location);
const filter = userFilter ? `(${nodeFilter}) and (${userFilter})` : nodeFilter;
const searchString = compose(
replaceLogFilterInQueryString(`${configuration.fields[nodeType]}: ${nodeId}`),
replaceLogFilterInQueryString(filter),
replaceLogPositionInQueryString(getTimeFromLocation(location))
)('');