[Enterprise Search] Fix React rendering issues (#138496)

This commit is contained in:
Sander Philipse 2022-08-10 16:19:43 +02:00 committed by GitHub
parent 05da4a3965
commit 9452be575e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 434 additions and 437 deletions

View file

@ -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
)}
</>
);
};
</>
);

View file

@ -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>
);
};

View file

@ -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>

View file

@ -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==');
});
});
});

View file

@ -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>

View file

@ -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(

View file

@ -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, dont 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 youve 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 youve 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, dont 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',

View file

@ -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>
);

View file

@ -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>

View file

@ -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>