[Enterprise Search] Disable content extraction in pipeline settings when applicable (#160012)

## Summary

Disable the `Content extraction` in the pipelines flyout if the
connector has been configured to use local content extraction. This is
only applicable to SharePoint Online in 8.9.
This commit is contained in:
Navarone Feekery 2023-06-20 17:54:57 +02:00 committed by GitHub
parent e4b8f0f0bf
commit ae5ccb9066
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 5 deletions

View file

@ -134,6 +134,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
connectorsAzureBlobStorage: `${ENTERPRISE_SEARCH_DOCS}connectors-azure-blob.html`,
connectorsClients: `${ENTERPRISE_SEARCH_DOCS}connectors.html#connectors-build`,
connectorsConfluence: `${ENTERPRISE_SEARCH_DOCS}connectors-confluence.html`,
connectorsContentExtraction: `${ENTERPRISE_SEARCH_DOCS}connectors-content-extraction.html`,
connectorsGoogleCloudStorage: `${ENTERPRISE_SEARCH_DOCS}connectors-google-cloud.html`,
connectorsJira: `${ENTERPRISE_SEARCH_DOCS}connectors-jira.html`,
connectorsMicrosoftSQL: `${ENTERPRISE_SEARCH_DOCS}connectors-ms-sql.html`,

View file

@ -119,6 +119,7 @@ export interface DocLinks {
readonly connectorsAzureBlobStorage: string;
readonly connectorsClients: string;
readonly connectorsConfluence: string;
readonly connectorsContentExtraction: string;
readonly connectorsGoogleCloudStorage: string;
readonly connectorsJira: string;
readonly connectorsMicrosoftSQL: string;

View file

@ -61,6 +61,7 @@ export type ConnectorConfiguration = Record<
ConnectorConfigProperties | ConnectorConfigCategoryProperties | null
> & {
extract_full_html?: { label: string; value: boolean }; // This only exists for Crawler
use_text_extraction_service?: ConnectorConfigProperties; // This only exists for SharePoint Online
};
export interface ConnectorSyncConfigProperties {

View file

@ -10,6 +10,7 @@ import React from 'react';
import {
EuiButton,
EuiButtonEmpty,
EuiCallOut,
EuiFlexGroup,
EuiFlexItem,
EuiForm,
@ -37,6 +38,7 @@ import { PipelineSettingsForm } from '../pipeline_settings_form';
interface IngestPipelineFlyoutProps {
closeFlyout: () => void;
displayOnly: boolean;
extractionDisabled: boolean;
indexName: string;
ingestionMethod: string;
isLoading: boolean;
@ -48,6 +50,7 @@ interface IngestPipelineFlyoutProps {
export const IngestPipelineFlyout: React.FC<IngestPipelineFlyoutProps> = ({
closeFlyout,
displayOnly,
extractionDisabled,
indexName,
ingestionMethod,
isLoading,
@ -82,6 +85,44 @@ export const IngestPipelineFlyout: React.FC<IngestPipelineFlyoutProps> = ({
</EuiFlyoutHeader>
<EuiFlyoutBody>
<EuiFlexGroup direction="column" gutterSize="none">
<EuiFlexItem>
{extractionDisabled ? (
<EuiCallOut
title={i18n.translate(
'xpack.enterpriseSearch.content.index.pipelines.settings.extractBinaryDisabledWarningTitle',
{
defaultMessage: 'Content extraction cannot be configured',
}
)}
color="warning"
iconType="warning"
>
<p>
{i18n.translate(
'xpack.enterpriseSearch.content.index.pipelines.settings.extractBinaryDisabledWarningContent',
{
defaultMessage:
'Because local content extraction is enabled for this connector, pipeline content extraction settings cannot be used.',
}
)}
</p>
<EuiLink
href={`${docLinks.connectorsContentExtraction}#connectors-content-extraction-local`}
target="_blank"
>
{i18n.translate(
'xpack.enterpriseSearch.content.index.pipelines.ingestFlyout.modalIngestLinkLocalExtractionLabel',
{
defaultMessage: 'Learn more about local content extraction.',
}
)}
</EuiLink>
</EuiCallOut>
) : (
<></>
)}
</EuiFlexItem>
<EuiSpacer size="xl" />
<EuiFlexItem>
<EuiFlexGroup direction="column" gutterSize="none">
<EuiFlexItem>
@ -155,6 +196,7 @@ export const IngestPipelineFlyout: React.FC<IngestPipelineFlyoutProps> = ({
</EuiFormRow>
<EuiFormRow fullWidth>
<PipelineSettingsForm
extractionDisabled={extractionDisabled}
ingestionMethod={ingestionMethod}
pipeline={pipeline}
setPipeline={setPipeline}

View file

@ -44,7 +44,7 @@ describe('IngestPipelinesCard', () => {
setMockValues({ ...DEFAULT_VALUES });
});
it('renders with default ingest pipeline', () => {
const wrapper = shallow(<IngestPipelinesCard />);
const wrapper = shallow(<IngestPipelinesCard extractionDisabled={false} />);
expect(wrapper.find(DefaultPipelineItem)).toHaveLength(1);
expect(wrapper.find(CustomPipelineItem)).toHaveLength(0);
});

View file

@ -20,7 +20,11 @@ import { CustomPipelineItem } from './custom_pipeline_item';
import { DefaultPipelineItem } from './default_pipeline_item';
import { IngestPipelineFlyout } from './ingest_pipeline_flyout';
export const IngestPipelinesCard: React.FC = () => {
interface IngestPipelinesCardProps {
extractionDisabled: boolean;
}
export const IngestPipelinesCard: React.FC<IngestPipelinesCardProps> = ({ extractionDisabled }) => {
const { indexName, ingestionMethod } = useValues(IndexViewLogic);
const { canSetPipeline, index, pipelineName, pipelineState, showPipelineSettings } =
@ -42,6 +46,7 @@ export const IngestPipelinesCard: React.FC = () => {
<IngestPipelineFlyout
closeFlyout={closePipelineSettings}
displayOnly={!canSetPipeline}
extractionDisabled={extractionDisabled}
indexName={indexName}
ingestionMethod={ingestionMethod}
isLoading={false}

View file

@ -14,12 +14,14 @@ import { IngestPipelineParams } from '../../../../../../common/types/connectors'
import { SettingsCheckableCard } from '../../shared/settings_checkable_card/settings_checkable_card';
interface PipelineSettingsFormProps {
extractionDisabled: boolean;
ingestionMethod: string;
pipeline: IngestPipelineParams;
setPipeline: (pipeline: IngestPipelineParams) => void;
}
export const PipelineSettingsForm: React.FC<PipelineSettingsFormProps> = ({
extractionDisabled,
ingestionMethod,
setPipeline,
pipeline,
@ -33,6 +35,7 @@ export const PipelineSettingsForm: React.FC<PipelineSettingsFormProps> = ({
<EuiFlexGroup direction="column" gutterSize="s">
<EuiFlexItem>
<SettingsCheckableCard
disabled={extractionDisabled}
data-telemetry-id={`entSearchContent-${ingestionMethod}-pipelines-ingestPipelines-extractBinaryContent`}
description={i18n.translate(
'xpack.enterpriseSearch.content.index.pipelines.settings.extractBinaryDescription',

View file

@ -30,7 +30,7 @@ import { CANCEL_BUTTON_LABEL } from '../../../../shared/constants';
import { DataPanel } from '../../../../shared/data_panel/data_panel';
import { docLinks } from '../../../../shared/doc_links';
import { RevertConnectorPipelineApilogic } from '../../../api/pipelines/revert_connector_pipeline_api_logic';
import { isApiIndex } from '../../../utils/indices';
import { getContentExtractionDisabled, isApiIndex } from '../../../utils/indices';
import { IndexNameLogic } from '../index_name_logic';
@ -58,6 +58,7 @@ export const SearchIndexPipelines: React.FC = () => {
const { status: revertStatus } = useValues(RevertConnectorPipelineApilogic);
const { makeRequest: revertPipeline } = useActions(RevertConnectorPipelineApilogic);
const apiIndex = isApiIndex(index);
const extractionDisabled = getContentExtractionDisabled(index);
const pipelinesTabs: EuiTabbedContentTab[] = [
{
@ -186,7 +187,7 @@ export const SearchIndexPipelines: React.FC = () => {
)
}
>
<IngestPipelinesCard />
<IngestPipelinesCard extractionDisabled={extractionDisabled} />
</DataPanel>
<EuiSpacer />
<DataPanel

View file

@ -12,16 +12,18 @@ import { EuiCheckableCard, EuiText, EuiTitle } from '@elastic/eui';
export const SettingsCheckableCard: React.FC<{
checked: boolean;
description: string;
disabled?: boolean;
id: string;
label: string;
onChange: React.ChangeEventHandler<HTMLInputElement>;
}> = ({ checked, description, id, label, onChange }) => (
}> = ({ checked, description, disabled, id, label, onChange }) => (
<EuiCheckableCard
label={
<EuiTitle size="xs">
<h4>{label}</h4>
</EuiTitle>
}
disabled={disabled}
checkableType="checkbox"
onChange={onChange}
checked={checked}

View file

@ -108,6 +108,17 @@ export function getLastUpdated(index?: ElasticsearchIndexWithIngestion): string
return isConnectorIndex(index) ? index.connector.last_synced ?? 'never' : null;
}
export function getContentExtractionDisabled(index?: ElasticsearchIndexWithIngestion): boolean {
if (!index) return false;
if (isConnectorIndex(index)) {
const contentExtractionDisabled =
index.connector.configuration?.use_text_extraction_service?.value;
return !!contentExtractionDisabled;
}
return false;
}
export function indexToViewIndex(index: ElasticsearchIndex): ConnectorViewIndex;
export function indexToViewIndex(index: ElasticsearchIndex): CrawlerViewIndex;
export function indexToViewIndex(index: ElasticsearchIndex): ApiViewIndex {

View file

@ -65,6 +65,7 @@ class DocLinks {
public connectorsAzureBlobStorage: string;
public connectorsClients: string;
public connectorsConfluence: string;
public connectorsContentExtraction: string;
public connectorsGoogleCloudStorage: string;
public connectorsJira: string;
public connectorsMicrosoftSQL: string;
@ -204,6 +205,7 @@ class DocLinks {
this.connectors = '';
this.connectorsAzureBlobStorage = '';
this.connectorsConfluence = '';
this.connectorsContentExtraction = '';
this.connectorsClients = '';
this.connectorsGoogleCloudStorage = '';
this.connectorsJira = '';
@ -345,6 +347,7 @@ class DocLinks {
this.connectors = docLinks.links.enterpriseSearch.connectors;
this.connectorsAzureBlobStorage = docLinks.links.enterpriseSearch.connectorsAzureBlobStorage;
this.connectorsConfluence = docLinks.links.enterpriseSearch.connectorsConfluence;
this.connectorsContentExtraction = docLinks.links.enterpriseSearch.connectorsContentExtraction;
this.connectorsClients = docLinks.links.enterpriseSearch.connectorsClients;
this.connectorsGoogleCloudStorage =
docLinks.links.enterpriseSearch.connectorsGoogleCloudStorage;