Skip to content

Commit

Permalink
debug a pipeline with an index document
Browse files Browse the repository at this point in the history
  • Loading branch information
alisonelizabeth committed Sep 21, 2020
1 parent f64aa5b commit 3936e3b
Show file tree
Hide file tree
Showing 10 changed files with 438 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,11 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
} else {
// default to "Documents" tab
tabContent = (
<Form
<DocumentsTab
form={form}
data-test-subj="testPipelineForm"
isInvalid={form.isSubmitted && !form.isValid}
onSubmit={validateAndTestPipeline}
error={form.getErrors()}
>
<DocumentsTab
validateAndTestPipeline={validateAndTestPipeline}
isRunningTest={isRunningTest}
isSubmitButtonDisabled={form.isSubmitted && !form.isValid}
/>
</Form>
validateAndTestPipeline={validateAndTestPipeline}
isRunningTest={isRunningTest}
/>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ export const documentsSchema: FormSchema = {
}
},
},
{
validator: ({ value }: ValidationFuncArg<any, any>) => {
const parsedJSON = JSON.parse(value);

const isMissingSourceField = parsedJSON.find((obj: { _source?: object }) => {
if (!obj._source) {
return true;
}

return false;
});

if (isMissingSourceField) {
return {
message: i18n.translate(
'xpack.ingestPipelines.testPipelineFlyout.documentsForm.sourceFieldRequiredError',
{
defaultMessage: 'Documents require a _source field.',
}
),
};
}
},
},
],
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { useState, FunctionComponent } from 'react';
import { i18n } from '@kbn/i18n';
import {
EuiFormRow,
EuiButton,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiCallOut,
EuiSpacer,
} from '@elastic/eui';

import {
getUseField,
Field,
useKibana,
useForm,
Form,
TextField,
fieldValidators,
FieldConfig,
} from '../../../../../../shared_imports';

const UseField = getUseField({ component: Field });

const { emptyField } = fieldValidators;

const i18nTexts = {
importDocumentButton: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.loadDocuments.importDocButtonLabel',
{
defaultMessage: 'Import',
}
),
importDocumentErrorMessage: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.loadDocuments.importDocErrorMessage',
{
defaultMessage: 'Error importing document',
}
),
indexField: {
fieldLabel: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.loadDocuments.table.indexColumnLabel',
{
defaultMessage: 'Index',
}
),
validationMessage: i18n.translate(
'ingestPipelines.pipelineEditor.loadDocuments.indexRequiredError',
{
defaultMessage: 'An index name is required.',
}
),
},
idField: {
fieldLabel: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.loadDocuments.table.documentIdColumnLabel',
{
defaultMessage: 'Document ID',
}
),
validationMessage: i18n.translate(
'ingestPipelines.pipelineEditor.loadDocuments.idRequiredError',
{
defaultMessage: 'A document ID is required.',
}
),
},
};

const fieldsConfig: Record<string, FieldConfig> = {
index: {
label: i18nTexts.indexField.fieldLabel,
validations: [
{
validator: emptyField(i18nTexts.indexField.validationMessage),
},
],
},
id: {
label: i18nTexts.idField.fieldLabel,
validations: [
{
validator: emptyField(i18nTexts.idField.validationMessage),
},
],
},
};

interface Props {
onAddDocuments: (document: any) => void;
}

export const ImportDocumentForm: FunctionComponent<Props> = ({ onAddDocuments }) => {
const { services } = useKibana();

const [isLoadingDocument, setIsLoadingDocument] = useState<boolean>(false);
const [loadingDocumentError, setLoadingDocumentError] = useState<Error | undefined>(undefined);

const { form } = useForm({ defaultValue: { index: '', id: '' } });

const submitForm = async (e: React.FormEvent) => {
// e.preventDefault();

const { isValid, data } = await form.submit();

const { id, index } = data;

if (isValid) {
setIsLoadingDocument(true);

const { error, data: document } = await services.api.loadDocument(index, id);

setIsLoadingDocument(false);

if (error) {
setLoadingDocumentError(error);
return;
}

onAddDocuments(document);
form.reset();
}
};

return (
<Form form={form} onSubmit={submitForm}>
{loadingDocumentError && (
<>
<EuiCallOut
title={i18nTexts.importDocumentErrorMessage}
color="danger"
iconType="alert"
data-test-subj="pipelineExecutionError"
>
<p>{loadingDocumentError.message}</p>
</EuiCallOut>

<EuiSpacer size="m" />
</>
)}

<EuiPanel paddingSize="m">
<EuiFlexGroup>
<EuiFlexItem>
<UseField path="index" component={TextField} config={fieldsConfig.index} />
</EuiFlexItem>

<EuiFlexItem>
<UseField path="id" component={TextField} config={fieldsConfig.id} />
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiFormRow hasEmptyLabelSpace>
<EuiButton
onClick={submitForm}
data-test-subj="addDocumentButton"
isLoading={isLoadingDocument}
>
{i18nTexts.importDocumentButton}
</EuiButton>
</EuiFormRow>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
</Form>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React, { FunctionComponent } from 'react';
import { i18n } from '@kbn/i18n';

import { EuiAccordion, EuiText, EuiSpacer } from '@elastic/eui';

import { ImportDocumentForm } from './import_document_form';

const i18nTexts = {
addDocumentsButton: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.importDocumentsAccordion.importButtonLabel',
{
defaultMessage: 'Import existing documents',
}
),
// TODO add link to Discover
contentDescription: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.importDocumentsAccordion.contentDescriptionText',
{
defaultMessage:
'Provide the index name and document ID of the indexed document to test. To explore your existing data, use Discover.',
}
),
};

interface Props {
onAddDocuments: (document: any) => void;
}

export const ImportDocumentsAccordion: FunctionComponent<Props> = ({ onAddDocuments }) => {
return (
<EuiAccordion
id="addDocumentsAccordion"
buttonContent={i18nTexts.addDocumentsButton}
paddingSize="s"
data-test-subj="importDocumentsAccordion"
>
<>
<EuiText size="s" color="subdued">
<p>{i18nTexts.contentDescription}</p>
</EuiText>

<EuiSpacer size="m" />

<ImportDocumentForm onAddDocuments={onAddDocuments} />
</>
</EuiAccordion>
);
};
Loading

0 comments on commit 3936e3b

Please sign in to comment.