mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Fix KQL typeahead missing description (#128480)
* fix display description in typeahead * Design fixes - Fiddled with the flex properties to ensure the min-width for text is 250px but will expand in full until the edges are reached then both the text and description will start truncating - Remove now unused/unnecssary `—withDescription` class * remove description for fields suggestions Co-authored-by: cchaos <caroline.horn@elastic.co>
This commit is contained in:
parent
610fe94a00
commit
d8323c2246
11 changed files with 54 additions and 56 deletions
|
@ -116,7 +116,7 @@ describe('Kuery field suggestions', () => {
|
|||
expect(keywordIndex).toBeLessThan(analyzedIndex);
|
||||
});
|
||||
|
||||
test('should have descriptions', async () => {
|
||||
test('should not have descriptions', async () => {
|
||||
const prefix = '';
|
||||
const suffix = '';
|
||||
const suggestions = await getSuggestions(
|
||||
|
@ -125,7 +125,7 @@ describe('Kuery field suggestions', () => {
|
|||
);
|
||||
expect(suggestions.length).toBeGreaterThan(0);
|
||||
suggestions.forEach((suggestion) => {
|
||||
expect(suggestion).toHaveProperty('description');
|
||||
expect(suggestion).not.toHaveProperty('description');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { flatten } from 'lodash';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { escapeKuery } from './lib/escape_kuery';
|
||||
import { sortPrefixFirst } from './sort_prefix_first';
|
||||
import {
|
||||
|
@ -19,18 +17,6 @@ import {
|
|||
} from '../../../../../../../src/plugins/data/public';
|
||||
import { KqlQuerySuggestionProvider } from './types';
|
||||
|
||||
const getDescription = (field: IFieldType) => {
|
||||
return (
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="data.kueryAutocomplete.filterResultsDescription"
|
||||
defaultMessage="Filter results that contain {fieldName}"
|
||||
values={{ fieldName: <span className="kbnSuggestionItem__callout">{field.name}</span> }}
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
};
|
||||
|
||||
const keywordComparator = (first: IFieldType, second: IFieldType) => {
|
||||
const extensions = ['raw', 'keyword'];
|
||||
if (extensions.map((ext) => `${first.name}.${ext}`).includes(second.name)) {
|
||||
|
@ -72,7 +58,6 @@ export const setupGetFieldSuggestions: KqlQuerySuggestionProvider<QuerySuggestio
|
|||
field.name.slice(field.subType.nested.path.length + 1)
|
||||
)} }`
|
||||
: `${escapeKuery(field.name.slice(nestedPath ? nestedPath.length + 1 : 0))} `;
|
||||
const description = getDescription(field);
|
||||
const cursorIndex =
|
||||
field.subType && field.subType.nested && remainingPath.length > 0
|
||||
? text.length - 2
|
||||
|
@ -81,7 +66,6 @@ export const setupGetFieldSuggestions: KqlQuerySuggestionProvider<QuerySuggestio
|
|||
return {
|
||||
type: QuerySuggestionTypes.Field,
|
||||
text,
|
||||
description,
|
||||
start,
|
||||
end,
|
||||
cursorIndex,
|
||||
|
|
|
@ -28,6 +28,7 @@ exports[`SuggestionComponent Should display the suggestion and use the provided
|
|||
</div>
|
||||
<div
|
||||
className="kbnSuggestionItem__description"
|
||||
data-test-subj="autoCompleteSuggestionDescription"
|
||||
>
|
||||
This is not a helpful suggestion
|
||||
</div>
|
||||
|
@ -63,6 +64,7 @@ exports[`SuggestionComponent Should make the element active if the selected prop
|
|||
</div>
|
||||
<div
|
||||
className="kbnSuggestionItem__description"
|
||||
data-test-subj="autoCompleteSuggestionDescription"
|
||||
>
|
||||
This is not a helpful suggestion
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ $kbnTypeaheadTypes: (
|
|||
value: $euiColorSuccess,
|
||||
operator: $euiColorPrimary,
|
||||
conjunction: $euiColorVis3,
|
||||
recentSearch: $euiColorMediumShade,
|
||||
);
|
||||
|
||||
.kbnTypeahead.kbnTypeahead--small {
|
||||
|
@ -88,11 +89,11 @@ $kbnTypeaheadTypes: (
|
|||
}
|
||||
|
||||
.kbnSuggestionItem {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: $euiFontSizeXS;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
@each $name, $color in $kbnTypeaheadTypes {
|
||||
&.kbnSuggestionItem--#{$name} {
|
||||
|
@ -102,29 +103,17 @@ $kbnTypeaheadTypes: (
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.kbnSuggestionItem--recentSearch {
|
||||
.kbnSuggestionItem__type {
|
||||
background-color: $euiColorLightShade;
|
||||
color: $euiColorMediumShade;
|
||||
}
|
||||
|
||||
.kbnSuggestionItem__text {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.kbnSuggestionItem__text,
|
||||
.kbnSuggestionItem__type,
|
||||
.kbnSuggestionItem__description {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-right: $euiSize;
|
||||
}
|
||||
|
||||
.kbnSuggestionItem__type {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: auto;
|
||||
|
@ -138,25 +127,28 @@ $kbnTypeaheadTypes: (
|
|||
}
|
||||
|
||||
.kbnSuggestionItem__text {
|
||||
flex-grow: 0; /* 2 */
|
||||
flex-basis: auto; /* 2 */
|
||||
font-family: $euiCodeFontFamily;
|
||||
width: 250px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: $euiSizeXS $euiSizeS;
|
||||
padding-left: $euiSizeS;
|
||||
color: $euiTextColor;
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.kbnSuggestionItem__description {
|
||||
color: $euiColorDarkShade;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-left: $euiSizeXL;
|
||||
flex-shrink: 1;
|
||||
|
||||
// In case the description contains a paragraph in which the truncation needs to be at this level
|
||||
> p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:empty {
|
||||
flex-grow: 0;
|
||||
margin-left: 0;
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +159,3 @@ $kbnTypeaheadTypes: (
|
|||
padding: 0 $euiSizeXS;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.kbnSuggestionItem--value .kbnSuggestionItem__text {
|
||||
flex-basis: 50%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,12 @@ export const SuggestionComponent = React.memo(function SuggestionComponent(props
|
|||
props.suggestion.type
|
||||
}-${props.suggestion.text.replace(/\s/g, '-')}`}
|
||||
>
|
||||
<div className={'kbnSuggestionItem kbnSuggestionItem--' + props.suggestion.type}>
|
||||
<div
|
||||
className={classNames({
|
||||
kbnSuggestionItem: true,
|
||||
['kbnSuggestionItem--' + props.suggestion.type]: true,
|
||||
})}
|
||||
>
|
||||
<div className="kbnSuggestionItem__type">
|
||||
<EuiIcon type={getEuiIconType(props.suggestion.type)} />
|
||||
</div>
|
||||
|
@ -83,7 +88,12 @@ export const SuggestionComponent = React.memo(function SuggestionComponent(props
|
|||
{props.suggestion.text}
|
||||
</div>
|
||||
{props.shouldDisplayDescription && (
|
||||
<div className="kbnSuggestionItem__description">{props.suggestion.description}</div>
|
||||
<div
|
||||
className="kbnSuggestionItem__description"
|
||||
data-test-subj="autoCompleteSuggestionDescription"
|
||||
>
|
||||
{props.suggestion.description}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -88,14 +88,14 @@ export default class SuggestionsComponent extends PureComponent<SuggestionsCompo
|
|||
inputContainer={this.props.inputContainer}
|
||||
suggestionsSize={this.props.size}
|
||||
>
|
||||
{(containerWidth: number) => (
|
||||
{(rect: DOMRect) => (
|
||||
<div
|
||||
id="kbnTypeahead__items"
|
||||
role="listbox"
|
||||
ref={this.assignParentNode}
|
||||
onScroll={this.handleScroll}
|
||||
>
|
||||
{renderSuggestions(containerWidth)}
|
||||
{renderSuggestions(rect.width)}
|
||||
</div>
|
||||
)}
|
||||
</ResizableSuggestionsListDiv>
|
||||
|
@ -158,9 +158,9 @@ const StyledSuggestionsListDiv = styled.div`
|
|||
const ResizableSuggestionsListDiv: React.FC<{
|
||||
inputContainer: HTMLElement;
|
||||
suggestionsSize?: SuggestionsListSize;
|
||||
children: (rect: DOMRect) => ReactNode;
|
||||
}> = React.memo((props) => {
|
||||
const inputContainer = props.inputContainer;
|
||||
const children = props.children as (rect: DOMRect) => ReactNode;
|
||||
|
||||
const [{ documentHeight }, { pageYOffset }, containerRect] = useDimensions(inputContainer);
|
||||
|
||||
|
@ -191,7 +191,7 @@ const ResizableSuggestionsListDiv: React.FC<{
|
|||
['kbnTypeahead__popover--top']: !isSuggestionsListFittable,
|
||||
})}
|
||||
>
|
||||
{children(containerRect)}
|
||||
{props.children(containerRect)}
|
||||
</div>
|
||||
</div>
|
||||
</StyledSuggestionsListDiv>
|
||||
|
|
|
@ -96,4 +96,16 @@ export class QueryBarService extends FtrService {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getSuggestionsDescription() {
|
||||
const suggestions = await this.testSubjects.findAll('autoCompleteSuggestionDescription');
|
||||
return Promise.all(suggestions.map((suggestion) => suggestion.getVisibleText()));
|
||||
}
|
||||
|
||||
public async expectSuggestionsDescription({ count }: { count: number }) {
|
||||
await this.retry.try(async () => {
|
||||
const suggestions = await this.getSuggestionsDescription();
|
||||
expect(suggestions.length).to.be(count);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1616,7 +1616,6 @@
|
|||
"data.kueryAutocomplete.equalOperatorDescription.equalsText": "égale",
|
||||
"data.kueryAutocomplete.existOperatorDescription": "{exists} sous un certain format",
|
||||
"data.kueryAutocomplete.existOperatorDescription.existsText": "existe",
|
||||
"data.kueryAutocomplete.filterResultsDescription": "Filtrer les résultats contenant {fieldName}",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription": "est {greaterThan} une certaine valeur",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "supérieur à",
|
||||
"data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "est {greaterThanOrEqualTo} une certaine valeur",
|
||||
|
|
|
@ -1939,7 +1939,6 @@
|
|||
"data.kueryAutocomplete.equalOperatorDescription.equalsText": "一致する",
|
||||
"data.kueryAutocomplete.existOperatorDescription": "いずれかの形式中に{exists}",
|
||||
"data.kueryAutocomplete.existOperatorDescription.existsText": "存在する",
|
||||
"data.kueryAutocomplete.filterResultsDescription": "{fieldName}を含む結果をフィルタリング",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription": "が一部の値{greaterThan}",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "より大きい",
|
||||
"data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "が一部の値{greaterThanOrEqualTo}",
|
||||
|
|
|
@ -1944,7 +1944,6 @@
|
|||
"data.kueryAutocomplete.equalOperatorDescription.equalsText": "等于",
|
||||
"data.kueryAutocomplete.existOperatorDescription": "以任意形式{exists}",
|
||||
"data.kueryAutocomplete.existOperatorDescription.existsText": "存在",
|
||||
"data.kueryAutocomplete.filterResultsDescription": "筛选包含 {fieldName} 的结果",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription": "{greaterThan}某一值",
|
||||
"data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText": "大于",
|
||||
"data.kueryAutocomplete.greaterThanOrEqualOperatorDescription": "{greaterThanOrEqualTo}某一值",
|
||||
|
|
|
@ -68,6 +68,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
await queryBar.setQuery('extension.raw : ');
|
||||
await queryBar.expectSuggestions({ count: 5, contains: '"jpg"' });
|
||||
});
|
||||
|
||||
it('also displays descriptions for operators', async () => {
|
||||
await PageObjects.timePicker.setDefaultAbsoluteRange();
|
||||
await queryBar.setQuery('extension.raw');
|
||||
await queryBar.expectSuggestionsDescription({ count: 2 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('context', () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue