Skip to content

Commit b46a335

Browse files
kevinlogpaul-tavareselasticmachine
authored
[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 <elasticmachine@users.noreply.github.com>
1 parent 06ebbb3 commit b46a335

File tree

4 files changed

+134
-0
lines changed

4 files changed

+134
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import React, { MouseEvent } from 'react';
8+
import { i18n } from '@kbn/i18n';
9+
import { EuiTabs, EuiTab } from '@elastic/eui';
10+
import { useHistory, useLocation } from 'react-router-dom';
11+
12+
export interface NavTabs {
13+
name: string;
14+
id: string;
15+
href: string;
16+
}
17+
18+
export const navTabs: NavTabs[] = [
19+
{
20+
id: 'home',
21+
name: i18n.translate('xpack.endpoint.headerNav.home', {
22+
defaultMessage: 'Home',
23+
}),
24+
href: '/',
25+
},
26+
{
27+
id: 'management',
28+
name: i18n.translate('xpack.endpoint.headerNav.management', {
29+
defaultMessage: 'Management',
30+
}),
31+
href: '/management',
32+
},
33+
{
34+
id: 'alerts',
35+
name: i18n.translate('xpack.endpoint.headerNav.alerts', {
36+
defaultMessage: 'Alerts',
37+
}),
38+
href: '/alerts',
39+
},
40+
{
41+
id: 'policies',
42+
name: i18n.translate('xpack.endpoint.headerNav.policies', {
43+
defaultMessage: 'Policies',
44+
}),
45+
href: '/policy',
46+
},
47+
];
48+
49+
export const HeaderNavigation: React.FunctionComponent<{ basename: string }> = React.memo(
50+
({ basename }) => {
51+
const history = useHistory();
52+
const location = useLocation();
53+
54+
function renderNavTabs(tabs: NavTabs[]) {
55+
return tabs.map((tab, index) => {
56+
return (
57+
<EuiTab
58+
data-testid={`${tab.id}EndpointTab`}
59+
data-test-subj={`${tab.id}EndpointTab`}
60+
key={index}
61+
href={`${basename}${tab.href}`}
62+
onClick={(event: MouseEvent) => {
63+
event.preventDefault();
64+
history.push(tab.href);
65+
}}
66+
isSelected={tab.href === location.pathname}
67+
>
68+
{tab.name}
69+
</EuiTab>
70+
);
71+
});
72+
}
73+
74+
return <EuiTabs>{renderNavTabs(navTabs)}</EuiTabs>;
75+
}
76+
);

x-pack/plugins/endpoint/public/applications/endpoint/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { appStoreFactory } from './store';
1616
import { AlertIndex } from './view/alerts';
1717
import { ManagementList } from './view/managing';
1818
import { PolicyList } from './view/policy';
19+
import { HeaderNavigation } from './components/header_nav';
1920

2021
/**
2122
* 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<RouterProps> = React.memo(({ basename, st
4142
<I18nProvider>
4243
<BrowserRouter basename={basename}>
4344
<RouteCapture>
45+
<HeaderNavigation basename={basename} />
4446
<Switch>
4547
<Route
4648
exact
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import expect from '@kbn/expect';
8+
import { FtrProviderContext } from '../../ftr_provider_context';
9+
10+
export default ({ getPageObjects, getService }: FtrProviderContext) => {
11+
const pageObjects = getPageObjects(['common', 'endpoint']);
12+
const testSubjects = getService('testSubjects');
13+
14+
describe('Header nav', function() {
15+
this.tags('ciGroup7');
16+
before(async () => {
17+
await pageObjects.common.navigateToApp('endpoint');
18+
});
19+
20+
it('renders the tabs when the app loads', async () => {
21+
const homeTabText = await testSubjects.getVisibleText('homeEndpointTab');
22+
const managementTabText = await testSubjects.getVisibleText('managementEndpointTab');
23+
const alertsTabText = await testSubjects.getVisibleText('alertsEndpointTab');
24+
const policiesTabText = await testSubjects.getVisibleText('policiesEndpointTab');
25+
26+
expect(homeTabText.trim()).to.be('Home');
27+
expect(managementTabText.trim()).to.be('Management');
28+
expect(alertsTabText.trim()).to.be('Alerts');
29+
expect(policiesTabText.trim()).to.be('Policies');
30+
});
31+
32+
it('renders the management page when the Management tab is selected', async () => {
33+
await (await testSubjects.find('managementEndpointTab')).click();
34+
await testSubjects.existOrFail('managementViewTitle');
35+
});
36+
37+
it('renders the alerts page when the Alerts tab is selected', async () => {
38+
await (await testSubjects.find('alertsEndpointTab')).click();
39+
await testSubjects.existOrFail('alertListPage');
40+
});
41+
42+
it('renders the policy page when Policy tab is selected', async () => {
43+
await (await testSubjects.find('policiesEndpointTab')).click();
44+
await testSubjects.existOrFail('policyViewTitle');
45+
});
46+
47+
it('renders the home page when Home tab is selected after selecting another tab', async () => {
48+
await (await testSubjects.find('managementEndpointTab')).click();
49+
await testSubjects.existOrFail('managementViewTitle');
50+
51+
await (await testSubjects.find('homeEndpointTab')).click();
52+
await testSubjects.existOrFail('welcomeTitle');
53+
});
54+
});
55+
};

x-pack/test/functional/apps/endpoint/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default function({ loadTestFile }: FtrProviderContext) {
1111

1212
loadTestFile(require.resolve('./feature_controls'));
1313
loadTestFile(require.resolve('./landing_page'));
14+
loadTestFile(require.resolve('./header_nav'));
1415
loadTestFile(require.resolve('./management'));
1516
loadTestFile(require.resolve('./policy_list'));
1617
loadTestFile(require.resolve('./alert_list'));

0 commit comments

Comments
 (0)