[UnifiedSearch] Add query DSL docs link to filters UI (#156543)

## Summary

This PR adds a link to "Query DSL" syntax docs.

<img width="1047" alt="Screenshot 2023-05-03 at 15 40 22"
src="https://user-images.githubusercontent.com/1415710/235933352-0c88d3d6-d5a3-4f10-ab5c-a438ecf44032.png">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Davis McPhee <davismcphee@hotmail.com>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
Co-authored-by: shahzad31 <shahzad31comp@gmail.com>
This commit is contained in:
Julia Rechkunova 2023-05-26 14:26:23 +02:00 committed by GitHub
parent 74d276ed0c
commit ad85cc0727
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 12 deletions

View file

@ -9,6 +9,7 @@
import React from 'react';
import { UseEuiTheme, EuiThemeComputed } from '@elastic/eui';
import { registerTestBed, TestBed } from '@kbn/test-jest-helpers';
import { coreMock } from '@kbn/core/public/mocks';
import type { FilterEditorProps } from '.';
import { FilterEditor } from '.';
@ -48,6 +49,7 @@ describe('<FilterEditor />', () => {
indexPatterns: [],
onCancel: jest.fn(),
onSubmit: jest.fn(),
docLinks: coreMock.createStart().docLinks,
};
testBed = await registerTestBed(FilterEditor, { defaultProps })();
});

View file

@ -14,6 +14,7 @@ import {
EuiFlexItem,
EuiForm,
EuiFormRow,
EuiFormRowProps,
EuiIcon,
EuiPopoverFooter,
EuiPopoverTitle,
@ -23,6 +24,7 @@ import {
EuiBadge,
withEuiTheme,
EuiTextColor,
EuiLink,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import {
@ -45,6 +47,7 @@ import { getIndexPatternFromFilter } from '@kbn/data-plugin/public';
import { CodeEditor } from '@kbn/kibana-react-plugin/public';
import { cx } from '@emotion/css';
import { WithEuiThemeProps } from '@elastic/eui/src/services/theme';
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
import { GenericComboBox } from './generic_combo_box';
import {
getFieldFromFilter,
@ -102,6 +105,10 @@ export const strings = {
i18n.translate('unifiedSearch.filter.filterEditor.queryDslLabel', {
defaultMessage: 'Elasticsearch Query DSL',
}),
getQueryDslDocsLinkLabel: () =>
i18n.translate('unifiedSearch.filter.filterEditor.queryDslDocsLinkLabel', {
defaultMessage: 'Learn about Query DSL syntax',
}),
getQueryDslAriaLabel: () =>
i18n.translate('unifiedSearch.filter.filterEditor.queryDslAriaLabel', {
defaultMessage: 'Elasticsearch Query DSL editor',
@ -128,6 +135,7 @@ export interface FilterEditorComponentProps {
timeRangeForSuggestionsOverride?: boolean;
filtersForSuggestions?: Filter[];
mode?: 'edit' | 'add';
docLinks: DocLinksStart;
}
export type FilterEditorProps = WithEuiThemeProps & FilterEditorComponentProps;
@ -375,12 +383,22 @@ class FilterEditorComponent extends Component<FilterEditorProps, State> {
}
private renderCustomEditor() {
const helpText =
this.props.filter?.meta.type === FILTERS.SPATIAL_FILTER ? (
<EuiTextColor color="warning">{strings.getSpatialFilterQueryDslHelpText()}</EuiTextColor>
) : (
''
let helpText: EuiFormRowProps['helpText'] = '';
if (this.props.docLinks) {
helpText = (
<EuiLink href={this.props.docLinks.links.query.queryDsl} target="_blank">
{strings.getQueryDslDocsLinkLabel()}
</EuiLink>
);
}
if (this.props.filter?.meta.type === FILTERS.SPATIAL_FILTER) {
helpText = (
<EuiTextColor color="warning">{strings.getSpatialFilterQueryDslHelpText()}</EuiTextColor>
);
}
return (
<EuiFormRow fullWidth label={strings.getQueryDslLabel()} helpText={helpText}>
<CodeEditor

View file

@ -33,7 +33,7 @@ import React, {
useMemo,
useCallback,
} from 'react';
import { IUiSettingsClient } from '@kbn/core/public';
import type { DocLinksStart, IUiSettingsClient } from '@kbn/core/public';
import { DataView } from '@kbn/data-views-plugin/public';
import { css } from '@emotion/react';
import { getIndexPatternFromFilter, getDisplayValueFromFilter } from '@kbn/data-plugin/public';
@ -54,6 +54,7 @@ export interface FilterItemProps extends WithCloseFilterEditorConfirmModalProps
onRemove: () => void;
intl: InjectedIntl;
uiSettings: IUiSettingsClient;
docLinks: DocLinksStart;
hiddenPanelOptions?: FilterPanelOption[];
timeRangeForSuggestionsOverride?: boolean;
filtersForSuggestions?: Filter[];
@ -84,7 +85,7 @@ function FilterItemComponent(props: FilterItemProps) {
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
const [renderedComponent, setRenderedComponent] = useState('menu');
const { id, filter, indexPatterns, hiddenPanelOptions, readOnly = false } = props;
const { id, filter, indexPatterns, hiddenPanelOptions, readOnly = false, docLinks } = props;
const closePopover = useCallback(() => {
onCloseFilterPopover([() => setIsPopoverOpen(false)]);
@ -393,6 +394,7 @@ function FilterItemComponent(props: FilterItemProps) {
onCancel={() => setIsPopoverOpen(false)}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
filtersForSuggestions={props.filtersForSuggestions}
docLinks={docLinks}
/>
</div>,
]}

View file

@ -44,7 +44,7 @@ export interface FilterItemsProps {
const FilterItemsUI = React.memo(function FilterItemsUI(props: FilterItemsProps) {
const groupRef = useRef<HTMLDivElement>(null);
const kibana = useKibana<IUnifiedSearchPluginServices>();
const { appName, usageCollection, uiSettings } = kibana.services;
const { appName, usageCollection, uiSettings, docLinks } = kibana.services;
const { readOnly = false } = props;
if (!uiSettings) return null;
@ -74,6 +74,7 @@ const FilterItemsUI = React.memo(function FilterItemsUI(props: FilterItemsProps)
onRemove={() => onRemove(i)}
indexPatterns={props.indexPatterns}
uiSettings={uiSettings!}
docLinks={docLinks}
hiddenPanelOptions={props.hiddenPanelOptions}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
filtersForSuggestions={props.filtersForSuggestions}

View file

@ -48,7 +48,7 @@ export const FilterEditorWrapper = React.memo(function FilterEditorWrapper({
const fetchIndexAbortController = useRef<AbortController>();
const kibana = useKibana<IUnifiedSearchPluginServices>();
const { uiSettings, data, usageCollection, appName } = kibana.services;
const { uiSettings, data, usageCollection, appName, docLinks } = kibana.services;
const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName);
const [dataViews, setDataviews] = useState<DataView[]>([]);
const [newFilter, setNewFilter] = useState<Filter | undefined>(undefined);
@ -114,6 +114,7 @@ export const FilterEditorWrapper = React.memo(function FilterEditorWrapper({
onLocalFilterCreate={onLocalFilterCreate}
timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride}
filtersForSuggestions={filtersForSuggestions}
docLinks={docLinks}
/>
)}
</div>

View file

@ -40,6 +40,7 @@
"@kbn/saved-objects-management-plugin",
"@kbn/text-based-languages",
"@kbn/text-based-editor",
"@kbn/core-doc-links-browser"
],
"exclude": [
"target/**/*",

View file

@ -11,6 +11,7 @@ import { Filter, buildPhrasesFilter, buildPhraseFilter } from '@kbn/es-query';
import { FilterItem } from '@kbn/unified-search-plugin/public';
import type { DataView } from '@kbn/data-views-plugin/common';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { ObservabilityAppServices } from '../../../application/types';
export function buildFilterLabel({
field,
@ -76,8 +77,8 @@ export function FilterValueLabel({
const filter = buildFilterLabel({ field, value, label, dataView, negate });
const {
services: { uiSettings },
} = useKibana();
services: { uiSettings, docLinks },
} = useKibana<ObservabilityAppServices>();
return dataView ? (
<FilterItemI18n
@ -92,7 +93,8 @@ export function FilterValueLabel({
invertFilter({ field, value, negate });
}
}}
uiSettings={uiSettings!}
uiSettings={uiSettings}
docLinks={docLinks}
hiddenPanelOptions={[
...(allowExclusion ? [] : ['negateFilter' as const]),
'pinFilter',