Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SECURITY SOLUTIONS] Keep context of timeline when switching tabs in security solutions #82237

Merged
merged 24 commits into from
Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
036d4fe
try to keep timeline context when switching tabs
XavierM Oct 30, 2020
6865090
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Oct 30, 2020
04adc6d
fix popover
patrykkopycinski Oct 30, 2020
f0ee419
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Oct 30, 2020
93e68f6
simpler solution to keep timelien context between tabs
XavierM Oct 30, 2020
edf6790
fix timeline context with relative date
XavierM Oct 31, 2020
228e8bc
allow update on the kql bar when opening new timeline
XavierM Oct 31, 2020
ec6e42c
keep detail view in context when savedObjectId of the timeline does n…
XavierM Nov 1, 2020
b31b6ea
remove redux solution and just KISS it
XavierM Nov 2, 2020
d6d7254
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Nov 2, 2020
f26dcac
add unit test for the popover
XavierM Nov 2, 2020
006d97d
add test on timeline context cache
XavierM Nov 2, 2020
15eb5e7
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Nov 2, 2020
91ef942
final commit -> to fix context of timeline between tabs
XavierM Nov 2, 2020
1373287
keep timerange kind to absolute when refreshing
XavierM Nov 3, 2020
991cd76
fix bug today/thiw week to be absolute and not relative
XavierM Nov 3, 2020
734d4ea
add unit test for absolute date for today and this week
XavierM Nov 3, 2020
24a86d4
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Nov 3, 2020
56662b7
fix absolute today/this week on timeline
XavierM Nov 3, 2020
d9a063f
fix refresh between page and timeline when link
XavierM Nov 5, 2020
8896fb3
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Nov 5, 2020
466505a
clean up
XavierM Nov 5, 2020
4184c95
Merge branch 'master' of github.com:elastic/kibana into keep_state_of…
XavierM Nov 5, 2020
a5d8325
remove nit
XavierM Nov 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions x-pack/plugins/security_solution/public/app/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import React, { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { useDispatch } from 'react-redux';

import { TimelineId } from '../../../common/types/timeline';
import { DragDropContextWrapper } from '../../common/components/drag_and_drop/drag_drop_context_wrapper';
Expand All @@ -23,6 +24,7 @@ import { DETECTIONS_SUB_PLUGIN_ID } from '../../../common/constants';
import { SourcererScopeName } from '../../common/store/sourcerer/model';
import { useUpgradeEndpointPackage } from '../../common/hooks/endpoint/upgrade';
import { useThrottledResizeObserver } from '../../common/components/utils';
import { inputsActions } from '../../common/store/inputs';

const Main = styled.main.attrs<{ paddingTop: number }>(({ paddingTop }) => ({
style: {
Expand All @@ -44,6 +46,7 @@ interface HomePageProps {
}

const HomePageComponent: React.FC<HomePageProps> = ({ children }) => {
const dispatch = useDispatch();
const { application, overlays } = useKibana().services;
const subPluginId = useRef<string>('');
const { ref, height = 0 } = useThrottledResizeObserver(300);
Expand Down Expand Up @@ -79,6 +82,12 @@ const HomePageComponent: React.FC<HomePageProps> = ({ children }) => {
// can remove this.
useUpgradeEndpointPackage();

useEffect(() => {
return () => {
dispatch(inputsActions.setIsInitializing({ id: 'timeline' }));
};
}, [dispatch]);

return (
<SecuritySolutionAppWrapper>
<HeaderGlobal ref={ref} isFixed={headerFixed} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ export const QueryBar = memo<QueryBarComponentProps>(
const [draftQuery, setDraftQuery] = useState(filterQuery);

useEffect(() => {
// Reset draftQuery when `Create new timeline` is clicked
setDraftQuery(filterQuery);
}, [filterQuery]);

useEffect(() => {
if (filterQueryDraft == null) {
setDraftQuery(filterQuery);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('selectors', () => {
};

let inputState: InputsRange = {
isInitializing: false,
timerange: absoluteTime,
policy: {
kind: 'manual',
Expand Down Expand Up @@ -62,6 +63,7 @@ describe('selectors', () => {
};

inputState = {
isInitializing: false,
timerange: absoluteTime,
policy: {
kind: 'manual',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export const mockGlobalState: State = {
},
inputs: {
global: {
isInitializing: false,
timerange: {
kind: 'relative',
fromStr: DEFAULT_FROM,
Expand All @@ -177,6 +178,7 @@ export const mockGlobalState: State = {
filters: [],
},
timeline: {
isInitializing: false,
timerange: {
kind: 'relative',
fromStr: DEFAULT_FROM,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ export const setSearchBarFilter = actionCreator<{
id: InputsModelId;
filters: Filter[];
}>('SET_SEARCH_BAR_FILTER');

export const setIsInitializing = actionCreator<{
id: InputsModelId;
}>('SET_IS_INITIALIZING');
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ describe('Inputs', () => {
})
).toEqual({
global: {
isInitializing: false,
linkTo: ['timeline'],
policy: {
duration: 300000,
Expand All @@ -284,6 +285,7 @@ describe('Inputs', () => {
filters: [],
},
timeline: {
isInitializing: false,
linkTo: ['global'],
policy: {
duration: 300000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const updateInputTimerange = (
...acc,
[linkToId]: {
...get(linkToId, state),
isInitializing: false,
timerange,
},
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface GlobalKqlQuery extends GlobalGenericQuery {
export type GlobalQuery = GlobalGraphqlQuery | GlobalKqlQuery;

export interface InputsRange {
isInitializing: boolean;
timerange: TimeRange;
policy: Policy;
queries: GlobalQuery[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
setFilterQuery,
setSavedQuery,
setSearchBarFilter,
setIsInitializing,
} from './actions';
import {
setIsInspected,
Expand All @@ -47,6 +48,7 @@ export type InputsState = InputsModel;

export const initialInputsState: InputsState = {
global: {
isInitializing: false,
timerange: {
kind: 'relative',
...getTimeRangeSettings(false),
Expand All @@ -62,6 +64,7 @@ export const initialInputsState: InputsState = {
fullScreen: false,
},
timeline: {
isInitializing: false,
timerange: {
kind: 'relative',
...getTimeRangeSettings(false),
Expand All @@ -84,6 +87,7 @@ export const createInitialInputsState = (): InputsState => {

return {
global: {
isInitializing: false,
timerange: {
kind: 'relative',
fromStr,
Expand All @@ -105,6 +109,7 @@ export const createInitialInputsState = (): InputsState => {
fullScreen: false,
},
timeline: {
isInitializing: false,
timerange: {
kind: 'relative',
fromStr,
Expand Down Expand Up @@ -245,4 +250,11 @@ export const inputsReducer = reducerWithInitialState(initialInputsState)
filters,
},
}))
.case(setIsInitializing, (state, { id }) => ({
...state,
[id]: {
...get(id, state),
isInitializing: true,
},
}))
.build();
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
reputationRenderer,
DefaultFieldRenderer,
DEFAULT_MORE_MAX_HEIGHT,
DefaultFieldRendererOverflow,
MoreContainer,
} from './field_renderers';
import { mockData } from '../../../network/components/details/mock';
Expand Down Expand Up @@ -330,4 +331,45 @@ describe('Field Renderers', () => {
expect(render).toHaveBeenCalledTimes(2);
});
});

describe('DefaultFieldRendererOverflow', () => {
const idPrefix = 'prefix-1';
const rowItems = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6', 'item7'];

test('it should render the length of items after the overflowIndexStart', () => {
const wrapper = mount(
<TestProviders>
<DefaultFieldRendererOverflow
idPrefix={idPrefix}
rowItems={rowItems}
moreMaxHeight={DEFAULT_MORE_MAX_HEIGHT}
overflowIndexStart={5}
/>
</TestProviders>
);

expect(wrapper.text()).toEqual(' ,+2 More');
expect(wrapper.find('[data-test-subj="more-container"]').first().exists()).toBe(false);
});

test('it should render the items after overflowIndexStart in the popover', () => {
const wrapper = mount(
<TestProviders>
<DefaultFieldRendererOverflow
idPrefix={idPrefix}
rowItems={rowItems}
moreMaxHeight={DEFAULT_MORE_MAX_HEIGHT}
overflowIndexStart={5}
/>
</TestProviders>
);

wrapper.find('button').first().simulate('click');
wrapper.update();
expect(wrapper.find('.euiPopover').first().exists()).toBe(true);
expect(wrapper.find('[data-test-subj="more-container"]').first().text()).toEqual(
'item6item7'
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,12 @@ MoreContainer.displayName = 'MoreContainer';
export const DefaultFieldRendererOverflow = React.memo<DefaultFieldRendererOverflowProps>(
({ idPrefix, moreMaxHeight, overflowIndexStart = 5, render, rowItems }) => {
const [isOpen, setIsOpen] = useState(false);
const handleClose = useCallback(() => setIsOpen(false), []);
const togglePopover = useCallback(() => setIsOpen((currentIsOpen) => !currentIsOpen), []);
const button = useMemo(
() => (
<>
{' ,'}
<EuiButtonEmpty size="xs" onClick={handleClose}>
<EuiButtonEmpty size="xs" onClick={togglePopover}>
{`+${rowItems.length - overflowIndexStart} `}
<FormattedMessage
id="xpack.securitySolution.fieldRenderers.moreLabel"
Expand All @@ -274,7 +274,7 @@ export const DefaultFieldRendererOverflow = React.memo<DefaultFieldRendererOverf
</EuiButtonEmpty>
</>
),
[handleClose, overflowIndexStart, rowItems.length]
[togglePopover, overflowIndexStart, rowItems.length]
);

return (
Expand All @@ -284,7 +284,7 @@ export const DefaultFieldRendererOverflow = React.memo<DefaultFieldRendererOverf
id="popover"
button={button}
isOpen={isOpen}
closePopover={handleClose}
closePopover={togglePopover}
repositionOnScroll
>
<MoreContainer
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ const EventsComponent: React.FC<Props> = ({
columnHeaders={columnHeaders}
columnRenderers={columnRenderers}
containerElementRef={containerElementRef}
disableSensorVisibility={data != null && data.length < 101}
docValueFields={docValueFields}
event={event}
eventIdToNoteIds={eventIdToNoteIds}
Expand Down
Loading