From 08fc41a9de846a4a0469eac7b20f0b9fe7eeae3a Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 27 Jul 2021 18:28:30 +0300 Subject: [PATCH] [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 --- .../__jest__/processors/processor.helpers.tsx | 3 +- .../__jest__/processors/set.test.tsx | 52 ++++-- .../processors/network_direction.tsx | 28 +-- .../processor_form/processors/set.tsx | 173 ++++++++++++++---- .../shared/map_processor_type_to_form.tsx | 17 +- .../context/processors_context.tsx | 2 + .../translations/translations/ja-JP.json | 47 +++-- .../translations/translations/zh-CN.json | 61 +++--- 8 files changed, 262 insertions(+), 121 deletions(-) diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx index 183777ca765b43..9101e64278dc60 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/processor.helpers.tsx @@ -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'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx index d7351c9dbf65f6..544b8aeb51c054 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/__jest__/processors/set.test.tsx @@ -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, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/network_direction.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/network_direction.tsx index 2026a77bc6566e..22f2226d80b10f 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/network_direction.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/network_direction.tsx @@ -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: ( - - {i18n.translate('xpack.ingestPipelines.pipelineEditor.internalNetworkCustomLabel', { - defaultMessage: 'Use custom field', - })} - + + + + + ), key: 'preset', }, @@ -171,11 +174,14 @@ const getInternalNetworkConfig: ( ), }, labelAppend: ( - - {i18n.translate('xpack.ingestPipelines.pipelineEditor.internalNetworkPredefinedLabel', { - defaultMessage: 'Use preset field', - })} - + + + + + ), key: 'custom', }, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/set.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/set.tsx index fda34f8700b33c..16d89fcbfb119b 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/set.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/components/processor_form/processors/set.tsx @@ -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; +}; + +// 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: ( - {'""'}, - }} - /> - ), - }, 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; + euiFieldProps?: Record; + 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: ( + + ), + 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: ( + + + + + + ), + 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: ( + {'Field'}, + }} + /> + ), + }, + labelAppend: ( + + + + + + ), + 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(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 = () => { })} /> - + {hasTemplateSnippet(fields?.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, diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx index 6233b220ae7730..f6848a7f2bf455 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_editor/context/processors_context.tsx @@ -156,6 +156,8 @@ export const PipelineProcessorsContextProvider: FunctionComponent = ({ // 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 diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ffdd031cfef066..e82658f2529032 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -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": "プロパティ (任意) ", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b241e1455864d4..4d954a609da8d8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -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": "属性(可选)",