Skip to content

Commit

Permalink
[Security Solution] Changed landing page navigation (#129000)
Browse files Browse the repository at this point in the history
* [Security Solution] Changed landing page navigation

* made all landings big

* removed getting started from the main left menu; centered empty page content for security template

* fixed linting rules

* fixed linting rules

* fixed tests

* fixed tests

* fixed tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
YulNaumenko and kibanamachine authored Apr 2, 2022
1 parent d27702a commit a0cf450
Show file tree
Hide file tree
Showing 41 changed files with 183 additions and 218 deletions.
2 changes: 1 addition & 1 deletion src/core/public/chrome/ui/header/collapsible_nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const overviewIDsToHide = ['kibanaOverview', 'enterpriseSearch'];
const overviewIDs = [
...overviewIDsToHide,
'observability-overview',
'securitySolutionUI:overview',
'securitySolutionUI:get_started',
'management',
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const securitySolutionsDeepLinks: SecuritySolutionDeepLink[] = [
id: SecurityPageName.landing,
title: GETTING_STARTED,
path: LANDING_PATH,
navLinkStatus: AppNavLinkStatus.visible,
navLinkStatus: AppNavLinkStatus.hidden,
features: [FEATURE.general],
keywords: [
i18n.translate('xpack.securitySolution.search.getStarted', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,20 @@ import {
} from '../../../common/constants';

export const navTabs: SecurityNav = {
[SecurityPageName.overview]: {
id: SecurityPageName.overview,
name: i18n.OVERVIEW,
href: APP_OVERVIEW_PATH,
disabled: false,
urlKey: 'overview',
},
[SecurityPageName.landing]: {
id: SecurityPageName.landing,
name: i18n.GETTING_STARTED,
href: APP_LANDING_PATH,
disabled: false,
urlKey: 'get_started',
},
[SecurityPageName.overview]: {
id: SecurityPageName.overview,
name: i18n.OVERVIEW,
href: APP_OVERVIEW_PATH,
disabled: false,
urlKey: 'overview',
},
[SecurityPageName.detectionAndResponse]: {
id: SecurityPageName.detectionAndResponse,
name: i18n.DETECTION_RESPONSE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ export const SecuritySolutionTemplateWrapper: React.FC<SecuritySolutionPageWrapp

const userHasSecuritySolutionVisible = useKibana().services.application.capabilities.siem.show;
const showEmptyState = useShowPagesWithEmptyView();
const emptyStateProps = showEmptyState ? NO_DATA_PAGE_TEMPLATE_PROPS : {};
const emptyStateProps = showEmptyState
? { ...NO_DATA_PAGE_TEMPLATE_PROPS, template: 'centeredContent' }
: {};

/*
* StyledKibanaPageTemplate is a styled EuiPageTemplate. Security solution currently passes the header
Expand All @@ -101,21 +103,17 @@ export const SecuritySolutionTemplateWrapper: React.FC<SecuritySolutionPageWrapp
template="default"
{...emptyStateProps}
>
{showEmptyState ? (
children
) : (
<>
<GlobalKQLHeader />
<EuiPanel
className="securityPageWrapper"
data-test-subj="pageContainer"
hasShadow={false}
paddingSize="l"
>
{children}
</EuiPanel>
</>
)}
<>
<GlobalKQLHeader />
<EuiPanel
className="securityPageWrapper"
data-test-subj="pageContainer"
hasShadow={false}
paddingSize="l"
>
{children}
</EuiPanel>
</>
</StyledKibanaPageTemplate>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import endpointPng from '../../images/endpoint.png';
import siemPng from '../../images/siem.png';
import videoSvg from '../../images/video.svg';
import { ADD_DATA_PATH } from '../../../../common/constants';
import { useKibana } from '../../../common/lib/kibana';
import { useKibana } from '../../lib/kibana';

const imgUrls = {
siem: siemPng,
Expand Down

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { shallow } from 'enzyme';
import React from 'react';

import { LandingPageComponent } from './index';

describe('LandingPageComponent component', () => {
it('renders page properly', () => {
const EmptyComponent = shallow(<LandingPageComponent />);
expect(EmptyComponent).toMatchSnapshot();
});
});
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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React, { memo } from 'react';
import { LandingCards } from '../landing_cards';
import { SecuritySolutionPageWrapper } from '../page_wrapper';

export const LandingPageComponent = memo(() => {
return (
<SecuritySolutionPageWrapper>
<LandingCards />
</SecuritySolutionPageWrapper>
);
});

LandingPageComponent.displayName = 'LandingPageComponent';
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { SecurityPageName } from '../../../../app/types';

export { getDetectionEngineUrl } from '../redirect_to_detection_engine';
export { getAppOverviewUrl } from '../redirect_to_overview';
export { getAppLandingUrl } from '../redirect_to_landing';
export { getHostDetailsUrl, getHostsUrl } from '../redirect_to_hosts';
export { getNetworkUrl, getNetworkDetailsUrl } from '../redirect_to_network';
export { getTimelineTabsUrl, getTimelineUrl } from '../redirect_to_timelines';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { SecurityNavKey } from '../navigation/types';
import { SecurityPageName } from '../../../app/types';

export { getDetectionEngineUrl, getRuleDetailsUrl } from './redirect_to_detection_engine';
export { getAppOverviewUrl } from './redirect_to_overview';
export { getHostDetailsUrl, getTabsOnHostDetailsUrl, getHostsUrl } from './redirect_to_hosts';
export { getNetworkUrl, getNetworkDetailsUrl } from './redirect_to_network';
export { getTimelineTabsUrl, getTimelineUrl } from './redirect_to_timelines';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,5 @@
*/

import { appendSearch } from './helpers';
import { LANDING_PATH } from '../../../../common/constants';

export const getAppOverviewUrl = (overviewPath: string, search?: string) =>
`${overviewPath}${appendSearch(search)}`;

export const getAppLandingUrl = (search?: string) => `${LANDING_PATH}${appendSearch(search)}`;
export const getAppLandingUrl = (path: string, search?: string) => `${path}${appendSearch(search)}`;
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ describe('Navigation Breadcrumbs', () => {
);
expect(breadcrumbs).toEqual([
{
href: 'securitySolutionUI/overview',
href: 'securitySolutionUI/get_started',
text: 'Security',
},
{
Expand All @@ -178,7 +178,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Network',
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -196,7 +196,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Timelines',
href: "securitySolutionUI/timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -210,7 +210,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Hosts',
href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -229,7 +229,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Network',
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -248,7 +248,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Network',
href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -267,7 +267,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Alerts',
href: '',
Expand All @@ -281,7 +281,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Exceptions',
href: '',
Expand All @@ -295,7 +295,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Rules',
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -309,7 +309,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Rules',
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -335,7 +335,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Rules',
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand All @@ -361,7 +361,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Rules',
href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))",
Expand Down Expand Up @@ -406,7 +406,7 @@ describe('Navigation Breadcrumbs', () => {
getUrlForAppMock
);
expect(breadcrumbs).toEqual([
{ text: 'Security', href: 'securitySolutionUI/overview' },
{ text: 'Security', href: 'securitySolutionUI/get_started' },
{
text: 'Endpoints',
href: '',
Expand All @@ -428,7 +428,7 @@ describe('Navigation Breadcrumbs', () => {
expect(setBreadcrumbsMock).toBeCalledWith([
expect.objectContaining({
text: 'Security',
href: 'securitySolutionUI/overview',
href: 'securitySolutionUI/get_started',
onClick: expect.any(Function),
}),
expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
AdministrationRouteSpyState,
UsersRouteSpyState,
} from '../../../utils/route/types';
import { getAppOverviewUrl } from '../../link_to';
import { getAppLandingUrl } from '../../link_to/redirect_to_landing';
import { timelineActions } from '../../../../../public/timelines/store/timeline';
import { TimelineId } from '../../../../../common/types/timeline';
import { TabNavigationProps } from '../tab_navigation/types';
Expand Down Expand Up @@ -91,10 +91,11 @@ export const getBreadcrumbsForRoute = (
getUrlForApp: GetUrlForApp
): ChromeBreadcrumb[] | null => {
const spyState: RouteSpyState = omit('navTabs', object);
const overviewPath = getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.overview });
const landingPath = getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.landing });

const siemRootBreadcrumb: ChromeBreadcrumb = {
text: APP_NAME,
href: getAppOverviewUrl(overviewPath),
href: getAppLandingUrl(landingPath),
};
if (isHostsRoutes(spyState) && object.navTabs) {
const tempNav: SearchNavTab = { urlKey: 'host', isDetailPage: false };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,6 @@ describe('useSecuritySolutionNavigation', () => {
Object {
"id": "main",
"items": Array [
Object {
"data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
"data-test-subj": "navigation-overview",
"disabled": false,
"href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
"id": "overview",
"isSelected": false,
"name": "Overview",
"onClick": [Function],
},
Object {
"data-href": "securitySolutionUI/get_started?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
"data-test-subj": "navigation-get_started",
Expand All @@ -135,6 +125,16 @@ describe('useSecuritySolutionNavigation', () => {
"name": "Getting started",
"onClick": [Function],
},
Object {
"data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
"data-test-subj": "navigation-overview",
"disabled": false,
"href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))",
"id": "overview",
"isSelected": false,
"name": "Overview",
"onClick": [Function],
},
],
"name": "",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ function usePrimaryNavigationItemsToDisplay(navTabs: Record<string, NavTab>) {
id: 'main',
name: '',
items: [
navTabs[SecurityPageName.overview],
navTabs[SecurityPageName.landing],
navTabs[SecurityPageName.overview],
// Temporary check for detectionAndResponse while page is feature flagged
...(navTabs[SecurityPageName.detectionAndResponse] != null
? [navTabs[SecurityPageName.detectionAndResponse]]
Expand Down
Loading

0 comments on commit a0cf450

Please sign in to comment.