mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Improve dashboard filters display to use color as well as text for negated filters (#49939) (#49992)
* Better key out negative filters * fragments not spans * Alter filter bar colors - Red border for excluded - Match pinned color to border color * Fix title by using `useInnerText` * Fix alignment of add filter button * Moving SASS variables to its own file
This commit is contained in:
parent
09dd7fdd3a
commit
f4477ec348
7 changed files with 93 additions and 17 deletions
|
@ -11,6 +11,10 @@
|
|||
margin-top: $euiSizeXS;
|
||||
}
|
||||
|
||||
.globalFilterBar__addButton {
|
||||
min-height: $euiSizeL + $euiSizeXS; // same height as the badges
|
||||
}
|
||||
|
||||
// sass-lint:disable quotes
|
||||
.globalFilterGroup__branch {
|
||||
padding: $euiSizeS $euiSizeM 0 0;
|
||||
|
@ -40,4 +44,3 @@
|
|||
margin-top: $euiSize * -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@import '@elastic/eui/src/components/form/mixins';
|
||||
@import '@elastic/eui/src/components/form/variables';
|
||||
@import '@elastic/eui/src/components/form/mixins';
|
||||
|
||||
/**
|
||||
* 1. Allow wrapping of long filter items
|
||||
|
@ -19,11 +19,17 @@
|
|||
|
||||
&:not(.globalFilterItem-isDisabled) {
|
||||
@include euiFormControlDefaultShadow;
|
||||
box-shadow: #{$euiFormControlBoxShadow}, inset 0 0 0 1px $kbnGlobalFilterItemBorderColor; // Make the actual border more visible
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
animation: none !important; // Remove focus ring animation otherwise it overrides simulated border via box-shadow
|
||||
}
|
||||
}
|
||||
|
||||
.globalFilterItem-isDisabled {
|
||||
background-color: transparentize($euiColorLightShade, .4);
|
||||
color: $euiColorDarkShade;
|
||||
background-color: transparentize($euiColorLightShade, 0.5);
|
||||
text-decoration: line-through;
|
||||
font-weight: $euiFontWeightRegular;
|
||||
font-style: italic;
|
||||
|
@ -39,12 +45,22 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
width: $euiSizeXS;
|
||||
background-color: $euiColorVis0;
|
||||
background-color: $kbnGlobalFilterItemBorderColor;
|
||||
border-top-left-radius: $euiBorderRadius / 2;
|
||||
border-bottom-left-radius: $euiBorderRadius / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.globalFilterItem-isExcluded {
|
||||
&:not(.globalFilterItem-isDisabled) {
|
||||
box-shadow: #{$euiFormControlBoxShadow}, inset 0 0 0 1px $kbnGlobalFilterItemBorderColorExcluded;
|
||||
|
||||
&::before {
|
||||
background-color: $kbnGlobalFilterItemPinnedColorExcluded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.globalFilterItem__editorForm {
|
||||
padding: $euiSizeM;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
@import 'variables';
|
||||
@import 'global_filter_group';
|
||||
@import 'global_filter_item';
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
$kbnGlobalFilterItemBorderColor: tintOrShade($euiColorMediumShade, 35%, 20%);
|
||||
$kbnGlobalFilterItemBorderColorExcluded: tintOrShade($euiColorDanger, 70%, 50%);
|
||||
$kbnGlobalFilterItemPinnedColorExcluded: tintOrShade($euiColorDanger, 30%, 20%);
|
|
@ -119,6 +119,7 @@ function FilterBarUI(props: Props) {
|
|||
size="xs"
|
||||
onClick={() => setIsAddFilterPopoverOpen(true)}
|
||||
data-test-subj="addFilter"
|
||||
className="globalFilterBar__addButton"
|
||||
>
|
||||
+{' '}
|
||||
<FormattedMessage
|
||||
|
|
|
@ -17,16 +17,24 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { Fragment } from 'react';
|
||||
import { EuiTextColor } from '@elastic/eui';
|
||||
import { Filter } from '@kbn/es-query';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { existsOperator, isOneOfOperator } from './filter_operators';
|
||||
|
||||
export function getFilterDisplayText(filter: Filter, filterDisplayName: string) {
|
||||
const prefix = filter.meta.negate
|
||||
const prefixText = filter.meta.negate
|
||||
? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', {
|
||||
defaultMessage: 'NOT ',
|
||||
})}`
|
||||
: '';
|
||||
const prefix =
|
||||
filter.meta.negate && !filter.meta.disabled ? (
|
||||
<EuiTextColor color="danger">{prefixText}</EuiTextColor>
|
||||
) : (
|
||||
prefixText
|
||||
);
|
||||
|
||||
if (filter.meta.alias !== null) {
|
||||
return `${prefix}${filter.meta.alias}`;
|
||||
|
@ -34,20 +42,61 @@ export function getFilterDisplayText(filter: Filter, filterDisplayName: string)
|
|||
|
||||
switch (filter.meta.type) {
|
||||
case 'exists':
|
||||
return `${prefix}${filter.meta.key} ${existsOperator.message}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key} {existsOperator.message}
|
||||
</Fragment>
|
||||
);
|
||||
case 'geo_bounding_box':
|
||||
return `${prefix}${filter.meta.key}: ${filterDisplayName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key}: {filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
case 'geo_polygon':
|
||||
return `${prefix}${filter.meta.key}: ${filterDisplayName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key}: {filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
case 'phrase':
|
||||
return `${prefix}${filter.meta.key}: ${filterDisplayName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key}: {filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
case 'phrases':
|
||||
return `${prefix}${filter.meta.key} ${isOneOfOperator.message} ${filterDisplayName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key} {isOneOfOperator.message} {filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
case 'query_string':
|
||||
return `${prefix}${filterDisplayName}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
case 'range':
|
||||
return `${prefix}${filter.meta.key}: ${filterDisplayName}`;
|
||||
case 'phrase':
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{filter.meta.key}: {filterDisplayName}
|
||||
</Fragment>
|
||||
);
|
||||
default:
|
||||
return `${prefix}${JSON.stringify(filter.query)}`;
|
||||
return (
|
||||
<Fragment>
|
||||
{prefix}
|
||||
{JSON.stringify(filter.query)}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { EuiBadge } from '@elastic/eui';
|
||||
import { EuiBadge, useInnerText } from '@elastic/eui';
|
||||
import { Filter, isFilterPinned } from '@kbn/es-query';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { SFC } from 'react';
|
||||
|
@ -36,9 +36,12 @@ export const FilterView: SFC<Props> = ({
|
|||
displayName,
|
||||
...rest
|
||||
}: Props) => {
|
||||
const [ref, innerText] = useInnerText();
|
||||
const displayText = <span ref={ref}>{getFilterDisplayText(filter, displayName)}</span>;
|
||||
|
||||
let title = i18n.translate('data.filter.filterBar.moreFilterActionsMessage', {
|
||||
defaultMessage: 'Filter: {displayText}. Select for more filter actions.',
|
||||
values: { displayText: getFilterDisplayText(filter, displayName) },
|
||||
defaultMessage: 'Filter: {innerText}. Select for more filter actions.',
|
||||
values: { innerText },
|
||||
});
|
||||
|
||||
if (isFilterPinned(filter)) {
|
||||
|
@ -72,7 +75,7 @@ export const FilterView: SFC<Props> = ({
|
|||
})}
|
||||
{...rest}
|
||||
>
|
||||
<span>{getFilterDisplayText(filter, displayName)}</span>
|
||||
{displayText}
|
||||
</EuiBadge>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue