Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Alerting] Moves the Index & Geo Threshold UIs into the Stack Alerts Public Plugin #82951

Merged
merged 20 commits into from
Nov 12, 2020
Merged
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1035,12 +1035,19 @@ module.exports = {
* Alerting Services overrides
*/
{
// typescript only for front and back end
// typescript for front and back end
files: ['x-pack/plugins/{alerts,stack_alerts,actions,task_manager,event_log}/**/*.{ts,tsx}'],
rules: {
'@typescript-eslint/no-explicit-any': 'error',
},
},
{
// typescript only for back end
files: ['x-pack/plugins/triggers_actions_ui/server/**/*.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'error',
},
},

/**
* Lens overrides
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
@@ -102,3 +102,4 @@ pageLoadAssetSize:
visualizations: 295025
visualize: 57431
watcher: 43598
stackAlerts: 29684
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ import { schema, TypeOf } from '@kbn/config-schema';

export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
enableGeoTrackingThresholdAlert: schema.maybe(schema.boolean({ defaultValue: false })),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think using defaultValue: false means you don't need a schema.maybe() wrapper. Or else I'm not sure what this could mean. When would the defaultValue be applied?

This is always a bit of a confusing aspect to me with config-schema, and other type builders like this. :-) I'd prefer we use the "fewer possibilities" of what the value can be, when we can, and removing the schema.maybe() means that property should always have a boolean value vs boolean | undefined, which seems like will be easier for us anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point - I copied it as is from the original plugin.
Think you're right... I'll sort that out.

});

export type Config = TypeOf<typeof configSchema>;
2 changes: 1 addition & 1 deletion x-pack/plugins/stack_alerts/common/index.ts
Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export * from './config';
export const STACK_ALERTS_FEATURE_ID = 'stackAlerts';
4 changes: 2 additions & 2 deletions x-pack/plugins/stack_alerts/kibana.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"server": true,
"version": "8.0.0",
"kibanaVersion": "kibana",
"requiredPlugins": ["alerts", "features"],
"requiredPlugins": ["alerts", "features", "triggersActionsUi", "kibanaReact"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have a case where someone would want to disable triggersActionsUi but have the stack alerts still usable, right? Probably anyway? :-)

I could imagine a situation where we might someday want to build a UI-free version of Kibana to be able to run the alerts/actions without the UI, but that's super-long term, and no need to account for that yet, I don't think.

Just wanted to make sure we didn't have any other use cases like that ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the time being we'll have to live with it as a dependency for actions or alerts 🤷
In the future, sure, we might want to offer alerting without UI, but for now I think this is ok.

"configPath": ["xpack", "stack_alerts"],
"ui": false
"ui": true
}
Original file line number Diff line number Diff line change
@@ -5,18 +5,17 @@
*/
import { lazy } from 'react';
import { i18n } from '@kbn/i18n';
import { AlertTypeModel } from '../../../../types';
import { validateExpression } from './validation';
import { GeoThresholdAlertParams } from './types';
import { AlertsContextValue } from '../../../context/alerts_context';
import { AlertTypeModel, AlertsContextValue } from '../../../../triggers_actions_ui/public';

export function getAlertType(): AlertTypeModel<GeoThresholdAlertParams, AlertsContextValue> {
return {
id: '.geo-threshold',
name: i18n.translate('xpack.triggersActionsUI.geoThreshold.name.trackingThreshold', {
name: i18n.translate('xpack.stackAlerts.geoThreshold.name.trackingThreshold', {
defaultMessage: 'Tracking threshold',
}),
description: i18n.translate('xpack.triggersActionsUI.geoThreshold.descriptionText', {
description: i18n.translate('xpack.stackAlerts.geoThreshold.descriptionText', {
defaultMessage: 'Alert when an entity enters or leaves a geo boundary.',
}),
iconClass: 'globe',
Original file line number Diff line number Diff line change
@@ -7,14 +7,13 @@
import React, { Fragment, FunctionComponent, useEffect, useRef } from 'react';
import { EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { IErrorObject } from '../../../../../../types';
import { IErrorObject, AlertsContextValue } from '../../../../../../triggers_actions_ui/public';
import { ES_GEO_SHAPE_TYPES, GeoThresholdAlertParams } from '../../types';
import { AlertsContextValue } from '../../../../../context/alerts_context';
import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select';
import { SingleFieldSelect } from '../util_components/single_field_select';
import { ExpressionWithPopover } from '../util_components/expression_with_popover';
import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';

interface Props {
alertParams: GeoThresholdAlertParams;
@@ -117,12 +116,12 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
<EuiFormRow
id="geoField"
fullWidth
label={i18n.translate('xpack.triggersActionsUI.geoThreshold.geofieldLabel', {
label={i18n.translate('xpack.stackAlerts.geoThreshold.geofieldLabel', {
defaultMessage: 'Geospatial field',
})}
>
<SingleFieldSelect
placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectLabel', {
placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectLabel', {
defaultMessage: 'Select geo field',
})}
value={boundaryGeoField}
@@ -133,12 +132,12 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
<EuiFormRow
id="boundaryNameFieldSelect"
fullWidth
label={i18n.translate('xpack.triggersActionsUI.geoThreshold.boundaryNameSelectLabel', {
label={i18n.translate('xpack.stackAlerts.geoThreshold.boundaryNameSelectLabel', {
defaultMessage: 'Human-readable boundary name (optional)',
})}
>
<SingleFieldSelect
placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.boundaryNameSelect', {
placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.boundaryNameSelect', {
defaultMessage: 'Select boundary name',
})}
value={boundaryNameField || null}
@@ -156,7 +155,7 @@ export const BoundaryIndexExpression: FunctionComponent<Props> = ({
defaultValue={'Select an index pattern and geo shape field'}
value={boundaryIndexPattern.title}
popoverContent={indexPopover}
expressionDescription={i18n.translate('xpack.triggersActionsUI.geoThreshold.indexLabel', {
expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.indexLabel', {
defaultMessage: 'index',
})}
/>
Original file line number Diff line number Diff line change
@@ -8,10 +8,10 @@ import React, { FunctionComponent, useEffect, useRef } from 'react';
import { EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import _ from 'lodash';
import { IErrorObject } from '../../../../../../types';
import { IErrorObject } from '../../../../../../triggers_actions_ui/public';
import { SingleFieldSelect } from '../util_components/single_field_select';
import { ExpressionWithPopover } from '../util_components/expression_with_popover';
import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';

interface Props {
errors: IErrorObject;
@@ -59,7 +59,7 @@ export const EntityByExpression: FunctionComponent<Props> = ({
<EuiFormRow id="entitySelect" fullWidth error={errors.index}>
<SingleFieldSelect
placeholder={i18n.translate(
'xpack.triggersActionsUI.geoThreshold.topHitsSplitFieldSelectPlaceholder',
'xpack.stackAlerts.geoThreshold.topHitsSplitFieldSelectPlaceholder',
{
defaultMessage: 'Select entity field',
}
@@ -77,7 +77,7 @@ export const EntityByExpression: FunctionComponent<Props> = ({
value={entity}
defaultValue={'Select entity field'}
popoverContent={indexPopover}
expressionDescription={i18n.translate('xpack.triggersActionsUI.geoThreshold.entityByLabel', {
expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.entityByLabel', {
defaultMessage: 'by',
})}
/>
Original file line number Diff line number Diff line change
@@ -8,14 +8,13 @@ import React, { Fragment, FunctionComponent, useEffect, useRef } from 'react';
import { EuiFormRow } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { IErrorObject } from '../../../../../../types';
import { IErrorObject, AlertsContextValue } from '../../../../../../triggers_actions_ui/public';
import { ES_GEO_FIELD_TYPES } from '../../types';
import { AlertsContextValue } from '../../../../../context/alerts_context';
import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select';
import { SingleFieldSelect } from '../util_components/single_field_select';
import { ExpressionWithPopover } from '../util_components/expression_with_popover';
import { IFieldType } from '../../../../../../../../../../src/plugins/data/common/index_patterns/fields';
import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns';
import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields';
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';

interface Props {
dateField: string;
@@ -105,13 +104,13 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
fullWidth
label={
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.timeFieldLabel"
id="xpack.stackAlerts.geoThreshold.timeFieldLabel"
defaultMessage="Time field"
/>
}
>
<SingleFieldSelect
placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectTimeLabel', {
placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectTimeLabel', {
defaultMessage: 'Select time field',
})}
value={timeField}
@@ -124,12 +123,12 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
<EuiFormRow
id="geoField"
fullWidth
label={i18n.translate('xpack.triggersActionsUI.geoThreshold.geofieldLabel', {
label={i18n.translate('xpack.stackAlerts.geoThreshold.geofieldLabel', {
defaultMessage: 'Geospatial field',
})}
>
<SingleFieldSelect
placeholder={i18n.translate('xpack.triggersActionsUI.geoThreshold.selectGeoLabel', {
placeholder={i18n.translate('xpack.stackAlerts.geoThreshold.selectGeoLabel', {
defaultMessage: 'Select geo field',
})}
value={geoField}
@@ -148,12 +147,9 @@ export const EntityIndexExpression: FunctionComponent<Props> = ({
value={indexPattern.title}
defaultValue={'Select an index pattern and geo shape/point field'}
popoverContent={indexPopover}
expressionDescription={i18n.translate(
'xpack.triggersActionsUI.geoThreshold.entityIndexLabel',
{
defaultMessage: 'index',
}
)}
expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.entityIndexLabel', {
defaultMessage: 'index',
})}
/>
);
};
Original file line number Diff line number Diff line change
@@ -19,15 +19,17 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { AlertTypeParamsExpressionProps } from '../../../../../types';
import {
AlertTypeParamsExpressionProps,
getTimeOptions,
AlertsContextValue,
} from '../../../../../triggers_actions_ui/public';
import { GeoThresholdAlertParams, TrackingEvent } from '../types';
import { AlertsContextValue } from '../../../../context/alerts_context';
import { ExpressionWithPopover } from './util_components/expression_with_popover';
import { EntityIndexExpression } from './expressions/entity_index_expression';
import { EntityByExpression } from './expressions/entity_by_expression';
import { BoundaryIndexExpression } from './expressions/boundary_index_expression';
import { IIndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns';
import { getTimeOptions } from '../../../../../common/lib/get_time_options';
import { IIndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns';

const DEFAULT_VALUES = {
TRACKING_EVENT: '',
@@ -45,20 +47,20 @@ const DEFAULT_VALUES = {
};

const conditionOptions = Object.keys(TrackingEvent).map((key) => ({
text: (TrackingEvent as any)[key],
value: (TrackingEvent as any)[key],
text: TrackingEvent[key as TrackingEvent],
value: TrackingEvent[key as TrackingEvent],
}));

const labelForDelayOffset = (
<>
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.delayOffset"
id="xpack.stackAlerts.geoThreshold.delayOffset"
defaultMessage="Delayed evaluation offset"
/>{' '}
<EuiIconTip
position="right"
type="questionInCircle"
content={i18n.translate('xpack.triggersActionsUI.geoThreshold.delayOffsetTooltip', {
content={i18n.translate('xpack.stackAlerts.geoThreshold.delayOffsetTooltip', {
defaultMessage: 'Evaluate alerts on a delayed cycle to adjust for data latency',
})}
/>
@@ -125,7 +127,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP

const hasExpressionErrors = false;
const expressionErrorMessage = i18n.translate(
'xpack.triggersActionsUI.geoThreshold.fixErrorInExpressionBelowValidationMessage',
'xpack.stackAlerts.geoThreshold.fixErrorInExpressionBelowValidationMessage',
{
defaultMessage: 'Expression contains errors.',
}
@@ -180,7 +182,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
<EuiTitle size="xs">
<h5>
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.selectOffset"
id="xpack.stackAlerts.geoThreshold.selectOffset"
defaultMessage="Select offset (optional)"
/>
</h5>
@@ -221,7 +223,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
<EuiTitle size="xs">
<h5>
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.selectEntity"
id="xpack.stackAlerts.geoThreshold.selectEntity"
defaultMessage="Select entity"
/>
</h5>
@@ -251,7 +253,7 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
<EuiTitle size="xs">
<h5>
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.selectIndex"
id="xpack.stackAlerts.geoThreshold.selectIndex"
defaultMessage="Define the condition"
/>
</h5>
@@ -280,19 +282,16 @@ export const GeoThresholdAlertTypeExpression: React.FunctionComponent<AlertTypeP
</div>
</EuiFormRow>
}
expressionDescription={i18n.translate(
'xpack.triggersActionsUI.geoThreshold.whenEntityLabel',
{
defaultMessage: 'when entity',
}
)}
expressionDescription={i18n.translate('xpack.stackAlerts.geoThreshold.whenEntityLabel', {
defaultMessage: 'when entity',
})}
/>

<EuiSpacer size="l" />
<EuiTitle size="xs">
<h5>
<FormattedMessage
id="xpack.triggersActionsUI.geoThreshold.selectBoundaryIndex"
id="xpack.stackAlerts.geoThreshold.selectBoundaryIndex"
defaultMessage="Select boundary:"
/>
</h5>
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { useState } from 'react';
import React, { ReactNode, useState } from 'react';
import {
EuiButtonIcon,
EuiExpression,
@@ -22,10 +22,10 @@ export const ExpressionWithPopover: ({
value,
isInvalid,
}: {
popoverContent: any;
expressionDescription: any;
defaultValue?: any;
value?: any;
popoverContent: ReactNode;
expressionDescription: ReactNode;
defaultValue?: ReactNode;
value?: ReactNode;
isInvalid?: boolean;
}) => JSX.Element = ({ popoverContent, expressionDescription, defaultValue, value, isInvalid }) => {
const [popoverOpen, setPopoverOpen] = useState(false);
@@ -61,7 +61,7 @@ export const ExpressionWithPopover: ({
iconType="cross"
color="danger"
aria-label={i18n.translate(
'xpack.triggersActionsUI.sections.alertAdd.geoThreshold.closePopoverLabel',
'xpack.stackAlerts.geoThreshold.ui.expressionPopover.closePopoverLabel',
{
defaultMessage: 'Close',
}
Loading