/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React, { Component } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { EuiAccordion, EuiButton, EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel, EuiSpacer, EuiText, EuiTitle, } from '@elastic/eui'; import { MAX_ALERT_CONDITIONS } from '../utils/constants'; import AlertConditionPanel from '../components/AlertCondition'; import { DetectorCreationStep } from '../../../models/types'; import { CreateDetectorRulesOptions } from '../../../../../models/types'; import { NotificationChannelTypeOptions } from '../models/interfaces'; import { getEmptyAlertCondition, getNotificationChannels, parseNotificationChannelsToOptions, } from '../utils/helpers'; import { NotificationsService } from '../../../../../services'; import { validateName } from '../../../../../utils/validation'; import { CoreServicesContext } from '../../../../../components/core_services'; import { BREADCRUMBS } from '../../../../../utils/constants'; import { Detector } from '../../../../../../types'; interface ConfigureAlertsProps extends RouteComponentProps { detector: Detector; isEdit: boolean; rulesOptions: CreateDetectorRulesOptions; changeDetector: (detector: Detector) => void; updateDataValidState: (step: DetectorCreationStep, isValid: boolean) => void; notificationsService: NotificationsService; hasNotificationPlugin: boolean; skipAndConfigureHandler: () => void; } interface ConfigureAlertsState { loading: boolean; notificationChannels: NotificationChannelTypeOptions[]; } export default class ConfigureAlerts extends Component { static contextType = CoreServicesContext; constructor(props: ConfigureAlertsProps) { super(props); this.state = { loading: false, notificationChannels: [], }; } updateBreadcrumbs = () => { const { isEdit, detector: { id = '', name }, } = this.props; isEdit && this.context.chrome.setBreadcrumbs([ BREADCRUMBS.SECURITY_ANALYTICS, BREADCRUMBS.DETECTORS, BREADCRUMBS.DETECTORS_DETAILS(name, id), { text: 'Edit alert triggers', }, ]); }; componentDidMount = async () => { this.updateBreadcrumbs(); const { detector: { triggers }, } = this.props; this.getNotificationChannels(); if (triggers.length === 0) { this.addCondition(); } }; componentDidUpdate( prevProps: Readonly, prevState: Readonly, snapshot?: any ) { this.updateBreadcrumbs(); } getNotificationChannels = async () => { this.setState({ loading: true }); const channels = await getNotificationChannels(this.props.notificationsService); this.setState({ notificationChannels: parseNotificationChannelsToOptions(channels) }); this.setState({ loading: false }); }; addCondition = () => { const { changeDetector, detector, detector: { triggers }, } = this.props; triggers.push(getEmptyAlertCondition()); changeDetector({ ...detector, triggers }); }; onAlertTriggerChanged = (newDetector: Detector): void => { const isTriggerDataValid = !newDetector.triggers.length || newDetector.triggers.every((trigger) => { return !!trigger.name && validateName(trigger.name) && trigger.severity; }); this.props.changeDetector(newDetector); this.props.updateDataValidState(DetectorCreationStep.CONFIGURE_ALERTS, isTriggerDataValid); }; onDelete = (index: number) => { const { detector, detector: { triggers }, } = this.props; triggers.splice(index, 1); this.onAlertTriggerChanged({ ...detector, triggers: triggers }); }; render() { const { isEdit, detector: { triggers }, skipAndConfigureHandler, } = this.props; let getPageTitle = (): string | JSX.Element => { if (isEdit) { return <>Alert triggers (${triggers.length}); } return (

Set up alert triggers

Get notified when specific rule conditions are found by the detector.
{triggers?.length && ( { const { changeDetector, detector } = this.props; changeDetector({ ...detector, triggers: [] }); skipAndConfigureHandler(); }} > Skip and configure later )}
); }; const { loading, notificationChannels } = this.state; return (
{getPageTitle()} {triggers.map((alertCondition, index) => (
{index > 0 && }

{isEdit ? alertCondition.name : 'Alert trigger'}

} paddingSize={'none'} initialIsOpen={true} extraAction={ this.onDelete(index)}> Remove } >
))} {!triggers?.length && (

We recommend creating alert triggers to get notified when specific conditions are found by the detector.

You can also configure alert triggers after the detector is created.

} /> )} = MAX_ALERT_CONDITIONS} onClick={this.addCondition}> {triggers.length > 0 ? 'Add another alert trigger' : 'Add alert triggers'}
); } }