grafana/public/app/core/components/IntervalInput/IntervalInput.tsx
Joey 76a83dd540
Traces: Add inline validation and greater precision to duration fields in span filters (#71404)
* Add inline validation to span filters

* Update filter spans by duration precision

* Update IntervalInput props

* Update validation

* Update span filters

* Update props

* Update test

* Update defaults and duration aria labels
2023-07-13 10:48:31 +01:00

70 lines
1.6 KiB
TypeScript

import React, { useState } from 'react';
import { useDebounce } from 'react-use';
import { InlineField, Input } from '@grafana/ui';
import { validateInterval, validateIntervalRegex } from './validation';
interface Props {
value: string;
onChange: (val: string) => void;
isInvalidError: string;
placeholder?: string;
width?: number;
ariaLabel?: string;
label?: string;
tooltip?: string;
disabled?: boolean;
validationRegex?: RegExp;
}
interface FieldProps {
labelWidth: number;
disabled: boolean;
invalid: boolean;
error: string;
label?: string;
tooltip?: string;
}
export const IntervalInput = (props: Props) => {
const validationRegex = props.validationRegex || validateIntervalRegex;
const [intervalIsInvalid, setIntervalIsInvalid] = useState(() => {
return props.value ? validateInterval(props.value, validationRegex) : false;
});
useDebounce(
() => {
setIntervalIsInvalid(validateInterval(props.value, validationRegex));
},
500,
[props.value]
);
const fieldProps: FieldProps = {
labelWidth: 26,
disabled: props.disabled ?? false,
invalid: intervalIsInvalid,
error: props.isInvalidError,
};
if (props.label) {
fieldProps.label = props.label;
fieldProps.tooltip = props.tooltip || '';
}
return (
<InlineField {...fieldProps}>
<Input
type="text"
placeholder={props.placeholder || '0'}
width={props.width || 40}
onChange={(e) => {
props.onChange(e.currentTarget.value);
}}
value={props.value}
aria-label={props.ariaLabel || 'interval input'}
/>
</InlineField>
);
};