Skip to content

Commit

Permalink
[SIEM] Fix Inspect query 'request timestamp' value changes when curso… (
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykkopycinski authored Jan 14, 2020
1 parent 1748054 commit 27d6925
Show file tree
Hide file tree
Showing 17 changed files with 1,327 additions and 1,426 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,179 +59,178 @@ interface Props {
kqlMode: KqlMode;
onChangeItemsPerPage: OnChangeItemsPerPage;
query: Query;
showInspect: boolean;
start: number;
sort: Sort;
timelineTypeContext: TimelineTypeContextProps;
toggleColumn: (column: ColumnHeader) => void;
utilityBar?: (totalCount: number) => React.ReactNode;
}

export const EventsViewer = React.memo<Props>(
({
browserFields,
columns,
const EventsViewerComponent: React.FC<Props> = ({
browserFields,
columns,
dataProviders,
deletedEventIds,
end,
filters,
headerFilterGroup,
height = DEFAULT_EVENTS_VIEWER_HEIGHT,
id,
indexPattern,
isLive,
itemsPerPage,
itemsPerPageOptions,
kqlMode,
onChangeItemsPerPage,
query,
start,
sort,
timelineTypeContext,
toggleColumn,
utilityBar,
}) => {
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
const kibana = useKibana();
const combinedQueries = combineQueries({
config: esQuery.getEsQueryConfig(kibana.services.uiSettings),
dataProviders,
deletedEventIds,
end,
filters,
headerFilterGroup,
height = DEFAULT_EVENTS_VIEWER_HEIGHT,
id,
indexPattern,
isLive,
itemsPerPage,
itemsPerPageOptions,
browserFields,
filters,
kqlQuery: query,
kqlMode,
onChangeItemsPerPage,
query,
showInspect,
start,
sort,
timelineTypeContext,
toggleColumn,
utilityBar,
}) => {
const columnsHeader = isEmpty(columns) ? defaultHeaders : columns;
const kibana = useKibana();
const combinedQueries = combineQueries({
config: esQuery.getEsQueryConfig(kibana.services.uiSettings),
dataProviders,
indexPattern,
browserFields,
filters,
kqlQuery: query,
kqlMode,
start,
end,
isEventViewer: true,
});
const queryFields = useMemo(
() =>
union(
columnsHeader.map(c => c.id),
timelineTypeContext.queryFields ?? []
),
[columnsHeader, timelineTypeContext.queryFields]
);
end,
isEventViewer: true,
});
const queryFields = useMemo(
() =>
union(
columnsHeader.map(c => c.id),
timelineTypeContext.queryFields ?? []
),
[columnsHeader, timelineTypeContext.queryFields]
);

return (
<EuiPanel data-test-subj="events-viewer-panel" grow={false}>
<AutoSizer detectAnyWindowResize={true} content>
{({ measureRef, content: { width = 0 } }) => (
<>
<WrappedByAutoSizer ref={measureRef}>
<div
data-test-subj="events-viewer-measured"
style={{ height: '0px', width: '100%' }}
/>
</WrappedByAutoSizer>
return (
<EuiPanel data-test-subj="events-viewer-panel" grow={false}>
<AutoSizer detectAnyWindowResize={true} content>
{({ measureRef, content: { width = 0 } }) => (
<>
<WrappedByAutoSizer ref={measureRef}>
<div
data-test-subj="events-viewer-measured"
style={{ height: '0px', width: '100%' }}
/>
</WrappedByAutoSizer>

{combinedQueries != null ? (
<TimelineQuery
fields={queryFields}
filterQuery={combinedQueries.filterQuery}
id={id}
indexPattern={indexPattern}
limit={itemsPerPage}
sortField={{
sortFieldId: sort.columnId,
direction: sort.sortDirection as Direction,
}}
sourceId="default"
>
{({
events,
getUpdatedAt,
inspect,
loading,
loadMore,
pageInfo,
refetch,
totalCount = 0,
}) => {
const totalCountMinusDeleted =
totalCount > 0 ? totalCount - deletedEventIds.length : 0;
{combinedQueries != null ? (
<TimelineQuery
fields={queryFields}
filterQuery={combinedQueries.filterQuery}
id={id}
indexPattern={indexPattern}
limit={itemsPerPage}
sortField={{
sortFieldId: sort.columnId,
direction: sort.sortDirection as Direction,
}}
sourceId="default"
>
{({
events,
getUpdatedAt,
inspect,
loading,
loadMore,
pageInfo,
refetch,
totalCount = 0,
}) => {
const totalCountMinusDeleted =
totalCount > 0 ? totalCount - deletedEventIds.length : 0;

// TODO: Reset eventDeletedIds/eventLoadingIds on refresh/loadmore (getUpdatedAt)
return (
<>
<HeaderSection
id={id}
showInspect={showInspect}
subtitle={
utilityBar
? undefined
: `${
i18n.SHOWING
}: ${totalCountMinusDeleted.toLocaleString()} ${i18n.UNIT(
totalCountMinusDeleted
)}`
}
title={timelineTypeContext?.title ?? i18n.EVENTS}
>
{headerFilterGroup}
</HeaderSection>
// TODO: Reset eventDeletedIds/eventLoadingIds on refresh/loadmore (getUpdatedAt)
return (
<>
<HeaderSection
id={id}
subtitle={
utilityBar
? undefined
: `${
i18n.SHOWING
}: ${totalCountMinusDeleted.toLocaleString()} ${i18n.UNIT(
totalCountMinusDeleted
)}`
}
title={timelineTypeContext?.title ?? i18n.EVENTS}
>
{headerFilterGroup}
</HeaderSection>

{utilityBar?.(totalCountMinusDeleted)}
{utilityBar?.(totalCountMinusDeleted)}

<div
data-test-subj={`events-container-loading-${loading}`}
style={{ width: `${width}px` }}
<div
data-test-subj={`events-container-loading-${loading}`}
style={{ width: `${width}px` }}
>
<ManageTimelineContext
loading={loading}
width={width}
type={timelineTypeContext}
>
<ManageTimelineContext
<TimelineRefetch
id={id}
inputId="global"
inspect={inspect}
loading={loading}
width={width}
type={timelineTypeContext}
>
<TimelineRefetch
id={id}
inputId="global"
inspect={inspect}
loading={loading}
refetch={refetch}
/>
refetch={refetch}
/>

<StatefulBody
browserFields={browserFields}
data={events.filter(e => !deletedEventIds.includes(e._id))}
id={id}
isEventViewer={true}
height={height}
sort={sort}
toggleColumn={toggleColumn}
/>

<StatefulBody
browserFields={browserFields}
data={events.filter(e => !deletedEventIds.includes(e._id))}
id={id}
isEventViewer={true}
height={height}
sort={sort}
toggleColumn={toggleColumn}
/>
<Footer
compact={isCompactFooter(width)}
getUpdatedAt={getUpdatedAt}
hasNextPage={getOr(false, 'hasNextPage', pageInfo)!}
height={footerHeight}
isEventViewer={true}
isLive={isLive}
isLoading={loading}
itemsCount={events.length}
itemsPerPage={itemsPerPage}
itemsPerPageOptions={itemsPerPageOptions}
onChangeItemsPerPage={onChangeItemsPerPage}
onLoadMore={loadMore}
nextCursor={getOr(null, 'endCursor.value', pageInfo)!}
serverSideEventCount={totalCountMinusDeleted}
tieBreaker={getOr(null, 'endCursor.tiebreaker', pageInfo)}
/>
</ManageTimelineContext>
</div>
</>
);
}}
</TimelineQuery>
) : null}
</>
)}
</AutoSizer>
</EuiPanel>
);
};

<Footer
compact={isCompactFooter(width)}
getUpdatedAt={getUpdatedAt}
hasNextPage={getOr(false, 'hasNextPage', pageInfo)!}
height={footerHeight}
isEventViewer={true}
isLive={isLive}
isLoading={loading}
itemsCount={events.length}
itemsPerPage={itemsPerPage}
itemsPerPageOptions={itemsPerPageOptions}
onChangeItemsPerPage={onChangeItemsPerPage}
onLoadMore={loadMore}
nextCursor={getOr(null, 'endCursor.value', pageInfo)!}
serverSideEventCount={totalCountMinusDeleted}
tieBreaker={getOr(null, 'endCursor.tiebreaker', pageInfo)}
/>
</ManageTimelineContext>
</div>
</>
);
}}
</TimelineQuery>
) : null}
</>
)}
</AutoSizer>
</EuiPanel>
);
},
export const EventsViewer = React.memo(
EventsViewerComponent,
(prevProps, nextProps) =>
prevProps.browserFields === nextProps.browserFields &&
prevProps.columns === nextProps.columns &&
Expand All @@ -247,10 +246,8 @@ export const EventsViewer = React.memo<Props>(
prevProps.itemsPerPageOptions === nextProps.itemsPerPageOptions &&
prevProps.kqlMode === nextProps.kqlMode &&
isEqual(prevProps.query, nextProps.query) &&
prevProps.showInspect === nextProps.showInspect &&
prevProps.start === nextProps.start &&
prevProps.sort === nextProps.sort &&
isEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) &&
prevProps.utilityBar === nextProps.utilityBar
);
EventsViewer.displayName = 'EventsViewer';
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ describe('StatefulEventsViewer', () => {
).toBe(true);
});

test('it renders a transparent inspect button when it does NOT have mouse focus', async () => {
// InspectButtonContainer controls displaying InspectButton components
test('it renders InspectButtonContainer', async () => {
const wrapper = mount(
<TestProviders>
<MockedProvider mocks={mockEventViewerResponse} addTypename={false}>
Expand All @@ -74,39 +75,6 @@ describe('StatefulEventsViewer', () => {
await wait();
wrapper.update();

expect(
wrapper
.find(`[data-test-subj="transparent-inspect-container"]`)
.first()
.exists()
).toBe(true);
});

test('it renders an opaque inspect button when it has mouse focus', async () => {
const wrapper = mount(
<TestProviders>
<MockedProvider mocks={mockEventViewerResponse} addTypename={false}>
<StatefulEventsViewer
defaultModel={eventsDefaultModel}
end={to}
id={'test-stateful-events-viewer'}
start={from}
/>
</MockedProvider>
</TestProviders>
);

await wait();
wrapper.update();

wrapper.simulate('mouseenter');
wrapper.update();

expect(
wrapper
.find(`[data-test-subj="opaque-inspect-container"]`)
.first()
.exists()
).toBe(true);
expect(wrapper.find(`InspectButtonContainer`).exists()).toBe(true);
});
});
Loading

0 comments on commit 27d6925

Please sign in to comment.