From fb10addeb1bf852059d2ccaf54a40d8655512f39 Mon Sep 17 00:00:00 2001 From: Andrea Del Rio Date: Wed, 12 Feb 2020 14:58:15 -0800 Subject: [PATCH 1/2] fix conflict --- .../threshold/expression.tsx | 27 +- .../threshold/visualization.tsx | 3 +- .../action_connector_form/_index.scss | 4 + .../sections/alert_add/alert_form.tsx | 879 ++++++++++++++++++ 4 files changed, 909 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_add/alert_form.tsx diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx index 5128fe23fd8a6..e03ccdd4d21e7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx @@ -10,6 +10,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiFlexItem, EuiFlexGroup, + EuiFormLabel, EuiExpression, EuiPopover, EuiPopoverTitle, @@ -345,7 +346,15 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent ) : null} - + + + + + + { setIndexPopoverOpen(true); @@ -388,6 +397,8 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent + + ) : null} + + + + + + + + + = ({ > {error} - ); } @@ -228,7 +227,7 @@ export const ThresholdVisualization: React.FunctionComponent = ({
{alertVisualizationDataKeys.length ? ( - + (), + interval: new Array(), + alertTypeId: new Array(), + actionConnectors: new Array(), + }; + validationResult.errors = errors; + if (!alertObject.name) { + errors.name.push( + i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredNameText', { + defaultMessage: 'Name is required.', + }) + ); + } + if (!alertObject.schedule.interval) { + errors.interval.push( + i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredIntervalText', { + defaultMessage: 'Check interval is required.', + }) + ); + } + if (!alertObject.alertTypeId) { + errors.alertTypeId.push( + i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredAlertTypeIdText', { + defaultMessage: 'Alert trigger is required.', + }) + ); + } + return validationResult; +} + +interface AlertFormProps { + alert: Alert; + dispatch: React.Dispatch; + errors: IErrorObject; + serverError: { + body: { message: string; error: string }; + } | null; + canChangeTrigger?: boolean; // to hide Change trigger button +} + +interface ActiveActionConnectorState { + actionTypeId: string; + index: number; +} + +export const AlertForm = ({ + alert, + canChangeTrigger = true, + dispatch, + errors, + serverError, +}: AlertFormProps) => { + const alertsContext = useAlertsContext(); + const { http, toastNotifications, alertTypeRegistry, actionTypeRegistry } = alertsContext; + + const [alertTypeModel, setAlertTypeModel] = useState( + alertTypeRegistry.get(alert.alertTypeId) + ); + + const [addModalVisible, setAddModalVisibility] = useState(false); + const [isLoadingActionTypes, setIsLoadingActionTypes] = useState(false); + const [actionTypesIndex, setActionTypesIndex] = useState(undefined); + const [alertTypesIndex, setAlertTypesIndex] = useState(undefined); + const [alertInterval, setAlertInterval] = useState(null); + const [alertIntervalUnit, setAlertIntervalUnit] = useState('m'); + const [alertThrottle, setAlertThrottle] = useState(null); + const [alertThrottleUnit, setAlertThrottleUnit] = useState('m'); + const [isAddActionPanelOpen, setIsAddActionPanelOpen] = useState(true); + const [connectors, setConnectors] = useState([]); + const [defaultActionGroup, setDefaultActionGroup] = useState(undefined); + const [activeActionItem, setActiveActionItem] = useState( + undefined + ); + + // load action types + useEffect(() => { + (async () => { + try { + setIsLoadingActionTypes(true); + const actionTypes = await loadActionTypes({ http }); + const index: ActionTypeIndex = {}; + for (const actionTypeItem of actionTypes) { + index[actionTypeItem.id] = actionTypeItem; + } + setActionTypesIndex(index); + } catch (e) { + if (toastNotifications) { + toastNotifications.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.alertForm.unableToLoadActionTypesMessage', + { defaultMessage: 'Unable to load action types' } + ), + }); + } + } finally { + setIsLoadingActionTypes(false); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // load alert types + useEffect(() => { + (async () => { + try { + const alertTypes = await loadAlertTypes({ http }); + // temp hack of API result + alertTypes.push({ + id: 'threshold', + actionGroups: [ + { id: 'alert', name: 'Alert' }, + { id: 'warning', name: 'Warning' }, + { id: 'ifUnacknowledged', name: 'If unacknowledged' }, + ], + name: 'threshold', + actionVariables: ['ctx.metadata.name', 'ctx.metadata.test'], + }); + const index: AlertTypeIndex = {}; + for (const alertTypeItem of alertTypes) { + index[alertTypeItem.id] = alertTypeItem; + } + if (alert.alertTypeId) { + setDefaultActionGroup(index[alert.alertTypeId].actionGroups[0]); + } + setAlertTypesIndex(index); + } catch (e) { + if (toastNotifications) { + toastNotifications.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.alertForm.unableToLoadAlertTypesMessage', + { defaultMessage: 'Unable to load alert types' } + ), + }); + } + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + loadConnectors(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const setAlertProperty = (key: string, value: any) => { + dispatch({ command: { type: 'setProperty' }, payload: { key, value } }); + }; + + const setAlertParams = (key: string, value: any) => { + dispatch({ command: { type: 'setAlertParams' }, payload: { key, value } }); + }; + + const setScheduleProperty = (key: string, value: any) => { + dispatch({ command: { type: 'setScheduleProperty' }, payload: { key, value } }); + }; + + const setActionParamsProperty = (key: string, value: any, index: number) => { + dispatch({ command: { type: 'setAlertActionParams' }, payload: { key, value, index } }); + }; + + const setActionProperty = (key: string, value: any, index: number) => { + dispatch({ command: { type: 'setAlertActionProperty' }, payload: { key, value, index } }); + }; + + const tagsOptions = alert.tags ? alert.tags.map((label: string) => ({ label })) : []; + + async function loadConnectors() { + try { + const actionsResponse = await loadAllActions({ http }); + setConnectors(actionsResponse.data); + } catch (e) { + if (toastNotifications) { + toastNotifications.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.alertForm.unableToLoadActionsMessage', + { + defaultMessage: 'Unable to load connectors', + } + ), + }); + } + } + } + + const actionsErrors = alert.actions.reduce( + (acc: Record, alertAction: AlertAction) => { + const actionType = actionTypeRegistry.get(alertAction.actionTypeId); + if (!actionType) { + return { ...acc }; + } + const actionValidationErrors = actionType.validateParams(alertAction.params); + return { ...acc, [alertAction.id]: actionValidationErrors }; + }, + {} + ); + + const AlertParamsExpressionComponent = alertTypeModel + ? alertTypeModel.alertParamsExpression + : null; + + function addActionType(actionTypeModel: ActionTypeModel) { + setIsAddActionPanelOpen(false); + const actionTypeConnectors = connectors.filter( + field => field.actionTypeId === actionTypeModel.id + ); + let freeConnectors; + if (actionTypeConnectors.length > 0) { + // Should we allow adding multiple actions to the same connector under the alert? + freeConnectors = actionTypeConnectors.filter( + (actionConnector: ActionConnector) => + !alert.actions.find((actionItem: AlertAction) => actionItem.id === actionConnector.id) + ); + if (freeConnectors.length > 0) { + alert.actions.push({ + id: '', + actionTypeId: actionTypeModel.id, + group: defaultActionGroup?.id ?? 'Alert', + params: {}, + }); + setActionProperty('id', freeConnectors[0].id, alert.actions.length - 1); + } + } + if (actionTypeConnectors.length === 0 || !freeConnectors || freeConnectors.length === 0) { + // if no connectors exists or all connectors is already assigned an action under current alert + // set actionType as id to be able to create new connector within the alert form + alert.actions.push({ + id: '', + actionTypeId: actionTypeModel.id, + group: defaultActionGroup?.id ?? 'Alert', + params: {}, + }); + setActionProperty('id', alert.actions.length, alert.actions.length - 1); + } + } + + const alertTypeNodes = alertTypeRegistry.list().map(function(item, index) { + return ( + { + setAlertProperty('alertTypeId', item.id); + setAlertTypeModel(item); + if ( + alertTypesIndex && + alertTypesIndex[item.id] && + alertTypesIndex[item.id].actionGroups.length > 0 + ) { + setDefaultActionGroup(alertTypesIndex[item.id].actionGroups[0]); + } + }} + > + + + ); + }); + + const actionTypeNodes = actionTypeRegistry.list().map(function(item, index) { + return ( + addActionType(item)} + > + + + ); + }); + + const getSelectedOptions = (actionItemId: string) => { + const val = connectors.find(connector => connector.id === actionItemId); + if (!val) { + return []; + } + return [ + { + label: val.name, + value: val.name, + id: actionItemId, + }, + ]; + }; + + const getActionTypeForm = ( + actionItem: AlertAction, + actionConnector: ActionConnector, + index: number + ) => { + const optionsList = connectors + .filter( + connectorItem => + connectorItem.actionTypeId === actionItem.actionTypeId && + (connectorItem.id === actionItem.id || + !alert.actions.find( + (existingAction: AlertAction) => + existingAction.id === connectorItem.id && existingAction.group === actionItem.group + )) + ) + .map(({ name, id }) => ({ + label: name, + key: id, + id, + })); + const actionTypeRegisterd = actionTypeRegistry.get(actionConnector.actionTypeId); + if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null; + const ParamsFieldsComponent = actionTypeRegisterd.actionParamsFields; + const actionParamsErrors: { errors: IErrorObject } = + Object.keys(actionsErrors).length > 0 ? actionsErrors[actionItem.id] : { errors: {} }; + + return ( + + + + + + +
+ +
+
+
+ + } + extraAction={ + { + const updatedActions = alert.actions.filter( + (item: AlertAction) => item.id !== actionItem.id + ); + setAlertProperty('actions', updatedActions); + setIsAddActionPanelOpen( + updatedActions.filter((item: AlertAction) => item.id !== actionItem.id).length === 0 + ); + setActiveActionItem(undefined); + }} + /> + } + paddingSize="l" + > + + + + } + labelAppend={ + { + setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index }); + setAddModalVisibility(true); + }} + > + + + } + > + { + setActionProperty('id', selectedOptions[0].id, index); + }} + isClearable={false} + /> + + + + + {ParamsFieldsComponent ? ( + + ) : null} +
+ ); + }; + + const getAddConnectorsForm = (actionItem: AlertAction, index: number) => { + const actionTypeName = actionTypesIndex + ? actionTypesIndex[actionItem.actionTypeId].name + : actionItem.actionTypeId; + const actionTypeRegisterd = actionTypeRegistry.get(actionItem.actionTypeId); + if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null; + return ( + + + + + + +
+ +
+
+
+ + } + extraAction={ + { + const updatedActions = alert.actions.filter( + (item: AlertAction) => item.id !== actionItem.id + ); + setAlertProperty('actions', updatedActions); + setIsAddActionPanelOpen( + updatedActions.filter((item: AlertAction) => item.id !== actionItem.id).length === 0 + ); + setActiveActionItem(undefined); + }} + /> + } + paddingSize="l" + > + + } + actions={[ + { + setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index }); + setAddModalVisibility(true); + }} + > + + , + ]} + /> +
+ ); + }; + + const selectedGroupActions = ( + + {alert.actions.map((actionItem: AlertAction, index: number) => { + const actionConnector = connectors.find(field => field.id === actionItem.id); + // connectors doesn't exists + if (!actionConnector) { + return getAddConnectorsForm(actionItem, index); + } + return getActionTypeForm(actionItem, actionConnector, index); + })} + + {isAddActionPanelOpen === false ? ( + setIsAddActionPanelOpen(true)} + > + + + ) : null} + + ); + + const alertTypeDetails = ( + + + + + +
+ +
+
+
+ {canChangeTrigger ? ( + + { + setAlertProperty('alertTypeId', null); + setAlertTypeModel(null); + }} + /> + + ) : null} +
+ {AlertParamsExpressionComponent ? ( + + ) : null} + + {selectedGroupActions} + {isAddActionPanelOpen ? ( + + +
+ +
+
+ + + {isLoadingActionTypes ? ( + + + + ) : ( + actionTypeNodes + )} + +
+ ) : null} +
+ ); + + const labelForAlertChecked = ( + <> + {' '} + + + ); + + const labelForAlertRenotify = ( + <> + {' '} + + + ); + + return ( + + + + + } + isInvalid={errors.name.length > 0 && alert.name !== undefined} + error={errors.name} + > + 0 && alert.name !== undefined} + compressed + name="name" + data-test-subj="alertNameInput" + value={alert.name || ''} + onChange={e => { + setAlertProperty('name', e.target.value); + }} + onBlur={() => { + if (!alert.name) { + setAlertProperty('name', ''); + } + }} + /> + + + + + { + const newOptions = [...tagsOptions, { label: searchValue }]; + setAlertProperty( + 'tags', + newOptions.map(newOption => newOption.label) + ); + }} + onChange={(selectedOptions: Array<{ label: string }>) => { + setAlertProperty( + 'tags', + selectedOptions.map(selectedOption => selectedOption.label) + ); + }} + onBlur={() => { + if (!alert.tags) { + setAlertProperty('tags', []); + } + }} + /> + + + + + + + + + + { + const interval = e.target.value !== '' ? parseInt(e.target.value, 10) : null; + setAlertInterval(interval); + setScheduleProperty('interval', `${e.target.value}${alertIntervalUnit}`); + }} + /> + + + { + setAlertIntervalUnit(e.target.value); + setScheduleProperty('interval', `${alertInterval}${e.target.value}`); + }} + /> + + + + + + + + + { + const throttle = e.target.value !== '' ? parseInt(e.target.value, 10) : null; + setAlertThrottle(throttle); + setAlertProperty('throttle', `${e.target.value}${alertThrottleUnit}`); + }} + /> + + + { + setAlertThrottleUnit(e.target.value); + setAlertProperty('throttle', `${alertThrottle}${e.target.value}`); + }} + /> + + + + + + + {alertTypeModel ? ( + {alertTypeDetails} + ) : ( + + + +
+ +
+
+ + + {alertTypeNodes} + +
+ )} + {actionTypesIndex && activeActionItem ? ( + { + connectors.push(savedAction); + setActionProperty('id', savedAction.id, activeActionItem.index); + }} + actionTypeRegistry={actionTypeRegistry} + alertTypeRegistry={alertTypeRegistry} + http={http} + toastNotifications={toastNotifications} + /> + ) : null} +
+ ); +}; From 05d5acf51a7ccb4d96da010a2d2fbc63fb8e5486 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Thu, 12 Mar 2020 15:43:37 -0700 Subject: [PATCH 2/2] Removed merge duplication file --- .../sections/alert_add/alert_form.tsx | 879 ------------------ 1 file changed, 879 deletions(-) delete mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_add/alert_form.tsx diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_add/alert_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_add/alert_form.tsx deleted file mode 100644 index 95c049f32436a..0000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_add/alert_form.tsx +++ /dev/null @@ -1,879 +0,0 @@ -/* - * 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, { Fragment, useState, useEffect } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { - EuiButton, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiTitle, - EuiForm, - EuiSpacer, - EuiFieldText, - EuiFlexGrid, - EuiFormRow, - EuiComboBox, - EuiKeyPadMenuItem, - EuiFieldNumber, - EuiSelect, - EuiIconTip, - EuiAccordion, - EuiButtonIcon, - EuiEmptyPrompt, - EuiButtonEmpty, - EuiHorizontalRule, -} from '@elastic/eui'; -import { loadAlertTypes } from '../../lib/alert_api'; -import { loadActionTypes, loadAllActions } from '../../lib/action_connector_api'; -import { AlertReducerAction } from './alert_reducer'; -import { - AlertTypeModel, - Alert, - IErrorObject, - ActionTypeModel, - AlertAction, - ActionTypeIndex, - ActionConnector, - AlertTypeIndex, - ActionGroup, -} from '../../../types'; -import { SectionLoading } from '../../components/section_loading'; -import { ConnectorAddModal } from '../action_connector_form/connector_add_modal'; -import { getTimeOptions } from '../../../common/lib/get_time_options'; -import { useAlertsContext } from '../../context/alerts_context'; - -export function validateBaseProperties(alertObject: Alert) { - const validationResult = { errors: {} }; - const errors = { - name: new Array(), - interval: new Array(), - alertTypeId: new Array(), - actionConnectors: new Array(), - }; - validationResult.errors = errors; - if (!alertObject.name) { - errors.name.push( - i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredNameText', { - defaultMessage: 'Name is required.', - }) - ); - } - if (!alertObject.schedule.interval) { - errors.interval.push( - i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredIntervalText', { - defaultMessage: 'Check interval is required.', - }) - ); - } - if (!alertObject.alertTypeId) { - errors.alertTypeId.push( - i18n.translate('xpack.triggersActionsUI.sections.alertForm.error.requiredAlertTypeIdText', { - defaultMessage: 'Alert trigger is required.', - }) - ); - } - return validationResult; -} - -interface AlertFormProps { - alert: Alert; - dispatch: React.Dispatch; - errors: IErrorObject; - serverError: { - body: { message: string; error: string }; - } | null; - canChangeTrigger?: boolean; // to hide Change trigger button -} - -interface ActiveActionConnectorState { - actionTypeId: string; - index: number; -} - -export const AlertForm = ({ - alert, - canChangeTrigger = true, - dispatch, - errors, - serverError, -}: AlertFormProps) => { - const alertsContext = useAlertsContext(); - const { http, toastNotifications, alertTypeRegistry, actionTypeRegistry } = alertsContext; - - const [alertTypeModel, setAlertTypeModel] = useState( - alertTypeRegistry.get(alert.alertTypeId) - ); - - const [addModalVisible, setAddModalVisibility] = useState(false); - const [isLoadingActionTypes, setIsLoadingActionTypes] = useState(false); - const [actionTypesIndex, setActionTypesIndex] = useState(undefined); - const [alertTypesIndex, setAlertTypesIndex] = useState(undefined); - const [alertInterval, setAlertInterval] = useState(null); - const [alertIntervalUnit, setAlertIntervalUnit] = useState('m'); - const [alertThrottle, setAlertThrottle] = useState(null); - const [alertThrottleUnit, setAlertThrottleUnit] = useState('m'); - const [isAddActionPanelOpen, setIsAddActionPanelOpen] = useState(true); - const [connectors, setConnectors] = useState([]); - const [defaultActionGroup, setDefaultActionGroup] = useState(undefined); - const [activeActionItem, setActiveActionItem] = useState( - undefined - ); - - // load action types - useEffect(() => { - (async () => { - try { - setIsLoadingActionTypes(true); - const actionTypes = await loadActionTypes({ http }); - const index: ActionTypeIndex = {}; - for (const actionTypeItem of actionTypes) { - index[actionTypeItem.id] = actionTypeItem; - } - setActionTypesIndex(index); - } catch (e) { - if (toastNotifications) { - toastNotifications.addDanger({ - title: i18n.translate( - 'xpack.triggersActionsUI.sections.alertForm.unableToLoadActionTypesMessage', - { defaultMessage: 'Unable to load action types' } - ), - }); - } - } finally { - setIsLoadingActionTypes(false); - } - })(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - // load alert types - useEffect(() => { - (async () => { - try { - const alertTypes = await loadAlertTypes({ http }); - // temp hack of API result - alertTypes.push({ - id: 'threshold', - actionGroups: [ - { id: 'alert', name: 'Alert' }, - { id: 'warning', name: 'Warning' }, - { id: 'ifUnacknowledged', name: 'If unacknowledged' }, - ], - name: 'threshold', - actionVariables: ['ctx.metadata.name', 'ctx.metadata.test'], - }); - const index: AlertTypeIndex = {}; - for (const alertTypeItem of alertTypes) { - index[alertTypeItem.id] = alertTypeItem; - } - if (alert.alertTypeId) { - setDefaultActionGroup(index[alert.alertTypeId].actionGroups[0]); - } - setAlertTypesIndex(index); - } catch (e) { - if (toastNotifications) { - toastNotifications.addDanger({ - title: i18n.translate( - 'xpack.triggersActionsUI.sections.alertForm.unableToLoadAlertTypesMessage', - { defaultMessage: 'Unable to load alert types' } - ), - }); - } - } - })(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - loadConnectors(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const setAlertProperty = (key: string, value: any) => { - dispatch({ command: { type: 'setProperty' }, payload: { key, value } }); - }; - - const setAlertParams = (key: string, value: any) => { - dispatch({ command: { type: 'setAlertParams' }, payload: { key, value } }); - }; - - const setScheduleProperty = (key: string, value: any) => { - dispatch({ command: { type: 'setScheduleProperty' }, payload: { key, value } }); - }; - - const setActionParamsProperty = (key: string, value: any, index: number) => { - dispatch({ command: { type: 'setAlertActionParams' }, payload: { key, value, index } }); - }; - - const setActionProperty = (key: string, value: any, index: number) => { - dispatch({ command: { type: 'setAlertActionProperty' }, payload: { key, value, index } }); - }; - - const tagsOptions = alert.tags ? alert.tags.map((label: string) => ({ label })) : []; - - async function loadConnectors() { - try { - const actionsResponse = await loadAllActions({ http }); - setConnectors(actionsResponse.data); - } catch (e) { - if (toastNotifications) { - toastNotifications.addDanger({ - title: i18n.translate( - 'xpack.triggersActionsUI.sections.alertForm.unableToLoadActionsMessage', - { - defaultMessage: 'Unable to load connectors', - } - ), - }); - } - } - } - - const actionsErrors = alert.actions.reduce( - (acc: Record, alertAction: AlertAction) => { - const actionType = actionTypeRegistry.get(alertAction.actionTypeId); - if (!actionType) { - return { ...acc }; - } - const actionValidationErrors = actionType.validateParams(alertAction.params); - return { ...acc, [alertAction.id]: actionValidationErrors }; - }, - {} - ); - - const AlertParamsExpressionComponent = alertTypeModel - ? alertTypeModel.alertParamsExpression - : null; - - function addActionType(actionTypeModel: ActionTypeModel) { - setIsAddActionPanelOpen(false); - const actionTypeConnectors = connectors.filter( - field => field.actionTypeId === actionTypeModel.id - ); - let freeConnectors; - if (actionTypeConnectors.length > 0) { - // Should we allow adding multiple actions to the same connector under the alert? - freeConnectors = actionTypeConnectors.filter( - (actionConnector: ActionConnector) => - !alert.actions.find((actionItem: AlertAction) => actionItem.id === actionConnector.id) - ); - if (freeConnectors.length > 0) { - alert.actions.push({ - id: '', - actionTypeId: actionTypeModel.id, - group: defaultActionGroup?.id ?? 'Alert', - params: {}, - }); - setActionProperty('id', freeConnectors[0].id, alert.actions.length - 1); - } - } - if (actionTypeConnectors.length === 0 || !freeConnectors || freeConnectors.length === 0) { - // if no connectors exists or all connectors is already assigned an action under current alert - // set actionType as id to be able to create new connector within the alert form - alert.actions.push({ - id: '', - actionTypeId: actionTypeModel.id, - group: defaultActionGroup?.id ?? 'Alert', - params: {}, - }); - setActionProperty('id', alert.actions.length, alert.actions.length - 1); - } - } - - const alertTypeNodes = alertTypeRegistry.list().map(function(item, index) { - return ( - { - setAlertProperty('alertTypeId', item.id); - setAlertTypeModel(item); - if ( - alertTypesIndex && - alertTypesIndex[item.id] && - alertTypesIndex[item.id].actionGroups.length > 0 - ) { - setDefaultActionGroup(alertTypesIndex[item.id].actionGroups[0]); - } - }} - > - - - ); - }); - - const actionTypeNodes = actionTypeRegistry.list().map(function(item, index) { - return ( - addActionType(item)} - > - - - ); - }); - - const getSelectedOptions = (actionItemId: string) => { - const val = connectors.find(connector => connector.id === actionItemId); - if (!val) { - return []; - } - return [ - { - label: val.name, - value: val.name, - id: actionItemId, - }, - ]; - }; - - const getActionTypeForm = ( - actionItem: AlertAction, - actionConnector: ActionConnector, - index: number - ) => { - const optionsList = connectors - .filter( - connectorItem => - connectorItem.actionTypeId === actionItem.actionTypeId && - (connectorItem.id === actionItem.id || - !alert.actions.find( - (existingAction: AlertAction) => - existingAction.id === connectorItem.id && existingAction.group === actionItem.group - )) - ) - .map(({ name, id }) => ({ - label: name, - key: id, - id, - })); - const actionTypeRegisterd = actionTypeRegistry.get(actionConnector.actionTypeId); - if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null; - const ParamsFieldsComponent = actionTypeRegisterd.actionParamsFields; - const actionParamsErrors: { errors: IErrorObject } = - Object.keys(actionsErrors).length > 0 ? actionsErrors[actionItem.id] : { errors: {} }; - - return ( - - - - - - -
- -
-
-
- - } - extraAction={ - { - const updatedActions = alert.actions.filter( - (item: AlertAction) => item.id !== actionItem.id - ); - setAlertProperty('actions', updatedActions); - setIsAddActionPanelOpen( - updatedActions.filter((item: AlertAction) => item.id !== actionItem.id).length === 0 - ); - setActiveActionItem(undefined); - }} - /> - } - paddingSize="l" - > - - - - } - labelAppend={ - { - setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index }); - setAddModalVisibility(true); - }} - > - - - } - > - { - setActionProperty('id', selectedOptions[0].id, index); - }} - isClearable={false} - /> - - - - - {ParamsFieldsComponent ? ( - - ) : null} -
- ); - }; - - const getAddConnectorsForm = (actionItem: AlertAction, index: number) => { - const actionTypeName = actionTypesIndex - ? actionTypesIndex[actionItem.actionTypeId].name - : actionItem.actionTypeId; - const actionTypeRegisterd = actionTypeRegistry.get(actionItem.actionTypeId); - if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null; - return ( - - - - - - -
- -
-
-
- - } - extraAction={ - { - const updatedActions = alert.actions.filter( - (item: AlertAction) => item.id !== actionItem.id - ); - setAlertProperty('actions', updatedActions); - setIsAddActionPanelOpen( - updatedActions.filter((item: AlertAction) => item.id !== actionItem.id).length === 0 - ); - setActiveActionItem(undefined); - }} - /> - } - paddingSize="l" - > - - } - actions={[ - { - setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index }); - setAddModalVisibility(true); - }} - > - - , - ]} - /> -
- ); - }; - - const selectedGroupActions = ( - - {alert.actions.map((actionItem: AlertAction, index: number) => { - const actionConnector = connectors.find(field => field.id === actionItem.id); - // connectors doesn't exists - if (!actionConnector) { - return getAddConnectorsForm(actionItem, index); - } - return getActionTypeForm(actionItem, actionConnector, index); - })} - - {isAddActionPanelOpen === false ? ( - setIsAddActionPanelOpen(true)} - > - - - ) : null} - - ); - - const alertTypeDetails = ( - - - - - -
- -
-
-
- {canChangeTrigger ? ( - - { - setAlertProperty('alertTypeId', null); - setAlertTypeModel(null); - }} - /> - - ) : null} -
- {AlertParamsExpressionComponent ? ( - - ) : null} - - {selectedGroupActions} - {isAddActionPanelOpen ? ( - - -
- -
-
- - - {isLoadingActionTypes ? ( - - - - ) : ( - actionTypeNodes - )} - -
- ) : null} -
- ); - - const labelForAlertChecked = ( - <> - {' '} - - - ); - - const labelForAlertRenotify = ( - <> - {' '} - - - ); - - return ( - - - - - } - isInvalid={errors.name.length > 0 && alert.name !== undefined} - error={errors.name} - > - 0 && alert.name !== undefined} - compressed - name="name" - data-test-subj="alertNameInput" - value={alert.name || ''} - onChange={e => { - setAlertProperty('name', e.target.value); - }} - onBlur={() => { - if (!alert.name) { - setAlertProperty('name', ''); - } - }} - /> - - - - - { - const newOptions = [...tagsOptions, { label: searchValue }]; - setAlertProperty( - 'tags', - newOptions.map(newOption => newOption.label) - ); - }} - onChange={(selectedOptions: Array<{ label: string }>) => { - setAlertProperty( - 'tags', - selectedOptions.map(selectedOption => selectedOption.label) - ); - }} - onBlur={() => { - if (!alert.tags) { - setAlertProperty('tags', []); - } - }} - /> - - - - - - - - - - { - const interval = e.target.value !== '' ? parseInt(e.target.value, 10) : null; - setAlertInterval(interval); - setScheduleProperty('interval', `${e.target.value}${alertIntervalUnit}`); - }} - /> - - - { - setAlertIntervalUnit(e.target.value); - setScheduleProperty('interval', `${alertInterval}${e.target.value}`); - }} - /> - - - - - - - - - { - const throttle = e.target.value !== '' ? parseInt(e.target.value, 10) : null; - setAlertThrottle(throttle); - setAlertProperty('throttle', `${e.target.value}${alertThrottleUnit}`); - }} - /> - - - { - setAlertThrottleUnit(e.target.value); - setAlertProperty('throttle', `${alertThrottle}${e.target.value}`); - }} - /> - - - - - - - {alertTypeModel ? ( - {alertTypeDetails} - ) : ( - - - -
- -
-
- - - {alertTypeNodes} - -
- )} - {actionTypesIndex && activeActionItem ? ( - { - connectors.push(savedAction); - setActionProperty('id', savedAction.id, activeActionItem.index); - }} - actionTypeRegistry={actionTypeRegistry} - alertTypeRegistry={alertTypeRegistry} - http={http} - toastNotifications={toastNotifications} - /> - ) : null} -
- ); -};