From 208e065a3aee7440c9f2cf7295cc817dd8b9fcd9 Mon Sep 17 00:00:00 2001 From: Pablo Neves Machado Date: Wed, 11 May 2022 11:11:02 +0200 Subject: [PATCH] Update navigation landing pages to use appLinks config --- .../public/app/translations.ts | 6 +- .../common/hooks/use_experimental_features.ts | 24 +-- .../common/images/detection_response_page.png | Bin 0 -> 28780 bytes .../public/common/links/links.ts | 11 ++ .../public/common/links/types.ts | 11 +- .../security_solution/public/hosts/links.ts | 6 + .../components/landing_links_icons.tsx | 33 ++-- .../components/landing_links_images.tsx | 34 ++-- .../public/landing_pages/constants.ts | 31 ++++ .../public/landing_pages/pages/dashboards.tsx | 35 ++--- .../public/landing_pages/pages/manage.tsx | 145 ++---------------- .../landing_pages/pages/threat_hunting.tsx | 56 ++----- .../icons/blocklist.tsx | 0 .../icons/endpoint_policies.tsx | 0 .../icons/endpoints.tsx | 0 .../icons/event_filters.tsx | 0 .../icons/exception_lists.tsx | 0 .../icons/host_isolation.tsx | 0 .../icons/siem_rules.tsx | 0 .../icons/trusted_applications.tsx | 0 .../public/management/links.ts | 44 ++++++ .../security_solution/public/network/links.ts | 6 + .../public/overview/links.ts | 11 ++ .../security_solution/public/users/links.ts | 5 + 24 files changed, 207 insertions(+), 251 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/images/detection_response_page.png create mode 100644 x-pack/plugins/security_solution/public/landing_pages/constants.ts rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/blocklist.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/endpoint_policies.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/endpoints.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/event_filters.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/exception_lists.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/host_isolation.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/siem_rules.tsx (100%) rename x-pack/plugins/security_solution/public/{landing_pages => management}/icons/trusted_applications.tsx (100%) diff --git a/x-pack/plugins/security_solution/public/app/translations.ts b/x-pack/plugins/security_solution/public/app/translations.ts index aa7eaa83685dbaf..e9a45c0397316e9 100644 --- a/x-pack/plugins/security_solution/public/app/translations.ts +++ b/x-pack/plugins/security_solution/public/app/translations.ts @@ -43,7 +43,7 @@ export const USERS = i18n.translate('xpack.securitySolution.navigation.users', { }); export const RULES = i18n.translate('xpack.securitySolution.navigation.rules', { - defaultMessage: 'Rules', + defaultMessage: 'SIEM rules', }); export const EXCEPTIONS = i18n.translate('xpack.securitySolution.navigation.exceptions', { @@ -71,7 +71,7 @@ export const ENDPOINTS = i18n.translate('xpack.securitySolution.search.administr export const POLICIES = i18n.translate( 'xpack.securitySolution.navigation.administration.policies', { - defaultMessage: 'Policies', + defaultMessage: 'Endpoint policies', } ); export const TRUSTED_APPLICATIONS = i18n.translate( @@ -90,7 +90,7 @@ export const EVENT_FILTERS = i18n.translate( export const HOST_ISOLATION_EXCEPTIONS = i18n.translate( 'xpack.securitySolution.search.administration.hostIsolationExceptions', { - defaultMessage: 'Host isolation exceptions', + defaultMessage: 'Host isolation IP exceptions', } ); export const DETECT = i18n.translate('xpack.securitySolution.navigation.detect', { diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_experimental_features.ts b/x-pack/plugins/security_solution/public/common/hooks/use_experimental_features.ts index 3132ae70381a299..1cc2506ec399686 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_experimental_features.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_experimental_features.ts @@ -14,14 +14,16 @@ import { const allowedExperimentalValues = getExperimentalAllowedValues(); -export const useIsExperimentalFeatureEnabled = (feature: keyof ExperimentalFeatures): boolean => - useSelector(({ app: { enableExperimental } }: State) => { - if (!enableExperimental || !(feature in enableExperimental)) { - throw new Error( - `Invalid enable value ${feature}. Allowed values are: ${allowedExperimentalValues.join( - ', ' - )}` - ); - } - return enableExperimental[feature]; - }); +export const useIsExperimentalFeatureEnabled = (feature: keyof ExperimentalFeatures): boolean => { + const enableExperimental = useEnableExperimental(); + + if (!enableExperimental || !(feature in enableExperimental)) { + throw new Error( + `Invalid enable value ${feature}. Allowed values are: ${allowedExperimentalValues.join(', ')}` + ); + } + return enableExperimental[feature]; +}; + +export const useEnableExperimental = (): ExperimentalFeatures => + useSelector(({ app: { enableExperimental } }: State) => enableExperimental); diff --git a/x-pack/plugins/security_solution/public/common/images/detection_response_page.png b/x-pack/plugins/security_solution/public/common/images/detection_response_page.png new file mode 100644 index 0000000000000000000000000000000000000000..c1651be0935efbb9d4f5889856edb3c809ac4783 GIT binary patch literal 28780 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 literal 0 HcmV?d00001 diff --git a/x-pack/plugins/security_solution/public/common/links/links.ts b/x-pack/plugins/security_solution/public/common/links/links.ts index 290a1f3fbd8208d..598d9aed578045b 100644 --- a/x-pack/plugins/security_solution/public/common/links/links.ts +++ b/x-pack/plugins/security_solution/public/common/links/links.ts @@ -8,6 +8,9 @@ import { AppDeepLink, AppNavLinkStatus, Capabilities } from '@kbn/core/public'; import { get } from 'lodash'; import { SecurityPageName } from '../../../common/constants'; +import { useEnableExperimental } from '../hooks/use_experimental_features'; +import { useLicense } from '../hooks/use_license'; +import { useKibana } from '../lib/kibana'; import { appLinks, getAppLinks } from './app_links'; import { Feature, @@ -195,3 +198,11 @@ export const getAncestorLinksInfo = (id: SecurityPageName): LinkInfo[] => { export const needsUrlState = (id: SecurityPageName): boolean => { return !getNormalizedLink(id).skipUrlState; }; + +export const useAppNavLinks = (): NavLinkItem[] => { + const license = useLicense(); + const enableExperimental = useEnableExperimental(); + const capabilities = useKibana().services.application.capabilities; + + return getNavLinkItems({ enableExperimental, license, capabilities }); +}; diff --git a/x-pack/plugins/security_solution/public/common/links/types.ts b/x-pack/plugins/security_solution/public/common/links/types.ts index eea348b3df73777..94ffd108a6d1fa0 100644 --- a/x-pack/plugins/security_solution/public/common/links/types.ts +++ b/x-pack/plugins/security_solution/public/common/links/types.ts @@ -7,6 +7,7 @@ import { Capabilities } from '@kbn/core/types'; import { LicenseType } from '@kbn/licensing-plugin/common/types'; +import { IconType } from '@elastic/eui'; import { LicenseService } from '../../../common/license'; import { ExperimentalFeatures } from '../../../common/experimental_features'; import { CASES_FEATURE_ID, SecurityPageName, SERVER_APP_ID } from '../../../common/constants'; @@ -41,8 +42,16 @@ export interface LinkItem { globalSearchEnabled?: boolean; globalSearchKeywords?: string[]; hideWhenExperimentalKey?: keyof ExperimentalFeatures; - icon?: string; + /** + * Icon that is displayed on menu navigation landing page. + * Only required for pages that are displayed inside a landing page. + */ + icon?: IconType; id: SecurityPageName; + /** + * Image that is displayed on menu navigation landing page. + * Only required for pages that are displayed inside a landing page. + */ image?: string; isBeta?: boolean; licenseType?: LicenseType; diff --git a/x-pack/plugins/security_solution/public/hosts/links.ts b/x-pack/plugins/security_solution/public/hosts/links.ts index 35730291d6c749c..49b41ee21b4c605 100644 --- a/x-pack/plugins/security_solution/public/hosts/links.ts +++ b/x-pack/plugins/security_solution/public/hosts/links.ts @@ -8,10 +8,16 @@ import { i18n } from '@kbn/i18n'; import { HOSTS_PATH, SecurityPageName } from '../../common/constants'; import { HOSTS } from '../app/translations'; import { LinkItem } from '../common/links/types'; +import hostsPageImg from '../common/images/hosts_page.png'; export const links: LinkItem = { id: SecurityPageName.hosts, title: HOSTS, + image: hostsPageImg, + description: i18n.translate('xpack.securitySolution.landing.threatHunting.hostsDescription', { + defaultMessage: + 'Computer or other device that communicates with other hosts on a network. Hosts on a network include clients and servers -- that send or receive data, services or applications.', + }), path: HOSTS_PATH, globalNavEnabled: true, globalSearchKeywords: [ diff --git a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_icons.tsx b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_icons.tsx index 82a0d2148f68350..04a3e20b1f17892 100644 --- a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_icons.tsx +++ b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_icons.tsx @@ -4,33 +4,18 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { - EuiFlexGrid, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiText, - EuiTitle, - IconType, -} from '@elastic/eui'; +import { EuiFlexGrid, EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiTitle } from '@elastic/eui'; import React from 'react'; import styled from 'styled-components'; -import { SecurityPageName } from '../../app/types'; + import { SecuritySolutionLinkAnchor, withSecuritySolutionLink, } from '../../common/components/links'; +import { NavLinkItem } from '../../common/links/types'; interface LandingLinksImagesProps { - items: NavItem[]; -} - -export interface NavItem { - id: SecurityPageName; - label: string; - icon: IconType; - description: string; - path?: string; + items: NavLinkItem[]; } const Link = styled.a` @@ -50,7 +35,7 @@ const StyledEuiTitle = styled(EuiTitle)` export const LandingLinksIcons: React.FC = ({ items }) => ( - {items.map(({ label, description, path, id, icon }) => ( + {items.map(({ title, description, id, icon }) => ( = ({ items }) responsive={false} > - - - -

{label}

+ +

{title}

diff --git a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx index b6a16da8cdc82eb..a534405f8750600 100644 --- a/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx +++ b/x-pack/plugins/security_solution/public/landing_pages/components/landing_links_images.tsx @@ -7,19 +7,11 @@ import { EuiFlexGroup, EuiFlexItem, EuiImage, EuiPanel, EuiText, EuiTitle } from '@elastic/eui'; import React from 'react'; import styled from 'styled-components'; -import { SecurityPageName } from '../../app/types'; import { withSecuritySolutionLink } from '../../common/components/links'; +import { LinkInfo } from '../../common/links/types'; interface LandingLinksImagesProps { - items: NavItem[]; -} - -export interface NavItem { - id: SecurityPageName; - label: string; - image: string; - description: string; - path?: string; + items: LinkInfo[]; } const PrimaryEuiTitle = styled(EuiTitle)` @@ -47,24 +39,26 @@ const Content = styled(EuiFlexItem)` export const LandingLinksImages: React.FC = ({ items }) => ( - {items.map(({ label, description, path, image, id }) => ( + {items.map(({ title, description, image, id }) => ( - + {/* Empty onClick is to force hover style on `EuiPanel` */} {}}> - + {image && ( + + )} -

{label}

+

{title}

{description} diff --git a/x-pack/plugins/security_solution/public/landing_pages/constants.ts b/x-pack/plugins/security_solution/public/landing_pages/constants.ts new file mode 100644 index 000000000000000..aa7c09fac0edb0f --- /dev/null +++ b/x-pack/plugins/security_solution/public/landing_pages/constants.ts @@ -0,0 +1,31 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { SecurityPageName } from '../app/types'; + +export const MANAGE_NAVIGATION_CATEGORIES = [ + { + label: i18n.translate('xpack.securitySolution.landing.siemTitle', { + defaultMessage: 'SIEM', + }), + itemIds: [SecurityPageName.rules, SecurityPageName.exceptions], + }, + { + label: i18n.translate('xpack.securitySolution.landing.endpointsTitle', { + defaultMessage: 'ENDPOINTS', + }), + itemIds: [ + SecurityPageName.endpoints, + SecurityPageName.policies, + SecurityPageName.trustedApps, + SecurityPageName.eventFilters, + SecurityPageName.blocklist, + SecurityPageName.hostIsolationExceptions, + ], + }, +]; diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx b/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx index 8c49fda169ad371..c2d5a3d8d2ee97c 100644 --- a/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/dashboards.tsx @@ -5,31 +5,24 @@ * 2.0. */ import React from 'react'; -import { i18n } from '@kbn/i18n'; import { SecurityPageName } from '../../app/types'; import { HeaderPage } from '../../common/components/header_page'; import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { SpyRoute } from '../../common/utils/route/spy_routes'; -import { LandingLinksImages, NavItem } from '../components/landing_links_images'; +import { LandingLinksImages } from '../components/landing_links_images'; import { DASHBOARDS_PAGE_TITLE } from './translations'; -import overviewPageImg from '../../common/images/overview_page.png'; -import { OVERVIEW } from '../../app/translations'; +import { useAppNavLinks } from '../../common/links'; -const items: NavItem[] = [ - { - id: SecurityPageName.overview, - label: OVERVIEW, - description: i18n.translate('xpack.securitySolution.landing.dashboards.overviewDescription', { - defaultMessage: 'What is going in your secuity environment', - }), - image: overviewPageImg, - }, -]; +export const DashboardsLandingPage = () => { + const dashboardlinks = useAppNavLinks().find( + ({ id }) => id === SecurityPageName.dashboardsLanding + ); -export const DashboardsLandingPage = () => ( - - - - - -); + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/manage.tsx b/x-pack/plugins/security_solution/public/landing_pages/pages/manage.tsx index da4d25f62130580..377df36ba30d463 100644 --- a/x-pack/plugins/security_solution/public/landing_pages/pages/manage.tsx +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/manage.tsx @@ -5,140 +5,25 @@ * 2.0. */ import { EuiHorizontalRule, EuiSpacer, EuiTitle } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import { compact } from 'lodash/fp'; import React from 'react'; import styled from 'styled-components'; -import { - BLOCKLIST, - ENDPOINTS, - EVENT_FILTERS, - EXCEPTIONS, - TRUSTED_APPLICATIONS, -} from '../../app/translations'; + import { SecurityPageName } from '../../app/types'; import { HeaderPage } from '../../common/components/header_page'; import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; +import { useAppNavLinks } from '../../common/links'; +import { NavLinkItem } from '../../common/links/types'; import { SpyRoute } from '../../common/utils/route/spy_routes'; -import { LandingLinksIcons, NavItem } from '../components/landing_links_icons'; -import { IconBlocklist } from '../icons/blocklist'; -import { IconEndpoints } from '../icons/endpoints'; -import { IconEndpointPolicies } from '../icons/endpoint_policies'; -import { IconEventFilters } from '../icons/event_filters'; -import { IconExceptionLists } from '../icons/exception_lists'; -import { IconHostIsolation } from '../icons/host_isolation'; -import { IconSiemRules } from '../icons/siem_rules'; -import { IconTrustedApplications } from '../icons/trusted_applications'; -import { MANAGE_PAGE_TITLE } from './translations'; - -// TODO -const FIX_ME_TEMPORARY_DESCRIPTION = 'Description here'; - -export interface NavConfigType { - items: NavItem[]; - categories: Array<{ label: string; itemIds: SecurityPageName[] }>; -} +import { LandingLinksIcons } from '../components/landing_links_icons'; +import { MANAGE_NAVIGATION_CATEGORIES } from '../constants'; -const config: NavConfigType = { - categories: [ - { - label: i18n.translate('xpack.securitySolution.landing.threatHunting.siemTitle', { - defaultMessage: 'SIEM', - }), - itemIds: [SecurityPageName.rules, SecurityPageName.exceptions], - }, - { - label: i18n.translate('xpack.securitySolution.landing.threatHunting.endpointsTitle', { - defaultMessage: 'ENDPOINTS', - }), - itemIds: [ - SecurityPageName.endpoints, - SecurityPageName.policies, - SecurityPageName.trustedApps, - SecurityPageName.eventFilters, - SecurityPageName.blocklist, - SecurityPageName.hostIsolationExceptions, - ], - }, - ], - items: [ - { - id: SecurityPageName.rules, - label: i18n.translate('xpack.securitySolution.landing.manage.rulesLabel', { - defaultMessage: 'SIEM rules', - }), - description: FIX_ME_TEMPORARY_DESCRIPTION, - icon: IconSiemRules, - }, - { - id: SecurityPageName.exceptions, - label: EXCEPTIONS, - description: FIX_ME_TEMPORARY_DESCRIPTION, - icon: IconExceptionLists, - }, - { - id: SecurityPageName.endpoints, - label: ENDPOINTS, - description: i18n.translate('xpack.securitySolution.landing.manage.endpointsDescription', { - defaultMessage: 'Hosts running endpoint security', - }), - icon: IconEndpoints, - }, - { - id: SecurityPageName.policies, - label: i18n.translate('xpack.securitySolution.landing.manage.endpointPoliceLabel', { - defaultMessage: 'Endpoint policies', - }), - description: FIX_ME_TEMPORARY_DESCRIPTION, - icon: IconEndpointPolicies, - }, - { - id: SecurityPageName.trustedApps, - label: TRUSTED_APPLICATIONS, - description: i18n.translate( - 'xpack.securitySolution.landing.manage.trustedApplicationsDescription', - { - defaultMessage: - 'Improve performance or alleviate conflicts with other applications running on your hosts', - } - ), - icon: IconTrustedApplications, - }, - { - id: SecurityPageName.eventFilters, - label: EVENT_FILTERS, - description: i18n.translate('xpack.securitySolution.landing.manage.eventFiltersDescription', { - defaultMessage: 'Exclude unwanted applications from running on your hosts', - }), - icon: IconEventFilters, - }, - { - id: SecurityPageName.blocklist, - label: BLOCKLIST, - description: FIX_ME_TEMPORARY_DESCRIPTION, - icon: IconBlocklist, - }, - { - id: SecurityPageName.hostIsolationExceptions, - label: i18n.translate('xpack.securitySolution.landing.manage.hostIsolationLabel', { - defaultMessage: 'Host isolation IP exceptions', - }), - description: i18n.translate( - 'xpack.securitySolution.landing.manage.hostIsolationDescription', - { - defaultMessage: 'Allow isolated hosts to communicate with specific IPs', - } - ), - - icon: IconHostIsolation, - }, - ], -}; +import { MANAGE_PAGE_TITLE } from './translations'; export const ManageLandingPage = () => ( - + ); @@ -148,16 +33,18 @@ const StyledEuiHorizontalRule = styled(EuiHorizontalRule)` margin-bottom: ${({ theme }) => theme.eui.paddingSizes.l}; `; -const getNavItembyId = (navConfig: NavConfigType) => (itemId: string) => - navConfig.items.find(({ id }: NavItem) => id === itemId); +const getNavItembyId = (links: NavLinkItem[]) => (itemId: string) => + links.find(({ id }: NavLinkItem) => id === itemId); + +const navItemsFromIds = (itemIds: SecurityPageName[], links: NavLinkItem[]) => + compact(itemIds.map(getNavItembyId(links))); -const navItemsFromIds = (itemIds: SecurityPageName[], navConfig: NavConfigType) => - compact(itemIds.map(getNavItembyId(navConfig))); +export const LandingCategories = React.memo(() => { + const manageLink = useAppNavLinks().find(({ id }) => id === SecurityPageName.administration); -export const LandingCategories = React.memo(({ navConfig }: { navConfig: NavConfigType }) => { return ( <> - {navConfig.categories.map(({ label, itemIds }, index) => ( + {MANAGE_NAVIGATION_CATEGORIES.map(({ label, itemIds }, index) => (
{index > 0 && ( <> @@ -169,7 +56,7 @@ export const LandingCategories = React.memo(({ navConfig }: { navConfig: NavConf

{label}

- +
))} diff --git a/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx b/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx index 2a0f4e471a75de8..7d486c102a2ddfe 100644 --- a/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx +++ b/x-pack/plugins/security_solution/public/landing_pages/pages/threat_hunting.tsx @@ -5,51 +5,23 @@ * 2.0. */ import React from 'react'; -import { i18n } from '@kbn/i18n'; import { SecurityPageName } from '../../app/types'; import { HeaderPage } from '../../common/components/header_page'; import { SecuritySolutionPageWrapper } from '../../common/components/page_wrapper'; import { SpyRoute } from '../../common/utils/route/spy_routes'; -import { LandingLinksImages, NavItem } from '../components/landing_links_images'; +import { LandingLinksImages } from '../components/landing_links_images'; import { THREAT_HUNTING_PAGE_TITLE } from './translations'; -import userPageImg from '../../common/images/users_page.png'; -import hostsPageImg from '../../common/images/hosts_page.png'; -import networkPageImg from '../../common/images/network_page.png'; -import { HOSTS, NETWORK, USERS } from '../../app/translations'; +import { useAppNavLinks } from '../../common/links'; -const items: NavItem[] = [ - { - id: SecurityPageName.hosts, - label: HOSTS, - description: i18n.translate('xpack.securitySolution.landing.threatHunting.hostsDescription', { - defaultMessage: - 'Computer or other device that communicates with other hosts on a network. Hosts on a network include clients and servers -- that send or receive data, services or applications.', - }), - image: hostsPageImg, - }, - { - id: SecurityPageName.network, - label: NETWORK, - description: i18n.translate('xpack.securitySolution.landing.threatHunting.networkDescription', { - defaultMessage: - 'The action or process of interacting with others to exchange information and develop professional or social contacts.', - }), - image: networkPageImg, - }, - { - id: SecurityPageName.users, - label: USERS, - description: i18n.translate('xpack.securitySolution.landing.threatHunting.usersDescription', { - defaultMessage: 'Sudo commands dashboard from the Logs System integration.', - }), - image: userPageImg, - }, -]; - -export const ThreatHuntingLandingPage = () => ( - - - - - -); +export const ThreatHuntingLandingPage = () => { + const threatHuntinglinks = useAppNavLinks().find( + ({ id }) => id === SecurityPageName.threatHuntingLanding + ); + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/blocklist.tsx b/x-pack/plugins/security_solution/public/management/icons/blocklist.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/blocklist.tsx rename to x-pack/plugins/security_solution/public/management/icons/blocklist.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/endpoint_policies.tsx b/x-pack/plugins/security_solution/public/management/icons/endpoint_policies.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/endpoint_policies.tsx rename to x-pack/plugins/security_solution/public/management/icons/endpoint_policies.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/endpoints.tsx b/x-pack/plugins/security_solution/public/management/icons/endpoints.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/endpoints.tsx rename to x-pack/plugins/security_solution/public/management/icons/endpoints.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/event_filters.tsx b/x-pack/plugins/security_solution/public/management/icons/event_filters.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/event_filters.tsx rename to x-pack/plugins/security_solution/public/management/icons/event_filters.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/exception_lists.tsx b/x-pack/plugins/security_solution/public/management/icons/exception_lists.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/exception_lists.tsx rename to x-pack/plugins/security_solution/public/management/icons/exception_lists.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/host_isolation.tsx b/x-pack/plugins/security_solution/public/management/icons/host_isolation.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/host_isolation.tsx rename to x-pack/plugins/security_solution/public/management/icons/host_isolation.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/siem_rules.tsx b/x-pack/plugins/security_solution/public/management/icons/siem_rules.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/siem_rules.tsx rename to x-pack/plugins/security_solution/public/management/icons/siem_rules.tsx diff --git a/x-pack/plugins/security_solution/public/landing_pages/icons/trusted_applications.tsx b/x-pack/plugins/security_solution/public/management/icons/trusted_applications.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/landing_pages/icons/trusted_applications.tsx rename to x-pack/plugins/security_solution/public/management/icons/trusted_applications.tsx diff --git a/x-pack/plugins/security_solution/public/management/links.ts b/x-pack/plugins/security_solution/public/management/links.ts index d941d538c80f7c6..6d24315b1e8b86a 100644 --- a/x-pack/plugins/security_solution/public/management/links.ts +++ b/x-pack/plugins/security_solution/public/management/links.ts @@ -31,6 +31,16 @@ import { } from '../app/translations'; import { FEATURE, LinkItem } from '../common/links/types'; +import { IconBlocklist } from './icons/blocklist'; +import { IconEndpoints } from './icons/endpoints'; +import { IconEndpointPolicies } from './icons/endpoint_policies'; +import { IconEventFilters } from './icons/event_filters'; +import { IconExceptionLists } from './icons/exception_lists'; +import { IconHostIsolation } from './icons/host_isolation'; +import { IconSiemRules } from './icons/siem_rules'; +import { IconTrustedApplications } from './icons/trusted_applications'; +const FIX_ME_TEMPORARY_DESCRIPTION = 'Description here'; + export const links: LinkItem = { id: SecurityPageName.administration, title: MANAGE, @@ -47,6 +57,8 @@ export const links: LinkItem = { { id: SecurityPageName.rules, title: RULES, + description: FIX_ME_TEMPORARY_DESCRIPTION, + icon: IconSiemRules, path: RULES_PATH, globalNavEnabled: false, globalSearchKeywords: [ @@ -59,6 +71,8 @@ export const links: LinkItem = { { id: SecurityPageName.exceptions, title: EXCEPTIONS, + description: FIX_ME_TEMPORARY_DESCRIPTION, + icon: IconExceptionLists, path: EXCEPTIONS_PATH, globalNavEnabled: false, globalSearchKeywords: [ @@ -70,6 +84,10 @@ export const links: LinkItem = { }, { id: SecurityPageName.endpoints, + description: i18n.translate('xpack.securitySolution.appLinks.endpointsDescription', { + defaultMessage: 'Hosts running endpoint security', + }), + icon: IconEndpoints, globalNavEnabled: true, title: ENDPOINTS, globalNavOrder: 9006, @@ -79,6 +97,14 @@ export const links: LinkItem = { { id: SecurityPageName.policies, title: POLICIES, + description: i18n.translate( + 'xpack.securitySolution.appLinks.trustedApplicationsDescription', + { + defaultMessage: + 'Use policies to customize endpoint and cloud workload protections and other configurations', + } + ), + icon: IconEndpointPolicies, path: POLICIES_PATH, skipUrlState: true, experimentalKey: 'policyListEnabled', @@ -86,24 +112,42 @@ export const links: LinkItem = { { id: SecurityPageName.trustedApps, title: TRUSTED_APPLICATIONS, + description: i18n.translate( + 'xpack.securitySolution.appLinks.trustedApplicationsDescription', + { + defaultMessage: + 'Improve performance or alleviate conflicts with other applications running on your hosts', + } + ), + icon: IconTrustedApplications, path: TRUSTED_APPS_PATH, skipUrlState: true, }, { id: SecurityPageName.eventFilters, title: EVENT_FILTERS, + description: i18n.translate('xpack.securitySolution.appLinks.eventFiltersDescription', { + defaultMessage: 'Exclude unwanted applications from running on your hosts', + }), + icon: IconEventFilters, path: EVENT_FILTERS_PATH, skipUrlState: true, }, { id: SecurityPageName.hostIsolationExceptions, title: HOST_ISOLATION_EXCEPTIONS, + description: i18n.translate('xpack.securitySolution.appLinks.hostIsolationDescription', { + defaultMessage: 'Allow isolated hosts to communicate with specific IPs', + }), + icon: IconHostIsolation, path: HOST_ISOLATION_EXCEPTIONS_PATH, skipUrlState: true, }, { id: SecurityPageName.blocklist, title: BLOCKLIST, + description: FIX_ME_TEMPORARY_DESCRIPTION, + icon: IconBlocklist, path: BLOCKLIST_PATH, skipUrlState: true, }, diff --git a/x-pack/plugins/security_solution/public/network/links.ts b/x-pack/plugins/security_solution/public/network/links.ts index ad209a220eebcb3..e56b6cf0c505537 100644 --- a/x-pack/plugins/security_solution/public/network/links.ts +++ b/x-pack/plugins/security_solution/public/network/links.ts @@ -9,10 +9,16 @@ import { i18n } from '@kbn/i18n'; import { NETWORK_PATH, SecurityPageName } from '../../common/constants'; import { NETWORK } from '../app/translations'; import { LinkItem } from '../common/links/types'; +import networkPageImg from '../common/images/network_page.png'; export const links: LinkItem = { id: SecurityPageName.network, title: NETWORK, + image: networkPageImg, + description: i18n.translate('xpack.securitySolution.appLinks.network.description', { + defaultMessage: + 'The action or process of interacting with others to exchange information and develop professional or social contacts.', + }), path: NETWORK_PATH, globalNavEnabled: true, globalSearchKeywords: [ diff --git a/x-pack/plugins/security_solution/public/overview/links.ts b/x-pack/plugins/security_solution/public/overview/links.ts index 89f75053b3d6f9f..079bfc6a4a6e1c8 100644 --- a/x-pack/plugins/security_solution/public/overview/links.ts +++ b/x-pack/plugins/security_solution/public/overview/links.ts @@ -15,10 +15,16 @@ import { } from '../../common/constants'; import { DASHBOARDS, DETECTION_RESPONSE, GETTING_STARTED, OVERVIEW } from '../app/translations'; import { FEATURE, LinkItem } from '../common/links/types'; +import overviewPageImg from '../common/images/overview_page.png'; +import detectionResponsePageImg from '../common/images/detection_response_page.png'; export const overviewLinks: LinkItem = { id: SecurityPageName.overview, title: OVERVIEW, + image: overviewPageImg, + description: i18n.translate('xpack.securitySolution.appLinks.overviewDescription', { + defaultMessage: 'What is going in your secuity environment', + }), path: OVERVIEW_PATH, globalNavEnabled: true, features: [FEATURE.general], @@ -47,6 +53,11 @@ export const gettingStartedLinks: LinkItem = { export const detectionResponseLinks: LinkItem = { id: SecurityPageName.detectionAndResponse, title: DETECTION_RESPONSE, + image: detectionResponsePageImg, + description: i18n.translate('xpack.securitySolution.appLinks.detectionAndResponseDescription', { + defaultMessage: + "Monitor the impact of application and device performance from the end user's point of view.", + }), path: DETECTION_RESPONSE_PATH, globalNavEnabled: false, experimentalKey: 'detectionResponseEnabled', diff --git a/x-pack/plugins/security_solution/public/users/links.ts b/x-pack/plugins/security_solution/public/users/links.ts index bd7bef4af8e82f2..23ec332a0491792 100644 --- a/x-pack/plugins/security_solution/public/users/links.ts +++ b/x-pack/plugins/security_solution/public/users/links.ts @@ -9,10 +9,15 @@ import { i18n } from '@kbn/i18n'; import { SecurityPageName, USERS_PATH } from '../../common/constants'; import { USERS } from '../app/translations'; import { LinkItem } from '../common/links/types'; +import userPageImg from '../common/images/users_page.png'; export const links: LinkItem = { id: SecurityPageName.users, title: USERS, + image: userPageImg, + description: i18n.translate('xpack.securitySolution.appLinks.users.description', { + defaultMessage: 'Sudo commands dashboard from the Logs System integration.', + }), path: USERS_PATH, globalNavEnabled: true, experimentalKey: 'usersEnabled',