[Ingest Pipelines] Preserve unknown fields in processors (#91146)

* keep known and unknown options in processor config

* added test for preserving unknown fields

* refactor form for NOT stripping empty field values, also allow empty "value" for set and gsub

* remove unused i18n

* fix user agent form serialization, update field help text

* remove out of date translation

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Jean-Louis Leysens 2021-02-17 12:57:23 +01:00 committed by GitHub
parent 26f088970e
commit edc11d9680
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 154 additions and 73 deletions

View file

@ -154,6 +154,17 @@ const createActions = (testBed: TestBed<TestSubject>) => {
find(`${processorSelector}.moreMenu.duplicateButton`).simulate('click');
});
},
openProcessorEditor: (processorSelector: string) => {
act(() => {
find(`${processorSelector}.manageItemButton`).simulate('click');
});
component.update();
},
submitProcessorForm: async () => {
await act(async () => {
find('editProcessorForm.submitButton').simulate('click');
});
},
};
};

View file

@ -22,6 +22,13 @@ const testProcessors: Pick<Pipeline, 'processors'> = {
replacement: '$17$2',
},
},
{
set: {
field: 'test',
value: 'test',
unknown_field_foo: 'unknown_value',
},
},
],
};
@ -79,11 +86,37 @@ describe('Pipeline Editor', () => {
await actions.addProcessor('processors', 'test', { if: '1 == 1' });
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors.length).toBe(3);
const [a, b, c] = processors;
expect(processors.length).toBe(4);
const [a, b, c, d] = processors;
expect(a).toEqual(testProcessors.processors[0]);
expect(b).toEqual(testProcessors.processors[1]);
expect(c).toEqual({ test: { if: '1 == 1' } });
expect(c).toEqual(testProcessors.processors[2]);
expect(d).toEqual({ test: { if: '1 == 1' } });
});
it('edits a processor without removing unknown processor.options', async () => {
const { actions, exists, form } = testBed;
// Open the edit processor form for the set processor
actions.openProcessorEditor('processors>2');
expect(exists('editProcessorForm')).toBeTruthy();
form.setInputValue('editProcessorForm.valueFieldInput', 'test44');
await actions.submitProcessorForm();
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const {
processors: { 2: setProcessor },
} = onUpdateResult.getData();
// The original field should still be unchanged
expect(testProcessors.processors[2].set.value).toBe('test');
expect(setProcessor.set).toEqual({
description: undefined,
field: 'test',
ignore_empty_value: undefined,
ignore_failure: undefined,
override: undefined,
// This unknown_field is not supported in the form
unknown_field_foo: 'unknown_value',
value: 'test44',
});
});
it('removes a processor', () => {
@ -92,7 +125,7 @@ describe('Pipeline Editor', () => {
actions.removeProcessor('processors>0');
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors.length).toBe(1);
expect(processors.length).toBe(2);
expect(processors[0]).toEqual({
gsub: {
field: '_index',
@ -107,7 +140,11 @@ describe('Pipeline Editor', () => {
actions.moveProcessor('processors>0', 'dropButtonBelow-processors>1');
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors).toEqual(testProcessors.processors.slice(0).reverse());
expect(processors).toEqual([
testProcessors.processors[1],
testProcessors.processors[0],
testProcessors.processors[2],
]);
});
it('adds an on-failure processor to a processor', async () => {
@ -121,7 +158,7 @@ describe('Pipeline Editor', () => {
expect(exists(`${processorSelector}.addProcessor`));
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors.length).toBe(2);
expect(processors.length).toBe(3);
expect(processors[0]).toEqual(testProcessors.processors[0]); // should be unchanged
expect(processors[1].gsub).toEqual({
...testProcessors.processors[1].gsub,
@ -135,7 +172,7 @@ describe('Pipeline Editor', () => {
actions.moveProcessor('processors>0', 'dropButtonBelow-processors>1>onFailure>0');
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors.length).toBe(1);
expect(processors.length).toBe(2);
expect(processors[0].gsub.on_failure).toEqual([
{
test: { if: '1 == 3' },
@ -150,7 +187,7 @@ describe('Pipeline Editor', () => {
actions.duplicateProcessor('processors>1');
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const { processors } = onUpdateResult.getData();
expect(processors.length).toBe(3);
expect(processors.length).toBe(4);
const duplicatedProcessor = {
gsub: {
...testProcessors.processors[1].gsub,
@ -161,6 +198,7 @@ describe('Pipeline Editor', () => {
testProcessors.processors[0],
duplicatedProcessor,
duplicatedProcessor,
testProcessors.processors[2],
]);
});
@ -182,14 +220,17 @@ describe('Pipeline Editor', () => {
actions.moveProcessor('processors>0', 'dropButtonBelow-onFailure>0');
const [onUpdateResult1] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const data1 = onUpdateResult1.getData();
expect(data1.processors.length).toBe(1);
expect(data1.processors.length).toBe(2);
expect(data1.on_failure.length).toBe(2);
expect(data1.processors).toEqual([testProcessors.processors[1]]);
expect(data1.processors).toEqual([
testProcessors.processors[1],
testProcessors.processors[2],
]);
expect(data1.on_failure).toEqual([{ test: { if: '1 == 5' } }, testProcessors.processors[0]]);
actions.moveProcessor('onFailure>1', 'dropButtonAbove-processors>0');
const [onUpdateResult2] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const data2 = onUpdateResult2.getData();
expect(data2.processors.length).toBe(2);
expect(data2.processors.length).toBe(3);
expect(data2.on_failure.length).toBe(1);
expect(data2.processors).toEqual(testProcessors.processors);
expect(data2.on_failure).toEqual([{ test: { if: '1 == 5' } }]);
@ -208,7 +249,7 @@ describe('Pipeline Editor', () => {
actions.moveProcessor('processors>0', 'onFailure.dropButtonEmptyTree');
const [onUpdateResult2] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
const data = onUpdateResult2.getData();
expect(data.processors).toEqual([testProcessors.processors[1]]);
expect(data.processors).toEqual([testProcessors.processors[1], testProcessors.processors[2]]);
expect(data.on_failure).toEqual([testProcessors.processors[0]]);
});
});

View file

@ -7,7 +7,13 @@
import React, { FunctionComponent, useCallback, useEffect, useRef } from 'react';
import { useForm, OnFormUpdateArg, FormData, useKibana } from '../../../../../shared_imports';
import {
useForm,
OnFormUpdateArg,
FormData,
FormOptions,
useKibana,
} from '../../../../../shared_imports';
import { ProcessorInternal } from '../../types';
import { EditProcessorForm } from './edit_processor_form';
@ -33,6 +39,14 @@ interface Props {
processor?: ProcessorInternal;
}
const formOptions: FormOptions = {
/**
* This is important for allowing configuration of empty text fields in certain processors that
* remove values from their inputs.
*/
stripEmptyFields: false,
};
export const ProcessorFormContainer: FunctionComponent<Props> = ({
processor,
onFormUpdate,
@ -81,6 +95,7 @@ export const ProcessorFormContainer: FunctionComponent<Props> = ({
const { form } = useForm({
defaultValue: { fields: getProcessor().options },
serializer: formSerializer,
options: formOptions,
});
const { subscribe } = form;

View file

@ -38,6 +38,7 @@ const ignoreFailureConfig: FieldConfig<any> = {
};
const ifConfig: FieldConfig = {
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.ifFieldLabel', {
defaultMessage: 'Condition (optional)',
}),
@ -48,6 +49,7 @@ const ifConfig: FieldConfig = {
};
const tagConfig: FieldConfig = {
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.tagFieldLabel', {
defaultMessage: 'Tag (optional)',
}),

View file

@ -10,12 +10,13 @@ import { i18n } from '@kbn/i18n';
import { Field, FIELD_TYPES, UseField, FieldConfig } from '../../../../../../../shared_imports';
import { FieldsConfig } from '../shared';
import { FieldsConfig, from } from '../shared';
const fieldsConfig: FieldsConfig = {
target_field: {
type: FIELD_TYPES.TEXT,
deserializer: String,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.commonFields.targetFieldLabel', {
defaultMessage: 'Target field (optional)',
}),

View file

@ -24,7 +24,7 @@ import { FieldsConfig } from './shared';
import { IgnoreMissingField } from './common_fields/ignore_missing_field';
import { FieldNameField } from './common_fields/field_name_field';
import { to } from './shared';
import { to, from } from './shared';
const { minLengthField } = fieldValidators;
@ -72,7 +72,7 @@ const fieldsConfig: FieldsConfig = {
/* Optional fields config */
separator: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.separatorFieldLabel', {
defaultMessage: 'Separator (optional)',
}),
@ -91,7 +91,7 @@ const fieldsConfig: FieldsConfig = {
},
quote: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.quoteFieldLabel', {
defaultMessage: 'Quote (optional)',
}),
@ -121,6 +121,7 @@ const fieldsConfig: FieldsConfig = {
},
empty_value: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.convertForm.emptyValueFieldLabel', {
defaultMessage: 'Empty value (optional)',
}),

View file

@ -18,7 +18,7 @@ import {
ComboBoxField,
} from '../../../../../../shared_imports';
import { FieldsConfig, to } from './shared';
import { FieldsConfig, to, from } from './shared';
import { FieldNameField } from './common_fields/field_name_field';
import { TargetField } from './common_fields/target_field';
@ -53,7 +53,7 @@ const fieldsConfig: FieldsConfig = {
/* Optional fields config */
timezone: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.timezoneFieldLabel', {
defaultMessage: 'Timezone (optional)',
}),
@ -67,7 +67,7 @@ const fieldsConfig: FieldsConfig = {
},
locale: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dateForm.localeFieldLabel', {
defaultMessage: 'Locale (optional)',
}),

View file

@ -19,7 +19,7 @@ import {
SelectField,
} from '../../../../../../shared_imports';
import { FieldsConfig, to } from './shared';
import { FieldsConfig, to, from } from './shared';
import { FieldNameField } from './common_fields/field_name_field';
const { emptyField } = fieldValidators;
@ -57,7 +57,7 @@ const fieldsConfig: FieldsConfig = {
/* Optional fields config */
index_name_prefix: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.indexNamePrefixFieldLabel',
{
@ -71,7 +71,7 @@ const fieldsConfig: FieldsConfig = {
},
index_name_format: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.indexNameFormatFieldLabel',
{
@ -108,7 +108,7 @@ const fieldsConfig: FieldsConfig = {
},
timezone: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.timezoneFieldLabel',
{
@ -125,7 +125,7 @@ const fieldsConfig: FieldsConfig = {
},
locale: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v ? v : undefined),
serializer: from.emptyStringToUndefined,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.dateIndexNameForm.localeFieldLabel',
{

View file

@ -22,7 +22,7 @@ import {
import { FieldNameField } from './common_fields/field_name_field';
import { IgnoreMissingField } from './common_fields/ignore_missing_field';
import { EDITOR_PX_HEIGHT } from './shared';
import { EDITOR_PX_HEIGHT, from } from './shared';
const { emptyField } = fieldValidators;
@ -72,6 +72,7 @@ const getFieldsConfig = (esDocUrl: string): Record<string, FieldConfig> => {
/* Optional field config */
append_separator: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.dissectForm.appendSeparatorparaotrFieldLabel',
{

View file

@ -12,9 +12,12 @@ import { FieldConfig, FIELD_TYPES, UseField, Field } from '../../../../../../sha
import { FieldNameField } from './common_fields/field_name_field';
import { from } from './shared';
const fieldsConfig: Record<string, FieldConfig> = {
path: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.dotExpanderForm.pathFieldLabel', {
defaultMessage: 'Path',
}),

View file

@ -22,7 +22,7 @@ const fieldsConfig: FieldsConfig = {
/* Optional field config */
database_file: {
type: FIELD_TYPES.TEXT,
serializer: (v) => (v === 'GeoLite2-City.mmdb' ? undefined : v),
serializer: (v) => (v === 'GeoLite2-City.mmdb' || v === '' ? undefined : v),
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.geoIPForm.databaseFileLabel', {
defaultMessage: 'Database file (optional)',
}),

View file

@ -41,6 +41,7 @@ const fieldsConfig: FieldsConfig = {
],
},
// This is a required field, but we exclude validation because we accept empty values as ''
replacement: {
type: FIELD_TYPES.TEXT,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel', {
@ -48,17 +49,11 @@ const fieldsConfig: FieldsConfig = {
}),
helpText: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldHelpText',
{ defaultMessage: 'Replacement text for matches.' }
),
validations: [
{
validator: emptyField(
i18n.translate('xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError', {
defaultMessage: 'A value is required.',
})
),
},
],
defaultMessage:
'Replacement text for matches. A blank value will remove the matched text from the resulting text.',
}
),
},
};

View file

@ -107,6 +107,7 @@ const fieldsConfig: FieldsConfig = {
prefix: {
type: FIELD_TYPES.TEXT,
deserializer: String,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.prefixFieldLabel', {
defaultMessage: 'Prefix',
}),
@ -118,6 +119,7 @@ const fieldsConfig: FieldsConfig = {
trim_key: {
type: FIELD_TYPES.TEXT,
deserializer: String,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.trimKeyFieldLabel', {
defaultMessage: 'Trim key',
}),
@ -129,6 +131,7 @@ const fieldsConfig: FieldsConfig = {
trim_value: {
type: FIELD_TYPES.TEXT,
deserializer: String,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.kvForm.trimValueFieldLabel', {
defaultMessage: 'Trim value',
}),

View file

@ -81,7 +81,7 @@ const fieldsConfig: FieldsConfig = {
lang: {
type: FIELD_TYPES.TEXT,
deserializer: String,
serializer: from.undefinedIfValue('painless'),
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.scriptForm.langFieldLabel', {
defaultMessage: 'Language (optional)',
}),

View file

@ -10,40 +10,30 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiCode } from '@elastic/eui';
import {
FIELD_TYPES,
fieldValidators,
ToggleField,
UseField,
Field,
} from '../../../../../../shared_imports';
import { FIELD_TYPES, ToggleField, UseField, Field } from '../../../../../../shared_imports';
import { FieldsConfig, to, from } from './shared';
import { FieldNameField } from './common_fields/field_name_field';
const { emptyField } = fieldValidators;
const fieldsConfig: FieldsConfig = {
/* Required fields config */
// This is a required field, but we exclude validation because we accept empty values as ''
value: {
type: FIELD_TYPES.TEXT,
deserializer: String,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel', {
defaultMessage: 'Value',
}),
helpText: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText', {
defaultMessage: 'Value for the field.',
}),
validations: [
{
validator: emptyField(
i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError', {
defaultMessage: 'A value is required.',
})
),
},
],
helpText: (
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText"
defaultMessage="Value for the field. A blank value will set {emptyString}."
values={{
emptyString: <EuiCode>{'""'}</EuiCode>,
}}
/>
),
},
/* Optional fields config */
override: {
@ -101,7 +91,16 @@ export const SetProcessor: FunctionComponent = () => {
})}
/>
<UseField config={fieldsConfig.value} component={Field} path="fields.value" />
<UseField
config={fieldsConfig.value}
component={Field}
componentProps={{
euiFieldProps: {
'data-test-subj': 'valueFieldInput',
},
}}
path="fields.value"
/>
<UseField config={fieldsConfig.override} component={ToggleField} path="fields.override" />

View file

@ -64,9 +64,11 @@ export const from = {
// Ignore
}
}
return undefined;
},
optionalArrayOfStrings: (v: string[]) => (v.length ? v : undefined),
undefinedIfValue: (value: any) => (v: boolean) => (v === value ? undefined : v),
undefinedIfValue: (value: unknown) => (v: boolean) => (v === value ? undefined : v),
emptyStringToUndefined: (v: unknown) => (v === '' ? undefined : v),
};
export const EDITOR_PX_HEIGHT = {
@ -78,4 +80,6 @@ export const EDITOR_PX_HEIGHT = {
export type FieldsConfig = Record<string, FieldConfig<any>>;
export type FormFieldsComponent = FunctionComponent<{ initialFieldValues?: Record<string, any> }>;
export type FormFieldsComponent = FunctionComponent<{
initialFieldValues?: Record<string, any>;
}>;

View file

@ -12,7 +12,7 @@ import { FIELD_TYPES, UseField, SelectField } from '../../../../../../shared_imp
import { FieldNameField } from './common_fields/field_name_field';
import { TargetField } from './common_fields/target_field';
import { FieldsConfig, from } from './shared';
import { FieldsConfig } from './shared';
const fieldsConfig: FieldsConfig = {
/* Optional fields config */
@ -20,7 +20,7 @@ const fieldsConfig: FieldsConfig = {
type: FIELD_TYPES.SELECT,
defaultValue: 'asc',
deserializer: (v) => (v === 'asc' || v === 'desc' ? v : 'asc'),
serializer: from.undefinedIfValue('asc'),
serializer: (v) => (v === 'asc' || v === '' ? undefined : v),
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.sortForm.orderFieldLabel', {
defaultMessage: 'Order',
}),

View file

@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n';
import { EuiComboBoxOptionOption } from '@elastic/eui';
import { FIELD_TYPES, UseField, Field } from '../../../../../../shared_imports';
import { FieldsConfig } from './shared';
import { FieldsConfig, from } from './shared';
import { IgnoreMissingField } from './common_fields/ignore_missing_field';
import { FieldNameField } from './common_fields/field_name_field';
import { TargetField } from './common_fields/target_field';
@ -31,6 +31,7 @@ const fieldsConfig: FieldsConfig = {
/* Optional fields config */
regex_file: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
deserializer: String,
label: i18n.translate(
'xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldLabel',

View file

@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { omit } from 'lodash';
import React, {
createContext,
FunctionComponent,
@ -150,12 +150,21 @@ export const PipelineProcessorsContextProvider: FunctionComponent<Props> = ({
});
break;
case 'managingProcessor':
// These are the option names we get back from our UI
const knownOptionNames = Object.keys(processorTypeAndOptions.options);
// The processor that we are updating may have options configured the UI does not know about
const unknownOptions = omit(mode.arg.processor.options, knownOptionNames);
// In order to keep the options we don't get back from our UI, we merge the known and unknown options
const updatedProcessorOptions = {
...processorTypeAndOptions.options,
...unknownOptions,
};
processorsDispatch({
type: 'updateProcessor',
payload: {
processor: {
...mode.arg.processor,
...processorTypeAndOptions,
options: updatedProcessorOptions,
},
selector: mode.arg.selector,
},

View file

@ -51,6 +51,7 @@ export {
ValidationFunc,
ValidationConfig,
useFormData,
FormOptions,
} from '../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib';
export {

View file

@ -10832,7 +10832,6 @@
"xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "値が必要です。",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldHelpText": "一致の置換テキスト。",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "置換",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "値が必要です。",
"xpack.ingestPipelines.pipelineEditor.htmlStripForm.fieldNameHelpText": "HTMLタグを削除するフィールド。",
"xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapHelpText": "ドキュメントフィールド名をモデルの既知のフィールド名にマッピングします。モデルのどのマッピングよりも優先されます。",
"xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapInvalidJSONError": "無効なJSON",
@ -10930,9 +10929,7 @@
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldHelpText": "有効にすると、既存のフィールド値を上書きします。無効にすると、{nullValue}フィールドのみを更新します。",
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "無効化",
"xpack.ingestPipelines.pipelineEditor.setForm.propertiesFieldHelpText": "追加するユーザー詳細情報。フォルトは{value}です。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText": "フィールドの値。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "値",
"xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "値が必要です。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.fieldNameField": "出力フィールド。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.propertiesFieldLabel": "プロパティ(任意)",
"xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}ドキュメント",

View file

@ -10860,7 +10860,6 @@
"xpack.ingestPipelines.pipelineEditor.gsubForm.patternRequiredError": "需要值。",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldHelpText": "匹配项的替换文本。",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementFieldLabel": "替换",
"xpack.ingestPipelines.pipelineEditor.gsubForm.replacementRequiredError": "需要值。",
"xpack.ingestPipelines.pipelineEditor.htmlStripForm.fieldNameHelpText": "从其中移除 HTML 标记的字段。",
"xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapHelpText": "将文档字段名称映射到模型的已知字段名称。优先于模型中的任何映射。",
"xpack.ingestPipelines.pipelineEditor.inferenceForm.fieldMapInvalidJSONError": "JSON 无效",
@ -10958,9 +10957,7 @@
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldHelpText": "如果启用,则覆盖现有字段值。如果禁用,则仅更新 {nullValue} 字段。",
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "覆盖",
"xpack.ingestPipelines.pipelineEditor.setForm.propertiesFieldHelpText": "要添加的用户详情。默认为 {value}",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText": "字段的值。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "值",
"xpack.ingestPipelines.pipelineEditor.setForm.valueRequiredError": "需要值。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.fieldNameField": "输出字段。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.propertiesFieldLabel": "属性(可选)",
"xpack.ingestPipelines.pipelineEditor.settingsForm.learnMoreLabelLink.processor": "{processorLabel}文档",