mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Add test code capability
This commit is contained in:
parent
8f92a7ce44
commit
ee51eef0c7
5 changed files with 184 additions and 18 deletions
|
@ -1659,4 +1659,4 @@
|
|||
"yargs": "^15.4.1",
|
||||
"yarn-deduplicate": "^6.0.2"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,8 @@ import {
|
|||
EuiSwitch,
|
||||
EuiSwitchEvent,
|
||||
EuiFieldText,
|
||||
EuiCallOut,
|
||||
EuiLoadingSpinner,
|
||||
} from '@elastic/eui';
|
||||
import type { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -27,12 +29,24 @@ import { ActionVariable } from '@kbn/alerting-types';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import type { UserDefinedRuleParams } from '../types';
|
||||
import { CodeEditorModal } from './code_editor_modal';
|
||||
import { useTestUserDefinedRule } from './use_test_user_defined_rule';
|
||||
|
||||
export const RuleForm: React.FunctionComponent<
|
||||
RuleTypeParamsExpressionProps<UserDefinedRuleParams>
|
||||
> = (props) => {
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
const [actionVariableOptions, setActionVariableOptions] = useState<EuiComboBoxOptionOption[]>([]);
|
||||
const [error, setError] = useState<string>('');
|
||||
const [success, setSuccess] = useState<string>('');
|
||||
|
||||
const { mutate: testRule, isLoading } = useTestUserDefinedRule({
|
||||
onSuccess: (data) => {
|
||||
setSuccess(JSON.stringify(data, null, 2));
|
||||
},
|
||||
onError: (data) => {
|
||||
setError(data.body.message);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (null == props.ruleParams.codeOrUrl) {
|
||||
|
@ -73,6 +87,84 @@ export const RuleForm: React.FunctionComponent<
|
|||
[props]
|
||||
);
|
||||
|
||||
const onTestRuleClick = useCallback(() => {
|
||||
setSuccess('');
|
||||
setError('');
|
||||
testRule({
|
||||
isUrl: props.ruleParams.isUrl,
|
||||
codeOrUrl: props.ruleParams.codeOrUrl,
|
||||
customContextVariables: props.ruleParams.customContextVariables,
|
||||
});
|
||||
}, [testRule, props]);
|
||||
|
||||
const renderTestCodeResult = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiLoadingSpinner />
|
||||
</EuiFlexItem>
|
||||
);
|
||||
}
|
||||
if (success) {
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiCallOut title="Your code looks good!" color="success" iconType="check">
|
||||
<EuiCodeBlock fontSize="m" paddingSize="m">
|
||||
{success}
|
||||
</EuiCodeBlock>
|
||||
</EuiCallOut>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
}
|
||||
if (error) {
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiCallOut
|
||||
title="Sorry, there was an error testing your code"
|
||||
color="danger"
|
||||
iconType="error"
|
||||
>
|
||||
<EuiCodeBlock fontSize="m" paddingSize="m">
|
||||
{error}
|
||||
</EuiCodeBlock>
|
||||
</EuiCallOut>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderButtons = () => {
|
||||
const hasError =
|
||||
(props.errors.customContextVariables as string[])?.length > 0 ||
|
||||
(props.errors.codeOrUrl as string[])?.length > 0;
|
||||
|
||||
if (props.ruleParams.isUrl) {
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" onClick={onTestRuleClick} isDisabled={hasError}>
|
||||
Test run
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" onClick={() => setIsModalOpen(true)}>
|
||||
Edit code
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" onClick={onTestRuleClick} isDisabled={hasError}>
|
||||
Test run
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlexGroup direction="column">
|
||||
|
@ -107,6 +199,7 @@ export const RuleForm: React.FunctionComponent<
|
|||
error={(props.errors.codeOrUrl as string[])[0]}
|
||||
>
|
||||
<EuiFieldText
|
||||
fullWidth
|
||||
placeholder="Url"
|
||||
value={props.ruleParams.codeOrUrl}
|
||||
onChange={(e) => onCodeOrUrlChange(e.target.value)}
|
||||
|
@ -130,23 +223,8 @@ export const RuleForm: React.FunctionComponent<
|
|||
</EuiCodeBlock>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" onClick={() => setIsModalOpen(true)}>
|
||||
Edit code
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" disabled>
|
||||
Test run
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</>
|
||||
)}
|
||||
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h5>
|
||||
|
@ -160,7 +238,7 @@ export const RuleForm: React.FunctionComponent<
|
|||
<EuiComboBox
|
||||
fullWidth
|
||||
async
|
||||
isInvalid={props.errors.customContextVariables?.length > 0}
|
||||
isInvalid={(props.errors.customContextVariables as string[])?.length > 0}
|
||||
noSuggestions={!actionVariableOptions?.length}
|
||||
options={actionVariableOptions}
|
||||
data-test-subj="actionVariableComboBox"
|
||||
|
@ -182,6 +260,8 @@ export const RuleForm: React.FunctionComponent<
|
|||
onSearchChange={loadActionVariableOptions}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{renderTestCodeResult()}
|
||||
{renderButtons()}
|
||||
</EuiFlexGroup>
|
||||
<EuiSpacer />
|
||||
<CodeEditorModal
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { HttpSetup } from '@kbn/core/public';
|
||||
import { INTERNAL_BASE_ALERTING_API_PATH } from '@kbn/alerting-plugin/common';
|
||||
|
||||
export const testUserDefinedRule = ({
|
||||
http,
|
||||
isUrl,
|
||||
codeOrUrl,
|
||||
customContextVariables,
|
||||
}: {
|
||||
http: HttpSetup;
|
||||
isUrl: boolean;
|
||||
codeOrUrl: string;
|
||||
customContextVariables?: Array<{
|
||||
name: string;
|
||||
description: string;
|
||||
}>;
|
||||
}) => {
|
||||
return http.post(`${INTERNAL_BASE_ALERTING_API_PATH}/rule/_test`, {
|
||||
body: JSON.stringify({
|
||||
params: {
|
||||
isUrl,
|
||||
codeOrUrl,
|
||||
...(customContextVariables ? { customContextVariables } : {}),
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { HttpSetup } from '@kbn/core-http-browser';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { testUserDefinedRule } from './test_user_defined_rule';
|
||||
|
||||
export const useTestUserDefinedRule = ({
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess: (data: unknown) => void;
|
||||
onError: (data: {
|
||||
body: {
|
||||
message: string;
|
||||
};
|
||||
}) => void;
|
||||
}) => {
|
||||
const { http } = useKibana<{
|
||||
http: HttpSetup;
|
||||
}>().services;
|
||||
|
||||
const mutation = ({
|
||||
isUrl,
|
||||
codeOrUrl,
|
||||
customContextVariables,
|
||||
}: {
|
||||
isUrl: boolean;
|
||||
codeOrUrl: string;
|
||||
customContextVariables?: Array<{
|
||||
name: string;
|
||||
description: string;
|
||||
}>;
|
||||
}) => {
|
||||
return testUserDefinedRule({
|
||||
http,
|
||||
isUrl,
|
||||
codeOrUrl,
|
||||
customContextVariables,
|
||||
});
|
||||
};
|
||||
|
||||
return useMutation(mutation, {
|
||||
onSuccess,
|
||||
onError,
|
||||
});
|
||||
};
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { parseDuration } from '../../../../../alerting/common/parse_duration.ts';
|
||||
import { parseDuration } from '@kbn/alerting-plugin/common/parse_duration';
|
||||
|
||||
if (!Deno.env.get('QUERY_DELAY_MS')) {
|
||||
throw new Error('QUERY_DELAY_MS not set');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue