mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Enterprise Search] Fix React rendering issues (#138496)
This commit is contained in:
parent
05da4a3965
commit
9452be575e
10 changed files with 434 additions and 437 deletions
|
@ -7,36 +7,23 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import { EuiCodeBlock, EuiFormLabel, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { EuiCodeBlock, EuiFormLabel, EuiSpacer } from '@elastic/eui';
|
||||
|
||||
interface ApiKeyProps {
|
||||
actions?: React.ReactNode;
|
||||
apiKey: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export const ApiKey: React.FC<ApiKeyProps> = ({ apiKey, label, actions }) => {
|
||||
const codeBlock = (
|
||||
export const ApiKey: React.FC<ApiKeyProps> = ({ apiKey, label }) => (
|
||||
<>
|
||||
{label && (
|
||||
<>
|
||||
<EuiFormLabel>{label}</EuiFormLabel>
|
||||
<EuiSpacer size="xs" />
|
||||
</>
|
||||
)}
|
||||
<EuiCodeBlock fontSize="m" paddingSize="m" color="dark" isCopyable>
|
||||
{apiKey}
|
||||
</EuiCodeBlock>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
{label && (
|
||||
<>
|
||||
<EuiFormLabel>{label}</EuiFormLabel>
|
||||
<EuiSpacer size="xs" />
|
||||
</>
|
||||
)}
|
||||
{actions ? (
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem>{codeBlock}</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>{actions}</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
) : (
|
||||
codeBlock
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -69,49 +69,6 @@ export const MethodConnector: React.FC = () => {
|
|||
const { setIsModalVisible } = useActions(AddConnectorPackageLogic);
|
||||
const { fullIndexName, language } = useValues(NewSearchIndexLogic);
|
||||
|
||||
const confirmModal = isModalVisible && (
|
||||
<EuiConfirmModal
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.title',
|
||||
{
|
||||
defaultMessage: 'Replace existing connector',
|
||||
}
|
||||
)}
|
||||
onCancel={(event) => {
|
||||
event?.preventDefault();
|
||||
setIsModalVisible(false);
|
||||
}}
|
||||
onConfirm={(event) => {
|
||||
event.preventDefault();
|
||||
makeRequest({ deleteExistingConnector: true, indexName: fullIndexName, language });
|
||||
}}
|
||||
cancelButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.cancelButton.label',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
)}
|
||||
confirmButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.confirmButton.label',
|
||||
{
|
||||
defaultMessage: 'Replace configuration',
|
||||
}
|
||||
)}
|
||||
defaultFocusedButton="confirm"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content..newIndex.steps.buildConnector.confirmModal.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A deleted index named {indexName} was originally tied to an existing connector configuration. Would you like to replace the existing connector configuration with a new one?',
|
||||
values: {
|
||||
indexName: fullIndexName,
|
||||
},
|
||||
}
|
||||
)}
|
||||
</EuiConfirmModal>
|
||||
);
|
||||
|
||||
return (
|
||||
<NewSearchIndexTemplate
|
||||
docsUrl="https://github.com/elastic/connectors-ruby/blob/main/README.md"
|
||||
|
@ -162,7 +119,48 @@ export const MethodConnector: React.FC = () => {
|
|||
BUILD_SEARCH_EXPERIENCE_STEP,
|
||||
]}
|
||||
/>
|
||||
{confirmModal}
|
||||
{isModalVisible && (
|
||||
<EuiConfirmModal
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.title',
|
||||
{
|
||||
defaultMessage: 'Replace existing connector',
|
||||
}
|
||||
)}
|
||||
onCancel={(event) => {
|
||||
event?.preventDefault();
|
||||
setIsModalVisible(false);
|
||||
}}
|
||||
onConfirm={(event) => {
|
||||
event.preventDefault();
|
||||
makeRequest({ deleteExistingConnector: true, indexName: fullIndexName, language });
|
||||
}}
|
||||
cancelButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.cancelButton.label',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
)}
|
||||
confirmButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.confirmButton.label',
|
||||
{
|
||||
defaultMessage: 'Replace configuration',
|
||||
}
|
||||
)}
|
||||
defaultFocusedButton="confirm"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content..newIndex.steps.buildConnector.confirmModal.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'A deleted index named {indexName} was originally tied to an existing connector configuration. Would you like to replace the existing connector configuration with a new one?',
|
||||
values: {
|
||||
indexName: fullIndexName,
|
||||
},
|
||||
}
|
||||
)}
|
||||
</EuiConfirmModal>
|
||||
)}
|
||||
</NewSearchIndexTemplate>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -57,72 +57,10 @@ export const DocumentList: React.FC = () => {
|
|||
return [];
|
||||
};
|
||||
|
||||
const docsPerPageButton = (
|
||||
<EuiButtonEmpty
|
||||
size="s"
|
||||
iconType="arrowDown"
|
||||
iconSide="right"
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(true);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage',
|
||||
{
|
||||
defaultMessage: 'Documents per page: {docPerPage}',
|
||||
values: { docPerPage: docsPerPage },
|
||||
}
|
||||
)}
|
||||
</EuiButtonEmpty>
|
||||
);
|
||||
|
||||
const getIconType = (size: number) => {
|
||||
return size === docsPerPage ? 'check' : 'empty';
|
||||
};
|
||||
|
||||
const docsPerPageOptions = [
|
||||
<EuiContextMenuItem
|
||||
key="10 rows"
|
||||
icon={getIconType(10)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(10);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 10 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
|
||||
<EuiContextMenuItem
|
||||
key="25 rows"
|
||||
icon={getIconType(25)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(25);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 25 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
<EuiContextMenuItem
|
||||
key="50 rows"
|
||||
icon={getIconType(50)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(50);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 50 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiPagination
|
||||
|
@ -175,7 +113,24 @@ export const DocumentList: React.FC = () => {
|
|||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.docsPerPage',
|
||||
{ defaultMessage: 'Document count per page dropdown' }
|
||||
)}
|
||||
button={docsPerPageButton}
|
||||
button={
|
||||
<EuiButtonEmpty
|
||||
size="s"
|
||||
iconType="arrowDown"
|
||||
iconSide="right"
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(true);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage',
|
||||
{
|
||||
defaultMessage: 'Documents per page: {docPerPage}',
|
||||
values: { docPerPage: docsPerPage },
|
||||
}
|
||||
)}
|
||||
</EuiButtonEmpty>
|
||||
}
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={() => {
|
||||
setIsPopoverOpen(false);
|
||||
|
@ -183,7 +138,51 @@ export const DocumentList: React.FC = () => {
|
|||
panelPaddingSize="none"
|
||||
anchorPosition="downLeft"
|
||||
>
|
||||
<EuiContextMenuPanel size="s" items={docsPerPageOptions} />
|
||||
<EuiContextMenuPanel
|
||||
size="s"
|
||||
items={[
|
||||
<EuiContextMenuItem
|
||||
key="10 rows"
|
||||
icon={getIconType(10)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(10);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 10 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
|
||||
<EuiContextMenuItem
|
||||
key="25 rows"
|
||||
icon={getIconType(25)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(25);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 25 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
<EuiContextMenuItem
|
||||
key="50 rows"
|
||||
icon={getIconType(50)}
|
||||
onClick={() => {
|
||||
setIsPopoverOpen(false);
|
||||
setDocsPerPage(50);
|
||||
}}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option',
|
||||
{ defaultMessage: '{docCount} documents', values: { docCount: 50 } }
|
||||
)}
|
||||
</EuiContextMenuItem>,
|
||||
]}
|
||||
/>
|
||||
</EuiPopover>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -11,14 +11,12 @@ import React from 'react';
|
|||
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { EuiModal, EuiFieldText } from '@elastic/eui';
|
||||
import { EuiModal, EuiFieldText, EuiCodeBlock } from '@elastic/eui';
|
||||
|
||||
const mockActions = { makeRequest: jest.fn(), setKeyName: jest.fn() };
|
||||
|
||||
const mockValues = { apiKey: '', isLoading: false, isSuccess: false, keyName: '' };
|
||||
|
||||
import { ApiKey } from '../../../api_key/api_key';
|
||||
|
||||
import { GenerateApiKeyModal } from './modal';
|
||||
|
||||
const onCloseMock = jest.fn();
|
||||
|
@ -84,8 +82,8 @@ describe('GenerateApiKeyModal', () => {
|
|||
);
|
||||
expect(wrapper.find(EuiFieldText)).toHaveLength(0);
|
||||
expect(wrapper.find('[data-test-subj="generateApiKeyButton"]')).toHaveLength(0);
|
||||
expect(wrapper.find(ApiKey)).toHaveLength(1);
|
||||
expect(wrapper.find(ApiKey).prop('apiKey')).toEqual('apiKeyFromBackend123123==');
|
||||
expect(wrapper.find(EuiCodeBlock)).toHaveLength(1);
|
||||
expect(wrapper.find(EuiCodeBlock).children().text()).toEqual('apiKeyFromBackend123123==');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -26,14 +26,14 @@ import {
|
|||
EuiText,
|
||||
EuiSpacer,
|
||||
EuiLink,
|
||||
EuiFormLabel,
|
||||
EuiCodeBlock,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { docLinks } from '../../../../../shared/doc_links';
|
||||
|
||||
import { ApiKey } from '../../../api_key/api_key';
|
||||
|
||||
import { GenerateApiKeyModalLogic } from './generate_api_key_modal.logic';
|
||||
|
||||
interface GenerateApiKeyModalProps {
|
||||
|
@ -114,10 +114,21 @@ export const GenerateApiKeyModal: React.FC<GenerateApiKeyModalProps> = ({ indexN
|
|||
</>
|
||||
) : (
|
||||
<EuiFlexItem>
|
||||
<ApiKey
|
||||
apiKey={apiKey}
|
||||
label={keyName}
|
||||
actions={
|
||||
<EuiFormLabel>{keyName}</EuiFormLabel>
|
||||
<EuiSpacer size="xs" />
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiCodeBlock
|
||||
aria-label={keyName}
|
||||
fontSize="m"
|
||||
paddingSize="m"
|
||||
color="dark"
|
||||
isCopyable
|
||||
>
|
||||
{apiKey}
|
||||
</EuiCodeBlock>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonIcon
|
||||
aria-label={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.overview.generateApiKeyModal.csvDownloadButton',
|
||||
|
@ -127,8 +138,8 @@ export const GenerateApiKeyModal: React.FC<GenerateApiKeyModalProps> = ({ indexN
|
|||
href={encodeURI(`data:text/csv;charset=utf-8,${apiKey}`)}
|
||||
download={`${keyName}.csv`}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -23,6 +23,43 @@ import { Status } from '../../../../../../common/types/api';
|
|||
import { GenerateConnectorApiKeyApiLogic } from '../../../api/connector_package/generate_connector_api_key_api_logic';
|
||||
import { ApiKey } from '../../api_key/api_key';
|
||||
|
||||
const ConfirmModal: React.FC<{
|
||||
onCancel: () => void;
|
||||
onConfirm: () => void;
|
||||
}> = ({ onCancel, onConfirm }) => (
|
||||
<EuiConfirmModal
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.title',
|
||||
{
|
||||
defaultMessage: 'Generate an Elasticsearch API key',
|
||||
}
|
||||
)}
|
||||
onCancel={onCancel}
|
||||
onConfirm={onConfirm}
|
||||
cancelButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.cancelButton.label',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
)}
|
||||
confirmButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.confirmButton.label',
|
||||
{
|
||||
defaultMessage: 'Generate API key',
|
||||
}
|
||||
)}
|
||||
defaultFocusedButton="confirm"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Generating a new API key will invalidate the previous key. Are you sure you want to generate a new API key? This can not be undone.',
|
||||
}
|
||||
)}
|
||||
</EuiConfirmModal>
|
||||
);
|
||||
|
||||
export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> = ({
|
||||
hasApiKey,
|
||||
indexName,
|
||||
|
@ -44,50 +81,18 @@ export const ApiKeyConfig: React.FC<{ hasApiKey: boolean; indexName: string }> =
|
|||
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
|
||||
const confirmModal = (
|
||||
<EuiConfirmModal
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.title',
|
||||
{
|
||||
defaultMessage: 'Generate an Elasticsearch API key.',
|
||||
}
|
||||
)}
|
||||
onCancel={(event) => {
|
||||
event?.preventDefault();
|
||||
setIsModalVisible(false);
|
||||
}}
|
||||
onConfirm={(event) => {
|
||||
event.preventDefault();
|
||||
makeRequest({ indexName });
|
||||
setIsModalVisible(false);
|
||||
}}
|
||||
cancelButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.cancelButton.label',
|
||||
{
|
||||
defaultMessage: 'Cancel',
|
||||
}
|
||||
)}
|
||||
confirmButtonText={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.confirmButton.label',
|
||||
{
|
||||
defaultMessage: 'Generate API key',
|
||||
}
|
||||
)}
|
||||
defaultFocusedButton="confirm"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.apiKey.confirmModal.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Generating a new API key will invalidate the previous key. Are you sure you want to generate a new API key? This can not be undone.',
|
||||
}
|
||||
)}
|
||||
</EuiConfirmModal>
|
||||
);
|
||||
const onCancel = () => {
|
||||
setIsModalVisible(false);
|
||||
};
|
||||
|
||||
const onConfirm = () => {
|
||||
makeRequest({ indexName });
|
||||
setIsModalVisible(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFlexGroup direction="column">
|
||||
{isModalVisible && confirmModal}
|
||||
{isModalVisible && <ConfirmModal onCancel={onCancel} onConfirm={onConfirm} />}
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
|
|
|
@ -55,172 +55,6 @@ export const ConnectorConfiguration: React.FC = () => {
|
|||
|
||||
const hasApiKey = !!(indexData.connector.api_key_id ?? apiKeyData);
|
||||
|
||||
const ScheduleStep: React.FC = () => (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.scheduleSync.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Once your connectors are configured to your liking, don’t forget to set a recurring sync schedule to make sure your documents are indexed and relevant. You can also trigger a one-time sync without enabling a sync schedule.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonTo
|
||||
to={`${generateEncodedPath(SEARCH_INDEX_TAB_PATH, {
|
||||
indexName,
|
||||
tabId: SearchIndexTabId.SCHEDULING,
|
||||
})}`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.button.label',
|
||||
{
|
||||
defaultMessage: 'Set schedule and sync',
|
||||
}
|
||||
)}
|
||||
</EuiButtonTo>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
const ConnectorPackage: React.FC = () => (
|
||||
<>
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.firstParagraph',
|
||||
{
|
||||
defaultMessage:
|
||||
'The connectors repository contains several connector client examples to help you utilize our framework for accelerated development against custom data sources.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
<EuiLink href="https://github.com/elastic/connectors" target="_blank">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.button.label',
|
||||
{
|
||||
defaultMessage: 'Explore the connectors repository',
|
||||
}
|
||||
)}
|
||||
</EuiLink>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.secondParagraph"
|
||||
defaultMessage="The connectors repository contains several {link} to help you utilize our framework for accelerated development against custom data sources."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/connectors-ruby/tree/main/lib/connectors"
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.clientExamplesLink',
|
||||
{ defaultMessage: 'connector client examples' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.thirdParagraph"
|
||||
defaultMessage="In this step, you will need to clone or fork the repository, and copy the generated API key and connector ID to the associated {link}. The connector ID will identify this connector to Enterprise Search."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/connectors-ruby/tree/main/config"
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.configurationFileLink',
|
||||
{ defaultMessage: 'configuration file' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiCodeBlock fontSize="m" paddingSize="m" color="dark" isCopyable>
|
||||
{`${
|
||||
apiKeyData?.encoded
|
||||
? `elasticsearch:
|
||||
api_key: "${apiKeyData?.encoded}"
|
||||
`
|
||||
: ''
|
||||
}connector_id: "${indexData.connector.id}"
|
||||
`}
|
||||
</EuiCodeBlock>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorDeployedText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Once you’ve configured the connector, deploy the connector to your self managed infrastructure.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
<EuiHorizontalRule />
|
||||
{!indexData.connector.status || indexData.connector.status === ConnectorStatus.CREATED ? (
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorTitle',
|
||||
{
|
||||
defaultMessage: 'Waiting for your connector',
|
||||
}
|
||||
)}
|
||||
iconType="iInCircle"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your connector has not connected to Enterprise Search. Troubleshoot your configuration and refresh the page.',
|
||||
}
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiButton
|
||||
iconType="refresh"
|
||||
onClick={() => recheckIndex()}
|
||||
isLoading={recheckIndexLoading}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnector.button.label',
|
||||
{
|
||||
defaultMessage: 'Recheck now',
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
</EuiCallOut>
|
||||
) : (
|
||||
<EuiCallOut
|
||||
iconType="check"
|
||||
color="success"
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorConnected',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your connector {name} has connected to Enterprise Search successfully.',
|
||||
values: { name: indexData.connector.name },
|
||||
}
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
|
@ -246,7 +80,137 @@ export const ConnectorConfiguration: React.FC = () => {
|
|||
titleSize: 'xs',
|
||||
},
|
||||
{
|
||||
children: <ConnectorPackage />,
|
||||
children: (
|
||||
<>
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.firstParagraph',
|
||||
{
|
||||
defaultMessage:
|
||||
'The connectors repository contains several connector client examples to help you utilize our framework for accelerated development against custom data sources.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
<EuiLink href="https://github.com/elastic/connectors" target="_blank">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.button.label',
|
||||
{
|
||||
defaultMessage: 'Explore the connectors repository',
|
||||
}
|
||||
)}
|
||||
</EuiLink>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.secondParagraph"
|
||||
defaultMessage="The connectors repository contains several {link} to help you utilize our framework for accelerated development against custom data sources."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/connectors-ruby/tree/main/lib/connectors"
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.clientExamplesLink',
|
||||
{ defaultMessage: 'connector client examples' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
<FormattedMessage
|
||||
id="xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.description.thirdParagraph"
|
||||
defaultMessage="In this step, you will need to clone or fork the repository, and copy the generated API key and connector ID to the associated {link}. The connector ID will identify this connector to Enterprise Search."
|
||||
values={{
|
||||
link: (
|
||||
<EuiLink
|
||||
href="https://github.com/elastic/connectors-ruby/tree/main/config"
|
||||
target="_blank"
|
||||
external
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.configurationFileLink',
|
||||
{ defaultMessage: 'configuration file' }
|
||||
)}
|
||||
</EuiLink>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</EuiText>
|
||||
<EuiSpacer />
|
||||
<EuiCodeBlock fontSize="m" paddingSize="m" color="dark" isCopyable>
|
||||
{`${
|
||||
apiKeyData?.encoded
|
||||
? `elasticsearch:
|
||||
api_key: "${apiKeyData?.encoded}"
|
||||
`
|
||||
: ''
|
||||
}connector_id: "${indexData.connector.id}"
|
||||
`}
|
||||
</EuiCodeBlock>
|
||||
<EuiSpacer />
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorDeployedText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Once you’ve configured the connector, deploy the connector to your self managed infrastructure.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
<EuiHorizontalRule />
|
||||
{!indexData.connector.status ||
|
||||
indexData.connector.status === ConnectorStatus.CREATED ? (
|
||||
<EuiCallOut
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorTitle',
|
||||
{
|
||||
defaultMessage: 'Waiting for your connector',
|
||||
}
|
||||
)}
|
||||
iconType="iInCircle"
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnectorText',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your connector has not connected to Enterprise Search. Troubleshoot your configuration and refresh the page.',
|
||||
}
|
||||
)}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiButton
|
||||
iconType="refresh"
|
||||
onClick={() => recheckIndex()}
|
||||
isLoading={recheckIndexLoading}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.waitingForConnector.button.label',
|
||||
{
|
||||
defaultMessage: 'Recheck now',
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
</EuiCallOut>
|
||||
) : (
|
||||
<EuiCallOut
|
||||
iconType="check"
|
||||
color="success"
|
||||
title={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.connectorConnected',
|
||||
{
|
||||
defaultMessage:
|
||||
'Your connector {name} has connected to Enterprise Search successfully.',
|
||||
values: { name: indexData.connector.name },
|
||||
}
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
status:
|
||||
!indexData.connector.status ||
|
||||
indexData.connector.status === ConnectorStatus.CREATED
|
||||
|
@ -275,7 +239,40 @@ export const ConnectorConfiguration: React.FC = () => {
|
|||
titleSize: 'xs',
|
||||
},
|
||||
{
|
||||
children: <ScheduleStep />,
|
||||
children: (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.scheduleSync.description',
|
||||
{
|
||||
defaultMessage:
|
||||
'Once your connectors are configured to your liking, don’t forget to set a recurring sync schedule to make sure your documents are indexed and relevant. You can also trigger a one-time sync without enabling a sync schedule.',
|
||||
}
|
||||
)}
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonTo
|
||||
to={`${generateEncodedPath(SEARCH_INDEX_TAB_PATH, {
|
||||
indexName,
|
||||
tabId: SearchIndexTabId.SCHEDULING,
|
||||
})}`}
|
||||
>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.button.label',
|
||||
{
|
||||
defaultMessage: 'Set schedule and sync',
|
||||
}
|
||||
)}
|
||||
</EuiButtonTo>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
),
|
||||
status: indexData.connector.scheduling.enabled ? 'complete' : 'incomplete',
|
||||
title: i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.steps.schedule.title',
|
||||
|
|
|
@ -35,28 +35,6 @@ export const ConnectorConfigurationConfig: React.FC = () => {
|
|||
title: label,
|
||||
}));
|
||||
|
||||
const display = (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiDescriptionList listItems={displayList} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton onClick={() => setIsEditing(!isEditing)}>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.config.editButton.title',
|
||||
{
|
||||
defaultMessage: 'Edit configuration',
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
|
@ -130,7 +108,31 @@ export const ConnectorConfigurationConfig: React.FC = () => {
|
|||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
{isEditing ? <ConnectorConfigurationForm /> : displayList.length > 0 && display}
|
||||
{isEditing ? (
|
||||
<ConnectorConfigurationForm />
|
||||
) : (
|
||||
displayList.length > 0 && (
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiDescriptionList listItems={displayList} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton onClick={() => setIsEditing(!isEditing)}>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.indices.configurationConnector.config.editButton.title',
|
||||
{
|
||||
defaultMessage: 'Edit configuration',
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -28,20 +28,20 @@ import {
|
|||
import { IndexViewLogic } from '../index_view_logic';
|
||||
import { SearchIndexTabId } from '../search_index';
|
||||
|
||||
const StatusPanel: React.FC<{ ingestionStatus: IngestionStatus }> = ({ ingestionStatus }) => (
|
||||
<EuiPanel color={ingestionStatusToColor(ingestionStatus)} hasShadow={false} paddingSize="l">
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.enterpriseSearch.connector.ingestionStatus.title', {
|
||||
defaultMessage: 'Ingestion status',
|
||||
})}
|
||||
title={ingestionStatusToText(ingestionStatus)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
);
|
||||
|
||||
export const ConnectorOverviewPanels: React.FC = () => {
|
||||
const { ingestionStatus, index } = useValues(IndexViewLogic);
|
||||
|
||||
const statusPanel = (
|
||||
<EuiPanel color={ingestionStatusToColor(ingestionStatus)} hasShadow={false} paddingSize="l">
|
||||
<EuiStat
|
||||
description={i18n.translate('xpack.enterpriseSearch.connector.ingestionStatus.title', {
|
||||
defaultMessage: 'Ingestion status',
|
||||
})}
|
||||
title={ingestionStatusToText(ingestionStatus)}
|
||||
/>
|
||||
</EuiPanel>
|
||||
);
|
||||
|
||||
return isConnectorIndex(index) ? (
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={1}>
|
||||
|
@ -83,10 +83,10 @@ export const ConnectorOverviewPanels: React.FC = () => {
|
|||
tabId: SearchIndexTabId.CONFIGURATION,
|
||||
})}
|
||||
>
|
||||
{statusPanel}
|
||||
<StatusPanel ingestionStatus={ingestionStatus} />
|
||||
</EuiLinkTo>
|
||||
) : (
|
||||
statusPanel
|
||||
<StatusPanel ingestionStatus={ingestionStatus} />
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
|
|
@ -60,50 +60,6 @@ export const SearchIndices: React.FC = () => {
|
|||
fetchIndices({ meta, returnHiddenIndices: showHiddenIndices, searchQuery });
|
||||
}, [searchQuery, meta.page.current, showHiddenIndices]);
|
||||
|
||||
const createNewIndexButton = (
|
||||
<EuiLinkTo data-test-subj="create-new-index-button" to={NEW_INDEX_PATH}>
|
||||
<EuiButton iconType="plusInCircle" color="primary" fill>
|
||||
{i18n.translate('xpack.enterpriseSearch.content.searchIndices.create.buttonTitle', {
|
||||
defaultMessage: 'Create new index',
|
||||
})}
|
||||
</EuiButton>
|
||||
</EuiLinkTo>
|
||||
);
|
||||
|
||||
const engineSteps = (
|
||||
<>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
{i18n.translate('xpack.enterpriseSearch.content.searchIndices.searchIndices.stepsTitle', {
|
||||
defaultMessage: 'Build beautiful search experiences with Enterprise Search',
|
||||
})}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<GettingStartedSteps step={indices.length === 0 ? 'first' : 'second'} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<ElasticsearchResources />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
|
||||
const hiddenIndicesSwitch = (
|
||||
<EuiSwitch
|
||||
checked={showHiddenIndices}
|
||||
label={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndices.searchIndices.includeHidden.label',
|
||||
{
|
||||
defaultMessage: 'Show hidden indices',
|
||||
}
|
||||
)}
|
||||
onChange={(event) => setShowHiddenIndices(event.target.checked)}
|
||||
/>
|
||||
);
|
||||
|
||||
const pageTitle = isLoading
|
||||
? ''
|
||||
: indices.length !== 0
|
||||
|
@ -122,7 +78,20 @@ export const SearchIndices: React.FC = () => {
|
|||
isLoading={isLoading}
|
||||
pageHeader={{
|
||||
pageTitle,
|
||||
rightSideItems: isLoading ? [] : [createNewIndexButton],
|
||||
rightSideItems: isLoading
|
||||
? []
|
||||
: [
|
||||
<EuiLinkTo data-test-subj="create-new-index-button" to={NEW_INDEX_PATH}>
|
||||
<EuiButton iconType="plusInCircle" color="primary" fill>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndices.create.buttonTitle',
|
||||
{
|
||||
defaultMessage: 'Create new index',
|
||||
}
|
||||
)}
|
||||
</EuiButton>
|
||||
</EuiLinkTo>,
|
||||
],
|
||||
}}
|
||||
>
|
||||
{!hasNoIndices ? (
|
||||
|
@ -179,7 +148,18 @@ export const SearchIndices: React.FC = () => {
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiFlexGroup justifyContent="flexEnd" alignItems="center">
|
||||
<EuiFlexItem grow={false}>{hiddenIndicesSwitch}</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiSwitch
|
||||
checked={showHiddenIndices}
|
||||
label={i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndices.searchIndices.includeHidden.label',
|
||||
{
|
||||
defaultMessage: 'Show hidden indices',
|
||||
}
|
||||
)}
|
||||
onChange={(event) => setShowHiddenIndices(event.target.checked)}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem className="entSearchIndicesSearchBar">
|
||||
<EuiSearchBar
|
||||
query={searchQuery}
|
||||
|
@ -213,7 +193,27 @@ export const SearchIndices: React.FC = () => {
|
|||
<>
|
||||
<AddContentEmptyPrompt />
|
||||
<EuiSpacer size="xxl" />
|
||||
{engineSteps}
|
||||
<>
|
||||
<EuiTitle>
|
||||
<h2>
|
||||
{i18n.translate(
|
||||
'xpack.enterpriseSearch.content.searchIndices.searchIndices.stepsTitle',
|
||||
{
|
||||
defaultMessage: 'Build beautiful search experiences with Enterprise Search',
|
||||
}
|
||||
)}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="l" />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<GettingStartedSteps step={indices.length === 0 ? 'first' : 'second'} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<ElasticsearchResources />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
</>
|
||||
)}
|
||||
</EnterpriseSearchContentPageTemplate>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue