From 786878d54dc8847ffc3906f3de2edba989f4c2cc Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Thu, 22 Jun 2023 17:01:42 +0200 Subject: [PATCH 1/7] Delete riskyHostsEnabled and riskyUsersEnabled experimental flags (#159299) ## Summary Delete `riskyHostsEnabled` and `riskyUsersEnabled` flags. Follow up on this change https://github.com/elastic/kibana/pull/158969 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../security_solution/common/experimental_features.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index dd00c9b3ab190..35e7ef3225e37 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -86,16 +86,6 @@ export const allowedExperimentalValues = Object.freeze({ */ assistantEnabled: false, - /** - * Keep DEPRECATED experimental flags that are documented to prevent failed upgrades. - * https://www.elastic.co/guide/en/security/current/user-risk-score.html - * https://www.elastic.co/guide/en/security/current/host-risk-score.html - * - * Issue: https://github.com/elastic/kibana/issues/146777 - */ - riskyHostsEnabled: false, // DEPRECATED - riskyUsersEnabled: false, // DEPRECATED - /* * Enables new Set of filters on the Alerts page. * From 79ff903f1448a73d5240501659e79416465538c4 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Thu, 22 Jun 2023 11:05:18 -0400 Subject: [PATCH 2/7] [Response Ops][Task Manager] Emitting background task utilization value even when polling fails (#160193) Resolves https://github.com/elastic/kibana/issues/160183 ## Summary This fixes a bug where no worker utilization value would be emitted if the task manager failed to poll for work. ### Checklist - [x] [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 --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/polling_lifecycle.test.ts | 91 ++++++++++++++++++- .../task_manager/server/polling_lifecycle.ts | 5 + 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts index 10c377cc8e894..fc72c950a4034 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.test.ts @@ -8,7 +8,7 @@ import sinon from 'sinon'; import { Observable, of, Subject } from 'rxjs'; -import { TaskPollingLifecycle, claimAvailableTasks } from './polling_lifecycle'; +import { TaskPollingLifecycle, claimAvailableTasks, TaskLifecycleEvent } from './polling_lifecycle'; import { createInitialMiddleware } from './lib/middleware'; import { TaskTypeDictionary } from './task_type_dictionary'; import { taskStoreMock } from './task_store.mock'; @@ -281,6 +281,65 @@ describe('TaskPollingLifecycle', () => { ); }); }); + + describe('workerUtilization events', () => { + test('should emit event when polling is successful', async () => { + clock.restore(); + mockTaskClaiming.claimAvailableTasksIfCapacityIsAvailable.mockImplementation(() => + of( + asOk({ + docs: [], + stats: { tasksUpdated: 0, tasksConflicted: 0, tasksClaimed: 0, tasksRejected: 0 }, + }) + ) + ); + const elasticsearchAndSOAvailability$ = new Subject(); + const taskPollingLifecycle = new TaskPollingLifecycle({ + ...taskManagerOpts, + elasticsearchAndSOAvailability$, + }); + + const emittedEvents: TaskLifecycleEvent[] = []; + + taskPollingLifecycle.events.subscribe((event: TaskLifecycleEvent) => + emittedEvents.push(event) + ); + + elasticsearchAndSOAvailability$.next(true); + expect(mockTaskClaiming.claimAvailableTasksIfCapacityIsAvailable).toHaveBeenCalled(); + await retryUntil('workerUtilizationEvent emitted', () => { + return !!emittedEvents.find( + (event: TaskLifecycleEvent) => event.id === 'workerUtilization' + ); + }); + }); + + test('should emit event when polling error occurs', async () => { + clock.restore(); + mockTaskClaiming.claimAvailableTasksIfCapacityIsAvailable.mockImplementation(() => { + throw new Error('booo'); + }); + const elasticsearchAndSOAvailability$ = new Subject(); + const taskPollingLifecycle = new TaskPollingLifecycle({ + ...taskManagerOpts, + elasticsearchAndSOAvailability$, + }); + + const emittedEvents: TaskLifecycleEvent[] = []; + + taskPollingLifecycle.events.subscribe((event: TaskLifecycleEvent) => + emittedEvents.push(event) + ); + + elasticsearchAndSOAvailability$.next(true); + expect(mockTaskClaiming.claimAvailableTasksIfCapacityIsAvailable).toHaveBeenCalled(); + await retryUntil('workerUtilizationEvent emitted', () => { + return !!emittedEvents.find( + (event: TaskLifecycleEvent) => event.id === 'workerUtilization' + ); + }); + }); + }); }); function getFirstAsPromise(obs$: Observable): Promise { @@ -288,3 +347,33 @@ function getFirstAsPromise(obs$: Observable): Promise { obs$.subscribe(resolve, reject); }); } + +type RetryableFunction = () => boolean; + +const RETRY_UNTIL_DEFAULT_COUNT = 20; +const RETRY_UNTIL_DEFAULT_WAIT = 1000; // milliseconds + +async function retryUntil( + label: string, + fn: RetryableFunction, + count: number = RETRY_UNTIL_DEFAULT_COUNT, + wait: number = RETRY_UNTIL_DEFAULT_WAIT +): Promise { + while (count > 0) { + count--; + + if (fn()) return true; + + // eslint-disable-next-line no-console + console.log(`attempt failed waiting for "${label}", attempts left: ${count}`); + + if (count === 0) return false; + await delay(wait); + } + + return false; +} + +async function delay(millis: number) { + await new Promise((resolve) => setTimeout(resolve, millis)); +} diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.ts index c60a8af2c9208..fff01563b3921 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.ts @@ -266,6 +266,10 @@ export class TaskPollingLifecycle { ); } this.logger.error(error.message); + + // Emit event indicating task manager utilization % at the end of a polling cycle + // Because there was a polling error, no tasks were claimed so this represents the number of workers busy + this.emitEvent(asTaskManagerStatEvent('workerUtilization', asOk(this.pool.workerLoad))); }) ) ) @@ -273,6 +277,7 @@ export class TaskPollingLifecycle { tap( mapOk(() => { // Emit event indicating task manager utilization % at the end of a polling cycle + // This represents the number of workers busy + number of tasks claimed in this cycle this.emitEvent(asTaskManagerStatEvent('workerUtilization', asOk(this.pool.workerLoad))); }) ) From 83acb13f72f508c932001e88eb98c95ec8585a61 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Thu, 22 Jun 2023 17:35:39 +0200 Subject: [PATCH 3/7] [Defend Workflows] Fix Osquery response action bug (#160258) --- .../rule_response_actions/response_actions_form.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_form.tsx index 8bbc5af0d15bf..de7afecf97f74 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/response_actions_form.tsx @@ -9,17 +9,12 @@ import React, { useEffect, useMemo, useState } from 'react'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { map, reduce, upperFirst } from 'lodash'; import ReactMarkdown from 'react-markdown'; -import { css } from '@emotion/react'; import { ResponseActionsWrapper } from './response_actions_wrapper'; import { FORM_ERRORS_TITLE } from '../../detections/components/rules/rule_actions_field/translations'; import { ResponseActionsHeader } from './response_actions_header'; import type { ArrayItem, FormHook } from '../../shared_imports'; import { useSupportedResponseActionTypes } from './use_supported_response_action_types'; -const FieldErrorsContainer = css` - margin-bottom: 0; -`; - interface ResponseActionsFormProps { items: ArrayItem[]; addItem: () => void; @@ -92,7 +87,7 @@ export const ResponseActionsForm = ({ {uiFieldErrors?.length ? ( <> -

+

Date: Thu, 22 Jun 2023 17:38:52 +0200 Subject: [PATCH 4/7] [AO] Fix EuiButtonIcon requires aria-label or aria-labelledby warning in the observability plugin (#160262) Fixes #160161 ## Summary This PR fixes EuiButtonIcon requires aria-label or aria-labelledby warning in the observability plugin Screenshot 2023-06-21 at 17 35 26 --- .../custom_equation/metric_row_controls.tsx | 1 + .../pages/alerts/components/alert_actions.tsx | 9 +-------- .../pages/slos/components/slo_list_item.tsx | 16 +++++++++------- .../plugins/translations/translations/fr-FR.json | 8 ++++---- .../plugins/translations/translations/ja-JP.json | 8 ++++---- .../plugins/translations/translations/zh-CN.json | 8 ++++---- 6 files changed, 23 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/observability/public/components/threshold/components/custom_equation/metric_row_controls.tsx b/x-pack/plugins/observability/public/components/threshold/components/custom_equation/metric_row_controls.tsx index 9cc103c591118..7533e23640ece 100644 --- a/x-pack/plugins/observability/public/components/threshold/components/custom_equation/metric_row_controls.tsx +++ b/x-pack/plugins/observability/public/components/threshold/components/custom_equation/metric_row_controls.tsx @@ -18,6 +18,7 @@ export function MetricRowControls({ onDelete, disableDelete }: MetricRowControlP <> {/* Hide the View In App for the Threshold alerts, temporarily https://github.com/elastic/kibana/pull/159915 */} {alert.fields[ALERT_RULE_TYPE_ID] === OBSERVABILITY_THRESHOLD_RULE_TYPE_ID ? ( - - - + ) : ( - {i18n.translate('xpack.observability.slo.slo.item.actions.details', { + {i18n.translate('xpack.observability.slo.item.actions.details', { defaultMessage: 'Details', })} , @@ -213,7 +215,7 @@ export function SloListItem({ onClick={handleEdit} data-test-subj="sloActionsEdit" > - {i18n.translate('xpack.observability.slo.slo.item.actions.edit', { + {i18n.translate('xpack.observability.slo.item.actions.edit', { defaultMessage: 'Edit', })} , @@ -224,7 +226,7 @@ export function SloListItem({ onClick={handleCreateRule} data-test-subj="sloActionsCreateRule" > - {i18n.translate('xpack.observability.slo.slo.item.actions.createRule', { + {i18n.translate('xpack.observability.slo.item.actions.createRule', { defaultMessage: 'Create new alert rule', })} , @@ -235,7 +237,7 @@ export function SloListItem({ onClick={handleNavigateToRules} data-test-subj="sloActionsManageRules" > - {i18n.translate('xpack.observability.slo.slo.item.actions.manageRules', { + {i18n.translate('xpack.observability.slo.item.actions.manageRules', { defaultMessage: 'Manage rules', })} , @@ -246,7 +248,7 @@ export function SloListItem({ onClick={handleClone} data-test-subj="sloActionsClone" > - {i18n.translate('xpack.observability.slo.slo.item.actions.clone', { + {i18n.translate('xpack.observability.slo.item.actions.clone', { defaultMessage: 'Clone', })} , @@ -257,7 +259,7 @@ export function SloListItem({ onClick={handleDelete} data-test-subj="sloActionsDelete" > - {i18n.translate('xpack.observability.slo.slo.item.actions.delete', { + {i18n.translate('xpack.observability.slo.item.actions.delete', { defaultMessage: 'Delete', })} , diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index f04a532c2d1e2..68a9564738668 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -26886,11 +26886,11 @@ "xpack.observability.slo.slo.deleteConfirmationModal.cancelButtonLabel": "Annuler", "xpack.observability.slo.slo.deleteConfirmationModal.title": "Voulez-vous vraiment continuer ?", "xpack.observability.slo.slo.item.actions.clone": "Cloner", - "xpack.observability.slo.slo.item.actions.createRule": "Créer une règle d'alerte", + "xpack.observability.slo.item.actions.createRule": "Créer une règle d'alerte", "xpack.observability.slo.slo.item.actions.delete": "Supprimer", - "xpack.observability.slo.slo.item.actions.details": "Détails", - "xpack.observability.slo.slo.item.actions.edit": "Modifier", - "xpack.observability.slo.slo.item.actions.manageRules": "Gérer les règles", + "xpack.observability.slo.item.actions.details": "Détails", + "xpack.observability.slo.item.actions.edit": "Modifier", + "xpack.observability.slo.item.actions.manageRules": "Gérer les règles", "xpack.observability.slo.slo.rulesBadge.popover": "Il n'y a pas encore de règles configurées pour ce SLO. Vous ne recevrez pas d'alertes lorsque le SLO est dépassé.", "xpack.observability.slo.slo.stats.budgetRemaining": "Budget restant", "xpack.observability.slo.sloDetails.errorBudgetChartPanel.chartTitle": "Budget d'erreur restant", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 0f631ccb8cfe6..d687bd4a18601 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -26868,11 +26868,11 @@ "xpack.observability.slo.slo.deleteConfirmationModal.cancelButtonLabel": "キャンセル", "xpack.observability.slo.slo.deleteConfirmationModal.title": "よろしいですか?", "xpack.observability.slo.slo.item.actions.clone": "クローンを作成", - "xpack.observability.slo.slo.item.actions.createRule": "新しいアラートルールを作成", + "xpack.observability.slo.item.actions.createRule": "新しいアラートルールを作成", "xpack.observability.slo.slo.item.actions.delete": "削除", - "xpack.observability.slo.slo.item.actions.details": "詳細", - "xpack.observability.slo.slo.item.actions.edit": "編集", - "xpack.observability.slo.slo.item.actions.manageRules": "ルールの管理", + "xpack.observability.slo.item.actions.details": "詳細", + "xpack.observability.slo.item.actions.edit": "編集", + "xpack.observability.slo.item.actions.manageRules": "ルールの管理", "xpack.observability.slo.slo.rulesBadge.popover": "このSLOではまだルールが構成されていません。SLOに違反したときにアラートを受信しません。", "xpack.observability.slo.slo.stats.budgetRemaining": "残り予算", "xpack.observability.slo.sloDetails.errorBudgetChartPanel.chartTitle": "残り予算エラー", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 8423874588000..7f3aba79a5bc0 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -26866,11 +26866,11 @@ "xpack.observability.slo.slo.deleteConfirmationModal.cancelButtonLabel": "取消", "xpack.observability.slo.slo.deleteConfirmationModal.title": "是否确定?", "xpack.observability.slo.slo.item.actions.clone": "克隆", - "xpack.observability.slo.slo.item.actions.createRule": "创建新告警规则", + "xpack.observability.slo.item.actions.createRule": "创建新告警规则", "xpack.observability.slo.slo.item.actions.delete": "删除", - "xpack.observability.slo.slo.item.actions.details": "详情", - "xpack.observability.slo.slo.item.actions.edit": "编辑", - "xpack.observability.slo.slo.item.actions.manageRules": "管理规则", + "xpack.observability.slo.item.actions.details": "详情", + "xpack.observability.slo.item.actions.edit": "编辑", + "xpack.observability.slo.item.actions.manageRules": "管理规则", "xpack.observability.slo.slo.rulesBadge.popover": "尚未为此 SLO 配置任何规则。超出 SLO 时,您不会收到告警。", "xpack.observability.slo.slo.stats.budgetRemaining": "剩余预算", "xpack.observability.slo.sloDetails.errorBudgetChartPanel.chartTitle": "剩余错误预算", From af96431880819060a94540ca30d47b0ed2c5a4ce Mon Sep 17 00:00:00 2001 From: Lukas Olson Date: Thu, 22 Jun 2023 08:42:03 -0700 Subject: [PATCH 5/7] Fix theming for search sessions management (#160182) ## Summary Fixes https://github.com/elastic/kibana/issues/159155. Fixes https://github.com/elastic/kibana/issues/159156. Applies the current theme (dark/light) to the search sessions management table & its components. Before: ![image](https://github.com/elastic/kibana/assets/1178348/ac58d9fe-0e54-43b3-af6e-87e44f3eee2a) After: ![image](https://github.com/elastic/kibana/assets/1178348/86414f6a-dbd4-4d2d-b6a3-cccc125936c9) --- .../public/search/session/sessions_mgmt/components/main.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/data/public/search/session/sessions_mgmt/components/main.tsx b/src/plugins/data/public/search/session/sessions_mgmt/components/main.tsx index 424ec701f79ad..78da4972b49d4 100644 --- a/src/plugins/data/public/search/session/sessions_mgmt/components/main.tsx +++ b/src/plugins/data/public/search/session/sessions_mgmt/components/main.tsx @@ -10,6 +10,7 @@ import { EuiButtonEmpty, EuiPageHeader, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import type { CoreStart, HttpStart } from '@kbn/core/public'; import React from 'react'; +import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import type { SearchSessionsMgmtAPI } from '../lib/api'; import type { AsyncSearchIntroDocumentation } from '../lib/documentation'; import { SearchSessionsMgmtTable } from './table'; @@ -29,7 +30,7 @@ interface Props { export function SearchSessionsMgmtMain({ documentation, ...tableProps }: Props) { return ( - <> + - + ); } From ff4b55a78b20bf8f498fff8bae797761de9322e3 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Thu, 22 Jun 2023 10:46:32 -0500 Subject: [PATCH 6/7] [Enterprise Search] refactor: rename engines to search applications (Frontend) (#159629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Dear Reviewer... I'm sorry 😬 This PR goes through the entire frontend for search applications and replaces usage of "engine" to search application. This include file & folder names, components, translation ids and telemetry ids. Which turns out to be a lot of changes. There are a lot of commits because I need to rename the files in single commits for git to recognize the change as a rename and not and delete+add. Some of the initial changes where committed as delete+add before I got the hang of this. While I was making these changes and needed to update translation ids, I also updated the translation id paths to replace `xpack.enterpriseSearch.content` usage in the search applications folder with `xpack.enterpriseSearch.searchApplications`. I tried my best to run unit test and manual testing as I made changes and do regression along the way. --- .../api/engines/delete_engines_api_logic.ts | 44 --- ...tch_engine_field_capabilities_api_logic.ts | 34 -- ...eate_search_application_api_logic.test.ts} | 14 +- .../create_search_application_api_logic.ts} | 31 +- ...lete_search_application_api_logic.test.ts} | 10 +- .../delete_search_application_api_logic.ts | 47 +++ .../fetch_indices_api_logic.ts | 16 +- ...etch_search_application_api_logic.test.ts} | 10 +- .../fetch_search_application_api_logic.ts} | 24 +- ...tion_field_capabilities_api_logic.test.ts} | 8 +- ...pplication_field_capabilities_api_logic.ts | 35 ++ ...tch_search_applications_api_logic.test.ts} | 14 +- .../fetch_search_applications_api_logic.ts} | 11 +- ..._search_application_api_key_logic.test.ts} | 10 +- ...erate_search_application_api_key_logic.ts} | 14 +- ...date_search_application_api_logic.test.ts} | 14 +- .../update_search_application_api_logic.ts} | 26 +- .../engine/engine_indices_logic.test.ts | 119 ------ .../components/engine/engine_indices_logic.ts | 86 ----- .../components/engine/engine_name_logic.ts | 36 -- .../components/engine/engine_router.tsx | 52 --- .../engine_search_preview_logic.ts | 98 ----- .../components/engine/engine_view.tsx | 121 ------- .../engine/engine_view_logic.test.ts | 62 ---- .../components/engine/engine_view_logic.ts | 117 ------ .../engines/create_engine_logic.test.ts | 155 -------- .../components/engines/create_engine_logic.ts | 118 ------ .../engines/engines_list_flyout_logic.test.ts | 111 ------ .../engines/engines_list_flyout_logic.ts | 73 ---- .../components/engines/engines_router.tsx | 37 -- ...es_page_template.tsx => page_template.tsx} | 20 +- .../applications/components/not_found.tsx | 9 +- .../add_indices_flyout.tsx | 27 +- .../add_indices_logic.test.ts | 24 +- .../add_indices_logic.ts | 31 +- ...h_application_api_key_modal.logic.test.ts} | 17 +- ...search_application_api_key_modal.logic.ts} | 10 +- ...search_application_api_key_modal.test.tsx} | 45 ++- ...rate_search_application_api_key_modal.tsx} | 45 ++- .../connect}/search_application_api.tsx | 58 +-- .../search_application_api_integration.tsx} | 43 ++- .../connect/search_application_api_logic.ts} | 27 +- .../connect/search_application_connect.tsx} | 48 +-- .../search_application_documentation.tsx | 24 +- .../field_icon.tsx | 0 .../header_docs_action.tsx | 15 +- .../search_application_content.tsx | 79 ++-- .../search_application_error.test.tsx} | 8 +- .../search_application_error.tsx} | 8 +- .../search_application_indices.tsx} | 84 +++-- .../search_application_indices_logic.test.ts | 138 +++++++ .../search_application_indices_logic.ts | 93 +++++ .../search_application_layout.scss | 0 .../search_application_name_logic.ts | 40 +++ .../search_application_router.tsx | 58 +++ .../search_application_schema.tsx} | 80 +++-- .../search_application_view.tsx | 126 +++++++ .../search_application_view_logic.test.ts | 70 ++++ .../search_application_view_logic.ts | 130 +++++++ .../search_preview}/api_call_flyout.tsx | 20 +- .../search_preview}/convert_results.test.ts | 0 .../search_preview}/convert_results.ts | 0 .../search_preview}/document_context.test.tsx | 0 .../search_preview}/document_context.tsx | 0 .../search_preview}/document_flyout.tsx | 12 +- .../search_preview}/field_value_cell.tsx | 0 .../search_preview/search_preview.tsx} | 109 +++--- .../search_preview/search_preview_logic.ts | 98 +++++ .../search_preview}/search_ui_components.tsx | 36 +- ...empty_search_applications_prompt.test.tsx} | 8 +- .../empty_search_applications_prompt.tsx} | 6 +- .../components/indices_select_combobox.tsx | 8 +- .../tables/search_applications_table.tsx} | 68 ++-- .../create_search_application_flyout.tsx} | 78 ++-- .../create_search_application_logic.test.ts | 168 +++++++++ .../create_search_application_logic.ts | 122 +++++++ .../delete_search_application_modal.tsx} | 32 +- .../search_application_indices_flyout.tsx} | 66 ++-- ...h_application_indices_flyout_logic.test.ts | 114 ++++++ ...search_application_indices_flyout_logic.ts | 78 ++++ .../search_applications_list.test.tsx} | 86 +++-- .../search_applications_list.tsx} | 118 +++--- .../search_applications_list_logic.test.ts} | 340 +++++++++--------- .../search_applications_list_logic.ts} | 111 +++--- .../search_applications_router.tsx | 41 +++ .../{engines => search_applications}/types.ts | 0 .../applications/applications/index.tsx | 10 +- .../applications/applications/routes.ts | 14 +- .../layout/engines_page_template.tsx | 41 --- .../create_engine_menu_item.tsx | 6 +- .../header_actions/search_engines_popover.tsx | 4 +- .../convert_connector_modal.tsx | 6 +- .../kibana_chrome/generate_breadcrumbs.ts | 2 +- .../shared/kibana_chrome/index.ts | 2 +- .../shared/kibana_chrome/set_chrome.tsx | 6 +- .../applications/shared/layout/index.ts | 2 +- .../applications/shared/layout/nav.test.tsx | 18 +- .../public/applications/shared/layout/nav.tsx | 43 +-- .../translations/translations/fr-FR.json | 245 +++++++------ .../translations/translations/ja-JP.json | 245 +++++++------ .../translations/translations/zh-CN.json | 245 +++++++------ 101 files changed, 2867 insertions(+), 2645 deletions(-) delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/create_engine_api_logic.test.ts => search_applications/create_search_application_api_logic.test.ts} (63%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/create_engine_api_logic.ts => search_applications/create_search_application_api_logic.ts} (51%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/delete_engines_api_logic.test.ts => search_applications/delete_search_application_api_logic.test.ts} (67%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines => search_applications}/fetch_indices_api_logic.ts (72%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/fetch_engine_api_logic.test.ts => search_applications/fetch_search_application_api_logic.test.ts} (69%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/fetch_engine_api_logic.ts => search_applications/fetch_search_application_api_logic.ts} (52%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/fetch_engine_field_capabilities_api_logic.test.ts => search_applications/fetch_search_application_field_capabilities_api_logic.test.ts} (72%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/fetch_engines_api_logic.test.ts => search_applications/fetch_search_applications_api_logic.test.ts} (77%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/fetch_engines_api_logic.ts => search_applications/fetch_search_applications_api_logic.ts} (74%) rename x-pack/plugins/enterprise_search/public/applications/{enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.test.ts => applications/api/search_applications/generate_search_application_api_key_logic.test.ts} (80%) rename x-pack/plugins/enterprise_search/public/applications/{enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.ts => applications/api/search_applications/generate_search_application_api_key_logic.ts} (71%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/update_engine_api_logic.test.ts => search_applications/update_search_application_api_logic.test.ts} (62%) rename x-pack/plugins/enterprise_search/public/applications/applications/api/{engines/update_engine_api_logic.ts => search_applications/update_search_application_api_logic.ts} (51%) delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_name_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_router.tsx delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view.tsx delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.test.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.ts delete mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_router.tsx rename x-pack/plugins/enterprise_search/public/applications/applications/components/layout/{engines_page_template.tsx => page_template.tsx} (65%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/add_indices_flyout.tsx (73%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/add_indices_logic.test.ts (74%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/add_indices_logic.ts (52%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.test.ts => search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.test.ts} (85%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.ts => search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.ts} (73%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.test.tsx => search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.test.tsx} (68%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.tsx => search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.tsx} (78%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect => search_application/connect}/search_application_api.tsx (72%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/engine_api_integration.tsx => search_application/connect/search_application_api_integration.tsx} (78%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/engine_api_logic.ts => search_application/connect/search_application_api_logic.ts} (54%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect/engine_connect.tsx => search_application/connect/search_application_connect.tsx} (67%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_connect => search_application/connect}/search_application_documentation.tsx (82%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/field_icon.tsx (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/header_docs_action.tsx (60%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/search_application_content.tsx (62%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_error.test.tsx => search_application/search_application_error.test.tsx} (88%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_error.tsx => search_application/search_application_error.tsx} (80%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_indices.tsx => search_application/search_application_indices.tsx} (72%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine => search_application}/search_application_layout.scss (100%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_name_logic.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_router.tsx rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_schema.tsx => search_application/search_application_schema.tsx} (82%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/api_call_flyout.tsx (75%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/convert_results.test.ts (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/convert_results.ts (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/document_context.test.tsx (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/document_context.tsx (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/document_flyout.tsx (82%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/field_value_cell.tsx (100%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview/engine_search_preview.tsx => search_application/search_preview/search_preview.tsx} (75%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engine/engine_search_preview => search_application/search_preview}/search_ui_components.tsx (81%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/components/empty_engines_prompt.test.tsx => search_applications/components/empty_search_applications_prompt.test.tsx} (69%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/components/empty_engines_prompt.tsx => search_applications/components/empty_search_applications_prompt.tsx} (77%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines => search_applications}/components/indices_select_combobox.tsx (88%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/components/tables/engines_table.tsx => search_applications/components/tables/search_applications_table.tsx} (62%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/create_engine_flyout.tsx => search_applications/create_search_application_flyout.tsx} (68%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/delete_engine_modal.tsx => search_applications/delete_search_application_modal.tsx} (56%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/engines_list_flyout.tsx => search_applications/search_application_indices_flyout.tsx} (60%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.test.ts create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.ts rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/engines_list.test.tsx => search_applications/search_applications_list.test.tsx} (53%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/engines_list.tsx => search_applications/search_applications_list.tsx} (62%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/engines_list_logic.test.ts => search_applications/search_applications_list_logic.test.ts} (59%) rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines/engines_list_logic.ts => search_applications/search_applications_list_logic.ts} (50%) create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_router.tsx rename x-pack/plugins/enterprise_search/public/applications/applications/components/{engines => search_applications}/types.ts (100%) delete mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/engines_page_template.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.ts deleted file mode 100644 index 836055321bb0d..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 { i18n } from '@kbn/i18n'; - -import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; -import { HttpLogic } from '../../../shared/http'; - -export interface DeleteEnginesApiLogicArguments { - engineName: string; -} -export interface DeleteEnginesApiLogicResponse { - engineName: string; -} - -export const deleteEngine = async ({ - engineName, -}: DeleteEnginesApiLogicArguments): Promise => { - const route = `/internal/enterprise_search/search_applications/${engineName}`; - await HttpLogic.values.http.delete(route); - return { engineName }; -}; -export const DeleteEngineAPILogic = createApiLogic( - ['content', 'delete_engine_api_logic'], - deleteEngine, - { - showSuccessFlashFn: ({ engineName }) => - i18n.translate('xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title', { - defaultMessage: '{engineName} has been deleted', - values: { - engineName, - }, - }), - } -); - -export type DeleteEnginesApiLogicActions = Actions< - DeleteEnginesApiLogicArguments, - DeleteEnginesApiLogicResponse ->; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.ts deleted file mode 100644 index 1ca2121b683b8..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 { EnterpriseSearchApplicationFieldCapabilities } from '../../../../../common/types/search_applications'; -import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; -import { HttpLogic } from '../../../shared/http'; - -export interface FetchEngineFieldCapabilitiesApiParams { - engineName: string; -} - -export type FetchEngineFieldCapabilitiesApiResponse = EnterpriseSearchApplicationFieldCapabilities; - -export const fetchEngineFieldCapabilities = async ({ - engineName, -}: FetchEngineFieldCapabilitiesApiParams): Promise => { - const route = `/internal/enterprise_search/search_applications/${engineName}/field_capabilities`; - - return await HttpLogic.values.http.get(route); -}; - -export const FetchEngineFieldCapabilitiesApiLogic = createApiLogic( - ['fetch_engine_field_capabilities_api_logic'], - fetchEngineFieldCapabilities -); - -export type FetchEngineFieldCapabilitiesApiLogicActions = Actions< - FetchEngineFieldCapabilitiesApiParams, - FetchEngineFieldCapabilitiesApiResponse ->; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.test.ts similarity index 63% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.test.ts index 098911454c050..560e2e2827a2b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.test.ts @@ -9,25 +9,25 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { createEngine } from './create_engine_api_logic'; +import { createSearchApplication } from './create_search_application_api_logic'; -describe('CreateEngineApiLogic', () => { +describe('CreateSearchApplicationApiLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('createEngine', () => { + describe('createSearchApplication', () => { it('calls correct api', async () => { - const engine = { engineName: 'my-engine', indices: ['an-index'] }; + const searchApplication = { indices: ['an-index'], name: 'my-search-application' }; const response = { result: 'created' }; const promise = Promise.resolve(response); http.put.mockReturnValue(promise); - const result = createEngine(engine); + const result = createSearchApplication(searchApplication); await nextTick(); expect(http.put).toHaveBeenCalledWith( - '/internal/enterprise_search/search_applications/my-engine', + '/internal/enterprise_search/search_applications/my-search-application', { - body: '{"indices":["an-index"],"name":"my-engine"}', + body: '{"indices":["an-index"],"name":"my-search-application"}', query: { create: true }, } ); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.ts similarity index 51% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.ts index b4a2a1eb904fd..daa51e04eadb7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/create_engine_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/create_search_application_api_logic.ts @@ -9,27 +9,34 @@ import { EnterpriseSearchApplicationUpsertResponse } from '../../../../../common import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; import { HttpLogic } from '../../../shared/http'; -export interface CreateEngineApiParams { - engineName: string; +export interface CreateSearchApplicationApiParams { indices: string[]; + name: string; } -export type CreateEngineApiResponse = EnterpriseSearchApplicationUpsertResponse; +export type CreateSearchApplicationApiResponse = EnterpriseSearchApplicationUpsertResponse; -export type CreateEngineApiLogicActions = Actions; +export type CreateSearchApplicationApiLogicActions = Actions< + CreateSearchApplicationApiParams, + CreateSearchApplicationApiResponse +>; -export const createEngine = async ({ - engineName, +export const createSearchApplication = async ({ + name, indices, -}: CreateEngineApiParams): Promise => { - const route = `/internal/enterprise_search/search_applications/${engineName}`; +}: CreateSearchApplicationApiParams): Promise => { + const route = `/internal/enterprise_search/search_applications/${name}`; return await HttpLogic.values.http.put(route, { - body: JSON.stringify({ indices, name: engineName }), + body: JSON.stringify({ indices, name }), query: { create: true }, }); }; -export const CreateEngineApiLogic = createApiLogic(['create_engine_api_logic'], createEngine, { - showErrorFlash: false, -}); +export const CreateSearchApplicationApiLogic = createApiLogic( + ['search_applications', 'create_search_application_api_logic'], + createSearchApplication, + { + showErrorFlash: false, + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.test.ts similarity index 67% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.test.ts index 665ae9eaa279e..becf40f0b0e3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/delete_engines_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.test.ts @@ -9,21 +9,21 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { deleteEngine } from './delete_engines_api_logic'; +import { deleteSearchApplication } from './delete_search_application_api_logic'; -describe('deleteEngineApiLogic', () => { +describe('DeleteSearchApplicationAPILogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('deleteEngine', () => { + describe('deleteSearchApplication', () => { it('calls correct api', async () => { const promise = Promise.resolve(); http.post.mockReturnValue(promise); - const result = deleteEngine({ engineName: 'deleteEngineName' }); + const result = deleteSearchApplication({ searchApplicationName: 'search-application' }); await nextTick(); expect(http.delete).toHaveBeenCalledWith( - '/internal/enterprise_search/search_applications/deleteEngineName' + '/internal/enterprise_search/search_applications/search-application' ); await expect(result).resolves; }); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.ts new file mode 100644 index 0000000000000..c65159660bb0c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/delete_search_application_api_logic.ts @@ -0,0 +1,47 @@ +/* + * 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 { i18n } from '@kbn/i18n'; + +import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface DeleteSearchApplicationApiLogicArguments { + searchApplicationName: string; +} +export interface DeleteSearchApplicationApiLogicResponse { + searchApplicationName: string; +} + +export const deleteSearchApplication = async ({ + searchApplicationName, +}: DeleteSearchApplicationApiLogicArguments): Promise => { + const route = `/internal/enterprise_search/search_applications/${searchApplicationName}`; + await HttpLogic.values.http.delete(route); + return { searchApplicationName }; +}; +export const DeleteSearchApplicationAPILogic = createApiLogic( + ['search_applications', 'delete_search_application_api_logic'], + deleteSearchApplication, + { + showSuccessFlashFn: ({ searchApplicationName }) => + i18n.translate( + 'xpack.enterpriseSearch.searchApplications.list.deleteSearchApplication.successToast.title', + { + defaultMessage: '{searchApplicationName} has been deleted', + values: { + searchApplicationName, + }, + } + ), + } +); + +export type DeleteSearchApplicationApiLogicActions = Actions< + DeleteSearchApplicationApiLogicArguments, + DeleteSearchApplicationApiLogicResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_indices_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_indices_api_logic.ts similarity index 72% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_indices_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_indices_api_logic.ts index dbb434032e79f..ec0cae05130b6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_indices_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_indices_api_logic.ts @@ -12,11 +12,11 @@ import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_lo import { INPUT_THROTTLE_DELAY_MS } from '../../../shared/constants/timers'; import { HttpLogic } from '../../../shared/http'; -export interface EnginesFetchIndicesApiParams { +export interface SearchApplicationsFetchIndicesApiParams { searchQuery?: string; } -export interface EnginesFetchIndicesApiResponse { +export interface SearchApplicationsFetchIndicesApiResponse { indices: ElasticsearchIndexWithIngestion[]; meta: Meta; searchQuery?: string; @@ -26,7 +26,7 @@ const INDEX_SEARCH_PAGE_SIZE = 40; export const fetchIndices = async ({ searchQuery, -}: EnginesFetchIndicesApiParams): Promise => { +}: SearchApplicationsFetchIndicesApiParams): Promise => { const { http } = HttpLogic.values; const route = '/internal/enterprise_search/indices'; const query = { @@ -45,15 +45,15 @@ export const fetchIndices = async ({ return { ...response, searchQuery }; }; -export const FetchIndicesForEnginesAPILogic = createApiLogic( - ['content', 'engines_fetch_indices_api_logic'], +export const FetchIndicesForSearchApplicationsAPILogic = createApiLogic( + ['search_applications', 'fetch_indices_api_logic'], fetchIndices, { requestBreakpointMS: INPUT_THROTTLE_DELAY_MS, } ); -export type FetchIndicesForEnginesAPILogicActions = Actions< - EnginesFetchIndicesApiParams, - EnginesFetchIndicesApiResponse +export type FetchIndicesForSearchApplicationsAPILogicActions = Actions< + SearchApplicationsFetchIndicesApiParams, + SearchApplicationsFetchIndicesApiResponse >; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.test.ts similarity index 69% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.test.ts index b5f05227f16d3..c8fc4a2f0ff07 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.test.ts @@ -9,21 +9,21 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { fetchEngine } from './fetch_engine_api_logic'; +import { fetchSearchApplication } from './fetch_search_application_api_logic'; -describe('FetchEngineApiLogic', () => { +describe('FetchSearchApplicationApiLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('fetchEngine', () => { + describe('fetchSearchApplication', () => { it('calls correct api', async () => { const promise = Promise.resolve('result'); http.get.mockReturnValue(promise); - const result = fetchEngine({ engineName: 'my-engine' }); + const result = fetchSearchApplication({ name: 'search-application' }); await nextTick(); expect(http.get).toHaveBeenCalledWith( - '/internal/enterprise_search/search_applications/my-engine' + '/internal/enterprise_search/search_applications/search-application' ); await expect(result).resolves.toEqual('result'); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.ts similarity index 52% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.ts index 7c1277c8586f0..6736324f40464 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_api_logic.ts @@ -9,20 +9,26 @@ import { EnterpriseSearchApplicationDetails } from '../../../../../common/types/ import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; import { HttpLogic } from '../../../shared/http'; -export interface FetchEngineApiParams { - engineName: string; +export interface FetchSearchApplicationApiParams { + name: string; } -export type FetchEngineApiResponse = EnterpriseSearchApplicationDetails; +export type FetchSearchApplicationApiResponse = EnterpriseSearchApplicationDetails; -export const fetchEngine = async ({ - engineName, -}: FetchEngineApiParams): Promise => { - const route = `/internal/enterprise_search/search_applications/${engineName}`; +export const fetchSearchApplication = async ({ + name, +}: FetchSearchApplicationApiParams): Promise => { + const route = `/internal/enterprise_search/search_applications/${name}`; return await HttpLogic.values.http.get(route); }; -export const FetchEngineApiLogic = createApiLogic(['fetch_engine_api_logic'], fetchEngine); +export const FetchSearchApplicationApiLogic = createApiLogic( + ['search_applications', 'fetch_search_application_api_logic'], + fetchSearchApplication +); -export type FetchEngineApiLogicActions = Actions; +export type FetchSearchApplicationApiLogicActions = Actions< + FetchSearchApplicationApiParams, + FetchSearchApplicationApiResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.test.ts similarity index 72% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.test.ts index 8ee69c224b00f..f9a52b0fe874a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engine_field_capabilities_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.test.ts @@ -9,18 +9,18 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { fetchEngineFieldCapabilities } from './fetch_engine_field_capabilities_api_logic'; +import { fetchSearchApplicationFieldCapabilities } from './fetch_search_application_field_capabilities_api_logic'; -describe('FetchEngineFieldCapabilitiesApiLogic', () => { +describe('FetchSearchApplicationFieldCapabilitiesApiLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('fetchEngineFieldCapabilities', () => { + describe('fetchSearchApplicationFieldCapabilities', () => { it('requests the field_capabilities api', async () => { const promise = Promise.resolve({ result: 'result' }); http.get.mockReturnValue(promise); - const result = fetchEngineFieldCapabilities({ engineName: 'foobar' }); + const result = fetchSearchApplicationFieldCapabilities({ name: 'foobar' }); await nextTick(); expect(http.get).toHaveBeenCalledWith( '/internal/enterprise_search/search_applications/foobar/field_capabilities' diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.ts new file mode 100644 index 0000000000000..10c4fb224c872 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_application_field_capabilities_api_logic.ts @@ -0,0 +1,35 @@ +/* + * 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 { EnterpriseSearchApplicationFieldCapabilities } from '../../../../../common/types/search_applications'; +import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface FetchSearchApplicationFieldCapabilitiesApiParams { + name: string; +} + +export type FetchSearchApplicationFieldCapabilitiesApiResponse = + EnterpriseSearchApplicationFieldCapabilities; + +export const fetchSearchApplicationFieldCapabilities = async ({ + name, +}: FetchSearchApplicationFieldCapabilitiesApiParams): Promise => { + const route = `/internal/enterprise_search/search_applications/${name}/field_capabilities`; + + return await HttpLogic.values.http.get(route); +}; + +export const FetchSearchApplicationFieldCapabilitiesApiLogic = createApiLogic( + ['search_applications', 'fetch_search_application_field_capabilities_api_logic'], + fetchSearchApplicationFieldCapabilities +); + +export type FetchSearchApplicationFieldCapabilitiesApiLogicActions = Actions< + FetchSearchApplicationFieldCapabilitiesApiParams, + FetchSearchApplicationFieldCapabilitiesApiResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.test.ts similarity index 77% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.test.ts index 6ff6014fac050..78944e3442a77 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.test.ts @@ -9,18 +9,18 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { fetchEngines } from './fetch_engines_api_logic'; +import { fetchSearchApplications } from './fetch_search_applications_api_logic'; -describe('FetchEnginesAPILogic', () => { +describe('FetchSearchApplicationsAPILogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('fetchEnginesAPILogic', () => { - it('request list engines api without search query', async () => { + describe('fetchSearchApplications', () => { + it('request list search applications api without search query', async () => { const promise = Promise.resolve({ result: 'result' }); http.get.mockReturnValue(promise); - const result = fetchEngines({ + const result = fetchSearchApplications({ meta: { from: 0, size: 10, total: 0 }, }); await nextTick(); @@ -36,10 +36,10 @@ describe('FetchEnginesAPILogic', () => { }, }); }); - it('request list engines api with search query', async () => { + it('request list search applications api with search query', async () => { const promise = Promise.resolve({ result: 'result' }); http.get.mockReturnValue(promise); - const result = fetchEngines({ + const result = fetchSearchApplications({ meta: { from: 0, size: 10, total: 0 }, searchQuery: 'te', }); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.ts similarity index 74% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.ts index 1f2ef05023f40..5aacfc75b1bac 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/fetch_engines_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/fetch_search_applications_api_logic.ts @@ -11,15 +11,15 @@ import { EnterpriseSearchApplicationsResponse } from '../../../../../common/type import { createApiLogic } from '../../../shared/api_logic/create_api_logic'; import { HttpLogic } from '../../../shared/http'; -export interface EnginesListAPIArguments { +export interface SearchApplicationsListAPIArguments { meta: Page; searchQuery?: string; } -export const fetchEngines = async ({ +export const fetchSearchApplications = async ({ meta, searchQuery, -}: EnginesListAPIArguments): Promise => { +}: SearchApplicationsListAPIArguments): Promise => { const route = '/internal/enterprise_search/search_applications'; const query = { from: meta.from, @@ -34,4 +34,7 @@ export const fetchEngines = async ({ return { ...response, params: query }; }; -export const FetchEnginesAPILogic = createApiLogic(['content', 'engines_api_logic'], fetchEngines); +export const FetchSearchApplicationsAPILogic = createApiLogic( + ['searchApplications', 'search_applications_api_logic'], + fetchSearchApplications +); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.test.ts similarity index 80% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.test.ts index 5e764d42a65a6..a53db47b99cf1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.test.ts @@ -9,15 +9,15 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { generateEngineApiKey } from './generate_engine_api_key_logic'; +import { generateSearchApplicationApiKey } from './generate_search_application_api_key_logic'; -describe('GenerateEngineApiKeyLogic', () => { +describe('GenerateSearchApplicationApiKeyLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('GenerateEngineApiKeyLogic', () => { + describe('generateSearchApplicationApiKey', () => { it('calls correct api', async () => { const promise = Promise.resolve({ apiKey: { @@ -28,8 +28,8 @@ describe('GenerateEngineApiKeyLogic', () => { }, }); http.post.mockReturnValue(promise); - const result = generateEngineApiKey({ - engineName: 'puggles', + const result = generateSearchApplicationApiKey({ + searchApplicationName: 'puggles', keyName: 'puggles read only key', }); await nextTick(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.ts similarity index 71% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.ts index 125c76d6a2d1a..42176c61d009b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/generate_search_application_api_key_logic.ts @@ -17,14 +17,14 @@ interface APIKeyResponse { }; } -export const generateEngineApiKey = async ({ - engineName, +export const generateSearchApplicationApiKey = async ({ keyName, + searchApplicationName, }: { - engineName: string; keyName: string; + searchApplicationName: string; }) => { - const route = `/internal/enterprise_search/search_applications/${engineName}/api_key`; + const route = `/internal/enterprise_search/search_applications/${searchApplicationName}/api_key`; return await HttpLogic.values.http.post(route, { body: JSON.stringify({ @@ -33,7 +33,7 @@ export const generateEngineApiKey = async ({ }); }; -export const GenerateEngineApiKeyLogic = createApiLogic( - ['generate_engine_api_key_logic'], - generateEngineApiKey +export const GenerateSearchApplicationApiKeyLogic = createApiLogic( + ['generate_search_application_api_key_logic'], + generateSearchApplicationApiKey ); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.test.ts similarity index 62% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.test.ts index eb504fc31b30b..8a263e4e1a630 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.test.ts @@ -9,25 +9,25 @@ import { mockHttpValues } from '../../../__mocks__/kea_logic'; import { nextTick } from '@kbn/test-jest-helpers'; -import { updateEngine } from './update_engine_api_logic'; +import { updateSearchApplication } from './update_search_application_api_logic'; -describe('UpdateEngineApiLogic', () => { +describe('UpdateSearchApplicationApiLogic', () => { const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); }); - describe('updateEngine', () => { + describe('updateSearchApplication', () => { it('calls correct api', async () => { - const engine = { engineName: 'my-engine', indices: ['an-index'] }; + const searchApplication = { name: 'my-search-application', indices: ['an-index'] }; const response = { result: 'updated' }; const promise = Promise.resolve(response); http.put.mockReturnValue(promise); - const result = updateEngine(engine); + const result = updateSearchApplication(searchApplication); await nextTick(); expect(http.put).toHaveBeenCalledWith( - '/internal/enterprise_search/search_applications/my-engine', + '/internal/enterprise_search/search_applications/my-search-application', { - body: '{"indices":["an-index"],"name":"my-engine"}', + body: '{"indices":["an-index"],"name":"my-search-application"}', } ); await expect(result).resolves.toEqual(response); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.ts similarity index 51% rename from x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.ts index 4af31960381dc..cea5b0b5c9e88 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/api/engines/update_engine_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/api/search_applications/update_search_application_api_logic.ts @@ -9,24 +9,30 @@ import { EnterpriseSearchApplication } from '../../../../../common/types/search_ import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; import { HttpLogic } from '../../../shared/http'; -export interface UpdateEngineApiParams { - engineName: string; +export interface UpdateSearchApplicationApiParams { indices: string[]; + name: string; } -export type UpdateEngineApiResponse = EnterpriseSearchApplication; +export type UpdateSearchApplicationApiResponse = EnterpriseSearchApplication; -export type UpdateEngineApiLogicActions = Actions; +export type UpdateSearchApplicationApiLogicActions = Actions< + UpdateSearchApplicationApiParams, + UpdateSearchApplicationApiResponse +>; -export const updateEngine = async ({ - engineName, +export const updateSearchApplication = async ({ + name, indices, -}: UpdateEngineApiParams): Promise => { - const route = `/internal/enterprise_search/search_applications/${engineName}`; +}: UpdateSearchApplicationApiParams): Promise => { + const route = `/internal/enterprise_search/search_applications/${name}`; return await HttpLogic.values.http.put(route, { - body: JSON.stringify({ indices, name: engineName }), + body: JSON.stringify({ indices, name }), }); }; -export const UpdateEngineApiLogic = createApiLogic(['update_engine_api_logic'], updateEngine); +export const UpdateSearchApplicationApiLogic = createApiLogic( + ['searchApplications', 'update_search_application_api_logic'], + updateSearchApplication +); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.test.ts deleted file mode 100644 index af7615bf11102..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.test.ts +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; - -import { EnterpriseSearchApplicationDetails } from '../../../../../common/types/search_applications'; -import { FetchEngineApiLogic } from '../../api/engines/fetch_engine_api_logic'; - -import { EngineIndicesLogic, EngineIndicesLogicValues } from './engine_indices_logic'; - -const DEFAULT_VALUES: EngineIndicesLogicValues = { - addIndicesFlyoutOpen: false, - engineData: undefined, - engineName: 'my-test-engine', - isLoadingEngine: true, -}; - -const mockEngineData: EnterpriseSearchApplicationDetails = { - indices: [ - { - count: 10, - health: 'green', - name: 'search-001', - }, - { - count: 1000, - health: 'yellow', - name: 'search-002', - }, - ], - name: DEFAULT_VALUES.engineName, - template: { - script: { - lang: 'mustache', - params: { query_string: '*' }, - source: '', - }, - }, - updated_at_millis: 1679501369566, -}; - -describe('EngineViewLogic', () => { - const { mount } = new LogicMounter(EngineIndicesLogic); - const { mount: mountFetchEngineApiLogic } = new LogicMounter(FetchEngineApiLogic); - - beforeEach(() => { - jest.clearAllMocks(); - jest.useRealTimers(); - - mountFetchEngineApiLogic(); - mount( - { - engineName: DEFAULT_VALUES.engineName, - }, - { - engineName: DEFAULT_VALUES.engineName, - } - ); - }); - - it('has expected default values', () => { - expect(EngineIndicesLogic.values).toEqual(DEFAULT_VALUES); - }); - - describe('listeners', () => { - beforeEach(() => { - FetchEngineApiLogic.actions.apiSuccess(mockEngineData); - }); - it('has engine data', () => { - expect(EngineIndicesLogic.values.engineData).toEqual(mockEngineData); - }); - - describe('engineUpdated', () => { - it('fetches new engine details', () => { - jest.spyOn(EngineIndicesLogic.actions, 'fetchEngine'); - - EngineIndicesLogic.actions.engineUpdated({ - ...mockEngineData, - indices: mockEngineData.indices.map((index) => index.name), - }); - - expect(EngineIndicesLogic.actions.fetchEngine).toHaveBeenCalledTimes(1); - expect(EngineIndicesLogic.actions.fetchEngine).toHaveBeenCalledWith({ - engineName: DEFAULT_VALUES.engineName, - }); - }); - }); - describe('removeIndexFromEngine', () => { - it('updated engine removing the given index', () => { - jest.spyOn(EngineIndicesLogic.actions, 'updateEngineRequest'); - - EngineIndicesLogic.actions.removeIndexFromEngine(mockEngineData.indices[0].name); - - expect(EngineIndicesLogic.actions.updateEngineRequest).toHaveBeenCalledTimes(1); - expect(EngineIndicesLogic.actions.updateEngineRequest).toHaveBeenCalledWith({ - engineName: DEFAULT_VALUES.engineName, - indices: ['search-002'], - }); - }); - }); - describe('addIndicesToEngine', () => { - it('updated engine removing the given index', () => { - jest.spyOn(EngineIndicesLogic.actions, 'updateEngineRequest'); - - EngineIndicesLogic.actions.addIndicesToEngine(['search-003']); - - expect(EngineIndicesLogic.actions.updateEngineRequest).toHaveBeenCalledTimes(1); - expect(EngineIndicesLogic.actions.updateEngineRequest).toHaveBeenCalledWith({ - engineName: DEFAULT_VALUES.engineName, - indices: ['search-001', 'search-002', 'search-003'], - }); - }); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.ts deleted file mode 100644 index 52c485c8ed7ec..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices_logic.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -import { - UpdateEngineApiLogic, - UpdateEngineApiLogicActions, -} from '../../api/engines/update_engine_api_logic'; - -import { EngineViewActions, EngineViewLogic, EngineViewValues } from './engine_view_logic'; - -export interface EngineIndicesLogicActions { - addIndicesToEngine: (indices: string[]) => { indices: string[] }; - closeAddIndicesFlyout: () => void; - engineUpdated: UpdateEngineApiLogicActions['apiSuccess']; - fetchEngine: EngineViewActions['fetchEngine']; - openAddIndicesFlyout: () => void; - removeIndexFromEngine: (indexName: string) => { indexName: string }; - updateEngineRequest: UpdateEngineApiLogicActions['makeRequest']; -} - -export interface EngineIndicesLogicValues { - addIndicesFlyoutOpen: boolean; - engineData: EngineViewValues['engineData']; - engineName: EngineViewValues['engineName']; - isLoadingEngine: EngineViewValues['isLoadingEngine']; -} - -export const EngineIndicesLogic = kea< - MakeLogicType ->({ - actions: { - addIndicesToEngine: (indices) => ({ indices }), - closeAddIndicesFlyout: () => true, - openAddIndicesFlyout: () => true, - removeIndexFromEngine: (indexName) => ({ indexName }), - }, - connect: { - actions: [ - EngineViewLogic, - ['fetchEngine'], - UpdateEngineApiLogic, - ['makeRequest as updateEngineRequest', 'apiSuccess as engineUpdated'], - ], - values: [EngineViewLogic, ['engineData', 'engineName', 'isLoadingEngine']], - }, - listeners: ({ actions, values }) => ({ - addIndicesToEngine: ({ indices }) => { - if (!values.engineData) return; - const existingIndicesNames = values.engineData.indices.map((index) => index.name); - const updatedIndices = Array.from(new Set([...existingIndicesNames, ...indices])); - actions.updateEngineRequest({ - engineName: values.engineName, - indices: updatedIndices, - }); - }, - engineUpdated: () => { - actions.fetchEngine({ engineName: values.engineName }); - }, - removeIndexFromEngine: ({ indexName }) => { - if (!values.engineData) return; - const updatedIndices = values.engineData.indices - .filter((index) => index.name !== indexName) - .map((index) => index.name); - actions.updateEngineRequest({ - engineName: values.engineName, - indices: updatedIndices, - }); - }, - }), - path: ['enterprise_search', 'content', 'engine_indices_logic'], - reducers: { - addIndicesFlyoutOpen: [ - false, - { - closeAddIndicesFlyout: () => false, - openAddIndicesFlyout: () => true, - }, - ], - }, -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_name_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_name_logic.ts deleted file mode 100644 index 91fb9ffc38fe6..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_name_logic.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -export interface EngineNameProps { - engineName: string; -} - -export type EngineNameValues = EngineNameProps; - -export interface EngineNameActions { - setEngineName: (engineName: string) => { engineName: string }; -} - -export const EngineNameLogic = kea< - MakeLogicType ->({ - actions: { - setEngineName: (engineName) => ({ engineName }), - }, - path: ['enterprise_search', 'content', 'engine_name'], - reducers: ({ props }) => ({ - engineName: [ - // Short-circuiting this to empty string is necessary to enable testing logics relying on this - props.engineName ?? '', - { - setEngineName: (_, { engineName }) => engineName, - }, - ], - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_router.tsx deleted file mode 100644 index 31122af9d8d50..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_router.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 React, { useEffect } from 'react'; -import { Redirect, Switch, useParams } from 'react-router-dom'; - -import { useActions } from 'kea'; - -import { Route } from '@kbn/shared-ux-router'; - -import { generateEncodedPath } from '../../../shared/encode_path_params'; -import { ENGINE_PATH, ENGINE_TAB_PATH, EngineViewTabs } from '../../routes'; - -import { EngineNameLogic } from './engine_name_logic'; -import { EngineView } from './engine_view'; - -export const EngineRouter: React.FC = () => { - const engineName = decodeURIComponent(useParams<{ engineName: string }>().engineName); - const engineNameLogic = EngineNameLogic({ engineName }); - const { setEngineName } = useActions(engineNameLogic); - - useEffect(() => { - const unmountName = engineNameLogic.mount(); - - return () => { - unmountName(); - }; - }, []); - useEffect(() => { - setEngineName(engineName); - }, [engineName]); - - return ( - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview_logic.ts deleted file mode 100644 index f1bac05e4333f..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview_logic.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -import { FieldConfiguration } from '@elastic/search-ui'; - -import { FetchEngineFieldCapabilitiesApiLogic } from '../../../api/engines/fetch_engine_field_capabilities_api_logic'; -import { EngineNameLogic } from '../engine_name_logic'; - -interface EngineSearchPreviewActions { - fetchEngineFieldCapabilities: typeof FetchEngineFieldCapabilitiesApiLogic.actions.makeRequest; -} - -export interface EngineSearchPreviewValues { - engineFieldCapabilitiesData: typeof FetchEngineFieldCapabilitiesApiLogic.values.data; - engineName: typeof EngineNameLogic.values.engineName; - fieldTypesByIndex: Record>; - resultFields: Record; - sortableFields: string[]; -} - -export const EngineSearchPreviewLogic = kea< - MakeLogicType ->({ - connect: { - actions: [ - FetchEngineFieldCapabilitiesApiLogic, - ['makeRequest as fetchEngineFieldCapabilities'], - ], - values: [ - EngineNameLogic, - ['engineName'], - FetchEngineFieldCapabilitiesApiLogic, - ['data as engineFieldCapabilitiesData'], - ], - }, - events: ({ actions, values }) => ({ - afterMount: () => { - if (!values.engineFieldCapabilitiesData) { - actions.fetchEngineFieldCapabilities({ - engineName: values.engineName, - }); - } - }, - }), - path: ['enterprise_search', 'content', 'engine_search_preview_logic'], - selectors: ({ selectors }) => ({ - fieldTypesByIndex: [ - () => [selectors.engineFieldCapabilitiesData], - (data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => { - if (!data) return {}; - - return data.fields.reduce( - (out: Record>, field) => - field.indices.reduce( - (acc: Record>, index) => ({ - ...acc, - [index.name]: { - ...(acc[index.name] || {}), - [field.name]: index.type, - }, - }), - out - ), - {} - ); - }, - ], - resultFields: [ - () => [selectors.engineFieldCapabilitiesData], - (data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => { - if (!data) return {}; - - return Object.fromEntries( - data.fields - .filter(({ metadata_field: isMeta }) => !isMeta) - .map(({ name }) => [name, { raw: {}, snippet: { fallback: true } }]) - ); - }, - ], - sortableFields: [ - () => [selectors.engineFieldCapabilitiesData], - (data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => { - if (!data) return []; - - return data.fields - .filter(({ metadata_field: isMeta, aggregatable }) => aggregatable && !isMeta) - .map(({ name }) => name) - .sort(); - }, - ], - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view.tsx deleted file mode 100644 index 6b66c94f5ecf6..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view.tsx +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 React, { useEffect, useLayoutEffect } from 'react'; -import { useParams, Redirect, Switch } from 'react-router-dom'; - -import { useValues, useActions } from 'kea'; - -import { Route } from '@kbn/shared-ux-router'; - -import { Status } from '../../../../../common/types/api'; - -import { KibanaLogic } from '../../../shared/kibana'; -import { - ENGINE_PATH, - SEARCH_APPLICATION_CONTENT_PATH, - SEARCH_APPLICATION_CONNECT_PATH, - EngineViewTabs, - SearchApplicationConnectTabs, - SearchApplicationContentTabs, -} from '../../routes'; - -import { DeleteEngineModal } from '../engines/delete_engine_modal'; -import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_template'; - -import { EngineConnect } from './engine_connect/engine_connect'; -import { EngineError } from './engine_error'; -import { EngineSearchPreview } from './engine_search_preview/engine_search_preview'; -import { EngineViewLogic } from './engine_view_logic'; -import { EngineHeaderDocsAction } from './header_docs_action'; -import { SearchApplicationContent } from './search_application_content'; - -export const EngineView: React.FC = () => { - const { fetchEngine, closeDeleteEngineModal } = useActions(EngineViewLogic); - const { - engineName, - fetchEngineApiError, - fetchEngineApiStatus, - hasSchemaConflicts, - isDeleteModalVisible, - } = useValues(EngineViewLogic); - const { tabId = EngineViewTabs.PREVIEW } = useParams<{ - tabId?: string; - }>(); - const { renderHeaderActions } = useValues(KibanaLogic); - - useLayoutEffect(() => { - renderHeaderActions(EngineHeaderDocsAction); - - return () => { - renderHeaderActions(); - }; - }, []); - - useEffect(() => { - fetchEngine({ engineName }); - }, [engineName]); - - if (fetchEngineApiStatus === Status.ERROR) { - return ( - } - hasSchemaConflicts={hasSchemaConflicts} - /> - ); - } - - return ( - <> - {isDeleteModalVisible ? ( - - ) : null} - - - - - - - - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.test.ts deleted file mode 100644 index 83050a3b4f184..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; - -import { Status } from '../../../../../common/types/api'; - -import { KibanaLogic } from '../../../shared/kibana'; -import { DeleteEnginesApiLogicResponse } from '../../api/engines/delete_engines_api_logic'; -import { ENGINES_PATH } from '../../routes'; -import { EnginesListLogic } from '../engines/engines_list_logic'; - -import { EngineViewLogic, EngineViewValues } from './engine_view_logic'; - -const DEFAULT_VALUES: EngineViewValues = { - engineData: undefined, - engineName: 'my-test-engine', - engineSchemaData: undefined, - fetchEngineApiError: undefined, - fetchEngineApiStatus: Status.IDLE, - fetchEngineSchemaApiError: undefined, - fetchEngineSchemaApiStatus: Status.IDLE, - hasSchemaConflicts: false, - isDeleteModalVisible: false, - isLoadingEngine: true, - isLoadingEngineSchema: true, - schemaFields: [], -}; - -describe('EngineViewLogic', () => { - const { mount } = new LogicMounter(EngineViewLogic); - const { mount: mountEnginesListLogic } = new LogicMounter(EnginesListLogic); - beforeEach(() => { - jest.clearAllMocks(); - jest.useRealTimers(); - - mountEnginesListLogic(); - mount({ engineName: DEFAULT_VALUES.engineName }, { engineName: DEFAULT_VALUES.engineName }); - }); - - it('has expected default values', () => { - expect(EngineViewLogic.values).toEqual(DEFAULT_VALUES); - }); - - describe('listeners', () => { - describe('deleteSuccess', () => { - it('should navigate to the engines list when an engine is deleted', () => { - jest.spyOn(EngineViewLogic.actions, 'deleteSuccess'); - jest - .spyOn(KibanaLogic.values, 'navigateToUrl') - .mockImplementationOnce(() => Promise.resolve()); - EnginesListLogic.actions.deleteSuccess({} as DeleteEnginesApiLogicResponse); - - expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith(ENGINES_PATH); - }); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.ts deleted file mode 100644 index 74492df6be398..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_view_logic.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -import { Status } from '../../../../../common/types/api'; -import { SchemaField } from '../../../../../common/types/search_applications'; - -import { KibanaLogic } from '../../../shared/kibana'; - -import { - FetchEngineApiLogic, - FetchEngineApiLogicActions, -} from '../../api/engines/fetch_engine_api_logic'; -import { FetchEngineFieldCapabilitiesApiLogic } from '../../api/engines/fetch_engine_field_capabilities_api_logic'; - -import { ENGINES_PATH } from '../../routes'; - -import { EnginesListLogic, EnginesListActions } from '../engines/engines_list_logic'; - -import { EngineNameLogic } from './engine_name_logic'; - -export interface EngineViewActions { - closeDeleteEngineModal(): void; - deleteSuccess: EnginesListActions['deleteSuccess']; - fetchEngine: FetchEngineApiLogicActions['makeRequest']; - fetchEngineSchema: FetchEngineApiLogicActions['makeRequest']; - openDeleteEngineModal(): void; -} - -export interface EngineViewValues { - engineData: typeof FetchEngineApiLogic.values.data; - engineName: typeof EngineNameLogic.values.engineName; - engineSchemaData: typeof FetchEngineFieldCapabilitiesApiLogic.values.data; - fetchEngineApiError?: typeof FetchEngineApiLogic.values.error; - fetchEngineApiStatus: typeof FetchEngineApiLogic.values.status; - fetchEngineSchemaApiError?: typeof FetchEngineFieldCapabilitiesApiLogic.values.error; - fetchEngineSchemaApiStatus: typeof FetchEngineFieldCapabilitiesApiLogic.values.status; - hasSchemaConflicts: boolean; - isDeleteModalVisible: boolean; - isLoadingEngine: boolean; - isLoadingEngineSchema: boolean; - schemaFields: SchemaField[]; -} - -export const EngineViewLogic = kea>({ - actions: { - closeDeleteEngineModal: true, - openDeleteEngineModal: true, - }, - connect: { - actions: [ - FetchEngineApiLogic, - ['makeRequest as fetchEngine'], - FetchEngineFieldCapabilitiesApiLogic, - ['makeRequest as fetchEngineSchema'], - EnginesListLogic, - ['deleteSuccess'], - ], - values: [ - EngineNameLogic, - ['engineName'], - FetchEngineApiLogic, - ['data as engineData', 'status as fetchEngineApiStatus', 'error as fetchEngineApiError'], - FetchEngineFieldCapabilitiesApiLogic, - [ - 'data as engineSchemaData', - 'status as fetchEngineSchemaApiStatus', - 'error as fetchEngineSchemaApiError', - ], - ], - }, - listeners: ({ actions }) => ({ - deleteSuccess: () => { - actions.closeDeleteEngineModal(); - KibanaLogic.values.navigateToUrl(ENGINES_PATH); - }, - fetchEngine: ({ engineName }) => { - actions.fetchEngineSchema({ engineName }); - }, - }), - path: ['enterprise_search', 'content', 'engine_view_logic'], - reducers: () => ({ - isDeleteModalVisible: [ - false, - { - closeDeleteEngineModal: () => false, - openDeleteEngineModal: () => true, - }, - ], - }), - selectors: ({ selectors }) => ({ - hasSchemaConflicts: [ - () => [selectors.schemaFields], - (data: EngineViewValues['schemaFields']) => data.some((f) => f.type === 'conflict'), - ], - isLoadingEngine: [ - () => [selectors.fetchEngineApiStatus, selectors.engineData], - (status: EngineViewValues['fetchEngineApiStatus'], data: EngineViewValues['engineData']) => { - return status === Status.IDLE || (!data && status === Status.LOADING); - }, - ], - isLoadingEngineSchema: [ - () => [selectors.fetchEngineSchemaApiStatus], - (status: EngineViewValues['fetchEngineSchemaApiStatus']) => - [Status.LOADING, Status.IDLE].includes(status), - ], - schemaFields: [ - () => [selectors.engineSchemaData], - (data: EngineViewValues['engineSchemaData']) => data?.fields || [], - ], - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.test.ts deleted file mode 100644 index 7147d061836de..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.test.ts +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; - -import { HttpError, Status } from '../../../../../common/types/api'; - -import { KibanaLogic } from '../../../shared/kibana'; -import { CreateEngineApiLogic } from '../../api/engines/create_engine_api_logic'; - -import { ENGINES_PATH } from '../../routes'; - -import { CreateEngineLogic, CreateEngineLogicValues } from './create_engine_logic'; - -const DEFAULT_VALUES: CreateEngineLogicValues = { - createDisabled: true, - createEngineError: undefined, - createEngineStatus: Status.IDLE, - engineName: '', - engineNameStatus: 'incomplete', - formDisabled: false, - indicesStatus: 'incomplete', - selectedIndices: [], -}; - -const VALID_ENGINE_NAME = 'unit-test-001'; -const INVALID_ENGINE_NAME = 'TEST'; -const VALID_INDICES_DATA = ['search-index-01']; - -describe('CreateEngineLogic', () => { - const { mount: apiLogicMount } = new LogicMounter(CreateEngineApiLogic); - const { mount } = new LogicMounter(CreateEngineLogic); - - beforeEach(() => { - jest.clearAllMocks(); - jest.useRealTimers(); - apiLogicMount(); - mount(); - }); - - it('has expected defaults', () => { - expect(CreateEngineLogic.values).toEqual(DEFAULT_VALUES); - }); - - describe('listeners', () => { - it('createEngine makes expected request action with VALID_ENGINE_NAME', () => { - jest.spyOn(CreateEngineLogic.actions, 'createEngineRequest'); - - CreateEngineLogic.actions.setEngineName(VALID_ENGINE_NAME); - CreateEngineLogic.actions.setSelectedIndices(VALID_INDICES_DATA); - - CreateEngineLogic.actions.createEngine(); - - expect(CreateEngineLogic.actions.createEngineRequest).toHaveBeenCalledTimes(1); - expect(CreateEngineLogic.actions.createEngineRequest).toHaveBeenCalledWith({ - engineName: VALID_ENGINE_NAME, - indices: ['search-index-01'], - }); - }); - - it('createEngine makes expected request action with INVALID_ENGINE_NAME', () => { - jest.spyOn(CreateEngineLogic.actions, 'createEngineRequest'); - - CreateEngineLogic.actions.setEngineName(INVALID_ENGINE_NAME); - CreateEngineLogic.actions.setSelectedIndices(VALID_INDICES_DATA); - - CreateEngineLogic.actions.createEngine(); - - expect(CreateEngineLogic.actions.createEngineRequest).toHaveBeenCalledTimes(1); - expect(CreateEngineLogic.actions.createEngineRequest).toHaveBeenCalledWith({ - engineName: INVALID_ENGINE_NAME, - indices: ['search-index-01'], - }); - }); - it('createEngine returns error when duplicate search application is created', () => { - const httpError: HttpError = { - body: { - error: 'search_application_already_exists', - message: 'Search application name already taken. Choose another name.', - statusCode: 409, - }, - fetchOptions: {}, - request: {}, - } as HttpError; - CreateEngineApiLogic.actions.apiError(httpError); - expect(CreateEngineLogic.values.createEngineError).toEqual(httpError); - }); - - it('engineCreated is handled and is navigated to Search application list page', () => { - jest.spyOn(CreateEngineLogic.actions, 'fetchEngines'); - jest - .spyOn(KibanaLogic.values, 'navigateToUrl') - .mockImplementationOnce(() => Promise.resolve()); - CreateEngineApiLogic.actions.apiSuccess({ - result: 'created', - }); - expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith(ENGINES_PATH); - - expect(CreateEngineLogic.actions.fetchEngines).toHaveBeenCalledTimes(1); - }); - }); - describe('selectors', () => { - describe('engineNameStatus', () => { - it('returns incomplete with empty engine name', () => { - expect(CreateEngineLogic.values.engineNameStatus).toEqual('incomplete'); - }); - it('returns complete with valid engine name', () => { - CreateEngineLogic.actions.setEngineName(VALID_ENGINE_NAME); - - expect(CreateEngineLogic.values.engineNameStatus).toEqual('complete'); - }); - it('returns complete with invalid engine name', () => { - CreateEngineLogic.actions.setEngineName(INVALID_ENGINE_NAME); - expect(CreateEngineLogic.values.engineNameStatus).toEqual('complete'); - }); - }); - describe('indicesStatus', () => { - it('returns incomplete with 0 indices', () => { - expect(CreateEngineLogic.values.indicesStatus).toEqual('incomplete'); - }); - it('returns complete with at least one index', () => { - CreateEngineLogic.actions.setSelectedIndices(VALID_INDICES_DATA); - expect(CreateEngineLogic.values.indicesStatus).toEqual('complete'); - }); - }); - describe('createDisabled', () => { - it('false with valid data', () => { - CreateEngineLogic.actions.setSelectedIndices(VALID_INDICES_DATA); - CreateEngineLogic.actions.setEngineName(VALID_ENGINE_NAME); - - expect(CreateEngineLogic.values.createDisabled).toEqual(false); - }); - it('false with invalid data', () => { - CreateEngineLogic.actions.setSelectedIndices(VALID_INDICES_DATA); - CreateEngineLogic.actions.setEngineName(INVALID_ENGINE_NAME); - - expect(CreateEngineLogic.values.createDisabled).toEqual(false); - }); - }); - describe('formDisabled', () => { - it('returns true while create request in progress', () => { - CreateEngineApiLogic.actions.makeRequest({ - engineName: VALID_ENGINE_NAME, - indices: [VALID_INDICES_DATA[0]], - }); - - expect(CreateEngineLogic.values.formDisabled).toEqual(true); - }); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.ts deleted file mode 100644 index 42be4ca0e3951..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/create_engine_logic.ts +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -import { Status } from '../../../../../common/types/api'; -import { KibanaLogic } from '../../../shared/kibana'; - -import { - CreateEngineApiLogic, - CreateEngineApiLogicActions, -} from '../../api/engines/create_engine_api_logic'; -import { ENGINES_PATH } from '../../routes'; - -import { EnginesListLogic } from './engines_list_logic'; - -export interface CreateEngineLogicActions { - createEngine: () => void; - createEngineRequest: CreateEngineApiLogicActions['makeRequest']; - engineCreateError: CreateEngineApiLogicActions['apiError']; - engineCreated: CreateEngineApiLogicActions['apiSuccess']; - fetchEngines: () => void; - setEngineName: (engineName: string) => { engineName: string }; - setSelectedIndices: (indices: string[]) => { - indices: string[]; - }; -} - -export interface CreateEngineLogicValues { - createDisabled: boolean; - createEngineError?: typeof CreateEngineApiLogic.values.error; - createEngineStatus: typeof CreateEngineApiLogic.values.status; - engineName: string; - engineNameStatus: 'complete' | 'incomplete'; - formDisabled: boolean; - indicesStatus: 'complete' | 'incomplete'; - selectedIndices: string[]; -} - -export const CreateEngineLogic = kea< - MakeLogicType ->({ - actions: { - createEngine: true, - setEngineName: (engineName: string) => ({ engineName }), - setSelectedIndices: (indices: string[]) => ({ indices }), - }, - connect: { - actions: [ - EnginesListLogic, - ['fetchEngines'], - CreateEngineApiLogic, - [ - 'makeRequest as createEngineRequest', - 'apiSuccess as engineCreated', - 'apiError as engineCreateError', - ], - ], - values: [CreateEngineApiLogic, ['status as createEngineStatus', 'error as createEngineError']], - }, - listeners: ({ actions, values }) => ({ - createEngine: () => { - actions.createEngineRequest({ - engineName: values.engineName, - indices: values.selectedIndices, - }); - }, - engineCreated: () => { - actions.fetchEngines(); - KibanaLogic.values.navigateToUrl(ENGINES_PATH); - }, - }), - path: ['enterprise_search', 'content', 'create_engine_logic'], - reducers: { - engineName: [ - '', - { - setEngineName: (_, { engineName }) => engineName, - }, - ], - selectedIndices: [ - [], - { - setSelectedIndices: (_, { indices }) => indices, - }, - ], - }, - selectors: ({ selectors }) => ({ - createDisabled: [ - () => [selectors.indicesStatus, selectors.engineNameStatus], - ( - indicesStatus: CreateEngineLogicValues['indicesStatus'], - engineNameStatus: CreateEngineLogicValues['engineNameStatus'] - ) => indicesStatus !== 'complete' || engineNameStatus !== 'complete', - ], - engineNameStatus: [ - () => [selectors.engineName], - (engineName: string) => { - if (engineName.length === 0) return 'incomplete'; - return 'complete'; - }, - ], - formDisabled: [ - () => [selectors.createEngineStatus], - (createEngineStatus: CreateEngineLogicValues['createEngineStatus']) => - createEngineStatus === Status.LOADING, - ], - indicesStatus: [ - () => [selectors.selectedIndices], - (selectedIndices: CreateEngineLogicValues['selectedIndices']) => - selectedIndices.length > 0 ? 'complete' : 'incomplete', - ], - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.test.ts deleted file mode 100644 index 20306f699d407..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.test.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; - -import { nextTick } from '@kbn/test-jest-helpers'; - -import { Status } from '../../../../../common/types/api'; -import { EnterpriseSearchApplicationDetails } from '../../../../../common/types/search_applications'; - -import { FetchEngineApiLogic } from '../../api/engines/fetch_engine_api_logic'; - -import { EngineListFlyoutValues, EnginesListFlyoutLogic } from './engines_list_flyout_logic'; - -const DEFAULT_VALUES: EngineListFlyoutValues = { - fetchEngineApiError: undefined, - fetchEngineApiStatus: Status.IDLE, - fetchEngineData: undefined, - fetchEngineName: null, - isFetchEngineFlyoutVisible: false, - isFetchEngineLoading: false, -}; -const mockEngineData: EnterpriseSearchApplicationDetails = { - indices: [ - { - count: 10, - health: 'green', - name: 'search-001', - }, - { - count: 1000, - health: 'yellow', - name: 'search-002', - }, - ], - name: 'my-test-engine', - template: { - script: { - lang: 'mustache', - params: { query_string: '*' }, - source: '', - }, - }, - updated_at_millis: 1679337823167, -}; - -describe('EngineListFlyoutLogic', () => { - const { mount } = new LogicMounter(EnginesListFlyoutLogic); - const { mount: apiLogicMount } = new LogicMounter(FetchEngineApiLogic); - - beforeEach(() => { - jest.clearAllMocks(); - jest.useRealTimers(); - apiLogicMount(); - mount(); - }); - it('has expected default values', () => { - expect(EnginesListFlyoutLogic.values).toEqual(DEFAULT_VALUES); - }); - - describe('actions', () => { - describe('closeFetchEngineIndicesFlyout', () => { - it('set isFetchEngineFlyoutVisible to false and fetchEngineName to empty string', () => { - EnginesListFlyoutLogic.actions.closeFetchIndicesFlyout(); - expect(EnginesListFlyoutLogic.values).toEqual(DEFAULT_VALUES); - }); - }); - describe('openFetchEngineIndicesFlyout', () => { - it('set isFetchEngineFlyoutVisible to true and sets fetchEngineName to engine name', () => { - EnginesListFlyoutLogic.actions.openFetchEngineFlyout('my-test-engine'); - expect(EnginesListFlyoutLogic.values).toEqual({ - ...DEFAULT_VALUES, - fetchEngineApiStatus: Status.LOADING, - fetchEngineName: 'my-test-engine', - isFetchEngineFlyoutVisible: true, - isFetchEngineLoading: true, - }); - }); - }); - }); - - describe('selectors', () => { - it('receives fetchEngine indices data on success', () => { - expect(EnginesListFlyoutLogic.values).toEqual(DEFAULT_VALUES); - FetchEngineApiLogic.actions.apiSuccess(mockEngineData); - expect(EnginesListFlyoutLogic.values).toEqual({ - ...DEFAULT_VALUES, - fetchEngineApiStatus: Status.SUCCESS, - fetchEngineData: mockEngineData, - }); - }); - }); - describe('listeners', () => { - beforeEach(() => { - FetchEngineApiLogic.actions.apiSuccess(mockEngineData); - }); - it('fetch engines flyout when flyout is visible', async () => { - jest.useFakeTimers({ legacyFakeTimers: true }); - EnginesListFlyoutLogic.actions.openFetchEngineFlyout = jest.fn(); - EnginesListFlyoutLogic.actions.openFetchEngineFlyout('my-test-engine'); - await nextTick(); - expect(EnginesListFlyoutLogic.actions.openFetchEngineFlyout).toHaveBeenCalledTimes(1); - expect(EnginesListFlyoutLogic.actions.openFetchEngineFlyout).toHaveBeenCalledWith( - 'my-test-engine' - ); - }); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.ts deleted file mode 100644 index 8598ecd92ae63..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout_logic.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 { kea, MakeLogicType } from 'kea'; - -import { Status } from '../../../../../common/types/api'; -import { FetchEngineApiLogic } from '../../api/engines/fetch_engine_api_logic'; -import { EngineViewActions, EngineViewLogic, EngineViewValues } from '../engine/engine_view_logic'; - -export interface EngineListFlyoutValues { - isFetchEngineLoading: EngineViewValues['isLoadingEngine']; - isFetchEngineFlyoutVisible: boolean; - fetchEngineData: EngineViewValues['engineData']; // data from fetchEngineAPI - fetchEngineName: string | null; - fetchEngineApiError?: EngineViewValues['fetchEngineApiError']; - fetchEngineApiStatus: EngineViewValues['fetchEngineApiStatus']; -} -export interface EngineListFlyoutActions { - closeFetchIndicesFlyout(): void; - fetchEngineData: EngineViewActions['fetchEngine'] | null; - openFetchEngineFlyout: (engineName: string) => { engineName: string }; -} - -export const EnginesListFlyoutLogic = kea< - MakeLogicType ->({ - connect: { - actions: [EngineViewLogic, ['fetchEngine as fetchEngine']], - values: [ - EngineViewLogic, - [ - 'engineData as fetchEngineData', - 'fetchEngineApiError as fetchEngineApiError', - 'fetchEngineApiStatus as fetchEngineApiStatus', - ], - ], - }, - actions: { - closeFetchIndicesFlyout: true, - openFetchEngineFlyout: (engineName) => ({ engineName }), - }, - path: ['enterprise_search', 'content', 'engine_list_flyout_logic'], - reducers: ({}) => ({ - fetchEngineName: [ - null, - { - closeFetchIndicesFlyout: () => null, - openFetchEngineFlyout: (_, { engineName }) => engineName, - }, - ], - isFetchEngineFlyoutVisible: [ - false, - { - closeFetchIndicesFlyout: () => false, - openFetchEngineFlyout: () => true, - }, - ], - }), - selectors: ({ selectors }) => ({ - isFetchEngineLoading: [ - () => [selectors.fetchEngineApiStatus], - (status: EngineListFlyoutValues['fetchEngineApiStatus']) => [Status.LOADING].includes(status), - ], - }), - listeners: ({}) => ({ - openFetchEngineFlyout: async (input) => { - FetchEngineApiLogic.actions.makeRequest(input); - }, - }), -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_router.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_router.tsx deleted file mode 100644 index bcd5e5ec3bcd2..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_router.tsx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 React from 'react'; -import { Switch } from 'react-router-dom'; - -import { Route } from '@kbn/shared-ux-router'; - -import { ENGINES_PATH, ENGINE_CREATION_PATH, ENGINE_PATH } from '../../routes'; - -import { EngineRouter } from '../engine/engine_router'; -import { NotFound } from '../not_found'; - -import { EnginesList } from './engines_list'; - -export const EnginesRouter: React.FC = () => { - return ( - - - - - - - - - - - - - - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/engines_page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx similarity index 65% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/layout/engines_page_template.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx index 54e6085a7948a..c339e694d3c45 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/engines_page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/layout/page_template.tsx @@ -8,28 +8,28 @@ import React from 'react'; import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; -import { SetEnterpriseSearchEnginesChrome } from '../../../shared/kibana_chrome'; +import { SetEnterpriseSearchApplicationsChrome } from '../../../shared/kibana_chrome'; import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; -import { useEnterpriseSearchEngineNav } from '../../../shared/layout'; +import { useEnterpriseSearchApplicationNav } from '../../../shared/layout'; import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; -export type EnterpriseSearchEnginesPageTemplateProps = PageTemplateProps & { - engineName?: string; +export type EnterpriseSearchApplicationsPageTemplateProps = PageTemplateProps & { hasSchemaConflicts?: boolean; + searchApplicationName?: string; }; -export const EnterpriseSearchEnginesPageTemplate: React.FC< - EnterpriseSearchEnginesPageTemplateProps +export const EnterpriseSearchApplicationsPageTemplate: React.FC< + EnterpriseSearchApplicationsPageTemplateProps > = ({ children, pageChrome, pageViewTelemetry, - engineName, + searchApplicationName, hasSchemaConflicts, ...pageTemplateProps }) => { - const navItems = useEnterpriseSearchEngineNav( - engineName, + const navItems = useEnterpriseSearchApplicationNav( + searchApplicationName, pageTemplateProps.isEmptyState, hasSchemaConflicts ); @@ -41,7 +41,7 @@ export const EnterpriseSearchEnginesPageTemplate: React.FC< name: ENTERPRISE_SEARCH_CONTENT_PLUGIN.NAME, }} restrictWidth - setPageChrome={pageChrome && } + setPageChrome={pageChrome && } > {pageViewTelemetry && ( diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/not_found.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/not_found.tsx index 3ebdb9d9e8caf..41f5a7e8a0e9b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/not_found.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/not_found.tsx @@ -12,13 +12,16 @@ import { PageTemplateProps } from '../../shared/layout'; import { NotFoundPrompt } from '../../shared/not_found'; import { SendEnterpriseSearchTelemetry } from '../../shared/telemetry'; -import { EnterpriseSearchEnginesPageTemplate } from './layout/engines_page_template'; +import { EnterpriseSearchApplicationsPageTemplate } from './layout/page_template'; export const NotFound: React.FC = ({ pageChrome = [] }) => { return ( - + - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_flyout.tsx similarity index 73% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_flyout.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_flyout.tsx index d1423add85e8a..0a0c7af7ed028 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_flyout.tsx @@ -33,21 +33,22 @@ import { IndicesSelectComboBox, IndicesSelectComboBoxOption, indexToOption, -} from '../engines/components/indices_select_combobox'; +} from '../search_applications/components/indices_select_combobox'; import { AddIndicesLogic } from './add_indices_logic'; -import { EngineViewLogic } from './engine_view_logic'; +import { SearchApplicationViewLogic } from './search_application_view_logic'; export interface AddIndicesFlyoutProps { onClose: () => void; } export const AddIndicesFlyout: React.FC = ({ onClose }) => { - const { engineData } = useValues(EngineViewLogic); - const { selectedIndices, updateEngineStatus, updateEngineError } = useValues(AddIndicesLogic); + const { searchApplicationData } = useValues(SearchApplicationViewLogic); + const { selectedIndices, updateSearchApplicationStatus, updateSearchApplicationError } = + useValues(AddIndicesLogic); const { setSelectedIndices, submitSelectedIndices } = useActions(AddIndicesLogic); - const existingIndices = engineData?.indices?.map((index) => index.name); + const existingIndices = searchApplicationData?.indices?.map((index) => index.name); const selectedOptions = useMemo( () => selectedIndices.map((index) => indexToOption(index)), @@ -66,22 +67,22 @@ export const AddIndicesFlyout: React.FC = ({ onClose }) =

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.title', { defaultMessage: 'Add new indices' } )}

- {updateEngineStatus === Status.ERROR && updateEngineError && ( + {updateSearchApplicationStatus === Status.ERROR && updateSearchApplicationError && ( <> - {getErrorsFromHttpResponse(updateEngineError).map((errMessage, i) => ( + {getErrorsFromHttpResponse(updateSearchApplicationError).map((errMessage, i) => (

{errMessage}

))}
@@ -92,7 +93,7 @@ export const AddIndicesFlyout: React.FC = ({ onClose }) = @@ -114,7 +115,7 @@ export const AddIndicesFlyout: React.FC = ({ onClose }) = onClick={submitSelectedIndices} > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.submitButton', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.submitButton', { defaultMessage: 'Add selected' } )} @@ -126,7 +127,7 @@ export const AddIndicesFlyout: React.FC = ({ onClose }) = onClick={onClose} > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.cancelButton', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.cancelButton', { defaultMessage: 'Cancel' } )} diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.test.ts similarity index 74% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.test.ts index 7b3e61940f001..860874af5b14e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.test.ts @@ -13,20 +13,18 @@ import { AddIndicesLogic, AddIndicesLogicValues } from './add_indices_logic'; const DEFAULT_VALUES: AddIndicesLogicValues = { selectedIndices: [], - updateEngineError: undefined, - updateEngineStatus: Status.IDLE, + updateSearchApplicationError: undefined, + updateSearchApplicationStatus: Status.IDLE, }; describe('AddIndicesLogic', () => { const { mount: mountAddIndicesLogic } = new LogicMounter(AddIndicesLogic); - const { mount: mountEngineIndicesLogic } = new LogicMounter(AddIndicesLogic); beforeEach(() => { jest.clearAllMocks(); jest.useRealTimers(); mountAddIndicesLogic(); - mountEngineIndicesLogic(); }); it('has expected default values', () => { @@ -51,13 +49,13 @@ describe('AddIndicesLogic', () => { }); describe('listeners', () => { - describe('engineUpdated', () => { + describe('searchApplicationUpdated', () => { it('closes the add indices flyout', () => { jest.spyOn(AddIndicesLogic.actions, 'closeAddIndicesFlyout'); - AddIndicesLogic.actions.engineUpdated({ + AddIndicesLogic.actions.searchApplicationUpdated({ indices: [], - name: 'engine-name', + name: 'search-application-name', updated_at_millis: 2202018295, }); @@ -67,21 +65,21 @@ describe('AddIndicesLogic', () => { describe('submitSelectedIndices', () => { it('does not make a request if there are no selectedIndices', () => { - jest.spyOn(AddIndicesLogic.actions, 'addIndicesToEngine'); + jest.spyOn(AddIndicesLogic.actions, 'addIndicesToSearchApplication'); AddIndicesLogic.actions.submitSelectedIndices(); - expect(AddIndicesLogic.actions.addIndicesToEngine).toHaveBeenCalledTimes(0); + expect(AddIndicesLogic.actions.addIndicesToSearchApplication).toHaveBeenCalledTimes(0); }); - it('calls addIndicesToEngine when there are selectedIndices', () => { - jest.spyOn(AddIndicesLogic.actions, 'addIndicesToEngine'); + it('calls addIndicesToSearchApplication when there are selectedIndices', () => { + jest.spyOn(AddIndicesLogic.actions, 'addIndicesToSearchApplication'); AddIndicesLogic.actions.setSelectedIndices(['index-001', 'index-002']); AddIndicesLogic.actions.submitSelectedIndices(); - expect(AddIndicesLogic.actions.addIndicesToEngine).toHaveBeenCalledTimes(1); - expect(AddIndicesLogic.actions.addIndicesToEngine).toHaveBeenCalledWith([ + expect(AddIndicesLogic.actions.addIndicesToSearchApplication).toHaveBeenCalledTimes(1); + expect(AddIndicesLogic.actions.addIndicesToSearchApplication).toHaveBeenCalledWith([ 'index-001', 'index-002', ]); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.ts similarity index 52% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.ts index add950937b30a..f69e52ced5c24 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/add_indices_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/add_indices_logic.ts @@ -7,14 +7,17 @@ import { kea, MakeLogicType } from 'kea'; -import { UpdateEngineApiLogic } from '../../api/engines/update_engine_api_logic'; +import { UpdateSearchApplicationApiLogic } from '../../api/search_applications/update_search_application_api_logic'; -import { EngineIndicesLogic, EngineIndicesLogicActions } from './engine_indices_logic'; +import { + SearchApplicationIndicesLogic, + SearchApplicationIndicesLogicActions, +} from './search_application_indices_logic'; export interface AddIndicesLogicActions { - addIndicesToEngine: EngineIndicesLogicActions['addIndicesToEngine']; - closeAddIndicesFlyout: EngineIndicesLogicActions['closeAddIndicesFlyout']; - engineUpdated: EngineIndicesLogicActions['engineUpdated']; + addIndicesToSearchApplication: SearchApplicationIndicesLogicActions['addIndicesToSearchApplication']; + closeAddIndicesFlyout: SearchApplicationIndicesLogicActions['closeAddIndicesFlyout']; + searchApplicationUpdated: SearchApplicationIndicesLogicActions['searchApplicationUpdated']; setSelectedIndices: (indices: string[]) => { indices: string[]; }; @@ -23,8 +26,8 @@ export interface AddIndicesLogicActions { export interface AddIndicesLogicValues { selectedIndices: string[]; - updateEngineError: typeof UpdateEngineApiLogic.values.error | undefined; - updateEngineStatus: typeof UpdateEngineApiLogic.values.status; + updateSearchApplicationError: typeof UpdateSearchApplicationApiLogic.values.error | undefined; + updateSearchApplicationStatus: typeof UpdateSearchApplicationApiLogic.values.status; } export const AddIndicesLogic = kea>({ @@ -33,18 +36,24 @@ export const AddIndicesLogic = kea true, }, connect: { - actions: [EngineIndicesLogic, ['addIndicesToEngine', 'engineUpdated', 'closeAddIndicesFlyout']], - values: [UpdateEngineApiLogic, ['status as updateEngineStatus', 'error as updateEngineError']], + actions: [ + SearchApplicationIndicesLogic, + ['addIndicesToSearchApplication', 'searchApplicationUpdated', 'closeAddIndicesFlyout'], + ], + values: [ + UpdateSearchApplicationApiLogic, + ['status as updateSearchApplicationStatus', 'error as updateSearchApplicationError'], + ], }, listeners: ({ actions, values }) => ({ - engineUpdated: () => { + searchApplicationUpdated: () => { actions.closeAddIndicesFlyout(); }, submitSelectedIndices: () => { const { selectedIndices } = values; if (selectedIndices.length === 0) return; - actions.addIndicesToEngine(selectedIndices); + actions.addIndicesToSearchApplication(selectedIndices); }, }), path: ['enterprise_search', 'content', 'add_indices_logic'], diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.test.ts similarity index 85% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.test.ts index fe41dafddd32e..16a210e2bd409 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.test.ts @@ -8,9 +8,9 @@ import { LogicMounter } from '../../../../../__mocks__/kea_logic'; import { Status } from '../../../../../../../common/types/api'; -import { GenerateEngineApiKeyLogic } from '../../../../../enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic'; +import { GenerateSearchApplicationApiKeyLogic } from '../../../../api/search_applications/generate_search_application_api_key_logic'; -import { GenerateApiKeyModalLogic } from './generate_engine_api_key_modal.logic'; +import { GenerateApiKeyModalLogic } from './generate_search_application_api_key_modal.logic'; const DEFAULT_VALUES = { apiKey: '', @@ -21,8 +21,8 @@ const DEFAULT_VALUES = { status: Status.IDLE, }; -describe('GenerateEngineApiKeyModal Logic', () => { - const { mount: apiLogicMount } = new LogicMounter(GenerateEngineApiKeyLogic); +describe('GenerateApiKeyModalLogic', () => { + const { mount: apiLogicMount } = new LogicMounter(GenerateSearchApplicationApiKeyLogic); const { mount } = new LogicMounter(GenerateApiKeyModalLogic); beforeEach(() => { @@ -67,7 +67,7 @@ describe('GenerateEngineApiKeyModal Logic', () => { describe('apiKey', () => { it('updates when apiSuccess listener triggered', () => { expect(GenerateApiKeyModalLogic.values).toEqual(DEFAULT_VALUES); - GenerateEngineApiKeyLogic.actions.apiSuccess({ + GenerateSearchApplicationApiKeyLogic.actions.apiSuccess({ apiKey: { api_key: 'some-api-key-123123', encoded: 'encoded-api-key123123==', @@ -97,7 +97,10 @@ describe('GenerateEngineApiKeyModal Logic', () => { describe('isLoading', () => { it('should update with API status', () => { expect(GenerateApiKeyModalLogic.values).toEqual(DEFAULT_VALUES); - GenerateEngineApiKeyLogic.actions.makeRequest({ engineName: 'puggles', keyName: 'test' }); + GenerateSearchApplicationApiKeyLogic.actions.makeRequest({ + keyName: 'test', + searchApplicationName: 'puggles', + }); expect(GenerateApiKeyModalLogic.values).toEqual({ ...DEFAULT_VALUES, @@ -110,7 +113,7 @@ describe('GenerateEngineApiKeyModal Logic', () => { describe('isSuccess', () => { it('should update with API status', () => { expect(GenerateApiKeyModalLogic.values).toEqual(DEFAULT_VALUES); - GenerateEngineApiKeyLogic.actions.apiSuccess({ + GenerateSearchApplicationApiKeyLogic.actions.apiSuccess({ apiKey: { api_key: 'some-api-key-123123', encoded: 'encoded-api-key123123==', diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.ts similarity index 73% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.ts index 60034e9e808ec..400fc37f50660 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.logic.ts @@ -9,7 +9,7 @@ import { kea, MakeLogicType } from 'kea'; import { Status } from '../../../../../../../common/types/api'; -import { GenerateEngineApiKeyLogic } from '../../../../../enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic'; +import { GenerateSearchApplicationApiKeyLogic } from '../../../../api/search_applications/generate_search_application_api_key_logic'; interface GenerateApiKeyModalActions { setKeyName(keyName: string): { keyName: string }; @@ -17,11 +17,11 @@ interface GenerateApiKeyModalActions { interface GenerateApiKeyModalValues { apiKey: string; - data: typeof GenerateEngineApiKeyLogic.values.data; + data: typeof GenerateSearchApplicationApiKeyLogic.values.data; isLoading: boolean; isSuccess: boolean; keyName: string; - status: typeof GenerateEngineApiKeyLogic.values.status; + status: typeof GenerateSearchApplicationApiKeyLogic.values.status; } export const GenerateApiKeyModalLogic = kea< @@ -31,9 +31,9 @@ export const GenerateApiKeyModalLogic = kea< setKeyName: (keyName) => ({ keyName }), }, connect: { - values: [GenerateEngineApiKeyLogic, ['data', 'status']], + values: [GenerateSearchApplicationApiKeyLogic, ['data', 'status']], }, - path: ['enterprise_search', 'engines', 'api', 'generate_api_key_modal'], + path: ['enterprise_search', 'search_applications', 'api', 'generate_api_key_modal'], reducers: () => ({ keyName: [ '', diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.test.tsx similarity index 68% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.test.tsx index d1b40ee921025..1ebd426b8b9c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.test.tsx @@ -17,10 +17,10 @@ const mockActions = { makeRequest: jest.fn(), setKeyName: jest.fn() }; const mockValues = { apiKey: '', isLoading: false, isSuccess: false, keyName: '' }; -import { GenerateEngineApiKeyModal } from './generate_engine_api_key_modal'; +import { GenerateSearchApplicationApiKeyModal } from './generate_search_application_api_key_modal'; const onCloseMock = jest.fn(); -describe('GenerateEngineApiKeyModal', () => { +describe('GenerateSearchApplicationApiKeyModal', () => { beforeEach(() => { jest.clearAllMocks(); setMockValues(mockValues); @@ -29,7 +29,7 @@ describe('GenerateEngineApiKeyModal', () => { it('renders the empty modal', () => { const wrapper = shallow( - + ); expect(wrapper.find(EuiModal)).toHaveLength(1); @@ -40,20 +40,31 @@ describe('GenerateEngineApiKeyModal', () => { describe('Modal content', () => { it('renders API key name form', () => { const wrapper = shallow( - + ); expect(wrapper.find(EuiFieldText)).toHaveLength(1); expect(wrapper.find('[data-test-subj="generateApiKeyButton"]')).toHaveLength(1); }); - it('pre-set the key name with engine name', () => { - mount(); + it('pre-set the key name with search application name', () => { + mount( + + ); expect(mockActions.setKeyName).toHaveBeenCalledWith('puggles read-only API key'); }); it('sets keyName name on form', () => { const wrapper = shallow( - + ); const textField = wrapper.find(EuiFieldText); expect(textField).toHaveLength(1); @@ -62,15 +73,22 @@ describe('GenerateEngineApiKeyModal', () => { }); it('should trigger api call from the form', () => { - setMockValues({ ...mockValues, engineName: 'test-123', keyName: ' with-spaces ' }); + setMockValues({ + ...mockValues, + searchApplicationName: 'test-123', + keyName: ' with-spaces ', + }); const wrapper = shallow( - + ); expect(wrapper.find(EuiFieldText)).toHaveLength(1); wrapper.find('[data-test-subj="generateApiKeyButton"]').simulate('click'); expect(mockActions.makeRequest).toHaveBeenCalledWith({ - engineName: 'puggles', + searchApplicationName: 'puggles', keyName: 'with-spaces', }); }); @@ -78,12 +96,15 @@ describe('GenerateEngineApiKeyModal', () => { setMockValues({ ...mockValues, apiKey: 'apiKeyFromBackend123123==', - engineName: 'test-123', + searchApplicationName: 'test-123', isSuccess: true, keyName: 'keyname', }); const wrapper = shallow( - + ); expect(wrapper.find(EuiFieldText)).toHaveLength(0); expect(wrapper.find('[data-test-subj="generateApiKeyButton"]')).toHaveLength(0); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.tsx similarity index 78% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.tsx index dac072f46c87f..806b37d809186 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/generate_engine_api_key_modal/generate_engine_api_key_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/generate_api_key_modal/generate_search_application_api_key_modal.tsx @@ -31,33 +31,32 @@ import { import { i18n } from '@kbn/i18n'; -import { GenerateEngineApiKeyLogic } from '../../../../../enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic'; +import { GenerateSearchApplicationApiKeyLogic } from '../../../../api/search_applications/generate_search_application_api_key_logic'; -import { GenerateApiKeyModalLogic } from './generate_engine_api_key_modal.logic'; +import { GenerateApiKeyModalLogic } from './generate_search_application_api_key_modal.logic'; -interface GenerateEngineApiKeyModalProps { - engineName: string; +interface GenerateSearchApplicationApiKeyModalProps { onClose(): void; + searchApplicationName: string; } -export const GenerateEngineApiKeyModal: React.FC = ({ - engineName, - onClose, -}) => { +export const GenerateSearchApplicationApiKeyModal: React.FC< + GenerateSearchApplicationApiKeyModalProps +> = ({ onClose, searchApplicationName }) => { const { keyName, apiKey, isLoading, isSuccess } = useValues(GenerateApiKeyModalLogic); const { setKeyName } = useActions(GenerateApiKeyModalLogic); - const { makeRequest } = useActions(GenerateEngineApiKeyLogic); + const { makeRequest } = useActions(GenerateSearchApplicationApiKeyLogic); useEffect(() => { - setKeyName(`${engineName} read-only API key`); - }, [engineName]); + setKeyName(`${searchApplicationName} read-only API key`); + }, [searchApplicationName]); return ( {i18n.translate( - 'xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.title', + 'xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.title', { defaultMessage: 'Create Search application read-only API Key', } @@ -75,7 +74,7 @@ export const GenerateEngineApiKeyModal: React.FC setKeyName(event.currentTarget.value)} @@ -87,21 +86,21 @@ export const GenerateEngineApiKeyModal: React.FC { makeRequest({ - engineName, keyName: keyName.trim(), + searchApplicationName, }); }} disabled={keyName.trim().length <= 0} > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.generateButton', + 'xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.generateButton', { defaultMessage: 'Generate read-only key', } @@ -127,9 +126,9 @@ export const GenerateEngineApiKeyModal: React.FC

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.apiKeyWarning', + 'xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.apiKeyWarning', { defaultMessage: "Elastic does not store API keys. Once generated, you'll only be able to view the key one time. Make sure you save it somewhere secure. If you lose access to it you'll need to generate a new API key from this screen.", @@ -166,12 +165,12 @@ export const GenerateEngineApiKeyModal: React.FC {apiKey ? ( {i18n.translate( - 'xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.done', + 'xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.done', { defaultMessage: 'Done', } @@ -179,11 +178,11 @@ export const GenerateEngineApiKeyModal: React.FC ) : ( {i18n.translate( - 'xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.cancel', + 'xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.cancel', { defaultMessage: 'Cancel', } diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_api.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api.tsx similarity index 72% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_api.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api.tsx index d615cd12c72e1..bc03e1236b4a7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_api.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api.tsx @@ -27,11 +27,11 @@ import { CloudDetails, useCloudDetails } from '../../../../shared/cloud_details/ import { docLinks } from '../../../../shared/doc_links'; import { KibanaLogic } from '../../../../shared/kibana'; -import { EngineViewLogic } from '../engine_view_logic'; +import { SearchApplicationViewLogic } from '../search_application_view_logic'; -import { EngineApiIntegrationStage } from './engine_api_integration'; -import { EngineApiLogic } from './engine_api_logic'; -import { GenerateEngineApiKeyModal } from './generate_engine_api_key_modal/generate_engine_api_key_modal'; +import { GenerateSearchApplicationApiKeyModal } from './generate_api_key_modal/generate_search_application_api_key_modal'; +import { SearchApplicationApiIntegrationStage } from './search_application_api_integration'; +import { SearchApplicationApiLogic } from './search_application_api_logic'; export const elasticsearchUrl = (cloudContext: CloudDetails): string => { const defaultUrl = 'http://localhost:9200'; @@ -40,9 +40,9 @@ export const elasticsearchUrl = (cloudContext: CloudDetails): string => { }; export const SearchApplicationAPI = () => { - const { engineName: searchApplicationName } = useValues(EngineViewLogic); - const { isGenerateModalOpen } = useValues(EngineApiLogic); - const { openGenerateModal, closeGenerateModal } = useActions(EngineApiLogic); + const { searchApplicationName } = useValues(SearchApplicationViewLogic); + const { isGenerateModalOpen } = useValues(SearchApplicationApiLogic); + const { openGenerateModal, closeGenerateModal } = useActions(SearchApplicationApiLogic); const cloudContext = useCloudDetails(); const steps = [ @@ -52,13 +52,13 @@ export const SearchApplicationAPI = () => {

@@ -80,13 +80,13 @@ export const SearchApplicationAPI = () => {

@@ -98,7 +98,7 @@ export const SearchApplicationAPI = () => { ), title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step1.setUpSearchtemplate.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step1.setUpSearchtemplate.title', { defaultMessage: 'Set up your search template', } @@ -110,13 +110,13 @@ export const SearchApplicationAPI = () => {

@@ -135,7 +135,7 @@ export const SearchApplicationAPI = () => { data-telemetry-id="entSearchApplications-searchApi-step2-createApiKeyButton" > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step2.createAPIKeyButton', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step2.createAPIKeyButton', { defaultMessage: 'Create API Key', } @@ -154,7 +154,7 @@ export const SearchApplicationAPI = () => { } > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step2.viewKeysButton', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step2.viewKeysButton', { defaultMessage: 'View Keys', } @@ -165,7 +165,7 @@ export const SearchApplicationAPI = () => { ), title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step2.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step2.title', { defaultMessage: 'Generate and save API key', } @@ -177,7 +177,7 @@ export const SearchApplicationAPI = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step3.copyEndpointDescription', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step3.copyEndpointDescription', { defaultMessage: "Here's the URL for your endpoint:", } @@ -197,16 +197,16 @@ export const SearchApplicationAPI = () => { ), title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step3.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step3.title', { defaultMessage: 'Copy your Search endpoint', } ), }, { - children: , + children: , title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.step4.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.step4.title', { defaultMessage: 'Learn how to call your endpoint', } @@ -217,22 +217,22 @@ export const SearchApplicationAPI = () => { return ( <> {isGenerateModalOpen ? ( - ) : null} } > { data-telemetry-id="entSearchApplications-searchApi-documentation-viewDocumentaion" > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.searchApiCallout.body.searchApiDocLink', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.searchApiCallout.body.searchApiDocLink', { defaultMessage: 'Search API', } @@ -256,7 +256,7 @@ export const SearchApplicationAPI = () => { data-telemetry-id="entSearchApplications-searchTemplate-documentation-viewDocumentaion" > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.searchApiCallout.body.searchTemplateDocLink', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.searchApiCallout.body.searchTemplateDocLink', { defaultMessage: 'search template', } @@ -267,7 +267,7 @@ export const SearchApplicationAPI = () => { /> { data-telemetry-id="entSearchApplications-searchApi-learnMoreDocumentation-viewDocumentaion" > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchApi.searchApiCallout.body.searchApiDocumentationLink', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchApi.searchApiCallout.body.searchApiDocumentationLink', { defaultMessage: 'Learn more about the Search API', } diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_integration.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_integration.tsx similarity index 78% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_integration.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_integration.tsx index 090e96758fe05..4e481d30ea7d0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_integration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_integration.tsx @@ -27,11 +27,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { useCloudDetails } from '../../../../shared/cloud_details/cloud_details'; import { docLinks } from '../../../../shared/doc_links'; import { KibanaLogic } from '../../../../shared/kibana'; -import { EngineViewLogic } from '../engine_view_logic'; - -import { EngineApiLogic } from './engine_api_logic'; +import { SearchApplicationViewLogic } from '../search_application_view_logic'; import { elasticsearchUrl } from './search_application_api'; +import { SearchApplicationApiLogic } from './search_application_api_logic'; const clientSnippet = (esUrl: string, searchApplicationName: string, apiKey: string) => ` import Client from '@elastic/search-application-client' @@ -82,46 +81,46 @@ interface Tab { title: string; } -export const EngineApiIntegrationStage: React.FC = () => { +export const SearchApplicationApiIntegrationStage: React.FC = () => { const { application, share: { url }, } = useValues(KibanaLogic); const [selectedTab, setSelectedTab] = React.useState('apirequest'); - const { engineName } = useValues(EngineViewLogic); - const { apiKey } = useValues(EngineApiLogic); + const { searchApplicationName } = useValues(SearchApplicationViewLogic); + const { apiKey } = useValues(SearchApplicationApiLogic); const cloudContext = useCloudDetails(); const params = { query: 'pizza', myCustomParameter: 'example value' }; const Tabs: Record = { apirequest: { - code: apiRequestSnippet(engineName, params), + code: apiRequestSnippet(searchApplicationName, params), copy: false, language: 'http', title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.tab.apirequestTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.tab.apirequestTitle', { defaultMessage: 'API Request', } ), }, client: { - code: clientSnippet(elasticsearchUrl(cloudContext), engineName, apiKey), + code: clientSnippet(elasticsearchUrl(cloudContext), searchApplicationName, apiKey), copy: true, language: 'javascript', title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.tab.clientTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.tab.clientTitle', { defaultMessage: 'Javascript Client', } ), }, curl: { - code: cURLSnippet(elasticsearchUrl(cloudContext), engineName, apiKey, params), + code: cURLSnippet(elasticsearchUrl(cloudContext), searchApplicationName, apiKey, params), copy: true, language: 'bash', title: i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.tab.curlTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.tab.curlTitle', { defaultMessage: 'cURL', } @@ -134,7 +133,7 @@ export const EngineApiIntegrationStage: React.FC = () => { ? url.locators.get('CONSOLE_APP_LOCATOR')?.useUrl( { loadFrom: `data:text/plain,${compressToEncodedURIComponent( - consoleRequest(engineName, params) + consoleRequest(searchApplicationName, params) )}`, }, undefined, @@ -147,13 +146,13 @@ export const EngineApiIntegrationStage: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step4.clientsDocumenation', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step4.clientsDocumenation', { defaultMessage: 'programming language clients', } @@ -184,7 +183,7 @@ export const EngineApiIntegrationStage: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step4.installationTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step4.installationTitle', { defaultMessage: 'Installation', } @@ -196,7 +195,7 @@ export const EngineApiIntegrationStage: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step4.npmInstallDescription', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step4.npmInstallDescription', { defaultMessage: 'Search application client is accessible from NPM package registry', @@ -215,7 +214,7 @@ export const EngineApiIntegrationStage: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step4.cdnInstallDescription', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step4.cdnInstallDescription', { defaultMessage: 'or via CDN', } @@ -233,7 +232,7 @@ export const EngineApiIntegrationStage: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step4.clientUsageTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step4.clientUsageTitle', { defaultMessage: 'Usage', } @@ -244,14 +243,14 @@ export const EngineApiIntegrationStage: React.FC = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.safeSearchApi.step3.clientDocumenation', + 'xpack.enterpriseSearch.searchApplications.searchApplication.safeSearchApi.step3.clientDocumenation', { defaultMessage: 'how to guide', } @@ -274,7 +273,7 @@ export const EngineApiIntegrationStage: React.FC = () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_logic.ts similarity index 54% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_logic.ts index f996fe836d112..565f337811a91 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_api_logic.ts @@ -8,38 +8,43 @@ import { kea, MakeLogicType } from 'kea'; import { Status } from '../../../../../../common/types/api'; -import { GenerateEngineApiKeyLogic } from '../../../../enterprise_search_content/api/generate_engine_api_key/generate_engine_api_key_logic'; +import { GenerateSearchApplicationApiKeyLogic } from '../../../api/search_applications/generate_search_application_api_key_logic'; -interface EngineAPIActions { - apiError: typeof GenerateEngineApiKeyLogic.actions.apiError; - apiReset: typeof GenerateEngineApiKeyLogic.actions.apiReset; +interface SearchApplicationAPIActions { + apiError: typeof GenerateSearchApplicationApiKeyLogic.actions.apiError; + apiReset: typeof GenerateSearchApplicationApiKeyLogic.actions.apiReset; closeGenerateModal: void; openGenerateModal: void; } -export interface EngineAPILogicValues { +export interface SearchApplicationAPILogicValues { apiKey: string; - apiKeyData: typeof GenerateEngineApiKeyLogic.values.data; - apiKeyStatus: typeof GenerateEngineApiKeyLogic.values.status; + apiKeyData: typeof GenerateSearchApplicationApiKeyLogic.values.data; + apiKeyStatus: typeof GenerateSearchApplicationApiKeyLogic.values.status; isError: boolean; isGenerateModalOpen: boolean; } -export const EngineApiLogic = kea>({ +export const SearchApplicationApiLogic = kea< + MakeLogicType +>({ actions: { closeGenerateModal: true, openGenerateModal: true, }, connect: { - actions: [GenerateEngineApiKeyLogic, ['apiReset']], - values: [GenerateEngineApiKeyLogic, ['data as apiKeyData', 'status as apiKeyStatus']], + actions: [GenerateSearchApplicationApiKeyLogic, ['apiReset']], + values: [ + GenerateSearchApplicationApiKeyLogic, + ['data as apiKeyData', 'status as apiKeyStatus'], + ], }, listeners: ({ actions }) => ({ openGenerateModal: () => { actions.apiReset(); }, }), - path: ['enterprise_search', 'content', 'engine_api_logic'], + path: ['enterprise_search', 'content', 'search_application_api_logic'], reducers: () => ({ isGenerateModalOpen: [ false, diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_connect.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx similarity index 67% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_connect.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx index 8d1c896f6ac54..f3047ac23b645 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/engine_connect.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_connect.tsx @@ -15,14 +15,14 @@ import { i18n } from '@kbn/i18n'; import { generateEncodedPath } from '../../../../shared/encode_path_params'; import { KibanaLogic } from '../../../../shared/kibana'; import { - EngineViewTabs, + SearchApplicationViewTabs, SearchApplicationConnectTabs, SEARCH_APPLICATION_CONNECT_PATH, } from '../../../routes'; -import { EnterpriseSearchEnginesPageTemplate } from '../../layout/engines_page_template'; +import { EnterpriseSearchApplicationsPageTemplate } from '../../layout/page_template'; -import { EngineError } from '../engine_error'; -import { EngineViewLogic } from '../engine_view_logic'; +import { SearchApplicationError } from '../search_application_error'; +import { SearchApplicationViewLogic } from '../search_application_view_logic'; import { SearchApplicationAPI } from './search_application_api'; @@ -30,19 +30,19 @@ import '../search_application_layout.scss'; import { SearchApplicationDocumentation } from './search_application_documentation'; const pageTitle = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.connect.pageTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.connect.pageTitle', { defaultMessage: 'Connect', } ); const SAFE_SEARCH_API_TAB_TITLE = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.connect.searchAPITabTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.connect.searchAPITabTitle', { defaultMessage: 'Search API', } ); const DOCUMENTATION_TAB_TITLE = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.connect.documentationTabTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.connect.documentationTabTitle', { defaultMessage: 'Documentation', } @@ -59,8 +59,10 @@ const getTabBreadCrumb = (tabId: string) => { } }; -export const EngineConnect: React.FC = () => { - const { engineName, isLoadingEngine, hasSchemaConflicts } = useValues(EngineViewLogic); +export const SearchApplicationConnect: React.FC = () => { + const { searchApplicationName, isLoadingSearchApplication, hasSchemaConflicts } = useValues( + SearchApplicationViewLogic + ); const { connectTabId = SearchApplicationConnectTabs.SEARCHAPI } = useParams<{ connectTabId?: string; }>(); @@ -69,36 +71,36 @@ export const EngineConnect: React.FC = () => { KibanaLogic.values.navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONNECT_PATH, { connectTabId: tab, - engineName, + searchApplicationName, }) ); }; if (!ConnectTabs.includes(connectTabId)) { return ( - - - + + ); } return ( - { }, ], }} - engineName={engineName} + searchApplicationName={searchApplicationName} hasSchemaConflicts={hasSchemaConflicts} > {connectTabId === SearchApplicationConnectTabs.SEARCHAPI && } {connectTabId === SearchApplicationConnectTabs.DOCUMENTATION && ( )} - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_documentation.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_documentation.tsx similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_documentation.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_documentation.tsx index 4edebb6989715..15d3bd6541762 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_connect/search_application_documentation.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/connect/search_application_documentation.tsx @@ -34,7 +34,7 @@ export const SearchApplicationDocumentation = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchApplication.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchApplication.title', { defaultMessage: 'Learn more about Search Applications', } @@ -45,7 +45,7 @@ export const SearchApplicationDocumentation = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchApplication.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchApplication.description', { defaultMessage: 'Search Applications help make your Elasticsearch data easily searchable for end users.', @@ -56,7 +56,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchApplication.readDocumentation', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchApplication.readDocumentation', { defaultMessage: 'Read our documentation', } @@ -74,7 +74,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.manageAPIKeys.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.manageAPIKeys.title', { defaultMessage: 'Manage API Keys' } )} @@ -87,7 +87,7 @@ export const SearchApplicationDocumentation = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.manageAPIKeys.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.manageAPIKeys.description', { defaultMessage: 'API keys provide a secure way to control access to Elasticsearch data and functionalities, and to limit access to specific indices or actions.', @@ -100,7 +100,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.manageAPIKeys.learnMore', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.manageAPIKeys.learnMore', { defaultMessage: 'Learn more', } @@ -121,7 +121,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.languageClients.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.languageClients.title', { defaultMessage: 'Build with language clients' } )} @@ -134,7 +134,7 @@ export const SearchApplicationDocumentation = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.languageClients.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.languageClients.description', { defaultMessage: 'Develop for Elasticsearch in your preferred programming languages through our first and third-party supported clients.', @@ -147,7 +147,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.languageClients.learnMore', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.languageClients.learnMore', { defaultMessage: 'Learn more', } @@ -168,7 +168,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchInsights.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchInsights.title', { defaultMessage: 'Search insights' } )} @@ -181,7 +181,7 @@ export const SearchApplicationDocumentation = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchInsights.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchInsights.description', { defaultMessage: 'Gain insights into the performance of your search application with Behavioral Analytics.', @@ -194,7 +194,7 @@ export const SearchApplicationDocumentation = () => { {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.documentation.searchInsights.learnMore', + 'xpack.enterpriseSearch.searchApplications.searchApplication.documentation.searchInsights.learnMore', { defaultMessage: 'Learn more', } diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/field_icon.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/field_icon.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/field_icon.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/field_icon.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/header_docs_action.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/header_docs_action.tsx similarity index 60% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/header_docs_action.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/header_docs_action.tsx index 9b17ffb319ab6..12754723736bd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/header_docs_action.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/header_docs_action.tsx @@ -13,19 +13,22 @@ import { i18n } from '@kbn/i18n'; import { docLinks } from '../../../shared/doc_links'; -export const EngineHeaderDocsAction: React.FC = () => ( +export const SearchApplicationHeaderDocsAction: React.FC = () => ( - {i18n.translate('xpack.enterpriseSearch.content.engine.header.searchApplicationsDoc', { - defaultMessage: 'Search Applications Doc', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.header.searchApplicationsDoc', + { + defaultMessage: 'Search Applications Doc', + } + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/search_application_content.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_content.tsx similarity index 62% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/search_application_content.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_content.tsx index 117e823d1fc8f..577154e27163a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/search_application_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_content.tsx @@ -17,35 +17,35 @@ import { generateEncodedPath } from '../../../shared/encode_path_params'; import { KibanaLogic } from '../../../shared/kibana'; import { - ENGINE_PATH, + SEARCH_APPLICATION_PATH, SEARCH_APPLICATION_CONTENT_PATH, - EngineViewTabs, + SearchApplicationViewTabs, SearchApplicationContentTabs, } from '../../routes'; -import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_template'; +import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; import { AddIndicesFlyout } from './add_indices_flyout'; -import { EngineError } from './engine_error'; -import { EngineIndices } from './engine_indices'; -import { EngineIndicesLogic } from './engine_indices_logic'; -import { EngineSchema } from './engine_schema'; -import { EngineViewLogic } from './engine_view_logic'; +import { SearchApplicationError } from './search_application_error'; +import { SearchApplicationIndices } from './search_application_indices'; +import { SearchApplicationIndicesLogic } from './search_application_indices_logic'; +import { SearchApplicationSchema } from './search_application_schema'; +import { SearchApplicationViewLogic } from './search_application_view_logic'; import './search_application_layout.scss'; const pageTitle = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.content.pageTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.content.pageTitle', { defaultMessage: 'Content', } ); const INDICES_TAB_TITLE = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.content.indicesTabTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.content.indicesTabTitle', { defaultMessage: 'Indices', } ); const SCHEMA_TAB_TITLE = i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.content.schemaTabTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.content.schemaTabTitle', { defaultMessage: 'Schema', } @@ -65,30 +65,32 @@ const getTabBreadCrumb = (tabId: string) => { const ContentTabs: string[] = Object.values(SearchApplicationContentTabs); export const SearchApplicationContent = () => { - const { engineName, isLoadingEngine, hasSchemaConflicts } = useValues(EngineViewLogic); - const { addIndicesFlyoutOpen } = useValues(EngineIndicesLogic); - const { closeAddIndicesFlyout, openAddIndicesFlyout } = useActions(EngineIndicesLogic); + const { searchApplicationName, isLoadingSearchApplication, hasSchemaConflicts } = useValues( + SearchApplicationViewLogic + ); + const { addIndicesFlyoutOpen } = useValues(SearchApplicationIndicesLogic); + const { closeAddIndicesFlyout, openAddIndicesFlyout } = useActions(SearchApplicationIndicesLogic); const { contentTabId = SearchApplicationContentTabs.INDICES } = useParams<{ contentTabId?: string; }>(); if (!ContentTabs.includes(contentTabId)) { return ( - - - + + ); } @@ -96,16 +98,16 @@ export const SearchApplicationContent = () => { KibanaLogic.values.navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONTENT_PATH, { contentTabId: tab, - engineName, + searchApplicationName, }) ); }; return ( - { color: 'primary', onClick: () => KibanaLogic.values.navigateToUrl( - generateEncodedPath(ENGINE_PATH, { - engineName, + generateEncodedPath(SEARCH_APPLICATION_PATH, { + searchApplicationName, }) ), text: ( <> - {engineName} + {searchApplicationName} ), }, @@ -129,14 +131,17 @@ export const SearchApplicationContent = () => { rightSideItems: [ - {i18n.translate('xpack.enterpriseSearch.content.engine.indices.addNewIndicesButton', { - defaultMessage: 'Add new indices', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.addNewIndicesButton', + { + defaultMessage: 'Add new indices', + } + )} , ], tabs: [ @@ -157,12 +162,12 @@ export const SearchApplicationContent = () => { }, ], }} - engineName={engineName} + searchApplicationName={searchApplicationName} hasSchemaConflicts={hasSchemaConflicts} > - {contentTabId === SearchApplicationContentTabs.INDICES && } - {contentTabId === SearchApplicationContentTabs.SCHEMA && } + {contentTabId === SearchApplicationContentTabs.INDICES && } + {contentTabId === SearchApplicationContentTabs.SCHEMA && } {addIndicesFlyoutOpen && } - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx similarity index 88% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx index 9b8df10b5bdf4..d24675822a730 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.test.tsx @@ -16,9 +16,9 @@ import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; import { mountWithIntl } from '../../../test_helpers'; -import { EngineError } from './engine_error'; +import { SearchApplicationError } from './search_application_error'; -describe('EngineError', () => { +describe('SearchApplicationError', () => { beforeEach(() => { jest.clearAllMocks(); setMockValues({}); @@ -32,7 +32,7 @@ describe('EngineError', () => { statusCode: 404, }, } as HttpError; - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); expect(wrapper.find(NotFoundPrompt)).toHaveLength(1); expect(wrapper.find(SendEnterpriseSearchTelemetry)).toHaveLength(1); @@ -55,7 +55,7 @@ describe('EngineError', () => { statusCode: 500, }, } as HttpError; - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); expect(wrapper.find(ErrorStatePrompt)).toHaveLength(1); expect(wrapper.find(SendEnterpriseSearchTelemetry)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx similarity index 80% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx index deb1051dae044..49a783dbbcec3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_error.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_error.tsx @@ -16,9 +16,9 @@ import { ErrorStatePrompt } from '../../../shared/error_state'; import { NotFoundPrompt } from '../../../shared/not_found'; import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; -import { ENGINES_PATH } from '../../routes'; +import { SEARCH_APPLICATIONS_PATH } from '../../routes'; -export const EngineError: React.FC<{ error?: HttpError; notFound?: boolean }> = ({ +export const SearchApplicationError: React.FC<{ error?: HttpError; notFound?: boolean }> = ({ error, notFound, }) => { @@ -28,12 +28,12 @@ export const EngineError: React.FC<{ error?: HttpError; notFound?: boolean }> = diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices.tsx similarity index 72% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices.tsx index ceaf3e9857f93..7cd9d3bae3d3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_indices.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices.tsx @@ -33,18 +33,18 @@ import { KibanaLogic } from '../../../shared/kibana'; import { EuiLinkTo } from '../../../shared/react_router_helpers'; import { TelemetryLogic } from '../../../shared/telemetry/telemetry_logic'; -import { EngineIndicesLogic } from './engine_indices_logic'; +import { SearchApplicationIndicesLogic } from './search_application_indices_logic'; -export const EngineIndices: React.FC = () => { +export const SearchApplicationIndices: React.FC = () => { const subduedBackground = useEuiBackgroundColor('subdued'); const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic); - const { engineData } = useValues(EngineIndicesLogic); - const { removeIndexFromEngine } = useActions(EngineIndicesLogic); + const { searchApplicationData } = useValues(SearchApplicationIndicesLogic); + const { removeIndexFromSearchApplication } = useActions(SearchApplicationIndicesLogic); const { navigateToUrl } = useValues(KibanaLogic); const [removeIndexConfirm, setConfirmRemoveIndex] = useState(null); - if (!engineData) return null; - const { indices } = engineData; + if (!searchApplicationData) return null; + const { indices } = searchApplicationData; const hasAllUnreachableIndices = indices.every(({ health }) => health === 'unknown'); @@ -53,9 +53,9 @@ export const EngineIndices: React.FC = () => { const removeIndexAction: EuiTableActionsColumnType['actions'][0] = { color: 'danger', - 'data-test-subj': 'engine-remove-index-btn', + 'data-test-subj': 'search-application-remove-index-btn', description: i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.title', { defaultMessage: 'Remove this index from search application', } @@ -64,7 +64,7 @@ export const EngineIndices: React.FC = () => { isPrimary: false, name: (index: EnterpriseSearchApplicationIndex) => i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.caption', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.caption', { defaultMessage: 'Remove index {indexName}', values: { @@ -84,16 +84,19 @@ export const EngineIndices: React.FC = () => { const columns: Array> = [ { - name: i18n.translate('xpack.enterpriseSearch.content.engine.indices.name.columnTitle', { - defaultMessage: 'Index name', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.name.columnTitle', + { + defaultMessage: 'Index name', + } + ), render: ({ health, name }: EnterpriseSearchApplicationIndex) => health === 'unknown' ? ( name ) : ( { }, { field: 'health', - name: i18n.translate('xpack.enterpriseSearch.content.engine.indices.health.columnTitle', { - defaultMessage: 'Index health', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.health.columnTitle', + { + defaultMessage: 'Index health', + } + ), render: (health: 'red' | 'green' | 'yellow' | 'unavailable') => ( @@ -122,13 +128,16 @@ export const EngineIndices: React.FC = () => { }, { field: 'count', - name: i18n.translate('xpack.enterpriseSearch.content.engine.indices.docsCount.columnTitle', { - defaultMessage: 'Docs count', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.columnTitle', + { + defaultMessage: 'Docs count', + } + ), render: (count: number | null) => count === null ? i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.docsCount.notAvailableLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.notAvailableLabel', { defaultMessage: 'N/A' } ) : count, @@ -140,9 +149,9 @@ export const EngineIndices: React.FC = () => { actions: [ { available: (index) => index.health !== 'unknown', - 'data-test-subj': 'engine-view-index-btn', + 'data-test-subj': 'search-application-view-index-btn', description: i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.title', { defaultMessage: 'View this index', } @@ -151,7 +160,7 @@ export const EngineIndices: React.FC = () => { isPrimary: false, name: (index) => i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.caption', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.caption', { defaultMessage: 'View index {indexName}', values: { @@ -172,9 +181,12 @@ export const EngineIndices: React.FC = () => { }, ...(indices.length > 1 ? [removeIndexAction] : []), ], - name: i18n.translate('xpack.enterpriseSearch.content.engine.indices.actions.columnTitle', { - defaultMessage: 'Actions', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.columnTitle', + { + defaultMessage: 'Actions', + } + ), width: '10%', }, ]; @@ -189,14 +201,14 @@ export const EngineIndices: React.FC = () => { hasAllUnreachableIndices ? ( <> {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.allUnknownIndicesCallout.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.allUnknownIndicesCallout.title', { defaultMessage: 'All of your indices are unavailable.' } )} ) : ( <> {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.someUnknownIndicesCallout.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.title', { defaultMessage: 'Some of your indices are unavailable.' } )} @@ -207,7 +219,7 @@ export const EngineIndices: React.FC = () => { {hasAllUnreachableIndices ? ( <> {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.allUnknownIndicesCallout.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.allUnknownIndicesCallout.description', { defaultMessage: 'Your search application has no reachable indices. Add some indices and check for any pending operations or errors on affected indices, or remove indices that should no longer be used by this search application.', @@ -217,7 +229,7 @@ export const EngineIndices: React.FC = () => { ) : ( <> {i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.someUnknownIndicesCallout.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.someUnknownIndicesCallout.description', { defaultMessage: 'Some data might be unreachable from this search application. Check for any pending operations or errors on affected indices, or remove indices that should no longer be used by this search application.', @@ -244,7 +256,7 @@ export const EngineIndices: React.FC = () => { box: { incremental: true, placeholder: i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.searchPlaceholder', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder', { defaultMessage: 'Filter indices' } ), schema: true, @@ -257,7 +269,7 @@ export const EngineIndices: React.FC = () => { setConfirmRemoveIndex(null)} onConfirm={() => { - removeIndexFromEngine(removeIndexConfirm); + removeIndexFromSearchApplication(removeIndexConfirm); setConfirmRemoveIndex(null); sendEnterpriseSearchTelemetry({ action: 'clicked', @@ -265,13 +277,13 @@ export const EngineIndices: React.FC = () => { }); }} title={i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.title', { defaultMessage: 'Remove this index from the search application' } )} buttonColor="danger" cancelButtonText={CANCEL_BUTTON_LABEL} confirmButtonText={i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.text', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.text', { defaultMessage: 'Yes, Remove This Index', } @@ -282,7 +294,7 @@ export const EngineIndices: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.description', { defaultMessage: "This won't delete the index. You may add it back to this search application at a later time.", diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.test.ts new file mode 100644 index 0000000000000..f5676faa47769 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.test.ts @@ -0,0 +1,138 @@ +/* + * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; + +import { EnterpriseSearchApplicationDetails } from '../../../../../common/types/search_applications'; +import { FetchSearchApplicationApiLogic } from '../../api/search_applications/fetch_search_application_api_logic'; + +import { + SearchApplicationIndicesLogic, + SearchApplicationIndicesLogicValues, +} from './search_application_indices_logic'; + +const DEFAULT_VALUES: SearchApplicationIndicesLogicValues = { + addIndicesFlyoutOpen: false, + isLoadingSearchApplication: true, + searchApplicationData: undefined, + searchApplicationName: 'my-test-search-application', +}; + +const mockSearchApplicationData: EnterpriseSearchApplicationDetails = { + indices: [ + { + count: 10, + health: 'green', + name: 'search-001', + }, + { + count: 1000, + health: 'yellow', + name: 'search-002', + }, + ], + name: DEFAULT_VALUES.searchApplicationName, + template: { + script: { + lang: 'mustache', + params: { query_string: '*' }, + source: '', + }, + }, + updated_at_millis: 1679501369566, +}; + +describe('SearchApplicationViewLogic', () => { + const { mount } = new LogicMounter(SearchApplicationIndicesLogic); + const { mount: mountFetchSearchApplicationApiLogic } = new LogicMounter( + FetchSearchApplicationApiLogic + ); + + beforeEach(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + + mountFetchSearchApplicationApiLogic(); + mount( + { + searchApplicationName: DEFAULT_VALUES.searchApplicationName, + }, + { + searchApplicationName: DEFAULT_VALUES.searchApplicationName, + } + ); + }); + + it('has expected default values', () => { + expect(SearchApplicationIndicesLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('listeners', () => { + beforeEach(() => { + FetchSearchApplicationApiLogic.actions.apiSuccess(mockSearchApplicationData); + }); + it('has search application data', () => { + expect(SearchApplicationIndicesLogic.values.searchApplicationData).toEqual( + mockSearchApplicationData + ); + }); + + describe('searchApplicationUpdated', () => { + it('fetches new search application details', () => { + jest.spyOn(SearchApplicationIndicesLogic.actions, 'fetchSearchApplication'); + + SearchApplicationIndicesLogic.actions.searchApplicationUpdated({ + ...mockSearchApplicationData, + indices: mockSearchApplicationData.indices.map((index) => index.name), + }); + + expect(SearchApplicationIndicesLogic.actions.fetchSearchApplication).toHaveBeenCalledTimes( + 1 + ); + expect(SearchApplicationIndicesLogic.actions.fetchSearchApplication).toHaveBeenCalledWith({ + name: DEFAULT_VALUES.searchApplicationName, + }); + }); + }); + describe('removeIndexFromSearchApplication', () => { + it('updated search application removing the given index', () => { + jest.spyOn(SearchApplicationIndicesLogic.actions, 'updateSearchApplicationRequest'); + + SearchApplicationIndicesLogic.actions.removeIndexFromSearchApplication( + mockSearchApplicationData.indices[0].name + ); + + expect( + SearchApplicationIndicesLogic.actions.updateSearchApplicationRequest + ).toHaveBeenCalledTimes(1); + expect( + SearchApplicationIndicesLogic.actions.updateSearchApplicationRequest + ).toHaveBeenCalledWith({ + name: DEFAULT_VALUES.searchApplicationName, + indices: ['search-002'], + }); + }); + }); + describe('addIndicesToSearchApplication', () => { + it('updated search application removing the given index', () => { + jest.spyOn(SearchApplicationIndicesLogic.actions, 'updateSearchApplicationRequest'); + + SearchApplicationIndicesLogic.actions.addIndicesToSearchApplication(['search-003']); + + expect( + SearchApplicationIndicesLogic.actions.updateSearchApplicationRequest + ).toHaveBeenCalledTimes(1); + expect( + SearchApplicationIndicesLogic.actions.updateSearchApplicationRequest + ).toHaveBeenCalledWith({ + name: DEFAULT_VALUES.searchApplicationName, + indices: ['search-001', 'search-002', 'search-003'], + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.ts new file mode 100644 index 0000000000000..bd994eff66b8c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_indices_logic.ts @@ -0,0 +1,93 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { + UpdateSearchApplicationApiLogic, + UpdateSearchApplicationApiLogicActions, +} from '../../api/search_applications/update_search_application_api_logic'; + +import { + SearchApplicationViewActions, + SearchApplicationViewLogic, + SearchApplicationViewValues, +} from './search_application_view_logic'; + +export interface SearchApplicationIndicesLogicActions { + addIndicesToSearchApplication: (indices: string[]) => { indices: string[] }; + closeAddIndicesFlyout: () => void; + fetchSearchApplication: SearchApplicationViewActions['fetchSearchApplication']; + openAddIndicesFlyout: () => void; + removeIndexFromSearchApplication: (indexName: string) => { indexName: string }; + searchApplicationUpdated: UpdateSearchApplicationApiLogicActions['apiSuccess']; + updateSearchApplicationRequest: UpdateSearchApplicationApiLogicActions['makeRequest']; +} + +export interface SearchApplicationIndicesLogicValues { + addIndicesFlyoutOpen: boolean; + isLoadingSearchApplication: SearchApplicationViewValues['isLoadingSearchApplication']; + searchApplicationData: SearchApplicationViewValues['searchApplicationData']; + searchApplicationName: SearchApplicationViewValues['searchApplicationName']; +} + +export const SearchApplicationIndicesLogic = kea< + MakeLogicType +>({ + actions: { + addIndicesToSearchApplication: (indices) => ({ indices }), + closeAddIndicesFlyout: () => true, + openAddIndicesFlyout: () => true, + removeIndexFromSearchApplication: (indexName) => ({ indexName }), + }, + connect: { + actions: [ + SearchApplicationViewLogic, + ['fetchSearchApplication'], + UpdateSearchApplicationApiLogic, + ['makeRequest as updateSearchApplicationRequest', 'apiSuccess as searchApplicationUpdated'], + ], + values: [ + SearchApplicationViewLogic, + ['searchApplicationData', 'searchApplicationName', 'isLoadingSearchApplication'], + ], + }, + listeners: ({ actions, values }) => ({ + addIndicesToSearchApplication: ({ indices }) => { + if (!values.searchApplicationData) return; + const existingIndicesNames = values.searchApplicationData.indices.map((index) => index.name); + const updatedIndices = Array.from(new Set([...existingIndicesNames, ...indices])); + actions.updateSearchApplicationRequest({ + name: values.searchApplicationName, + indices: updatedIndices, + }); + }, + searchApplicationUpdated: () => { + actions.fetchSearchApplication({ name: values.searchApplicationName }); + }, + removeIndexFromSearchApplication: ({ indexName }) => { + if (!values.searchApplicationData) return; + const updatedIndices = values.searchApplicationData.indices + .filter((index) => index.name !== indexName) + .map((index) => index.name); + actions.updateSearchApplicationRequest({ + name: values.searchApplicationName, + indices: updatedIndices, + }); + }, + }), + path: ['enterprise_search', 'content', 'search_application_indices_logic'], + reducers: { + addIndicesFlyoutOpen: [ + false, + { + closeAddIndicesFlyout: () => false, + openAddIndicesFlyout: () => true, + }, + ], + }, +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/search_application_layout.scss b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_layout.scss similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/search_application_layout.scss rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_layout.scss diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_name_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_name_logic.ts new file mode 100644 index 0000000000000..3aec921316ff5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_name_logic.ts @@ -0,0 +1,40 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +export interface SearchApplicationNameProps { + searchApplicationName: string; +} + +export type SearchApplicationNameValues = SearchApplicationNameProps; + +export interface SearchApplicationNameActions { + setSearchApplicationName: (name: string) => { name: string }; +} + +export const SearchApplicationNameLogic = kea< + MakeLogicType< + SearchApplicationNameValues, + SearchApplicationNameActions, + SearchApplicationNameProps + > +>({ + actions: { + setSearchApplicationName: (name) => ({ name }), + }, + path: ['enterprise_search', 'search_applications', 'search_application_name'], + reducers: ({ props }) => ({ + searchApplicationName: [ + // Short-circuiting this to empty string is necessary to enable testing logics relying on this + props.searchApplicationName ?? '', + { + setSearchApplicationName: (_, { name }) => name, + }, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_router.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_router.tsx new file mode 100644 index 0000000000000..a3d8dea27ea57 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_router.tsx @@ -0,0 +1,58 @@ +/* + * 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 React, { useEffect } from 'react'; +import { Redirect, Switch, useParams } from 'react-router-dom'; + +import { useActions } from 'kea'; + +import { Route } from '@kbn/shared-ux-router'; + +import { generateEncodedPath } from '../../../shared/encode_path_params'; +import { + SEARCH_APPLICATION_PATH, + SEARCH_APPLICATION_TAB_PATH, + SearchApplicationViewTabs, +} from '../../routes'; + +import { SearchApplicationNameLogic } from './search_application_name_logic'; +import { SearchApplicationView } from './search_application_view'; + +export const SearchApplicationRouter: React.FC = () => { + const searchApplicationName = decodeURIComponent( + useParams<{ searchApplicationName: string }>().searchApplicationName + ); + const searchApplicationNameLogic = SearchApplicationNameLogic({ searchApplicationName }); + const { setSearchApplicationName } = useActions(searchApplicationNameLogic); + + useEffect(() => { + const unmountName = searchApplicationNameLogic.mount(); + + return () => { + unmountName(); + }; + }, []); + useEffect(() => { + setSearchApplicationName(searchApplicationName); + }, [searchApplicationName]); + + return ( + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_schema.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_schema.tsx similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_schema.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_schema.tsx index 045bde7c6d4a1..98dcd4131fede 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_schema.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_schema.tsx @@ -45,7 +45,7 @@ import { generateEncodedPath } from '../../../shared/encode_path_params'; import { KibanaLogic } from '../../../shared/kibana'; import { EuiLinkTo } from '../../../shared/react_router_helpers'; -import { EngineViewLogic } from './engine_view_logic'; +import { SearchApplicationViewLogic } from './search_application_view_logic'; const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaField }) => { const { navigateToUrl } = useValues(KibanaLogic); @@ -55,7 +55,7 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel { field: 'name', name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.fieldIndices.index.columnTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.index.columnTitle', { defaultMessage: 'Parent index', } @@ -74,7 +74,7 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel { field: 'type', name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.columnTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.columnTitle', { defaultMessage: 'Field mapped as', } @@ -84,7 +84,7 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel return ( @@ -120,7 +120,7 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel iconType="iInCircle" title={ } @@ -128,12 +128,12 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel

{' '} @@ -152,9 +152,11 @@ const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaFiel ); }; -export const EngineSchema: React.FC = () => { +export const SearchApplicationSchema: React.FC = () => { const [onlyShowConflicts, setOnlyShowConflicts] = useState(false); - const { isLoadingEngineSchema, schemaFields, hasSchemaConflicts } = useValues(EngineViewLogic); + const { isLoadingSearchApplicationSchema, schemaFields, hasSchemaConflicts } = useValues( + SearchApplicationViewLogic + ); const [isFilterByPopoverOpen, setIsFilterByPopoverOpen] = useState(false); const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState>( @@ -220,9 +222,12 @@ export const EngineSchema: React.FC = () => { width: '24px', }, { - name: i18n.translate('xpack.enterpriseSearch.content.engine.schema.field_name.columnTitle', { - defaultMessage: 'Field name', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_name.columnTitle', + { + defaultMessage: 'Field name', + } + ), render: ({ name, type }: SchemaField) => ( {name.includes('.') && } @@ -233,16 +238,19 @@ export const EngineSchema: React.FC = () => { ), }, { - name: i18n.translate('xpack.enterpriseSearch.content.engine.schema.field_type.columnTitle', { - defaultMessage: 'Field type', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.columnTitle', + { + defaultMessage: 'Field type', + } + ), render: ({ type }: SchemaField) => { if (type === 'conflict') { return ( @@ -263,7 +271,7 @@ export const EngineSchema: React.FC = () => { }, { name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.field_indices.columnTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.columnTitle', { defaultMessage: 'In all indices?', } @@ -274,7 +282,7 @@ export const EngineSchema: React.FC = () => {

@@ -282,7 +290,7 @@ export const EngineSchema: React.FC = () => { ) : ( @@ -308,7 +316,7 @@ export const EngineSchema: React.FC = () => { }} > @@ -330,9 +338,12 @@ export const EngineSchema: React.FC = () => { numActiveFilters={filteredDataTypes.length} isSelected={isFilterByPopoverOpen} > - {i18n.translate('xpack.enterpriseSearch.content.engine.schema.filters', { - defaultMessage: 'Field types', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters', + { + defaultMessage: 'Field types', + } + )} ); @@ -367,7 +378,7 @@ export const EngineSchema: React.FC = () => { { /> - {i18n.translate('xpack.enterpriseSearch.content.engine.schema.filters.label', { - defaultMessage: 'Filter By', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.label', + { + defaultMessage: 'Filter By', + } + )} { searchable searchProps={{ placeholder: i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.filters.searchPlaceholder', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.searchPlaceholder', { defaultMessage: 'Filter list ', } @@ -418,7 +432,7 @@ export const EngineSchema: React.FC = () => { onClick={() => setSelectedEsFieldTypes(esFieldTypes)} > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.filters.clearAll', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.clearAll', { defaultMessage: 'Clear all ', } @@ -434,7 +448,7 @@ export const EngineSchema: React.FC = () => { { @@ -454,7 +468,7 @@ export const EngineSchema: React.FC = () => { >

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.subTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.subTitle', { defaultMessage: 'In order to see all field conflicts you must clear your field filters', @@ -463,7 +477,7 @@ export const EngineSchema: React.FC = () => {

setSelectedEsFieldTypes(esFieldTypes)}> {i18n.translate( - 'xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.clearFilters', + 'xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.clearFilters', { defaultMessage: 'Clear filters ', } diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx new file mode 100644 index 0000000000000..246d47cfd4e3b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view.tsx @@ -0,0 +1,126 @@ +/* + * 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 React, { useEffect, useLayoutEffect } from 'react'; +import { useParams, Redirect, Switch } from 'react-router-dom'; + +import { useValues, useActions } from 'kea'; + +import { Route } from '@kbn/shared-ux-router'; + +import { Status } from '../../../../../common/types/api'; + +import { KibanaLogic } from '../../../shared/kibana'; +import { + SEARCH_APPLICATION_PATH, + SEARCH_APPLICATION_CONTENT_PATH, + SEARCH_APPLICATION_CONNECT_PATH, + SearchApplicationViewTabs, + SearchApplicationConnectTabs, + SearchApplicationContentTabs, +} from '../../routes'; + +import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; +import { DeleteSearchApplicationModal } from '../search_applications/delete_search_application_modal'; + +import { SearchApplicationConnect } from './connect/search_application_connect'; +import { SearchApplicationHeaderDocsAction } from './header_docs_action'; +import { SearchApplicationContent } from './search_application_content'; +import { SearchApplicationError } from './search_application_error'; +import { SearchApplicationViewLogic } from './search_application_view_logic'; +import { SearchApplicationSearchPreview } from './search_preview/search_preview'; + +export const SearchApplicationView: React.FC = () => { + const { fetchSearchApplication, closeDeleteSearchApplicationModal } = useActions( + SearchApplicationViewLogic + ); + const { + searchApplicationName, + fetchSearchApplicationApiError, + fetchSearchApplicationApiStatus, + hasSchemaConflicts, + isDeleteModalVisible, + } = useValues(SearchApplicationViewLogic); + const { tabId = SearchApplicationViewTabs.PREVIEW } = useParams<{ + tabId?: string; + }>(); + const { renderHeaderActions } = useValues(KibanaLogic); + + useLayoutEffect(() => { + renderHeaderActions(SearchApplicationHeaderDocsAction); + + return () => { + renderHeaderActions(); + }; + }, []); + + useEffect(() => { + fetchSearchApplication({ name: searchApplicationName }); + }, [searchApplicationName]); + + if (fetchSearchApplicationApiStatus === Status.ERROR) { + return ( + } + hasSchemaConflicts={hasSchemaConflicts} + /> + ); + } + + return ( + <> + {isDeleteModalVisible ? ( + + ) : null} + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.test.ts new file mode 100644 index 0000000000000..f9dbedcc111d2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.test.ts @@ -0,0 +1,70 @@ +/* + * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; + +import { Status } from '../../../../../common/types/api'; + +import { KibanaLogic } from '../../../shared/kibana'; +import { DeleteSearchApplicationApiLogicResponse } from '../../api/search_applications/delete_search_application_api_logic'; +import { SEARCH_APPLICATIONS_PATH } from '../../routes'; +import { SearchApplicationsListLogic } from '../search_applications/search_applications_list_logic'; + +import { + SearchApplicationViewLogic, + SearchApplicationViewValues, +} from './search_application_view_logic'; + +const DEFAULT_VALUES: SearchApplicationViewValues = { + fetchSearchApplicationApiError: undefined, + fetchSearchApplicationApiStatus: Status.IDLE, + fetchSearchApplicationSchemaApiError: undefined, + fetchSearchApplicationSchemaApiStatus: Status.IDLE, + hasSchemaConflicts: false, + isDeleteModalVisible: false, + isLoadingSearchApplication: true, + isLoadingSearchApplicationSchema: true, + schemaFields: [], + searchApplicationData: undefined, + searchApplicationName: 'my-test-search-application', + searchApplicationSchemaData: undefined, +}; + +describe('SearchApplicationViewLogic', () => { + const { mount } = new LogicMounter(SearchApplicationViewLogic); + const { mount: mountSearchApplicationsListLogic } = new LogicMounter(SearchApplicationsListLogic); + beforeEach(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + + mountSearchApplicationsListLogic(); + mount( + { searchApplicationName: DEFAULT_VALUES.searchApplicationName }, + { searchApplicationName: DEFAULT_VALUES.searchApplicationName } + ); + }); + + it('has expected default values', () => { + expect(SearchApplicationViewLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('listeners', () => { + describe('deleteSuccess', () => { + it('should navigate to the search applications list when an search application is deleted', () => { + jest.spyOn(SearchApplicationViewLogic.actions, 'deleteSuccess'); + jest + .spyOn(KibanaLogic.values, 'navigateToUrl') + .mockImplementationOnce(() => Promise.resolve()); + SearchApplicationsListLogic.actions.deleteSuccess( + {} as DeleteSearchApplicationApiLogicResponse + ); + + expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith(SEARCH_APPLICATIONS_PATH); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.ts new file mode 100644 index 0000000000000..bfb164846ef41 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_application_view_logic.ts @@ -0,0 +1,130 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { Status } from '../../../../../common/types/api'; +import { SchemaField } from '../../../../../common/types/search_applications'; + +import { KibanaLogic } from '../../../shared/kibana'; + +import { + FetchSearchApplicationApiLogic, + FetchSearchApplicationApiLogicActions, +} from '../../api/search_applications/fetch_search_application_api_logic'; +import { FetchSearchApplicationFieldCapabilitiesApiLogic } from '../../api/search_applications/fetch_search_application_field_capabilities_api_logic'; + +import { SEARCH_APPLICATIONS_PATH } from '../../routes'; + +import { + SearchApplicationsListLogic, + SearchApplicationsListActions, +} from '../search_applications/search_applications_list_logic'; + +import { SearchApplicationNameLogic } from './search_application_name_logic'; + +export interface SearchApplicationViewActions { + closeDeleteSearchApplicationModal(): void; + deleteSuccess: SearchApplicationsListActions['deleteSuccess']; + fetchSearchApplication: FetchSearchApplicationApiLogicActions['makeRequest']; + fetchSearchApplicationSchema: FetchSearchApplicationApiLogicActions['makeRequest']; + openDeleteSearchApplicationModal(): void; +} + +export interface SearchApplicationViewValues { + fetchSearchApplicationApiError?: typeof FetchSearchApplicationApiLogic.values.error; + fetchSearchApplicationApiStatus: typeof FetchSearchApplicationApiLogic.values.status; + fetchSearchApplicationSchemaApiError?: typeof FetchSearchApplicationFieldCapabilitiesApiLogic.values.error; + fetchSearchApplicationSchemaApiStatus: typeof FetchSearchApplicationFieldCapabilitiesApiLogic.values.status; + hasSchemaConflicts: boolean; + isDeleteModalVisible: boolean; + isLoadingSearchApplication: boolean; + isLoadingSearchApplicationSchema: boolean; + schemaFields: SchemaField[]; + searchApplicationData: typeof FetchSearchApplicationApiLogic.values.data; + searchApplicationName: typeof SearchApplicationNameLogic.values.searchApplicationName; + searchApplicationSchemaData: typeof FetchSearchApplicationFieldCapabilitiesApiLogic.values.data; +} + +export const SearchApplicationViewLogic = kea< + MakeLogicType +>({ + actions: { + closeDeleteSearchApplicationModal: true, + openDeleteSearchApplicationModal: true, + }, + connect: { + actions: [ + FetchSearchApplicationApiLogic, + ['makeRequest as fetchSearchApplication'], + FetchSearchApplicationFieldCapabilitiesApiLogic, + ['makeRequest as fetchSearchApplicationSchema'], + SearchApplicationsListLogic, + ['deleteSuccess'], + ], + values: [ + SearchApplicationNameLogic, + ['searchApplicationName'], + FetchSearchApplicationApiLogic, + [ + 'data as searchApplicationData', + 'status as fetchSearchApplicationApiStatus', + 'error as fetchSearchApplicationApiError', + ], + FetchSearchApplicationFieldCapabilitiesApiLogic, + [ + 'data as searchApplicationSchemaData', + 'status as fetchSearchApplicationSchemaApiStatus', + 'error as fetchSearchApplicationSchemaApiError', + ], + ], + }, + listeners: ({ actions }) => ({ + deleteSuccess: () => { + actions.closeDeleteSearchApplicationModal(); + KibanaLogic.values.navigateToUrl(SEARCH_APPLICATIONS_PATH); + }, + fetchSearchApplication: ({ name }) => { + actions.fetchSearchApplicationSchema({ name }); + }, + }), + path: ['enterprise_search', 'content', 'search_application_view_logic'], + reducers: () => ({ + isDeleteModalVisible: [ + false, + { + closeDeleteSearchApplicationModal: () => false, + openDeleteSearchApplicationModal: () => true, + }, + ], + }), + selectors: ({ selectors }) => ({ + hasSchemaConflicts: [ + () => [selectors.schemaFields], + (data: SearchApplicationViewValues['schemaFields']) => + data.some((f) => f.type === 'conflict'), + ], + isLoadingSearchApplication: [ + () => [selectors.fetchSearchApplicationApiStatus, selectors.searchApplicationData], + ( + status: SearchApplicationViewValues['fetchSearchApplicationApiStatus'], + data: SearchApplicationViewValues['searchApplicationData'] + ) => { + return status === Status.IDLE || (!data && status === Status.LOADING); + }, + ], + isLoadingSearchApplicationSchema: [ + () => [selectors.fetchSearchApplicationSchemaApiStatus], + (status: SearchApplicationViewValues['fetchSearchApplicationSchemaApiStatus']) => + [Status.LOADING, Status.IDLE].includes(status), + ], + schemaFields: [ + () => [selectors.searchApplicationSchemaData], + (data: SearchApplicationViewValues['searchApplicationSchemaData']) => data?.fields || [], + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/api_call_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/api_call_flyout.tsx similarity index 75% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/api_call_flyout.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/api_call_flyout.tsx index ca64d73bf1b64..82f9a3ce911e5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/api_call_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/api_call_flyout.tsx @@ -23,7 +23,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { generateEncodedPath } from '../../../../shared/encode_path_params'; import { EuiLinkTo } from '../../../../shared/react_router_helpers'; -import { EngineViewTabs, ENGINE_TAB_PATH } from '../../../routes'; +import { SearchApplicationViewTabs, SEARCH_APPLICATION_TAB_PATH } from '../../../routes'; export interface APICallData { request: SearchRequest; @@ -31,15 +31,15 @@ export interface APICallData { } export interface APICallFlyoutProps { - engineName: string; lastAPICall: APICallData; onClose: () => void; + searchApplicationName: string; } export const APICallFlyout: React.FC = ({ - engineName, onClose, lastAPICall, + searchApplicationName, }) => { const [tab, setTab] = useState<'request' | 'response'>('request'); @@ -51,7 +51,7 @@ export const APICallFlyout: React.FC = ({

@@ -65,27 +65,27 @@ export const APICallFlyout: React.FC = ({ setTab('request')}> setTab('response')}> diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/convert_results.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/convert_results.test.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/convert_results.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/convert_results.test.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/convert_results.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/convert_results.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/convert_results.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/convert_results.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_context.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_context.test.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_context.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_context.test.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_context.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_context.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_context.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_context.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_flyout.tsx similarity index 82% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_flyout.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_flyout.tsx index 9a9ae598b17b2..d2464ee64886d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/document_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/document_flyout.tsx @@ -32,11 +32,11 @@ import { FieldValue, } from './convert_results'; import { useSelectedDocument } from './document_context'; -import { EngineSearchPreviewLogic } from './engine_search_preview_logic'; import { FieldValueCell } from './field_value_cell'; +import { SearchApplicationSearchPreviewLogic } from './search_preview_logic'; export const DocumentFlyout: React.FC = () => { - const { fieldTypesByIndex } = useValues(EngineSearchPreviewLogic); + const { fieldTypesByIndex } = useValues(SearchApplicationSearchPreviewLogic); const { selectedDocument, setSelectedDocument } = useSelectedDocument(); if (!selectedDocument) return null; @@ -53,7 +53,7 @@ export const DocumentFlyout: React.FC = () => { const columns: Array> = [ { name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.fieldLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldLabel', { defaultMessage: 'Field' } ), render: ({ field: key, type }: ConvertedResultWithType) => ( @@ -71,7 +71,7 @@ export const DocumentFlyout: React.FC = () => { { field: 'value', name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.valueLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.valueLabel', { defaultMessage: 'Value' } ), render: (value: FieldValue) => ( @@ -92,7 +92,7 @@ export const DocumentFlyout: React.FC = () => {

@@ -100,7 +100,7 @@ export const DocumentFlyout: React.FC = () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/field_value_cell.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/field_value_cell.tsx similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/field_value_cell.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/field_value_cell.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview.tsx similarity index 75% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview.tsx index bfec3086c5e87..56399592b9df6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/engine_search_preview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview.tsx @@ -52,20 +52,20 @@ import { HttpLogic } from '../../../../shared/http'; import { KibanaLogic } from '../../../../shared/kibana'; import { TelemetryLogic } from '../../../../shared/telemetry'; import { - EngineViewTabs, + SearchApplicationViewTabs, SearchApplicationConnectTabs, SearchApplicationContentTabs, SEARCH_APPLICATION_CONNECT_PATH, SEARCH_APPLICATION_CONTENT_PATH, } from '../../../routes'; -import { EnterpriseSearchEnginesPageTemplate } from '../../layout/engines_page_template'; +import { EnterpriseSearchApplicationsPageTemplate } from '../../layout/page_template'; -import { EngineIndicesLogic } from '../engine_indices_logic'; -import { EngineViewLogic } from '../engine_view_logic'; +import { SearchApplicationIndicesLogic } from '../search_application_indices_logic'; +import { SearchApplicationViewLogic } from '../search_application_view_logic'; import { DocumentProvider } from './document_context'; import { DocumentFlyout } from './document_flyout'; -import { EngineSearchPreviewLogic } from './engine_search_preview_logic'; +import { SearchApplicationSearchPreviewLogic } from './search_preview_logic'; import { InputView, @@ -78,14 +78,14 @@ import { } from './search_ui_components'; import '../search_application_layout.scss'; -class InternalEngineTransporter implements Transporter { +class InternalSearchApplicationTransporter implements Transporter { constructor( private http: HttpSetup, - private engineName: string // uncomment and add setLastAPICall to constructor when view this API call is needed // private setLastAPICall?: (apiCallData: APICallData) => void + private searchApplicationName: string // uncomment and add setLastAPICall to constructor when view this API call is needed // private setLastAPICall?: (apiCallData: APICallData) => void ) {} async performRequest(request: SearchRequest) { - const url = `/internal/enterprise_search/search_applications/${this.engineName}/search`; + const url = `/internal/enterprise_search/search_applications/${this.searchApplicationName}/search`; const response = await this.http.post(url, { body: JSON.stringify(request), @@ -115,21 +115,21 @@ class InternalEngineTransporter implements Transporter { } interface ConfigurationPopOverProps { - engineName: string; hasSchemaConflicts: boolean; + searchApplicationName: string; setCloseConfiguration: () => void; showConfiguration: boolean; } const ConfigurationPopover: React.FC = ({ - engineName, + searchApplicationName, hasSchemaConflicts, setCloseConfiguration, showConfiguration, }) => { const { navigateToUrl } = useValues(KibanaLogic); - const { engineData } = useValues(EngineViewLogic); - const { openDeleteEngineModal } = useActions(EngineViewLogic); + const { searchApplicationData } = useValues(SearchApplicationViewLogic); + const { openDeleteSearchApplicationModal } = useActions(SearchApplicationViewLogic); const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic); const [isTourClosed, setTourClosed] = useLocalStorage( 'search-application-tour-closed', @@ -161,7 +161,7 @@ const ConfigurationPopover: React.FC = ({

{i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchPreview.configuration.tourContent', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreview.configuration.tourContent', { defaultMessage: 'Create your API key, learn about using language clients and find more resources in Connect.', @@ -180,7 +180,7 @@ const ConfigurationPopover: React.FC = ({ stepsTotal={1} anchorPosition="downCenter" title={i18n.translate( - 'xpack.enterpriseSearch.content.searchApplication.searchPreview.configuration.tourTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreview.configuration.tourTitle', { defaultMessage: 'Review our API page to start using your search application', } @@ -198,7 +198,7 @@ const ConfigurationPopover: React.FC = ({ onClick={setCloseConfiguration} > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.buttonTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.buttonTitle', { defaultMessage: 'Configuration', } @@ -213,7 +213,7 @@ const ConfigurationPopover: React.FC = ({

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.contentTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.contentTitle', { defaultMessage: 'Content', } @@ -230,13 +230,13 @@ const ConfigurationPopover: React.FC = ({ navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONTENT_PATH, { contentTabId: SearchApplicationContentTabs.INDICES, - engineName, + searchApplicationName, }) ) } > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.content.Indices', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.content.Indices', { defaultMessage: 'Indices', } @@ -249,20 +249,20 @@ const ConfigurationPopover: React.FC = ({ navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONTENT_PATH, { contentTabId: SearchApplicationContentTabs.SCHEMA, - engineName, + searchApplicationName, }) ) } > {hasSchemaConflicts && ( @@ -274,7 +274,7 @@ const ConfigurationPopover: React.FC = ({

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.connectTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connectTitle', { defaultMessage: 'Connect', } @@ -290,13 +290,13 @@ const ConfigurationPopover: React.FC = ({ navigateToUrl( generateEncodedPath(SEARCH_APPLICATION_CONNECT_PATH, { connectTabId: SearchApplicationConnectTabs.SEARCHAPI, - engineName, + searchApplicationName, }) ) } > {i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.connect.Api', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connect.Api', { defaultMessage: 'API', } @@ -307,7 +307,7 @@ const ConfigurationPopover: React.FC = ({

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.settingsTitle', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settingsTitle', { defaultMessage: 'Settings', } @@ -320,11 +320,11 @@ const ConfigurationPopover: React.FC = ({ key="delete" icon={} onClick={() => { - if (engineData) { - openDeleteEngineModal(); + if (searchApplicationData) { + openDeleteSearchApplicationModal(); sendEnterpriseSearchTelemetry({ action: 'clicked', - metric: 'entSearchApplications-engineView-deleteEngine', + metric: 'entSearchApplications-searchApplicationView-deleteSearchApplication', }); } }} @@ -332,7 +332,7 @@ const ConfigurationPopover: React.FC = ({

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.configuration.settings.delete', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settings.delete', { defaultMessage: 'Delete this app', } @@ -345,17 +345,19 @@ const ConfigurationPopover: React.FC = ({ ); }; -export const EngineSearchPreview: React.FC = () => { +export const SearchApplicationSearchPreview: React.FC = () => { const { http } = useValues(HttpLogic); // const [showAPICallFlyout, setShowAPICallFlyout] = useState(false); Uncomment when view this API call is needed const [showConfigurationPopover, setShowConfigurationPopover] = useState(false); // const [lastAPICall, setLastAPICall] = useState(null); Uncomment when view this API call is needed - const { engineName, isLoadingEngine, hasSchemaConflicts } = useValues(EngineViewLogic); - const { resultFields, sortableFields } = useValues(EngineSearchPreviewLogic); - const { engineData } = useValues(EngineIndicesLogic); + const { searchApplicationName, isLoadingSearchApplication, hasSchemaConflicts } = useValues( + SearchApplicationViewLogic + ); + const { resultFields, sortableFields } = useValues(SearchApplicationSearchPreviewLogic); + const { searchApplicationData } = useValues(SearchApplicationIndicesLogic); const config: SearchDriverOptions = useMemo(() => { - const transporter = new InternalEngineTransporter(http, engineName); + const transporter = new InternalSearchApplicationTransporter(http, searchApplicationName); const connector = new EnginesAPIConnector(transporter); return { @@ -366,34 +368,31 @@ export const EngineSearchPreview: React.FC = () => { result_fields: resultFields, }, }; - }, [http, engineName, resultFields]); + }, [http, searchApplicationName, resultFields]); - if (!engineData) return null; + if (!searchApplicationData) return null; return ( - - ), + pageTitle: searchApplicationName, rightSideItems: [ <> setShowConfigurationPopover(!showConfigurationPopover)} @@ -401,7 +400,7 @@ export const EngineSearchPreview: React.FC = () => { , ], }} - engineName={engineName} + searchApplicationName={searchApplicationName} hasSchemaConflicts={hasSchemaConflicts} > @@ -420,7 +419,7 @@ export const EngineSearchPreview: React.FC = () => { @@ -440,11 +439,11 @@ export const EngineSearchPreview: React.FC = () => { setShowAPICallFlyout(false)} lastAPICall={lastAPICall} - engineName={engineName} + searchApplicationName={searchApplicationName} /> )} */} - + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview_logic.ts new file mode 100644 index 0000000000000..eb11bfd088dd4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_preview_logic.ts @@ -0,0 +1,98 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { FieldConfiguration } from '@elastic/search-ui'; + +import { FetchSearchApplicationFieldCapabilitiesApiLogic } from '../../../api/search_applications/fetch_search_application_field_capabilities_api_logic'; +import { SearchApplicationNameLogic } from '../search_application_name_logic'; + +interface SearchApplicationSearchPreviewActions { + fetchSearchApplicationFieldCapabilities: typeof FetchSearchApplicationFieldCapabilitiesApiLogic.actions.makeRequest; +} + +export interface SearchApplicationPreviewValues { + fieldTypesByIndex: Record>; + resultFields: Record; + searchApplicationFieldCapabilitiesData: typeof FetchSearchApplicationFieldCapabilitiesApiLogic.values.data; + searchApplicationName: typeof SearchApplicationNameLogic.values.searchApplicationName; + sortableFields: string[]; +} + +export const SearchApplicationSearchPreviewLogic = kea< + MakeLogicType +>({ + connect: { + actions: [ + FetchSearchApplicationFieldCapabilitiesApiLogic, + ['makeRequest as fetchSearchApplicationFieldCapabilities'], + ], + values: [ + SearchApplicationNameLogic, + ['searchApplicationName'], + FetchSearchApplicationFieldCapabilitiesApiLogic, + ['data as searchApplicationFieldCapabilitiesData'], + ], + }, + events: ({ actions, values }) => ({ + afterMount: () => { + if (!values.searchApplicationFieldCapabilitiesData) { + actions.fetchSearchApplicationFieldCapabilities({ + name: values.searchApplicationName, + }); + } + }, + }), + path: ['enterprise_search', 'content', 'search_application_search_preview_logic'], + selectors: ({ selectors }) => ({ + fieldTypesByIndex: [ + () => [selectors.searchApplicationFieldCapabilitiesData], + (data: SearchApplicationPreviewValues['searchApplicationFieldCapabilitiesData']) => { + if (!data) return {}; + + return data.fields.reduce( + (out: Record>, field) => + field.indices.reduce( + (acc: Record>, index) => ({ + ...acc, + [index.name]: { + ...(acc[index.name] || {}), + [field.name]: index.type, + }, + }), + out + ), + {} + ); + }, + ], + resultFields: [ + () => [selectors.searchApplicationFieldCapabilitiesData], + (data: SearchApplicationPreviewValues['searchApplicationFieldCapabilitiesData']) => { + if (!data) return {}; + + return Object.fromEntries( + data.fields + .filter(({ metadata_field: isMeta }) => !isMeta) + .map(({ name }) => [name, { raw: {}, snippet: { fallback: true } }]) + ); + }, + ], + sortableFields: [ + () => [selectors.searchApplicationFieldCapabilitiesData], + (data: SearchApplicationPreviewValues['searchApplicationFieldCapabilitiesData']) => { + if (!data) return []; + + return data.fields + .filter(({ metadata_field: isMeta, aggregatable }) => aggregatable && !isMeta) + .map(({ name }) => name) + .sort(); + }, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/search_ui_components.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_ui_components.tsx similarity index 81% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/search_ui_components.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_ui_components.tsx index fd417419adbef..887c847620c0c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engine/engine_search_preview/search_ui_components.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_application/search_preview/search_ui_components.tsx @@ -40,7 +40,7 @@ import { FormattedMessage, FormattedHTMLMessage } from '@kbn/i18n-react'; import { indexHealthToHealthColor } from '../../../../shared/constants/health_colors'; -import { EngineViewLogic } from '../engine_view_logic'; +import { SearchApplicationViewLogic } from '../search_application_view_logic'; import { convertResultToFieldsAndIndex, ConvertedResult, FieldValue } from './convert_results'; import { useSelectedDocument } from './document_context'; @@ -53,7 +53,7 @@ export const ResultsView: React.FC = ({ children }) => { const RESULT_FIELDS_TRUNCATE_AT = 4; export const ResultView: React.FC = ({ result }) => { - const { engineData } = useValues(EngineViewLogic); + const { searchApplicationData } = useValues(SearchApplicationViewLogic); const { setSelectedDocument } = useSelectedDocument(); const { fields, index } = convertResultToFieldsAndIndex(result); @@ -63,7 +63,7 @@ export const ResultView: React.FC = ({ result }) => { const truncatedFields = fields.slice(0, RESULT_FIELDS_TRUNCATE_AT); const hiddenFields = fields.length - truncatedFields.length; - const indexHealth = engineData?.indices.find((i) => i.name === index)?.health; + const indexHealth = searchApplicationData?.indices.find((i) => i.name === index)?.health; const badgeColor = !indexHealth || indexHealth === 'unknown' ? 'hollow' : indexHealthToHealthColor(indexHealth); @@ -71,7 +71,7 @@ export const ResultView: React.FC = ({ result }) => { { field: 'field', name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.result.nameColumn', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.nameColumn', { defaultMessage: 'Field' } ), render: (field: string) => { @@ -89,7 +89,7 @@ export const ResultView: React.FC = ({ result }) => { { field: 'value', name: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.result.valueColumn', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.valueColumn', { defaultMessage: 'Value' } ), render: (value: FieldValue) => ( @@ -109,7 +109,7 @@ export const ResultView: React.FC = ({ result }) => { @@ -118,7 +118,7 @@ export const ResultView: React.FC = ({ result }) => { @@ -133,7 +133,7 @@ export const ResultView: React.FC = ({ result }) => { @@ -153,13 +153,13 @@ export const InputView: React.FC = ({ getInputProps }) => { @@ -174,7 +174,7 @@ export const PagingInfoView: React.FC = ({ start, end, tota @@ -193,7 +193,7 @@ export const ResultsPerPageView: React.FC = ({ @@ -203,7 +203,7 @@ export const ResultsPerPageView: React.FC = ({ options={ options?.map((option) => ({ text: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.option.label', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.option.label', { defaultMessage: '{value} {value, plural, one {Result} other {Results}}', values: { value: option }, @@ -225,7 +225,7 @@ export const Sorting = withSearch< >(({ setSort, sortList }) => ({ setSort, sortList }))(({ sortableFields, sortList, setSort }) => { const [{ direction, field }] = !sortList?.length ? [{ direction: '', field: '' }] : sortList; const relevance = i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreivew.sortingView.relevanceLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.relevanceLabel', { defaultMessage: 'Relevance' } ); @@ -235,7 +235,7 @@ export const Sorting = withSearch< @@ -261,7 +261,7 @@ export const Sorting = withSearch< @@ -280,14 +280,14 @@ export const Sorting = withSearch< options={[ { text: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.sortingView.ascLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.ascLabel', { defaultMessage: 'Ascending' } ), value: 'asc', }, { text: i18n.translate( - 'xpack.enterpriseSearch.content.engine.searchPreview.sortingView.descLabel', + 'xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.descLabel', { defaultMessage: 'Descending' } ), value: 'desc', diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.test.tsx similarity index 69% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.test.tsx index 81d81bc8a164c..6fd6e4432bf55 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.test.tsx @@ -10,12 +10,14 @@ import { shallow } from 'enzyme'; import { EuiEmptyPrompt } from '@elastic/eui'; -import { EmptyEnginesPrompt } from './empty_engines_prompt'; +import { EmptySearchApplicationsPrompt } from './empty_search_applications_prompt'; -describe('EmptyEnginesPrompt', () => { +describe('EmptySearchApplicationsPrompt', () => { it('should pass children to prompt actions', () => { const dummyEl =

dummy
; - const wrapper = shallow({dummyEl}); + const wrapper = shallow( + {dummyEl} + ); const euiPrompt = wrapper.find(EuiEmptyPrompt); expect(euiPrompt.prop('actions')).toEqual(dummyEl); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx similarity index 77% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx index fa9c5238ea08c..52647335d0f50 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/empty_engines_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/empty_search_applications_prompt.tsx @@ -10,14 +10,14 @@ import React from 'react'; import { EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -export const EmptyEnginesPrompt: React.FC = ({ children }) => { +export const EmptySearchApplicationsPrompt: React.FC = ({ children }) => { return (

@@ -25,7 +25,7 @@ export const EmptyEnginesPrompt: React.FC = ({ children }) => { body={

diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/indices_select_combobox.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/indices_select_combobox.tsx similarity index 88% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/indices_select_combobox.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/indices_select_combobox.tsx index 4704947d72c32..76880766438af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/indices_select_combobox.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/indices_select_combobox.tsx @@ -26,7 +26,7 @@ import { Status } from '../../../../../../common/types/api'; import { ElasticsearchIndexWithIngestion } from '../../../../../../common/types/indices'; import { indexHealthToHealthColor } from '../../../../shared/constants/health_colors'; -import { FetchIndicesForEnginesAPILogic } from '../../../api/engines/fetch_indices_api_logic'; +import { FetchIndicesForSearchApplicationsAPILogic } from '../../../api/search_applications/fetch_indices_api_logic'; export type IndicesSelectComboBoxOption = EuiComboBoxOptionOption; @@ -40,8 +40,8 @@ export type IndicesSelectComboBoxProps = Omit< export const IndicesSelectComboBox = ({ ignoredOptions, ...props }: IndicesSelectComboBoxProps) => { const [searchQuery, setSearchQuery] = useState(undefined); - const { makeRequest } = useActions(FetchIndicesForEnginesAPILogic); - const { status, data } = useValues(FetchIndicesForEnginesAPILogic); + const { makeRequest } = useActions(FetchIndicesForSearchApplicationsAPILogic); + const { status, data } = useValues(FetchIndicesForSearchApplicationsAPILogic); useEffect(() => { makeRequest({ searchQuery }); @@ -64,7 +64,7 @@ export const IndicesSelectComboBox = ({ ignoredOptions, ...props }: IndicesSelec - {i18n.translate('xpack.enterpriseSearch.content.engine.indicesSelect.docsLabel', { + {i18n.translate('xpack.enterpriseSearch.searchApplications.indicesSelect.docsLabel', { defaultMessage: 'Docs:', })} diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/tables/engines_table.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/tables/search_applications_table.tsx similarity index 62% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/tables/engines_table.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/tables/search_applications_table.tsx index 566cf9e8c4704..047fe51117c17 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/components/tables/engines_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/components/tables/search_applications_table.tsx @@ -31,31 +31,31 @@ import { pageToPagination } from '../../../../../shared/pagination/page_to_pagin import { EuiLinkTo } from '../../../../../shared/react_router_helpers'; import { TelemetryLogic } from '../../../../../shared/telemetry/telemetry_logic'; -import { ENGINE_PATH } from '../../../../routes'; +import { SEARCH_APPLICATION_PATH } from '../../../../routes'; -interface EnginesListTableProps { - enginesList: EnterpriseSearchApplication[]; +interface SearchApplicationsListTableProps { isLoading?: boolean; loading: boolean; meta: Page; onChange: (criteria: CriteriaWithPagination) => void; - onDelete: (engine: EnterpriseSearchApplication) => void; - viewEngineIndices: (engineName: string) => void; + onDelete: (searchApplication: EnterpriseSearchApplication) => void; + searchApplications: EnterpriseSearchApplication[]; + viewSearchApplicationIndices: (searchApplicationName: string) => void; } -export const EnginesListTable: React.FC = ({ - enginesList, +export const SearchApplicationsListTable: React.FC = ({ + searchApplications, isLoading, meta, onChange, onDelete, - viewEngineIndices, + viewSearchApplicationIndices, }) => { const { navigateToUrl } = useValues(KibanaLogic); const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic); const columns: Array> = [ { field: 'name', - name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.name', { + name: i18n.translate('xpack.enterpriseSearch.searchApplications.list.table.column.name', { defaultMessage: 'Search Application Name', }), mobileOptions: { @@ -65,9 +65,9 @@ export const EnginesListTable: React.FC = ({ }, render: (name: string) => ( {name} @@ -77,29 +77,31 @@ export const EnginesListTable: React.FC = ({ }, { field: 'updated_at_millis', - name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated', { - defaultMessage: 'Last updated', - }), + name: i18n.translate( + 'xpack.enterpriseSearch.searchApplications.list.table.column.lastUpdated', + { + defaultMessage: 'Last updated', + } + ), dataType: 'number', render: (dateString: string) => , }, { field: 'indices', - name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.indices', { + name: i18n.translate('xpack.enterpriseSearch.searchApplications.list.table.column.indices', { defaultMessage: 'Indices', }), align: 'right', - render: (indices: string[], engine) => ( + render: (indices: string[], searchApplication) => ( viewEngineIndices(engine.name)} + data-test-subj="searchApplicationsListTableIndicesFlyoutButton" + data-telemetry-id="entSearchApplications-table-viewSearchApplicationIndices" + onClick={() => viewSearchApplicationIndices(searchApplication.name)} > @@ -108,31 +110,31 @@ export const EnginesListTable: React.FC = ({ }, { - name: i18n.translate('xpack.enterpriseSearch.content.enginesList.table.column.actions', { + name: i18n.translate('xpack.enterpriseSearch.searchApplications.list.table.column.actions', { defaultMessage: 'Actions', }), actions: [ { name: MANAGE_BUTTON_LABEL, description: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription', + 'xpack.enterpriseSearch.searchApplications.list.table.column.actions.view.buttonDescription', { defaultMessage: 'View this search application', } ), type: 'icon', icon: 'eye', - onClick: (engine) => + onClick: (searchApplication) => navigateToUrl( - generateEncodedPath(ENGINE_PATH, { - engineName: engine.name, + generateEncodedPath(SEARCH_APPLICATION_PATH, { + searchApplicationName: searchApplication.name, }) ), }, { color: 'danger', description: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription', + 'xpack.enterpriseSearch.searchApplications.list.table.column.action.delete.buttonDescription', { defaultMessage: 'Delete this search application', } @@ -142,16 +144,16 @@ export const EnginesListTable: React.FC = ({ isPrimary: false, name: () => i18n.translate( - 'xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel', + 'xpack.enterpriseSearch.searchApplications.list.table.column.actions.deleteSearchApplicationLabel', { defaultMessage: 'Delete this search application', } ), - onClick: (engine) => { - onDelete(engine); + onClick: (searchApplication) => { + onDelete(searchApplication); sendEnterpriseSearchTelemetry({ action: 'clicked', - metric: 'entSearchApplications-table-deleteEngine', + metric: 'entSearchApplications-table-deleteSearchApplication', }); }, }, @@ -161,7 +163,7 @@ export const EnginesListTable: React.FC = ({ return ( void; } -export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { - const { createEngine, setEngineName, setSelectedIndices } = useActions(CreateEngineLogic); +export const CreateSearchApplication = ({ onClose }: CreateSearchApplicationFlyoutProps) => { + const { createSearchApplication, setName, setSelectedIndices } = useActions( + CreateSearchApplicationLogic + ); const { createDisabled, - createEngineError, - createEngineStatus, - engineName, - engineNameStatus, + createSearchApplicationError, + createSearchApplicationStatus, + searchApplicationName, + searchApplicationNameStatus, formDisabled, indicesStatus, selectedIndices, - } = useValues(CreateEngineLogic); + } = useValues(CreateSearchApplicationLogic); const { search } = useLocation() as unknown as Location; const { ...params } = parseQueryParams(search); @@ -80,27 +82,30 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => {

- {i18n.translate('xpack.enterpriseSearch.content.engines.createEngine.headerTitle', { - defaultMessage: 'Create a Search Application', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.headerTitle', + { + defaultMessage: 'Create a Search Application', + } + )}

{i18n.translate( - 'xpack.enterpriseSearch.content.engines.createEngine.header.docsLink', + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.header.docsLink', { defaultMessage: 'Search Applications documentation' } )} @@ -109,17 +114,17 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { />

- {createEngineStatus === Status.ERROR && createEngineError && ( + {createSearchApplicationStatus === Status.ERROR && createSearchApplicationError && ( <> - {getErrorsFromHttpResponse(createEngineError).map((errMessage, i) => ( + {getErrorsFromHttpResponse(createSearchApplicationError).map((errMessage, i) => (

{errMessage}

))}
@@ -131,14 +136,14 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { @@ -157,7 +162,7 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { ), status: indicesStatus, title: i18n.translate( - 'xpack.enterpriseSearch.content.engines.createEngine.selectIndices.title', + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.selectIndices.title', { defaultMessage: 'Select indices' } ), }, @@ -167,16 +172,16 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { fullWidth disabled={formDisabled} placeholder={i18n.translate( - 'xpack.enterpriseSearch.content.engines.createEngine.nameEngine.placeholder', + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.placeholder', { defaultMessage: 'Search application name' } )} - value={engineName} - onChange={(e) => setEngineName(e.target.value)} + value={searchApplicationName} + onChange={(e) => setName(e.target.value)} /> ), - status: engineNameStatus, + status: searchApplicationNameStatus, title: i18n.translate( - 'xpack.enterpriseSearch.content.engines.createEngine.nameEngine.title', + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.title', { defaultMessage: 'Name your search application' } ), }, @@ -190,7 +195,7 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { {CANCEL_BUTTON_LABEL} @@ -200,16 +205,17 @@ export const CreateEngineFlyout = ({ onClose }: CreateEngineFlyoutProps) => { { - createEngine(); - }} + onClick={() => createSearchApplication()} > - {i18n.translate('xpack.enterpriseSearch.content.engines.createEngine.submit', { - defaultMessage: 'Create', - })} + {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.createSearchApplication.submit', + { + defaultMessage: 'Create', + } + )}
diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.test.ts new file mode 100644 index 0000000000000..34b084a1285ab --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.test.ts @@ -0,0 +1,168 @@ +/* + * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; + +import { HttpError, Status } from '../../../../../common/types/api'; + +import { KibanaLogic } from '../../../shared/kibana'; +import { CreateSearchApplicationApiLogic } from '../../api/search_applications/create_search_application_api_logic'; + +import { SEARCH_APPLICATIONS_PATH } from '../../routes'; + +import { + CreateSearchApplicationLogic, + CreateSearchApplicationLogicValues, +} from './create_search_application_logic'; + +const DEFAULT_VALUES: CreateSearchApplicationLogicValues = { + createDisabled: true, + createSearchApplicationError: undefined, + createSearchApplicationStatus: Status.IDLE, + formDisabled: false, + indicesStatus: 'incomplete', + searchApplicationName: '', + searchApplicationNameStatus: 'incomplete', + selectedIndices: [], +}; + +const VALID_SEARCH_APPLICATION_NAME = 'unit-test-001'; +const INVALID_SEARCH_APPLICATION_NAME = 'TEST'; +const VALID_INDICES_DATA = ['search-index-01']; + +describe('CreateSearchApplicationLogic', () => { + const { mount: apiLogicMount } = new LogicMounter(CreateSearchApplicationApiLogic); + const { mount } = new LogicMounter(CreateSearchApplicationLogic); + + beforeEach(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + apiLogicMount(); + mount(); + }); + + it('has expected defaults', () => { + expect(CreateSearchApplicationLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('listeners', () => { + it('createSearchApplication makes expected request action with VALID_SEARCH_APPLICATION_NAME', () => { + jest.spyOn(CreateSearchApplicationLogic.actions, 'createSearchApplicationRequest'); + + CreateSearchApplicationLogic.actions.setName(VALID_SEARCH_APPLICATION_NAME); + CreateSearchApplicationLogic.actions.setSelectedIndices(VALID_INDICES_DATA); + + CreateSearchApplicationLogic.actions.createSearchApplication(); + + expect( + CreateSearchApplicationLogic.actions.createSearchApplicationRequest + ).toHaveBeenCalledTimes(1); + expect( + CreateSearchApplicationLogic.actions.createSearchApplicationRequest + ).toHaveBeenCalledWith({ + indices: ['search-index-01'], + name: VALID_SEARCH_APPLICATION_NAME, + }); + }); + + it('createSearchApplication makes expected request action with INVALID_SEARCH_APPLICATION_NAME', () => { + jest.spyOn(CreateSearchApplicationLogic.actions, 'createSearchApplicationRequest'); + + CreateSearchApplicationLogic.actions.setName(INVALID_SEARCH_APPLICATION_NAME); + CreateSearchApplicationLogic.actions.setSelectedIndices(VALID_INDICES_DATA); + + CreateSearchApplicationLogic.actions.createSearchApplication(); + + expect( + CreateSearchApplicationLogic.actions.createSearchApplicationRequest + ).toHaveBeenCalledTimes(1); + expect( + CreateSearchApplicationLogic.actions.createSearchApplicationRequest + ).toHaveBeenCalledWith({ + indices: ['search-index-01'], + name: INVALID_SEARCH_APPLICATION_NAME, + }); + }); + it('createSearchApplication returns error when duplicate search application is created', () => { + const httpError: HttpError = { + body: { + error: 'search_application_already_exists', + message: 'Search application name already taken. Choose another name.', + statusCode: 409, + }, + fetchOptions: {}, + request: {}, + } as HttpError; + CreateSearchApplicationApiLogic.actions.apiError(httpError); + expect(CreateSearchApplicationLogic.values.createSearchApplicationError).toEqual(httpError); + }); + + it('searchApplicationCreated is handled and is navigated to Search application list page', () => { + jest.spyOn(CreateSearchApplicationLogic.actions, 'fetchSearchApplications'); + jest + .spyOn(KibanaLogic.values, 'navigateToUrl') + .mockImplementationOnce(() => Promise.resolve()); + CreateSearchApplicationApiLogic.actions.apiSuccess({ + result: 'created', + }); + expect(KibanaLogic.values.navigateToUrl).toHaveBeenCalledWith(SEARCH_APPLICATIONS_PATH); + + expect(CreateSearchApplicationLogic.actions.fetchSearchApplications).toHaveBeenCalledTimes(1); + }); + }); + describe('selectors', () => { + describe('searchApplicationNameStatus', () => { + it('returns incomplete with empty search application name', () => { + expect(CreateSearchApplicationLogic.values.searchApplicationNameStatus).toEqual( + 'incomplete' + ); + }); + it('returns complete with valid search application name', () => { + CreateSearchApplicationLogic.actions.setName(VALID_SEARCH_APPLICATION_NAME); + + expect(CreateSearchApplicationLogic.values.searchApplicationNameStatus).toEqual('complete'); + }); + it('returns complete with invalid search application name', () => { + CreateSearchApplicationLogic.actions.setName(INVALID_SEARCH_APPLICATION_NAME); + expect(CreateSearchApplicationLogic.values.searchApplicationNameStatus).toEqual('complete'); + }); + }); + describe('indicesStatus', () => { + it('returns incomplete with 0 indices', () => { + expect(CreateSearchApplicationLogic.values.indicesStatus).toEqual('incomplete'); + }); + it('returns complete with at least one index', () => { + CreateSearchApplicationLogic.actions.setSelectedIndices(VALID_INDICES_DATA); + expect(CreateSearchApplicationLogic.values.indicesStatus).toEqual('complete'); + }); + }); + describe('createDisabled', () => { + it('false with valid data', () => { + CreateSearchApplicationLogic.actions.setSelectedIndices(VALID_INDICES_DATA); + CreateSearchApplicationLogic.actions.setName(VALID_SEARCH_APPLICATION_NAME); + + expect(CreateSearchApplicationLogic.values.createDisabled).toEqual(false); + }); + it('false with invalid data', () => { + CreateSearchApplicationLogic.actions.setSelectedIndices(VALID_INDICES_DATA); + CreateSearchApplicationLogic.actions.setName(INVALID_SEARCH_APPLICATION_NAME); + + expect(CreateSearchApplicationLogic.values.createDisabled).toEqual(false); + }); + }); + describe('formDisabled', () => { + it('returns true while create request in progress', () => { + CreateSearchApplicationApiLogic.actions.makeRequest({ + indices: [VALID_INDICES_DATA[0]], + name: VALID_SEARCH_APPLICATION_NAME, + }); + + expect(CreateSearchApplicationLogic.values.formDisabled).toEqual(true); + }); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.ts new file mode 100644 index 0000000000000..117b239355fee --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/create_search_application_logic.ts @@ -0,0 +1,122 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { Status } from '../../../../../common/types/api'; +import { KibanaLogic } from '../../../shared/kibana'; + +import { + CreateSearchApplicationApiLogic, + CreateSearchApplicationApiLogicActions, +} from '../../api/search_applications/create_search_application_api_logic'; +import { SEARCH_APPLICATIONS_PATH } from '../../routes'; + +import { SearchApplicationsListLogic } from './search_applications_list_logic'; + +export interface CreateSearchApplicationLogicActions { + createSearchApplication: () => void; + createSearchApplicationRequest: CreateSearchApplicationApiLogicActions['makeRequest']; + fetchSearchApplications: () => void; + searchApplicationCreateError: CreateSearchApplicationApiLogicActions['apiError']; + searchApplicationCreated: CreateSearchApplicationApiLogicActions['apiSuccess']; + setName: (name: string) => { name: string }; + setSelectedIndices: (indices: string[]) => { + indices: string[]; + }; +} + +export interface CreateSearchApplicationLogicValues { + createDisabled: boolean; + createSearchApplicationError?: typeof CreateSearchApplicationApiLogic.values.error; + createSearchApplicationStatus: typeof CreateSearchApplicationApiLogic.values.status; + formDisabled: boolean; + indicesStatus: 'complete' | 'incomplete'; + searchApplicationName: string; + searchApplicationNameStatus: 'complete' | 'incomplete'; + selectedIndices: string[]; +} + +export const CreateSearchApplicationLogic = kea< + MakeLogicType +>({ + actions: { + createSearchApplication: true, + setName: (name: string) => ({ name }), + setSelectedIndices: (indices: string[]) => ({ indices }), + }, + connect: { + actions: [ + SearchApplicationsListLogic, + ['fetchSearchApplications'], + CreateSearchApplicationApiLogic, + [ + 'makeRequest as createSearchApplicationRequest', + 'apiSuccess as searchApplicationCreated', + 'apiError as searchApplicationCreateError', + ], + ], + values: [ + CreateSearchApplicationApiLogic, + ['status as createSearchApplicationStatus', 'error as createSearchApplicationError'], + ], + }, + listeners: ({ actions, values }) => ({ + createSearchApplication: () => { + actions.createSearchApplicationRequest({ + indices: values.selectedIndices, + name: values.searchApplicationName, + }); + }, + searchApplicationCreated: () => { + actions.fetchSearchApplications(); + KibanaLogic.values.navigateToUrl(SEARCH_APPLICATIONS_PATH); + }, + }), + path: ['enterprise_search', 'content', 'create_search_application_logic'], + reducers: { + searchApplicationName: [ + '', + { + setName: (_, { name }) => name, + }, + ], + selectedIndices: [ + [], + { + setSelectedIndices: (_, { indices }) => indices, + }, + ], + }, + selectors: ({ selectors }) => ({ + createDisabled: [ + () => [selectors.indicesStatus, selectors.searchApplicationNameStatus], + ( + indicesStatus: CreateSearchApplicationLogicValues['indicesStatus'], + searchApplicationNameStatus: CreateSearchApplicationLogicValues['searchApplicationNameStatus'] + ) => indicesStatus !== 'complete' || searchApplicationNameStatus !== 'complete', + ], + searchApplicationNameStatus: [ + () => [selectors.searchApplicationName], + (searchApplicationName: string) => { + if (searchApplicationName.length === 0) return 'incomplete'; + return 'complete'; + }, + ], + formDisabled: [ + () => [selectors.createSearchApplicationStatus], + ( + createSearchApplicationStatus: CreateSearchApplicationLogicValues['createSearchApplicationStatus'] + ) => createSearchApplicationStatus === Status.LOADING, + ], + indicesStatus: [ + () => [selectors.selectedIndices], + (selectedIndices: CreateSearchApplicationLogicValues['selectedIndices']) => + selectedIndices.length > 0 ? 'complete' : 'incomplete', + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/delete_engine_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/delete_search_application_modal.tsx similarity index 56% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/delete_engine_modal.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/delete_search_application_modal.tsx index 0f8e7290d7607..1e8ccef1ed081 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/delete_engine_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/delete_search_application_modal.tsx @@ -14,33 +14,39 @@ import { i18n } from '@kbn/i18n'; import { CANCEL_BUTTON_LABEL } from '../../../shared/constants'; import { TelemetryLogic } from '../../../shared/telemetry/telemetry_logic'; -import { EnginesListLogic } from './engines_list_logic'; +import { SearchApplicationsListLogic } from './search_applications_list_logic'; -export interface DeleteEngineModalProps { - engineName: string; +export interface DeleteSearchApplicationModalProps { onClose: () => void; + searchApplicationName: string; } -export const DeleteEngineModal: React.FC = ({ engineName, onClose }) => { - const { deleteEngine } = useActions(EnginesListLogic); +export const DeleteSearchApplicationModal: React.FC = ({ + searchApplicationName, + onClose, +}) => { + const { deleteSearchApplication } = useActions(SearchApplicationsListLogic); const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic); - const { isDeleteLoading } = useValues(EnginesListLogic); + const { isDeleteLoading } = useValues(SearchApplicationsListLogic); return ( { - deleteEngine({ engineName }); + deleteSearchApplication({ searchApplicationName }); sendEnterpriseSearchTelemetry({ action: 'clicked', - metric: 'entSearchApplications-engineView-deleteEngineConfirm', + metric: 'entSearchApplications-deleteSearchApplicationConfirm', }); }} cancelButtonText={CANCEL_BUTTON_LABEL} confirmButtonText={i18n.translate( - 'xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title', + 'xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.confirmButton.title', { defaultMessage: 'Yes, delete this search application', } @@ -50,7 +56,7 @@ export const DeleteEngineModal: React.FC = ({ engineName >

{i18n.translate( - 'xpack.enterpriseSearch.content.engineList.deleteEngineModal.delete.description', + 'xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.delete.description', { defaultMessage: 'Deleting your search application is not a reversible action. Your indices will not be affected. ', diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx similarity index 60% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx index b32f45157db31..532ba053af1d0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout.tsx @@ -35,39 +35,40 @@ import { healthColorsMap } from '../../../shared/constants/health_colors'; import { generateEncodedPath } from '../../../shared/encode_path_params'; import { EuiLinkTo } from '../../../shared/react_router_helpers'; -import { EngineError } from '../engine/engine_error'; +import { SearchApplicationError } from '../search_application/search_application_error'; -import { EnginesListFlyoutLogic } from './engines_list_flyout_logic'; +import { SearchApplicationIndicesFlyoutLogic } from './search_application_indices_flyout_logic'; -export const EngineListIndicesFlyout: React.FC = () => { +export const SearchApplicationIndicesFlyout: React.FC = () => { const { - fetchEngineData, - fetchEngineName, - isFetchEngineLoading, - isFetchEngineFlyoutVisible, - fetchEngineApiStatus, - fetchEngineApiError, - } = useValues(EnginesListFlyoutLogic); - const { closeFetchIndicesFlyout } = useActions(EnginesListFlyoutLogic); + searchApplicationData, + searchApplicationName, + isSearchApplicationLoading, + isFlyoutVisible, + fetchSearchApplicationApiStatus, + fetchSearchApplicationApiError, + } = useValues(SearchApplicationIndicesFlyoutLogic); + const { closeFlyout } = useActions(SearchApplicationIndicesFlyoutLogic); - if (!fetchEngineData) return null; - const { indices } = fetchEngineData; - const engineFetchError = fetchEngineApiStatus === Status.ERROR ? true : false; + if (!searchApplicationData) return null; + const { indices } = searchApplicationData; + const searchApplicationFetchError = + fetchSearchApplicationApiStatus === Status.ERROR ? true : false; const columns: Array> = [ { field: 'name', name: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.name.columnTitle', + 'xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.name.columnTitle', { defaultMessage: 'Index name', } ), render: (indexName: string) => ( { { field: 'health', name: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.health.columnTitle', + 'xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.health.columnTitle', { defaultMessage: 'Index health', } @@ -100,7 +101,7 @@ export const EngineListIndicesFlyout: React.FC = () => { { field: 'count', name: i18n.translate( - 'xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.docsCount.columnTitle', + 'xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.docsCount.columnTitle', { defaultMessage: 'Docs count', } @@ -111,34 +112,37 @@ export const EngineListIndicesFlyout: React.FC = () => { }, ]; - if (isFetchEngineFlyoutVisible) { + if (isFlyoutVisible) { return ( - + -

- {i18n.translate('xpack.enterpriseSearch.content.enginesList.indicesFlyout.title', { - defaultMessage: 'View Indices', - })} +

+ {i18n.translate( + 'xpack.enterpriseSearch.searchApplications.list.indicesFlyout.title', + { + defaultMessage: 'View Indices', + } + )}

- {engineFetchError ? ( - + {searchApplicationFetchError ? ( + ) : ( - + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.test.ts new file mode 100644 index 0000000000000..b41a3050bbc0c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.test.ts @@ -0,0 +1,114 @@ +/* + * 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 { LogicMounter } from '../../../__mocks__/kea_logic'; + +import { nextTick } from '@kbn/test-jest-helpers'; + +import { Status } from '../../../../../common/types/api'; +import { EnterpriseSearchApplicationDetails } from '../../../../../common/types/search_applications'; + +import { FetchSearchApplicationApiLogic } from '../../api/search_applications/fetch_search_application_api_logic'; + +import { + SearchApplicationIndicesFlyoutValues, + SearchApplicationIndicesFlyoutLogic, +} from './search_application_indices_flyout_logic'; + +const DEFAULT_VALUES: SearchApplicationIndicesFlyoutValues = { + fetchSearchApplicationApiError: undefined, + fetchSearchApplicationApiStatus: Status.IDLE, + isFlyoutVisible: false, + isSearchApplicationLoading: false, + searchApplicationData: undefined, + searchApplicationName: null, +}; +const mockSearchApplicationData: EnterpriseSearchApplicationDetails = { + indices: [ + { + count: 10, + health: 'green', + name: 'search-001', + }, + { + count: 1000, + health: 'yellow', + name: 'search-002', + }, + ], + name: 'my-test-search-application', + template: { + script: { + lang: 'mustache', + params: { query_string: '*' }, + source: '', + }, + }, + updated_at_millis: 1679337823167, +}; + +describe('SearchApplicationIndicesFlyoutLogic', () => { + const { mount } = new LogicMounter(SearchApplicationIndicesFlyoutLogic); + const { mount: apiLogicMount } = new LogicMounter(FetchSearchApplicationApiLogic); + + beforeEach(() => { + jest.clearAllMocks(); + jest.useRealTimers(); + apiLogicMount(); + mount(); + }); + it('has expected default values', () => { + expect(SearchApplicationIndicesFlyoutLogic.values).toEqual(DEFAULT_VALUES); + }); + + describe('actions', () => { + describe('closeFlyout', () => { + it('set isFlyoutVisible to false and searchApplicationName is null', () => { + SearchApplicationIndicesFlyoutLogic.actions.closeFlyout(); + expect(SearchApplicationIndicesFlyoutLogic.values).toEqual(DEFAULT_VALUES); + }); + }); + describe('openFlyout', () => { + it('set isFlyoutVisible to true and sets searchApplicationName to search application name', () => { + SearchApplicationIndicesFlyoutLogic.actions.openFlyout('my-test-search-application'); + expect(SearchApplicationIndicesFlyoutLogic.values).toEqual({ + ...DEFAULT_VALUES, + fetchSearchApplicationApiStatus: Status.LOADING, + isFlyoutVisible: true, + isSearchApplicationLoading: true, + searchApplicationName: 'my-test-search-application', + }); + }); + }); + }); + + describe('selectors', () => { + it('receives fetchSearchApplication indices data on success', () => { + expect(SearchApplicationIndicesFlyoutLogic.values).toEqual(DEFAULT_VALUES); + FetchSearchApplicationApiLogic.actions.apiSuccess(mockSearchApplicationData); + expect(SearchApplicationIndicesFlyoutLogic.values).toEqual({ + ...DEFAULT_VALUES, + fetchSearchApplicationApiStatus: Status.SUCCESS, + searchApplicationData: mockSearchApplicationData, + }); + }); + }); + describe('listeners', () => { + beforeEach(() => { + FetchSearchApplicationApiLogic.actions.apiSuccess(mockSearchApplicationData); + }); + it('fetch search applications flyout when flyout is visible', async () => { + jest.useFakeTimers({ legacyFakeTimers: true }); + SearchApplicationIndicesFlyoutLogic.actions.openFlyout = jest.fn(); + SearchApplicationIndicesFlyoutLogic.actions.openFlyout('my-test-search-application'); + await nextTick(); + expect(SearchApplicationIndicesFlyoutLogic.actions.openFlyout).toHaveBeenCalledTimes(1); + expect(SearchApplicationIndicesFlyoutLogic.actions.openFlyout).toHaveBeenCalledWith( + 'my-test-search-application' + ); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.ts new file mode 100644 index 0000000000000..723b5e5e4d5b3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_application_indices_flyout_logic.ts @@ -0,0 +1,78 @@ +/* + * 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 { kea, MakeLogicType } from 'kea'; + +import { Status } from '../../../../../common/types/api'; +import { FetchSearchApplicationApiLogic } from '../../api/search_applications/fetch_search_application_api_logic'; +import { + SearchApplicationViewActions, + SearchApplicationViewLogic, + SearchApplicationViewValues, +} from '../search_application/search_application_view_logic'; + +export interface SearchApplicationIndicesFlyoutValues { + fetchSearchApplicationApiError?: SearchApplicationViewValues['fetchSearchApplicationApiError']; + fetchSearchApplicationApiStatus: SearchApplicationViewValues['fetchSearchApplicationApiStatus']; + isFlyoutVisible: boolean; + isSearchApplicationLoading: SearchApplicationViewValues['isLoadingSearchApplication']; + searchApplicationData: SearchApplicationViewValues['searchApplicationData']; // data from fetchSearchApplication API + searchApplicationName: string | null; +} +export interface SearchApplicationIndicesFlyoutActions { + closeFlyout(): void; + fetchSearchApplication: SearchApplicationViewActions['fetchSearchApplication'] | null; + openFlyout: (name: string) => { name: string }; +} + +export const SearchApplicationIndicesFlyoutLogic = kea< + MakeLogicType +>({ + actions: { + closeFlyout: true, + openFlyout: (name) => ({ name }), + }, + connect: { + actions: [SearchApplicationViewLogic, ['fetchSearchApplication']], + values: [ + SearchApplicationViewLogic, + [ + 'searchApplicationData', + 'fetchSearchApplicationApiError', + 'fetchSearchApplicationApiStatus', + ], + ], + }, + listeners: ({}) => ({ + openFlyout: async ({ name }) => { + FetchSearchApplicationApiLogic.actions.makeRequest({ name }); + }, + }), + path: ['enterprise_search', 'search_applications', 'search_application_indices_flyout_logic'], + reducers: ({}) => ({ + isFlyoutVisible: [ + false, + { + closeFlyout: () => false, + openFlyout: () => true, + }, + ], + searchApplicationName: [ + null, + { + closeFlyout: () => null, + openFlyout: (_, { name }) => name, + }, + ], + }), + selectors: ({ selectors }) => ({ + isSearchApplicationLoading: [ + () => [selectors.fetchSearchApplicationApiStatus], + (status: SearchApplicationIndicesFlyoutValues['fetchSearchApplicationApiStatus']) => + [Status.LOADING].includes(status), + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.test.tsx similarity index 53% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.test.tsx index 5705a8f81b5b1..97aef11cb6dea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.test.tsx @@ -14,11 +14,11 @@ import { mount, shallow } from 'enzyme'; import { Status } from '../../../../../common/types/api'; import { LicensingCallout } from '../../../shared/licensing_callout/licensing_callout'; -import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_template'; +import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; -import { EmptyEnginesPrompt } from './components/empty_engines_prompt'; -import { EnginesListTable } from './components/tables/engines_table'; -import { EnginesList, CreateEngineButton } from './engines_list'; +import { EmptySearchApplicationsPrompt } from './components/empty_search_applications_prompt'; +import { SearchApplicationsListTable } from './components/tables/search_applications_table'; +import { SearchApplicationsList, CreateSearchApplicationButton } from './search_applications_list'; import { DEFAULT_META } from './types'; const DEFAULT_VALUES = { @@ -40,7 +40,7 @@ const mockValues = { { created: '1999-12-31T23:59:59Z', indices: ['index-18', 'index-23'], - name: 'engine-name-1', + name: 'search-application-1', updated: '1999-12-31T23:59:59Z', }, ], @@ -48,11 +48,11 @@ const mockValues = { }; const mockActions = { - fetchEngines: jest.fn(), + fetchSearchApplications: jest.fn(), onPaginate: jest.fn(), }; -describe('EnginesList', () => { +describe('SearchApplicationsList', () => { beforeEach(() => { jest.clearAllMocks(); global.localStorage.clear(); @@ -61,31 +61,31 @@ describe('EnginesList', () => { setMockValues(DEFAULT_VALUES); setMockActions(mockActions); - const wrapper = shallow(); - const pageTemplate = wrapper.find(EnterpriseSearchEnginesPageTemplate); + const wrapper = shallow(); + const pageTemplate = wrapper.find(EnterpriseSearchApplicationsPageTemplate); expect(pageTemplate.prop('isLoading')).toEqual(true); }); it('renders empty prompt when no data is available', () => { - setMockValues({ ...DEFAULT_VALUES, hasNoEngines: true, isFirstRequest: false }); + setMockValues({ ...DEFAULT_VALUES, hasNoSearchApplications: true, isFirstRequest: false }); setMockActions(mockActions); - const wrapper = shallow(); + const wrapper = shallow(); - expect(wrapper.find(EmptyEnginesPrompt)).toHaveLength(1); - expect(wrapper.find(EnginesListTable)).toHaveLength(0); - expect(wrapper.find(CreateEngineButton)).toHaveLength(1); - expect(wrapper.find(CreateEngineButton).prop('disabled')).toBeFalsy(); + expect(wrapper.find(EmptySearchApplicationsPrompt)).toHaveLength(1); + expect(wrapper.find(SearchApplicationsListTable)).toHaveLength(0); + expect(wrapper.find(CreateSearchApplicationButton)).toHaveLength(1); + expect(wrapper.find(CreateSearchApplicationButton).prop('disabled')).toBeFalsy(); }); - it('renders with Engines data ', async () => { + it('renders with Search Applications data ', async () => { setMockValues(mockValues); setMockActions(mockActions); - const wrapper = shallow(); + const wrapper = shallow(); - expect(wrapper.find(EnginesListTable)).toHaveLength(1); - expect(wrapper.find(EmptyEnginesPrompt)).toHaveLength(0); - expect(wrapper.find(CreateEngineButton)).toHaveLength(0); + expect(wrapper.find(SearchApplicationsListTable)).toHaveLength(1); + expect(wrapper.find(EmptySearchApplicationsPrompt)).toHaveLength(0); + expect(wrapper.find(CreateSearchApplicationButton)).toHaveLength(0); }); it('renders Platinum license callout when not Cloud or Platinum', async () => { @@ -95,13 +95,13 @@ describe('EnginesList', () => { isCloud: false, }); setMockActions(mockActions); - const wrapper = shallow(); + const wrapper = shallow(); - expect(wrapper.find(EnginesListTable)).toHaveLength(0); - expect(wrapper.find(EmptyEnginesPrompt)).toHaveLength(1); + expect(wrapper.find(SearchApplicationsListTable)).toHaveLength(0); + expect(wrapper.find(EmptySearchApplicationsPrompt)).toHaveLength(1); expect(wrapper.find(LicensingCallout)).toHaveLength(1); - expect(wrapper.find(CreateEngineButton)).toHaveLength(1); - expect(wrapper.find(CreateEngineButton).prop('disabled')).toBeTruthy(); + expect(wrapper.find(CreateSearchApplicationButton)).toHaveLength(1); + expect(wrapper.find(CreateSearchApplicationButton).prop('disabled')).toBeTruthy(); }); it('Does not render Platinum license callout when Cloud', async () => { @@ -111,29 +111,33 @@ describe('EnginesList', () => { isCloud: true, }); setMockActions(mockActions); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find(LicensingCallout)).toHaveLength(0); }); }); -describe('CreateEngineButton', () => { +describe('CreateSearchApplicationButton', () => { describe('disabled={true}', () => { it('renders a disabled button that shows a popover when hovered', () => { - const wrapper = mount(); + const wrapper = mount(); const button = wrapper.find( - 'button[data-test-subj="enterprise-search-content-engines-creation-button"]' + 'button[data-test-subj="enterprise-search-search-applications-creation-button"]' ); expect(button).toHaveLength(1); expect(button.prop('disabled')).toBeTruthy(); - let popover = wrapper.find('div[data-test-subj="create-engine-button-popover-content"]'); + let popover = wrapper.find( + 'div[data-test-subj="create-search-application-button-popover-content"]' + ); expect(popover).toHaveLength(0); - const hoverTarget = wrapper.find('div[data-test-subj="create-engine-button-hover-target"]'); + const hoverTarget = wrapper.find( + 'div[data-test-subj="create-search-application-button-hover-target"]' + ); expect(hoverTarget).toHaveLength(1); @@ -141,7 +145,9 @@ describe('CreateEngineButton', () => { wrapper.update(); - popover = wrapper.find('div[data-test-subj="create-engine-button-popover-content"]'); + popover = wrapper.find( + 'div[data-test-subj="create-search-application-button-popover-content"]' + ); expect(popover).toHaveLength(1); expect(popover.text()).toMatch( @@ -151,20 +157,24 @@ describe('CreateEngineButton', () => { }); describe('disabled={false}', () => { it('renders a button and shows a popover when hovered', () => { - const wrapper = mount(); + const wrapper = mount(); const button = wrapper.find( - 'button[data-test-subj="enterprise-search-content-engines-creation-button"]' + 'button[data-test-subj="enterprise-search-search-applications-creation-button"]' ); expect(button).toHaveLength(1); expect(button.prop('disabled')).toBeFalsy(); - let popover = wrapper.find('div[data-test-subj="create-engine-button-popover-content"]'); + let popover = wrapper.find( + 'div[data-test-subj="create-search-application-button-popover-content"]' + ); expect(popover).toHaveLength(0); - const hoverTarget = wrapper.find('div[data-test-subj="create-engine-button-hover-target"]'); + const hoverTarget = wrapper.find( + 'div[data-test-subj="create-search-application-button-hover-target"]' + ); expect(hoverTarget).toHaveLength(1); @@ -172,7 +182,9 @@ describe('CreateEngineButton', () => { wrapper.update(); - popover = wrapper.find('div[data-test-subj="create-engine-button-popover-content"]'); + popover = wrapper.find( + 'div[data-test-subj="create-search-application-button-popover-content"]' + ); expect(popover).toHaveLength(1); expect(popover.text()).toMatch( diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.tsx similarity index 62% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.tsx rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.tsx index fe16b13932ff3..7c385619729f2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list.tsx @@ -36,21 +36,23 @@ import { LICENSING_FEATURE, } from '../../../shared/licensing_callout/licensing_callout'; -import { ENGINES_PATH, ENGINE_CREATION_PATH } from '../../routes'; -import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_template'; +import { SEARCH_APPLICATIONS_PATH, SEARCH_APPLICATION_CREATION_PATH } from '../../routes'; +import { EnterpriseSearchApplicationsPageTemplate } from '../layout/page_template'; -import { EmptyEnginesPrompt } from './components/empty_engines_prompt'; -import { EnginesListTable } from './components/tables/engines_table'; -import { CreateEngineFlyout } from './create_engine_flyout'; -import { DeleteEngineModal } from './delete_engine_modal'; -import { EngineListIndicesFlyout } from './engines_list_flyout'; -import { EnginesListFlyoutLogic } from './engines_list_flyout_logic'; -import { EnginesListLogic } from './engines_list_logic'; +import { EmptySearchApplicationsPrompt } from './components/empty_search_applications_prompt'; +import { SearchApplicationsListTable } from './components/tables/search_applications_table'; +import { CreateSearchApplication } from './create_search_application_flyout'; +import { DeleteSearchApplicationModal } from './delete_search_application_modal'; +import { SearchApplicationIndicesFlyout } from './search_application_indices_flyout'; +import { SearchApplicationIndicesFlyoutLogic } from './search_application_indices_flyout_logic'; +import { SearchApplicationsListLogic } from './search_applications_list_logic'; -interface CreateEngineButtonProps { +interface CreateSearchApplicationButtonProps { disabled: boolean; } -export const CreateEngineButton: React.FC = ({ disabled }) => { +export const CreateSearchApplicationButton: React.FC = ({ + disabled, +}) => { const [showPopover, setShowPopover] = useState(false); return ( @@ -59,7 +61,7 @@ export const CreateEngineButton: React.FC = ({ disabled closePopover={() => setShowPopover(false)} button={
setShowPopover(true)} onMouseLeave={() => setShowPopover(false)} tabIndex={0} @@ -67,13 +69,13 @@ export const CreateEngineButton: React.FC = ({ disabled KibanaLogic.values.navigateToUrl(ENGINE_CREATION_PATH)} + onClick={() => KibanaLogic.values.navigateToUrl(SEARCH_APPLICATION_CREATION_PATH)} > {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.createEngineButtonLabel', + 'xpack.enterpriseSearch.searchApplications.list.createSearchApplicationButton.label', { defaultMessage: 'Create', } @@ -89,17 +91,20 @@ export const CreateEngineButton: React.FC = ({ disabled -
+
@@ -109,19 +114,21 @@ export const CreateEngineButton: React.FC = ({ disabled ); }; interface ListProps { - createEngineFlyoutOpen?: boolean; + createSearchApplicationFlyoutOpen?: boolean; } -export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => { +export const SearchApplicationsList: React.FC = ({ + createSearchApplicationFlyoutOpen, +}) => { const { - closeDeleteEngineModal, - fetchEngines, + closeDeleteSearchApplicationModal, + fetchSearchApplications, onPaginate, - openDeleteEngineModal, + openDeleteSearchApplicationModal, setSearchQuery, setIsFirstRequest, - } = useActions(EnginesListLogic); - const { openFetchEngineFlyout } = useActions(EnginesListFlyoutLogic); + } = useActions(SearchApplicationsListLogic); + const { openFlyout: openViewIndicesFlyout } = useActions(SearchApplicationIndicesFlyoutLogic); const { isCloud, navigateToUrl } = useValues(KibanaLogic); const { hasPlatinumLicense } = useValues(LicensingLogic); @@ -129,21 +136,21 @@ export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => const isGated = !isCloud && !hasPlatinumLicense; const { - deleteModalEngineName, - hasNoEngines, + deleteModalSearchApplicationName, + hasNoSearchApplications, isDeleteModalVisible, isLoading, meta, results, searchQuery, - } = useValues(EnginesListLogic); + } = useValues(SearchApplicationsListLogic); const throttledSearchQuery = useThrottle(searchQuery, INPUT_THROTTLE_DELAY_MS); useEffect(() => { // Don't fetch search applications if we don't have a valid license if (!isGated) { - fetchEngines(); + fetchSearchApplications(); } }, [meta.from, meta.size, throttledSearchQuery]); @@ -158,28 +165,33 @@ export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => return ( <> {isDeleteModalVisible ? ( - + ) : null} - - {createEngineFlyoutOpen && navigateToUrl(ENGINES_PATH)} />} - + {createSearchApplicationFlyoutOpen && ( + navigateToUrl(SEARCH_APPLICATIONS_PATH)} /> + )} + {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.documentation', + 'xpack.enterpriseSearch.searchApplications.list.documentation', { defaultMessage: 'explore our Search Applications documentation', } @@ -189,13 +201,13 @@ export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => }} /> ), - pageTitle: i18n.translate('xpack.enterpriseSearch.content.searchApplications.title', { + pageTitle: i18n.translate('xpack.enterpriseSearch.searchApplications.list.title', { defaultMessage: 'Search Applications', }), rightSideItems: isLoading ? [] - : !hasNoEngines - ? [] + : !hasNoSearchApplications + ? [] : [], }} pageViewTelemetry="Search Applications" @@ -207,19 +219,19 @@ export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => )} - {!hasNoEngines && !isGated ? ( + {!hasNoSearchApplications && !isGated ? ( <>
= ({ createEngineFlyoutOpen }) => {i18n.translate( - 'xpack.enterpriseSearch.content.searchApplications.searchPlaceholder.description', + 'xpack.enterpriseSearch.searchApplications.list.searchBar.description', { defaultMessage: 'Locate a search application via name or by its included indices.', @@ -244,7 +256,7 @@ export const EnginesList: React.FC = ({ createEngineFlyoutOpen }) => = ({ createEngineFlyoutOpen }) => /> - ) : ( - - - + + + )}
- + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.test.ts similarity index 59% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.test.ts index 52db8aef8375a..03b9e6c2562f3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.test.ts @@ -12,42 +12,42 @@ import { nextTick } from '@kbn/test-jest-helpers'; import { HttpError, Status } from '../../../../../common/types/api'; import { EnterpriseSearchApplication } from '../../../../../common/types/search_applications'; -import { FetchEnginesAPILogic } from '../../api/engines/fetch_engines_api_logic'; +import { FetchSearchApplicationsAPILogic } from '../../api/search_applications/fetch_search_applications_api_logic'; -import { EnginesListLogic } from './engines_list_logic'; +import { SearchApplicationsListLogic } from './search_applications_list_logic'; import { DEFAULT_META } from './types'; const DEFAULT_VALUES = { data: undefined, - deleteModalEngine: null, - deleteModalEngineName: '', + deleteModalSearchApplication: null, + deleteModalSearchApplicationName: '', deleteStatus: Status.IDLE, - hasNoEngines: false, + hasNoSearchApplications: false, isDeleteLoading: false, isDeleteModalVisible: false, isFirstRequest: true, isLoading: true, meta: DEFAULT_META, - parameters: { meta: DEFAULT_META, count: 0 }, + parameters: { count: 0, meta: DEFAULT_META }, results: [], searchQuery: '', status: Status.IDLE, }; -// may need to call mock engines response when ready +// may need to call mock search applications response when ready const results: EnterpriseSearchApplication[] = [ { indices: ['index-18', 'index-23'], - name: 'engine-name-1', + name: 'search-application-1', updated_at_millis: 1679337823167, }, { indices: ['index-180', 'index-230', 'index-8', 'index-2'], - name: 'engine-name-2', + name: 'search-application-2', updated_at_millis: 1679337823167, }, { indices: ['index-2', 'index-3'], - name: 'engine-name-3', + name: 'search-application-3', updated_at_millis: 1679337823167, }, ]; @@ -57,9 +57,9 @@ const mockData = { results, }; -describe('EnginesListLogic', () => { - const { mount: apiLogicMount } = new LogicMounter(FetchEnginesAPILogic); - const { mount } = new LogicMounter(EnginesListLogic); +describe('SearchApplicationsListLogic', () => { + const { mount: apiLogicMount } = new LogicMounter(FetchSearchApplicationsAPILogic); + const { mount } = new LogicMounter(SearchApplicationsListLogic); beforeEach(() => { jest.clearAllMocks(); @@ -68,89 +68,89 @@ describe('EnginesListLogic', () => { mount(); }); it('has expected default values', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); }); describe('actions', () => { describe('onPaginate - change page', () => { beforeEach(() => { - EnginesListLogic.actions.apiSuccess({ + SearchApplicationsListLogic.actions.apiSuccess({ ...mockData, count: 11, // update count to simulate next page }); }); - it('has engine data', () => { - expect(EnginesListLogic.values.data).toEqual({ ...mockData, count: 11 }); + it('has search applications data', () => { + expect(SearchApplicationsListLogic.values.data).toEqual({ ...mockData, count: 11 }); }); it('updates meta with newPageIndex', () => { - jest.spyOn(EnginesListLogic.actions, 'fetchEngines'); - jest.spyOn(EnginesListLogic.actions, 'onPaginate'); + jest.spyOn(SearchApplicationsListLogic.actions, 'fetchSearchApplications'); + jest.spyOn(SearchApplicationsListLogic.actions, 'onPaginate'); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 11 }, - results: mockData.results, isFirstRequest: false, isLoading: false, meta: { ...DEFAULT_META, total: 11 }, - status: Status.SUCCESS, parameters: { count: 11, meta: { ...DEFAULT_META, total: 11 } }, + results: mockData.results, + status: Status.SUCCESS, }); // move to next page - EnginesListLogic.actions.onPaginate({ page: { index: 1 } }); + SearchApplicationsListLogic.actions.onPaginate({ page: { index: 1 } }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 11 }, - results: mockData.results, isFirstRequest: false, isLoading: false, meta: { ...DEFAULT_META, from: 10, total: 11 }, - status: Status.SUCCESS, parameters: { count: 11, meta: { ...DEFAULT_META, from: 10, total: 11 } }, + results: mockData.results, + status: Status.SUCCESS, }); // move back to previous page - EnginesListLogic.actions.onPaginate({ page: { index: 0 } }); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.onPaginate({ page: { index: 0 } }); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 11 }, - results: mockData.results, isFirstRequest: false, isLoading: false, meta: { ...DEFAULT_META, total: 11 }, - status: Status.SUCCESS, parameters: { count: 11, meta: { ...DEFAULT_META, total: 11 } }, + results: mockData.results, + status: Status.SUCCESS, }); - EnginesListLogic.actions.onPaginate({ page: { index: 3 } }); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.onPaginate({ page: { index: 3 } }); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 11 }, - results: mockData.results, isFirstRequest: false, isLoading: false, - meta: { ...DEFAULT_META, total: 11, from: 30 }, + meta: { ...DEFAULT_META, from: 30, total: 11 }, + parameters: { count: 11, meta: { ...DEFAULT_META, from: 30, total: 11 } }, + results: mockData.results, status: Status.SUCCESS, - parameters: { count: 11, meta: { ...DEFAULT_META, total: 11, from: 30 } }, }); }); }); - describe('closeDeleteEngineModal', () => { - it('set isDeleteModalVisible to false and engineName to empty string', () => { - EnginesListLogic.actions.openDeleteEngineModal(results[0]); - EnginesListLogic.actions.closeDeleteEngineModal(); - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); + describe('closeDeleteSearchApplicationModal', () => { + it('set isDeleteModalVisible to false and deleteModalSearchApplicationName to empty string', () => { + SearchApplicationsListLogic.actions.openDeleteSearchApplicationModal(results[0]); + SearchApplicationsListLogic.actions.closeDeleteSearchApplicationModal(); + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); }); }); - describe('openDeleteEngineModal', () => { - it('set deleteModalEngineName and set isDeleteModalVisible to true', () => { - EnginesListLogic.actions.openDeleteEngineModal(results[0]); - expect(EnginesListLogic.values).toEqual({ + describe('openDeleteSearchApplicationModal', () => { + it('set deleteModalSearchApplicationName and set isDeleteModalVisible to true', () => { + SearchApplicationsListLogic.actions.openDeleteSearchApplicationModal(results[0]); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, - deleteModalEngine: results[0], - deleteModalEngineName: 'engine-name-1', + deleteModalSearchApplication: results[0], + deleteModalSearchApplicationName: 'search-application-1', isDeleteModalVisible: true, }); }); @@ -158,8 +158,8 @@ describe('EnginesListLogic', () => { describe('setSearchQuery', () => { it('set setSearchQuery to search value', () => { - EnginesListLogic.actions.setSearchQuery('my-search-query'); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.setSearchQuery('my-search-query'); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, parameters: { count: 0, @@ -177,36 +177,39 @@ describe('EnginesListLogic', () => { describe('reducers', () => { describe('meta', () => { beforeEach(() => { - FetchEnginesAPILogic.actions.apiSuccess({ ...mockData, params: { from: 10, size: 20 } }); + FetchSearchApplicationsAPILogic.actions.apiSuccess({ + ...mockData, + params: { from: 10, size: 20 }, + }); }); - it('has engine data', () => { - expect(EnginesListLogic.values.data).toEqual({ + it('has search applications data', () => { + expect(SearchApplicationsListLogic.values.data).toEqual({ ...mockData, params: { from: 10, size: 20 }, }); }); it('updates meta with new state when apiSuccess', () => { - jest.spyOn(EnginesListLogic.actions, 'fetchEngines'); + jest.spyOn(SearchApplicationsListLogic.actions, 'fetchSearchApplications'); const newCount = 20; const newPageMeta = { from: 10, size: 20, total: newCount, }; - FetchEnginesAPILogic.actions.apiSuccess({ + FetchSearchApplicationsAPILogic.actions.apiSuccess({ ...mockData, count: newCount, params: { from: newPageMeta.from, size: newPageMeta.size }, }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: newCount, params: { from: newPageMeta.from, size: newPageMeta.size }, }, - hasNoEngines: false, + hasNoSearchApplications: false, isFirstRequest: false, isLoading: false, meta: { @@ -214,59 +217,70 @@ describe('EnginesListLogic', () => { total: newCount, }, parameters: { + count: newPageMeta.total, meta: { ...DEFAULT_META, total: newCount, }, - count: newPageMeta.total, }, results, status: Status.SUCCESS, }); }); }); - describe('request to delete Engine', () => { - it('should set isDeleteLoading to true on delete engine request', () => { - EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); - EnginesListLogic.actions.deleteError({} as HttpError); - expect(EnginesListLogic.values).toEqual({ + describe('request to delete Search Application', () => { + it('should set isDeleteLoading to true on delete search application request', () => { + SearchApplicationsListLogic.actions.deleteSearchApplication({ + searchApplicationName: results[0].name, + }); + SearchApplicationsListLogic.actions.deleteError({} as HttpError); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, deleteStatus: Status.ERROR, isDeleteLoading: false, }); }); it('should set isDeleteLoading to false on delete apiError', () => { - EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); - EnginesListLogic.actions.deleteError({} as HttpError); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.deleteSearchApplication({ + searchApplicationName: results[0].name, + }); + SearchApplicationsListLogic.actions.deleteError({} as HttpError); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, deleteStatus: Status.ERROR, isDeleteLoading: false, }); }); it('should set isDeleteLoading to false on delete apiSuccess', () => { - EnginesListLogic.actions.deleteEngine({ engineName: results[0].name }); - EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.deleteSearchApplication({ + searchApplicationName: results[0].name, + }); + SearchApplicationsListLogic.actions.deleteSuccess({ + searchApplicationName: results[0].name, + }); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, deleteStatus: Status.SUCCESS, isDeleteLoading: false, isLoading: true, - status: Status.LOADING, // fetchEngine api status + status: Status.LOADING, // fetchSearchApplication api status }); }); }); describe('isFirstRequest', () => { it('should update to true on setIsFirstRequest', () => { - EnginesListLogic.actions.setIsFirstRequest(); - expect(EnginesListLogic.values).toEqual({ ...DEFAULT_VALUES, isFirstRequest: true }); + SearchApplicationsListLogic.actions.setIsFirstRequest(); + expect(SearchApplicationsListLogic.values).toEqual({ + ...DEFAULT_VALUES, + isFirstRequest: true, + }); }); }); it('should update to false on apiError', () => { - EnginesListLogic.actions.setIsFirstRequest(); - EnginesListLogic.actions.apiError({} as HttpError); + SearchApplicationsListLogic.actions.setIsFirstRequest(); + SearchApplicationsListLogic.actions.apiError({} as HttpError); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, isFirstRequest: false, isLoading: false, @@ -274,90 +288,92 @@ describe('EnginesListLogic', () => { }); }); it('should update to false on apiSuccess', () => { - EnginesListLogic.actions.setIsFirstRequest(); - EnginesListLogic.actions.apiSuccess({ + SearchApplicationsListLogic.actions.setIsFirstRequest(); + SearchApplicationsListLogic.actions.apiSuccess({ count: 0, - results: [], params: { - q: undefined, from: DEFAULT_VALUES.meta.from, + q: undefined, size: DEFAULT_VALUES.meta.size, }, + results: [], }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, - meta: DEFAULT_VALUES.meta, data: { ...mockData, count: 0, - results: [], params: { - q: undefined, from: DEFAULT_VALUES.meta.from, + q: undefined, size: DEFAULT_VALUES.meta.size, }, + results: [], }, - hasNoEngines: true, + hasNoSearchApplications: true, isFirstRequest: false, isLoading: false, + meta: DEFAULT_VALUES.meta, status: Status.SUCCESS, }); }); }); describe('listeners', () => { - it('calls flashSuccessToast, closeDeleteEngineModal and fetchEngines on deleteSuccess', () => { - EnginesListLogic.actions.fetchEngines = jest.fn(); - EnginesListLogic.actions.closeDeleteEngineModal = jest.fn(); - EnginesListLogic.actions.deleteSuccess({ engineName: results[0].name }); + it('calls flashSuccessToast, closeDeleteSearchApplicationModal and fetchSearchApplications on deleteSuccess', () => { + SearchApplicationsListLogic.actions.fetchSearchApplications = jest.fn(); + SearchApplicationsListLogic.actions.closeDeleteSearchApplicationModal = jest.fn(); + SearchApplicationsListLogic.actions.deleteSuccess({ searchApplicationName: results[0].name }); expect(mockFlashMessageHelpers.flashSuccessToast).toHaveBeenCalledTimes(1); - expect(EnginesListLogic.actions.fetchEngines).toHaveBeenCalledWith(); - expect(EnginesListLogic.actions.closeDeleteEngineModal).toHaveBeenCalled(); + expect(SearchApplicationsListLogic.actions.fetchSearchApplications).toHaveBeenCalledWith(); + expect( + SearchApplicationsListLogic.actions.closeDeleteSearchApplicationModal + ).toHaveBeenCalled(); }); - it('call makeRequest on fetchEngines', async () => { + it('call makeRequest on fetchSearchApplications', async () => { jest.useFakeTimers({ legacyFakeTimers: true }); - EnginesListLogic.actions.makeRequest = jest.fn(); - EnginesListLogic.actions.fetchEngines(); + SearchApplicationsListLogic.actions.makeRequest = jest.fn(); + SearchApplicationsListLogic.actions.fetchSearchApplications(); await nextTick(); - expect(EnginesListLogic.actions.makeRequest).toHaveBeenCalledWith({ - meta: DEFAULT_META, + expect(SearchApplicationsListLogic.actions.makeRequest).toHaveBeenCalledWith({ count: 0, + meta: DEFAULT_META, }); }); }); describe('selectors', () => { - describe('enginesList', () => { + describe('data', () => { // response without search query parameter it('updates when apiSuccess with no search query', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ count: 0, - results, params: { - q: undefined, from: DEFAULT_META.from, + q: undefined, size: DEFAULT_META.size, }, + results, }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { count: 0, - results, params: { - q: undefined, from: DEFAULT_META.from, + q: undefined, size: DEFAULT_META.size, }, + results, }, isFirstRequest: false, isLoading: false, meta: DEFAULT_META, parameters: { - meta: DEFAULT_META, count: 0, + meta: DEFAULT_META, }, results, status: Status.SUCCESS, @@ -365,26 +381,26 @@ describe('EnginesListLogic', () => { }); // response with search query parameter and matching result it('updates when apiSuccess with search query', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results, + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { - q: 'engine', from: DEFAULT_META.from, + q: 'application', size: DEFAULT_META.size, }, - count: 0, + results, }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { count: 0, - results, params: { - q: 'engine', from: DEFAULT_META.from, + q: 'application', size: DEFAULT_META.size, }, + results, }, isFirstRequest: false, isLoading: false, @@ -399,26 +415,26 @@ describe('EnginesListLogic', () => { }); // response with search query parameter and no matching result it('updates when apiSuccess with search query with no matching results ', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results: [], + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { - q: 'zzz', from: DEFAULT_META.from, + q: 'zzz', size: DEFAULT_META.size, }, - count: 0, + results: [], }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { count: 0, - results: [], params: { - q: 'zzz', from: DEFAULT_META.from, + q: 'zzz', size: DEFAULT_META.size, }, + results: [], }, isFirstRequest: false, isLoading: false, @@ -432,26 +448,27 @@ describe('EnginesListLogic', () => { }); }); }); - describe('hasNoEngines', () => { - describe('no engines to list ', () => { - // when all engines are deleted from list page, redirect to empty engine prompt - it('updates to true when all engines are deleted ', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results: [], + describe('hasNoSearchApplications', () => { + describe('no search applications to list ', () => { + // when all search applications are deleted from list page, redirect to empty search application prompt + it('updates to true when all search applications are deleted ', () => { + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { from: DEFAULT_META.from, size: DEFAULT_META.size, }, - count: 0, + results: [], }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 0, results: [], }, + hasNoSearchApplications: true, isFirstRequest: false, isLoading: false, meta: DEFAULT_META, @@ -459,29 +476,29 @@ describe('EnginesListLogic', () => { count: 0, meta: DEFAULT_META, }, - hasNoEngines: true, results: [], status: Status.SUCCESS, }); }); - // when no engines to list, redirect to empty engine prompt + // when no search applications to list, redirect to empty search application prompt it('updates to true when isFirstRequest is true ', () => { - EnginesListLogic.actions.apiSuccess({ - results: [], + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { from: DEFAULT_META.from, size: DEFAULT_META.size, }, - count: 0, + results: [], }); - EnginesListLogic.actions.setIsFirstRequest(); - expect(EnginesListLogic.values).toEqual({ + SearchApplicationsListLogic.actions.setIsFirstRequest(); + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 0, results: [], }, + hasNoSearchApplications: true, isFirstRequest: true, isLoading: false, meta: DEFAULT_META, @@ -489,34 +506,33 @@ describe('EnginesListLogic', () => { count: 0, meta: DEFAULT_META, }, - hasNoEngines: true, results: [], status: Status.SUCCESS, }); }); - // when search query returns no engines, show engine list table + // when search query returns no search applications, show search application list table it('updates to false for a search query ', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results: [], + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ count: 0, params: { - q: 'zzz', from: DEFAULT_META.from, + q: 'zzz', size: DEFAULT_META.size, }, + results: [], }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { count: 0, - results: [], params: { - q: 'zzz', from: DEFAULT_META.from, + q: 'zzz', size: DEFAULT_META.size, }, + results: [], }, isFirstRequest: false, isLoading: false, @@ -530,25 +546,26 @@ describe('EnginesListLogic', () => { }); }); }); - describe('with engines to list', () => { - // when no search query, show table with list of engines + describe('with search applications to list', () => { + // when no search query, show table with list of search applications it('updates to false without search query ', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results, + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { - q: undefined, from: DEFAULT_META.from, + q: undefined, size: DEFAULT_META.size, }, - count: 0, + results, }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { ...mockData, count: 0, }, + hasNoSearchApplications: false, isFirstRequest: false, isLoading: false, meta: DEFAULT_META, @@ -556,34 +573,34 @@ describe('EnginesListLogic', () => { count: 0, meta: DEFAULT_META, }, - hasNoEngines: false, results, status: Status.SUCCESS, }); }); - // with search query, show table with list of engines + // with search query, show table with list of search applications it('updates to false with search query ', () => { - expect(EnginesListLogic.values).toEqual(DEFAULT_VALUES); - EnginesListLogic.actions.apiSuccess({ - results, + expect(SearchApplicationsListLogic.values).toEqual(DEFAULT_VALUES); + SearchApplicationsListLogic.actions.apiSuccess({ + count: 0, params: { - q: 'en', from: DEFAULT_META.from, + q: 'en', size: DEFAULT_META.size, }, - count: 0, + results, }); - expect(EnginesListLogic.values).toEqual({ + expect(SearchApplicationsListLogic.values).toEqual({ ...DEFAULT_VALUES, data: { - results, count: 0, params: { - q: 'en', from: DEFAULT_META.from, + q: 'en', size: DEFAULT_META.size, }, + results, }, + hasNoSearchApplications: false, isFirstRequest: false, isLoading: false, meta: DEFAULT_META, @@ -591,7 +608,6 @@ describe('EnginesListLogic', () => { count: 0, meta: DEFAULT_META, }, - hasNoEngines: false, results, status: Status.SUCCESS, }); diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.ts similarity index 50% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.ts index 978c090de3463..23fca303dd218 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/engines_list_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_list_logic.ts @@ -19,14 +19,14 @@ import { import { Actions } from '../../../shared/api_logic/create_api_logic'; import { - DeleteEngineAPILogic, - DeleteEnginesApiLogicActions, -} from '../../api/engines/delete_engines_api_logic'; + DeleteSearchApplicationAPILogic, + DeleteSearchApplicationApiLogicActions, +} from '../../api/search_applications/delete_search_application_api_logic'; import { - EnginesListAPIArguments, - FetchEnginesAPILogic, -} from '../../api/engines/fetch_engines_api_logic'; + SearchApplicationsListAPIArguments, + FetchSearchApplicationsAPILogic, +} from '../../api/search_applications/fetch_search_applications_api_logic'; import { DEFAULT_META, updateMetaPageIndex, updateMetaTotalState } from './types'; @@ -34,94 +34,100 @@ interface EuiBasicTableOnChange { page: { index: number }; } -export type EnginesListActions = Pick< - Actions, +export type SearchApplicationsListActions = Pick< + Actions, 'apiError' | 'apiSuccess' | 'makeRequest' > & { - closeDeleteEngineModal(): void; + closeDeleteSearchApplicationModal(): void; - deleteEngine: DeleteEnginesApiLogicActions['makeRequest']; - deleteError: DeleteEnginesApiLogicActions['apiError']; - deleteSuccess: DeleteEnginesApiLogicActions['apiSuccess']; + deleteError: DeleteSearchApplicationApiLogicActions['apiError']; + deleteSearchApplication: DeleteSearchApplicationApiLogicActions['makeRequest']; + deleteSuccess: DeleteSearchApplicationApiLogicActions['apiSuccess']; - fetchEngines(): void; + fetchSearchApplications(): void; onPaginate(args: EuiBasicTableOnChange): { pageNumber: number }; - openDeleteEngineModal: ( - engine: EnterpriseSearchApplication | EnterpriseSearchApplicationDetails + openDeleteSearchApplicationModal: ( + searchApplication: EnterpriseSearchApplication | EnterpriseSearchApplicationDetails ) => { - engine: EnterpriseSearchApplication; + searchApplication: EnterpriseSearchApplication; }; setIsFirstRequest(): void; setSearchQuery(searchQuery: string): { searchQuery: string }; }; -interface EngineListValues { - data: typeof FetchEnginesAPILogic.values.data; - deleteModalEngine: EnterpriseSearchApplication | null; - deleteModalEngineName: string; - deleteStatus: typeof DeleteEngineAPILogic.values.status; - hasNoEngines: boolean; +interface SearchApplicationsListValues { + data: typeof FetchSearchApplicationsAPILogic.values.data; + deleteModalSearchApplication: EnterpriseSearchApplication | null; + deleteModalSearchApplicationName: string; + deleteStatus: typeof DeleteSearchApplicationAPILogic.values.status; + hasNoSearchApplications: boolean; isDeleteLoading: boolean; isDeleteModalVisible: boolean; isFirstRequest: boolean; isLoading: boolean; meta: Page; parameters: { count: number; meta: Page; searchQuery?: string }; // Added this variable to store to the search Query value as well - results: EnterpriseSearchApplication[]; // stores engine list value from data + results: EnterpriseSearchApplication[]; // stores search applications list value from data searchQuery: string; - status: typeof FetchEnginesAPILogic.values.status; + status: typeof FetchSearchApplicationsAPILogic.values.status; } -export const EnginesListLogic = kea>({ +export const SearchApplicationsListLogic = kea< + MakeLogicType +>({ actions: { - closeDeleteEngineModal: true, - fetchEngines: true, + closeDeleteSearchApplicationModal: true, + fetchSearchApplications: true, onPaginate: (args: EuiBasicTableOnChange) => ({ pageNumber: args.page.index }), - openDeleteEngineModal: (engine) => ({ engine }), + openDeleteSearchApplicationModal: (searchApplication) => ({ searchApplication }), setIsFirstRequest: true, setSearchQuery: (searchQuery: string) => ({ searchQuery }), }, connect: { actions: [ - FetchEnginesAPILogic, + FetchSearchApplicationsAPILogic, ['makeRequest', 'apiSuccess', 'apiError'], - DeleteEngineAPILogic, - ['apiSuccess as deleteSuccess', 'makeRequest as deleteEngine', 'apiError as deleteError'], + DeleteSearchApplicationAPILogic, + [ + 'apiSuccess as deleteSuccess', + 'makeRequest as deleteSearchApplication', + 'apiError as deleteError', + ], ], values: [ - FetchEnginesAPILogic, + FetchSearchApplicationsAPILogic, ['data', 'status'], - DeleteEngineAPILogic, + DeleteSearchApplicationAPILogic, ['status as deleteStatus'], ], }, listeners: ({ actions, values }) => ({ deleteSuccess: () => { - actions.closeDeleteEngineModal(); - actions.fetchEngines(); + actions.closeDeleteSearchApplicationModal(); + actions.fetchSearchApplications(); }, - fetchEngines: async () => { + fetchSearchApplications: async () => { actions.makeRequest(values.parameters); }, }), - path: ['enterprise_search', 'content', 'engine_list_logic'], + path: ['enterprise_search', 'search_applications', 'search_applications_list_logic'], reducers: ({}) => ({ - deleteModalEngine: [ + deleteModalSearchApplication: [ null, { - closeDeleteEngineModal: () => null, - openDeleteEngineModal: (_, { engine }) => engine, + closeDeleteSearchApplicationModal: () => null, + openDeleteSearchApplicationModal: (_, { searchApplication }) => searchApplication, }, ], isDeleteModalVisible: [ false, { - closeDeleteEngineModal: () => false, - openDeleteEngineModal: () => true, + closeDeleteSearchApplicationModal: () => false, + openDeleteSearchApplicationModal: () => true, }, ], isFirstRequest: [ @@ -159,21 +165,28 @@ export const EnginesListLogic = kea ({ - deleteModalEngineName: [() => [selectors.deleteModalEngine], (engine) => engine?.name ?? ''], - hasNoEngines: [ + deleteModalSearchApplicationName: [ + () => [selectors.deleteModalSearchApplication], + (searchApplication) => searchApplication?.name ?? '', + ], + hasNoSearchApplications: [ () => [selectors.data, selectors.results], - (data: EngineListValues['data'], results: EngineListValues['results']) => - (data?.params?.from === 0 && results.length === 0 && !data?.params?.q) ?? false, + ( + data: SearchApplicationsListValues['data'], + results: SearchApplicationsListValues['results'] + ) => (data?.params?.from === 0 && results.length === 0 && !data?.params?.q) ?? false, ], isDeleteLoading: [ () => [selectors.deleteStatus], - (status: EngineListValues['deleteStatus']) => [Status.LOADING].includes(status), + (status: SearchApplicationsListValues['deleteStatus']) => [Status.LOADING].includes(status), ], isLoading: [ () => [selectors.status, selectors.isFirstRequest], - (status: EngineListValues['status'], isFirstRequest: EngineListValues['isFirstRequest']) => - [Status.LOADING, Status.IDLE].includes(status) && isFirstRequest, + ( + status: SearchApplicationsListValues['status'], + isFirstRequest: SearchApplicationsListValues['isFirstRequest'] + ) => [Status.LOADING, Status.IDLE].includes(status) && isFirstRequest, ], meta: [() => [selectors.parameters], (parameters) => parameters.meta], results: [() => [selectors.data], (data) => data?.results ?? []], diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_router.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_router.tsx new file mode 100644 index 0000000000000..937d62e059b83 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/search_applications_router.tsx @@ -0,0 +1,41 @@ +/* + * 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 React from 'react'; +import { Switch } from 'react-router-dom'; + +import { Route } from '@kbn/shared-ux-router'; + +import { + SEARCH_APPLICATIONS_PATH, + SEARCH_APPLICATION_CREATION_PATH, + SEARCH_APPLICATION_PATH, +} from '../../routes'; + +import { NotFound } from '../not_found'; +import { SearchApplicationRouter } from '../search_application/search_application_router'; + +import { SearchApplicationsList } from './search_applications_list'; + +export const SearchApplicationsRouter: React.FC = () => { + return ( + + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/components/engines/types.ts b/x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/types.ts similarity index 100% rename from x-pack/plugins/enterprise_search/public/applications/applications/components/engines/types.ts rename to x-pack/plugins/enterprise_search/public/applications/applications/components/search_applications/types.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/applications/index.tsx index da404e2081b01..5cb12c72d9fa7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/applications/index.tsx @@ -10,16 +10,16 @@ import { Redirect, Switch } from 'react-router-dom'; import { Route } from '@kbn/shared-ux-router'; -import { EnginesRouter } from './components/engines/engines_router'; import { NotFound } from './components/not_found'; -import { ROOT_PATH, ENGINES_PATH } from './routes'; +import { SearchApplicationsRouter } from './components/search_applications/search_applications_router'; +import { ROOT_PATH, SEARCH_APPLICATIONS_PATH } from './routes'; export const Applications = () => { return ( - - - + + + diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/routes.ts b/x-pack/plugins/enterprise_search/public/applications/applications/routes.ts index e294449f742c6..ad9a57411d0fd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/applications/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/applications/routes.ts @@ -7,22 +7,22 @@ export const ROOT_PATH = '/'; -export const ENGINES_PATH = `${ROOT_PATH}search_applications`; +export const SEARCH_APPLICATIONS_PATH = `${ROOT_PATH}search_applications`; -export enum EngineViewTabs { +export enum SearchApplicationViewTabs { PREVIEW = 'preview', CONTENT = 'content', CONNECT = 'connect', } -export const ENGINE_CREATION_PATH = `${ENGINES_PATH}/new`; -export const ENGINE_PATH = `${ENGINES_PATH}/:engineName`; -export const ENGINE_TAB_PATH = `${ENGINE_PATH}/:tabId`; -export const SEARCH_APPLICATION_CONNECT_PATH = `${ENGINE_PATH}/${EngineViewTabs.CONNECT}/:connectTabId`; +export const SEARCH_APPLICATION_CREATION_PATH = `${SEARCH_APPLICATIONS_PATH}/new`; +export const SEARCH_APPLICATION_PATH = `${SEARCH_APPLICATIONS_PATH}/:searchApplicationName`; +export const SEARCH_APPLICATION_TAB_PATH = `${SEARCH_APPLICATION_PATH}/:tabId`; +export const SEARCH_APPLICATION_CONNECT_PATH = `${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.CONNECT}/:connectTabId`; export enum SearchApplicationConnectTabs { SEARCHAPI = 'search_api', DOCUMENTATION = 'documentation', } -export const SEARCH_APPLICATION_CONTENT_PATH = `${ENGINE_PATH}/${EngineViewTabs.CONTENT}/:contentTabId`; +export const SEARCH_APPLICATION_CONTENT_PATH = `${SEARCH_APPLICATION_PATH}/${SearchApplicationViewTabs.CONTENT}/:contentTabId`; export enum SearchApplicationContentTabs { INDICES = 'indices', SCHEMA = 'schema', diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/engines_page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/engines_page_template.tsx deleted file mode 100644 index ed0cd55b7549a..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/layout/engines_page_template.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 React from 'react'; - -import { ENTERPRISE_SEARCH_CONTENT_PLUGIN } from '../../../../../common/constants'; -import { SetEnterpriseSearchEnginesChrome } from '../../../shared/kibana_chrome'; -import { EnterpriseSearchPageTemplateWrapper, PageTemplateProps } from '../../../shared/layout'; -import { useEnterpriseSearchEngineNav } from '../../../shared/layout'; -import { SendEnterpriseSearchTelemetry } from '../../../shared/telemetry'; - -export type EnterpriseSearchEnginesPageTemplateProps = PageTemplateProps & { - engineName?: string; -}; - -export const EnterpriseSearchEnginesPageTemplate: React.FC< - EnterpriseSearchEnginesPageTemplateProps -> = ({ children, pageChrome, pageViewTelemetry, engineName, ...pageTemplateProps }) => { - const navItems = useEnterpriseSearchEngineNav(engineName, pageTemplateProps.isEmptyState); - return ( - } - > - {pageViewTelemetry && ( - - )} - {children} - - ); -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx index 620e97457fd77..692770eaeb321 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/create_engine_menu_item.tsx @@ -12,7 +12,7 @@ import { EuiContextMenuItem, EuiText, EuiFlexGroup, EuiFlexItem } from '@elastic import { i18n } from '@kbn/i18n'; import { APPLICATIONS_PLUGIN } from '../../../../../../../common/constants'; -import { ENGINE_CREATION_PATH } from '../../../../../applications/routes'; +import { SEARCH_APPLICATION_CREATION_PATH } from '../../../../../applications/routes'; import { ESINDEX_QUERY_PARAMETER } from '../../../../../shared/constants'; import { generateEncodedPath } from '../../../../../shared/encode_path_params'; import { KibanaLogic } from '../../../../../shared/kibana'; @@ -29,9 +29,9 @@ export const CreateEngineMenuItem: React.FC = ({ isHiddenIndex, }) => { const searchApplicationCreationPath = !indexName - ? `${APPLICATIONS_PLUGIN.URL}${ENGINE_CREATION_PATH}` + ? `${APPLICATIONS_PLUGIN.URL}${SEARCH_APPLICATION_CREATION_PATH}` : generateEncodedPath( - `${APPLICATIONS_PLUGIN.URL}${ENGINE_CREATION_PATH}?:indexKey=:indexName`, + `${APPLICATIONS_PLUGIN.URL}${SEARCH_APPLICATION_CREATION_PATH}?:indexKey=:indexName`, { indexKey: ESINDEX_QUERY_PARAMETER, indexName, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx index 7a6abf65a59b8..db7a8cee5cd75 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/header_actions/search_engines_popover.tsx @@ -21,7 +21,7 @@ import { import { i18n } from '@kbn/i18n'; import { APPLICATIONS_PLUGIN } from '../../../../../../../common/constants'; -import { ENGINES_PATH } from '../../../../../applications/routes'; +import { SEARCH_APPLICATIONS_PATH } from '../../../../../applications/routes'; import { KibanaLogic } from '../../../../../shared/kibana'; import { CreateEngineMenuItem } from './create_engine_menu_item'; @@ -65,7 +65,7 @@ export const SearchEnginesPopover: React.FC = ({ data-telemetry-id={`entSearchContent-${ingestionMethod}-header-searchEngines-viewEngines`} icon="eye" onClick={() => { - KibanaLogic.values.navigateToUrl(APPLICATIONS_PLUGIN.URL + ENGINES_PATH, { + KibanaLogic.values.navigateToUrl(APPLICATIONS_PLUGIN.URL + SEARCH_APPLICATIONS_PATH, { shouldNotCreateHref: true, }); }} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/convert_connector_modal/convert_connector_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/convert_connector_modal/convert_connector_modal.tsx index efaccd17bfed2..c05b155e38b2e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/convert_connector_modal/convert_connector_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/shared/convert_connector_modal/convert_connector_modal.tsx @@ -25,13 +25,13 @@ export const ConvertConnectorModal: React.FC = () => { onCancel={() => hideModal()} onConfirm={() => convertConnector()} title={i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.convertInfexConfirm.title', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.convertInfexConfirm.title', { defaultMessage: 'Sure you want to convert your connector?' } )} buttonColor="danger" cancelButtonText={CANCEL_BUTTON_LABEL} confirmButtonText={i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.convertIndexConfirm.text', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.convertIndexConfirm.text', { defaultMessage: 'Yes', } @@ -43,7 +43,7 @@ export const ConvertConnectorModal: React.FC = () => {

{i18n.translate( - 'xpack.enterpriseSearch.content.engine.indices.convertIndexConfirm.description', + 'xpack.enterpriseSearch.searchApplications.searchApplication.indices.convertIndexConfirm.description', { defaultMessage: "Once you convert a native connector to a self-managed connector client this can't be undone.", diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 2897b968bf9b1..8aafff634cbf0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -138,7 +138,7 @@ export const useSearchExperiencesBreadcrumbs = (breadcrumbs: Breadcrumbs = []) = ...breadcrumbs, ]); -export const useEnterpriseSearchEnginesBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => +export const useEnterpriseSearchApplicationsBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => useEnterpriseSearchBreadcrumbs(breadcrumbs); export const useEsreBreadcrumbs = (breadcrumbs: Breadcrumbs = []) => diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts index f924307c15d39..92e442676fc0e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/index.ts @@ -14,5 +14,5 @@ export { SetAppSearchChrome, SetWorkplaceSearchChrome, SetSearchExperiencesChrome, - SetEnterpriseSearchEnginesChrome, + SetEnterpriseSearchApplicationsChrome, } from './set_chrome'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 7b2323c6d2a38..ab73d2c5bf9cb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -16,7 +16,7 @@ import { KibanaLogic } from '../kibana'; import { useGenerateBreadcrumbs, useEnterpriseSearchBreadcrumbs, - useEnterpriseSearchEnginesBreadcrumbs, + useEnterpriseSearchApplicationsBreadcrumbs, useAnalyticsBreadcrumbs, useEnterpriseSearchContentBreadcrumbs, useEsreBreadcrumbs, @@ -191,13 +191,13 @@ export const SetSearchExperiencesChrome: React.FC = ({ trail = [ return null; }; -export const SetEnterpriseSearchEnginesChrome: React.FC = ({ trail = [] }) => { +export const SetEnterpriseSearchApplicationsChrome: React.FC = ({ trail = [] }) => { const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = reverseArray(trail); const docTitle = appSearchTitle(title); - const breadcrumbs = useEnterpriseSearchEnginesBreadcrumbs( + const breadcrumbs = useEnterpriseSearchApplicationsBreadcrumbs( useGenerateBreadcrumbs([APPLICATIONS_PLUGIN.NAV_TITLE, ...trail]) ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/layout/index.ts index 81a4a89c5242d..84a0d48c6e975 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/index.ts @@ -8,4 +8,4 @@ export type { PageTemplateProps } from './page_template'; export { EnterpriseSearchPageTemplateWrapper } from './page_template'; export { generateNavLink } from './nav_link_helpers'; -export { useEnterpriseSearchNav, useEnterpriseSearchEngineNav } from './nav'; +export { useEnterpriseSearchNav, useEnterpriseSearchApplicationNav } from './nav'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx index 8aeb5557baa48..401492100eb6e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.test.tsx @@ -18,7 +18,7 @@ import { ProductAccess } from '../../../../common/types'; import { useEnterpriseSearchNav, - useEnterpriseSearchEngineNav, + useEnterpriseSearchApplicationNav, useEnterpriseSearchAnalyticsNav, } from './nav'; @@ -193,7 +193,7 @@ describe('useEnterpriseSearchContentNav', () => { }); }); -describe('useEnterpriseSearchEngineNav', () => { +describe('useEnterpriseSearchApplicationNav', () => { beforeEach(() => { jest.clearAllMocks(); mockKibanaValues.uiSettings.get.mockReturnValue(true); @@ -205,7 +205,7 @@ describe('useEnterpriseSearchEngineNav', () => { }); it('returns an array of top-level Enterprise Search nav items', () => { - expect(useEnterpriseSearchEngineNav()).toEqual([ + expect(useEnterpriseSearchApplicationNav()).toEqual([ { href: '/app/enterprise_search/overview', id: 'es_overview', @@ -281,7 +281,7 @@ describe('useEnterpriseSearchEngineNav', () => { it('returns selected engine sub nav items', () => { const engineName = 'my-test-engine'; - const navItems = useEnterpriseSearchEngineNav(engineName); + const navItems = useEnterpriseSearchApplicationNav(engineName); expect(navItems?.map((ni) => ni.name)).toEqual([ 'Overview', 'Content', @@ -304,11 +304,11 @@ describe('useEnterpriseSearchEngineNav', () => { expect(engineItem).toMatchInlineSnapshot(` Object { "href": "/app/enterprise_search/applications/search_applications/my-test-engine", - "id": "engineId", + "id": "searchApplicationId", "items": Array [ Object { "href": "/app/enterprise_search/applications/search_applications/my-test-engine/preview", - "id": "enterpriseSearchEnginePreview", + "id": "enterpriseSearchApplicationPreview", "items": undefined, "name": "Search Preview", }, @@ -337,7 +337,7 @@ describe('useEnterpriseSearchEngineNav', () => { it('returns selected engine without tabs when isEmpty', () => { const engineName = 'my-test-engine'; - const navItems = useEnterpriseSearchEngineNav(engineName, true); + const navItems = useEnterpriseSearchApplicationNav(engineName, true); expect(navItems?.map((ni) => ni.name)).toEqual([ 'Overview', 'Content', @@ -359,14 +359,14 @@ describe('useEnterpriseSearchEngineNav', () => { const engineItem: EuiSideNavItemType = enginesItem!.items[0]; expect(engineItem).toEqual({ href: `/app/enterprise_search/applications/search_applications/${engineName}`, - id: 'engineId', + id: 'searchApplicationId', name: engineName, }); }); it('returns selected engine with conflict warning when hasSchemaConflicts', () => { const engineName = 'my-test-engine'; - const navItems = useEnterpriseSearchEngineNav(engineName, false, true); + const navItems = useEnterpriseSearchApplicationNav(engineName, false, true); // @ts-ignore const engineItem = navItems diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx index 89bd7ed369139..841955bbf21e7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/nav.tsx @@ -23,7 +23,7 @@ import { SEARCH_EXPERIENCES_PLUGIN, WORKPLACE_SEARCH_PLUGIN, } from '../../../../common/constants'; -import { ENGINES_PATH, EngineViewTabs } from '../../applications/routes'; +import { SEARCH_APPLICATIONS_PATH, SearchApplicationViewTabs } from '../../applications/routes'; import { SEARCH_INDICES_PATH, SETTINGS_PATH } from '../../enterprise_search_content/routes'; import { KibanaLogic } from '../kibana'; @@ -183,47 +183,50 @@ export const useEnterpriseSearchNav = () => { return navItems; }; -export const useEnterpriseSearchEngineNav = ( - engineName?: string, +export const useEnterpriseSearchApplicationNav = ( + searchApplicationName?: string, isEmptyState?: boolean, hasSchemaConflicts?: boolean ) => { const navItems = useEnterpriseSearchNav(); if (!navItems) return undefined; - if (!engineName) return navItems; + if (!searchApplicationName) return navItems; const applicationsItem = navItems.find((item) => item.id === 'applications'); if (!applicationsItem || !applicationsItem.items) return navItems; - const enginesItem = applicationsItem.items?.find((item) => item.id === 'searchApplications'); - if (!enginesItem || enginesItem.id !== 'searchApplications') return navItems; + const searchApplicationsItem = applicationsItem.items?.find( + (item) => item.id === 'searchApplications' + ); + if (!searchApplicationsItem || searchApplicationsItem.id !== 'searchApplications') + return navItems; - const enginePath = `${APPLICATIONS_PLUGIN.URL}${ENGINES_PATH}/${engineName}`; + const searchApplicationPath = `${APPLICATIONS_PLUGIN.URL}${SEARCH_APPLICATIONS_PATH}/${searchApplicationName}`; - enginesItem.items = !isEmptyState + searchApplicationsItem.items = !isEmptyState ? [ { - id: 'engineId', - name: engineName, + id: 'searchApplicationId', + name: searchApplicationName, ...generateNavLink({ shouldNotCreateHref: true, shouldShowActiveForSubroutes: false, - to: enginePath, + to: searchApplicationPath, }), items: [ { - id: 'enterpriseSearchEnginePreview', - name: i18n.translate('xpack.enterpriseSearch.nav.engine.previewTitle', { + id: 'enterpriseSearchApplicationPreview', + name: i18n.translate('xpack.enterpriseSearch.nav.searchApplication.previewTitle', { defaultMessage: 'Search Preview', }), ...generateNavLink({ shouldNotCreateHref: true, - to: `${enginePath}/${EngineViewTabs.PREVIEW}`, + to: `${searchApplicationPath}/${SearchApplicationViewTabs.PREVIEW}`, }), }, { id: 'enterpriseSearchApplicationsContent', name: ( - {i18n.translate('xpack.enterpriseSearch.nav.engine.contentTitle', { + {i18n.translate('xpack.enterpriseSearch.nav.searchApplication.contentTitle', { defaultMessage: 'Content', })} {hasSchemaConflicts && } @@ -232,7 +235,7 @@ export const useEnterpriseSearchEngineNav = ( ...generateNavLink({ shouldNotCreateHref: true, shouldShowActiveForSubroutes: true, - to: `${enginePath}/${EngineViewTabs.CONTENT}`, + to: `${searchApplicationPath}/${SearchApplicationViewTabs.CONTENT}`, }), }, { @@ -246,7 +249,7 @@ export const useEnterpriseSearchEngineNav = ( ...generateNavLink({ shouldNotCreateHref: true, shouldShowActiveForSubroutes: true, - to: `${enginePath}/${EngineViewTabs.CONNECT}`, + to: `${searchApplicationPath}/${SearchApplicationViewTabs.CONNECT}`, }), }, ], @@ -254,12 +257,12 @@ export const useEnterpriseSearchEngineNav = ( ] : [ { - id: 'engineId', - name: engineName, + id: 'searchApplicationId', + name: searchApplicationName, ...generateNavLink({ shouldNotCreateHref: true, shouldShowActiveForSubroutes: true, - to: enginePath, + to: searchApplicationPath, }), }, ]; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 68a9564738668..ac0ce9e0615a9 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -11701,19 +11701,18 @@ "xpack.enterpriseSearch.appSearch.sourceEngines.removeEngineConfirmDialogue.description": "Le moteur {engineName} sera retiré de ce métamoteur. Tous les paramètres existants seront perdus. Voulez-vous vraiment continuer ?", "xpack.enterpriseSearch.content.crawler.domainDetail.title": "Gérer {domain}", "xpack.enterpriseSearch.content.crawler.extractionRules.deleteModal.description": "Si vous supprimez cette règle, cela supprimera également {fields, plural, one {une règle de champ} many {# règles de champ} other {# règles de champ}}. Cette action ne peut pas être annulée.", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.caption": "Retirer l'index {indexName}", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.caption": "Afficher l'index {indexName}", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.title": "{totalConflictsHiddenByTypeFilters, number} {totalConflictsHiddenByTypeFilters, plural, one {conflit} many {conflits} other {conflits}} en plus ne sont pas affichés ici", - "xpack.enterpriseSearch.content.engine.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, one {Champ} many {Champs} other {Champs}}", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.title": "Document : {id}", - "xpack.enterpriseSearch.content.engine.searchPreview.pageTitle": "{engineName}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.id": "ID : {id}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.moreFieldsButton": "{count} {count, plural, one {autre champ} many {autres champs} other {autres champs}}", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.option.label": "{value} {value, plural, one {Résultat} many {Résultats} other {Résultats}}", - "xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title": "{engineName} a été supprimé", - "xpack.enterpriseSearch.content.engines.createEngine.headerSubTitle": "Pour en savoir plus, explorez notre {enginesDocsLink} !", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.subTitle": "Afficher les index associés à {engineName}", - "xpack.enterpriseSearch.content.enginesList.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, one {index} many {index} other {index}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.caption": "Retirer l'index {indexName}", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.caption": "Afficher l'index {indexName}", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.title": "{totalConflictsHiddenByTypeFilters, number} {totalConflictsHiddenByTypeFilters, plural, one {conflit} many {conflits} other {conflits}} en plus ne sont pas affichés ici", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, one {Champ} many {Champs} other {Champs}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.title": "Document : {id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.id": "ID : {id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.moreFieldsButton": "{count} {count, plural, one {autre champ} many {autres champs} other {autres champs}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.option.label": "{value} {value, plural, one {Résultat} many {Résultats} other {Résultats}}", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplication.successToast.title": "{searchApplicationName} a été supprimé", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerSubTitle": "Pour en savoir plus, explorez notre {docsLink} !", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.subTitle": "Afficher les index associés à {searchApplicationName}", + "xpack.enterpriseSearch.searchApplications.list.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, one {index} many {index} other {index}}", "xpack.enterpriseSearch.content.index.connector.syncRules.description": "Ajoutez une règle de synchronisation pour personnaliser les données qui sont synchronisées à partir de {indexName}. Tout est inclus par défaut, et les documents sont validés par rapport à l'ensemble des règles de synchronisation configurées dans l'ordre répertorié.", "xpack.enterpriseSearch.content.index.connector.syncRules.flyout.errorTitle": "{ids} {idsLength, plural, one {règle} many {règles} other {règles}} de synchronisation {idsLength, plural, one {est} many {sont} other {sont}} non valide(s).", "xpack.enterpriseSearch.content.index.pipelines.copyCustomizeCallout.description": "Votre index utilise notre pipeline d'ingestion par défaut {defaultPipeline}. Copiez ce pipeline dans une configuration spécifique à l'index pour déverrouiller la possibilité de créer des pipelines d'ingestion et d'inférence personnalisés.", @@ -11749,8 +11748,8 @@ "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.isInvalid.error": "{indexName} n'est pas un nom d'index valide", "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.nameInputHelpText.lineOne": "Votre index sera nommé : {indexName}", "xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.description": "Un index supprimé appelé {indexName} était, à l'origine, lié à une configuration de connecteur. Voulez-vous remplacer cette configuration de connecteur par la nouvelle ?", - "xpack.enterpriseSearch.content.searchApplications.description": "Les applications de recherche permettent de rendre vos données Elasticsearch consultables par les utilisateurs finaux, avec des outils de pertinence, d'analyse et de personnalisation prêts à l'emploi. Pour en savoir plus, {documentationUrl}.", - "xpack.enterpriseSearch.content.searchApplications.enginesList.description": "Affichage de {from}-{to} sur {total}", + "xpack.enterpriseSearch.searchApplications.list.description": "Les applications de recherche permettent de rendre vos données Elasticsearch consultables par les utilisateurs finaux, avec des outils de pertinence, d'analyse et de personnalisation prêts à l'emploi. Pour en savoir plus, {documentationUrl}.", + "xpack.enterpriseSearch.searchApplications.list.itemRange": "Affichage de {from}-{to} sur {total}", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.description": "Affichage de {results} sur {total}. Nombre maximal de résultats de recherche de {maximum} documents.", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage": "Documents par page : {docPerPage}", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option": "{docCount} documents", @@ -12878,99 +12877,99 @@ "xpack.enterpriseSearch.content.crawler.extractionRulesTable.emptyMessageTitle": "Il n'existe aucune règle d'extraction de contenu", "xpack.enterpriseSearch.content.crawler.siteMaps": "Plans de site", "xpack.enterpriseSearch.content.description": "Enterprise Search offre un certain nombre de moyens de rendre vos données facilement interrogeables. Vous pouvez choisir entre le robot d'indexation, les indices Elasticsearch, l'API, les téléchargements directs ou les connecteurs tiers.", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.apiKeyWarning": "Elastic ne stocke pas les clés d’API. Une fois la clé générée, vous ne pourrez la visualiser qu'une seule fois. Veillez à l'enregistrer dans un endroit sûr. Si vous n'y avez plus accès, vous devrez générer une nouvelle clé d’API à partir de cet écran.", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.cancel": "Annuler", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.csvDownloadButton": "Télécharger la clé d'API", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.done": "Terminé", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.generateButton": "Générer une clé en lecture seule", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.title": "Créer une clé d'API en lecture seule pour l'application de recherche", - "xpack.enterpriseSearch.content.engine.indices.actions.columnTitle": "Actions", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.title": "Supprimer cet index de l'application de recherche", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.title": "Afficher cet index", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.cancelButton": "Annuler", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.selectableLabel": "Sélectionner des index interrogeables", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.submitButton": "Ajouter la sélection", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.title": "Ajouter de nouveaux index", - "xpack.enterpriseSearch.content.engine.indices.addNewIndicesButton": "Ajouter de nouveaux index", - "xpack.enterpriseSearch.content.engine.indices.docsCount.columnTitle": "Nombre de documents", - "xpack.enterpriseSearch.content.engine.indices.docsCount.notAvailableLabel": "S. O.", - "xpack.enterpriseSearch.content.engine.indices.health.columnTitle": "Intégrité des index", - "xpack.enterpriseSearch.content.engine.indices.name.columnTitle": "Nom de l'index", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.description": "L'index ne sera pas supprimé. Vous pourrez l'ajouter de nouveau à cette application de recherche ultérieurement.", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.text": "Oui, retirer cet index", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.title": "Supprimer cet index de l'application de recherche", - "xpack.enterpriseSearch.content.engine.indices.searchPlaceholder": "Filtrer les index", - "xpack.enterpriseSearch.content.engine.indicesSelect.docsLabel": "Documents :", - "xpack.enterpriseSearch.content.engine.schema.field_indices.columnTitle": "Dans tous les index ?", - "xpack.enterpriseSearch.content.engine.schema.field_indices.moreInfo": "Plus d'infos", - "xpack.enterpriseSearch.content.engine.schema.field_indices.no": "Non", - "xpack.enterpriseSearch.content.engine.schema.field_indices.yes": "Oui", - "xpack.enterpriseSearch.content.engine.schema.field_name.columnTitle": "Nom du champ", - "xpack.enterpriseSearch.content.engine.schema.field_type.columnTitle": "Type du champ", - "xpack.enterpriseSearch.content.engine.schema.field_type.conflict": "Conflit", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.index.columnTitle": "Index parent", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.description": "Découvrez le mapping de champs dans", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.link": "notre documentation.", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.title": "Ce champ n'est pas mappé dans chaque index.", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.columnTitle": "Champs mappés en tant que", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.unmapped": "Non mappés", - "xpack.enterpriseSearch.content.engine.schema.filters": "Types de champ", - "xpack.enterpriseSearch.content.engine.schema.filters.clearAll": "Tout effacer ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.clearFilters": "Effacer les filtres ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.subTitle": "Afin de voir tous les conflits de champ, vous devez effacer vos filtres de recherche.", - "xpack.enterpriseSearch.content.engine.schema.filters.label": "Filtrer par", - "xpack.enterpriseSearch.content.engine.schema.filters.searchPlaceholder": "Liste de filtres ", - "xpack.enterpriseSearch.content.engine.schema.onlyShowConflicts": "Afficher uniquement les conflits", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.requestTab": "Requête", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.responseTab": "Réponse", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.searchEndpointLink": "Point de terminaison de la recherche", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.title": "Appel de l'API", - "xpack.enterpriseSearch.content.engine.searchPreivew.sortingView.relevanceLabel": "Pertinence", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.buttonTitle": "Configuration", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connect.Api": "API", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connectTitle": "Connecter", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.content.Indices": "Index", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.contentTitle": "Contenu", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settings.delete": "Supprimer cette application", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settingsTitle": "Paramètres", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.fieldLabel": "Champ", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.valueLabel": "Valeur", - "xpack.enterpriseSearch.content.engine.searchPreview.improveResultsLink": "Améliorer ces résultats", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.label": "Entrée de la recherche", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.placeholder": "Recherche", - "xpack.enterpriseSearch.content.engine.searchPreview.pageChrome": "Aperçu de la recherche", - "xpack.enterpriseSearch.content.engine.searchPreview.result.fromIndex": "de", - "xpack.enterpriseSearch.content.engine.searchPreview.result.nameColumn": "Champ", - "xpack.enterpriseSearch.content.engine.searchPreview.result.valueColumn": "Valeur", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.label": "Afficher", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.ascLabel": "Croissant", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.descLabel": "Décroissant", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.directionLabel": "Classer par", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.fieldLabel": "Trier par", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title": "Oui, supprimer cette application de recherche", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.delete.description": "La suppression de votre application de recherche ne peut pas être annulée. Vos index ne seront pas affectés. ", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.title": "Supprimer définitivement cette application de recherche ?", - "xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel": "Supprimer cette application de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.header.createError.title": "Erreur lors de la création de l'application de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.header.docsLink": "Documentation sur les applications de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.headerTitle": "Créer une application de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.placeholder": "Nom de l'application de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.title": "Nommer votre application de recherche", - "xpack.enterpriseSearch.content.engines.createEngine.selectIndices.title": "Sélectionner les index", - "xpack.enterpriseSearch.content.engines.createEngine.submit": "Créer", - "xpack.enterpriseSearch.content.engines.enginesList.empty.description": "Découvrez comment créer votre première application de recherche.", - "xpack.enterpriseSearch.content.engines.enginesList.empty.title": "Créer votre première application de recherche", - "xpack.enterpriseSearch.content.engines.indices.addIndicesFlyout.updateError.title": "Erreur lors de la mise à jour du moteur", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.docsCount.columnTitle": "Nombre de documents", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.health.columnTitle": "Intégrité des index", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.name.columnTitle": "Nom de l'index", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.title": "Afficher les index", - "xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription": "Supprimer cette application de recherche", - "xpack.enterpriseSearch.content.enginesList.table.column.actions": "Actions", - "xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription": "Afficher cette application de recherche", - "xpack.enterpriseSearch.content.enginesList.table.column.indices": "Index", - "xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated": "Dernière mise à jour", - "xpack.enterpriseSearch.content.enginesList.table.column.name": "Nom de l'application de recherche", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.apiKeyWarning": "Elastic ne stocke pas les clés d’API. Une fois la clé générée, vous ne pourrez la visualiser qu'une seule fois. Veillez à l'enregistrer dans un endroit sûr. Si vous n'y avez plus accès, vous devrez générer une nouvelle clé d’API à partir de cet écran.", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.cancel": "Annuler", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.csvDownloadButton": "Télécharger la clé d'API", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.done": "Terminé", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.generateButton": "Générer une clé en lecture seule", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.title": "Créer une clé d'API en lecture seule pour l'application de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.columnTitle": "Actions", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.title": "Supprimer cet index de l'application de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.title": "Afficher cet index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.cancelButton": "Annuler", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.selectableLabel": "Sélectionner des index interrogeables", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.submitButton": "Ajouter la sélection", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.title": "Ajouter de nouveaux index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addNewIndicesButton": "Ajouter de nouveaux index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.columnTitle": "Nombre de documents", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.notAvailableLabel": "S. O.", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.health.columnTitle": "Intégrité des index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.name.columnTitle": "Nom de l'index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.description": "L'index ne sera pas supprimé. Vous pourrez l'ajouter de nouveau à cette application de recherche ultérieurement.", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.text": "Oui, retirer cet index", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.title": "Supprimer cet index de l'application de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "Filtrer les index", + "xpack.enterpriseSearch.searchApplications.indicesSelect.docsLabel": "Documents :", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.columnTitle": "Dans tous les index ?", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.moreInfo": "Plus d'infos", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.no": "Non", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.yes": "Oui", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_name.columnTitle": "Nom du champ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.columnTitle": "Type du champ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.conflict": "Conflit", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.index.columnTitle": "Index parent", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.description": "Découvrez le mapping de champs dans", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.link": "notre documentation.", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.title": "Ce champ n'est pas mappé dans chaque index.", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.columnTitle": "Champs mappés en tant que", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.unmapped": "Non mappés", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters": "Types de champ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.clearAll": "Tout effacer ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.clearFilters": "Effacer les filtres ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.subTitle": "Afin de voir tous les conflits de champ, vous devez effacer vos filtres de recherche.", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.label": "Filtrer par", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.searchPlaceholder": "Liste de filtres ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.onlyShowConflicts": "Afficher uniquement les conflits", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.requestTab": "Requête", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.responseTab": "Réponse", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.searchEndpointLink": "Point de terminaison de la recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.title": "Appel de l'API", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.relevanceLabel": "Pertinence", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.buttonTitle": "Configuration", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connect.Api": "API", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connectTitle": "Connecter", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.content.Indices": "Index", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.contentTitle": "Contenu", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settings.delete": "Supprimer cette application", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settingsTitle": "Paramètres", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldLabel": "Champ", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.valueLabel": "Valeur", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.improveResultsLink": "Améliorer ces résultats", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.label": "Entrée de la recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.placeholder": "Recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.pageChrome": "Aperçu de la recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.fromIndex": "de", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.nameColumn": "Champ", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.valueColumn": "Valeur", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.label": "Afficher", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.ascLabel": "Croissant", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.descLabel": "Décroissant", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.directionLabel": "Classer par", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.fieldLabel": "Trier par", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.confirmButton.title": "Oui, supprimer cette application de recherche", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.delete.description": "La suppression de votre application de recherche ne peut pas être annulée. Vos index ne seront pas affectés. ", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.title": "Supprimer définitivement cette application de recherche ?", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.deleteSearchApplicationLabel": "Supprimer cette application de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.createError.title": "Erreur lors de la création de l'application de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.docsLink": "Documentation sur les applications de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerTitle": "Créer une application de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.placeholder": "Nom de l'application de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.title": "Nommer votre application de recherche", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.selectIndices.title": "Sélectionner les index", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.submit": "Créer", + "xpack.enterpriseSearch.searchApplications.list.empty.description": "Découvrez comment créer votre première application de recherche.", + "xpack.enterpriseSearch.searchApplications.list.empty.title": "Créer votre première application de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.updateError.title": "Erreur lors de la mise à jour du moteur", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.docsCount.columnTitle": "Nombre de documents", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.health.columnTitle": "Intégrité des index", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.name.columnTitle": "Nom de l'index", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.title": "Afficher les index", + "xpack.enterpriseSearch.searchApplications.list.table.column.action.delete.buttonDescription": "Supprimer cette application de recherche", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions": "Actions", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.view.buttonDescription": "Afficher cette application de recherche", + "xpack.enterpriseSearch.searchApplications.list.table.column.indices": "Index", + "xpack.enterpriseSearch.searchApplications.list.table.column.lastUpdated": "Dernière mise à jour", + "xpack.enterpriseSearch.searchApplications.list.table.column.name": "Nom de l'application de recherche", "xpack.enterpriseSearch.content.filteringRules.policy.exclude": "Exclure", "xpack.enterpriseSearch.content.filteringRules.policy.include": "Inclure", "xpack.enterpriseSearch.content.filteringRules.rules.contains": "Contient", @@ -13413,18 +13412,18 @@ "xpack.enterpriseSearch.content.overview.generateApiKeyModal.title": "Générer une clé d’API", "xpack.enterpriseSearch.content.overview.optimizedRequest.label": "Afficher la requête optimisée d'Enterprise Search", "xpack.enterpriseSearch.content.productName": "Enterprise Search", - "xpack.enterpriseSearch.content.searchApplications.connect.pageTitle": "Connecter", - "xpack.enterpriseSearch.content.searchApplications.content.indicesTabTitle": "Index", - "xpack.enterpriseSearch.content.searchApplications.content.pageTitle": "Contenu", - "xpack.enterpriseSearch.content.searchApplications.content.schemaTabTitle": "Schéma", - "xpack.enterpriseSearch.content.searchApplications.createEngineButtonLabel": "Créer", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.body": "Cette fonctionnalité est en version d'évaluation technique et pourra être modifiée ou retirée complètement dans une future version. Elastic s'efforcera au maximum de corriger tout problème, mais les fonctionnalités en version d'évaluation technique ne sont pas soumises aux accords de niveau de service d'assistance des fonctionnalités officielles en disponibilité générale.", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.title": "Version d'évaluation technique", - "xpack.enterpriseSearch.content.searchApplications.documentation": "explorer la documentation sur les applications de recherche", - "xpack.enterpriseSearch.content.searchApplications.searchBar.ariaLabel": "Applications de recherche", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder": "Applications de recherche", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder.description": "Localisez une application de recherche en fonction de son nom ou de ses index inclus.", - "xpack.enterpriseSearch.content.searchApplications.title": "Applications de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.connect.pageTitle": "Connecter", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.indicesTabTitle": "Index", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.pageTitle": "Contenu", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.schemaTabTitle": "Schéma", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationButton.label": "Créer", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.body": "Cette fonctionnalité est en version d'évaluation technique et pourra être modifiée ou retirée complètement dans une future version. Elastic s'efforcera au maximum de corriger tout problème, mais les fonctionnalités en version d'évaluation technique ne sont pas soumises aux accords de niveau de service d'assistance des fonctionnalités officielles en disponibilité générale.", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.title": "Version d'évaluation technique", + "xpack.enterpriseSearch.searchApplications.list.documentation": "explorer la documentation sur les applications de recherche", + "xpack.enterpriseSearch.searchApplications.list.searchBar.ariaLabel": "Applications de recherche", + "xpack.enterpriseSearch.searchApplications.list.searchBar.placeholder": "Applications de recherche", + "xpack.enterpriseSearch.searchApplications.list.searchBar.description": "Localisez une application de recherche en fonction de son nom ou de ses index inclus.", + "xpack.enterpriseSearch.searchApplications.list.title": "Applications de recherche", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "Annulation réussie des synchronisations", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "Configuration", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "Votre connecteur a rapporté une erreur", @@ -13902,8 +13901,8 @@ "xpack.enterpriseSearch.nav.contentSettingsTitle": "Paramètres", "xpack.enterpriseSearch.nav.contentTitle": "Contenu", "xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch", - "xpack.enterpriseSearch.nav.engine.contentTitle": "Contenu", - "xpack.enterpriseSearch.nav.engine.previewTitle": "Aperçu", + "xpack.enterpriseSearch.nav.searchApplication.contentTitle": "Contenu", + "xpack.enterpriseSearch.nav.searchApplication.previewTitle": "Aperçu", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "Aperçu", "xpack.enterpriseSearch.nav.searchApplicationsTitle": "Applications de recherche", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "Expériences de recherche", @@ -14073,7 +14072,7 @@ "xpack.enterpriseSearch.schema.errorsTable.link.view": "Afficher", "xpack.enterpriseSearch.schema.fieldNameLabel": "Nom du champ", "xpack.enterpriseSearch.schema.fieldTypeLabel": "Type du champ", - "xpack.enterpriseSearch.searchApplications.engine.notFound.action1": "Revenir aux applications de recherche", + "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "Revenir aux applications de recherche", "xpack.enterpriseSearch.searchExperiences.guide.description": "Search UI est une bibliothèque JavaScript qui offre des expériences de recherche exceptionnelles. Étant donné qu'il fonctionne immédiatement avec Elasticsearch, App Search et Workplace Search, vous pouvez donc vous concentrer sur la création de la meilleure expérience possible pour vos utilisateurs, vos clients et vos employés.", "xpack.enterpriseSearch.searchExperiences.guide.documentationLink": "Visiter la documentation Search UI", "xpack.enterpriseSearch.searchExperiences.guide.features.1": "Vous savez, pour la recherche. Elastic crée et met à jour Search UI.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d687bd4a18601..544e0bb311266 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -11700,19 +11700,18 @@ "xpack.enterpriseSearch.appSearch.sourceEngines.removeEngineConfirmDialogue.description": "エンジン{engineName}はこのメタエンジンから削除されます。すべての既存の設定は失われます。よろしいですか?", "xpack.enterpriseSearch.content.crawler.domainDetail.title": "{domain}の管理", "xpack.enterpriseSearch.content.crawler.extractionRules.deleteModal.description": "このルールを削除すると、{fields, plural, other {#個のフィールドルール}}も削除されます。この操作は元に戻すことができません。", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.caption": "インデックス{indexName}の削除", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.caption": "インデックス{indexName}を表示", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.title": "ここに表示されている以外に、その他の{totalConflictsHiddenByTypeFilters, number}件の{totalConflictsHiddenByTypeFilters, plural, other {不一致}}があります", - "xpack.enterpriseSearch.content.engine.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, other {フィールド}}", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.title": "ドキュメント:{id}", - "xpack.enterpriseSearch.content.engine.searchPreview.pageTitle": "{engineName}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.id": "ID: {id}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.moreFieldsButton": "{count} {count, plural, other {その他のフィールド}}", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.option.label": "{value} {value, plural, other {結果}}", - "xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title": "{engineName}が削除されました。", - "xpack.enterpriseSearch.content.engines.createEngine.headerSubTitle": "詳細については、{enginesDocsLink}を探索してください。", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.subTitle": "{engineName}に関連付けられたインデックスを表示", - "xpack.enterpriseSearch.content.enginesList.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, other {インデックス}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.caption": "インデックス{indexName}の削除", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.caption": "インデックス{indexName}を表示", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.title": "ここに表示されている以外に、その他の{totalConflictsHiddenByTypeFilters, number}件の{totalConflictsHiddenByTypeFilters, plural, other {不一致}}があります", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, other {フィールド}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.title": "ドキュメント:{id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.id": "ID: {id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.moreFieldsButton": "{count} {count, plural, other {その他のフィールド}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.option.label": "{value} {value, plural, other {結果}}", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplication.successToast.title": "{searchApplicationName}が削除されました。", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerSubTitle": "詳細については、{docsLink}を探索してください。", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.subTitle": "{searchApplicationName}に関連付けられたインデックスを表示", + "xpack.enterpriseSearch.searchApplications.list.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, other {インデックス}}", "xpack.enterpriseSearch.content.index.connector.syncRules.description": "同期ルールを追加して、{indexName}から同期されるデータをカスタマイズします。デフォルトではすべてが含まれます。ドキュメントは、リストの順序で、構成された同期ルールのセットに対して検証されます。", "xpack.enterpriseSearch.content.index.connector.syncRules.flyout.errorTitle": "同期{idsLength, plural, other {ルール}}{ids}{idsLength, plural, other {あります}}無効です。", "xpack.enterpriseSearch.content.index.pipelines.copyCustomizeCallout.description": "インデックスはデフォルトインジェストパイプライン\"{defaultPipeline}\"を使用しています。パイプラインをインデックス固有の構成にコピーし、カスタムインジェストと推論パイプラインを作成できるようにします。", @@ -11748,8 +11747,8 @@ "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.isInvalid.error": "{indexName}は無効なインデックス名です", "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.nameInputHelpText.lineOne": "インデックスは次の名前になります:{indexName}", "xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.description": "削除されたインデックス{indexName}は、既存のコネクター構成に関連付けられていました。既存のコネクター構成を新しいコネクター構成で置き換えますか?", - "xpack.enterpriseSearch.content.searchApplications.description": "Searchアプリケーションでは、すぐに使える関連性、分析、およびパーソナライゼーションツールを利用して、エンドユーザーがElasticsearchデータを検索できるようにします。詳細については、{documentationUrl}。", - "xpack.enterpriseSearch.content.searchApplications.enginesList.description": "{total}件中{from}-{to}件を表示中", + "xpack.enterpriseSearch.searchApplications.list.description": "Searchアプリケーションでは、すぐに使える関連性、分析、およびパーソナライゼーションツールを利用して、エンドユーザーがElasticsearchデータを検索できるようにします。詳細については、{documentationUrl}。", + "xpack.enterpriseSearch.searchApplications.list.itemRange": "{total}件中{from}-{to}件を表示中", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.description": "{total}件中{results}件を表示中。{maximum}ドキュメントが検索結果の最大数です。", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage": "毎秒あたりのドキュメント:{docPerPage}", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option": "{docCount}ドキュメント", @@ -12877,99 +12876,99 @@ "xpack.enterpriseSearch.content.crawler.extractionRulesTable.emptyMessageTitle": "コンテンツ抽出ルールがありません", "xpack.enterpriseSearch.content.crawler.siteMaps": "サイトマップ", "xpack.enterpriseSearch.content.description": "エンタープライズ サーチでは、さまざまな方法で簡単にデータを検索可能にできます。Webクローラー、Elasticsearchインデックス、API、直接アップロード、サードパーティコネクターから選択します。", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.apiKeyWarning": "ElasticはAPIキーを保存しません。生成後は、1回だけキーを表示できます。必ず安全に保管してください。アクセスできなくなった場合は、この画面から新しいAPIキーを生成する必要があります。", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.cancel": "キャンセル", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.csvDownloadButton": "APIキーのダウンロード", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.done": "完了", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.generateButton": "読み取り専用キーを生成", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.title": "検索アプリケーション読み取り専用APIキーを作成", - "xpack.enterpriseSearch.content.engine.indices.actions.columnTitle": "アクション", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.title": "このインデックスを検索アプリケーションから削除", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.title": "このインデックスを表示", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.cancelButton": "キャンセル", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.selectableLabel": "検索可能なインデックスを選択", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.submitButton": "選択項目を追加", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.title": "新しいインデックスを追加", - "xpack.enterpriseSearch.content.engine.indices.addNewIndicesButton": "新しいインデックスを追加", - "xpack.enterpriseSearch.content.engine.indices.docsCount.columnTitle": "ドキュメント数", - "xpack.enterpriseSearch.content.engine.indices.docsCount.notAvailableLabel": "N/A", - "xpack.enterpriseSearch.content.engine.indices.health.columnTitle": "インデックス正常性", - "xpack.enterpriseSearch.content.engine.indices.name.columnTitle": "インデックス名", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.description": "インデックスは削除されません。後からこの検索アプリケーションに追加することができます。", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.text": "はい。このインデックスを削除します", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.title": "このインデックスを検索アプリケーションから削除", - "xpack.enterpriseSearch.content.engine.indices.searchPlaceholder": "インデックスのフィルター", - "xpack.enterpriseSearch.content.engine.indicesSelect.docsLabel": "ドキュメント:", - "xpack.enterpriseSearch.content.engine.schema.field_indices.columnTitle": "すべてのインデックスにありますか?", - "xpack.enterpriseSearch.content.engine.schema.field_indices.moreInfo": "詳細", - "xpack.enterpriseSearch.content.engine.schema.field_indices.no": "いいえ", - "xpack.enterpriseSearch.content.engine.schema.field_indices.yes": "はい", - "xpack.enterpriseSearch.content.engine.schema.field_name.columnTitle": "フィールド名", - "xpack.enterpriseSearch.content.engine.schema.field_type.columnTitle": "フィールド型", - "xpack.enterpriseSearch.content.engine.schema.field_type.conflict": "競合", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.index.columnTitle": "親インデックス", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.description": "フィールドマッピングの詳細", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.link": "Elasticのドキュメント。", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.title": "このフィールドはすべてのインデックスでマッピングされていません。", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.columnTitle": "マッピングされたフィールド", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.unmapped": "マッピングなし", - "xpack.enterpriseSearch.content.engine.schema.filters": "フィールド型", - "xpack.enterpriseSearch.content.engine.schema.filters.clearAll": "すべて消去 ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.clearFilters": "フィルターを消去 ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.subTitle": "すべてのフィールドの不一致を表示するには、フィールドフィルターをクリアする必要があります", - "xpack.enterpriseSearch.content.engine.schema.filters.label": "フィルタリング条件", - "xpack.enterpriseSearch.content.engine.schema.filters.searchPlaceholder": "リストをフィルター ", - "xpack.enterpriseSearch.content.engine.schema.onlyShowConflicts": "不一致のみを表示", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.requestTab": "リクエスト", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.responseTab": "応答", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.searchEndpointLink": "エンドポイントを検索", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.title": "API呼び出し", - "xpack.enterpriseSearch.content.engine.searchPreivew.sortingView.relevanceLabel": "関連性", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.buttonTitle": "構成", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connect.Api": "API", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connectTitle": "接続", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.content.Indices": "インデックス", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.contentTitle": "コンテンツ", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settings.delete": "このアプリを削除", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settingsTitle": "設定", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.fieldLabel": "フィールド", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.valueLabel": "値", - "xpack.enterpriseSearch.content.engine.searchPreview.improveResultsLink": "これらの結果を改善", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.label": "検索インプット", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.placeholder": "検索", - "xpack.enterpriseSearch.content.engine.searchPreview.pageChrome": "検索プレビュー", - "xpack.enterpriseSearch.content.engine.searchPreview.result.fromIndex": "開始", - "xpack.enterpriseSearch.content.engine.searchPreview.result.nameColumn": "フィールド", - "xpack.enterpriseSearch.content.engine.searchPreview.result.valueColumn": "値", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.label": "表示", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.ascLabel": "昇順", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.descLabel": "降順", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.directionLabel": "並び順", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.fieldLabel": "並べ替え基準", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title": "はい。この検索アプリケーションを削除します", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.delete.description": "検索アプリケーショを削除すると、元に戻せません。インデックスには影響しません。", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.title": "この検索アプリケーションを完全に削除しますか?", - "xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel": "この検索アプリケーションを削除", - "xpack.enterpriseSearch.content.engines.createEngine.header.createError.title": "検索アプリケーションの作成エラー", - "xpack.enterpriseSearch.content.engines.createEngine.header.docsLink": "検索アプリケーションドキュメント", - "xpack.enterpriseSearch.content.engines.createEngine.headerTitle": "検索アプリケーションを作成", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.placeholder": "検索アプリケーション名", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.title": "検索アプリケーションの名前を指定", - "xpack.enterpriseSearch.content.engines.createEngine.selectIndices.title": "インデックスを選択", - "xpack.enterpriseSearch.content.engines.createEngine.submit": "作成", - "xpack.enterpriseSearch.content.engines.enginesList.empty.description": "最初の検索アプリケーションの作成を説明します。", - "xpack.enterpriseSearch.content.engines.enginesList.empty.title": "最初の検索アプリケーションを作成", - "xpack.enterpriseSearch.content.engines.indices.addIndicesFlyout.updateError.title": "エンジンの更新エラー", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.docsCount.columnTitle": "ドキュメント数", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.health.columnTitle": "インデックス正常性", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.name.columnTitle": "インデックス名", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.title": "インデックスを表示", - "xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription": "この検索アプリケーションを削除", - "xpack.enterpriseSearch.content.enginesList.table.column.actions": "アクション", - "xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription": "この検索アプリケーションを表示", - "xpack.enterpriseSearch.content.enginesList.table.column.indices": "インデックス", - "xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated": "最終更新", - "xpack.enterpriseSearch.content.enginesList.table.column.name": "検索アプリケーション名", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.apiKeyWarning": "ElasticはAPIキーを保存しません。生成後は、1回だけキーを表示できます。必ず安全に保管してください。アクセスできなくなった場合は、この画面から新しいAPIキーを生成する必要があります。", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.cancel": "キャンセル", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.csvDownloadButton": "APIキーのダウンロード", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.done": "完了", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.generateButton": "読み取り専用キーを生成", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.title": "検索アプリケーション読み取り専用APIキーを作成", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.columnTitle": "アクション", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.title": "このインデックスを検索アプリケーションから削除", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.title": "このインデックスを表示", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.cancelButton": "キャンセル", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.selectableLabel": "検索可能なインデックスを選択", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.submitButton": "選択項目を追加", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.title": "新しいインデックスを追加", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addNewIndicesButton": "新しいインデックスを追加", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.columnTitle": "ドキュメント数", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.notAvailableLabel": "N/A", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.health.columnTitle": "インデックス正常性", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.name.columnTitle": "インデックス名", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.description": "インデックスは削除されません。後からこの検索アプリケーションに追加することができます。", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.text": "はい。このインデックスを削除します", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.title": "このインデックスを検索アプリケーションから削除", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "インデックスのフィルター", + "xpack.enterpriseSearch.searchApplications.indicesSelect.docsLabel": "ドキュメント:", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.columnTitle": "すべてのインデックスにありますか?", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.moreInfo": "詳細", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.no": "いいえ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.yes": "はい", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_name.columnTitle": "フィールド名", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.columnTitle": "フィールド型", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.conflict": "競合", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.index.columnTitle": "親インデックス", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.description": "フィールドマッピングの詳細", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.link": "Elasticのドキュメント。", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.title": "このフィールドはすべてのインデックスでマッピングされていません。", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.columnTitle": "マッピングされたフィールド", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.unmapped": "マッピングなし", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters": "フィールド型", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.clearAll": "すべて消去 ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.clearFilters": "フィルターを消去 ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.subTitle": "すべてのフィールドの不一致を表示するには、フィールドフィルターをクリアする必要があります", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.label": "フィルタリング条件", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.searchPlaceholder": "リストをフィルター ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.onlyShowConflicts": "不一致のみを表示", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.requestTab": "リクエスト", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.responseTab": "応答", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.searchEndpointLink": "エンドポイントを検索", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.title": "API呼び出し", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.relevanceLabel": "関連性", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.buttonTitle": "構成", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connect.Api": "API", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connectTitle": "接続", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.content.Indices": "インデックス", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.contentTitle": "コンテンツ", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settings.delete": "このアプリを削除", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settingsTitle": "設定", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldLabel": "フィールド", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.valueLabel": "値", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.improveResultsLink": "これらの結果を改善", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.label": "検索インプット", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.placeholder": "検索", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.pageChrome": "検索プレビュー", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.fromIndex": "開始", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.nameColumn": "フィールド", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.valueColumn": "値", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.label": "表示", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.ascLabel": "昇順", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.descLabel": "降順", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.directionLabel": "並び順", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.fieldLabel": "並べ替え基準", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.confirmButton.title": "はい。この検索アプリケーションを削除します", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.delete.description": "検索アプリケーショを削除すると、元に戻せません。インデックスには影響しません。", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.title": "この検索アプリケーションを完全に削除しますか?", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.deleteSearchApplicationLabel": "この検索アプリケーションを削除", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.createError.title": "検索アプリケーションの作成エラー", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.docsLink": "検索アプリケーションドキュメント", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerTitle": "検索アプリケーションを作成", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.placeholder": "検索アプリケーション名", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.title": "検索アプリケーションの名前を指定", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.selectIndices.title": "インデックスを選択", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.submit": "作成", + "xpack.enterpriseSearch.searchApplications.list.empty.description": "最初の検索アプリケーションの作成を説明します。", + "xpack.enterpriseSearch.searchApplications.list.empty.title": "最初の検索アプリケーションを作成", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.updateError.title": "エンジンの更新エラー", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.docsCount.columnTitle": "ドキュメント数", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.health.columnTitle": "インデックス正常性", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.name.columnTitle": "インデックス名", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.title": "インデックスを表示", + "xpack.enterpriseSearch.searchApplications.list.table.column.action.delete.buttonDescription": "この検索アプリケーションを削除", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions": "アクション", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.view.buttonDescription": "この検索アプリケーションを表示", + "xpack.enterpriseSearch.searchApplications.list.table.column.indices": "インデックス", + "xpack.enterpriseSearch.searchApplications.list.table.column.lastUpdated": "最終更新", + "xpack.enterpriseSearch.searchApplications.list.table.column.name": "検索アプリケーション名", "xpack.enterpriseSearch.content.filteringRules.policy.exclude": "除外", "xpack.enterpriseSearch.content.filteringRules.policy.include": "含める", "xpack.enterpriseSearch.content.filteringRules.rules.contains": "を含む", @@ -13412,18 +13411,18 @@ "xpack.enterpriseSearch.content.overview.generateApiKeyModal.title": "APIキーを生成", "xpack.enterpriseSearch.content.overview.optimizedRequest.label": "エンタープライズ サーチで最適化されたリクエストを表示", "xpack.enterpriseSearch.content.productName": "エンタープライズ サーチ", - "xpack.enterpriseSearch.content.searchApplications.connect.pageTitle": "接続", - "xpack.enterpriseSearch.content.searchApplications.content.indicesTabTitle": "インデックス", - "xpack.enterpriseSearch.content.searchApplications.content.pageTitle": "コンテンツ", - "xpack.enterpriseSearch.content.searchApplications.content.schemaTabTitle": "スキーマ", - "xpack.enterpriseSearch.content.searchApplications.createEngineButtonLabel": "作成", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.body": "この機能はテクニカルプレビュー中であり、将来のリリースでは変更されたり完全に削除されたりする場合があります。Elasticは最善の努力を講じてすべての問題の修正に努めますが、テクニカルプレビュー中の機能には正式なGA機能のサポートSLAが適用されません。", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.title": "テクニカルプレビュー", - "xpack.enterpriseSearch.content.searchApplications.documentation": "検索アプリケーションのドキュメントを見る", - "xpack.enterpriseSearch.content.searchApplications.searchBar.ariaLabel": "検索アプリケーション", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder": "検索アプリケーション", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder.description": "名前または含まれているインデックスで検索アプリケーションを検索します。", - "xpack.enterpriseSearch.content.searchApplications.title": "検索アプリケーション", + "xpack.enterpriseSearch.searchApplications.searchApplication.connect.pageTitle": "接続", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.indicesTabTitle": "インデックス", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.pageTitle": "コンテンツ", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.schemaTabTitle": "スキーマ", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationButton.label": "作成", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.body": "この機能はテクニカルプレビュー中であり、将来のリリースでは変更されたり完全に削除されたりする場合があります。Elasticは最善の努力を講じてすべての問題の修正に努めますが、テクニカルプレビュー中の機能には正式なGA機能のサポートSLAが適用されません。", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.title": "テクニカルプレビュー", + "xpack.enterpriseSearch.searchApplications.list.documentation": "検索アプリケーションのドキュメントを見る", + "xpack.enterpriseSearch.searchApplications.list.searchBar.ariaLabel": "検索アプリケーション", + "xpack.enterpriseSearch.searchApplications.list.searchBar.placeholder": "検索アプリケーション", + "xpack.enterpriseSearch.searchApplications.list.searchBar.description": "名前または含まれているインデックスで検索アプリケーションを検索します。", + "xpack.enterpriseSearch.searchApplications.list.title": "検索アプリケーション", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "同期が正常にキャンセルされました", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "構成", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "コネクターでエラーが発生しました", @@ -13901,8 +13900,8 @@ "xpack.enterpriseSearch.nav.contentSettingsTitle": "設定", "xpack.enterpriseSearch.nav.contentTitle": "コンテンツ", "xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch", - "xpack.enterpriseSearch.nav.engine.contentTitle": "コンテンツ", - "xpack.enterpriseSearch.nav.engine.previewTitle": "プレビュー", + "xpack.enterpriseSearch.nav.searchApplication.contentTitle": "コンテンツ", + "xpack.enterpriseSearch.nav.searchApplication.previewTitle": "プレビュー", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概要", "xpack.enterpriseSearch.nav.searchApplicationsTitle": "検索アプリケーション", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "検索エクスペリエンス", @@ -14072,7 +14071,7 @@ "xpack.enterpriseSearch.schema.errorsTable.link.view": "表示", "xpack.enterpriseSearch.schema.fieldNameLabel": "フィールド名", "xpack.enterpriseSearch.schema.fieldTypeLabel": "フィールド型", - "xpack.enterpriseSearch.searchApplications.engine.notFound.action1": "検索アプリケーションに戻る", + "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "検索アプリケーションに戻る", "xpack.enterpriseSearch.searchExperiences.guide.description": "JavaScriptのライブラリであるSearch UIを使えば、追加の開発を行わずに、ワールドクラスの検索エクスペリエンスを実装できます。Elasticsearch、App Search、Workplace Searchでそのまま使えるため、ユーザー、顧客、従業員のための最善のエクスペリエンスを構築することに集中できます。", "xpack.enterpriseSearch.searchExperiences.guide.documentationLink": "Search UIドキュメントを表示", "xpack.enterpriseSearch.searchExperiences.guide.features.1": "検索の象徴ElasticはSearch UIを構築、管理します。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7f3aba79a5bc0..6b11bcea51340 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11700,19 +11700,18 @@ "xpack.enterpriseSearch.appSearch.sourceEngines.removeEngineConfirmDialogue.description": "这将从此元引擎中移除引擎“{engineName}”。所有现有设置将丢失。是否确定?", "xpack.enterpriseSearch.content.crawler.domainDetail.title": "管理 {domain}", "xpack.enterpriseSearch.content.crawler.extractionRules.deleteModal.description": "移除此规则还会删除 {fields, plural, other {# 个字段规则}}。此操作无法撤消。", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.caption": "移除索引 {indexName}", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.caption": "查看索引 {indexName}", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.title": "有另外 {totalConflictsHiddenByTypeFilters, number} 个{totalConflictsHiddenByTypeFilters, plural, other {冲突}}未在此处显示", - "xpack.enterpriseSearch.content.engine.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, other {字段}}", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.title": "文档:{id}", - "xpack.enterpriseSearch.content.engine.searchPreview.pageTitle": "{engineName}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.id": "ID:{id}", - "xpack.enterpriseSearch.content.engine.searchPreview.result.moreFieldsButton": "{count} {count, plural, other {更多字段}}", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.option.label": "{value} {value, plural, other {结果}}", - "xpack.enterpriseSearch.content.engineList.deleteEngine.successToast.title": "{engineName} 已删除", - "xpack.enterpriseSearch.content.engines.createEngine.headerSubTitle": "请浏览我们的 {enginesDocsLink} 了解详情!", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.subTitle": "查看与 {engineName} 关联的索引", - "xpack.enterpriseSearch.content.enginesList.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, other {索引}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.caption": "移除索引 {indexName}", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.caption": "查看索引 {indexName}", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.title": "有另外 {totalConflictsHiddenByTypeFilters, number} 个{totalConflictsHiddenByTypeFilters, plural, other {冲突}}未在此处显示", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldCount": "{fieldCount} {fieldCount, plural, other {字段}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.title": "文档:{id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.id": "ID:{id}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.moreFieldsButton": "{count} {count, plural, other {更多字段}}", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.option.label": "{value} {value, plural, other {结果}}", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplication.successToast.title": "{searchApplicationName} 已删除", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerSubTitle": "请浏览我们的 {docsLink} 了解详情!", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.subTitle": "查看与 {searchApplicationName} 关联的索引", + "xpack.enterpriseSearch.searchApplications.list.table.column.view.indices": "{indicesCount, number} {indicesCount, plural, other {索引}}", "xpack.enterpriseSearch.content.index.connector.syncRules.description": "添加同步规则以定制要从 {indexName} 同步哪些数据。默认包括所有内容,并根据按所列顺序显示的已配置同步规则集验证文档。", "xpack.enterpriseSearch.content.index.connector.syncRules.flyout.errorTitle": "同步{idsLength, plural, other {规则}} {ids}{idsLength, plural, other { }}无效。", "xpack.enterpriseSearch.content.index.pipelines.copyCustomizeCallout.description": "您的索引正使用默认采集管道 {defaultPipeline}。将该管道复制到特定于索引的配置中,以解锁创建定制采集和推理管道的功能。", @@ -11748,8 +11747,8 @@ "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.isInvalid.error": "{indexName} 为无效索引名称", "xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.nameInputHelpText.lineOne": "您的索引将命名为:{indexName}", "xpack.enterpriseSearch.content.newIndex.steps.buildConnector.confirmModal.description": "名为 {indexName} 的已删除索引最初绑定到现有连接器配置。是否要将现有连接器配置替换成新的?", - "xpack.enterpriseSearch.content.searchApplications.description": "利用开箱即用的相关性、分析和个性化工具,搜索应用程序可帮助使最终用户能够搜索您的 Elasticsearch 数据。欲了解详情,{documentationUrl}。", - "xpack.enterpriseSearch.content.searchApplications.enginesList.description": "正在显示第 {from}-{to} 个(共 {total} 个)", + "xpack.enterpriseSearch.searchApplications.list.description": "利用开箱即用的相关性、分析和个性化工具,搜索应用程序可帮助使最终用户能够搜索您的 Elasticsearch 数据。欲了解详情,{documentationUrl}。", + "xpack.enterpriseSearch.searchApplications.list.itemRange": "正在显示第 {from}-{to} 个(共 {total} 个)", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.description": "显示 {results} 个,共 {total} 个。搜索结果最多包含 {maximum} 个文档。", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.pagination.itemsPerPage": "每页文档数:{docPerPage}", "xpack.enterpriseSearch.content.searchIndex.documents.documentList.paginationOptions.option": "{docCount} 个文档", @@ -12877,99 +12876,99 @@ "xpack.enterpriseSearch.content.crawler.extractionRulesTable.emptyMessageTitle": "没有内容提取规则", "xpack.enterpriseSearch.content.crawler.siteMaps": "站点地图", "xpack.enterpriseSearch.content.description": "Enterprise Search 提供了各种方法以便您轻松搜索数据。从网络爬虫、Elasticsearch 索引、API、直接上传或第三方连接器中选择。", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.apiKeyWarning": "Elastic 不会存储 API 密钥。一旦生成,您只能查看密钥一次。请确保将其保存在某个安全位置。如果失去它的访问权限,您需要从此屏幕生成新的 API 密钥。", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.cancel": "取消", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.csvDownloadButton": "下载 API 密钥", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.done": "完成", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.generateButton": "生成只读密钥", - "xpack.enterpriseSearch.content.engine.api.generateEngineApiKeyModal.title": "创建搜索应用程序只读 API 密钥", - "xpack.enterpriseSearch.content.engine.indices.actions.columnTitle": "操作", - "xpack.enterpriseSearch.content.engine.indices.actions.removeIndex.title": "从搜索应用程序中移除此索引", - "xpack.enterpriseSearch.content.engine.indices.actions.viewIndex.title": "查看此索引", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.cancelButton": "取消", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.selectableLabel": "选择可搜索索引", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.submitButton": "添加所选内容", - "xpack.enterpriseSearch.content.engine.indices.addIndicesFlyout.title": "添加新索引", - "xpack.enterpriseSearch.content.engine.indices.addNewIndicesButton": "添加新索引", - "xpack.enterpriseSearch.content.engine.indices.docsCount.columnTitle": "文档计数", - "xpack.enterpriseSearch.content.engine.indices.docsCount.notAvailableLabel": "不可用", - "xpack.enterpriseSearch.content.engine.indices.health.columnTitle": "索引运行状况", - "xpack.enterpriseSearch.content.engine.indices.name.columnTitle": "索引名称", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.description": "这不会删除该索引。您可以在稍后将其重新添加到此搜索应用程序。", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.text": "是,移除此索引", - "xpack.enterpriseSearch.content.engine.indices.removeIndexConfirm.title": "从搜索应用程序中移除此索引", - "xpack.enterpriseSearch.content.engine.indices.searchPlaceholder": "筛选索引", - "xpack.enterpriseSearch.content.engine.indicesSelect.docsLabel": "文档:", - "xpack.enterpriseSearch.content.engine.schema.field_indices.columnTitle": "在所有索引中?", - "xpack.enterpriseSearch.content.engine.schema.field_indices.moreInfo": "更多信息", - "xpack.enterpriseSearch.content.engine.schema.field_indices.no": "否", - "xpack.enterpriseSearch.content.engine.schema.field_indices.yes": "是", - "xpack.enterpriseSearch.content.engine.schema.field_name.columnTitle": "字段名称", - "xpack.enterpriseSearch.content.engine.schema.field_type.columnTitle": "字段类型", - "xpack.enterpriseSearch.content.engine.schema.field_type.conflict": "冲突", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.index.columnTitle": "父索引", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.description": "在我们的文档中", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.link": "详细了解字段映射。", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.notInAllIndices.title": "不是每个索引都映射了此字段。", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.columnTitle": "字段已映射为", - "xpack.enterpriseSearch.content.engine.schema.fieldIndices.type.unmapped": "未映射", - "xpack.enterpriseSearch.content.engine.schema.filters": "字段类型", - "xpack.enterpriseSearch.content.engine.schema.filters.clearAll": "全部清除 ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.clearFilters": "清除筛选 ", - "xpack.enterpriseSearch.content.engine.schema.filters.conflict.callout.subTitle": "要查看所有字段冲突,必须清除字段筛选", - "xpack.enterpriseSearch.content.engine.schema.filters.label": "筛选依据", - "xpack.enterpriseSearch.content.engine.schema.filters.searchPlaceholder": "筛选列表 ", - "xpack.enterpriseSearch.content.engine.schema.onlyShowConflicts": "仅显示冲突", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.requestTab": "请求", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.responseTab": "响应", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.searchEndpointLink": "搜索终端", - "xpack.enterpriseSearch.content.engine.searchPreivew.apiCallFlyout.title": "API 调用", - "xpack.enterpriseSearch.content.engine.searchPreivew.sortingView.relevanceLabel": "相关性", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.buttonTitle": "配置", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connect.Api": "API", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.connectTitle": "连接", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.content.Indices": "索引", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.contentTitle": "内容", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settings.delete": "删除此应用", - "xpack.enterpriseSearch.content.engine.searchPreview.configuration.settingsTitle": "设置", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.fieldLabel": "字段", - "xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.valueLabel": "值", - "xpack.enterpriseSearch.content.engine.searchPreview.improveResultsLink": "改进这些结果", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.label": "搜索输入", - "xpack.enterpriseSearch.content.engine.searchPreview.inputView.placeholder": "搜索", - "xpack.enterpriseSearch.content.engine.searchPreview.pageChrome": "搜索预览", - "xpack.enterpriseSearch.content.engine.searchPreview.result.fromIndex": "来自", - "xpack.enterpriseSearch.content.engine.searchPreview.result.nameColumn": "字段", - "xpack.enterpriseSearch.content.engine.searchPreview.result.valueColumn": "值", - "xpack.enterpriseSearch.content.engine.searchPreview.resultsPerPage.label": "显示", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.ascLabel": "升序", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.descLabel": "降序", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.directionLabel": "排序依据", - "xpack.enterpriseSearch.content.engine.searchPreview.sortingView.fieldLabel": "排序依据", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.confirmButton.title": "是,删除此搜索应用程序", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.delete.description": "删除搜索应用程序是不可逆操作。您的索引不会受到影响。", - "xpack.enterpriseSearch.content.engineList.deleteEngineModal.title": "永久删除此搜索应用程序?", - "xpack.enterpriseSearch.content.engineList.table.column.actions.deleteEngineLabel": "删除此搜索应用程序", - "xpack.enterpriseSearch.content.engines.createEngine.header.createError.title": "创建搜索应用程序时出错", - "xpack.enterpriseSearch.content.engines.createEngine.header.docsLink": "搜索应用程序文档", - "xpack.enterpriseSearch.content.engines.createEngine.headerTitle": "创建搜索应用程序", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.placeholder": "搜索应用程序名称", - "xpack.enterpriseSearch.content.engines.createEngine.nameEngine.title": "命名搜索应用程序", - "xpack.enterpriseSearch.content.engines.createEngine.selectIndices.title": "选择索引", - "xpack.enterpriseSearch.content.engines.createEngine.submit": "创建", - "xpack.enterpriseSearch.content.engines.enginesList.empty.description": "下面我们指导您创建首个搜索应用程序。", - "xpack.enterpriseSearch.content.engines.enginesList.empty.title": "创建您的首个搜索应用程序", - "xpack.enterpriseSearch.content.engines.indices.addIndicesFlyout.updateError.title": "更新引擎时出错", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.docsCount.columnTitle": "文档计数", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.health.columnTitle": "索引运行状况", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.table.name.columnTitle": "索引名称", - "xpack.enterpriseSearch.content.enginesList.indicesFlyout.title": "查看索引", - "xpack.enterpriseSearch.content.enginesList.table.column.action.delete.buttonDescription": "删除此搜索应用程序", - "xpack.enterpriseSearch.content.enginesList.table.column.actions": "操作", - "xpack.enterpriseSearch.content.enginesList.table.column.actions.view.buttonDescription": "查看此搜索应用程序", - "xpack.enterpriseSearch.content.enginesList.table.column.indices": "索引", - "xpack.enterpriseSearch.content.enginesList.table.column.lastUpdated": "上次更新时间", - "xpack.enterpriseSearch.content.enginesList.table.column.name": "搜索应用程序名称", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.apiKeyWarning": "Elastic 不会存储 API 密钥。一旦生成,您只能查看密钥一次。请确保将其保存在某个安全位置。如果失去它的访问权限,您需要从此屏幕生成新的 API 密钥。", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.cancel": "取消", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.csvDownloadButton": "下载 API 密钥", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.done": "完成", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.generateButton": "生成只读密钥", + "xpack.enterpriseSearch.searchApplication.searchApplication.api.generateApiKeyModal.title": "创建搜索应用程序只读 API 密钥", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.columnTitle": "操作", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.removeIndex.title": "从搜索应用程序中移除此索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.actions.viewIndex.title": "查看此索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.cancelButton": "取消", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.selectableLabel": "选择可搜索索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.submitButton": "添加所选内容", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.title": "添加新索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addNewIndicesButton": "添加新索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.columnTitle": "文档计数", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.docsCount.notAvailableLabel": "不可用", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.health.columnTitle": "索引运行状况", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.name.columnTitle": "索引名称", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.description": "这不会删除该索引。您可以在稍后将其重新添加到此搜索应用程序。", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.text": "是,移除此索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.removeIndexConfirm.title": "从搜索应用程序中移除此索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.searchPlaceholder": "筛选索引", + "xpack.enterpriseSearch.searchApplications.indicesSelect.docsLabel": "文档:", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.columnTitle": "在所有索引中?", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.moreInfo": "更多信息", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.no": "否", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_indices.yes": "是", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_name.columnTitle": "字段名称", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.columnTitle": "字段类型", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.field_type.conflict": "冲突", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.index.columnTitle": "父索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.description": "在我们的文档中", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.link": "详细了解字段映射。", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.notInAllIndices.title": "不是每个索引都映射了此字段。", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.columnTitle": "字段已映射为", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.fieldIndices.type.unmapped": "未映射", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters": "字段类型", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.clearAll": "全部清除 ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.clearFilters": "清除筛选 ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.conflict.callout.subTitle": "要查看所有字段冲突,必须清除字段筛选", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.label": "筛选依据", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.filters.searchPlaceholder": "筛选列表 ", + "xpack.enterpriseSearch.searchApplications.searchApplication.schema.onlyShowConflicts": "仅显示冲突", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.requestTab": "请求", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.responseTab": "响应", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.searchEndpointLink": "搜索终端", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.apiCallFlyout.title": "API 调用", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.relevanceLabel": "相关性", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.buttonTitle": "配置", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connect.Api": "API", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.connectTitle": "连接", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.content.Indices": "索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.contentTitle": "内容", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settings.delete": "删除此应用", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.configuration.settingsTitle": "设置", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.fieldLabel": "字段", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.documentFlyout.valueLabel": "值", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.improveResultsLink": "改进这些结果", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.label": "搜索输入", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.inputView.placeholder": "搜索", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.pageChrome": "搜索预览", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.fromIndex": "来自", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.nameColumn": "字段", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.result.valueColumn": "值", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.resultsPerPage.label": "显示", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.ascLabel": "升序", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.descLabel": "降序", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.directionLabel": "排序依据", + "xpack.enterpriseSearch.searchApplications.searchApplication.searchPreivew.sortingView.fieldLabel": "排序依据", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.confirmButton.title": "是,删除此搜索应用程序", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.delete.description": "删除搜索应用程序是不可逆操作。您的索引不会受到影响。", + "xpack.enterpriseSearch.searchApplications.list.deleteSearchApplicationModal.title": "永久删除此搜索应用程序?", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.deleteSearchApplicationLabel": "删除此搜索应用程序", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.createError.title": "创建搜索应用程序时出错", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.header.docsLink": "搜索应用程序文档", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.headerTitle": "创建搜索应用程序", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.placeholder": "搜索应用程序名称", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.searchApplicationName.title": "命名搜索应用程序", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.selectIndices.title": "选择索引", + "xpack.enterpriseSearch.searchApplications.createSearchApplication.submit": "创建", + "xpack.enterpriseSearch.searchApplications.list.empty.description": "下面我们指导您创建首个搜索应用程序。", + "xpack.enterpriseSearch.searchApplications.list.empty.title": "创建您的首个搜索应用程序", + "xpack.enterpriseSearch.searchApplications.searchApplication.indices.addIndicesFlyout.updateError.title": "更新引擎时出错", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.docsCount.columnTitle": "文档计数", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.health.columnTitle": "索引运行状况", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.table.name.columnTitle": "索引名称", + "xpack.enterpriseSearch.searchApplications.list.indicesFlyout.title": "查看索引", + "xpack.enterpriseSearch.searchApplications.list.table.column.action.delete.buttonDescription": "删除此搜索应用程序", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions": "操作", + "xpack.enterpriseSearch.searchApplications.list.table.column.actions.view.buttonDescription": "查看此搜索应用程序", + "xpack.enterpriseSearch.searchApplications.list.table.column.indices": "索引", + "xpack.enterpriseSearch.searchApplications.list.table.column.lastUpdated": "上次更新时间", + "xpack.enterpriseSearch.searchApplications.list.table.column.name": "搜索应用程序名称", "xpack.enterpriseSearch.content.filteringRules.policy.exclude": "排除", "xpack.enterpriseSearch.content.filteringRules.policy.include": "包括", "xpack.enterpriseSearch.content.filteringRules.rules.contains": "Contains", @@ -13412,18 +13411,18 @@ "xpack.enterpriseSearch.content.overview.generateApiKeyModal.title": "生成 API 密钥", "xpack.enterpriseSearch.content.overview.optimizedRequest.label": "查看 Enterprise Search 优化的请求", "xpack.enterpriseSearch.content.productName": "Enterprise Search", - "xpack.enterpriseSearch.content.searchApplications.connect.pageTitle": "连接", - "xpack.enterpriseSearch.content.searchApplications.content.indicesTabTitle": "索引", - "xpack.enterpriseSearch.content.searchApplications.content.pageTitle": "内容", - "xpack.enterpriseSearch.content.searchApplications.content.schemaTabTitle": "架构", - "xpack.enterpriseSearch.content.searchApplications.createEngineButtonLabel": "创建", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.body": "此功能处于技术预览状态,在未来版本中可能会更改或完全移除。Elastic 将尽最大努力来修复任何问题,但处于技术预览状态的功能不受正式 GA 功能支持 SLA 的约束。", - "xpack.enterpriseSearch.content.searchApplications.createEngineTechnicalPreviewPopover.title": "技术预览", - "xpack.enterpriseSearch.content.searchApplications.documentation": "浏览我们的搜索应用程序文档", - "xpack.enterpriseSearch.content.searchApplications.searchBar.ariaLabel": "搜索应用程序", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder": "搜索应用程序", - "xpack.enterpriseSearch.content.searchApplications.searchPlaceholder.description": "通过名称或根据其包含的索引查找搜索应用程序。", - "xpack.enterpriseSearch.content.searchApplications.title": "搜索应用程序", + "xpack.enterpriseSearch.searchApplications.searchApplication.connect.pageTitle": "连接", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.indicesTabTitle": "索引", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.pageTitle": "内容", + "xpack.enterpriseSearch.searchApplications.searchApplication.content.schemaTabTitle": "架构", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationButton.label": "创建", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.body": "此功能处于技术预览状态,在未来版本中可能会更改或完全移除。Elastic 将尽最大努力来修复任何问题,但处于技术预览状态的功能不受正式 GA 功能支持 SLA 的约束。", + "xpack.enterpriseSearch.searchApplications.list.createSearchApplicationTechnicalPreviewPopover.title": "技术预览", + "xpack.enterpriseSearch.searchApplications.list.documentation": "浏览我们的搜索应用程序文档", + "xpack.enterpriseSearch.searchApplications.list.searchBar.ariaLabel": "搜索应用程序", + "xpack.enterpriseSearch.searchApplications.list.searchBar.placeholder": "搜索应用程序", + "xpack.enterpriseSearch.searchApplications.list.searchBar.description": "通过名称或根据其包含的索引查找搜索应用程序。", + "xpack.enterpriseSearch.searchApplications.list.title": "搜索应用程序", "xpack.enterpriseSearch.content.searchIndex.cancelSyncs.successMessage": "已成功取消同步", "xpack.enterpriseSearch.content.searchIndex.configurationTabLabel": "配置", "xpack.enterpriseSearch.content.searchIndex.connectorErrorCallOut.title": "您的连接器报告了错误", @@ -13901,8 +13900,8 @@ "xpack.enterpriseSearch.nav.contentSettingsTitle": "设置", "xpack.enterpriseSearch.nav.contentTitle": "内容", "xpack.enterpriseSearch.nav.elasticsearchTitle": "Elasticsearch", - "xpack.enterpriseSearch.nav.engine.contentTitle": "内容", - "xpack.enterpriseSearch.nav.engine.previewTitle": "预览", + "xpack.enterpriseSearch.nav.searchApplication.contentTitle": "内容", + "xpack.enterpriseSearch.nav.searchApplication.previewTitle": "预览", "xpack.enterpriseSearch.nav.enterpriseSearchOverviewTitle": "概览", "xpack.enterpriseSearch.nav.searchApplicationsTitle": "搜索应用程序", "xpack.enterpriseSearch.nav.searchExperiencesTitle": "搜索体验", @@ -14072,7 +14071,7 @@ "xpack.enterpriseSearch.schema.errorsTable.link.view": "查看", "xpack.enterpriseSearch.schema.fieldNameLabel": "字段名称", "xpack.enterpriseSearch.schema.fieldTypeLabel": "字段类型", - "xpack.enterpriseSearch.searchApplications.engine.notFound.action1": "返回到搜索应用程序", + "xpack.enterpriseSearch.searchApplications.searchApplication.notFound.action1": "返回到搜索应用程序", "xpack.enterpriseSearch.searchExperiences.guide.description": "搜索 UI 是一个 JavaScript 库,您无需浪费时间进行重复工作便可实现卓越的搜索体验。它开箱即可兼容 Elasticsearch、App Search 和 Workplace Search,以便您专注于为用户、客户和员工构建最佳体验。", "xpack.enterpriseSearch.searchExperiences.guide.documentationLink": "访问搜索 UI 文档", "xpack.enterpriseSearch.searchExperiences.guide.features.1": "用途是进行搜索。Elastic 将构建并维护搜索 UI。", From 590e5c6019e3ec254a4f833f4b0adb3fa215c870 Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Thu, 22 Jun 2023 10:57:50 -0500 Subject: [PATCH 7/7] [ML] Fixes time range in link to data visualizer after file upload (#160189) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/components/results_links/results_links.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx index 791bd9280bdab..7bb835d292e33 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/results_links/results_links.tsx @@ -112,6 +112,7 @@ export const ResultsLinks: FC = ({ getAdditionalLinks.map(async (asyncCardGetter) => { const results = await asyncCardGetter({ dataViewId, + globalState, }); if (Array.isArray(results)) { return await Promise.all(