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

[SIEM] Fix link on overview page #60348

Merged
merged 7 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 { appendSearch } from './helpers';

describe('appendSearch', () => {
test('should return empty string if no parameter', () => {
expect(appendSearch()).toEqual('');
});
test('should return empty string if parameter is undefined', () => {
expect(appendSearch(undefined)).toEqual('');
});
test('should return parameter if parameter is defined', () => {
expect(appendSearch('helloWorld')).toEqual('helloWorld');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export const appendSearch = (search?: string) => (search != null ? `${search}` : '');
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import React from 'react';
import { RouteComponentProps } from 'react-router-dom';

import { DetectionEngineTab } from '../../pages/detection_engine/types';
import { appendSearch } from './helpers';
import { RedirectWrapper } from './redirect_wrapper';

export type DetectionEngineComponentProps = RouteComponentProps<{
Expand Down Expand Up @@ -63,9 +64,10 @@ export const RedirectToEditRulePage = ({

const baseDetectionEngineUrl = `#/link-to/${DETECTION_ENGINE_PAGE_NAME}`;

export const getDetectionEngineUrl = () => `${baseDetectionEngineUrl}`;
export const getDetectionEngineAlertUrl = () =>
`${baseDetectionEngineUrl}/${DetectionEngineTab.alerts}`;
export const getDetectionEngineUrl = (search?: string) =>
`${baseDetectionEngineUrl}${appendSearch(search)}`;
export const getDetectionEngineAlertUrl = (search?: string) =>
`${baseDetectionEngineUrl}/${DetectionEngineTab.alerts}${appendSearch(search)}`;
export const getDetectionEngineTabUrl = (tabPath: string) => `${baseDetectionEngineUrl}/${tabPath}`;
export const getRulesUrl = () => `${baseDetectionEngineUrl}/rules`;
export const getCreateRuleUrl = () => `${baseDetectionEngineUrl}/rules/create`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';

import { RedirectWrapper } from './redirect_wrapper';
import { HostsTableType } from '../../store/hosts/model';
import { SiemPageName } from '../../pages/home/types';

import { appendSearch } from './helpers';
import { RedirectWrapper } from './redirect_wrapper';

export type HostComponentProps = RouteComponentProps<{
detailName: string;
tabName: HostsTableType;
Expand Down Expand Up @@ -44,9 +46,10 @@ export const RedirectToHostDetailsPage = ({

const baseHostsUrl = `#/link-to/${SiemPageName.hosts}`;

export const getHostsUrl = () => baseHostsUrl;
export const getHostsUrl = (search?: string) => `${baseHostsUrl}${appendSearch(search)}`;

export const getTabsOnHostsUrl = (tabName: HostsTableType) => `${baseHostsUrl}/${tabName}`;
export const getTabsOnHostsUrl = (tabName: HostsTableType, search?: string) =>
`${baseHostsUrl}/${tabName}${appendSearch(search)}`;

export const getHostDetailsUrl = (detailName: string) => `${baseHostsUrl}/${detailName}`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';

import { RedirectWrapper } from './redirect_wrapper';
import { SiemPageName } from '../../pages/home/types';
import { FlowTarget, FlowTargetSourceDest } from '../../graphql/types';

import { appendSearch } from './helpers';
import { RedirectWrapper } from './redirect_wrapper';

export type NetworkComponentProps = RouteComponentProps<{
detailName?: string;
flowTarget?: string;
Expand All @@ -33,7 +35,7 @@ export const RedirectToNetworkPage = ({
);

const baseNetworkUrl = `#/link-to/${SiemPageName.network}`;
export const getNetworkUrl = () => baseNetworkUrl;
export const getNetworkUrl = (search?: string) => `${baseNetworkUrl}${appendSearch(search)}`;
export const getIPDetailsUrl = (
detailName: string,
flowTarget?: FlowTarget | FlowTargetSourceDest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

import React from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { RedirectWrapper } from './redirect_wrapper';

import { SiemPageName } from '../../pages/home/types';

import { appendSearch } from './helpers';
import { RedirectWrapper } from './redirect_wrapper';

export type TimelineComponentProps = RouteComponentProps<{
search: string;
}>;
Expand All @@ -17,4 +20,5 @@ export const RedirectToTimelinesPage = ({ location: { search } }: TimelineCompon
<RedirectWrapper to={`/${SiemPageName.timelines}${search}`} />
);

export const getTimelinesUrl = () => `#/link-to/${SiemPageName.timelines}`;
export const getTimelinesUrl = (search?: string) =>
`#/link-to/${SiemPageName.timelines}${appendSearch(search)}`;
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,17 @@ import { Location } from 'history';
import { UrlInputsModel } from '../../store/inputs/model';
import { TimelineUrl } from '../../store/timeline/model';
import { CONSTANTS } from '../url_state/constants';
import { URL_STATE_KEYS, KeyUrlState } from '../url_state/types';
import { URL_STATE_KEYS, KeyUrlState, UrlState } from '../url_state/types';
import {
replaceQueryStringInLocation,
replaceStateKeyInQueryString,
getQueryStringFromLocation,
} from '../url_state/helpers';
import { Query, Filter } from '../../../../../../../src/plugins/data/public';

import { TabNavigationProps } from './tab_navigation/types';
import { SearchNavTab } from './types';

export const getSearch = (tab: SearchNavTab, urlState: TabNavigationProps): string => {
export const getSearch = (tab: SearchNavTab, urlState: UrlState): string => {
if (tab && tab.urlKey != null && URL_STATE_KEYS[tab.urlKey] != null) {
return URL_STATE_KEYS[tab.urlKey].reduce<Location>(
(myLocation: Location, urlKey: KeyUrlState) => {
Expand Down Expand Up @@ -58,7 +57,7 @@ export const getSearch = (tab: SearchNavTab, urlState: TabNavigationProps): stri
);
},
{
pathname: urlState.pathName,
pathname: '',
hash: '',
search: '',
state: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export const TabNavigationComponent = (props: TabNavigationProps) => {
() =>
Object.values(navTabs).map(tab => {
const isSelected = selectedTabId === tab.id;
const hrefWithSearch = tab.href + getSearch(tab, props);
const { query, filters, savedQuery, timerange, timeline } = props;
const hrefWithSearch =
tab.href + getSearch(tab, { query, filters, savedQuery, timerange, timeline });

return (
<TabNavigationItem
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { isEqual } from 'lodash/fp';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';

import { makeMapStateToProps } from '../url_state/helpers';
import { getSearch } from './helpers';
import { SearchNavTab } from './types';

export const useGetUrlSearch = (tab: SearchNavTab) => {
const mapState = makeMapStateToProps();
const { urlState } = useSelector(mapState, isEqual);
const urlSearch = useMemo(() => getSearch(tab, urlState), [tab, urlState]);
return urlSearch;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isEmpty } from 'lodash/fp';
import { EuiButton, EuiFlexItem, EuiPanel } from '@elastic/eui';
import numeral from '@elastic/numeral';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { useMemo } from 'react';

import { DEFAULT_NUMBER_FORMAT } from '../../../../../common/constants';
import { ESQuery } from '../../../../../common/typed_json';
Expand All @@ -23,6 +23,8 @@ import { getOverviewHostStats, OverviewHostStats } from '../overview_host_stats'
import { manageQuery } from '../../../page/manage_query';
import { inputsModel } from '../../../../store/inputs';
import { InspectButtonContainer } from '../../../inspect';
import { useGetUrlSearch } from '../../../navigation/use_get_url_search';
import { navTabs } from '../../../../pages/home/home_navigations';

export interface OwnProps {
startDate: number;
Expand Down Expand Up @@ -51,7 +53,15 @@ const OverviewHostComponent: React.FC<OverviewHostProps> = ({
setQuery,
}) => {
const [defaultNumberFormat] = useUiSetting$<string>(DEFAULT_NUMBER_FORMAT);

const urlSearch = useGetUrlSearch(navTabs.hosts);
const hostPageButton = useMemo(
() => (
<EuiButton href={getHostsUrl(urlSearch)}>
<FormattedMessage id="xpack.siem.overview.hostsAction" defaultMessage="View hosts" />
</EuiButton>
),
[urlSearch]
);
return (
<EuiFlexItem>
<InspectButtonContainer>
Expand Down Expand Up @@ -95,12 +105,7 @@ const OverviewHostComponent: React.FC<OverviewHostProps> = ({
/>
}
>
<EuiButton href={getHostsUrl()}>
<FormattedMessage
id="xpack.siem.overview.hostsAction"
defaultMessage="View hosts"
/>
</EuiButton>
{hostPageButton}
</HeaderSection>

<OverviewHostStatsManage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { isEmpty } from 'lodash/fp';
import { EuiButton, EuiFlexItem, EuiPanel } from '@elastic/eui';
import numeral from '@elastic/numeral';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import React, { useMemo } from 'react';

import { DEFAULT_NUMBER_FORMAT } from '../../../../../common/constants';
import { ESQuery } from '../../../../../common/typed_json';
Expand All @@ -23,6 +23,8 @@ import { inputsModel } from '../../../../store/inputs';
import { getOverviewNetworkStats, OverviewNetworkStats } from '../overview_network_stats';
import { getNetworkUrl } from '../../../link_to';
import { InspectButtonContainer } from '../../../inspect';
import { useGetUrlSearch } from '../../../navigation/use_get_url_search';
import { navTabs } from '../../../../pages/home/home_navigations';

export interface OverviewNetworkProps {
startDate: number;
Expand Down Expand Up @@ -50,7 +52,15 @@ const OverviewNetworkComponent: React.FC<OverviewNetworkProps> = ({
setQuery,
}) => {
const [defaultNumberFormat] = useUiSetting$<string>(DEFAULT_NUMBER_FORMAT);

const urlSearch = useGetUrlSearch(navTabs.network);
const networkPageButton = useMemo(
() => (
<EuiButton href={getNetworkUrl(urlSearch)}>
<FormattedMessage id="xpack.siem.overview.networkAction" defaultMessage="View network" />
</EuiButton>
),
[urlSearch]
);
return (
<EuiFlexItem>
<InspectButtonContainer>
Expand Down Expand Up @@ -96,12 +106,7 @@ const OverviewNetworkComponent: React.FC<OverviewNetworkProps> = ({
/>
}
>
<EuiButton href={getNetworkUrl()}>
<FormattedMessage
id="xpack.siem.overview.networkAction"
defaultMessage="View network"
/>
</EuiButton>
{networkPageButton}
</HeaderSection>

<OverviewNetworkStatsManage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import ApolloClient from 'apollo-client';
import { EuiHorizontalRule, EuiLink, EuiText } from '@elastic/eui';
import React, { useCallback } from 'react';
import React, { useCallback, useMemo } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { Dispatch } from 'redux';

Expand All @@ -20,6 +20,9 @@ import { updateIsLoading as dispatchUpdateIsLoading } from '../../store/timeline
import { RecentTimelines } from './recent_timelines';
import * as i18n from './translations';
import { FilterMode } from './types';
import { useGetUrlSearch } from '../navigation/use_get_url_search';
import { navTabs } from '../../pages/home/home_navigations';
import { getTimelinesUrl } from '../link_to/redirect_to_timelines';

interface OwnProps {
apolloClient: ApolloClient<{}>;
Expand All @@ -45,6 +48,11 @@ const StatefulRecentTimelinesComponent = React.memo<Props>(

const noTimelinesMessage =
filterBy === 'favorites' ? i18n.NO_FAVORITE_TIMELINES : i18n.NO_TIMELINES;
const urlSearch = useGetUrlSearch(navTabs.timelines);
const linkAllTimelines = useMemo(
() => <EuiLink href={getTimelinesUrl(urlSearch)}>{i18n.VIEW_ALL_TIMELINES}</EuiLink>,
[urlSearch]
);

return (
<AllTimelinesQuery
Expand All @@ -71,9 +79,7 @@ const StatefulRecentTimelinesComponent = React.memo<Props>(
/>
)}
<EuiHorizontalRule margin="s" />
<EuiText size="xs">
<EuiLink href="#/link-to/timelines">{i18n.VIEW_ALL_TIMELINES}</EuiLink>
</EuiText>
<EuiText size="xs">{linkAllTimelines}</EuiText>
</>
)}
</AllTimelinesQuery>
Expand Down
38 changes: 2 additions & 36 deletions x-pack/legacy/plugins/siem/public/components/url_state/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@ import { TimelineUrl } from '../../store/timeline/model';
import { formatDate } from '../super_date_picker';
import { NavTab } from '../navigation/types';
import { CONSTANTS, UrlStateType } from './constants';
import {
LocationTypes,
UrlStateContainerPropTypes,
ReplaceStateInLocation,
UpdateUrlStateString,
} from './types';
import { ReplaceStateInLocation, UpdateUrlStateString } from './types';

export const decodeRisonUrlState = <T>(value: string | undefined): T | null => {
try {
Expand Down Expand Up @@ -113,42 +108,13 @@ export const getTitle = (
return navTabs[pageName] != null ? navTabs[pageName].name : '';
};

export const getCurrentLocation = (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI -> It was not used @stephmilovic told me and when I went in this files, I had to delete it ;)

pageName: string,
detailName: string | undefined
): LocationTypes => {
if (pageName === SiemPageName.overview) {
return CONSTANTS.overviewPage;
} else if (pageName === SiemPageName.hosts) {
if (detailName != null) {
return CONSTANTS.hostsDetails;
}
return CONSTANTS.hostsPage;
} else if (pageName === SiemPageName.network) {
if (detailName != null) {
return CONSTANTS.networkDetails;
}
return CONSTANTS.networkPage;
} else if (pageName === SiemPageName.detections) {
return CONSTANTS.detectionsPage;
} else if (pageName === SiemPageName.timelines) {
return CONSTANTS.timelinePage;
} else if (pageName === SiemPageName.case) {
if (detailName != null) {
return CONSTANTS.caseDetails;
}
return CONSTANTS.casePage;
}
return CONSTANTS.unknown;
};

export const makeMapStateToProps = () => {
const getInputsSelector = inputsSelectors.inputsSelector();
const getGlobalQuerySelector = inputsSelectors.globalQuerySelector();
const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector();
const getGlobalSavedQuerySelector = inputsSelectors.globalSavedQuerySelector();
const getTimelines = timelineSelectors.getTimelines();
const mapStateToProps = (state: State, { pageName, detailName }: UrlStateContainerPropTypes) => {
const mapStateToProps = (state: State) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pageName and detailName are not used in the function

const inputState = getInputsSelector(state);
const { linkTo: globalLinkTo, timerange: globalTimerange } = inputState.global;
const { linkTo: timelineLinkTo, timerange: timelineTimerange } = inputState.timeline;
Expand Down
Loading