diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/index_exists_api_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/index_exists_api_logic.ts index 461f055d81ead..8929f390e73ad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/index_exists_api_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/index/index_exists_api_logic.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createApiLogic } from '../../../shared/api_logic/create_api_logic'; +import { Actions, createApiLogic } from '../../../shared/api_logic/create_api_logic'; import { HttpLogic } from '../../../shared/http'; export interface IndexExistsApiParams { @@ -27,3 +27,5 @@ export const fetchIndexExists = async ({ }; export const IndexExistsApiLogic = createApiLogic(['index_exists_api_logic'], fetchIndexExists); + +export type IndexExistsApiLogicActions = Actions; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx index 4a91655f8c501..59d41ec272221 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_box.tsx @@ -38,10 +38,20 @@ export interface AttachIndexBoxProps { } export const AttachIndexBox: React.FC = ({ connector }) => { - const { createIndex, attachIndex, setConnector } = useActions(AttachIndexLogic); - const { isLoading: isSaveLoading } = useValues(AttachIndexLogic); + const { createIndex, attachIndex, setConnector, checkIndexExists } = useActions(AttachIndexLogic); + const { + isLoading: isSaveLoading, + isExistLoading, + canCreateSameNameIndex, + } = useValues(AttachIndexLogic); const [selectedIndex, setSelectedIndex] = useState<{ label: string; shouldCreate?: boolean }>(); const [selectedLanguage] = useState(); + const [showError, setShowError] = useState(false); + useEffect(() => { + if (!canCreateSameNameIndex) { + setShowError(true); + } + }, [canCreateSameNameIndex]); const { makeRequest } = useActions(FetchAllIndicesAPILogic); const { data, status } = useValues(FetchAllIndicesAPILogic); @@ -65,6 +75,9 @@ export const AttachIndexBox: React.FC = ({ connector }) => useEffect(() => { setConnector(connector); makeRequest({}); + if (!connector.index_name) { + checkIndexExists({ indexName: connector.name }); + } }, [connector.id]); return ( @@ -99,10 +112,23 @@ export const AttachIndexBox: React.FC = ({ connector }) => 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexLabel', { defaultMessage: 'Associated index' } )} - helpText={i18n.translate( - 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexHelpTextLabel', - { defaultMessage: 'You can use an existing index or create a new one' } - )} + helpText={ + showError + ? '' + : i18n.translate( + 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexHelpTextLabel', + { defaultMessage: 'You can use an existing index or create a new one' } + ) + } + error={ + showError + ? i18n.translate( + 'xpack.enterpriseSearch.attachIndexBox.euiFormRow.associatedIndexErrorTextLabel', + { defaultMessage: 'You can use another existing index or create a new one' } + ) + : undefined + } + isInvalid={showError} > = ({ connector }) => )} isLoading={isLoading} options={options} - onChange={(selection) => setSelectedIndex(selection[0] || undefined)} + onChange={(selection) => { + if (showError) { + setShowError(false); + } + setSelectedIndex(selection[0] || undefined); + }} selectedOptions={selectedIndex ? [selectedIndex] : undefined} onCreateOption={(value) => { setSelectedIndex({ label: value.trim(), shouldCreate: true }); @@ -130,6 +161,21 @@ export const AttachIndexBox: React.FC = ({ connector }) => + + { + createIndex({ indexName: connector.name, language: null }); + }} + isLoading={isSaveLoading || isExistLoading} + disabled={!canCreateSameNameIndex} + > + {i18n.translate('xpack.enterpriseSearch.attachIndexBox.createSameIndexButtonLabel', { + defaultMessage: 'Create and attach an index with same name', + })} + + onSave()} disabled={!selectedIndex} isLoading={isSaveLoading}> {i18n.translate('xpack.enterpriseSearch.attachIndexBox.saveConfigurationButtonLabel', { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_logic.ts index 42a38b30dbc3e..298fc333490e5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/attach_index_logic.ts @@ -19,11 +19,18 @@ import { CreateApiIndexApiLogic, CreateApiIndexApiLogicActions, } from '../../api/index/create_api_index_api_logic'; +import { + IndexExistsApiLogic, + IndexExistsApiLogicActions, +} from '../../api/index/index_exists_api_logic'; export interface AttachIndexActions { attachIndex: AttachIndexApiLogicActions['makeRequest']; attachIndexApiError: AttachIndexApiLogicActions['apiError']; attachIndexApiSuccess: AttachIndexApiLogicActions['apiSuccess']; + checkIndexExists: IndexExistsApiLogicActions['makeRequest']; + checkIndexExistsApiError: IndexExistsApiLogicActions['apiError']; + checkIndexExistsApiSuccess: IndexExistsApiLogicActions['apiSuccess']; createIndex: CreateApiIndexApiLogicActions['makeRequest']; createIndexApiError: CreateApiIndexApiLogicActions['apiError']; createIndexApiSuccess: CreateApiIndexApiLogicActions['apiSuccess']; @@ -32,8 +39,11 @@ export interface AttachIndexActions { export interface AttachIndexValues { attachApiStatus: Status; + canCreateSameNameIndex: boolean; connector: Connector | null; createIndexApiStatus: Status; + indexExistsApiStatus: Status; + isExistLoading: boolean; isLoading: boolean; } @@ -53,12 +63,20 @@ export const AttachIndexLogic = kea ({ @@ -77,6 +95,12 @@ export const AttachIndexLogic = kea !exists, + }, + ], connector: [ null, { @@ -85,10 +109,17 @@ export const AttachIndexLogic = kea ({ + isExistLoading: [ + () => [selectors.indexExistsApiStatus], + (indexExistsApiStatus: AttachIndexValues['indexExistsApiStatus']) => + Status.LOADING === indexExistsApiStatus, + ], isLoading: [ () => [selectors.attachApiStatus, selectors.createIndexApiStatus], - (attachStatus, createStatus) => - attachStatus === Status.LOADING || createStatus === Status.LOADING, + ( + attachStatus: AttachIndexValues['attachApiStatus'], + createStatus: AttachIndexValues['createIndexApiStatus'] + ) => attachStatus === Status.LOADING || createStatus === Status.LOADING, ], }), }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx index b06459dfb4d02..5cfcb8bf54735 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/native_connector_configuration.tsx @@ -136,12 +136,6 @@ export const NativeConnectorConfiguration: React.FC = () => { )} - {!connector.index_name && ( - <> - - - - )} { ]} /> + {!connector.index_name && ( + <> + + + + )}