From b46a335f2bf03d6b8ce3ce5cb830bf4e998765b5 Mon Sep 17 00:00:00 2001 From: Kevin Logan <56395104+kevinlog@users.noreply.github.com> Date: Fri, 28 Feb 2020 11:25:36 -0800 Subject: [PATCH] [Endpoint] Task/add nav bar (#58604) * Add tabs to the Endpoint app. Uses EuiTabs and browser history for integration with react-router Co-authored-by: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Co-authored-by: Elastic Machine --- .../endpoint/components/header_nav.tsx | 76 +++++++++++++++++++ .../public/applications/endpoint/index.tsx | 2 + .../functional/apps/endpoint/header_nav.ts | 55 ++++++++++++++ x-pack/test/functional/apps/endpoint/index.ts | 1 + 4 files changed, 134 insertions(+) create mode 100644 x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx create mode 100644 x-pack/test/functional/apps/endpoint/header_nav.ts diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx new file mode 100644 index 0000000000000..84570fe82ed44 --- /dev/null +++ b/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx @@ -0,0 +1,76 @@ +/* + * 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 React, { MouseEvent } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiTabs, EuiTab } from '@elastic/eui'; +import { useHistory, useLocation } from 'react-router-dom'; + +export interface NavTabs { + name: string; + id: string; + href: string; +} + +export const navTabs: NavTabs[] = [ + { + id: 'home', + name: i18n.translate('xpack.endpoint.headerNav.home', { + defaultMessage: 'Home', + }), + href: '/', + }, + { + id: 'management', + name: i18n.translate('xpack.endpoint.headerNav.management', { + defaultMessage: 'Management', + }), + href: '/management', + }, + { + id: 'alerts', + name: i18n.translate('xpack.endpoint.headerNav.alerts', { + defaultMessage: 'Alerts', + }), + href: '/alerts', + }, + { + id: 'policies', + name: i18n.translate('xpack.endpoint.headerNav.policies', { + defaultMessage: 'Policies', + }), + href: '/policy', + }, +]; + +export const HeaderNavigation: React.FunctionComponent<{ basename: string }> = React.memo( + ({ basename }) => { + const history = useHistory(); + const location = useLocation(); + + function renderNavTabs(tabs: NavTabs[]) { + return tabs.map((tab, index) => { + return ( + { + event.preventDefault(); + history.push(tab.href); + }} + isSelected={tab.href === location.pathname} + > + {tab.name} + + ); + }); + } + + return {renderNavTabs(navTabs)}; + } +); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx index c6c032c273543..7ab66817a0888 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx @@ -16,6 +16,7 @@ import { appStoreFactory } from './store'; import { AlertIndex } from './view/alerts'; import { ManagementList } from './view/managing'; import { PolicyList } from './view/policy'; +import { HeaderNavigation } from './components/header_nav'; /** * This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle. @@ -41,6 +42,7 @@ const AppRoot: React.FunctionComponent = React.memo(({ basename, st + { + const pageObjects = getPageObjects(['common', 'endpoint']); + const testSubjects = getService('testSubjects'); + + describe('Header nav', function() { + this.tags('ciGroup7'); + before(async () => { + await pageObjects.common.navigateToApp('endpoint'); + }); + + it('renders the tabs when the app loads', async () => { + const homeTabText = await testSubjects.getVisibleText('homeEndpointTab'); + const managementTabText = await testSubjects.getVisibleText('managementEndpointTab'); + const alertsTabText = await testSubjects.getVisibleText('alertsEndpointTab'); + const policiesTabText = await testSubjects.getVisibleText('policiesEndpointTab'); + + expect(homeTabText.trim()).to.be('Home'); + expect(managementTabText.trim()).to.be('Management'); + expect(alertsTabText.trim()).to.be('Alerts'); + expect(policiesTabText.trim()).to.be('Policies'); + }); + + it('renders the management page when the Management tab is selected', async () => { + await (await testSubjects.find('managementEndpointTab')).click(); + await testSubjects.existOrFail('managementViewTitle'); + }); + + it('renders the alerts page when the Alerts tab is selected', async () => { + await (await testSubjects.find('alertsEndpointTab')).click(); + await testSubjects.existOrFail('alertListPage'); + }); + + it('renders the policy page when Policy tab is selected', async () => { + await (await testSubjects.find('policiesEndpointTab')).click(); + await testSubjects.existOrFail('policyViewTitle'); + }); + + it('renders the home page when Home tab is selected after selecting another tab', async () => { + await (await testSubjects.find('managementEndpointTab')).click(); + await testSubjects.existOrFail('managementViewTitle'); + + await (await testSubjects.find('homeEndpointTab')).click(); + await testSubjects.existOrFail('welcomeTitle'); + }); + }); +}; diff --git a/x-pack/test/functional/apps/endpoint/index.ts b/x-pack/test/functional/apps/endpoint/index.ts index 818c040f824d9..0c9179c23ea6c 100644 --- a/x-pack/test/functional/apps/endpoint/index.ts +++ b/x-pack/test/functional/apps/endpoint/index.ts @@ -11,6 +11,7 @@ export default function({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./landing_page')); + loadTestFile(require.resolve('./header_nav')); loadTestFile(require.resolve('./management')); loadTestFile(require.resolve('./policy_list')); loadTestFile(require.resolve('./alert_list'));