diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/app_search_gate/app_search_gate.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/app_search_gate/app_search_gate.tsx index 155f06f508d3c..84c57fe528621 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/app_search_gate/app_search_gate.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/app_search_gate/app_search_gate.tsx @@ -58,7 +58,7 @@ const featuresList = { 'Did you know the new self-managed Elastic open crawler is now available? You can keep your web content in sync with your search-optimized indices!', }), title: i18n.translate('xpack.enterpriseSearch.appSearch.gateForm.webCrawler.featureName', { - defaultMessage: 'Web crawler', + defaultMessage: 'Web Crawler', }), }, analyticsAndLogs: { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx index deef693166711..7f669d7fd0660 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx @@ -50,7 +50,7 @@ const CAPITALIZATION_MAP = { [LogRetentionOptions.Crawler]: { capitalized: i18n.translate( 'xpack.enterpriseSearch.appSearch.logRetention.type.crawler.title.capitalized', - { defaultMessage: 'Web crawler' } + { defaultMessage: 'Web Crawler' } ), lowercase: i18n.translate( 'xpack.enterpriseSearch.appSearch.logRetention.type.crawler.title.lowercase', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/delete_connector_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/delete_connector_api_logic.ts index a427b634c3b6e..80af793a42f80 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/delete_connector_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/delete_connector_api_logic.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { i18n } from '@kbn/i18n'; import { DeleteConnectorResponse } from '../../../../../common/types/connectors'; @@ -12,30 +13,42 @@ import { HttpLogic } from '../../../shared/http'; export interface DeleteConnectorApiLogicArgs { connectorId: string; + connectorName: string; shouldDeleteIndex: boolean; } export interface DeleteConnectorApiLogicResponse { - acknowledged: boolean; + connectorName: string; } export const deleteConnector = async ({ connectorId, + connectorName, shouldDeleteIndex = false, -}: DeleteConnectorApiLogicArgs) => { - return await HttpLogic.values.http.delete( - `/internal/enterprise_search/connectors/${connectorId}`, - { - query: { - shouldDeleteIndex, - }, - } - ); +}: DeleteConnectorApiLogicArgs): Promise => { + await HttpLogic.values.http.delete(`/internal/enterprise_search/connectors/${connectorId}`, { + query: { + shouldDeleteIndex, + }, + }); + return { connectorName }; }; export const DeleteConnectorApiLogic = createApiLogic( ['delete_connector_api_logic'], - deleteConnector + deleteConnector, + { + showSuccessFlashFn: ({ connectorName }) => + i18n.translate( + 'xpack.enterpriseSearch.content.connectors.deleteConnector.successToast.title', + { + defaultMessage: 'The connector {connectorName} was successfully deleted', + values: { + connectorName, + }, + } + ), + } ); export type DeleteConnectorApiLogicActions = Actions< diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_type.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_type.tsx index ae07ebe05f96a..5036ae3bf2c4a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_type.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connector_type.tsx @@ -36,7 +36,7 @@ export const ConnectorType: React.FC = ({ serviceType }) =>

{serviceType === CRAWLER_SERVICE_TYPE ? i18n.translate('xpack.enterpriseSearch.content.connectors.connectorType.crawler', { - defaultMessage: 'Web crawler', + defaultMessage: 'Web Crawler', }) : connector?.name ?? '-'}

diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors.tsx index c12dd8036b6b9..821d61951601e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors.tsx @@ -95,7 +95,7 @@ export const Connectors: React.FC = ({ isCrawler }) => { defaultMessage: 'Elasticsearch connectors', }) : i18n.translate('xpack.enterpriseSearch.crawlers.title', { - defaultMessage: 'Elasticsearch web crawlers', + defaultMessage: 'Elastic Web Crawler', }), rightSideGroupProps: { gutterSize: 's', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/crawler_empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/crawler_empty_state.tsx index 5a03d0560dfbf..2dc97fb86c04f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/crawler_empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/crawler_empty_state.tsx @@ -11,7 +11,6 @@ import { useValues } from 'kea'; import { EuiButton, EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { CRAWLER } from '../../../../../common/constants'; import { HttpLogic } from '../../../shared/http'; import { GithubIcon } from '../../../shared/icons/github_icon'; import { KibanaLogic } from '../../../shared/kibana'; @@ -49,7 +48,8 @@ export const CrawlerEmptyState: React.FC = () => { color="primary" fill iconType={GithubIcon} - href={CRAWLER.github_repo} + href={'https://github.com/elastic/crawler'} + target="_blank" > {i18n.translate( 'xpack.enterpriseSearch.crawlerEmptyState.openSourceCrawlerButtonLabel', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/delete_connector_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/delete_connector_modal.tsx index a047b8ab8219b..65f3e38916faf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/delete_connector_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/delete_connector_modal.tsx @@ -46,7 +46,7 @@ export const DeleteConnectorModal: React.FC = ({ isCr isDeleteModalVisible, } = useValues(ConnectorsLogic); - const connectorName = isCrawler ? deleteModalIndexName : deleteModalConnectorName; + const connectorName = (isCrawler ? deleteModalIndexName : deleteModalConnectorName) || ''; const [inputConnectorName, setInputConnectorName] = useState(''); const [shouldDeleteIndex, setShouldDeleteIndex] = useState(false); @@ -80,6 +80,7 @@ export const DeleteConnectorModal: React.FC = ({ isCr } else { deleteConnector({ connectorId, + connectorName, shouldDeleteIndex, }); setConnectorUiOptions(omit(connectorUiOptions, connectorId)); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/constants.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/constants.ts index c39d26314671c..c27e62491218e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/constants.ts @@ -18,7 +18,7 @@ export const NEW_INDEX_TEMPLATE_TYPES: { [key: string]: string } = { defaultMessage: 'Connector', }), crawler: i18n.translate('xpack.enterpriseSearch.content.newIndex.types.crawler', { - defaultMessage: 'Web crawler', + defaultMessage: 'Web Crawler', }), elasticsearch: i18n.translate('xpack.enterpriseSearch.content.newIndex.types.elasticsearch', { defaultMessage: 'Elasticsearch index', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx index 9676394b29105..eae92d6e48c39 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_index_card.tsx @@ -57,7 +57,7 @@ const METHOD_CARD_OPTIONS: Record = { }, icon: getIngestionMethodIconType(INGESTION_METHOD_IDS.CRAWLER), title: i18n.translate('xpack.enterpriseSearch.content.newIndex.methodCard.crawler.title', { - defaultMessage: 'Web crawler', + defaultMessage: 'Web Crawler', }), }, [INGESTION_METHOD_IDS.CONNECTOR]: { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx index 25baabb388575..211738b43f25d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx @@ -289,7 +289,7 @@ export const NewSearchIndexTemplate: React.FC = ({ {i18n.translate( 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.learnMoreCrawler.linkText', { - defaultMessage: 'Learn more about the Elastic web crawler', + defaultMessage: 'Learn more about the Elastic Web Crawler', } )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.test.ts index df02a53fe0ab0..bacde5895073e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/pipelines_logic.test.ts @@ -138,7 +138,10 @@ describe('PipelinesLogic', () => { describe('apiSuccess', () => { it('should call flashSuccessToast', () => { PipelinesLogic.actions.apiSuccess({ connectorId: 'a', pipeline: newPipeline }); - expect(flashSuccessToast).toHaveBeenCalledWith('Pipelines updated'); + expect(flashSuccessToast).toHaveBeenCalledWith('Pipelines updated', { + 'aria-live': 'assertive', + role: 'alert', + }); }); }); describe('createCustomPipelineError', () => { @@ -154,7 +157,10 @@ describe('PipelinesLogic', () => { PipelinesLogic.actions.fetchCustomPipeline = jest.fn(); PipelinesLogic.actions.fetchIndexApiSuccess(connectorIndex); PipelinesLogic.actions.createCustomPipelineSuccess({ [connectorIndex.name]: {} }); - expect(flashSuccessToast).toHaveBeenCalledWith('Custom pipeline created'); + expect(flashSuccessToast).toHaveBeenCalledWith('Custom pipeline created', { + 'aria-live': 'assertive', + role: 'alert', + }); expect(PipelinesLogic.actions.setPipelineState).toHaveBeenCalledWith({ ...PipelinesLogic.values.pipelineState, name: connectorIndex.name, diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.test.ts index ced4a7c5004b5..5598510567684 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.test.ts @@ -91,7 +91,10 @@ describe('CreateApiLogic', () => { const { mount: messageMount } = messageLogic; messageMount(); messageLogic.actions.apiSuccess({}); - expect(flashSuccessToast).toHaveBeenCalledWith('test message'); + expect(flashSuccessToast).toHaveBeenCalledWith('test message', { + 'aria-live': 'assertive', + role: 'alert', + }); }); }); describe('apiError', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.ts index 65e0b5f052e33..a32f479dcda82 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/api_logic/create_api_logic.ts @@ -59,7 +59,10 @@ export const createApiLogic = ( }, apiSuccess: (result) => { if (options.showSuccessFlashFn) { - flashSuccessToast(options.showSuccessFlashFn(result)); + flashSuccessToast(options.showSuccessFlashFn(result), { + 'aria-live': 'assertive', + role: 'alert', + }); } }, makeRequest: async (args, breakpoint) => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts index d7cea1fe1b26d..6c7012bb1a061 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts @@ -103,9 +103,18 @@ describe('toastAPIErrors', () => { it('converts API errors into flash messages', () => { toastAPIErrors(mockHttpError); - expect(flashErrorToast).toHaveBeenNthCalledWith(1, 'Could not find X'); - expect(flashErrorToast).toHaveBeenNthCalledWith(2, 'Could not find Y'); - expect(flashErrorToast).toHaveBeenNthCalledWith(3, 'Something else bad happened'); + expect(flashErrorToast).toHaveBeenNthCalledWith(1, 'Could not find X', { + 'aria-live': 'assertive', + role: 'alert', + }); + expect(flashErrorToast).toHaveBeenNthCalledWith(2, 'Could not find Y', { + 'aria-live': 'assertive', + role: 'alert', + }); + expect(flashErrorToast).toHaveBeenNthCalledWith(3, 'Something else bad happened', { + 'aria-live': 'assertive', + role: 'alert', + }); }); it('falls back to the basic message for http responses without an errors array', () => { @@ -117,7 +126,10 @@ describe('toastAPIErrors', () => { }, } as any); - expect(flashErrorToast).toHaveBeenCalledWith('Not Found'); + expect(flashErrorToast).toHaveBeenCalledWith('Not Found', { + 'aria-live': 'assertive', + role: 'alert', + }); }); it('displays a generic error message and re-throws non-API errors', () => { @@ -127,7 +139,10 @@ describe('toastAPIErrors', () => { toastAPIErrors(error as any); }).toThrowError(error); - expect(flashErrorToast).toHaveBeenCalledWith(expect.any(String)); + expect(flashErrorToast).toHaveBeenCalledWith(expect.any(String), { + 'aria-live': 'assertive', + role: 'alert', + }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts index 9e74d90605dc0..e08178f730d27 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts @@ -74,7 +74,10 @@ export const toastAPIErrors = (response: HttpResponse) => { const messages = getErrorsFromHttpResponse(response); for (const message of messages) { - flashErrorToast(message); + flashErrorToast(message, { + 'aria-live': 'assertive', + role: 'alert', + }); } // If this was a programming error or a failed request (such as a CORS) error, // we rethrow the error so it shows up in the developer console diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts index 47040fb76cbc4..48a883e8ed28c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts @@ -19,7 +19,9 @@ export interface IFlashMessage { // @see EuiGlobalToastListToast for more props export interface ToastOptions { + 'aria-live'?: 'assertive' | 'polite'; // Defaults to 'polite' iconType?: string; + role?: string; // Defaults to the log role. The alert role can be considered only if all toasts in this list will require immediate user attention. text?: string; // Additional text below the message/title, same as EuiToast['text'] toastLifeTimeMs?: number; // Allows customizing per-toast timeout } diff --git a/x-pack/plugins/enterprise_search/server/integrations.ts b/x-pack/plugins/enterprise_search/server/integrations.ts index 2918ef862dbdf..2a581396a63fb 100644 --- a/x-pack/plugins/enterprise_search/server/integrations.ts +++ b/x-pack/plugins/enterprise_search/server/integrations.ts @@ -21,7 +21,7 @@ export const registerEnterpriseSearchIntegrations = ( customIntegrations.registerCustomIntegration({ id: 'web_crawler', title: i18n.translate('xpack.enterpriseSearch.integrations.webCrawlerName', { - defaultMessage: 'Web crawler', + defaultMessage: 'Web Crawler', }), description: i18n.translate('xpack.enterpriseSearch.integrations.webCrawlerDescription', { defaultMessage: 'Add search to your website with the web crawler.', diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx index acb65de2a9a16..ce35d0d5781ce 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx @@ -17,6 +17,7 @@ import { EuiPopover, EuiPopoverFooter, EuiPopoverTitle, + EuiLoadingSpinner, EuiText, useEuiPaddingCSS, } from '@elastic/eui'; @@ -58,13 +59,14 @@ export const DataViewSelectPopover: React.FunctionComponent { + const [loadingDataViews, setLoadingDataViews] = useState(false); const [dataViewItems, setDataViewsItems] = useState([]); const [dataViewPopoverOpen, setDataViewPopoverOpen] = useState(false); const closeDataViewEditor = useRef<() => void | undefined>(); const allDataViewItems = useMemo( - () => [...dataViewItems, ...metadata.adHocDataViewList.map(toDataViewListItem)], + () => [...(dataViewItems ?? []), ...metadata.adHocDataViewList.map(toDataViewListItem)], [dataViewItems, metadata.adHocDataViewList] ); @@ -80,10 +82,16 @@ export const DataViewSelectPopover: React.FunctionComponent { - const ids = await dataViews.getIds(); - const dataViewsList = await Promise.all(ids.map((id) => dataViews.get(id))); - - setDataViewsItems(dataViewsList.map(toDataViewListItem)); + setLoadingDataViews(true); + try { + // Calling getIds with refresh = true to make sure we don't get stale data + const ids = await dataViews.getIds(true); + const dataViewsList = await Promise.all(ids.map((id) => dataViews.get(id))); + setDataViewsItems(dataViewsList.map(toDataViewListItem)); + } catch (e) { + // Error fetching data views + } + setLoadingDataViews(false); }, [dataViews]); const onAddAdHocDataView = useCallback( @@ -146,8 +154,10 @@ export const DataViewSelectPopover: React.FunctionComponent; } return ( diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/ai_assistant/conversations.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/ai_assistant/conversations.cy.ts index 4d87cce1fdaa8..a97fa8ab9f6e3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/ai_assistant/conversations.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/ai_assistant/conversations.cy.ts @@ -47,7 +47,8 @@ import { } from '../../screens/ai_assistant'; import { visit, visitGetStartedPage } from '../../tasks/navigation'; -describe('AI Assistant Conversations', { tags: ['@ess', '@serverless'] }, () => { +// Failing: See https://github.com/elastic/kibana/issues/204167 +describe.skip('AI Assistant Conversations', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { deleteConnectors(); deleteConversations();