andres comments
This commit is contained in:
+23
@@ -82,5 +82,28 @@ describe('MultiFilters', () => {
|
||||
'my-key': ['my-value1', 'my-value2'],
|
||||
});
|
||||
});
|
||||
|
||||
describe('when editing an existing filter item key', () => {
|
||||
it('it should change the key and call onChange', async () => {
|
||||
const filters = { 'my-key': ['my-value'] };
|
||||
const onChange = jest.fn();
|
||||
render(<MultiFilter filters={filters} onChange={onChange} />);
|
||||
|
||||
const filterItemElement = screen.getByTestId('cloudwatch-multifilter-item');
|
||||
expect(filterItemElement).toBeInTheDocument();
|
||||
expect(within(filterItemElement).getByDisplayValue('my-key')).toBeInTheDocument();
|
||||
expect(within(filterItemElement).getByDisplayValue('my-value')).toBeInTheDocument();
|
||||
|
||||
const keyElement = screen.getByTestId('cloudwatch-multifilter-item-key');
|
||||
expect(keyElement).toBeInTheDocument();
|
||||
userEvent.type(keyElement!, '2');
|
||||
fireEvent.blur(keyElement!);
|
||||
|
||||
expect(within(filterItemElement).getByDisplayValue('my-key2')).toBeInTheDocument();
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
'my-key2': ['my-value'],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+19
-8
@@ -7,6 +7,7 @@ import { MultiFilterItem } from './MultiFilterItem';
|
||||
export interface Props {
|
||||
filters?: MultiFilters;
|
||||
onChange: (filters: MultiFilters) => void;
|
||||
keyPlaceholder?: string;
|
||||
}
|
||||
|
||||
export interface MultiFilterCondition {
|
||||
@@ -28,7 +29,7 @@ const filterConditionsToMultiFilters = (filters: MultiFilterCondition[]) => {
|
||||
return res;
|
||||
};
|
||||
|
||||
export const MultiFilter: React.FC<Props> = ({ filters, onChange }) => {
|
||||
export const MultiFilter: React.FC<Props> = ({ filters, onChange, keyPlaceholder }) => {
|
||||
const [items, setItems] = useState<MultiFilterCondition[]>([]);
|
||||
useEffect(() => setItems(filters ? multiFiltersToFilterConditions(filters) : []), [filters]);
|
||||
const onFiltersChange = (newItems: Array<Partial<MultiFilterCondition>>) => {
|
||||
@@ -42,13 +43,23 @@ export const MultiFilter: React.FC<Props> = ({ filters, onChange }) => {
|
||||
}
|
||||
};
|
||||
|
||||
return <EditorList items={items} onChange={onFiltersChange} renderItem={renderFilter} />;
|
||||
return <EditorList items={items} onChange={onFiltersChange} renderItem={makeRenderFilter(keyPlaceholder)} />;
|
||||
};
|
||||
|
||||
function renderFilter(
|
||||
item: MultiFilterCondition,
|
||||
onChange: (item: MultiFilterCondition) => void,
|
||||
onDelete: () => void
|
||||
) {
|
||||
return <MultiFilterItem filter={item} onChange={(item) => onChange(item)} onDelete={onDelete} />;
|
||||
function makeRenderFilter(keyPlaceholder?: string) {
|
||||
function renderFilter(
|
||||
item: MultiFilterCondition,
|
||||
onChange: (item: MultiFilterCondition) => void,
|
||||
onDelete: () => void
|
||||
) {
|
||||
return (
|
||||
<MultiFilterItem
|
||||
filter={item}
|
||||
onChange={(item) => onChange(item)}
|
||||
onDelete={onDelete}
|
||||
keyPlaceholder={keyPlaceholder}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return renderFilter;
|
||||
}
|
||||
|
||||
+5
-4
@@ -9,9 +9,10 @@ export interface Props {
|
||||
filter: MultiFilterCondition;
|
||||
onChange: (value: MultiFilterCondition) => void;
|
||||
onDelete: () => void;
|
||||
keyPlaceholder?: string;
|
||||
}
|
||||
|
||||
export const MultiFilterItem: FunctionComponent<Props> = ({ filter, onChange, onDelete }) => {
|
||||
export const MultiFilterItem: FunctionComponent<Props> = ({ filter, onChange, onDelete, keyPlaceholder }) => {
|
||||
const [localKey, setLocalKey] = useState(filter.key || '');
|
||||
const [localValue, setLocalValue] = useState(filter.value?.join(', ') || '');
|
||||
const theme = useTheme2();
|
||||
@@ -24,11 +25,11 @@ export const MultiFilterItem: FunctionComponent<Props> = ({ filter, onChange, on
|
||||
data-testid="cloudwatch-multifilter-item-key"
|
||||
aria-label="Filter key"
|
||||
value={localKey}
|
||||
placeholder="key"
|
||||
placeholder={keyPlaceholder ?? 'key'}
|
||||
onChange={(e) => setLocalKey(e.currentTarget.value)}
|
||||
onBlur={() => {
|
||||
if (localKey && localKey !== filter.key) {
|
||||
onChange({ key: localKey, value: undefined });
|
||||
onChange({ ...filter, key: localKey });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -42,7 +43,7 @@ export const MultiFilterItem: FunctionComponent<Props> = ({ filter, onChange, on
|
||||
placeholder="value1, value2,..."
|
||||
onChange={(e) => setLocalValue(e.currentTarget.value)}
|
||||
onBlur={() => {
|
||||
const newValues = localValue.replace(' ', '').split(',');
|
||||
const newValues = localValue.split(',').map((v) => v.trim());
|
||||
if (localValue && newValues !== filter.value) {
|
||||
onChange({ ...filter, value: newValues });
|
||||
}
|
||||
|
||||
+3
-1
@@ -171,13 +171,14 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
<InlineField
|
||||
label="Filters"
|
||||
labelWidth={20}
|
||||
tooltip='Pre-defined ec2:DescribeInstances filters/tags and the values to filter on. Tags should be formatted "tag:<name>" '
|
||||
tooltip='Pre-defined ec2:DescribeInstances filters/tags and the values to filter on. Tags should be formatted "tag:<name>. See the documentation for more details.'
|
||||
>
|
||||
<MultiFilter
|
||||
filters={parsedQuery.ec2Filters}
|
||||
onChange={(filters) => {
|
||||
onChange({ ...parsedQuery, ec2Filters: filters });
|
||||
}}
|
||||
keyPlaceholder="filter/tag"
|
||||
/>
|
||||
</InlineField>
|
||||
</>
|
||||
@@ -196,6 +197,7 @@ export const VariableQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
onChange={(filters) => {
|
||||
onChange({ ...parsedQuery, tags: filters });
|
||||
}}
|
||||
keyPlaceholder="tag"
|
||||
/>
|
||||
</InlineField>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user