Skip to content

Commit 1ca013a

Browse files
dplumleepeluja1012
andauthored
Basic Functionality Alert List (#55800)
* sets up initial grid and data type * data feeds in from backend but doesnt update * sample data feeding in correctly * Fix combineReducers issue by importing Redux type from 'redux' package * Add usePageId hook that fires action when user navigates to page * Strict typing for middleware * addresses comments and uses better types * move types to common/types.ts * Move types to endpoint/types.ts, address PR comments blah 2 Co-authored-by: Pedro Jaramillo <[email protected]>
1 parent 0d2ac94 commit 1ca013a

File tree

22 files changed

+11716
-16
lines changed

22 files changed

+11716
-16
lines changed

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
/**
8+
* A deep readonly type that will make all children of a given object readonly recursively
9+
*/
10+
export type Immutable<T> = T extends undefined | null | boolean | string | number
11+
? T
12+
: T extends Array<infer U>
13+
? ImmutableArray<U>
14+
: T extends Map<infer K, infer V>
15+
? ImmutableMap<K, V>
16+
: T extends Set<infer M>
17+
? ImmutableSet<M>
18+
: ImmutableObject<T>;
19+
20+
export type ImmutableArray<T> = ReadonlyArray<Immutable<T>>;
21+
export type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>>;
22+
export type ImmutableSet<T> = ReadonlySet<Immutable<T>>;
23+
export type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
24+
725
export class EndpointAppConstants {
826
static ENDPOINT_INDEX_NAME = 'endpoint-agent*';
927
}
@@ -44,3 +62,37 @@ export interface EndpointMetadata {
4462
};
4563
};
4664
}
65+
66+
export interface AlertData {
67+
value: {
68+
source: {
69+
endgame: {
70+
data: {
71+
file_operation: string;
72+
malware_classification: {
73+
score: number;
74+
};
75+
};
76+
metadata: {
77+
key: string;
78+
};
79+
timestamp_utc: Date;
80+
};
81+
labels: {
82+
endpoint_id: string;
83+
};
84+
host: {
85+
hostname: string;
86+
ip: string;
87+
os: {
88+
name: string;
89+
};
90+
};
91+
};
92+
};
93+
}
94+
95+
/**
96+
* The PageId type is used for the payload when firing userNavigatedToPage actions
97+
*/
98+
export type PageId = 'alertsPage' | 'endpointListPage';

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Route, BrowserRouter, Switch } from 'react-router-dom';
1212
import { Provider } from 'react-redux';
1313
import { Store } from 'redux';
1414
import { appStoreFactory } from './store';
15+
import { AlertIndex } from './view/alerts';
1516

1617
/**
1718
* This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle.
@@ -64,6 +65,7 @@ const AppRoot: React.FunctionComponent<RouterProps> = React.memo(({ basename, st
6465
);
6566
}}
6667
/>
68+
<Route path="/alerts" component={AlertIndex} />
6769
<Route
6870
render={() => (
6971
<FormattedMessage id="xpack.endpoint.notFound" defaultMessage="Page Not Found" />

x-pack/plugins/endpoint/public/applications/endpoint/lib/saga.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import { AnyAction, Dispatch, Middleware, MiddlewareAPI } from 'redux';
8-
import { GlobalState } from '../store';
8+
import { GlobalState } from '../types';
99

1010
interface QueuedAction<TAction = AnyAction> {
1111
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 { EndpointListAction } from './endpoint_list';
8+
import { AlertAction } from './alerts';
9+
import { RoutingAction } from './routing';
10+
11+
export type AppAction = EndpointListAction | AlertAction | RoutingAction;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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 { AlertData, Immutable } from '../../../../../common/types';
8+
9+
type ServerReturnedAlertsData = Immutable<{
10+
type: 'serverReturnedAlertsData';
11+
payload: AlertData[];
12+
}>;
13+
14+
export type AlertAction = ServerReturnedAlertsData;

x-pack/plugins/endpoint/public/applications/endpoint/store/actions.ts renamed to x-pack/plugins/endpoint/public/applications/endpoint/store/alerts/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,5 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { EndpointListAction } from './endpoint_list';
8-
9-
export type AppAction = EndpointListAction;
7+
export { alertListReducer } from './reducer';
8+
export { AlertAction } from './action';
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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 { AlertData, ImmutableArray } from '../../../../../common/types';
8+
import { AppAction } from '../action';
9+
import { MiddlewareFactory } from '../../types';
10+
11+
export const alertMiddlewareFactory: MiddlewareFactory = coreStart => {
12+
return api => next => async (action: AppAction) => {
13+
next(action);
14+
if (action.type === 'userNavigatedToPage' && action.payload === 'alertsPage') {
15+
const response: ImmutableArray<AlertData> = await coreStart.http.get('/api/endpoint/alerts');
16+
api.dispatch({ type: 'serverReturnedAlertsData', payload: response });
17+
}
18+
};
19+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 { Reducer } from 'redux';
8+
import { AlertListState } from '../../types';
9+
import { AppAction } from '../action';
10+
11+
const initialState = (): AlertListState => {
12+
return {
13+
alerts: [],
14+
};
15+
};
16+
17+
export const alertListReducer: Reducer<AlertListState, AppAction> = (
18+
state = initialState(),
19+
action
20+
) => {
21+
if (action.type === 'serverReturnedAlertsData') {
22+
return {
23+
...state,
24+
alerts: action.payload,
25+
};
26+
}
27+
28+
return state;
29+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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 { AlertListState } from '../../types';
8+
9+
export const alertListData = (state: AlertListState) => state.alerts;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
import { Reducer } from 'redux';
78
import { EndpointListState } from './types';
8-
import { EndpointListAction } from './action';
9+
import { AppAction } from '../action';
910

1011
const initialState = (): EndpointListState => {
1112
return {
@@ -16,7 +17,10 @@ const initialState = (): EndpointListState => {
1617
};
1718
};
1819

19-
export const endpointListReducer = (state = initialState(), action: EndpointListAction) => {
20+
export const endpointListReducer: Reducer<EndpointListState, AppAction> = (
21+
state = initialState(),
22+
action
23+
) => {
2024
if (action.type === 'serverReturnedEndpointList') {
2125
return {
2226
...state,

0 commit comments

Comments
 (0)