mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SIEM] Fix unnecessary re-renders on the Overview page (#56587)
This commit is contained in:
parent
db05fb6738
commit
418c44a47e
56 changed files with 376 additions and 332 deletions
|
@ -1,5 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`BarChartBaseComponent render with customized configs should 2 render BarSeries 1`] = `[Function]`;
|
||||
|
||||
exports[`BarChartBaseComponent render with default configs if no customized configs given should 2 render BarSeries 1`] = `[Function]`;
|
||||
|
|
|
@ -331,7 +331,7 @@ describe('AreaChart', () => {
|
|||
});
|
||||
|
||||
it(`should render area chart`, () => {
|
||||
expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(1);
|
||||
expect(shallowWrapper.find('AreaChartBase')).toHaveLength(1);
|
||||
expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
@ -344,7 +344,7 @@ describe('AreaChart', () => {
|
|||
});
|
||||
|
||||
it(`should render a chart place holder`, () => {
|
||||
expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(0);
|
||||
expect(shallowWrapper.find('AreaChartBase')).toHaveLength(0);
|
||||
expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(1);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -146,8 +146,4 @@ export const AreaChartComponent: React.FC<AreaChartComponentProps> = ({ areaChar
|
|||
);
|
||||
};
|
||||
|
||||
AreaChartComponent.displayName = 'AreaChartComponent';
|
||||
|
||||
export const AreaChart = React.memo(AreaChartComponent);
|
||||
|
||||
AreaChart.displayName = 'AreaChart';
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
|
||||
import { BarChartBaseComponent, BarChartComponent } from './barchart';
|
||||
import { ChartSeriesData } from './common';
|
||||
import { BarSeries, ScaleType, Axis } from '@elastic/charts';
|
||||
import { Chart, BarSeries, Axis, ScaleType } from '@elastic/charts';
|
||||
|
||||
jest.mock('../../lib/kibana');
|
||||
|
||||
|
@ -139,7 +139,7 @@ describe('BarChartBaseComponent', () => {
|
|||
});
|
||||
|
||||
it('should render two bar series', () => {
|
||||
expect(shallowWrapper.find('Chart')).toHaveLength(1);
|
||||
expect(shallowWrapper.find(Chart)).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -167,7 +167,6 @@ describe('BarChartBaseComponent', () => {
|
|||
});
|
||||
|
||||
it(`should ${mockBarChartData.length} render BarSeries`, () => {
|
||||
expect(shallow).toMatchSnapshot();
|
||||
expect(shallowWrapper.find(BarSeries)).toHaveLength(mockBarChartData.length);
|
||||
});
|
||||
|
||||
|
@ -265,7 +264,7 @@ describe('BarChartBaseComponent', () => {
|
|||
});
|
||||
|
||||
it('should not render without height and width', () => {
|
||||
expect(shallowWrapper.find('Chart')).toHaveLength(0);
|
||||
expect(shallowWrapper.find(Chart)).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -278,7 +277,7 @@ describe.each(chartDataSets)('BarChart with valid data [%o]', data => {
|
|||
});
|
||||
|
||||
it(`should render chart`, () => {
|
||||
expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(1);
|
||||
expect(shallowWrapper.find('BarChartBase')).toHaveLength(1);
|
||||
expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
@ -291,7 +290,7 @@ describe.each(chartHolderDataSets)('BarChart with invalid data [%o]', data => {
|
|||
});
|
||||
|
||||
it(`should render a ChartPlaceHolder`, () => {
|
||||
expect(shallowWrapper.find('WrappedByAutoSizer')).toHaveLength(0);
|
||||
expect(shallowWrapper.find('BarChartBase')).toHaveLength(0);
|
||||
expect(shallowWrapper.find('ChartPlaceHolder')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,9 @@ import {
|
|||
TickFormatter,
|
||||
Position,
|
||||
} from '@elastic/charts';
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { useUiSetting } from '../../lib/kibana';
|
||||
import { DEFAULT_DARK_MODE } from '../../../common/constants';
|
||||
|
||||
|
@ -54,7 +56,7 @@ export interface ChartSeriesData {
|
|||
color?: string | undefined;
|
||||
}
|
||||
|
||||
export const WrappedByAutoSizer = styled.div<{ height?: string }>`
|
||||
const WrappedByAutoSizerComponent = styled.div<{ height?: string }>`
|
||||
${style =>
|
||||
`
|
||||
height: ${style.height != null ? style.height : defaultChartHeight};
|
||||
|
@ -66,7 +68,9 @@ export const WrappedByAutoSizer = styled.div<{ height?: string }>`
|
|||
}
|
||||
`;
|
||||
|
||||
WrappedByAutoSizer.displayName = 'WrappedByAutoSizer';
|
||||
WrappedByAutoSizerComponent.displayName = 'WrappedByAutoSizer';
|
||||
|
||||
export const WrappedByAutoSizer = React.memo(WrappedByAutoSizerComponent);
|
||||
|
||||
export enum SeriesType {
|
||||
BAR = 'bar',
|
||||
|
@ -96,8 +100,9 @@ const theme: PartialTheme = {
|
|||
export const useTheme = () => {
|
||||
const isDarkMode = useUiSetting<boolean>(DEFAULT_DARK_MODE);
|
||||
const defaultTheme = isDarkMode ? DARK_THEME : LIGHT_THEME;
|
||||
const themeValue = useMemo(() => mergeWithDefaultTheme(theme, defaultTheme), []);
|
||||
|
||||
return mergeWithDefaultTheme(theme, defaultTheme);
|
||||
return themeValue;
|
||||
};
|
||||
|
||||
export const chartDefaultSettings = {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { createContext, useContext, useEffect } from 'react';
|
||||
import {
|
||||
Draggable,
|
||||
|
@ -14,6 +13,7 @@ import {
|
|||
} from 'react-beautiful-dnd';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { EuiPortal } from '@elastic/eui';
|
||||
import { dragAndDropActions } from '../../store/drag_and_drop';
|
||||
|
@ -122,7 +122,7 @@ const DraggableWrapperComponent = React.memo<Props>(
|
|||
},
|
||||
(prevProps, nextProps) => {
|
||||
return (
|
||||
isEqual(prevProps.dataProvider, nextProps.dataProvider) &&
|
||||
deepEqual(prevProps.dataProvider, nextProps.dataProvider) &&
|
||||
prevProps.render !== nextProps.render &&
|
||||
prevProps.truncate === nextProps.truncate
|
||||
);
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { getOr, isEmpty, isEqual, union } from 'lodash/fp';
|
||||
import { getOr, isEmpty, union } from 'lodash/fp';
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import useResizeObserver from 'use-resize-observer/polyfilled';
|
||||
|
||||
import { BrowserFields } from '../../containers/source';
|
||||
|
@ -228,7 +228,7 @@ const EventsViewerComponent: React.FC<Props> = ({
|
|||
export const EventsViewer = React.memo(
|
||||
EventsViewerComponent,
|
||||
(prevProps, nextProps) =>
|
||||
isEqual(prevProps.browserFields, nextProps.browserFields) &&
|
||||
deepEqual(prevProps.browserFields, nextProps.browserFields) &&
|
||||
prevProps.columns === nextProps.columns &&
|
||||
prevProps.dataProviders === nextProps.dataProviders &&
|
||||
prevProps.deletedEventIds === nextProps.deletedEventIds &&
|
||||
|
@ -241,9 +241,9 @@ export const EventsViewer = React.memo(
|
|||
prevProps.itemsPerPage === nextProps.itemsPerPage &&
|
||||
prevProps.itemsPerPageOptions === nextProps.itemsPerPageOptions &&
|
||||
prevProps.kqlMode === nextProps.kqlMode &&
|
||||
isEqual(prevProps.query, nextProps.query) &&
|
||||
deepEqual(prevProps.query, nextProps.query) &&
|
||||
prevProps.start === nextProps.start &&
|
||||
prevProps.sort === nextProps.sort &&
|
||||
isEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) &&
|
||||
deepEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) &&
|
||||
prevProps.utilityBar === nextProps.utilityBar
|
||||
);
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useCallback, useMemo, useEffect } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { inputsModel, inputsSelectors, State, timelineSelectors } from '../../store';
|
||||
import { inputsActions, timelineActions } from '../../store/actions';
|
||||
|
@ -197,23 +197,23 @@ export const StatefulEventsViewer = connector(
|
|||
StatefulEventsViewerComponent,
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.id === nextProps.id &&
|
||||
isEqual(prevProps.columns, nextProps.columns) &&
|
||||
isEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
deepEqual(prevProps.columns, nextProps.columns) &&
|
||||
deepEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
prevProps.deletedEventIds === nextProps.deletedEventIds &&
|
||||
prevProps.end === nextProps.end &&
|
||||
isEqual(prevProps.filters, nextProps.filters) &&
|
||||
deepEqual(prevProps.filters, nextProps.filters) &&
|
||||
prevProps.isLive === nextProps.isLive &&
|
||||
prevProps.itemsPerPage === nextProps.itemsPerPage &&
|
||||
isEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) &&
|
||||
deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) &&
|
||||
prevProps.kqlMode === nextProps.kqlMode &&
|
||||
isEqual(prevProps.query, nextProps.query) &&
|
||||
isEqual(prevProps.sort, nextProps.sort) &&
|
||||
deepEqual(prevProps.query, nextProps.query) &&
|
||||
deepEqual(prevProps.sort, nextProps.sort) &&
|
||||
prevProps.start === nextProps.start &&
|
||||
isEqual(prevProps.pageFilters, nextProps.pageFilters) &&
|
||||
deepEqual(prevProps.pageFilters, nextProps.pageFilters) &&
|
||||
prevProps.showCheckboxes === nextProps.showCheckboxes &&
|
||||
prevProps.showRowRenderers === nextProps.showRowRenderers &&
|
||||
prevProps.start === nextProps.start &&
|
||||
isEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) &&
|
||||
deepEqual(prevProps.timelineTypeContext, nextProps.timelineTypeContext) &&
|
||||
prevProps.utilityBar === nextProps.utilityBar
|
||||
)
|
||||
);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import { defaultTo, getOr } from 'lodash/fp';
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
|
||||
|
@ -58,28 +58,39 @@ export const FlyoutComponent = React.memo<Props>(
|
|||
timelineId,
|
||||
usersViewing,
|
||||
width,
|
||||
}) => (
|
||||
<>
|
||||
<Visible show={show}>
|
||||
<Pane
|
||||
flyoutHeight={flyoutHeight}
|
||||
headerHeight={headerHeight}
|
||||
onClose={() => showTimeline({ id: timelineId, show: false })}
|
||||
}) => {
|
||||
const handleClose = useCallback(() => showTimeline({ id: timelineId, show: false }), [
|
||||
showTimeline,
|
||||
timelineId,
|
||||
]);
|
||||
const handleOpen = useCallback(() => showTimeline({ id: timelineId, show: true }), [
|
||||
showTimeline,
|
||||
timelineId,
|
||||
]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Visible show={show}>
|
||||
<Pane
|
||||
flyoutHeight={flyoutHeight}
|
||||
headerHeight={headerHeight}
|
||||
onClose={handleClose}
|
||||
timelineId={timelineId}
|
||||
usersViewing={usersViewing}
|
||||
width={width}
|
||||
>
|
||||
{children}
|
||||
</Pane>
|
||||
</Visible>
|
||||
<FlyoutButton
|
||||
dataProviders={dataProviders!}
|
||||
show={!show}
|
||||
timelineId={timelineId}
|
||||
usersViewing={usersViewing}
|
||||
width={width}
|
||||
>
|
||||
{children}
|
||||
</Pane>
|
||||
</Visible>
|
||||
<FlyoutButton
|
||||
dataProviders={dataProviders!}
|
||||
show={!show}
|
||||
timelineId={timelineId}
|
||||
onOpen={() => showTimeline({ id: timelineId, show: true })}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
onOpen={handleOpen}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
FlyoutComponent.displayName = 'FlyoutComponent';
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
|
||||
import { getOr } from 'lodash/fp';
|
||||
import { getOr, omit } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { ActionCreator } from 'typescript-fsa';
|
||||
|
@ -162,7 +162,11 @@ const makeMapStateToProps = () => {
|
|||
const getGlobalQuery = inputsSelectors.globalQueryByIdSelector();
|
||||
const getTimelineQuery = inputsSelectors.timelineQueryByIdSelector();
|
||||
const mapStateToProps = (state: State, { inputId = 'global', queryId }: OwnProps) => {
|
||||
return inputId === 'global' ? getGlobalQuery(state, queryId) : getTimelineQuery(state, queryId);
|
||||
const props =
|
||||
inputId === 'global' ? getGlobalQuery(state, queryId) : getTimelineQuery(state, queryId);
|
||||
// refetch caused unnecessary component rerender and it was even not used
|
||||
const propsWithoutRefetch = omit('refetch', props);
|
||||
return propsWithoutRefetch;
|
||||
};
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import isEqual from 'lodash/fp/isEqual';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import React, { useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { compose } from 'redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
import { RouteSpyState } from '../../utils/route/types';
|
||||
|
@ -81,8 +80,8 @@ export const SiemNavigationRedux = compose<
|
|||
(prevProps, nextProps) =>
|
||||
prevProps.pathName === nextProps.pathName &&
|
||||
prevProps.search === nextProps.search &&
|
||||
isEqual(prevProps.navTabs, nextProps.navTabs) &&
|
||||
isEqual(prevProps.urlState, nextProps.urlState) &&
|
||||
deepEqual(prevProps.navTabs, nextProps.navTabs) &&
|
||||
deepEqual(prevProps.urlState, nextProps.urlState) &&
|
||||
deepEqual(prevProps.state, nextProps.state)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/* eslint-disable react/display-name */
|
||||
|
||||
import { has } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
|
||||
import { hostsActions } from '../../../../store/hosts';
|
||||
|
@ -100,10 +100,12 @@ const AuthenticationTableComponent = React.memo<AuthenticationTableProps>(
|
|||
[type, updateTableActivePage]
|
||||
);
|
||||
|
||||
const columns = useMemo(() => getAuthenticationColumnsCurated(type), [type]);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getAuthenticationColumnsCurated(type)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
headerCount={totalCount}
|
||||
headerTitle={i18n.AUTHENTICATIONS}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React, { useMemo, useCallback } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
|
||||
import { hostsActions } from '../../../../store/actions';
|
||||
import {
|
||||
Direction,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { KpiHostsData, KpiHostDetailsData } from '../../../../graphql/types';
|
||||
import { StatItemsComponent, StatItemsProps, useKpiMatrixStatus } from '../../../stat_items';
|
||||
import { kpiHostsMapping } from './kpi_hosts_mapping';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/* eslint-disable react/display-name */
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
|
||||
import { hostsActions } from '../../../../store/actions';
|
||||
|
@ -98,10 +98,12 @@ const UncommonProcessTableComponent = React.memo<UncommonProcessTableProps>(
|
|||
[type, updateTableActivePage]
|
||||
);
|
||||
|
||||
const columns = useMemo(() => getUncommonColumnsCurated(type), [type]);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getUncommonColumnsCurated(type)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
headerCount={totalCount}
|
||||
headerTitle={i18n.UNCOMMON_PROCESSES}
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import styled from 'styled-components';
|
||||
import { chunk as _chunk } from 'lodash/fp';
|
||||
|
||||
import {
|
||||
StatItemsComponent,
|
||||
StatItemsProps,
|
||||
|
|
|
@ -8,7 +8,6 @@ import numeral from '@elastic/numeral';
|
|||
import React from 'react';
|
||||
|
||||
import { NetworkDnsFields, NetworkDnsItem } from '../../../../graphql/types';
|
||||
import { networkModel } from '../../../../store';
|
||||
import { DragEffects, DraggableWrapper } from '../../../drag_and_drop/draggable_wrapper';
|
||||
import { escapeDataProviderId } from '../../../drag_and_drop/helpers';
|
||||
import { defaultToEmptyTag, getEmptyTagValue } from '../../../empty_value';
|
||||
|
@ -26,7 +25,7 @@ export type NetworkDnsColumns = [
|
|||
Columns<NetworkDnsItem['dnsBytesOut']>
|
||||
];
|
||||
|
||||
export const getNetworkDnsColumns = (type: networkModel.NetworkType): NetworkDnsColumns => [
|
||||
export const getNetworkDnsColumns = (): NetworkDnsColumns => [
|
||||
{
|
||||
field: `node.${NetworkDnsFields.dnsName}`,
|
||||
name: i18n.REGISTERED_DOMAIN,
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { networkActions } from '../../../../store/actions';
|
||||
import {
|
||||
|
@ -93,7 +93,7 @@ export const NetworkDnsTableComponent = React.memo<NetworkDnsTableProps>(
|
|||
field: criteria.sort.field.split('.')[1] as NetworkDnsFields,
|
||||
direction: criteria.sort.direction as Direction,
|
||||
};
|
||||
if (!isEqual(newDnsSortField, sort)) {
|
||||
if (!deepEqual(newDnsSortField, sort)) {
|
||||
updateNetworkTable({
|
||||
networkType: type,
|
||||
tableType,
|
||||
|
@ -115,10 +115,12 @@ export const NetworkDnsTableComponent = React.memo<NetworkDnsTableProps>(
|
|||
[type, updateNetworkTable, isPtrIncluded]
|
||||
);
|
||||
|
||||
const columns = useMemo(() => getNetworkDnsColumns(), []);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getNetworkDnsColumns(type)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
headerCount={totalCount}
|
||||
headerSupplement={
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
|
||||
import { networkActions } from '../../../../store/actions';
|
||||
|
@ -99,10 +99,12 @@ const NetworkHttpTableComponent: React.FC<NetworkHttpTableProps> = ({
|
|||
|
||||
const sorting = { field: `node.${NetworkHttpFields.requestCount}`, direction: sort.direction };
|
||||
|
||||
const columns = useMemo(() => getNetworkHttpColumns(tableType), [tableType]);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getNetworkHttpColumns(tableType)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
headerCount={totalCount}
|
||||
headerTitle={i18n.HTTP_REQUESTS}
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual, last } from 'lodash/fp';
|
||||
import { last } from 'lodash/fp';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
|
||||
import { networkActions } from '../../../../store/actions';
|
||||
|
@ -125,7 +126,7 @@ const NetworkTopCountriesTableComponent = React.memo<NetworkTopCountriesTablePro
|
|||
field: lastField as NetworkTopTablesFields,
|
||||
direction: newSortDirection as Direction,
|
||||
};
|
||||
if (!isEqual(newTopCountriesSort, sort)) {
|
||||
if (!deepEqual(newTopCountriesSort, sort)) {
|
||||
updateNetworkTable({
|
||||
networkType: type,
|
||||
tableType,
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { isEqual, last } from 'lodash/fp';
|
||||
import { last } from 'lodash/fp';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { networkActions } from '../../../../store/actions';
|
||||
import {
|
||||
|
@ -96,7 +97,7 @@ const NetworkTopNFlowTableComponent: React.FC<NetworkTopNFlowTableProps> = ({
|
|||
field: field as NetworkTopTablesFields,
|
||||
direction: newSortDirection as Direction,
|
||||
};
|
||||
if (!isEqual(newTopNFlowSort, sort)) {
|
||||
if (!deepEqual(newTopNFlowSort, sort)) {
|
||||
updateNetworkTable({
|
||||
networkType: type,
|
||||
tableType,
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { networkActions } from '../../../../store/network';
|
||||
import { TlsEdges, TlsSortField, TlsFields, Direction } from '../../../../graphql/types';
|
||||
|
@ -91,7 +91,7 @@ const TlsTableComponent = React.memo<TlsTableProps>(
|
|||
field: getSortFromString(splitField[splitField.length - 1]),
|
||||
direction: criteria.sort.direction as Direction,
|
||||
};
|
||||
if (!isEqual(newTlsSort, sort)) {
|
||||
if (!deepEqual(newTlsSort, sort)) {
|
||||
updateNetworkTable({
|
||||
networkType: type,
|
||||
tableType,
|
||||
|
@ -103,10 +103,12 @@ const TlsTableComponent = React.memo<TlsTableProps>(
|
|||
[sort, type, tableType, updateNetworkTable]
|
||||
);
|
||||
|
||||
const columns = useMemo(() => getTlsColumns(tlsTableId), [tlsTableId]);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getTlsColumns(tlsTableId)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
showMorePagesIndicator={showMorePagesIndicator}
|
||||
headerCount={totalCount}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { networkActions } from '../../../../store/network';
|
||||
import {
|
||||
|
@ -97,7 +97,7 @@ const UsersTableComponent = React.memo<UsersTableProps>(
|
|||
field: getSortFromString(splitField[splitField.length - 1]),
|
||||
direction: criteria.sort.direction as Direction,
|
||||
};
|
||||
if (!isEqual(newUsersSort, sort)) {
|
||||
if (!deepEqual(newUsersSort, sort)) {
|
||||
updateNetworkTable({
|
||||
networkType: type,
|
||||
tableType,
|
||||
|
@ -109,10 +109,15 @@ const UsersTableComponent = React.memo<UsersTableProps>(
|
|||
[sort, type, updateNetworkTable]
|
||||
);
|
||||
|
||||
const columns = useMemo(() => getUsersColumns(flowTarget, usersTableId), [
|
||||
flowTarget,
|
||||
usersTableId,
|
||||
]);
|
||||
|
||||
return (
|
||||
<PaginatedTable
|
||||
activePage={activePage}
|
||||
columns={getUsersColumns(flowTarget, usersTableId)}
|
||||
columns={columns}
|
||||
dataTestSubj={`table-${tableType}`}
|
||||
showMorePagesIndicator={showMorePagesIndicator}
|
||||
headerCount={totalCount}
|
||||
|
|
|
@ -266,6 +266,4 @@ const OverviewHostStatsComponent: React.FC<OverviewHostProps> = ({ data, loading
|
|||
);
|
||||
};
|
||||
|
||||
OverviewHostStatsComponent.displayName = 'OverviewHostStatsComponent';
|
||||
|
||||
export const OverviewHostStats = React.memo(OverviewHostStatsComponent);
|
||||
|
|
|
@ -130,7 +130,7 @@ const AccordionContent = styled.div`
|
|||
margin-top: 8px;
|
||||
`;
|
||||
|
||||
export const OverviewNetworkStats = React.memo<OverviewNetworkProps>(({ data, loading }) => {
|
||||
const OverviewNetworkStatsComponent: React.FC<OverviewNetworkProps> = ({ data, loading }) => {
|
||||
const allNetworkStats = getOverviewNetworkStats(data);
|
||||
const allNetworkStatsCount = allNetworkStats.reduce((total, stat) => total + stat.count, 0);
|
||||
|
||||
|
@ -190,6 +190,6 @@ export const OverviewNetworkStats = React.memo<OverviewNetworkProps>(({ data, lo
|
|||
})}
|
||||
</NetworkStatsContainer>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
OverviewNetworkStats.displayName = 'OverviewNetworkStats';
|
||||
export const OverviewNetworkStats = React.memo(OverviewNetworkStatsComponent);
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { memo, useState, useEffect, useMemo, useCallback } from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import {
|
||||
Filter,
|
||||
|
@ -64,7 +64,7 @@ export const QueryBar = memo<QueryBarComponentProps>(
|
|||
|
||||
const onQuerySubmit = useCallback(
|
||||
(payload: { dateRange: TimeRange; query?: Query }) => {
|
||||
if (payload.query != null && !isEqual(payload.query, filterQuery)) {
|
||||
if (payload.query != null && !deepEqual(payload.query, filterQuery)) {
|
||||
onSubmitQuery(payload.query);
|
||||
}
|
||||
},
|
||||
|
@ -73,7 +73,7 @@ export const QueryBar = memo<QueryBarComponentProps>(
|
|||
|
||||
const onQueryChange = useCallback(
|
||||
(payload: { dateRange: TimeRange; query?: Query }) => {
|
||||
if (payload.query != null && !isEqual(payload.query, draftQuery)) {
|
||||
if (payload.query != null && !deepEqual(payload.query, draftQuery)) {
|
||||
setDraftQuery(payload.query);
|
||||
onChangedQuery(payload.query);
|
||||
}
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { getOr, isEqual, set } from 'lodash/fp';
|
||||
import { getOr, set } from 'lodash/fp';
|
||||
import React, { memo, useEffect, useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { Dispatch } from 'redux';
|
||||
import { Subscription } from 'rxjs';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import { FilterManager, IIndexPattern, TimeRange, Query, Filter } from 'src/plugins/data/public';
|
||||
import { SavedQuery } from 'src/legacy/core_plugins/data/public';
|
||||
|
||||
|
@ -60,7 +61,6 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
|
|||
setSavedQuery,
|
||||
setSearchBarFilter,
|
||||
start,
|
||||
timelineId,
|
||||
toStr,
|
||||
updateSearch,
|
||||
dataTestSubj,
|
||||
|
@ -108,7 +108,7 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
|
|||
updateSearchBar.start = payload.dateRange.from;
|
||||
}
|
||||
|
||||
if (payload.query != null && !isEqual(payload.query, filterQuery)) {
|
||||
if (payload.query != null && !deepEqual(payload.query, filterQuery)) {
|
||||
isStateUpdated = true;
|
||||
updateSearchBar = set('query', payload.query, updateSearchBar);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
*/
|
||||
|
||||
import { EuiBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { isEmpty, isEqual, uniqWith } from 'lodash/fp';
|
||||
import { isEmpty, uniqWith } from 'lodash/fp';
|
||||
import React from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { DESTINATION_IP_FIELD_NAME, SOURCE_IP_FIELD_NAME } from '../ip';
|
||||
import { DESTINATION_PORT_FIELD_NAME, SOURCE_PORT_FIELD_NAME, Port } from '../port';
|
||||
|
@ -115,7 +116,7 @@ const IpAdressesWithPorts = React.memo<{
|
|||
|
||||
return (
|
||||
<EuiFlexGroup gutterSize="none">
|
||||
{uniqWith(isEqual, ipPortPairs).map(
|
||||
{uniqWith(deepEqual, ipPortPairs).map(
|
||||
ipPortPair =>
|
||||
ipPortPair.ip != null && (
|
||||
<EuiFlexItem grow={false} key={ipPortPair.ip}>
|
||||
|
|
|
@ -94,7 +94,6 @@ exports[`Stat Items Component disable charts it renders the default widget 1`] =
|
|||
isInspected={false}
|
||||
loading={false}
|
||||
queryId="statItems"
|
||||
refetch={null}
|
||||
selectedInspectIndex={0}
|
||||
setIsInspected={[Function]}
|
||||
title="KPI HOSTS"
|
||||
|
@ -328,7 +327,6 @@ exports[`Stat Items Component disable charts it renders the default widget 2`] =
|
|||
isInspected={false}
|
||||
loading={false}
|
||||
queryId="statItems"
|
||||
refetch={null}
|
||||
selectedInspectIndex={0}
|
||||
setIsInspected={[Function]}
|
||||
title="KPI HOSTS"
|
||||
|
@ -632,7 +630,6 @@ exports[`Stat Items Component rendering kpis with charts it renders the default
|
|||
isInspected={false}
|
||||
loading={false}
|
||||
queryId="statItems"
|
||||
refetch={null}
|
||||
selectedInspectIndex={0}
|
||||
setIsInspected={[Function]}
|
||||
title="KPI UNIQUE_PRIVATE_IPS"
|
||||
|
|
|
@ -8,7 +8,7 @@ exports[`Timeline rendering renders correctly against snapshot 1`] = `
|
|||
justifyContent="flexStart"
|
||||
>
|
||||
<WrappedByAutoSizer>
|
||||
<TimelineHeader
|
||||
<Memo(TimelineHeaderComponent)
|
||||
browserFields={
|
||||
Object {
|
||||
"agent": Object {
|
||||
|
|
|
@ -47,7 +47,7 @@ const TimelineHeaderContainer = styled.div`
|
|||
|
||||
TimelineHeaderContainer.displayName = 'TimelineHeaderContainer';
|
||||
|
||||
export const TimelineHeaderComponent = ({
|
||||
export const TimelineHeaderComponent: React.FC<Props> = ({
|
||||
browserFields,
|
||||
id,
|
||||
indexPattern,
|
||||
|
@ -60,7 +60,7 @@ export const TimelineHeaderComponent = ({
|
|||
onToggleDataProviderExcluded,
|
||||
show,
|
||||
showCallOutUnauthorizedMsg,
|
||||
}: Props) => (
|
||||
}) => (
|
||||
<TimelineHeaderContainer data-test-subj="timelineHeader">
|
||||
{showCallOutUnauthorizedMsg && (
|
||||
<EuiCallOut
|
||||
|
@ -91,8 +91,4 @@ export const TimelineHeaderComponent = ({
|
|||
</TimelineHeaderContainer>
|
||||
);
|
||||
|
||||
TimelineHeaderComponent.displayName = 'TimelineHeaderComponent';
|
||||
|
||||
export const TimelineHeader = React.memo(TimelineHeaderComponent);
|
||||
|
||||
TimelineHeader.displayName = 'TimelineHeader';
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useEffect, useCallback, useMemo } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { WithSource } from '../../containers/source';
|
||||
import { useSignalIndex } from '../../containers/detection_engine/signals/use_signal_index';
|
||||
|
@ -215,11 +215,11 @@ const StatefulTimelineComponent = React.memo<Props>(
|
|||
prevProps.show === nextProps.show &&
|
||||
prevProps.showCallOutUnauthorizedMsg === nextProps.showCallOutUnauthorizedMsg &&
|
||||
prevProps.start === nextProps.start &&
|
||||
isEqual(prevProps.columns, nextProps.columns) &&
|
||||
isEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
isEqual(prevProps.filters, nextProps.filters) &&
|
||||
isEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) &&
|
||||
isEqual(prevProps.sort, nextProps.sort)
|
||||
deepEqual(prevProps.columns, nextProps.columns) &&
|
||||
deepEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
deepEqual(prevProps.filters, nextProps.filters) &&
|
||||
deepEqual(prevProps.itemsPerPageOptions, nextProps.itemsPerPageOptions) &&
|
||||
deepEqual(prevProps.sort, nextProps.sort)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual, isEmpty } from 'lodash/fp';
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import React, { memo, useCallback, useState, useEffect } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import {
|
||||
IIndexPattern,
|
||||
|
@ -127,7 +128,7 @@ export const QueryBarTimeline = memo<QueryBarTimelineComponentProps>(
|
|||
const filterWithoutDropArea = filterManager
|
||||
.getFilters()
|
||||
.filter((f: Filter) => f.meta.controlledBy !== timelineFilterDropArea);
|
||||
if (!isEqual(filters, filterWithoutDropArea)) {
|
||||
if (!deepEqual(filters, filterWithoutDropArea)) {
|
||||
filterManager.setFilters(filters);
|
||||
}
|
||||
}, [filters]);
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { getOr, isEqual } from 'lodash/fp';
|
||||
import { getOr } from 'lodash/fp';
|
||||
import React, { useCallback } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { Dispatch } from 'redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { Filter, IIndexPattern } from '../../../../../../../../src/plugins/data/public';
|
||||
import { BrowserFields } from '../../../containers/source';
|
||||
|
@ -152,15 +153,15 @@ const StatefulSearchOrFilterComponent = React.memo<Props>(
|
|||
prevProps.isRefreshPaused === nextProps.isRefreshPaused &&
|
||||
prevProps.refreshInterval === nextProps.refreshInterval &&
|
||||
prevProps.timelineId === nextProps.timelineId &&
|
||||
isEqual(prevProps.browserFields, nextProps.browserFields) &&
|
||||
isEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
isEqual(prevProps.filters, nextProps.filters) &&
|
||||
isEqual(prevProps.filterQuery, nextProps.filterQuery) &&
|
||||
isEqual(prevProps.filterQueryDraft, nextProps.filterQueryDraft) &&
|
||||
isEqual(prevProps.indexPattern, nextProps.indexPattern) &&
|
||||
isEqual(prevProps.kqlMode, nextProps.kqlMode) &&
|
||||
isEqual(prevProps.savedQueryId, nextProps.savedQueryId) &&
|
||||
isEqual(prevProps.timelineId, nextProps.timelineId)
|
||||
deepEqual(prevProps.browserFields, nextProps.browserFields) &&
|
||||
deepEqual(prevProps.dataProviders, nextProps.dataProviders) &&
|
||||
deepEqual(prevProps.filters, nextProps.filters) &&
|
||||
deepEqual(prevProps.filterQuery, nextProps.filterQuery) &&
|
||||
deepEqual(prevProps.filterQueryDraft, nextProps.filterQueryDraft) &&
|
||||
deepEqual(prevProps.indexPattern, nextProps.indexPattern) &&
|
||||
deepEqual(prevProps.kqlMode, nextProps.kqlMode) &&
|
||||
deepEqual(prevProps.savedQueryId, nextProps.savedQueryId) &&
|
||||
deepEqual(prevProps.timelineId, nextProps.timelineId)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -229,8 +229,4 @@ export const TimelineComponent: React.FC<Props> = ({
|
|||
);
|
||||
};
|
||||
|
||||
TimelineComponent.displayName = 'TimelineComponent';
|
||||
|
||||
export const Timeline = React.memo(TimelineComponent);
|
||||
|
||||
Timeline.displayName = 'Timeline';
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React from 'react';
|
||||
import { compose, Dispatch } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { timelineActions } from '../../store/actions';
|
||||
import { RouteSpyState } from '../../utils/route/types';
|
||||
|
@ -39,7 +39,7 @@ export const UrlStateRedux = compose<React.ComponentClass<UrlStateProps & RouteS
|
|||
React.memo(
|
||||
UrlStateContainer,
|
||||
(prevProps, nextProps) =>
|
||||
prevProps.pathName === nextProps.pathName && isEqual(prevProps.urlState, nextProps.urlState)
|
||||
prevProps.pathName === nextProps.pathName && deepEqual(prevProps.urlState, nextProps.urlState)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual, difference, isEmpty } from 'lodash/fp';
|
||||
import { difference, isEmpty } from 'lodash/fp';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { useKibana } from '../../lib/kibana';
|
||||
import { useApolloClient } from '../../utils/apollo_context';
|
||||
|
@ -77,7 +78,7 @@ export const useUrlStateHooks = ({
|
|||
const updatedUrlStateString =
|
||||
getParamFromQueryString(getQueryStringFromLocation(mySearch), urlKey) ??
|
||||
newUrlStateString;
|
||||
if (isInitializing || !isEqual(updatedUrlStateString, newUrlStateString)) {
|
||||
if (isInitializing || !deepEqual(updatedUrlStateString, newUrlStateString)) {
|
||||
urlStateToUpdate = [
|
||||
...urlStateToUpdate,
|
||||
{
|
||||
|
@ -157,7 +158,7 @@ export const useUrlStateHooks = ({
|
|||
if (isInitializing && pageName != null && pageName !== '') {
|
||||
handleInitialize(type);
|
||||
setIsInitializing(false);
|
||||
} else if (!isEqual(urlState, prevProps.urlState) && !isInitializing) {
|
||||
} else if (!deepEqual(urlState, prevProps.urlState) && !isInitializing) {
|
||||
let mySearch = search;
|
||||
URL_STATE_KEYS[type].forEach((urlKey: KeyUrlState) => {
|
||||
if (
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEmpty, isEqual, get } from 'lodash/fp';
|
||||
import { isEmpty, get } from 'lodash/fp';
|
||||
import { useEffect, useState, Dispatch, SetStateAction } from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/public';
|
||||
import {
|
||||
|
@ -41,7 +42,7 @@ export const useFetchIndexPatterns = (defaultIndices: string[] = []): Return =>
|
|||
const [, dispatchToaster] = useStateToaster();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEqual(defaultIndices, indices)) {
|
||||
if (!deepEqual(defaultIndices, indices)) {
|
||||
setIndices(defaultIndices);
|
||||
}
|
||||
}, [defaultIndices, indices]);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useCallback, useState, useEffect } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
|
||||
import { inputsModel, inputsSelectors, State } from '../../store';
|
||||
|
@ -41,6 +41,17 @@ export const GlobalTimeComponent: React.FC<GlobalTimeProps> = ({
|
|||
}) => {
|
||||
const [isInitializing, setIsInitializing] = useState(true);
|
||||
|
||||
const setQuery = useCallback(
|
||||
({ id, inspect, loading, refetch }: SetQuery) =>
|
||||
setGlobalQuery({ inputId: 'global', id, inspect, loading, refetch }),
|
||||
[setGlobalQuery]
|
||||
);
|
||||
|
||||
const deleteQuery = useCallback(
|
||||
({ id }: { id: string }) => deleteOneQuery({ inputId: 'global', id }),
|
||||
[deleteOneQuery]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isInitializing) {
|
||||
setIsInitializing(false);
|
||||
|
@ -56,9 +67,8 @@ export const GlobalTimeComponent: React.FC<GlobalTimeProps> = ({
|
|||
isInitializing,
|
||||
from,
|
||||
to,
|
||||
setQuery: ({ id, inspect, loading, refetch }: SetQuery) =>
|
||||
setGlobalQuery({ inputId: 'global', id, inspect, loading, refetch }),
|
||||
deleteQuery: ({ id }: { id: string }) => deleteOneQuery({ inputId: 'global', id }),
|
||||
setQuery,
|
||||
deleteQuery,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
import { ApolloQueryResult, NetworkStatus } from 'apollo-client';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import memoizeOne from 'memoize-one';
|
||||
import React from 'react';
|
||||
import { FetchMoreOptions, FetchMoreQueryOptions, OperationVariables } from 'react-apollo';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { ESQuery } from '../../common/typed_json';
|
||||
import { inputsModel } from '../store/model';
|
||||
|
@ -85,7 +85,7 @@ export class QueryTemplatePaginated<
|
|||
public isItAValidLoading(loading: boolean, variables: TVariables, networkStatus: NetworkStatus) {
|
||||
if (
|
||||
!this.myLoading &&
|
||||
(!isEqual(variables, this.queryVariables) || networkStatus === NetworkStatus.refetch) &&
|
||||
(!deepEqual(variables, this.queryVariables) || networkStatus === NetworkStatus.refetch) &&
|
||||
loading
|
||||
) {
|
||||
this.myLoading = true;
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Query } from 'react-apollo';
|
|||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import memoizeOne from 'memoize-one';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
|
||||
import { useUiSetting$ } from '../../lib/kibana';
|
||||
|
||||
import { DEFAULT_INDEX_KEY } from '../../../common/constants';
|
||||
|
|
|
@ -12,9 +12,11 @@ import {
|
|||
HistogramBarSeries,
|
||||
Position,
|
||||
Settings,
|
||||
ChartSizeArray,
|
||||
} from '@elastic/charts';
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { EuiProgress } from '@elastic/eui';
|
||||
|
||||
import { useTheme } from '../../../../components/charts/common';
|
||||
import { histogramDateTimeFormatter } from '../../../../components/utils';
|
||||
import { HistogramData } from './types';
|
||||
|
@ -43,6 +45,14 @@ export const SignalsHistogram = React.memo<HistogramSignalsProps>(
|
|||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const chartSize: ChartSizeArray = useMemo(() => ['100%', chartHeight], [chartHeight]);
|
||||
const xAxisId = useMemo(() => getAxisId('signalsHistogramAxisX'), []);
|
||||
const yAxisId = useMemo(() => getAxisId('signalsHistogramAxisY'), []);
|
||||
const id = useMemo(() => getSpecId('signalsHistogram'), []);
|
||||
const yAccessors = useMemo(() => ['y'], []);
|
||||
const splitSeriesAccessors = useMemo(() => ['g'], []);
|
||||
const tickFormat = useMemo(() => histogramDateTimeFormatter([from, to]), [from, to]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading && (
|
||||
|
@ -54,7 +64,7 @@ export const SignalsHistogram = React.memo<HistogramSignalsProps>(
|
|||
/>
|
||||
)}
|
||||
|
||||
<Chart size={['100%', chartHeight]}>
|
||||
<Chart size={chartSize}>
|
||||
<Settings
|
||||
legendPosition={legendPosition}
|
||||
onBrushEnd={updateDateRange}
|
||||
|
@ -62,21 +72,17 @@ export const SignalsHistogram = React.memo<HistogramSignalsProps>(
|
|||
theme={theme}
|
||||
/>
|
||||
|
||||
<Axis
|
||||
id={getAxisId('signalsHistogramAxisX')}
|
||||
position="bottom"
|
||||
tickFormat={histogramDateTimeFormatter([from, to])}
|
||||
/>
|
||||
<Axis id={xAxisId} position="bottom" tickFormat={tickFormat} />
|
||||
|
||||
<Axis id={getAxisId('signalsHistogramAxisY')} position="left" />
|
||||
<Axis id={yAxisId} position="left" />
|
||||
|
||||
<HistogramBarSeries
|
||||
id={getSpecId('signalsHistogram')}
|
||||
id={id}
|
||||
xScaleType="time"
|
||||
yScaleType="linear"
|
||||
xAccessor="x"
|
||||
yAccessors={['y']}
|
||||
splitSeriesAccessors={['g']}
|
||||
yAccessors={yAccessors}
|
||||
splitSeriesAccessors={splitSeriesAccessors}
|
||||
data={data}
|
||||
/>
|
||||
</Chart>
|
||||
|
@ -84,4 +90,5 @@ export const SignalsHistogram = React.memo<HistogramSignalsProps>(
|
|||
);
|
||||
}
|
||||
);
|
||||
|
||||
SignalsHistogram.displayName = 'SignalsHistogram';
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
import { EuiFormRow, EuiMutationObserver } from '@elastic/eui';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import {
|
||||
Filter,
|
||||
|
@ -99,7 +99,7 @@ export const QueryBarDefineRule = ({
|
|||
const newFilters = filterManager.getFilters();
|
||||
const { filters } = field.value as FieldValueQueryBar;
|
||||
|
||||
if (!isEqual(filters, newFilters)) {
|
||||
if (!deepEqual(filters, newFilters)) {
|
||||
field.setValue({ ...(field.value as FieldValueQueryBar), filters: newFilters });
|
||||
}
|
||||
}
|
||||
|
@ -117,10 +117,10 @@ export const QueryBarDefineRule = ({
|
|||
let isSubscribed = true;
|
||||
async function updateFilterQueryFromValue() {
|
||||
const { filters, query, saved_id: savedId } = field.value as FieldValueQueryBar;
|
||||
if (!isEqual(query, queryDraft)) {
|
||||
if (!deepEqual(query, queryDraft)) {
|
||||
setQueryDraft(query);
|
||||
}
|
||||
if (!isEqual(filters, filterManager.getFilters())) {
|
||||
if (!deepEqual(filters, filterManager.getFilters())) {
|
||||
filterManager.setFilters(filters);
|
||||
}
|
||||
if (
|
||||
|
@ -148,7 +148,7 @@ export const QueryBarDefineRule = ({
|
|||
const onSubmitQuery = useCallback(
|
||||
(newQuery: Query, timefilter?: SavedQueryTimeFilter) => {
|
||||
const { query } = field.value as FieldValueQueryBar;
|
||||
if (!isEqual(query, newQuery)) {
|
||||
if (!deepEqual(query, newQuery)) {
|
||||
field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery });
|
||||
}
|
||||
},
|
||||
|
@ -158,7 +158,7 @@ export const QueryBarDefineRule = ({
|
|||
const onChangedQuery = useCallback(
|
||||
(newQuery: Query) => {
|
||||
const { query } = field.value as FieldValueQueryBar;
|
||||
if (!isEqual(query, newQuery)) {
|
||||
if (!deepEqual(query, newQuery)) {
|
||||
field.setValue({ ...(field.value as FieldValueQueryBar), query: newQuery });
|
||||
}
|
||||
},
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
EuiLoadingSpinner,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { memo, useCallback, useEffect, useState } from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { useRuleStatus, RuleInfoStatus } from '../../../../../containers/detection_engine/rules';
|
||||
import { FormattedDate } from '../../../../../components/formatted_date';
|
||||
|
@ -43,7 +43,7 @@ const RuleStatusComponent: React.FC<RuleStatusProps> = ({ ruleId, ruleEnabled })
|
|||
}, [fetchRuleStatus, myRuleEnabled, ruleId, ruleEnabled, setMyRuleEnabled]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEqual(currentStatus, ruleStatus?.current_status)) {
|
||||
if (!deepEqual(currentStatus, ruleStatus?.current_status)) {
|
||||
setCurrentStatus(ruleStatus?.current_status ?? null);
|
||||
}
|
||||
}, [currentStatus, ruleStatus, setCurrentStatus]);
|
||||
|
|
|
@ -13,9 +13,9 @@ import {
|
|||
EuiSpacer,
|
||||
EuiButtonEmpty,
|
||||
} from '@elastic/eui';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { FC, memo, useCallback, useEffect, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { setFieldValue } from '../../helpers';
|
||||
import { RuleStepProps, RuleStep, AboutStepRule } from '../../types';
|
||||
|
@ -103,7 +103,7 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
|
|||
|
||||
useEffect(() => {
|
||||
const { isNew, ...initDefaultValue } = myStepData;
|
||||
if (defaultValues != null && !isEqual(initDefaultValue, defaultValues)) {
|
||||
if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) {
|
||||
const myDefaultValues = {
|
||||
...defaultValues,
|
||||
isNew: false,
|
||||
|
|
|
@ -11,9 +11,10 @@ import {
|
|||
EuiFlexItem,
|
||||
EuiButton,
|
||||
} from '@elastic/eui';
|
||||
import { isEmpty, isEqual } from 'lodash/fp';
|
||||
import { isEmpty } from 'lodash/fp';
|
||||
import React, { FC, memo, useCallback, useState, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/public';
|
||||
import { useFetchIndexPatterns } from '../../../../../containers/detection_engine/rules';
|
||||
|
@ -126,9 +127,9 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
|
|||
useEffect(() => {
|
||||
if (indicesConfig != null && defaultValues != null) {
|
||||
const myDefaultValues = getStepDefaultValue(indicesConfig, defaultValues);
|
||||
if (!isEqual(myDefaultValues, myStepData)) {
|
||||
if (!deepEqual(myDefaultValues, myStepData)) {
|
||||
setMyStepData(myDefaultValues);
|
||||
setLocalUseIndicesConfig(isEqual(myDefaultValues.index, indicesConfig));
|
||||
setLocalUseIndicesConfig(deepEqual(myDefaultValues.index, indicesConfig));
|
||||
setFieldValue(form, schema, myDefaultValues);
|
||||
}
|
||||
}
|
||||
|
@ -212,13 +213,13 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
|
|||
<FormDataProvider pathsToWatch="index">
|
||||
{({ index }) => {
|
||||
if (index != null) {
|
||||
if (isEqual(index, indicesConfig) && !localUseIndicesConfig) {
|
||||
if (deepEqual(index, indicesConfig) && !localUseIndicesConfig) {
|
||||
setLocalUseIndicesConfig(true);
|
||||
}
|
||||
if (!isEqual(index, indicesConfig) && localUseIndicesConfig) {
|
||||
if (!deepEqual(index, indicesConfig) && localUseIndicesConfig) {
|
||||
setLocalUseIndicesConfig(false);
|
||||
}
|
||||
if (index != null && !isEmpty(index) && !isEqual(index, mylocalIndicesConfig)) {
|
||||
if (index != null && !isEmpty(index) && !deepEqual(index, mylocalIndicesConfig)) {
|
||||
setMyLocalIndicesConfig(index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
|
||||
import { EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import React, { FC, memo, useCallback, useEffect, useState } from 'react';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { setFieldValue } from '../../helpers';
|
||||
import { RuleStep, RuleStepProps, ScheduleStepRule } from '../../types';
|
||||
|
@ -62,7 +62,7 @@ const StepScheduleRuleComponent: FC<StepScheduleRuleProps> = ({
|
|||
|
||||
useEffect(() => {
|
||||
const { isNew, ...initDefaultValue } = myStepData;
|
||||
if (defaultValues != null && !isEqual(initDefaultValue, defaultValues)) {
|
||||
if (defaultValues != null && !deepEqual(initDefaultValue, defaultValues)) {
|
||||
const myDefaultValues = {
|
||||
...defaultValues,
|
||||
isNew: false,
|
||||
|
|
|
@ -73,32 +73,25 @@ export const HostDetailsTabs = React.memo<HostDetailsTabsProps>(
|
|||
|
||||
return (
|
||||
<Switch>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.authentications})`}
|
||||
render={() => <AuthenticationsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.hosts})`}
|
||||
render={() => <HostsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.uncommonProcesses})`}
|
||||
render={() => <UncommonProcessQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.anomalies})`}
|
||||
render={() => (
|
||||
<AnomaliesQueryTabBody {...tabProps} AnomaliesTableComponent={AnomaliesHostTable} />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.events})`}
|
||||
render={() => <EventsQueryTabBody {...tabProps} pageFilters={pageFilters} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostDetailsPagePath}/:tabName(${HostsTableType.alerts})`}
|
||||
render={() => <HostAlertsQueryTabBody {...tabProps} pageFilters={pageFilters} />}
|
||||
/>
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.authentications})`}>
|
||||
<AuthenticationsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.hosts})`}>
|
||||
<HostsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.uncommonProcesses})`}>
|
||||
<UncommonProcessQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.anomalies})`}>
|
||||
<AnomaliesQueryTabBody {...tabProps} AnomaliesTableComponent={AnomaliesHostTable} />
|
||||
</Route>
|
||||
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.events})`}>
|
||||
<EventsQueryTabBody {...tabProps} pageFilters={pageFilters} />
|
||||
</Route>
|
||||
<Route path={`${hostDetailsPagePath}/:tabName(${HostsTableType.alerts})`}>
|
||||
<HostAlertsQueryTabBody {...tabProps} pageFilters={pageFilters} />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { HostsTabsProps } from './types';
|
||||
|
@ -22,7 +22,7 @@ import {
|
|||
} from './navigation';
|
||||
import { HostAlertsQueryTabBody } from './navigation/alerts_query_tab_body';
|
||||
|
||||
const HostsTabs = memo<HostsTabsProps>(
|
||||
export const HostsTabs = memo<HostsTabsProps>(
|
||||
({
|
||||
deleteQuery,
|
||||
filterQuery,
|
||||
|
@ -44,49 +44,48 @@ const HostsTabs = memo<HostsTabsProps>(
|
|||
startDate: from,
|
||||
type,
|
||||
indexPattern,
|
||||
narrowDateRange: (score: Anomaly, interval: string) => {
|
||||
const fromTo = scoreIntervalToDateTime(score, interval);
|
||||
setAbsoluteRangeDatePicker({
|
||||
id: 'global',
|
||||
from: fromTo.from,
|
||||
to: fromTo.to,
|
||||
});
|
||||
},
|
||||
narrowDateRange: useCallback(
|
||||
(score: Anomaly, interval: string) => {
|
||||
const fromTo = scoreIntervalToDateTime(score, interval);
|
||||
setAbsoluteRangeDatePicker({
|
||||
id: 'global',
|
||||
from: fromTo.from,
|
||||
to: fromTo.to,
|
||||
});
|
||||
},
|
||||
[setAbsoluteRangeDatePicker]
|
||||
),
|
||||
updateDateRange: useCallback(
|
||||
(min: number, max: number) => {
|
||||
setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
|
||||
},
|
||||
[setAbsoluteRangeDatePicker]
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.hosts})`}
|
||||
render={() => <HostsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.authentications})`}
|
||||
render={() => <AuthenticationsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.uncommonProcesses})`}
|
||||
render={() => <UncommonProcessQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.anomalies})`}
|
||||
render={() => (
|
||||
<AnomaliesQueryTabBody {...tabProps} AnomaliesTableComponent={AnomaliesHostTable} />
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.events})`}
|
||||
render={() => <EventsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${hostsPagePath}/:tabName(${HostsTableType.alerts})`}
|
||||
render={() => <HostAlertsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.hosts})`}>
|
||||
<HostsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.authentications})`}>
|
||||
<AuthenticationsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.uncommonProcesses})`}>
|
||||
<UncommonProcessQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.anomalies})`}>
|
||||
<AnomaliesQueryTabBody {...tabProps} AnomaliesTableComponent={AnomaliesHostTable} />
|
||||
</Route>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.events})`}>
|
||||
<EventsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${hostsPagePath}/:tabName(${HostsTableType.alerts})`}>
|
||||
<HostAlertsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
HostsTabs.displayName = 'HostsTabs';
|
||||
|
||||
export { HostsTabs };
|
||||
|
|
|
@ -23,77 +23,82 @@ import { TlsQueryTabBody } from './tls_query_tab_body';
|
|||
import { Anomaly } from '../../../components/ml/types';
|
||||
import { NetworkAlertsQueryTabBody } from './alerts_query_tab_body';
|
||||
|
||||
export const NetworkRoutes = ({
|
||||
networkPagePath,
|
||||
type,
|
||||
to,
|
||||
filterQuery,
|
||||
isInitializing,
|
||||
from,
|
||||
indexPattern,
|
||||
setQuery,
|
||||
setAbsoluteRangeDatePicker,
|
||||
}: NetworkRoutesProps) => {
|
||||
const narrowDateRange = useCallback(
|
||||
(score: Anomaly, interval: string) => {
|
||||
const fromTo = scoreIntervalToDateTime(score, interval);
|
||||
setAbsoluteRangeDatePicker({
|
||||
id: 'global',
|
||||
from: fromTo.from,
|
||||
to: fromTo.to,
|
||||
});
|
||||
},
|
||||
[setAbsoluteRangeDatePicker]
|
||||
);
|
||||
|
||||
const networkAnomaliesFilterQuery = {
|
||||
bool: {
|
||||
should: [
|
||||
{
|
||||
exists: {
|
||||
field: 'source.ip',
|
||||
},
|
||||
},
|
||||
{
|
||||
exists: {
|
||||
field: 'destination.ip',
|
||||
},
|
||||
},
|
||||
],
|
||||
minimum_should_match: 1,
|
||||
},
|
||||
};
|
||||
|
||||
const commonProps = {
|
||||
startDate: from,
|
||||
endDate: to,
|
||||
skip: isInitializing,
|
||||
export const NetworkRoutes = React.memo<NetworkRoutesProps>(
|
||||
({
|
||||
networkPagePath,
|
||||
type,
|
||||
narrowDateRange,
|
||||
setQuery,
|
||||
to,
|
||||
filterQuery,
|
||||
};
|
||||
|
||||
const tabProps = {
|
||||
...commonProps,
|
||||
isInitializing,
|
||||
from,
|
||||
indexPattern,
|
||||
};
|
||||
setQuery,
|
||||
setAbsoluteRangeDatePicker,
|
||||
}) => {
|
||||
const narrowDateRange = useCallback(
|
||||
(score: Anomaly, interval: string) => {
|
||||
const fromTo = scoreIntervalToDateTime(score, interval);
|
||||
setAbsoluteRangeDatePicker({
|
||||
id: 'global',
|
||||
from: fromTo.from,
|
||||
to: fromTo.to,
|
||||
});
|
||||
},
|
||||
[setAbsoluteRangeDatePicker]
|
||||
);
|
||||
const updateDateRange = useCallback(
|
||||
(min: number, max: number) => {
|
||||
setAbsoluteRangeDatePicker({ id: 'global', from: min, to: max });
|
||||
},
|
||||
[setAbsoluteRangeDatePicker]
|
||||
);
|
||||
|
||||
const anomaliesProps = {
|
||||
...commonProps,
|
||||
anomaliesFilterQuery: networkAnomaliesFilterQuery,
|
||||
AnomaliesTableComponent: AnomaliesNetworkTable,
|
||||
};
|
||||
const networkAnomaliesFilterQuery = {
|
||||
bool: {
|
||||
should: [
|
||||
{
|
||||
exists: {
|
||||
field: 'source.ip',
|
||||
},
|
||||
},
|
||||
{
|
||||
exists: {
|
||||
field: 'destination.ip',
|
||||
},
|
||||
},
|
||||
],
|
||||
minimum_should_match: 1,
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.dns})`}
|
||||
render={() => <DnsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.flows})`}
|
||||
render={() => (
|
||||
const commonProps = {
|
||||
startDate: from,
|
||||
endDate: to,
|
||||
skip: isInitializing,
|
||||
type,
|
||||
narrowDateRange,
|
||||
setQuery,
|
||||
filterQuery,
|
||||
};
|
||||
|
||||
const tabProps = {
|
||||
...commonProps,
|
||||
indexPattern,
|
||||
updateDateRange,
|
||||
};
|
||||
|
||||
const anomaliesProps = {
|
||||
...commonProps,
|
||||
anomaliesFilterQuery: networkAnomaliesFilterQuery,
|
||||
AnomaliesTableComponent: AnomaliesNetworkTable,
|
||||
};
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.dns})`}>
|
||||
<DnsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.flows})`}>
|
||||
<>
|
||||
<ConditionalFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
|
@ -118,31 +123,25 @@ export const NetworkRoutes = ({
|
|||
</EuiFlexItem>
|
||||
</ConditionalFlexGroup>
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.http})`}
|
||||
render={() => <HttpQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.tls})`}
|
||||
render={() => <TlsQueryTabBody {...tabProps} flowTarget={FlowTargetSourceDest.source} />}
|
||||
/>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.anomalies})`}
|
||||
render={() => (
|
||||
</Route>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.http})`}>
|
||||
<HttpQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.tls})`}>
|
||||
<TlsQueryTabBody {...tabProps} flowTarget={FlowTargetSourceDest.source} />
|
||||
</Route>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.anomalies})`}>
|
||||
<AnomaliesQueryTabBody
|
||||
{...anomaliesProps}
|
||||
AnomaliesTableComponent={AnomaliesNetworkTable}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path={`${networkPagePath}/:tabName(${NetworkRouteType.alerts})`}
|
||||
render={() => <NetworkAlertsQueryTabBody {...tabProps} />}
|
||||
/>
|
||||
</Switch>
|
||||
);
|
||||
};
|
||||
</Route>
|
||||
<Route path={`${networkPagePath}/:tabName(${NetworkRouteType.alerts})`}>
|
||||
<NetworkAlertsQueryTabBody {...tabProps} />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
NetworkRoutes.displayName = 'NetworkRoutes';
|
||||
|
|
|
@ -20,8 +20,12 @@ const PageRouterComponent: FC<RouterProps> = ({ history }) => (
|
|||
<ManageRoutesSpy>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/" render={() => <HomePage />} />
|
||||
<Route render={() => <NotFoundPage />} />
|
||||
<Route path="/">
|
||||
<HomePage />
|
||||
</Route>
|
||||
<Route>
|
||||
<NotFoundPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</ManageRoutesSpy>
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import { Dispatch } from 'redux';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import { KueryFilterQuery } from '../../store';
|
||||
import { applyKqlFilterQuery as dispatchApplyTimelineFilterQuery } from '../../store/timeline/actions';
|
||||
|
@ -29,7 +29,7 @@ export const useUpdateKql = ({
|
|||
timelineId,
|
||||
}: UseUpdateKqlProps): RefetchKql => {
|
||||
const updateKql: RefetchKql = (dispatch: Dispatch) => {
|
||||
if (kueryFilterQueryDraft != null && !isEqual(kueryFilterQuery, kueryFilterQueryDraft)) {
|
||||
if (kueryFilterQueryDraft != null && !deepEqual(kueryFilterQuery, kueryFilterQueryDraft)) {
|
||||
if (storeType === 'timelineType' && timelineId != null) {
|
||||
dispatch(
|
||||
dispatchApplyTimelineFilterQuery({
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import * as H from 'history';
|
||||
import { isEqual } from 'lodash/fp';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
@ -35,7 +34,7 @@ export const SpyRouteComponent = memo<SpyRouteProps & { location: H.Location }>(
|
|||
}
|
||||
}, [search]);
|
||||
useEffect(() => {
|
||||
if (pageName && !isEqual(route.pathName, pathname)) {
|
||||
if (pageName && !deepEqual(route.pathName, pathname)) {
|
||||
if (isInitializing && detailName == null) {
|
||||
dispatch({
|
||||
type: 'updateRouteWithOutSearch',
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
"@types/uuid": "^3.4.4",
|
||||
"@types/xml-crypto": "^1.4.0",
|
||||
"@types/xml2js": "^0.4.5",
|
||||
"@welldone-software/why-did-you-render": "^4.0.0",
|
||||
"abab": "^1.0.4",
|
||||
"axios": "^0.19.0",
|
||||
"babel-jest": "^24.9.0",
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"x-pack/test_utils/*"
|
||||
],
|
||||
"plugins/*": ["src/legacy/core_plugins/*/public/"],
|
||||
"fixtures/*": ["src/fixtures/*"]
|
||||
"fixtures/*": ["src/fixtures/*"],
|
||||
},
|
||||
"types": [
|
||||
"node",
|
||||
|
|
|
@ -5684,6 +5684,13 @@
|
|||
text-table "^0.2.0"
|
||||
webpack-log "^1.1.2"
|
||||
|
||||
"@welldone-software/why-did-you-render@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@welldone-software/why-did-you-render/-/why-did-you-render-4.0.0.tgz#cc98c996f5a06ea55bd07dc99ba4b4d68af93332"
|
||||
integrity sha512-PjqriZ8Ak9biP2+kOcIrg+NwsFwWVhGV03Hm+ns84YBCArn+hWBKM9rMBEU6e62I1qyrYF2/G9yktNpEmfWfJA==
|
||||
dependencies:
|
||||
lodash "^4"
|
||||
|
||||
"@wry/context@^0.4.0":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.4.1.tgz#b3e23ca036035cbad0bd9711269352dd03a6fe3c"
|
||||
|
@ -19767,7 +19774,7 @@ lodash.uniqby@^4.7.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
|
||||
integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=
|
||||
|
||||
lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5:
|
||||
lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue