grafana/public/app/features/alerting/unified/components/AlertLabelDropdown.tsx

70 lines
2.1 KiB
TypeScript

import { css } from '@emotion/css';
import { FC, forwardRef } from 'react';
import { GroupBase, OptionsOrGroups, createFilter } from 'react-select';
import { SelectableValue } from '@grafana/data';
import { Field, Select, useStyles2 } from '@grafana/ui';
export interface AlertLabelDropdownProps {
onChange: (newValue: SelectableValue<string>) => void;
onOpenMenu?: () => void;
options: SelectableValue[];
defaultValue?: SelectableValue;
type: 'key' | 'value';
}
const _customFilter = createFilter({ ignoreCase: false });
function customFilter(opt: SelectableValue, searchQuery: string) {
return _customFilter(
{
label: opt.label ?? '',
value: opt.value ?? '',
data: {},
},
searchQuery
);
}
const handleIsValidNewOption = (
inputValue: string,
_: SelectableValue<string> | null,
options: OptionsOrGroups<SelectableValue<string>, GroupBase<SelectableValue<string>>>
) => {
const exactValueExists = options.some((el) => el.label === inputValue);
const valueIsNotEmpty = inputValue.trim().length;
return !Boolean(exactValueExists) && Boolean(valueIsNotEmpty);
};
const AlertLabelDropdown: FC<AlertLabelDropdownProps> = forwardRef<HTMLDivElement, AlertLabelDropdownProps>(
function LabelPicker({ onChange, options, defaultValue, type, onOpenMenu = () => {} }, ref) {
const styles = useStyles2(getStyles);
return (
<div ref={ref}>
<Field disabled={false} data-testid={`alertlabel-${type}-picker`} className={styles.resetMargin}>
<Select<string>
placeholder={`Choose ${type}`}
width={29}
className="ds-picker select-container"
backspaceRemovesValue={false}
onChange={onChange}
onOpenMenu={onOpenMenu}
filterOption={customFilter}
isValidNewOption={handleIsValidNewOption}
options={options}
maxMenuHeight={500}
noOptionsMessage="No labels found"
defaultValue={defaultValue}
allowCustomValue
/>
</Field>
</div>
);
}
);
const getStyles = () => ({
resetMargin: css({ marginBottom: 0 }),
});
export default AlertLabelDropdown;