Skip to content

Commit

Permalink
Show error if field is not found during filter rendering (#59298) (#5…
Browse files Browse the repository at this point in the history
…9610)

* Show error if field is not found

* Errored filter state

* Design adjustments

* Fixing class names and making look similar to disabled

* code review fixes

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: cchaos <[email protected]>

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: cchaos <[email protected]>
  • Loading branch information
3 people authored Mar 7, 2020
1 parent 0219d77 commit 769d08a
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 16 deletions.
12 changes: 11 additions & 1 deletion src/plugins/data/common/es_query/filters/get_display_value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
import { IIndexPattern, IFieldType } from '../..';
import { getIndexPatternFromFilter } from './get_index_pattern_from_filter';
import { Filter } from '../filters';
Expand All @@ -27,7 +28,16 @@ function getValueFormatter(indexPattern?: IIndexPattern, key?: string) {
let format = get(indexPattern, ['fields', 'byName', key, 'format']);
if (!format && (indexPattern.fields as any).getByName) {
// TODO: Why is indexPatterns sometimes a map and sometimes an array?
format = ((indexPattern.fields as any).getByName(key) as IFieldType).format;
const field: IFieldType = (indexPattern.fields as any).getByName(key);
if (!field) {
throw new Error(
i18n.translate('data.filter.filterBar.fieldNotFound', {
defaultMessage: 'Field {key} not found in index pattern {indexPattern}',
values: { key, indexPattern: indexPattern.title },
})
);
}
format = field.format;
}
return format;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
font-style: italic;
}

.globalFilterItem-isInvalid {
text-decoration: none;

.globalFilterLabel__value {
color: $euiColorDanger;
font-weight: $euiFontWeightBold;
}
}

.globalFilterItem-isPinned {
position: relative;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export function FilterLabel({ filter, valueLabel }: Props) {
prefixText
);

const getValue = (text?: string) => {
return <span className="globalFilterLabel__value">{text}</span>;
};

if (filter.meta.alias !== null) {
return (
<Fragment>
Expand All @@ -55,50 +59,50 @@ export function FilterLabel({ filter, valueLabel }: Props) {
return (
<Fragment>
{prefix}
{filter.meta.key} {existsOperator.message}
{filter.meta.key}: {getValue(`${existsOperator.message}`)}
</Fragment>
);
case FILTERS.GEO_BOUNDING_BOX:
return (
<Fragment>
{prefix}
{filter.meta.key}: {valueLabel}
{filter.meta.key}: {getValue(valueLabel)}
</Fragment>
);
case FILTERS.GEO_POLYGON:
return (
<Fragment>
{prefix}
{filter.meta.key}: {valueLabel}
{filter.meta.key}: {getValue(valueLabel)}
</Fragment>
);
case FILTERS.PHRASES:
return (
<Fragment>
{prefix}
{filter.meta.key} {isOneOfOperator.message} {valueLabel}
{filter.meta.key}: {getValue(`${isOneOfOperator.message} ${valueLabel}`)}
</Fragment>
);
case FILTERS.QUERY_STRING:
return (
<Fragment>
{prefix}
{valueLabel}
{getValue(`${valueLabel}`)}
</Fragment>
);
case FILTERS.PHRASE:
case FILTERS.RANGE:
return (
<Fragment>
{prefix}
{filter.meta.key}: {valueLabel}
{filter.meta.key}: {getValue(valueLabel)}
</Fragment>
);
default:
return (
<Fragment>
{prefix}
{JSON.stringify(filter.query) || filter.meta.value}
{getValue(`${JSON.stringify(filter.query) || filter.meta.value}`)}
</Fragment>
);
}
Expand Down
34 changes: 26 additions & 8 deletions src/plugins/data/public/ui/filter_bar/filter_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
toggleFilterPinned,
toggleFilterDisabled,
} from '../../../common';
import { getNotifications } from '../../services';

interface Props {
id: string;
Expand Down Expand Up @@ -64,24 +65,41 @@ class FilterItemUI extends Component<Props, State> {
public render() {
const { filter, id } = this.props;
const { negate, disabled } = filter.meta;
let hasError: boolean = false;

let valueLabel;
try {
valueLabel = getDisplayValueFromFilter(filter, this.props.indexPatterns);
} catch (e) {
getNotifications().toasts.addError(e, {
title: this.props.intl.formatMessage({
id: 'data.filter.filterBar.labelErrorMessage',
defaultMessage: 'Failed to display filter',
}),
});
valueLabel = this.props.intl.formatMessage({
id: 'data.filter.filterBar.labelErrorText',
defaultMessage: 'Error',
});
hasError = true;
}
const dataTestSubjKey = filter.meta.key ? `filter-key-${filter.meta.key}` : '';
const dataTestSubjValue = filter.meta.value ? `filter-value-${valueLabel}` : '';
const dataTestSubjDisabled = `filter-${
this.props.filter.meta.disabled ? 'disabled' : 'enabled'
}`;

const classes = classNames(
'globalFilterItem',
{
'globalFilterItem-isDisabled': disabled,
'globalFilterItem-isDisabled': disabled || hasError,
'globalFilterItem-isInvalid': hasError,
'globalFilterItem-isPinned': isFilterPinned(filter),
'globalFilterItem-isExcluded': negate,
},
this.props.className
);

const valueLabel = getDisplayValueFromFilter(filter, this.props.indexPatterns);
const dataTestSubjKey = filter.meta.key ? `filter-key-${filter.meta.key}` : '';
const dataTestSubjValue = filter.meta.value ? `filter-value-${valueLabel}` : '';
const dataTestSubjDisabled = `filter-${
this.props.filter.meta.disabled ? 'disabled' : 'enabled'
}`;

const badge = (
<FilterView
filter={filter}
Expand Down

0 comments on commit 769d08a

Please sign in to comment.