Skip to content

Commit

Permalink
[8.x] Handle Json in Set and Append Value field (#204336) (#205470)
Browse files Browse the repository at this point in the history
# Backport

This will backport the following commits from `main` to `8.x`:
- [Handle Json in Set and Append Value field
(#204336)](#204336)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Sonia Sanz
Vivas","email":"sonia.sanzvivas@elastic.co"},"sourceCommit":{"committedDate":"2025-01-03T06:34:57Z","message":"Handle
Json in Set and Append Value field (#204336)\n\nCloses
[#193186](https://github.com/elastic/kibana/issues/193186)\n\n##
Sumary\n\nThis PR introduces changes in two processors: Set y Append.
The aim of\nthis changes is to allow introducing the Value field in both
processors\nin Json format. Now, Set accepts Text format or Json and
Append a list\nof values or Json. The toggle between the format is done
by the new\nLabel Append button.\n<img width=\"705\" alt=\"Screenshot
2024-12-16 at 07 30
11\"\nsrc=\"https://github.com/user-attachments/assets/0f6283ed-6117-48d8-bdd8-e0685ae1b42d\"\n/>\n\n\nAlso,
since the Set processor already had a Label Append button for\ntoggling
between the `Value` and the `Copy_from` field, this now has\nbeen
replaced by a toggle button that enables a field for the\n`Copy_from`
field (see the last comments in the related Issue for see\nthe most
updated mocks).\n<img width=\"708\" alt=\"Screenshot 2024-12-16 at 07 30
49\"\nsrc=\"https://github.com/user-attachments/assets/4a632bda-4b4b-49b1-b3d4-d11579d7c27c\"\n/>\n\nNote:
the Set copies still pending review so probably will be changed.\n\n###
Demo\n\n\nhttps://github.com/user-attachments/assets/f9d1da6a-782d-4197-836b-fab46b4476b7","sha":"59b229280d2d48d45f5623d7d521a804b24848bc","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Kibana
Management","release_note:skip","v9.0.0","Feature:Ingest Node
Pipelines","backport:prev-major"],"title":"Handle Json in Set and Append
Value
field","number":204336,"url":"https://github.com/elastic/kibana/pull/204336","mergeCommit":{"message":"Handle
Json in Set and Append Value field (#204336)\n\nCloses
[#193186](https://github.com/elastic/kibana/issues/193186)\n\n##
Sumary\n\nThis PR introduces changes in two processors: Set y Append.
The aim of\nthis changes is to allow introducing the Value field in both
processors\nin Json format. Now, Set accepts Text format or Json and
Append a list\nof values or Json. The toggle between the format is done
by the new\nLabel Append button.\n<img width=\"705\" alt=\"Screenshot
2024-12-16 at 07 30
11\"\nsrc=\"https://github.com/user-attachments/assets/0f6283ed-6117-48d8-bdd8-e0685ae1b42d\"\n/>\n\n\nAlso,
since the Set processor already had a Label Append button for\ntoggling
between the `Value` and the `Copy_from` field, this now has\nbeen
replaced by a toggle button that enables a field for the\n`Copy_from`
field (see the last comments in the related Issue for see\nthe most
updated mocks).\n<img width=\"708\" alt=\"Screenshot 2024-12-16 at 07 30
49\"\nsrc=\"https://github.com/user-attachments/assets/4a632bda-4b4b-49b1-b3d4-d11579d7c27c\"\n/>\n\nNote:
the Set copies still pending review so probably will be changed.\n\n###
Demo\n\n\nhttps://github.com/user-attachments/assets/f9d1da6a-782d-4197-836b-fab46b4476b7","sha":"59b229280d2d48d45f5623d7d521a804b24848bc"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/204336","number":204336,"mergeCommit":{"message":"Handle
Json in Set and Append Value field (#204336)\n\nCloses
[#193186](https://github.com/elastic/kibana/issues/193186)\n\n##
Sumary\n\nThis PR introduces changes in two processors: Set y Append.
The aim of\nthis changes is to allow introducing the Value field in both
processors\nin Json format. Now, Set accepts Text format or Json and
Append a list\nof values or Json. The toggle between the format is done
by the new\nLabel Append button.\n<img width=\"705\" alt=\"Screenshot
2024-12-16 at 07 30
11\"\nsrc=\"https://github.com/user-attachments/assets/0f6283ed-6117-48d8-bdd8-e0685ae1b42d\"\n/>\n\n\nAlso,
since the Set processor already had a Label Append button for\ntoggling
between the `Value` and the `Copy_from` field, this now has\nbeen
replaced by a toggle button that enables a field for the\n`Copy_from`
field (see the last comments in the related Issue for see\nthe most
updated mocks).\n<img width=\"708\" alt=\"Screenshot 2024-12-16 at 07 30
49\"\nsrc=\"https://github.com/user-attachments/assets/4a632bda-4b4b-49b1-b3d4-d11579d7c27c\"\n/>\n\nNote:
the Set copies still pending review so probably will be changed.\n\n###
Demo\n\n\nhttps://github.com/user-attachments/assets/f9d1da6a-782d-4197-836b-fab46b4476b7","sha":"59b229280d2d48d45f5623d7d521a804b24848bc"}}]}]
BACKPORT-->

Co-authored-by: Sonia Sanz Vivas <sonia.sanzvivas@elastic.co>
  • Loading branch information
kibanamachine and SoniaSanzV authored Jan 3, 2025
1 parent 465d2aa commit 4152249
Show file tree
Hide file tree
Showing 15 changed files with 453 additions and 164 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25613,7 +25613,6 @@
"xpack.ingestPipelines.pipelineEditor.uppercaseForm.fieldNameHelpText": "Champ à mettre en majuscules. Pour un tableau de chaînes, chaque élément est mis en majuscules.",
"xpack.ingestPipelines.pipelineEditor.uriPartsForm.fieldNameHelpText": "Champ contenant la chaîne d'URI.",
"xpack.ingestPipelines.pipelineEditor.urlDecodeForm.fieldNameHelpText": "Champ à décoder. Pour un tableau de chaînes, chaque élément est décodé.",
"xpack.ingestPipelines.pipelineEditor.useCopyFromLabel": "Utiliser le champ Copier à partir de",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameFieldText": "Extraire le type d'appareil",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameTooltipText": "Cette fonctionnalité est en version bêta et susceptible d'être modifiée.",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText": "Extrait le type d'appareil à partir de la chaîne d'agent utilisateur.",
Expand All @@ -25622,7 +25621,6 @@
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldHelpText": "Fichier contenant les expressions régulières utilisées pour analyser la chaîne d'agent utilisateur.",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldLabel": "Fichier d'expression régulière (facultatif)",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.targetFieldHelpText": "Champ de sortie. La valeur par défaut est {defaultField}.",
"xpack.ingestPipelines.pipelineEditor.useValueLabel": "Utiliser le champ de valeur",
"xpack.ingestPipelines.pipelineEditorItem.droppedStatusAriaLabel": "Abandonné",
"xpack.ingestPipelines.pipelineEditorItem.errorIgnoredStatusAriaLabel": "Erreur ignorée",
"xpack.ingestPipelines.pipelineEditorItem.errorStatusAriaLabel": "Erreur",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25471,7 +25471,6 @@
"xpack.ingestPipelines.pipelineEditor.uppercaseForm.fieldNameHelpText": "大文字にするフィールド。文字列の配列の場合、各エレメントが大文字にされます。",
"xpack.ingestPipelines.pipelineEditor.uriPartsForm.fieldNameHelpText": "URI文字列を含むフィールド。",
"xpack.ingestPipelines.pipelineEditor.urlDecodeForm.fieldNameHelpText": "デコードするフィールド。文字列の配列の場合、各エレメントがデコードされます。",
"xpack.ingestPipelines.pipelineEditor.useCopyFromLabel": "フィールドからコピーを使用",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameFieldText": "デバイスタイプを抽出",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameTooltipText": "この機能はベータ段階で、変更される可能性があります。",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText": "ユーザーエージェント文字列からデバイスタイプを抽出します。",
Expand All @@ -25480,7 +25479,6 @@
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldHelpText": "ユーザーエージェント文字列を解析するために使用される正規表現を含むファイル。",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldLabel": "正規表現ファイル(任意)",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.targetFieldHelpText": "出力フィールド。デフォルトは{defaultField}です。",
"xpack.ingestPipelines.pipelineEditor.useValueLabel": "値フィールドを使用",
"xpack.ingestPipelines.pipelineEditorItem.droppedStatusAriaLabel": "ドロップ",
"xpack.ingestPipelines.pipelineEditorItem.errorIgnoredStatusAriaLabel": "エラーを無視",
"xpack.ingestPipelines.pipelineEditorItem.errorStatusAriaLabel": "エラー",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25558,7 +25558,6 @@
"xpack.ingestPipelines.pipelineEditor.uppercaseForm.fieldNameHelpText": "要大写的字段。对于字符串数组,每个元素都为大写。",
"xpack.ingestPipelines.pipelineEditor.uriPartsForm.fieldNameHelpText": "包含 URI 字符串的字段。",
"xpack.ingestPipelines.pipelineEditor.urlDecodeForm.fieldNameHelpText": "要解码的字段。对于字符串数组,每个元素都要解码。",
"xpack.ingestPipelines.pipelineEditor.useCopyFromLabel": "使用复制位置字段",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameFieldText": "确切设备类型",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceNameTooltipText": "此功能为公测版,可能会进行更改。",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.extractDeviceTypeFieldHelpText": "从用户代理字符串中提取设备类型。",
Expand All @@ -25567,7 +25566,6 @@
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldHelpText": "包含用于解析用户代理字符串的正则表达式的文件。",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.regexFileFieldLabel": "正则表达式文件(可选)",
"xpack.ingestPipelines.pipelineEditor.userAgentForm.targetFieldHelpText": "输出字段。默认为 {defaultField}。",
"xpack.ingestPipelines.pipelineEditor.useValueLabel": "使用值字段",
"xpack.ingestPipelines.pipelineEditorItem.droppedStatusAriaLabel": "已丢弃",
"xpack.ingestPipelines.pipelineEditorItem.errorIgnoredStatusAriaLabel": "错误已忽略",
"xpack.ingestPipelines.pipelineEditorItem.errorStatusAriaLabel": "错误",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ describe('Pipeline Editor', () => {
// Open the edit processor form for the set processor
actions.openProcessorEditor('processors>2');
expect(exists('editProcessorForm')).toBeTruthy();
form.setInputValue('editProcessorForm.valueFieldInput', 'test44');
form.setInputValue('editProcessorForm.textValueField.input', 'test44');
jest.advanceTimersByTime(0); // advance timers to allow the form to validate
await actions.submitProcessorForm();
const [onUpdateResult] = onUpdate.mock.calls[onUpdate.mock.calls.length - 1];
Expand Down Expand Up @@ -175,7 +175,7 @@ describe('Pipeline Editor', () => {
// Change its type to `append` and set the missing required fields
await actions.setProcessorType('append');
await act(async () => {
find('appendValueField.input').simulate('change', [{ label: 'some_value' }]);
find('comboxValueField.input').simulate('change', [{ label: 'some_value' }]);
});
component.update();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ describe('Processor: Append', () => {
form.setInputValue('fieldNameField.input', 'field_1');

await act(async () => {
find('appendValueField.input').simulate('change', [{ label: 'Some_Value' }]);
find('comboxValueField.input').simulate('change', [{ label: 'Some_Value' }]);
});
component.update();

Expand All @@ -102,7 +102,7 @@ describe('Processor: Append', () => {

// Set optional parameteres
await act(async () => {
find('appendValueField.input').simulate('change', [{ label: 'Some_Value' }]);
find('comboxValueField.input').simulate('change', [{ label: 'Some_Value' }]);
component.update();
});
form.toggleEuiSwitch('allowDuplicatesSwitch.input');
Expand Down Expand Up @@ -134,14 +134,14 @@ describe('Processor: Append', () => {

// Shouldn't be able to set media_type if value is not a template string
await act(async () => {
find('appendValueField.input').simulate('change', [{ label: 'value_1' }]);
find('comboxValueField.input').simulate('change', [{ label: 'value_1' }]);
});
component.update();
expect(exists('mediaTypeSelectorField')).toBe(false);

// Set value to a template snippet and media_type to a non-default value
await act(async () => {
find('appendValueField.input').simulate('change', [{ label: '{{{value_2}}}' }]);
find('comboxValueField.input').simulate('change', [{ label: '{{{value_2}}}' }]);
});
component.update();
form.setSelectValue('mediaTypeSelectorField', 'text/plain');
Expand All @@ -156,4 +156,42 @@ describe('Processor: Append', () => {
media_type: 'text/plain',
});
});

test('saves with json parameter values', async () => {
const {
actions: { saveNewProcessor },
form,
find,
component,
} = testBed;

// Add "field" value (required)
form.setInputValue('fieldNameField.input', 'field_1');

await act(async () => {
find('comboxValueField.input').simulate('change', [{ label: 'Some_Value' }]);
});
component.update();

find('toggleTextField').simulate('click');

await act(async () => {
find('jsonValueField').simulate('change', {
jsonContent: '{"value_1":"""aaa"bbb""", "value_2":"aaa(bbb"}',
});

// advance timers to allow the form to validate
jest.advanceTimersByTime(0);
});

// Save the field
await saveNewProcessor();

const processors = getProcessorValue(onUpdate, APPEND_TYPE);
expect(processors[0].append).toEqual({
field: 'field_1',
// eslint-disable-next-line prettier/prettier
value: { value_1: 'aaa\"bbb', value_2: 'aaa(bbb' },
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ type TestSubject =
| 'addProcessorForm.submitButton'
| 'addProcessorButton'
| 'addProcessorForm.submitButton'
| 'appendValueField.input'
| 'comboxValueField.input'
| 'allowDuplicatesSwitch.input'
| 'formatsValueField.input'
| 'timezoneField.input'
Expand Down Expand Up @@ -157,10 +157,11 @@ type TestSubject =
| 'extractDeviceTypeSwitch.input'
| 'propertiesValueField'
| 'regexFileField.input'
| 'valueFieldInput'
| 'textValueField.input'
| 'mediaTypeSelectorField'
| 'networkDirectionField.input'
| 'toggleCustomField'
| 'toggleCustomField.input'
| 'ignoreEmptyField.input'
| 'overrideField.input'
| 'fieldsValueField.input'
Expand All @@ -175,7 +176,7 @@ type TestSubject =
| 'ianaField.input'
| 'transportField.input'
| 'seedField.input'
| 'copyFromInput'
| 'copyFromInput.input'
| 'trimSwitch.input'
| 'droppableList.addButton'
| 'droppableList.input-0'
Expand Down Expand Up @@ -205,4 +206,6 @@ type TestSubject =
| 'scriptSource'
| 'inferenceModelId.input'
| 'inferenceConfig'
| 'fieldMap';
| 'fieldMap'
| 'toggleTextField'
| 'jsonValueField';
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('Processor: Set', () => {
} = testBed;

// Add required fields
form.setInputValue('valueFieldInput', 'value');
form.setInputValue('textValueField.input', 'value');
form.setInputValue('fieldNameField.input', 'field_1');
// Save the field
await saveNewProcessor();
Expand All @@ -83,18 +83,17 @@ describe('Processor: Set', () => {
const {
actions: { saveNewProcessor },
form,
find,
} = testBed;

// Add required fields
form.setInputValue('fieldNameField.input', 'field_1');

// Set value field
form.setInputValue('valueFieldInput', 'value');
form.setInputValue('textValueField.input', 'value');

// Toggle to copy_from field and set a random value
find('toggleCustomField').simulate('click');
form.setInputValue('copyFromInput', 'copy_from');
form.toggleEuiSwitch('toggleCustomField.input');
form.setInputValue('copyFromInput.input', 'copy_from');

// Save the field with new changes
await saveNewProcessor();
Expand All @@ -117,11 +116,11 @@ describe('Processor: Set', () => {
form.setInputValue('fieldNameField.input', 'field_1');

// Shouldnt be able to set mediaType if value is not a template string
form.setInputValue('valueFieldInput', 'hello');
form.setInputValue('textValueField.input', 'hello');
expect(exists('mediaTypeSelectorField')).toBe(false);

// Set value to a template snippet and media_type to a non-default value
form.setInputValue('valueFieldInput', '{{{hello}}}');
form.setInputValue('textValueField.input', '{{{hello}}}');
form.setSelectValue('mediaTypeSelectorField', 'text/plain');

// Save the field with new changes
Expand All @@ -145,7 +144,7 @@ describe('Processor: Set', () => {
form.setInputValue('fieldNameField.input', 'field_1');

// Set optional parameteres
form.setInputValue('valueFieldInput', '{{{hello}}}');
form.setInputValue('textValueField.input', '{{{hello}}}');
form.toggleEuiSwitch('overrideField.input');
form.toggleEuiSwitch('ignoreEmptyField.input');

Expand All @@ -160,4 +159,37 @@ describe('Processor: Set', () => {
override: false,
});
});

test('saves with json parameter value', async () => {
const {
actions: { saveNewProcessor },
form,
find,
component,
} = testBed;

form.setInputValue('textValueField.input', 'value');

find('toggleTextField').simulate('click');

form.setInputValue('fieldNameField.input', 'field_1');
await act(async () => {
find('jsonValueField').simulate('change', {
jsonContent: '{"value_1":"""aaa"bbb""", "value_2":"aaa(bbb"}',
});

// advance timers to allow the form to validate
jest.advanceTimersByTime(0);
});
component.update();
// Save the field
await saveNewProcessor();

const processors = getProcessorValue(onUpdate, SET_TYPE);
expect(processors[0][SET_TYPE]).toEqual({
field: 'field_1',
// eslint-disable-next-line prettier/prettier
value: { value_1: 'aaa\"bbb', value_2: 'aaa(bbb' },
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { DragAndDropTextList } from './drag_and_drop_text_list';
export { XJsonEditor } from './xjson_editor';
export { TextEditor } from './text_editor';
export { InputList } from './input_list';
export { XJsonToggle } from './xjson_toggle';
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ import './text_editor.scss';
interface Props {
field: FieldHook<string>;
editorProps: { [key: string]: any };
euiFieldProps?: Record<string, any>;
}

export const TextEditor: FunctionComponent<Props> = ({ field, editorProps }) => {
export const TextEditor: FunctionComponent<Props> = ({ field, editorProps, euiFieldProps }) => {
const { value, helpText, setValue, label } = field;
const { errorMessage } = getFieldValidityAndErrorMessage(field);

Expand All @@ -32,11 +33,13 @@ export const TextEditor: FunctionComponent<Props> = ({ field, editorProps }) =>
isInvalid={typeof errorMessage === 'string'}
error={errorMessage}
fullWidth
labelAppend={editorProps.labelAppend}
>
<EuiPanel
className="pipelineProcessorsEditor__form__textEditor__panel"
paddingSize="s"
hasShadow={false}
{...euiFieldProps}
>
<CodeEditor value={value} onChange={setValue} {...(editorProps as any)} />
</EuiPanel>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@ import { TextEditor } from './text_editor';
interface Props {
field: FieldHook<string>;
editorProps: { [key: string]: any };
disabled?: boolean;
}

const defaultEditorOptions = {
minimap: { enabled: false },
lineNumbers: 'off',
};

export const XJsonEditor: FunctionComponent<Props> = ({ field, editorProps }) => {
export const XJsonEditor: FunctionComponent<Props> = ({ field, editorProps, disabled }) => {
const { value, setValue } = field;
const onChange = useCallback(
(s: any) => {
setValue(s);
},
[setValue]
);

return (
<TextEditor
field={field}
Expand All @@ -39,6 +41,7 @@ export const XJsonEditor: FunctionComponent<Props> = ({ field, editorProps }) =>
onChange,
...editorProps,
}}
euiFieldProps={{ disabled }}
/>
);
};
Loading

0 comments on commit 4152249

Please sign in to comment.