Skip to content

Commit

Permalink
[FEATURE] More validations on YAML rule editor (opensearch-project#279)
Browse files Browse the repository at this point in the history
* yaml editor as custom form component

Signed-off-by: Aleksandar Djindjic <[email protected]>

* refactor file structure for rule editor

Signed-off-by: Aleksandar Djindjic <[email protected]>

* rename RuleEditorFormState to RuleEditorFormModel

Signed-off-by: Aleksandar Djindjic <[email protected]>

* refactor yaml rule editor custom form component

Signed-off-by: Aleksandar Djindjic <[email protected]>

* pr comments fixes and snapshot tests

Signed-off-by: Aleksandar Djindjic <[email protected]>

* more snapshot tests

Signed-off-by: Aleksandar Djindjic <[email protected]>

* align fields labels styling with create detector

Signed-off-by: Aleksandar Djindjic <[email protected]>

* aligne formik version with alerting plugin

Signed-off-by: Aleksandar Djindjic <[email protected]>

* addresing validation UX issues

Signed-off-by: Aleksandar Djindjic <[email protected]>

* validate tag format

Signed-off-by: Aleksandar Djindjic <[email protected]>

Signed-off-by: Aleksandar Djindjic <[email protected]>
  • Loading branch information
djindjic authored Jan 9, 2023
1 parent 9072a4f commit 6da7c82
Show file tree
Hide file tree
Showing 24 changed files with 878 additions and 995 deletions.
6 changes: 2 additions & 4 deletions cypress/integration/2_rules.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,10 @@ describe('Rules', () => {
);

// Enter the reference
cy.get('[data-test-subj="rule_references_-_optional_field_0"]').type(SAMPLE_RULE.references);
cy.get('[data-test-subj="rule_references_field_0"]').type(SAMPLE_RULE.references);

// Enter the false positive cases
cy.get('[data-test-subj="rule_false_positive_cases_-_optional_field_0"]').type(
SAMPLE_RULE.falsePositive
);
cy.get('[data-test-subj="rule_false_positives_field_0"]').type(SAMPLE_RULE.falsePositive);

// Enter the author
cy.get('[data-test-subj="rule_author_field"]').type(SAMPLE_RULE.author);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@
"yarn": "^1.21.1"
},
"dependencies": {
"formik": "^2.2.9"
"formik": "^2.2.6"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ export const UpdateDetectorRules: React.FC<UpdateDetectorRulesProps> = (props) =
const ruleItems = prePackagedRuleItems.concat(customRuleItems);

const onRuleDetails = (ruleItem: RuleItem) => {
console.log('onRuleDetails', ruleItem);
setFlyoutData(() => ({
title: ruleItem.name,
level: ruleItem.severity,
Expand Down
6 changes: 4 additions & 2 deletions public/pages/Rules/components/RuleEditor/FieldTextArray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
import React, { ChangeEvent } from 'react';

export interface FieldTextArrayProps {
label: string;
label: string | React.ReactNode;
name: string;
fields: string[];
addButtonName: string;
onFieldEdit: (value: string, fieldIndex: number) => void;
Expand All @@ -25,6 +26,7 @@ export interface FieldTextArrayProps {
export const FieldTextArray: React.FC<FieldTextArrayProps> = ({
addButtonName,
label,
name,
fields,
onFieldEdit,
onFieldRemove,
Expand All @@ -43,7 +45,7 @@ export const FieldTextArray: React.FC<FieldTextArrayProps> = ({
onChange={(e: ChangeEvent<HTMLInputElement>) => {
onFieldEdit(e.target.value, index);
}}
data-test-subj={`rule_${label
data-test-subj={`rule_${name
.toLowerCase()
.replaceAll(' ', '_')}_field_${index}`}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useFormikContext } from 'formik';
import { NotificationsStart } from 'opensearch-dashboards/public';
import { errorNotificationToast } from '../../../../utils/helpers';

export const FormSubmitionErrorToastNotification = ({
export const FormSubmissionErrorToastNotification = ({
notifications,
}: {
notifications?: NotificationsStart;
Expand Down
140 changes: 0 additions & 140 deletions public/pages/Rules/components/RuleEditor/RuleEditor.tsx

This file was deleted.

92 changes: 92 additions & 0 deletions public/pages/Rules/components/RuleEditor/RuleEditorContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useCallback } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { NotificationsStart } from 'opensearch-dashboards/public';
import { RuleService } from '../../../../services';
import { ROUTES } from '../../../../utils/constants';
import { EuiSpacer } from '@elastic/eui';
import { Rule } from '../../../../../models/interfaces';
import { RuleEditorFormModel, ruleEditorStateDefaultValue } from './RuleEditorFormModel';
import { mapFormToRule, mapRuleToForm } from './mappers';
import { RuleEditorForm } from './RuleEditorForm';
import { validateRule } from '../../utils/helpers';
import { errorNotificationToast } from '../../../../utils/helpers';

export interface RuleEditorProps {
title: string;
rule?: Rule;
history: RouteComponentProps['history'];
notifications?: NotificationsStart;
ruleService: RuleService;
mode: 'create' | 'edit';
}

export interface VisualEditorFormErrorsState {
nameError: string | null;
descriptionError: string | null;
authorError: string | null;
}

export const RuleEditorContainer: React.FC<RuleEditorProps> = ({
history,
notifications,
title,
rule,
ruleService,
mode,
}) => {
const initialRuleValue = rule
? { ...mapRuleToForm(rule), id: ruleEditorStateDefaultValue.id }
: ruleEditorStateDefaultValue;

const onSubmit = async (values: RuleEditorFormModel) => {
const submitingRule = mapFormToRule(values);
if (!validateRule(submitingRule, notifications!, 'create')) {
return;
}

let result;
if (mode === 'edit') {
if (!rule) {
console.error('No rule id found');
return;
}
result = await ruleService.updateRule(rule?.id, submitingRule.category, submitingRule);
} else {
result = await ruleService.createRule(submitingRule);
}

if (!result.ok) {
errorNotificationToast(
notifications!,
mode === 'create' ? 'create' : 'save',
'rule',
result.error
);
} else {
history.replace(ROUTES.RULES);
}
};

const goToRulesList = useCallback(() => {
history.replace(ROUTES.RULES);
}, [history]);

return (
<>
<RuleEditorForm
title={title}
mode={mode}
notifications={notifications}
initialValue={initialRuleValue}
cancel={goToRulesList}
submit={onSubmit}
/>
<EuiSpacer size="xl" />
</>
);
};
Loading

0 comments on commit 6da7c82

Please sign in to comment.