Skip to content

Commit

Permalink
[Metrics UI] Alerting for metrics explorer and inventory (#58779)
Browse files Browse the repository at this point in the history
* Add flyout with expressions

* Integrate frontend with backend

* Extended AlertContextValue with metadata optional property

* Progress

* Pre-fill criteria with current page filters

* Better validation. Naming for clarity

* Fix types for flyout

* Respect the groupby property in metric explorer

* Fix lint errors

* Fix text, add toast notifications

* Fix tests. Make sure update handles predefined expressions

* Dynamically load source from alert flyout

* Remove unused import

* Simplify and add group by functionality

* Remove unecessary useEffect

* disable exhastive deps

* Remove unecessary useEffect

* change language

* Implement design feedback

* Add alert dropdown to the header and snapshot screen

* Remove icon

* Remove unused props. Code cleanup

* Remove unused values

* Fix formatted message id

* Remove create alert option for now.

* Fix type issue

* Add rate, card and count as aggs

* Fix types

Co-authored-by: Yuliia Naumenko <[email protected]>
Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Henry Harding <[email protected]>
  • Loading branch information
4 people authored Mar 23, 2020
1 parent 8572e3f commit a790877
Show file tree
Hide file tree
Showing 15 changed files with 887 additions and 96 deletions.
3 changes: 2 additions & 1 deletion x-pack/plugins/infra/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"data",
"dataEnhanced",
"metrics",
"alerting"
"alerting",
"triggers_actions_ui"
],
"server": true,
"ui": true,
Expand Down
36 changes: 21 additions & 15 deletions x-pack/plugins/infra/public/apps/start_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import { CoreStart, AppMountParameters } from 'kibana/public';

// TODO use theme provided from parentApp when kibana supports it
import { EuiErrorBoundary } from '@elastic/eui';
import { EuiThemeProvider } from '../../../observability/public';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { EuiThemeProvider } from '../../../observability/public/typings/eui_styled_components';
import { InfraFrontendLibs } from '../lib/lib';
import { createStore } from '../store';
import { ApolloClientContext } from '../utils/apollo_context';
Expand All @@ -26,6 +27,8 @@ import {
KibanaContextProvider,
} from '../../../../../src/plugins/kibana_react/public';
import { AppRouter } from '../routers';
import { TriggersAndActionsUIPublicPluginSetup } from '../../../triggers_actions_ui/public';
import { TriggersActionsProvider } from '../utils/triggers_actions_context';
import '../index.scss';

export const CONTAINER_CLASSNAME = 'infra-container-element';
Expand All @@ -35,7 +38,8 @@ export async function startApp(
core: CoreStart,
plugins: object,
params: AppMountParameters,
Router: AppRouter
Router: AppRouter,
triggersActionsUI: TriggersAndActionsUIPublicPluginSetup
) {
const { element, appBasePath } = params;
const history = createBrowserHistory({ basename: appBasePath });
Expand All @@ -51,19 +55,21 @@ export async function startApp(
return (
<core.i18n.Context>
<EuiErrorBoundary>
<ReduxStoreProvider store={store}>
<ReduxStateContextProvider>
<ApolloProvider client={libs.apolloClient}>
<ApolloClientContext.Provider value={libs.apolloClient}>
<EuiThemeProvider darkMode={darkMode}>
<HistoryContext.Provider value={history}>
<Router history={history} />
</HistoryContext.Provider>
</EuiThemeProvider>
</ApolloClientContext.Provider>
</ApolloProvider>
</ReduxStateContextProvider>
</ReduxStoreProvider>
<TriggersActionsProvider triggersActionsUI={triggersActionsUI}>
<ReduxStoreProvider store={store}>
<ReduxStateContextProvider>
<ApolloProvider client={libs.apolloClient}>
<ApolloClientContext.Provider value={libs.apolloClient}>
<EuiThemeProvider darkMode={darkMode}>
<HistoryContext.Provider value={history}>
<Router history={history} />
</HistoryContext.Provider>
</EuiThemeProvider>
</ApolloClientContext.Provider>
</ApolloProvider>
</ReduxStateContextProvider>
</ReduxStoreProvider>
</TriggersActionsProvider>
</EuiErrorBoundary>
</core.i18n.Context>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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, { useState, useCallback, useMemo } from 'react';
import { EuiPopover, EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { AlertFlyout } from './alert_flyout';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';

export const AlertDropdown = () => {
const [popoverOpen, setPopoverOpen] = useState(false);
const [flyoutVisible, setFlyoutVisible] = useState(false);
const kibana = useKibana();

const closePopover = useCallback(() => {
setPopoverOpen(false);
}, [setPopoverOpen]);

const openPopover = useCallback(() => {
setPopoverOpen(true);
}, [setPopoverOpen]);

const menuItems = useMemo(() => {
return [
<EuiContextMenuItem icon="bell" key="createLink" onClick={() => setFlyoutVisible(true)}>
<FormattedMessage
id="xpack.infra.alerting.createAlertButton"
defaultMessage="Create alert"
/>
</EuiContextMenuItem>,
<EuiContextMenuItem
icon="tableOfContents"
key="manageLink"
href={kibana.services?.application?.getUrlForApp(
'kibana#/management/kibana/triggersActions/alerts'
)}
>
<FormattedMessage id="xpack.infra.alerting.manageAlerts" defaultMessage="Manage Alerts" />
</EuiContextMenuItem>,
];
}, [kibana.services]);

return (
<>
<EuiPopover
button={
<EuiButtonEmpty iconSide={'right'} iconType={'arrowDown'} onClick={openPopover}>
<FormattedMessage id="xpack.infra.alerting.alertsButton" defaultMessage="Alerts" />
</EuiButtonEmpty>
}
isOpen={popoverOpen}
closePopover={closePopover}
>
<EuiContextMenuPanel items={menuItems} />
</EuiPopover>
<AlertFlyout setVisible={setFlyoutVisible} visible={flyoutVisible} />
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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, { useContext } from 'react';
import { AlertsContextProvider, AlertAdd } from '../../../../../triggers_actions_ui/public';
import { TriggerActionsContext } from '../../../utils/triggers_actions_context';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { METRIC_THRESHOLD_ALERT_TYPE_ID } from '../../../../server/lib/alerting/metric_threshold/types';
import { MetricsExplorerOptions } from '../../../containers/metrics_explorer/use_metrics_explorer_options';
import { MetricsExplorerSeries } from '../../../../common/http_api/metrics_explorer';

interface Props {
visible?: boolean;
options?: Partial<MetricsExplorerOptions>;
series?: MetricsExplorerSeries;
setVisible: React.Dispatch<React.SetStateAction<boolean>>;
}

export const AlertFlyout = (props: Props) => {
const { triggersActionsUI } = useContext(TriggerActionsContext);
const { services } = useKibana();

return (
<>
{triggersActionsUI && (
<AlertsContextProvider
value={{
metadata: {
currentOptions: props.options,
series: props.series,
},
toastNotifications: services.notifications?.toasts,
http: services.http,
actionTypeRegistry: triggersActionsUI.actionTypeRegistry,
alertTypeRegistry: triggersActionsUI.alertTypeRegistry,
}}
>
<AlertAdd
addFlyoutVisible={props.visible!}
setAddFlyoutVisibility={props.setVisible}
alertTypeId={METRIC_THRESHOLD_ALERT_TYPE_ID}
canChangeTrigger={false}
consumer={'metrics'}
/>
</AlertsContextProvider>
)}
</>
);
};
Loading

0 comments on commit a790877

Please sign in to comment.