mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Synonyms UI] Fix rendering issues and adds a code example (#210229)
## Summary Improved rendering when long lists are added with explicit rule. Added code example flyout. <img width="1075" alt="Screenshot 2025-02-07 at 18 09 18" src="https://github.com/user-attachments/assets/95020f5b-8162-4cb7-bf7a-11439ff5b2d0" /> <img width="1049" alt="Screenshot 2025-02-07 at 18 09 26" src="https://github.com/user-attachments/assets/5912e930-1356-4919-b637-92ca4009bc30" /> ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/src/platform/packages/shared/kbn-i18n/README.md) - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
0d5cecc2af
commit
e326c7759a
6 changed files with 210 additions and 9 deletions
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export const getExampleCode = (rulesetId: string) => `
|
||||
PUT my-index
|
||||
{
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "text",
|
||||
"search_analyzer": "my_analyzer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"analysis": {
|
||||
"analyzer": {
|
||||
"my_analyzer": {
|
||||
"tokenizer": "whitespace",
|
||||
"filter": [
|
||||
"synonyms_filter"
|
||||
]
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"synonyms_filter": {
|
||||
"type": "synonym",
|
||||
"synonyms_set": "${rulesetId}",
|
||||
"updateable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiButton } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
interface ConnectToApiButtonProps {
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
export const ConnectToApiButton: React.FC<ConnectToApiButtonProps> = ({ onClick }) => {
|
||||
return (
|
||||
<EuiButton
|
||||
data-test-subj="searchSynonymsSynonymsSetDetailConnectToApiButton"
|
||||
color="text"
|
||||
iconType="endpoint"
|
||||
onClick={onClick}
|
||||
>
|
||||
{i18n.translate('xpack.searchSynonyms.synonymsSetDetail.connectToApiButton', {
|
||||
defaultMessage: 'Connect to API',
|
||||
})}
|
||||
</EuiButton>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiCodeBlock,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
EuiFlyoutFooter,
|
||||
EuiFlyoutHeader,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiThemeProvider,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { docLinks } from '../../../common/doc_links';
|
||||
import { getExampleCode } from './code_examples';
|
||||
|
||||
interface ConnectToApiFlyoutProps {
|
||||
onClose: () => void;
|
||||
rulesetId: string;
|
||||
}
|
||||
|
||||
export const ConnectToApiFlyout: React.FC<ConnectToApiFlyoutProps> = ({ onClose, rulesetId }) => {
|
||||
return (
|
||||
<EuiFlyout onClose={onClose} size="m">
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
<EuiFlexGroup justifyContent="spaceBetween" direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiTitle size="m">
|
||||
<h2>
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.title', {
|
||||
defaultMessage: 'Connect with the API',
|
||||
})}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s" color="subdued">
|
||||
<p>
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.description', {
|
||||
defaultMessage: 'You can access and manage this synonym set from the API.',
|
||||
})}
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiLink
|
||||
data-test-subj="searchSynonymsConnectToApiFlyoutViewFullApiReferenceLink"
|
||||
href={docLinks.synonymsApi}
|
||||
external
|
||||
>
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.viewFullApiReference', {
|
||||
defaultMessage: 'View full API reference',
|
||||
})}
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<EuiText size="s">
|
||||
<p>
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.description', {
|
||||
defaultMessage: `You can specify the analyzer that contains your synonyms set as a search time analyzer.`,
|
||||
})}
|
||||
<EuiSpacer size="s" />
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.description.example', {
|
||||
defaultMessage: `The following example adds my_analyzer as a search analyzer to the title field in an index mapping`,
|
||||
})}
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiThemeProvider colorMode="dark">
|
||||
<EuiCodeBlock language="json" isCopyable fontSize="m">
|
||||
{getExampleCode(rulesetId)}
|
||||
</EuiCodeBlock>
|
||||
</EuiThemeProvider>
|
||||
</EuiFlyoutBody>
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
fill
|
||||
data-test-subj="searchSynonymsConnectToApiFlyoutButton"
|
||||
onClick={onClose}
|
||||
>
|
||||
{i18n.translate('xpack.searchSynonyms.ConnectToApiFlyout.close', {
|
||||
defaultMessage: 'Close',
|
||||
})}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutFooter>
|
||||
</EuiFlyout>
|
||||
);
|
||||
};
|
|
@ -10,6 +10,8 @@ import React, { useMemo } from 'react';
|
|||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { useKibana } from '../../hooks/use_kibana';
|
||||
import { SynonymsSetRuleTable } from './synonyms_set_rule_table';
|
||||
import { ConnectToApiButton } from '../connect_to_api/connect_to_api_button';
|
||||
import { ConnectToApiFlyout } from '../connect_to_api/connect_to_api_flyout';
|
||||
|
||||
export const SynonymsSetDetail = () => {
|
||||
const { synonymsSetId = '' } = useParams<{
|
||||
|
@ -23,6 +25,7 @@ export const SynonymsSetDetail = () => {
|
|||
() => (consolePlugin?.EmbeddableConsole ? <consolePlugin.EmbeddableConsole /> : null),
|
||||
[consolePlugin]
|
||||
);
|
||||
const [isApiConnectModalVisible, setIsApiConnectModalVisible] = React.useState(false);
|
||||
|
||||
return (
|
||||
<KibanaPageTemplate
|
||||
|
@ -33,9 +36,28 @@ export const SynonymsSetDetail = () => {
|
|||
solutionNav={searchNavigation?.useClassicNavigation(history)}
|
||||
color="primary"
|
||||
>
|
||||
<KibanaPageTemplate.Header pageTitle={synonymsSetId} restrictWidth color="primary" />
|
||||
<KibanaPageTemplate.Header
|
||||
pageTitle={synonymsSetId}
|
||||
restrictWidth
|
||||
color="primary"
|
||||
rightSideItems={[
|
||||
<ConnectToApiButton
|
||||
onClick={() => {
|
||||
setIsApiConnectModalVisible(true);
|
||||
}}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
<KibanaPageTemplate.Section restrictWidth>
|
||||
{synonymsSetId && <SynonymsSetRuleTable synonymsSetId={synonymsSetId} />}
|
||||
{isApiConnectModalVisible && (
|
||||
<ConnectToApiFlyout
|
||||
rulesetId={synonymsSetId}
|
||||
onClose={() => {
|
||||
setIsApiConnectModalVisible(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</KibanaPageTemplate.Section>
|
||||
{embeddableConsole}
|
||||
</KibanaPageTemplate>
|
||||
|
|
|
@ -72,7 +72,7 @@ export const SynonymsRuleFlyout: React.FC<SynonymsRuleFlyoutProps> = ({
|
|||
synonymsOptionToString({ fromTerms: selectedFromTerms, toTerms: selectedToTerms, isExplicit });
|
||||
|
||||
return (
|
||||
<EuiFlyout onClose={onClose}>
|
||||
<EuiFlyout onClose={onClose} size="s">
|
||||
<EuiFlyoutHeader hasBorder aria-labelledby={flyoutHeadingId}>
|
||||
{flyoutMode === 'edit' ? (
|
||||
<EuiText>
|
||||
|
@ -103,6 +103,7 @@ export const SynonymsRuleFlyout: React.FC<SynonymsRuleFlyoutProps> = ({
|
|||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
fullWidth
|
||||
title="Synonyms"
|
||||
id="synonyms"
|
||||
options={selectedFromTerms}
|
||||
|
@ -130,6 +131,7 @@ export const SynonymsRuleFlyout: React.FC<SynonymsRuleFlyoutProps> = ({
|
|||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
fullWidth
|
||||
title="Synonyms"
|
||||
id="synonyms-to"
|
||||
options={selectedToTerms}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
EuiPopover,
|
||||
EuiPopoverTitle,
|
||||
EuiText,
|
||||
EuiTextTruncate,
|
||||
} from '@elastic/eui';
|
||||
import { SynonymsSynonymRule } from '@elastic/elasticsearch/lib/api/types';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -97,14 +98,20 @@ export const SynonymsSetRuleTable = ({ synonymsSetId = '' }: { synonymsSetId: st
|
|||
</EuiFlexItem>
|
||||
{isExplicit ? (
|
||||
<>
|
||||
<EuiFlexItem data-test-subj="synonyms-set-item-explicit-from">
|
||||
<EuiCode>{explicitFrom}</EuiCode>
|
||||
<EuiFlexItem data-test-subj="synonyms-set-item-explicit-from" grow={7}>
|
||||
<EuiCode>
|
||||
<EuiTextTruncate text={explicitFrom} />
|
||||
</EuiCode>
|
||||
</EuiFlexItem>
|
||||
<EuiText>
|
||||
<b>{'=>'}</b>
|
||||
</EuiText>
|
||||
<EuiFlexItem grow={false} data-test-subj="synonyms-set-item-explicit-to">
|
||||
<EuiCode>{explicitTo}</EuiCode>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText>
|
||||
<b>{'=>'}</b>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={1} data-test-subj="synonyms-set-item-explicit-to">
|
||||
<EuiCode>
|
||||
<EuiTextTruncate text={explicitTo} />
|
||||
</EuiCode>
|
||||
</EuiFlexItem>
|
||||
</>
|
||||
) : (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue