[Ingest pipelines] Add copy_from to set processor (#104070)

* fix up validation conditions for fields

* add tests and fix prettier errors

* Small refactor and fix tests

* Fix copy surrounding error handling

* Clean up unnecessary boilerplate from tests

* Fix i18n error

* Keep optional select next to bound input

* Pass disabled prop as boolean

* fix test matchers

* No need to whitelist fields anymore

* Small CR changes

* Convert optional inputs to toggle state

* Fix testcase copy

* address CR suggestions

* address CR changes

* Fix i18n

* Fix labelAppend link alignment
This commit is contained in:
Ignacio Rivas 2021-07-27 18:28:30 +03:00 committed by GitHub
parent 5dd68dd7b3
commit 374de9dbc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 121 deletions

View file

@ -172,8 +172,6 @@ type TestSubject =
| 'valueFieldInput'
| 'mediaTypeSelectorField'
| 'networkDirectionField.input'
| 'sourceIpField.input'
| 'destinationIpField.input'
| 'toggleCustomField'
| 'ignoreEmptyField.input'
| 'overrideField.input'
@ -189,4 +187,5 @@ type TestSubject =
| 'ianaField.input'
| 'transportField.input'
| 'seedField.input'
| 'copyFromInput'
| 'trimSwitch.input';

View file

@ -8,19 +8,6 @@
import { act } from 'react-dom/test-utils';
import { setup, SetupResult, getProcessorValue } from './processor.helpers';
// Default parameter values automatically added to the set processor when saved
const defaultSetParameters = {
value: '',
if: undefined,
tag: undefined,
override: undefined,
media_type: undefined,
description: undefined,
ignore_missing: undefined,
ignore_failure: undefined,
ignore_empty_value: undefined,
};
const SET_TYPE = 'set';
describe('Processor: Set', () => {
@ -66,7 +53,10 @@ describe('Processor: Set', () => {
await saveNewProcessor();
// Expect form error as "field" is required parameter
expect(form.getErrorsMessages()).toEqual(['A field value is required.']);
expect(form.getErrorsMessages()).toEqual([
'A field value is required.',
'A value is required.',
]);
});
test('saves with default parameter value', async () => {
@ -75,15 +65,43 @@ describe('Processor: Set', () => {
form,
} = testBed;
// Add "field" value (required)
// Add required fields
form.setInputValue('valueFieldInput', 'value');
form.setInputValue('fieldNameField.input', 'field_1');
// Save the field
await saveNewProcessor();
const processors = getProcessorValue(onUpdate, SET_TYPE);
expect(processors[0][SET_TYPE]).toEqual({
...defaultSetParameters,
field: 'field_1',
value: 'value',
});
});
test('allows to save the the copy_from value', async () => {
const {
actions: { saveNewProcessor },
form,
find,
} = testBed;
// Add required fields
form.setInputValue('fieldNameField.input', 'field_1');
// Set value field
form.setInputValue('valueFieldInput', 'value');
// Toggle to copy_from field and set a random value
find('toggleCustomField').simulate('click');
form.setInputValue('copyFromInput', 'copy_from');
// Save the field with new changes
await saveNewProcessor();
const processors = getProcessorValue(onUpdate, SET_TYPE);
expect(processors[0][SET_TYPE]).toEqual({
field: 'field_1',
copy_from: 'copy_from',
});
});
@ -110,7 +128,6 @@ describe('Processor: Set', () => {
const processors = getProcessorValue(onUpdate, SET_TYPE);
expect(processors[0][SET_TYPE]).toEqual({
...defaultSetParameters,
field: 'field_1',
value: '{{{hello}}}',
media_type: 'text/plain',
@ -136,7 +153,6 @@ describe('Processor: Set', () => {
const processors = getProcessorValue(onUpdate, SET_TYPE);
expect(processors[0][SET_TYPE]).toEqual({
...defaultSetParameters,
field: 'field_1',
value: '{{{hello}}}',
ignore_empty_value: true,

View file

@ -9,7 +9,7 @@ import React, { FunctionComponent, useState, useCallback, useMemo } from 'react'
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButtonEmpty, EuiCode } from '@elastic/eui';
import { EuiCode, EuiLink, EuiText } from '@elastic/eui';
import {
FIELD_TYPES,
@ -131,11 +131,14 @@ const getInternalNetworkConfig: (
),
},
labelAppend: (
<EuiButtonEmpty size="xs" onClick={toggleCustom} data-test-subj="toggleCustomField">
{i18n.translate('xpack.ingestPipelines.pipelineEditor.internalNetworkCustomLabel', {
defaultMessage: 'Use custom field',
})}
</EuiButtonEmpty>
<EuiText size="xs">
<EuiLink onClick={toggleCustom} data-test-subj="toggleCustomField">
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.internalNetworkCustomLabel"
defaultMessage="Use custom field"
/>
</EuiLink>
</EuiText>
),
key: 'preset',
},
@ -171,11 +174,14 @@ const getInternalNetworkConfig: (
),
},
labelAppend: (
<EuiButtonEmpty size="xs" onClick={toggleCustom} data-test-subj="toggleCustomField">
{i18n.translate('xpack.ingestPipelines.pipelineEditor.internalNetworkPredefinedLabel', {
defaultMessage: 'Use preset field',
})}
</EuiButtonEmpty>
<EuiText size="xs">
<EuiLink onClick={toggleCustom} data-test-subj="toggleCustomField">
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.internalNetworkPredefinedLabel"
defaultMessage="Use preset field"
/>
</EuiLink>
</EuiText>
),
key: 'custom',
},

View file

@ -5,10 +5,11 @@
* 2.0.
*/
import React, { FunctionComponent } from 'react';
import React, { FunctionComponent, useState, useCallback, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import { isEmpty } from 'lodash';
import { EuiCode, EuiLink, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiCode } from '@elastic/eui';
import {
FIELD_TYPES,
@ -17,6 +18,9 @@ import {
ToggleField,
UseField,
Field,
FieldHook,
FieldConfig,
useFormContext,
} from '../../../../../../shared_imports';
import { hasTemplateSnippet } from '../../../utils';
@ -24,25 +28,17 @@ import { FieldsConfig, to, from } from './shared';
import { FieldNameField } from './common_fields/field_name_field';
interface ValueToggleTypes {
value: string;
copy_from: string;
}
type ValueToggleFields = {
[K in keyof ValueToggleTypes]: FieldHook<ValueToggleTypes[K]>;
};
// Optional fields config
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: (
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText"
defaultMessage="Value for the field. A blank value will set {emptyString}."
values={{
emptyString: <EuiCode>{'""'}</EuiCode>,
}}
/>
),
},
mediaType: {
type: FIELD_TYPES.SELECT,
defaultValue: 'application/json',
@ -57,7 +53,6 @@ const fieldsConfig: FieldsConfig = {
/>
),
},
/* Optional fields config */
override: {
type: FIELD_TYPES.TOGGLE,
defaultValue: true,
@ -101,11 +96,134 @@ const fieldsConfig: FieldsConfig = {
},
};
// Required fields config
const getValueConfig: (
toggleCustom: () => void
) => Record<
keyof ValueToggleFields,
{
path: string;
config?: FieldConfig<any>;
euiFieldProps?: Record<string, any>;
labelAppend: JSX.Element;
}
> = (toggleCustom: () => void) => ({
value: {
path: 'fields.value',
euiFieldProps: {
'data-test-subj': 'valueFieldInput',
},
config: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel', {
defaultMessage: 'Value',
}),
helpText: (
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText"
defaultMessage="Value for the field."
/>
),
fieldsToValidateOnChange: ['fields.value', 'fields.copy_from'],
validations: [
{
validator: ({ value, path, formData }) => {
if (isEmpty(value) && isEmpty(formData['fields.copy_from'])) {
return {
path,
message: i18n.translate('xpack.ingestPipelines.pipelineEditor.requiredValue', {
defaultMessage: 'A value is required.',
}),
};
}
},
},
],
},
labelAppend: (
<EuiText size="xs">
<EuiLink onClick={toggleCustom} data-test-subj="toggleCustomField">
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.useCopyFromLabel"
defaultMessage="Use copy from field"
/>
</EuiLink>
</EuiText>
),
key: 'value',
},
copy_from: {
path: 'fields.copy_from',
euiFieldProps: {
'data-test-subj': 'copyFromInput',
},
config: {
type: FIELD_TYPES.TEXT,
serializer: from.emptyStringToUndefined,
fieldsToValidateOnChange: ['fields.value', 'fields.copy_from'],
validations: [
{
validator: ({ value, path, formData }) => {
if (isEmpty(value) && isEmpty(formData['fields.value'])) {
return {
path,
message: i18n.translate('xpack.ingestPipelines.pipelineEditor.requiredCopyFrom', {
defaultMessage: 'A copy from value is required.',
}),
};
}
},
},
],
label: i18n.translate('xpack.ingestPipelines.pipelineEditor.setForm.copyFromFieldLabel', {
defaultMessage: 'Copy from',
}),
helpText: (
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.setForm.copyFromFieldHelpText"
defaultMessage="Field to copy into {field}."
values={{
field: <EuiCode>{'Field'}</EuiCode>,
}}
/>
),
},
labelAppend: (
<EuiText size="xs">
<EuiLink onClick={toggleCustom} data-test-subj="toggleCustomField">
<FormattedMessage
id="xpack.ingestPipelines.pipelineEditor.useValueLabel"
defaultMessage="Use value field"
/>
</EuiLink>
</EuiText>
),
key: 'copy_from',
},
});
/**
* Disambiguate name from the Set data structure
*/
export const SetProcessor: FunctionComponent = () => {
const [{ fields }] = useFormData({ watch: 'fields.value' });
const { getFieldDefaultValue } = useFormContext();
const [{ fields }] = useFormData({ watch: ['fields.value', 'fields.copy_from'] });
const isCopyFromDefined = getFieldDefaultValue('fields.copy_from') !== undefined;
const [isCopyFromEnabled, setIsCopyFrom] = useState<boolean>(isCopyFromDefined);
const toggleCustom = useCallback(() => {
setIsCopyFrom((prev) => !prev);
}, []);
const valueFieldProps = useMemo(
() =>
isCopyFromEnabled
? getValueConfig(toggleCustom).copy_from
: getValueConfig(toggleCustom).value,
[isCopyFromEnabled, toggleCustom]
);
return (
<>
@ -115,16 +233,7 @@ export const SetProcessor: FunctionComponent = () => {
})}
/>
<UseField
config={fieldsConfig.value}
component={Field}
componentProps={{
euiFieldProps: {
'data-test-subj': 'valueFieldInput',
},
}}
path="fields.value"
/>
<UseField {...valueFieldProps} component={Field} />
{hasTemplateSnippet(fields?.value) && (
<UseField

View file

@ -644,14 +644,25 @@ export const mapProcessorTypeToDescriptor: MapProcessorTypeToDescriptor = {
typeDescription: i18n.translate('xpack.ingestPipelines.processors.description.set', {
defaultMessage: 'Sets the value of a field.',
}),
getDefaultDescription: ({ field, value }) =>
i18n.translate('xpack.ingestPipelines.processors.defaultDescription.set', {
getDefaultDescription: ({ field, value, copy_from: copyFrom }) => {
if (copyFrom) {
return i18n.translate('xpack.ingestPipelines.processors.defaultDescription.setCopyFrom', {
defaultMessage: 'Sets value of "{field}" to the value of "{copyFrom}"',
values: {
field,
copyFrom,
},
});
}
return i18n.translate('xpack.ingestPipelines.processors.defaultDescription.set', {
defaultMessage: 'Sets value of "{field}" to "{value}"',
values: {
field,
value,
},
}),
});
},
},
set_security_user: {
FieldsComponent: SetSecurityUser,

View file

@ -156,6 +156,8 @@ export const PipelineProcessorsContextProvider: FunctionComponent<Props> = ({
// We manually add fields that we **don't** want to be treated as "unknownOptions"
'internal_networks',
'internal_networks_field',
'value',
'copy_from',
];
// If the processor type is changed while editing, we need to ignore unkownOptions as they

View file

@ -6530,7 +6530,6 @@
"xpack.canvas.error.esService.fieldsFetchErrorMessage": "「{index}」の Elasticsearch フィールドを取得できませんでした",
"xpack.canvas.error.esService.indicesFetchErrorMessage": "Elasticsearch インデックスを取得できませんでした",
"xpack.canvas.error.RenderWithFn.renderErrorMessage": "「{functionName}」のレンダリングが失敗しました",
"expressionRepeatImage.error.repeatImage.missingMaxArgument": "{emptyImageArgument} を指定する場合は、{maxArgument} を設定する必要があります",
"xpack.canvas.error.useCloneWorkpad.cloneFailureErrorMessage": "ワークパッドのクローンを作成できませんでした",
"xpack.canvas.error.useCreateWorkpad.uploadFailureErrorMessage": "ワークパッドをアップロードできませんでした",
"xpack.canvas.error.useDeleteWorkpads.deleteFailureErrorMessage": "すべてのワークパッドを削除できませんでした",
@ -6703,10 +6702,6 @@
"xpack.canvas.functions.if.args.elseHelpText": "条件が {BOOLEAN_FALSE} の場合の戻り値です。指定されておらず、条件が満たされていない場合は、元の {CONTEXT} が戻されます。",
"xpack.canvas.functions.if.args.thenHelpText": "条件が {BOOLEAN_TRUE} の場合の戻り値です。指定されておらず、条件が満たされている場合は、元の {CONTEXT} が戻されます。",
"xpack.canvas.functions.ifHelpText": "条件付きロジックを実行します。",
"expressionImage.functions.image.args.dataurlHelpText": "画像の {https} {URL} または {BASE64} データ {URL} です。",
"expressionImage.functions.image.args.modeHelpText": "{contain} はサイズに合わせて拡大・縮小して画像全体を表示し、{cover} はコンテナーを画像で埋め、必要に応じて両端や下をクロップします。{stretch} は画像の高さと幅をコンテナーの 100% になるよう変更します。",
"expressionImage.functions.image.invalidImageModeErrorMessage": "「mode」は「{contain}」、「{cover}」、または「{stretch}」でなければなりません",
"expressionImage.functions.imageHelpText": "画像を表示します。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"xpack.canvas.functions.joinRows.args.columnHelpText": "値を抽出する列またはフィールド。",
"xpack.canvas.functions.joinRows.args.distinctHelpText": "一意の値のみを抽出しますか?",
"xpack.canvas.functions.joinRows.args.quoteHelpText": "各抽出された値を囲む引用符文字。",
@ -6724,11 +6719,6 @@
"xpack.canvas.functions.markdown.args.fontHelpText": "コンテンツの {CSS} フォントプロパティです。たとえば、{fontFamily} または {fontWeight} です。",
"xpack.canvas.functions.markdown.args.openLinkHelpText": "新しいタブでリンクを開くためのtrue/false値。デフォルト値は「false」です。「true」に設定するとすべてのリンクが新しいタブで開くようになります。",
"xpack.canvas.functions.markdownHelpText": "{MARKDOWN} テキストをレンダリングするエレメントを追加します。ヒント:単一の数字、メトリック、テキストの段落には {markdownFn} 関数を使います。",
"expressionMetric.functions.metric.args.labelFontHelpText": "ラベルの {CSS} フォントプロパティです。例:{FONT_FAMILY} または {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.labelHelpText": "メトリックを説明するテキストです。",
"expressionMetric.functions.metric.args.metricFontHelpText": "メトリックの {CSS} フォントプロパティです。例:{FONT_FAMILY} または {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.metricFormatHelpText": "{NUMERALJS} 形式の文字列。例:{example1} または {example2}。",
"expressionMetric.functions.metricHelpText": "ラベルの上に数字を表示します。",
"xpack.canvas.functions.neq.args.valueHelpText": "{CONTEXT} と比較される値です。",
"xpack.canvas.functions.neqHelpText": "{CONTEXT} が引数と等しくないかを戻します。",
"xpack.canvas.functions.pie.args.fontHelpText": "ラベルの {CSS} フォントプロパティです。例:{FONT_FAMILY} または {FONT_WEIGHT}。",
@ -6776,11 +6766,6 @@
"xpack.canvas.functions.render.args.containerStyleHelpText": "背景、境界、透明度を含む、コンテナーのスタイルです。",
"xpack.canvas.functions.render.args.cssHelpText": "このエレメントの対象となるカスタム {CSS} のブロックです。",
"xpack.canvas.functions.renderHelpText": "{CONTEXT}を特定のエレメントとしてレンダリングし、背景と境界のスタイルなどのエレメントレベルのオプションを設定します。",
"expressionRepeatImage.functions.repeatImage.args.emptyImageHelpText": "この画像のエレメントについて、{CONTEXT}および{maxArg}パラメーターの差異を解消します。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"expressionRepeatImage.functions.repeatImage.args.imageHelpText": "繰り返す画像です。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"expressionRepeatImage.functions.repeatImage.args.maxHelpText": "画像が繰り返される最高回数です。",
"expressionRepeatImage.functions.repeatImage.args.sizeHelpText": "画像の高さまたは幅のピクセル単位での最高値です。画像が縦長の場合、この関数は高さを制限します。",
"expressionRepeatImage.functions.repeatImageHelpText": "繰り返し画像エレメントを構成します。",
"xpack.canvas.functions.replace.args.flagsHelpText": "フラグを指定します。{url}を参照してください。",
"xpack.canvas.functions.replace.args.patternHelpText": "{JS} 正規表現のテキストまたはパターンです。例:{example}。ここではキャプチャグループを使用できます。",
"xpack.canvas.functions.replace.args.replacementHelpText": "文字列の一致する部分の代わりです。キャプチャグループはノードによってアクセス可能です。例:{example}。",
@ -6959,22 +6944,14 @@
"xpack.canvas.renderer.dropdownFilter.matchAllOptionLabel": "すべて",
"xpack.canvas.renderer.embeddable.displayName": "埋め込み可能",
"xpack.canvas.renderer.embeddable.helpDescription": "Kibana の他の部分から埋め込み可能な保存済みオブジェクトをレンダリングします",
"expressionImage.renderer.image.displayName": "画像",
"expressionImage.renderer.image.helpDescription": "画像をレンダリングします",
"xpack.canvas.renderer.markdown.displayName": "マークダウン",
"xpack.canvas.renderer.markdown.helpDescription": "{MARKDOWN} インプットを使用して {HTML} を表示",
"expressionMetric.renderer.metric.displayName": "メトリック",
"expressionMetric.renderer.metric.helpDescription": "ラベルの上に数字をレンダリングします",
"xpack.canvas.renderer.pie.displayName": "円グラフ",
"xpack.canvas.renderer.pie.helpDescription": "データから円グラフをレンダリングします",
"xpack.canvas.renderer.plot.displayName": "座標プロット",
"xpack.canvas.renderer.plot.helpDescription": "データから XY プロットをレンダリングします",
"xpack.canvas.renderer.progress.displayName": "進捗インジケーター",
"xpack.canvas.renderer.progress.helpDescription": "エレメントのパーセンテージを示す進捗インジケーターをレンダリングします",
"expressionRepeatImage.renderer.repeatImage.displayName": "画像の繰り返し",
"expressionRepeatImage.renderer.repeatImage.helpDescription": "画像を指定回数繰り返し表示します",
"expressionShape.renderer.shape.displayName": "形状",
"expressionShape.renderer.shape.helpDescription": "基本的な図形をレンダリングします",
"xpack.canvas.renderer.table.displayName": "データテーブル",
"xpack.canvas.renderer.table.helpDescription": "表形式データを {HTML} としてレンダリングします",
"xpack.canvas.renderer.text.displayName": "プレインテキスト",
@ -7458,6 +7435,29 @@
"xpack.canvas.workpadTemplates.table.descriptionColumnTitle": "説明",
"xpack.canvas.workpadTemplates.table.nameColumnTitle": "テンプレート名",
"xpack.canvas.workpadTemplates.table.tagsColumnTitle": "タグ",
"expressionRepeatImage.error.repeatImage.missingMaxArgument": "{emptyImageArgument} を指定する場合は、{maxArgument} を設定する必要があります",
"expressionRepeatImage.functions.repeatImage.args.emptyImageHelpText": "この画像のエレメントについて、{CONTEXT}および{maxArg}パラメーターの差異を解消します。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"expressionRepeatImage.functions.repeatImage.args.imageHelpText": "繰り返す画像です。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"expressionRepeatImage.functions.repeatImage.args.maxHelpText": "画像が繰り返される最高回数です。",
"expressionRepeatImage.functions.repeatImage.args.sizeHelpText": "画像の高さまたは幅のピクセル単位での最高値です。画像が縦長の場合、この関数は高さを制限します。",
"expressionRepeatImage.functions.repeatImageHelpText": "繰り返し画像エレメントを構成します。",
"expressionRepeatImage.renderer.repeatImage.displayName": "画像の繰り返し",
"expressionRepeatImage.renderer.repeatImage.helpDescription": "画像を指定回数繰り返し表示します",
"expressionImage.functions.image.args.dataurlHelpText": "画像の {https} {URL} または {BASE64} データ {URL} です。",
"expressionImage.functions.image.args.modeHelpText": "{contain} はサイズに合わせて拡大・縮小して画像全体を表示し、{cover} はコンテナーを画像で埋め、必要に応じて両端や下をクロップします。{stretch} は画像の高さと幅をコンテナーの 100% になるよう変更します。",
"expressionImage.functions.image.invalidImageModeErrorMessage": "「mode」は「{contain}」、「{cover}」、または「{stretch}」でなければなりません",
"expressionImage.functions.imageHelpText": "画像を表示します。画像アセットは{BASE64}データ{URL}として提供するか、部分式で渡します。",
"expressionImage.renderer.image.displayName": "画像",
"expressionImage.renderer.image.helpDescription": "画像をレンダリングします",
"expressionMetric.functions.metric.args.labelFontHelpText": "ラベルの {CSS} フォントプロパティです。例:{FONT_FAMILY} または {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.labelHelpText": "メトリックを説明するテキストです。",
"expressionMetric.functions.metric.args.metricFontHelpText": "メトリックの {CSS} フォントプロパティです。例:{FONT_FAMILY} または {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.metricFormatHelpText": "{NUMERALJS} 形式の文字列。例:{example1} または {example2}。",
"expressionMetric.functions.metricHelpText": "ラベルの上に数字を表示します。",
"expressionMetric.renderer.metric.displayName": "メトリック",
"expressionMetric.renderer.metric.helpDescription": "ラベルの上に数字をレンダリングします",
"expressionShape.renderer.shape.displayName": "形状",
"expressionShape.renderer.shape.helpDescription": "基本的な図形をレンダリングします",
"expressionError.errorComponent.description": "表現が失敗し次のメッセージが返されました:",
"expressionError.errorComponent.title": "おっと!表現が失敗しました",
"expressionError.renderer.debug.displayName": "デバッグ",
@ -13103,7 +13103,6 @@
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldHelpText": "有効にすると、既存のフィールド値を上書きします。無効にすると、{nullValue}フィールドのみを更新します。",
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "無効化",
"xpack.ingestPipelines.pipelineEditor.setForm.propertiesFieldHelpText": "追加するユーザー詳細情報。フォルトは{value}です。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText": "フィールドの値。空白の値は{emptyString}を設定します。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "値",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.fieldNameField": "出力フィールド。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.propertiesFieldLabel": "プロパティ (任意) ",

View file

@ -6570,7 +6570,6 @@
"xpack.canvas.error.esService.fieldsFetchErrorMessage": "无法为“{index}”提取 Elasticsearch 字段",
"xpack.canvas.error.esService.indicesFetchErrorMessage": "无法提取 Elasticsearch 索引",
"xpack.canvas.error.RenderWithFn.renderErrorMessage": "呈现“{functionName}”失败。",
"expressionRepeatImage.error.repeatImage.missingMaxArgument": "如果提供 {emptyImageArgument},则必须设置 {maxArgument}",
"xpack.canvas.error.useCloneWorkpad.cloneFailureErrorMessage": "无法克隆 Workpad",
"xpack.canvas.error.useCreateWorkpad.uploadFailureErrorMessage": "无法上传 Workpad",
"xpack.canvas.error.useDeleteWorkpads.deleteFailureErrorMessage": "无法删除所有 Workpad",
@ -6744,10 +6743,6 @@
"xpack.canvas.functions.if.args.elseHelpText": "条件为 {BOOLEAN_FALSE} 时的返回值。未指定且条件未满足时,将返回原始 {CONTEXT}。",
"xpack.canvas.functions.if.args.thenHelpText": "条件为 {BOOLEAN_TRUE} 时的返回值。未指定且条件满足时,将返回原始 {CONTEXT}。",
"xpack.canvas.functions.ifHelpText": "执行条件逻辑。",
"expressionImage.functions.image.args.dataurlHelpText": "图像的 {https} {URL} 或 {BASE64} 数据 {URL}。",
"expressionImage.functions.image.args.modeHelpText": "{contain} 将显示整个图像,图像缩放至适合大小。{cover} 将使用该图像填充容器,根据需要在两边或底部裁剪图像。{stretch} 将图像的高和宽调整为容器的 100%。",
"expressionImage.functions.image.invalidImageModeErrorMessage": "“mode”必须为“{contain}”、“{cover}”或“{stretch}”",
"expressionImage.functions.imageHelpText": "显示图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"xpack.canvas.functions.joinRows.args.columnHelpText": "从其中提取值的列或字段。",
"xpack.canvas.functions.joinRows.args.distinctHelpText": "仅提取唯一值?",
"xpack.canvas.functions.joinRows.args.quoteHelpText": "要将每个提取的值引起来的引号字符。",
@ -6765,11 +6760,6 @@
"xpack.canvas.functions.markdown.args.fontHelpText": "内容的 {CSS} 字体属性。例如 {fontFamily} 或 {fontWeight}。",
"xpack.canvas.functions.markdown.args.openLinkHelpText": "用于在新标签页中打开链接的 true 或 false 值。默认值为 `false`。设置为 `true` 时将在新标签页中打开所有链接。",
"xpack.canvas.functions.markdownHelpText": "添加呈现 {MARKDOWN} 文本的元素。提示:将 {markdownFn} 函数用于单个数字、指标和文本段落。",
"expressionMetric.functions.metric.args.labelFontHelpText": "标签的 {CSS} 字体属性。例如 {FONT_FAMILY} 或 {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.labelHelpText": "描述指标的文本。",
"expressionMetric.functions.metric.args.metricFontHelpText": "指标的 {CSS} 字体属性。例如 {FONT_FAMILY} 或 {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.metricFormatHelpText": "{NUMERALJS} 格式字符串。例如 {example1} 或 {example2}。",
"expressionMetric.functions.metricHelpText": "在标签上显示数字。",
"xpack.canvas.functions.neq.args.valueHelpText": "与 {CONTEXT} 比较的值。",
"xpack.canvas.functions.neqHelpText": "返回 {CONTEXT} 是否不等于参数。",
"xpack.canvas.functions.pie.args.fontHelpText": "标签的 {CSS} 字体属性。例如 {FONT_FAMILY} 或 {FONT_WEIGHT}。",
@ -6817,11 +6807,6 @@
"xpack.canvas.functions.render.args.containerStyleHelpText": "容器的样式,包括背景、边框和透明度。",
"xpack.canvas.functions.render.args.cssHelpText": "要限定于元素的任何定制 {CSS} 块。",
"xpack.canvas.functions.renderHelpText": "将 {CONTEXT} 呈现为特定元素,并设置元素级别选项,例如背景和边框样式。",
"expressionRepeatImage.functions.repeatImage.args.emptyImageHelpText": "使用此图像填充元素的 {CONTEXT} 和 {maxArg} 参数之间的差距。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRepeatImage.functions.repeatImage.args.imageHelpText": "要重复的图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRepeatImage.functions.repeatImage.args.maxHelpText": "图像可以重复的最大次数。",
"expressionRepeatImage.functions.repeatImage.args.sizeHelpText": "图像的最大高度或宽度,以像素为单位。图像的高大于宽时,此函数将限制高度。",
"expressionRepeatImage.functions.repeatImageHelpText": "配置重复图像元素。",
"xpack.canvas.functions.replace.args.flagsHelpText": "指定标志。请参见 {url}。",
"xpack.canvas.functions.replace.args.patternHelpText": "{JS} 正则表达式的文本或模式。例如,{example}。您可以在此处使用捕获组。",
"xpack.canvas.functions.replace.args.replacementHelpText": "字符串匹配部分的替代。捕获组可以通过其索引进行访问。例如,{example}。",
@ -7000,24 +6985,14 @@
"xpack.canvas.renderer.dropdownFilter.matchAllOptionLabel": "任意",
"xpack.canvas.renderer.embeddable.displayName": "可嵌入",
"xpack.canvas.renderer.embeddable.helpDescription": "从 Kibana 的其他部分呈现可嵌入的已保存对象",
"expressionImage.renderer.image.displayName": "图像",
"expressionImage.renderer.image.helpDescription": "呈现图像",
"xpack.canvas.renderer.markdown.displayName": "Markdown",
"xpack.canvas.renderer.markdown.helpDescription": "使用 {MARKDOWN} 输入呈现 {HTML}",
"expressionMetric.renderer.metric.displayName": "指标",
"expressionMetric.renderer.metric.helpDescription": "在标签上呈现数字",
"xpack.canvas.renderer.pie.displayName": "饼图",
"xpack.canvas.renderer.pie.helpDescription": "根据您的数据呈现饼图",
"xpack.canvas.renderer.plot.displayName": "坐标图",
"xpack.canvas.renderer.plot.helpDescription": "根据您的数据呈现 XY 坐标图",
"xpack.canvas.renderer.progress.displayName": "进度指示",
"xpack.canvas.renderer.progress.helpDescription": "呈现显示元素百分比的进度指示",
"expressionRepeatImage.renderer.repeatImage.displayName": "图像重复",
"expressionRepeatImage.renderer.repeatImage.helpDescription": "重复图像给定次数",
"expressionRevealImage.renderer.revealImage.displayName": "图像显示",
"expressionRevealImage.renderer.revealImage.helpDescription": "显示一定百分比的图像,以制作定制的仪表样式图表",
"expressionShape.renderer.shape.displayName": "形状",
"expressionShape.renderer.shape.helpDescription": "呈现基本形状",
"xpack.canvas.renderer.table.displayName": "数据表",
"xpack.canvas.renderer.table.helpDescription": "将表格数据呈现为 {HTML}",
"xpack.canvas.renderer.text.displayName": "纯文本",
@ -7509,17 +7484,42 @@
"xpack.canvas.workpadTemplates.table.descriptionColumnTitle": "描述",
"xpack.canvas.workpadTemplates.table.nameColumnTitle": "模板名称",
"xpack.canvas.workpadTemplates.table.tagsColumnTitle": "标签",
"expressionRepeatImage.error.repeatImage.missingMaxArgument": "如果提供 {emptyImageArgument},则必须设置 {maxArgument}",
"expressionRepeatImage.functions.repeatImage.args.emptyImageHelpText": "使用此图像填充元素的 {CONTEXT} 和 {maxArg} 参数之间的差距。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRepeatImage.functions.repeatImage.args.imageHelpText": "要重复的图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRepeatImage.functions.repeatImage.args.maxHelpText": "图像可以重复的最大次数。",
"expressionRepeatImage.functions.repeatImage.args.sizeHelpText": "图像的最大高度或宽度,以像素为单位。图像的高大于宽时,此函数将限制高度。",
"expressionRepeatImage.functions.repeatImageHelpText": "配置重复图像元素。",
"expressionRepeatImage.renderer.repeatImage.displayName": "图像重复",
"expressionRepeatImage.renderer.repeatImage.helpDescription": "重复图像给定次数",
"expressionImage.functions.image.args.dataurlHelpText": "图像的 {https} {URL} 或 {BASE64} 数据 {URL}。",
"expressionImage.functions.image.args.modeHelpText": "{contain} 将显示整个图像,图像缩放至适合大小。{cover} 将使用该图像填充容器,根据需要在两边或底部裁剪图像。{stretch} 将图像的高和宽调整为容器的 100%。",
"expressionImage.functions.image.invalidImageModeErrorMessage": "“mode”必须为“{contain}”、“{cover}”或“{stretch}”",
"expressionImage.functions.imageHelpText": "显示图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionImage.renderer.image.displayName": "图像",
"expressionImage.renderer.image.helpDescription": "呈现图像",
"expressionMetric.functions.metric.args.labelFontHelpText": "标签的 {CSS} 字体属性。例如 {FONT_FAMILY} 或 {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.labelHelpText": "描述指标的文本。",
"expressionMetric.functions.metric.args.metricFontHelpText": "指标的 {CSS} 字体属性。例如 {FONT_FAMILY} 或 {FONT_WEIGHT}。",
"expressionMetric.functions.metric.args.metricFormatHelpText": "{NUMERALJS} 格式字符串。例如 {example1} 或 {example2}。",
"expressionMetric.functions.metricHelpText": "在标签上显示数字。",
"expressionMetric.renderer.metric.displayName": "指标",
"expressionMetric.renderer.metric.helpDescription": "在标签上呈现数字",
"expressionRevealImage.renderer.revealImage.displayName": "图像显示",
"expressionRevealImage.renderer.revealImage.helpDescription": "显示一定百分比的图像,以制作定制的仪表样式图表",
"expressionRevealImage.functions.revealImage.args.emptyImageHelpText": "要显示的可选背景图像。以 `{BASE64}` 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRevealImage.functions.revealImage.args.imageHelpText": "要显示的图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRevealImage.functions.revealImage.args.originHelpText": "要开始图像填充的位置。例如 {list} 或 {end}。",
"expressionRevealImage.functions.revealImage.invalidPercentErrorMessage": "无效值:“{percent}”。百分比必须介于 0 和 1 之间",
"expressionRevealImage.functions.revealImageHelpText": "配置图像显示元素。",
"expressionShape.renderer.shape.displayName": "形状",
"expressionShape.renderer.shape.helpDescription": "呈现基本形状",
"expressionError.errorComponent.description": "表达式失败,并显示消息:",
"expressionError.errorComponent.title": "哎哟!表达式失败",
"expressionError.renderer.debug.displayName": "故障排查",
"expressionError.renderer.debug.helpDescription": "将故障排查输出呈现为带格式的 {JSON}",
"expressionError.renderer.error.displayName": "错误信息",
"expressionError.renderer.error.helpDescription": "以用户友好的方式呈现错误数据",
"expressionRevealImage.functions.revealImage.args.emptyImageHelpText": "要显示的可选背景图像。以 `{BASE64}` 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRevealImage.functions.revealImage.args.imageHelpText": "要显示的图像。以 {BASE64} 数据 {URL} 的形式提供图像资产或传入子表达式。",
"expressionRevealImage.functions.revealImage.args.originHelpText": "要开始图像填充的位置。例如 {list} 或 {end}。",
"expressionRevealImage.functions.revealImage.invalidPercentErrorMessage": "无效值:“{percent}”。百分比必须介于 0 和 1 之间",
"expressionRevealImage.functions.revealImageHelpText": "配置图像显示元素。",
"xpack.cases.connectors.cases.externalIncidentAdded": " (由 {user} 于 {date}添加) ",
"xpack.cases.connectors.cases.externalIncidentCreated": " (由 {user} 于 {date}创建) ",
"xpack.cases.connectors.cases.externalIncidentDefault": " (由 {user} 于 {date}创建) ",
@ -13272,7 +13272,6 @@
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldHelpText": "如果启用,则覆盖现有字段值。如果禁用,则仅更新 {nullValue} 字段。",
"xpack.ingestPipelines.pipelineEditor.setForm.overrideFieldLabel": "覆盖",
"xpack.ingestPipelines.pipelineEditor.setForm.propertiesFieldHelpText": "要添加的用户详情。默认为 {value}",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldHelpText": "字段的值。空值将设置 {emptyString}。",
"xpack.ingestPipelines.pipelineEditor.setForm.valueFieldLabel": "值",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.fieldNameField": "输出字段。",
"xpack.ingestPipelines.pipelineEditor.setSecurityUserForm.propertiesFieldLabel": "属性(可选)",