Skip to content

Commit

Permalink
[OBX-UX-MNGMT] Allow decimals in the threshold filed for the Failed t…
Browse files Browse the repository at this point in the history
…ransaction rate threshold rule (#184647)

## Summary

It fixes #184527 by allowing decimals in the threshold value. This was a
purely UI restriction.

![Screenshot 2024-06-03 at 14 29
23](https://github.com/elastic/kibana/assets/6838659/cce7eb52-977d-403d-b4e3-6e9e5a87a8d3)

### Release note:
Now we allow the decimals value in the threshold filed for the Failed
transaction rate threshold rule e.g. `30.50`% or `0.1` %
  • Loading branch information
fkanout authored Jun 24, 2024
1 parent 15d19bf commit 9280bdd
Showing 1 changed file with 60 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* 2.0.
*/
import moment from 'moment';
import { EuiFieldNumber } from '@elastic/eui';
import { EuiExpression, EuiFieldNumber, EuiFormRow, EuiPopover } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import React, { useState } from 'react';
import {
ERROR_GROUP_ID,
SERVICE_ENVIRONMENT,
Expand Down Expand Up @@ -42,7 +42,7 @@ export function ServiceField({
<SuggestionsSelect
customOptions={allowAll ? [{ label: allOptionText, value: undefined }] : undefined}
customOptionText={i18n.translate('xpack.apm.serviceNamesSelectCustomOptionText', {
defaultMessage: `Add '{searchValue}' as a new service name`,
defaultMessage: 'Add \\{searchValue\\} as a new service name',
})}
defaultValue={currentValue}
fieldName={SERVICE_NAME}
Expand Down Expand Up @@ -76,7 +76,7 @@ export function EnvironmentField({
<SuggestionsSelect
customOptions={[ENVIRONMENT_ALL]}
customOptionText={i18n.translate('xpack.apm.environmentsSelectCustomOptionText', {
defaultMessage: `Add '{searchValue}' as a new environment`,
defaultMessage: 'Add \\{searchValue\\} as a new environment',
})}
defaultValue={getEnvironmentLabel(currentValue)}
fieldName={SERVICE_ENVIRONMENT}
Expand Down Expand Up @@ -110,7 +110,7 @@ export function TransactionNameField({
<SuggestionsSelect
customOptions={[{ label: allOptionText, value: undefined }]}
customOptionText={i18n.translate('xpack.apm.alerting.transaction.name.custom.text', {
defaultMessage: `Add '{searchValue}' as a new transaction name`,
defaultMessage: 'Add \\{searchValue\\} as a new transaction name',
})}
defaultValue={currentValue}
fieldName={TRANSACTION_NAME}
Expand Down Expand Up @@ -143,7 +143,7 @@ export function TransactionTypeField({
<SuggestionsSelect
customOptions={[{ label: allOptionText, value: undefined }]}
customOptionText={i18n.translate('xpack.apm.transactionTypesSelectCustomOptionText', {
defaultMessage: `Add '{searchValue}' as a new transaction type`,
defaultMessage: 'Add \\{searchValue\\} as a new transaction type',
})}
defaultValue={currentValue}
fieldName={TRANSACTION_TYPE}
Expand Down Expand Up @@ -176,7 +176,7 @@ export function ErrorGroupingKeyField({
<SuggestionsSelect
customOptions={[{ label: allOptionText, value: undefined }]}
customOptionText={i18n.translate('xpack.apm.errorKeySelectCustomOptionText', {
defaultMessage: `Add '{searchValue}' as a new error grouping key`,
defaultMessage: 'Add \\{searchValue\\} as a new error grouping key',
})}
defaultValue={currentValue}
fieldName={ERROR_GROUP_ID}
Expand All @@ -192,6 +192,10 @@ export function ErrorGroupingKeyField({
);
}

function isNumeric(value: string): boolean {
return !isNaN(Number(value)) && value.trim() !== '';
}

export function IsAboveField({
value,
unit,
Expand All @@ -203,22 +207,56 @@ export function IsAboveField({
onChange: (value: number) => void;
step?: number;
}) {
const [thresholdPopoverOpen, serThresholdPopoverOpen] = useState(false);
const [isAboveValue, setIsAboveValue] = useState(String(value));

return (
<PopoverExpression
value={`${value}${unit}`}
title={i18n.translate('xpack.apm.transactionErrorRateRuleType.isAbove', {
defaultMessage: 'is above',
})}
<EuiPopover
isOpen={thresholdPopoverOpen}
anchorPosition={'downLeft'}
ownFocus
closePopover={() => {
serThresholdPopoverOpen(false);
}}
button={
<EuiExpression
value={`${value}${unit}`}
description={i18n.translate('xpack.apm.transactionErrorRateRuleType.isAbove', {
defaultMessage: 'is above',
})}
isInvalid={!isNumeric(isAboveValue)}
isActive={thresholdPopoverOpen}
onClick={() => {
serThresholdPopoverOpen(true);
}}
/>
}
>
<EuiFieldNumber
data-test-subj="apmIsAboveFieldFieldNumber"
min={0}
value={value ?? 0}
onChange={(e) => onChange(parseInt(e.target.value, 10))}
append={unit}
compressed
step={step}
/>
</PopoverExpression>
<EuiFormRow
isInvalid={!isNumeric(isAboveValue)}
error={i18n.translate('xpack.apm.transactionErrorRateRuleType.error.validThreshold', {
defaultMessage: 'Thresholds must contain a valid number.',
})}
>
<EuiFieldNumber
data-test-subj="apmIsAboveFieldFieldNumber"
min={0}
value={isAboveValue}
onChange={(e) => {
const thresholdVal = e.target.value;
// Update the value to continue typing (if user stopped at . or ,)
setIsAboveValue(thresholdVal);
// Only send the value back to the rule if it's a valid number
if (!isNaN(Number(thresholdVal))) {
onChange(Number(thresholdVal));
}
}}
append={unit}
isInvalid={!isNumeric(isAboveValue)}
compressed
step={step}
/>
</EuiFormRow>
</EuiPopover>
);
}

0 comments on commit 9280bdd

Please sign in to comment.