-
Notifications
You must be signed in to change notification settings - Fork 71
Fix various bugs #504
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
Fix various bugs #504
Changes from all commits
8c6a8bd
a9f28c1
be37b70
dc15cff
c233860
b8af76e
12f25c4
9cf2919
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,6 +70,7 @@ import { | |
| import { | ||
| focusOnFirstWrongFeature, | ||
| initialFeatureValue, | ||
| validateFeatures, | ||
| } from '../../../../public/pages/ConfigureModel/utils/helpers'; | ||
| import { | ||
| getIndices, | ||
|
|
@@ -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'; | ||
|
|
@@ -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) { | ||
|
amitgalitz marked this conversation as resolved.
|
||
| 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) => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: why not use
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the return type of this function is not ideal, wanted to show warning toast message instead of that not well formatted error message |
||
| 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.' | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
|
|
@@ -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) => {}) | ||
|
|
@@ -222,7 +269,7 @@ function AddAnomalyDetector({ | |
| const augmentVisSavedObjectToCreate: ISavedAugmentVis = | ||
| getAugmentVisSavedObject(detectorId); | ||
|
|
||
| createAugmentVisSavedObject( | ||
| await createAugmentVisSavedObject( | ||
| augmentVisSavedObjectToCreate, | ||
| savedObjectLoader, | ||
| uiSettings | ||
|
|
@@ -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( | ||
|
|
@@ -426,6 +473,7 @@ function AddAnomalyDetector({ | |
| initialValues={initialDetectorValue} | ||
| onSubmit={handleSubmit} | ||
| validateOnChange={true} | ||
| validate={validateFeatures} | ||
|
ohltyler marked this conversation as resolved.
|
||
| > | ||
| {(formikProps) => ( | ||
| <> | ||
|
|
@@ -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> | ||
| } | ||
|
|
@@ -584,7 +632,7 @@ function AddAnomalyDetector({ | |
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiText> | ||
| <p className="minutes">minutes</p> | ||
| <p className="minutes">minute(s)</p> | ||
| </EuiText> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
|
|
@@ -618,7 +666,7 @@ function AddAnomalyDetector({ | |
| </EuiFlexItem> | ||
| <EuiFlexItem> | ||
| <EuiText> | ||
| <p className="minutes">minutes</p> | ||
| <p className="minutes">minute(s)</p> | ||
| </EuiText> | ||
| </EuiFlexItem> | ||
| </EuiFlexGroup> | ||
|
|
@@ -788,8 +836,6 @@ function AddAnomalyDetector({ | |
| isOpen={accordionsOpen.modelFeatures} | ||
| onToggle={() => onAccordionToggle('modelFeatures')} | ||
| > | ||
| <EuiSpacer size="s" /> | ||
|
|
||
| <FieldArray name="featureList"> | ||
| {({ | ||
| push, | ||
|
|
@@ -811,6 +857,8 @@ function AddAnomalyDetector({ | |
| /> | ||
| ) | ||
| )} | ||
|
|
||
| <EuiSpacer size="m" /> | ||
| <EuiPanel paddingSize="none"> | ||
| <EuiButton | ||
| className="featureButton" | ||
|
|
@@ -841,6 +889,7 @@ function AddAnomalyDetector({ | |
| }} | ||
| </FieldArray> | ||
| </EnhancedAccordion> | ||
| <EuiSpacer size="m" /> | ||
| </div> | ||
| )} | ||
| </div> | ||
|
|
||
| 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, | ||
|
|
@@ -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) | ||
|
|
@@ -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) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add a regression test for this?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, will add a test case for this later. Looked up react best practice guidance. It seems like this is the best practice on how to check if an array is empty as react doesn't have built-in Array.isEmpty() method
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just meant adding a test where this conditional is false. Also, you may use lodash |
||
| 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') { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we define count as value_count in our code across the board?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| return 'value_count'; | ||
| } | ||
| return 'sum'; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| .euiFormAccordion_button { | ||
| padding: 20px 16px 0 0; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.