Skip to content

Commit

Permalink
Bucket level alerting dev trigger components (opensearch-project#40)
Browse files Browse the repository at this point in the history
* Refactored MonitorType such that the AD definition option cannot be selected for aggregation monitors. Also implemented logic to clear the form when changing from an unsupported definition option to aggregation monitor type. Reimplemented the query response display in the trigger panel when defining an AD trigger condition using the query response option. Also made minor edits to various other classes to align UX with mocks.

* Refactored actions panel to align with new mocks. Disabled throttling when per execution is selected in the action configuration.

* Refactored the visual editor for bucket-level triggers to align with new mocks.

* Refactored the visual and response editor options for query-level AD triggers to align with new mocks. Refactored form reset logic to remove trigger definitions from the form when changing the monitor type.

* Implemented logic to set bucket-level monitor search type to a default value when changing from a query-level monitor with an unsupported search type.

* Refactored monitor details panel on the monitor creation/edit page to align with mocks.

Signed-off-by: Annie Lee <[email protected]>
  • Loading branch information
AWSHurneyt authored and Annie Lee committed Aug 31, 2021
1 parent 66b9642 commit 14f7ce9
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,30 @@
* GitHub history for details.
*/

/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';
import _ from 'lodash';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import FormikCheckableCard from '../../../../components/FormControls/FormikCheckableCard/FormikCheckableCard';
import { OS_AD_PLUGIN, MONITOR_TYPE, SEARCH_TYPE } from '../../../../utils/constants';
import { MONITOR_TYPE_CARD_WIDTH } from '../MonitorType/MonitorType';

const MONITOR_DEFINITION_CARD_WIDTH =
(MONITOR_TYPE_CARD_WIDTH * _.keys(MONITOR_TYPE).length) / _.keys(SEARCH_TYPE).length;

const onChangeDefinition = (e, form) => {
const type = e.target.value;
Expand All @@ -22,17 +42,15 @@ const onChangeDefinition = (e, form) => {
const MonitorDefinitionCard = ({ values, resetResponse, plugins }) => {
const hasADPlugin = plugins.indexOf(OS_AD_PLUGIN) !== -1;
const isBucketLevelMonitor = values.monitor_type === MONITOR_TYPE.BUCKET_LEVEL;

return (
<div>
<EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup alignItems={'flexEnd'} gutterSize={'s'}>
<EuiFlexItem grow={false} style={{ width: `${MONITOR_DEFINITION_CARD_WIDTH}px` }}>
<FormikCheckableCard
name="searchTypeGraph"
formRow
rowProps={{
label: 'Choose a monitor defining method',
style: { paddingLeft: '10px' },
}}
rowProps={{ label: 'Choose a monitor defining method' }}
inputProps={{
id: 'visualEditorRadioCard',
label: 'Visual editor',
Expand All @@ -44,15 +62,11 @@ const MonitorDefinitionCard = ({ values, resetResponse, plugins }) => {
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexItem grow={false} style={{ width: `${MONITOR_DEFINITION_CARD_WIDTH}px` }}>
<EuiSpacer />
<FormikCheckableCard
name="searchTypeQuery"
formRow
rowProps={{
label: '',
style: { paddingLeft: '10px' },
}}
inputProps={{
id: 'extractionQueryEditorRadioCard',
label: 'Extraction query editor',
Expand All @@ -66,7 +80,7 @@ const MonitorDefinitionCard = ({ values, resetResponse, plugins }) => {
</EuiFlexItem>
{/*// Only show the anomaly detector option when anomaly detection plugin is present, but not for bucket-level monitors.*/}
{hasADPlugin && !isBucketLevelMonitor && (
<EuiFlexItem>
<EuiFlexItem grow={false} style={{ width: `${MONITOR_DEFINITION_CARD_WIDTH}px` }}>
<EuiSpacer />
<FormikCheckableCard
name="searchTypeAD"
Expand Down
126 changes: 77 additions & 49 deletions public/pages/CreateMonitor/components/MonitorType/MonitorType.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,70 +9,98 @@
* GitHub history for details.
*/

/*
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';
import _ from 'lodash';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import FormikCheckableCard from '../../../../components/FormControls/FormikCheckableCard';
import { MONITOR_TYPE, SEARCH_TYPE } from '../../../../utils/constants';
import { FORMIK_INITIAL_TRIGGER_VALUES } from '../../../CreateTrigger/containers/CreateTrigger/utils/constants';

export const MONITOR_TYPE_CARD_WIDTH = 400;

const onChangeDefinition = (e, form) => {
const type = e.target.value;
form.setFieldValue('monitor_type', type);

// Clearing trigger definitions when changing monitor types.
// TODO: Implement modal that confirms the change before clearing.
form.setFieldValue('triggerDefinitions', FORMIK_INITIAL_TRIGGER_VALUES.triggerConditions);
};

const queryLevelDescription = (
<EuiText color={'subdued'} size={'xs'} style={{ paddingBottom: '10px', paddingTop: '0px' }}>
Per query monitors run a specified query and allow you to define triggers based on the result of
that query.
</EuiText>
);

const bucketLevelDescription = (
<EuiText color={'subdued'} size={'xs'} style={{ paddingBottom: '10px', paddingTop: '0px' }}>
Per bucket monitors allow you to group results into buckets and define triggers that run per
bucket.
</EuiText>
);

const MonitorType = ({ values }) => (
<div>
<EuiFlexGroup>
<EuiFlexItem>
<FormikCheckableCard
name="monitorTypeQueryLevel"
formRow
rowProps={{
label: 'Choose a monitor type',
style: { paddingLeft: '10px' },
}}
inputProps={{
id: 'queryLevelMonitorRadioCard',
label: 'Query-Level Monitor',
checked: values.monitor_type === MONITOR_TYPE.QUERY_LEVEL,
value: MONITOR_TYPE.QUERY_LEVEL,
onChange: (e, field, form) => {
onChangeDefinition(e, form);
},
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiSpacer />
<FormikCheckableCard
name="monitorTypeBucketLevel"
formRow
rowProps={{
label: '',
style: { paddingLeft: '10px' },
}}
inputProps={{
id: 'bucketLevelMonitorRadioCard',
label: 'Bucket-Level Monitor',
checked: values.monitor_type === MONITOR_TYPE.BUCKET_LEVEL,
value: MONITOR_TYPE.BUCKET_LEVEL,
onChange: (e, field, form) => {
const searchType = _.get(values, 'searchType');
// Setting search type to graph when changing monitor type from query-level to bucket-level,
// and the search type is not supported by bucket-level monitors.
if (searchType !== SEARCH_TYPE.GRAPH || searchType !== SEARCH_TYPE.QUERY)
form.setFieldValue('searchType', SEARCH_TYPE.GRAPH);
onChangeDefinition(e, form);
},
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
</div>
<EuiFlexGroup alignItems={'flexEnd'} gutterSize={'m'}>
<EuiFlexItem grow={false}>
<FormikCheckableCard
name="monitorTypeQueryLevel"
formRow
rowProps={{
label: 'Choose a monitor type',
style: { width: `${MONITOR_TYPE_CARD_WIDTH}px` },
}}
inputProps={{
id: 'queryLevelMonitorRadioCard',
label: 'Per query monitor',
checked: values.monitor_type === MONITOR_TYPE.QUERY_LEVEL,
value: MONITOR_TYPE.QUERY_LEVEL,
onChange: (e, field, form) => {
onChangeDefinition(e, form);
},
children: queryLevelDescription,
}}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<FormikCheckableCard
name="monitorTypeBucketLevel"
formRow
rowProps={{ style: { width: '400px' } }}
inputProps={{
id: 'bucketLevelMonitorRadioCard',
label: 'Per bucket monitor',
checked: values.monitor_type === MONITOR_TYPE.BUCKET_LEVEL,
value: MONITOR_TYPE.BUCKET_LEVEL,
onChange: (e, field, form) => {
const searchType = _.get(values, 'searchType');
// Setting search type to graph when changing monitor type from query-level to bucket-level,
// and the search type is not supported by bucket-level monitors.
if (searchType !== SEARCH_TYPE.GRAPH || searchType !== SEARCH_TYPE.QUERY)
form.setFieldValue('searchType', SEARCH_TYPE.GRAPH);
onChangeDefinition(e, form);
},
children: bucketLevelDescription,
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
);

export default MonitorType;
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
*/

/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';
Expand All @@ -41,13 +41,13 @@ const cronHelpLink = (
const cronHelpText = <EuiText size="s">Use {cronHelpLink} for complex schedules</EuiText>;

const CustomCron = () => (
<EuiFlexGroup direction="column" style={{ paddingLeft: '10px', marginTop: '5px' }}>
<EuiFlexGroup direction="column" style={{ marginTop: '5px' }}>
<EuiFlexItem style={{ marginTop: '0px' }}>
<FormikTextArea
name="cronExpression"
formRow
rowProps={{
label: 'Every',
label: 'Run every',
helpText: cronHelpText,
isInvalid,
error: hasError,
Expand Down
20 changes: 10 additions & 10 deletions public/pages/CreateMonitor/components/Schedule/Frequencies/Daily.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
*/

/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';
Expand All @@ -31,7 +31,7 @@ import { EuiFormRow, EuiDatePicker, EuiFlexGroup, EuiFlexItem } from '@elastic/e
import TimezoneComboBox from './TimezoneComboBox';

const Daily = () => (
<EuiFlexGroup direction="column" style={{ paddingLeft: '10px', marginTop: '5px' }}>
<EuiFlexGroup direction="column" style={{ marginTop: '5px' }}>
<EuiFlexItem style={{ marginTop: '0px' }}>
<Field name="daily">
{({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@
*/

/*
* Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';

import { FormikSelect } from '../../../../../components/FormControls';
import { isInvalid, hasError } from '../../../../../utils/validate';

Expand All @@ -42,8 +41,7 @@ const Frequency = () => (
name="frequency"
formRow
rowProps={{
label: 'Monitor frequency',
style: { paddingLeft: '10px' },
label: 'Frequency',
isInvalid,
error: hasError,
}}
Expand Down
Loading

0 comments on commit 14f7ce9

Please sign in to comment.