Skip to content

Commit

Permalink
Fix various bugs (opensearch-project#504)
Browse files Browse the repository at this point in the history
* fix bug bash bugs

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* bug fix

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* yarn prettier

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* bug fix

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* bug fixes

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* clean up code

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

* removed unused snapshot

Signed-off-by: Jackie Han <jkhanjob@gmail.com>

---------

Signed-off-by: Jackie Han <jkhanjob@gmail.com>
Signed-off-by: Jackie Han <hnyng@amazon.com>
  • Loading branch information
jackiehanyang authored and amitgalitz committed Jul 7, 2023
1 parent 88324cd commit f3266b8
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import {
import {
focusOnFirstWrongFeature,
initialFeatureValue,
validateFeatures,
} from '../../../../public/pages/ConfigureModel/utils/helpers';
import {
getIndices,
Expand All @@ -95,6 +96,8 @@ import {
ORIGIN_PLUGIN_VIS_LAYER,
OVERLAY_ANOMALIES,
VIS_LAYER_PLUGIN_TYPE,
PLUGIN_AUGMENTATION_ENABLE_SETTING,
PLUGIN_AUGMENTATION_MAX_OBJECTS_SETTING,
} from '../../../../public/expressions/constants';
import { formikToDetectorName, visFeatureListToFormik } from './helpers';
import { AssociateExisting } from './AssociateExisting';
Expand Down Expand Up @@ -157,11 +160,55 @@ function AddAnomalyDetector({

const notifications = getNotifications();
const handleValidationAndSubmit = (formikProps) => {
if (!isEmpty(formikProps.errors)) {
focusOnFirstWrongFeature(formikProps.errors, formikProps.setFieldTouched);
notifications.toasts.addDanger('One or more input fields is invalid');
if (formikProps.values.featureList.length !== 0) {
formikProps.setFieldTouched('featureList', true);
formikProps.validateForm().then(async (errors) => {
if (!isEmpty(errors)) {
focusOnFirstWrongFeature(errors, formikProps.setFieldTouched);
notifications.toasts.addDanger(
'One or more input fields is invalid.'
);
} else {
const isAugmentationEnabled = uiSettings.get(
PLUGIN_AUGMENTATION_ENABLE_SETTING
);
if (!isAugmentationEnabled) {
notifications.toasts.addDanger(
'Visualization augmentation is disabled, please enable visualization:enablePluginAugmentation.'
);
} else {
const maxAssociatedCount = uiSettings.get(
PLUGIN_AUGMENTATION_MAX_OBJECTS_SETTING
);
await savedObjectLoader.findAll().then(async (resp) => {
if (resp !== undefined) {
const savedAugmentObjects = get(resp, 'hits', []);
// gets all the saved object for this visualization
const savedObjectsForThisVisualization =
savedAugmentObjects.filter(
(savedObj) =>
get(savedObj, 'visId', '') === embeddable.vis.id
);
if (
maxAssociatedCount <= savedObjectsForThisVisualization.length
) {
notifications.toasts.addDanger(
`Cannot create the detector and associate it to the visualization due to the limit of the max
amount of associated plugin resources (${maxAssociatedCount}) with
${savedObjectsForThisVisualization.length} associated to the visualization`
);
} else {
handleSubmit(formikProps);
}
}
});
}
}
});
} else {
handleSubmit(formikProps);
notifications.toasts.addDanger(
'One or more features are required.'
);
}
};

Expand Down Expand Up @@ -203,7 +250,7 @@ function AddAnomalyDetector({
formikProps.setSubmitting(true);
try {
const detectorToCreate = formikToDetector(formikProps.values);
dispatch(createDetector(detectorToCreate))
await dispatch(createDetector(detectorToCreate))
.then(async (response) => {
dispatch(startDetector(response.response.id))
.then((startDetectorResponse) => {})
Expand All @@ -222,7 +269,7 @@ function AddAnomalyDetector({
const augmentVisSavedObjectToCreate: ISavedAugmentVis =
getAugmentVisSavedObject(detectorId);

createAugmentVisSavedObject(
await createAugmentVisSavedObject(
augmentVisSavedObjectToCreate,
savedObjectLoader,
uiSettings
Expand Down Expand Up @@ -408,7 +455,7 @@ function AddAnomalyDetector({
windowDelay: delayValue,
shingleSize: 8,
filterQuery: { match_all: {} },
description: '',
description: 'Created based on ' + embeddable.vis.title,
resultIndex: undefined,
filters: [],
featureList: visFeatureListToFormik(
Expand All @@ -426,6 +473,7 @@ function AddAnomalyDetector({
initialValues={initialDetectorValue}
onSubmit={handleSubmit}
validateOnChange={true}
validate={validateFeatures}
>
{(formikProps) => (
<>
Expand Down Expand Up @@ -532,8 +580,8 @@ function AddAnomalyDetector({
subTitle={
<EuiText size="m">
<p>
Detector interval: {intervalValue} minutes; Window
delay: {delayValue} minutes
Detector interval: {intervalValue} minute(s); Window
delay: {delayValue} minute(s)
</p>
</EuiText>
}
Expand Down Expand Up @@ -584,7 +632,7 @@ function AddAnomalyDetector({
</EuiFlexItem>
<EuiFlexItem>
<EuiText>
<p className="minutes">minutes</p>
<p className="minutes">minute(s)</p>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down Expand Up @@ -618,7 +666,7 @@ function AddAnomalyDetector({
</EuiFlexItem>
<EuiFlexItem>
<EuiText>
<p className="minutes">minutes</p>
<p className="minutes">minute(s)</p>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down Expand Up @@ -788,8 +836,6 @@ function AddAnomalyDetector({
isOpen={accordionsOpen.modelFeatures}
onToggle={() => onAccordionToggle('modelFeatures')}
>
<EuiSpacer size="s" />

<FieldArray name="featureList">
{({
push,
Expand All @@ -811,6 +857,8 @@ function AddAnomalyDetector({
/>
)
)}

<EuiSpacer size="m" />
<EuiPanel paddingSize="none">
<EuiButton
className="featureButton"
Expand Down Expand Up @@ -841,6 +889,7 @@ function AddAnomalyDetector({
}}
</FieldArray>
</EnhancedAccordion>
<EuiSpacer size="m" />
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { dispatch } from 'd3';
import { matchDetector } from 'public/redux/reducers/ad';
import { validateDetectorName } from 'public/utils/utils';
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { FEATURE_TYPE } from '../../../../public/models/interfaces';
import { FeaturesFormikValues } from '../../../../public/pages/ConfigureModel/models/interfaces';
import { find, get, isEmpty, snakeCase } from 'lodash';
import { find, snakeCase } from 'lodash';
import { AGGREGATION_TYPES } from '../../../../public/pages/ConfigureModel/utils/constants';

export function visFeatureListToFormik(
featureList,
Expand All @@ -17,7 +20,7 @@ export function visFeatureListToFormik(
featureType: FEATURE_TYPE.SIMPLE,
importance: 1,
newFeature: false,
aggregationBy: 'sum',
aggregationBy: visAggregationTypeToFormik(feature),
aggregationOf: visAggregationToFormik(feature),
aggregationQuery: JSON.stringify(
visAggregationQueryToFormik(feature, seriesParams)
Expand All @@ -44,18 +47,40 @@ const getFeatureNameFromVisParams = (id, seriesParams) => {
};

function visAggregationToFormik(value) {
return [
{
label: value.params.field.name,
type: 'number',
},
];
if (Object.values(value.params).length !== 0) {
return [
{
label: value.params?.field?.name,
type: value.type,
},
];
}
// for count type of vis, there's no field name in the embeddable-vis schema
return [];
}

function visAggregationQueryToFormik(value, seriesParams) {
return {
[snakeCase(getFeatureNameFromVisParams(value.id, seriesParams))]: {
sum: { field: value.params.field.name },
},
};
if (Object.values(value.params).length !== 0) {
return {
[snakeCase(getFeatureNameFromVisParams(value.id, seriesParams))]: {
[visAggregationTypeToFormik(value)]: {
field: value.params?.field?.name,
},
},
};
}
// for count type of vis, there's no field name in the embeddable-vis schema
// return '' as the custom expression query
return '';
}

function visAggregationTypeToFormik(feature) {
const aggType = feature.__type.name;
if (AGGREGATION_TYPES.some((type) => type.value === aggType)) {
return aggType;
}
if (aggType === 'count') {
return 'value_count';
}
return 'sum';
}
6 changes: 6 additions & 0 deletions public/expressions/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ export const OVERLAY_ANOMALIES = 'overlay_anomalies';

export const PLUGIN_EVENT_TYPE = 'Anomalies';

export const PLUGIN_AUGMENTATION_ENABLE_SETTING =
'visualization:enablePluginAugmentation';

export const PLUGIN_AUGMENTATION_MAX_OBJECTS_SETTING =
'visualization:enablePluginAugmentation.maxPluginObjects';

export const DETECTOR_HAS_BEEN_DELETED = 'detector has been deleted';

export const START_OR_END_TIME_INVALID_ERROR = 'start or end time invalid';
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
EuiCheckbox,
EuiButtonIcon,
} from '@elastic/eui';
import './styles.scss';
import { Field, FieldProps } from 'formik';
import {
required,
Expand Down Expand Up @@ -80,6 +81,18 @@ export const FeatureAccordion = (props: FeatureAccordionProps) => {
};

const featureButtonContent = (feature: any, index: number) => {
if (props.displayMode === 'flyout') {
return (
<div id={`featureAccordionHeaders.${index}`}>
<EuiTitle size="xxs">
<h5 style={{ marginTop: '-5px', fontWeight: 400 }}>
{feature.featureName ? feature.featureName : 'Add feature'}
</h5>
</EuiTitle>
{showSubtitle ? showFeatureDescription(feature) : null}
</div>
);
}
return (
<div id={`featureAccordionHeaders.${index}`}>
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
Expand Down Expand Up @@ -125,7 +138,7 @@ export const FeatureAccordion = (props: FeatureAccordionProps) => {
buttonClassName={
props.index === 0
? 'euiAccordionForm__noTopPaddingButton'
: 'euiAccordionForm__button'
: 'euiFormAccordion_button'
}
className="euiAccordion__noTopBorder"
paddingSize="l"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.euiFormAccordion_button {
padding: 20px 16px 0 0;
}
4 changes: 2 additions & 2 deletions public/utils/contextMenu/getActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { FLYOUT_MODES } from '../../../public/components/FeatureAnywhereContextM
const grouping: Action['grouping'] = [
{
id: 'ad-dashboard-context-menu',
getDisplayName: () => 'Anomaly Detector',
getDisplayName: () => 'Anomaly Detection',
getIconType: () => APM_TRACE,
},
];
Expand Down Expand Up @@ -54,7 +54,7 @@ export const getActions = () => {
title: i18n.translate(
'dashboard.actions.adMenuItem.createAnomalyDetector.displayName',
{
defaultMessage: 'Create anomaly detector',
defaultMessage: 'Add anomaly detector',
}
),
icon: 'plusInCircle' as EuiIconType,
Expand Down

0 comments on commit f3266b8

Please sign in to comment.