import { css } from '@emotion/css'; import React, { FormEvent, useState, KeyboardEvent, useRef, useEffect } from 'react'; import { Draggable } from 'react-beautiful-dnd'; import { GrafanaTheme2 } from '@grafana/data'; import { Icon, Input, IconButton, HorizontalGroup, FieldValidationMessage, useStyles2 } from '@grafana/ui'; type EnumMappingRowProps = { transformIndex: number; value: string; index: number; mappedIndex: number; onChangeEnumValue: (index: number, value: string) => void; onRemoveEnumRow: (index: number) => void; checkIsEnumUniqueValue: (value: string) => boolean; }; const EnumMappingRow = ({ transformIndex, value, index, mappedIndex, onChangeEnumValue, onRemoveEnumRow, checkIsEnumUniqueValue, }: EnumMappingRowProps) => { const styles = useStyles2(getStyles); const [enumValue, setEnumValue] = useState(value); // If the enum value is empty, we assume it is a new row and should be editable const [isEditing, setIsEditing] = useState(enumValue === ''); const [validationError, setValidationError] = useState(null); const inputRef = useRef(null); // Focus the input field if it is rendered useEffect(() => { if (inputRef.current) { inputRef.current.focus(); } }, [inputRef]); const onEnumInputChange = (event: FormEvent) => { if ( event.currentTarget.value !== '' && checkIsEnumUniqueValue(event.currentTarget.value) && event.currentTarget.value !== value ) { setValidationError('Enum value already exists'); } else { setValidationError(null); } setEnumValue(event.currentTarget.value); }; const onEnumInputBlur = () => { setIsEditing(false); setValidationError(null); // Do not add empty or duplicate enum values if (enumValue === '' || validationError !== null) { onRemoveEnumRow(mappedIndex); return; } onChangeEnumValue(mappedIndex, enumValue); }; const onEnumInputKeyDown = (event: KeyboardEvent) => { if (event.key === 'Enter') { event.preventDefault(); onEnumInputBlur(); } }; const onEnumValueClick = () => { setIsEditing(true); }; const onRemoveButtonClick = () => { onRemoveEnumRow(mappedIndex); }; return ( {(provided) => (
{isEditing ? ( {validationError && {validationError}} ) : ( {value && value !== '' ? value : 'Click to edit'} )} )}
); }; const getStyles = (theme: GrafanaTheme2) => ({ dragHandle: css({ cursor: 'grab', }), textAlignCenter: css({ textAlign: 'center', }), clickableTableCell: css({ cursor: 'pointer', width: '100px', '&:hover': { color: theme.colors.text.maxContrast, }, }), }); export default EnumMappingRow;