mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 08:56:43 -06:00
ValueMappings: UX Feedback and fixes (#34011)
* ValueMappings: UX Feedback and fixes * minor update to texts * Update
This commit is contained in:
parent
d1a44044e5
commit
1601f12cf1
@ -154,7 +154,7 @@ export function ValueMappingEditRow({ mapping, index, onChange, onRemove }: Prop
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
<Input type="text" value={result.text ?? ''} onChange={onChangeText} placeholder="Display text" />
|
||||
<Input type="text" value={result.text ?? ''} onChange={onChangeText} placeholder="Optional display text" />
|
||||
</td>
|
||||
<td className={styles.textAlignCenter}>
|
||||
{result.color && (
|
||||
|
@ -2,6 +2,8 @@ import React from 'react';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { ValueMappingsEditorModal, Props } from './ValueMappingsEditorModal';
|
||||
import { MappingType } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import selectEvent from 'react-select-event';
|
||||
|
||||
const setup = (spy?: any, propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
@ -75,12 +77,14 @@ describe('When adding and updating value mapp', () => {
|
||||
const onChangeSpy = jest.fn();
|
||||
setup(onChangeSpy);
|
||||
|
||||
fireEvent.click(screen.getByTestId('add value map'));
|
||||
fireEvent.click(screen.getByLabelText(selectors.components.ValuePicker.button('Add a new mapping')));
|
||||
const selectComponent = await screen.findByLabelText(selectors.components.ValuePicker.select('Add a new mapping'));
|
||||
await selectEvent.select(selectComponent, 'Value');
|
||||
|
||||
const input = (await screen.findAllByPlaceholderText('Exact value to match'))[1];
|
||||
|
||||
fireEvent.change(input, { target: { value: 'New' } });
|
||||
fireEvent.change(screen.getAllByPlaceholderText('Display text')[2], { target: { value: 'display' } });
|
||||
fireEvent.change(screen.getAllByPlaceholderText('Optional display text')[2], { target: { value: 'display' } });
|
||||
fireEvent.click(screen.getByText('Update'));
|
||||
|
||||
expect(onChangeSpy).toBeCalledWith([
|
||||
@ -117,11 +121,13 @@ describe('When adding and updating range map', () => {
|
||||
const onChangeSpy = jest.fn();
|
||||
setup(onChangeSpy, { value: [] });
|
||||
|
||||
fireEvent.click(screen.getByTestId('add range map'));
|
||||
fireEvent.click(screen.getByLabelText(selectors.components.ValuePicker.button('Add a new mapping')));
|
||||
const selectComponent = await screen.findByLabelText(selectors.components.ValuePicker.select('Add a new mapping'));
|
||||
await selectEvent.select(selectComponent, 'Range');
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('Range start'), { target: { value: '10' } });
|
||||
fireEvent.change(screen.getByPlaceholderText('Range end'), { target: { value: '20' } });
|
||||
fireEvent.change(screen.getByPlaceholderText('Display text'), { target: { value: 'display' } });
|
||||
fireEvent.change(screen.getByPlaceholderText('Optional display text'), { target: { value: 'display' } });
|
||||
|
||||
fireEvent.click(screen.getByText('Update'));
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { GrafanaTheme2, MappingType, SpecialValueMatch, ValueMapping } from '@grafana/data';
|
||||
import { GrafanaTheme2, MappingType, SelectableValue, SpecialValueMatch, ValueMapping } from '@grafana/data';
|
||||
import { Button } from '../Button/Button';
|
||||
import { Modal } from '../Modal/Modal';
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { ValueMappingEditRow, ValueMappingEditRowModel } from './ValueMappingEditRow';
|
||||
import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
|
||||
import { HorizontalGroup } from '../Layout/Layout';
|
||||
import { css } from '@emotion/css';
|
||||
import { ValuePicker } from '../ValuePicker/ValuePicker';
|
||||
|
||||
export interface Props {
|
||||
value: ValueMapping[];
|
||||
@ -46,39 +46,23 @@ export function ValueMappingsEditorModal({ value, onChange, onClose }: Props) {
|
||||
updateRows(newList);
|
||||
};
|
||||
|
||||
const onAddValueMap = () => {
|
||||
updateRows([
|
||||
...rows,
|
||||
{
|
||||
type: MappingType.ValueToText,
|
||||
isNew: true,
|
||||
result: {},
|
||||
},
|
||||
]);
|
||||
};
|
||||
const mappingTypes: Array<SelectableValue<MappingType>> = [
|
||||
{ label: 'Value', value: MappingType.ValueToText, description: 'Match a specific text value' },
|
||||
{ label: 'Range', value: MappingType.RangeToText, description: 'Match a numerical range of values' },
|
||||
{ label: 'Special', value: MappingType.SpecialValue, description: 'Match on null, NaN, boolean and empty values' },
|
||||
];
|
||||
|
||||
const onAddRangeMap = () => {
|
||||
const onAddValueMapping = (value: SelectableValue<MappingType>) => {
|
||||
updateRows([
|
||||
...rows,
|
||||
{
|
||||
type: MappingType.RangeToText,
|
||||
type: value.value!,
|
||||
isNew: true,
|
||||
result: {},
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const onAddSpecialValueMap = () => {
|
||||
updateRows([
|
||||
...rows,
|
||||
{
|
||||
type: MappingType.SpecialValue,
|
||||
specialMatch: SpecialValueMatch.Null,
|
||||
result: {},
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const onUpdate = () => {
|
||||
onChange(editModelToSaveModel(rows));
|
||||
onClose();
|
||||
@ -90,10 +74,11 @@ export function ValueMappingsEditorModal({ value, onChange, onClose }: Props) {
|
||||
<thead>
|
||||
<tr>
|
||||
<th style={{ width: '1%' }}></th>
|
||||
<th style={{ width: '1%' }}>Type</th>
|
||||
<th style={{ width: '40%' }}>Match</th>
|
||||
<th>Display text</th>
|
||||
<th>Color</th>
|
||||
<th style={{ width: '40%', textAlign: 'left' }} colSpan={2}>
|
||||
Condition
|
||||
</th>
|
||||
<th style={{ textAlign: 'left' }}>Display text</th>
|
||||
<th style={{ width: '10%' }}>Color</th>
|
||||
<th style={{ width: '1%' }}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -116,17 +101,16 @@ export function ValueMappingsEditorModal({ value, onChange, onClose }: Props) {
|
||||
</Droppable>
|
||||
</DragDropContext>
|
||||
</table>
|
||||
<HorizontalGroup>
|
||||
<Button variant="secondary" icon="plus" onClick={onAddValueMap} data-testid="add value map">
|
||||
Value map
|
||||
</Button>
|
||||
<Button variant="secondary" icon="plus" onClick={onAddRangeMap} data-testid="add range map">
|
||||
Range map
|
||||
</Button>
|
||||
<Button variant="secondary" icon="plus" onClick={onAddSpecialValueMap} data-testid="add special map">
|
||||
Special value map
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
<ValuePicker
|
||||
label="Add a new mapping"
|
||||
variant="secondary"
|
||||
size="md"
|
||||
icon="plus"
|
||||
menuPlacement="auto"
|
||||
isFullWidth={false}
|
||||
options={mappingTypes}
|
||||
onChange={onAddValueMapping}
|
||||
/>
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" fill="outline" onClick={onClose}>
|
||||
Cancel
|
||||
@ -171,6 +155,11 @@ export function editModelToSaveModel(rows: ValueMappingEditRowModel[]) {
|
||||
index,
|
||||
};
|
||||
|
||||
// Set empty texts to undefined
|
||||
if (!result.text || result.text.trim().length === 0) {
|
||||
result.text = undefined;
|
||||
}
|
||||
|
||||
switch (item.type) {
|
||||
case MappingType.ValueToText:
|
||||
if (item.key != null) {
|
||||
|
@ -54,10 +54,11 @@ export function ValuePicker<T>({
|
||||
{!isPicking && (isFullWidth ? <FullWidthButtonContainer>{buttonEl}</FullWidthButtonContainer> : buttonEl)}
|
||||
|
||||
{isPicking && (
|
||||
<span aria-label={selectors.components.ValuePicker.select(label)}>
|
||||
<span>
|
||||
<Select
|
||||
placeholder={label}
|
||||
options={options}
|
||||
aria-label={selectors.components.ValuePicker.select(label)}
|
||||
isOpen
|
||||
onCloseMenu={() => setIsPicking(false)}
|
||||
autoFocus={true}
|
||||
|
Loading…
Reference in New Issue
Block a user