Skip to content

Commit

Permalink
WIP: Fixing type errors in the other form steps
Browse files Browse the repository at this point in the history
Things still aren't quite working, state gets lost when moving through
steps but I believe this is addressed in an outstanding PR so I'm not
sweating it right now.

* Removes as much state in Step components as possible
  * We shouldn't need this as the form holds all the state as well. If
    we need to "watch" for a change, we can subscribe to the form's
    observable to replace FormDataProvider and local state (TODO)
* Removes setting of default values in form components
  * I believe that this is redundant with defaultValues provided to
    useForm, but I need to verify.
  • Loading branch information
rylnd committed Aug 27, 2020
1 parent fdf2cf4 commit 788135b
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { EuiAccordion, EuiFlexItem, EuiSpacer, EuiFormRow } from '@elastic/eui';
import React, { FC, memo, useCallback, useEffect, useState } from 'react';
import React, { FC, memo, useCallback, useEffect } from 'react';
import styled from 'styled-components';

import { isMlRule } from '../../../../../common/machine_learning/helpers';
Expand Down Expand Up @@ -72,7 +72,6 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
setStepData,
}) => {
const initialState = defaultValues ?? stepAboutDefaultValue;
const [myStepData, setMyStepData] = useState<AboutStepRule>(initialState);
const [{ isLoading: indexPatternLoading, indexPatterns }] = useFetchIndexPatterns(
defineRuleData?.index ?? [],
'step_about_rule'
Expand All @@ -82,33 +81,32 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
!isMlRule(defineRuleData.ruleType) &&
!isThresholdRule(defineRuleData.ruleType);

const { form } = useForm({
const { form } = useForm<AboutStepRule>({
defaultValue: initialState,
options: { stripEmptyFields: false },
schema,
});
const { getFields, submit } = form;
const { getFields, reset, submit } = form;

const onSubmit = useCallback(async () => {
if (setStepData) {
setStepData(RuleStep.aboutRule, null, false);
const { isValid, data } = await submit();
if (isValid) {
setStepData(RuleStep.aboutRule, data, isValid);
setMyStepData(data as AboutStepRule);
reset({ defaultValue: data });
}
}
}, [setStepData, submit]);
}, [reset, setStepData, submit]);

useEffect(() => {
if (setForm) {
setForm(RuleStep.aboutRule, form);
}
}, [setForm, form]);

return isReadOnlyView && myStepData.name != null ? (
return isReadOnlyView ? (
<StepContentWrapper data-test-subj="aboutStep" addPadding={addPadding}>
<StepRuleDescription columns={descriptionColumns} schema={schema} data={myStepData} />
<StepRuleDescription columns={descriptionColumns} schema={schema} data={initialState} />
</StepContentWrapper>
) : (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import {
ValidationFunc,
ERROR_CODE,
} from '../../../../shared_imports';
import { IMitreEnterpriseAttack } from '../../../pages/detection_engine/rules/types';
import { IMitreEnterpriseAttack, AboutStepRule } from '../../../pages/detection_engine/rules/types';
import { isMitreAttackInvalid } from '../mitre/helpers';
import { OptionalFieldLabel } from '../optional_field_label';
import { isUrlInvalid } from '../../../../common/utils/validators';
import * as I18n from './translations';

const { emptyField } = fieldValidators;

export const schema: FormSchema = {
export const schema: FormSchema<AboutStepRule> = {
author: {
type: FIELD_TYPES.COMBO_BOX,
label: i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import * as i18n from './translations';
const CommonUseField = getUseField({ component: Field });

interface StepDefineRuleProps extends RuleStepProps {
defaultValues: DefineStepRule | undefined;
defaultValues?: DefineStepRule;
}

const stepDefineDefaultValue: DefineStepRule = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
actionMessageParams,
}) => {
const initialState = defaultValues ?? stepActionsDefaultValue;
const [myStepData, setMyStepData] = useState<ActionsStepRule>(initialState);
const [throttle, setThrottle] = useState<ActionsStepRule['throttle']>(initialState.throttle);
const {
services: {
application,
Expand All @@ -78,12 +78,12 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
} = useKibana();
const schema = useMemo(() => getSchema({ actionTypeRegistry }), [actionTypeRegistry]);

const { form } = useForm({
const { form } = useForm<ActionsStepRule>({
defaultValue: initialState,
options: { stripEmptyFields: false },
schema,
});
const { submit } = form;
const { getFields, reset, submit } = form;

const kibanaAbsoluteUrl = useMemo(
() =>
Expand All @@ -96,15 +96,16 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
const onSubmit = useCallback(
async (enabled: boolean) => {
if (setStepData) {
setStepData(RuleStep.ruleActions, null, false);
const { isValid: newIsValid, data } = await submit();
if (newIsValid) {
setStepData(RuleStep.ruleActions, { ...data, enabled }, newIsValid);
setMyStepData(data as ActionsStepRule);
// setStepData(RuleStep.ruleActions, null, false);
const { isValid, data } = await submit();
if (isValid) {
setStepData(RuleStep.ruleActions, { ...data, enabled }, isValid);
reset({ defaultValue: { ...data, enabled } });
// setMyStepData(data as ActionsStepRule);
}
}
},
[setStepData, submit]
[reset, setStepData, submit]
);

useEffect(() => {
Expand All @@ -113,16 +114,18 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
}
}, [form, setForm]);

const updateThrottle = useCallback((throttle) => setMyStepData({ ...myStepData, throttle }), [
myStepData,
setMyStepData,
]);
const updateThrottle = useCallback(
(_throttle) => {
const throttleField = getFields().throttle;
throttleField.setValue(_throttle);
setThrottle(_throttle);
},
[getFields]
);

const throttleOptions = useMemo(() => {
const throttle = myStepData.throttle;

return getThrottleOptions(throttle);
}, [myStepData]);
}, [throttle]);

const throttleFieldComponentProps = useMemo(
() => ({
Expand All @@ -135,13 +138,12 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
options: throttleOptions,
},
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[isLoading, updateThrottle]
[isLoading, throttleOptions, updateThrottle]
);

return isReadOnlyView && myStepData != null ? (
return isReadOnlyView ? (
<StepContentWrapper addPadding={addPadding}>
<StepRuleDescription schema={schema} data={myStepData} columns="single" />
<StepRuleDescription schema={schema} data={initialState} columns="single" />
</StepContentWrapper>
) : (
<>
Expand All @@ -153,12 +155,12 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
component={ThrottleSelectField}
componentProps={throttleFieldComponentProps}
/>
{myStepData.throttle !== stepActionsDefaultValue.throttle ? (
{throttle !== stepActionsDefaultValue.throttle ? (
<>
<EuiSpacer />
<UseField
path="actions"
defaultValue={myStepData.actions}
// defaultValue={initialState.actions}
component={RuleActionsField}
componentProps={{
messageVariables: actionMessageParams,
Expand All @@ -168,7 +170,7 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
) : (
<UseField
path="actions"
defaultValue={myStepData.actions}
// defaultValue={initialState.actions}
component={GhostFormField}
/>
)}
Expand All @@ -177,7 +179,7 @@ const StepRuleActionsComponent: FC<StepRuleActionsProps> = ({
defaultValue={kibanaAbsoluteUrl}
component={GhostFormField}
/>
<UseField path="enabled" defaultValue={myStepData.enabled} component={GhostFormField} />
<UseField path="enabled" component={GhostFormField} />
</EuiForm>
</Form>
</StepContentWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
AlertAction,
ActionTypeRegistryContract,
} from '../../../../../../triggers_actions_ui/public';
import { FormSchema, FormData, ValidationFunc, ERROR_CODE } from '../../../../shared_imports';
import { FormSchema, ValidationFunc, ERROR_CODE } from '../../../../shared_imports';
import { ActionsStepRule } from '../../../pages/detection_engine/rules/types';
import * as I18n from './translations';
import { isUuidv4, getActionTypeName, validateMustache, validateActionParams } from './utils';

Expand Down Expand Up @@ -61,7 +62,7 @@ export const getSchema = ({
actionTypeRegistry,
}: {
actionTypeRegistry: ActionTypeRegistryContract;
}): FormSchema<FormData> => ({
}): FormSchema<ActionsStepRule> => ({
actions: {
validations: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { FC, memo, useCallback, useEffect, useState } from 'react';
import React, { FC, memo, useCallback, useEffect } from 'react';

import {
RuleStep,
Expand Down Expand Up @@ -38,35 +38,35 @@ const StepScheduleRuleComponent: FC<StepScheduleRuleProps> = ({
setForm,
}) => {
const initialState = defaultValues ?? stepScheduleDefaultValue;
const [myStepData, setMyStepData] = useState<ScheduleStepRule>(initialState);
// const [myStepData, setMyStepData] = useState<ScheduleStepRule>(initialState);

const { form } = useForm({
const { form } = useForm<ScheduleStepRule>({
defaultValue: initialState,
options: { stripEmptyFields: false },
schema,
});
const { submit } = form;
const { reset, submit } = form;

const onSubmit = useCallback(async () => {
if (setStepData) {
setStepData(RuleStep.scheduleRule, null, false);
const { isValid: newIsValid, data } = await submit();
if (newIsValid) {
setStepData(RuleStep.scheduleRule, { ...data }, newIsValid);
setMyStepData(data as ScheduleStepRule);
// setStepData(RuleStep.scheduleRule, null, false);
const { isValid, data } = await submit();
if (isValid) {
setStepData(RuleStep.scheduleRule, data, isValid);
reset({ defaultValue: data });
}
}
}, [setStepData, submit]);
}, [reset, setStepData, submit]);

useEffect(() => {
if (setForm) {
setForm(RuleStep.scheduleRule, form);
}
}, [form, setForm]);

return isReadOnlyView && myStepData != null ? (
return isReadOnlyView ? (
<StepContentWrapper addPadding={addPadding}>
<StepRuleDescription columns={descriptionColumns} schema={schema} data={myStepData} />
<StepRuleDescription columns={descriptionColumns} schema={schema} data={initialState} />
</StepContentWrapper>
) : (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
import { i18n } from '@kbn/i18n';

import { OptionalFieldLabel } from '../optional_field_label';
import { ScheduleStepRule } from '../../../pages/detection_engine/rules/types';
import { FormSchema } from '../../../../shared_imports';

export const schema: FormSchema = {
export const schema: FormSchema<ScheduleStepRule> = {
interval: {
label: i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepScheduleRule.fieldIntervalLabel',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ const CreateRulePageComponent: React.FC = () => {
const manageIsEditable = useCallback(
async (step: RuleStep) => {
const activeForm = await stepsForm.current[activeStep]?.submit();
if (activeForm != null && activeForm?.isValid) {
if (activeForm?.isValid) {
stepsData.current[activeStep].isValid = true;
stepsData.current[activeStep].data = {
...stepsData.current[activeStep].data,
Expand Down

0 comments on commit 788135b

Please sign in to comment.