Skip to content

Commit 7c7eaee

Browse files
Fixing conflicts
2 parents b69c2ad + eacdbcd commit 7c7eaee

10 files changed

Lines changed: 455 additions & 59 deletions

File tree

x-pack/plugins/endpoint/common/generate_data.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
import uuid from 'uuid';
88
import seedrandom from 'seedrandom';
99
import { AlertEvent, EndpointEvent, HostMetadata, OSFields, HostFields } from './types';
10+
// FIXME: move types/model to top-level
11+
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
12+
import { PolicyData } from '../public/applications/endpoint/types';
13+
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
14+
import { generatePolicy } from '../public/applications/endpoint/models/policy';
1015

1116
export type Event = AlertEvent | EndpointEvent;
1217

@@ -452,6 +457,39 @@ export class EndpointDocGenerator {
452457
}
453458
}
454459

460+
/**
461+
* Generates an Ingest `datasource` that includes the Endpoint Policy data
462+
*/
463+
public generatePolicyDatasource(): PolicyData {
464+
return {
465+
id: this.seededUUIDv4(),
466+
name: 'Endpoint Policy',
467+
description: 'Policy to protect the worlds data',
468+
config_id: this.seededUUIDv4(),
469+
enabled: true,
470+
output_id: '',
471+
inputs: [
472+
{
473+
type: 'endpoint',
474+
enabled: true,
475+
streams: [],
476+
config: {
477+
policy: {
478+
value: generatePolicy(),
479+
},
480+
},
481+
},
482+
],
483+
namespace: 'default',
484+
package: {
485+
name: 'endpoint',
486+
title: 'Elastic Endpoint',
487+
version: '1.0.0',
488+
},
489+
revision: 1,
490+
};
491+
}
492+
455493
private randomN(n: number): number {
456494
return Math.floor(this.random() * n);
457495
}

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

Lines changed: 28 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,17 @@
77
import * as React from 'react';
88
import ReactDOM from 'react-dom';
99
import { CoreStart, AppMountParameters, ScopedHistory } from 'kibana/public';
10-
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
11-
import { Route, Switch, Router } from 'react-router-dom';
12-
import { Provider } from 'react-redux';
10+
import { FormattedMessage } from '@kbn/i18n/react';
11+
import { Route, Switch } from 'react-router-dom';
1312
import { Store } from 'redux';
14-
import { useObservable } from 'react-use';
15-
import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public';
16-
import { RouteCapture } from './view/route_capture';
1713
import { EndpointPluginStartDependencies } from '../../plugin';
1814
import { appStoreFactory } from './store';
1915
import { AlertIndex } from './view/alerts';
2016
import { HostList } from './view/hosts';
2117
import { PolicyList } from './view/policy';
2218
import { PolicyDetails } from './view/policy';
2319
import { HeaderNavigation } from './components/header_nav';
24-
import { EuiThemeProvider } from '../../../../../legacy/common/eui_styled_components';
20+
import { AppRootProvider } from './view/app_root_provider';
2521
import { Setup } from './view/setup';
2622

2723
/**
@@ -50,55 +46,32 @@ interface RouterProps {
5046
}
5147

5248
const AppRoot: React.FunctionComponent<RouterProps> = React.memo(
53-
({
54-
history,
55-
store,
56-
coreStart: { http, notifications, uiSettings, application },
57-
depsStart: { data, ingestManager },
58-
}) => {
59-
const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode'));
60-
49+
({ history, store, coreStart, depsStart }) => {
6150
return (
62-
<Provider store={store}>
63-
<I18nProvider>
64-
<KibanaContextProvider services={{ http, notifications, application, data }}>
65-
<Setup ingestManager={ingestManager} notifications={notifications} />
66-
<EuiThemeProvider darkMode={isDarkMode}>
67-
<Router history={history}>
68-
<RouteCapture>
69-
<HeaderNavigation />
70-
<Switch>
71-
<Route
72-
exact
73-
path="/"
74-
render={() => (
75-
<h1 data-test-subj="welcomeTitle">
76-
<FormattedMessage
77-
id="xpack.endpoint.welcomeTitle"
78-
defaultMessage="Hello World"
79-
/>
80-
</h1>
81-
)}
82-
/>
83-
<Route path="/hosts" component={HostList} />
84-
<Route path="/alerts" component={AlertIndex} />
85-
<Route path="/policy" exact component={PolicyList} />
86-
<Route path="/policy/:id" exact component={PolicyDetails} />
87-
<Route
88-
render={() => (
89-
<FormattedMessage
90-
id="xpack.endpoint.notFound"
91-
defaultMessage="Page Not Found"
92-
/>
93-
)}
94-
/>
95-
</Switch>
96-
</RouteCapture>
97-
</Router>
98-
</EuiThemeProvider>
99-
</KibanaContextProvider>
100-
</I18nProvider>
101-
</Provider>
51+
<AppRootProvider store={store} history={history} coreStart={coreStart} depsStart={depsStart}>
52+
<Setup ingestManager={depsStart.ingestManager} notifications={coreStart.notifications} />
53+
<HeaderNavigation />
54+
<Switch>
55+
<Route
56+
exact
57+
path="/"
58+
render={() => (
59+
<h1 data-test-subj="welcomeTitle">
60+
<FormattedMessage id="xpack.endpoint.welcomeTitle" defaultMessage="Hello World" />
61+
</h1>
62+
)}
63+
/>
64+
<Route path="/hosts" component={HostList} />
65+
<Route path="/alerts" component={AlertIndex} />
66+
<Route path="/policy" exact component={PolicyList} />
67+
<Route path="/policy/:id" exact component={PolicyDetails} />
68+
<Route
69+
render={() => (
70+
<FormattedMessage id="xpack.endpoint.notFound" defaultMessage="Page Not Found" />
71+
)}
72+
/>
73+
</Switch>
74+
</AppRootProvider>
10275
);
10376
}
10477
);
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 from 'react';
8+
import { createMemoryHistory } from 'history';
9+
import { render as reactRender, RenderOptions, RenderResult } from '@testing-library/react';
10+
import { appStoreFactory } from '../store';
11+
import { coreMock } from '../../../../../../../src/core/public/mocks';
12+
import { EndpointPluginStartDependencies } from '../../../plugin';
13+
import { depsStartMock } from './dependencies_start_mock';
14+
import { AppRootProvider } from '../view/app_root_provider';
15+
16+
type UiRender = (ui: React.ReactElement, options?: RenderOptions) => RenderResult;
17+
18+
/**
19+
* Mocked app root context renderer
20+
*/
21+
interface AppContextTestRender {
22+
store: ReturnType<typeof appStoreFactory>;
23+
history: ReturnType<typeof createMemoryHistory>;
24+
coreStart: ReturnType<typeof coreMock.createStart>;
25+
depsStart: EndpointPluginStartDependencies;
26+
/**
27+
* A wrapper around `AppRootContext` component. Uses the mocked modules as input to the
28+
* `AppRootContext`
29+
*/
30+
AppWrapper: React.FC<any>;
31+
/**
32+
* Renders the given UI within the created `AppWrapper` providing the given UI a mocked
33+
* endpoint runtime context environment
34+
*/
35+
render: UiRender;
36+
}
37+
38+
/**
39+
* Creates a mocked endpoint app context custom renderer that can be used to render
40+
* component that depend upon the application's surrounding context providers.
41+
* Factory also returns the content that was used to create the custom renderer, allowing
42+
* for further customization.
43+
*/
44+
export const createAppRootMockRenderer = (): AppContextTestRender => {
45+
const history = createMemoryHistory<never>();
46+
const coreStart = coreMock.createStart({ basePath: '/mock' });
47+
const depsStart = depsStartMock();
48+
const store = appStoreFactory({ coreStart, depsStart });
49+
const AppWrapper: React.FunctionComponent<{ children: React.ReactElement }> = ({ children }) => (
50+
<AppRootProvider store={store} history={history} coreStart={coreStart} depsStart={depsStart}>
51+
{children}
52+
</AppRootProvider>
53+
);
54+
const render: UiRender = (ui, options) => {
55+
// @ts-ignore
56+
return reactRender(ui, {
57+
wrapper: AppWrapper,
58+
...options,
59+
});
60+
};
61+
62+
return {
63+
store,
64+
history,
65+
coreStart,
66+
depsStart,
67+
AppWrapper,
68+
render,
69+
};
70+
};

x-pack/plugins/endpoint/public/applications/endpoint/mocks.ts renamed to x-pack/plugins/endpoint/public/applications/endpoint/mocks/dependencies_start_mock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { IngestManagerStart } from '../../../../ingest_manager/public';
88
import {
99
dataPluginMock,
1010
Start as DataPublicStartMock,
11-
} from '../../../../../../src/plugins/data/public/mocks';
11+
} from '../../../../../../../src/plugins/data/public/mocks';
1212

1313
type DataMock = Omit<DataPublicStartMock, 'indexPatterns' | 'query'> & {
1414
indexPatterns: Omit<DataPublicStartMock['indexPatterns'], 'getFieldsForWildcard'> & {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
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+
export * from './dependencies_start_mock';
8+
export * from './app_context_render';

x-pack/plugins/endpoint/public/applications/endpoint/store/policy_details/reducer.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,12 @@ export const policyDetailsReducer: Reducer<PolicyDetailsState, AppAction> = (
7474
...state,
7575
location: action.payload,
7676
};
77+
const isCurrentlyOnDetailsPage = isOnPolicyDetailsPage(newState);
78+
const wasPreviouslyOnDetailsPage = isOnPolicyDetailsPage(state);
7779

78-
if (isOnPolicyDetailsPage(newState)) {
80+
// Did user just enter the Detail page? if so, then set the loading indicator and return new state
81+
if (isCurrentlyOnDetailsPage && !wasPreviouslyOnDetailsPage) {
82+
newState.isLoading = true;
7983
return newState;
8084
}
8185
return {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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, { memo, ReactNode, useMemo } from 'react';
8+
import { Provider } from 'react-redux';
9+
import { I18nProvider } from '@kbn/i18n/react';
10+
import { Router } from 'react-router-dom';
11+
import { History } from 'history';
12+
import { CoreStart } from 'kibana/public';
13+
import { useObservable } from 'react-use';
14+
import { EuiThemeProvider } from '../../../../../../legacy/common/eui_styled_components';
15+
import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
16+
import { appStoreFactory } from '../store';
17+
import { RouteCapture } from './route_capture';
18+
import { EndpointPluginStartDependencies } from '../../../plugin';
19+
20+
/**
21+
* Provides the context for rendering the endpoint app
22+
*/
23+
export const AppRootProvider = memo<{
24+
store: ReturnType<typeof appStoreFactory>;
25+
history: History;
26+
coreStart: CoreStart;
27+
depsStart: EndpointPluginStartDependencies;
28+
children: ReactNode | ReactNode[];
29+
}>(
30+
({
31+
store,
32+
history,
33+
coreStart: { http, notifications, uiSettings, application },
34+
depsStart: { data },
35+
children,
36+
}) => {
37+
const isDarkMode = useObservable<boolean>(uiSettings.get$('theme:darkMode'));
38+
const services = useMemo(() => ({ http, notifications, application, data }), [
39+
application,
40+
data,
41+
http,
42+
notifications,
43+
]);
44+
return (
45+
<Provider store={store}>
46+
<I18nProvider>
47+
<KibanaContextProvider services={services}>
48+
<EuiThemeProvider darkMode={isDarkMode}>
49+
<Router history={history}>
50+
<RouteCapture>{children}</RouteCapture>
51+
</Router>
52+
</EuiThemeProvider>
53+
</KibanaContextProvider>
54+
</I18nProvider>
55+
</Provider>
56+
);
57+
}
58+
);

x-pack/plugins/endpoint/public/applications/endpoint/view/policy/agents_summary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const AgentsSummary = memo<AgentsSummaryProps>(props => {
6161
}, []);
6262

6363
return (
64-
<EuiFlexGroup gutterSize="xl">
64+
<EuiFlexGroup gutterSize="xl" data-test-subj="policyAgentsSummary">
6565
{stats.map(({ key, title, health }) => {
6666
return (
6767
<EuiFlexItem grow={false} key={key}>

0 commit comments

Comments
 (0)