Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,22 @@ describe('convertUIStepsToDSL', () => {
expect(dsl.steps).toHaveLength(0);
});

it('strips undefined fields from action steps', () => {
const uiSteps: StreamlangStepWithUIAttributes[] = [
{
customIdentifier: '1',
action: 'set',
to: 'foo',
value: 'bar',
description: undefined,
parentId: null,
},
];
const dsl = convertUIStepsToDSL(uiSteps);
expect(dsl.steps[0]).not.toHaveProperty('description');
expect(dsl.steps[0]).toMatchObject({ action: 'set', to: 'foo', value: 'bar' });
});

it('nests else-branch steps under condition.else using branch attribute', () => {
const uiSteps: StreamlangStepWithUIAttributes[] = [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export const convertStepToUIDefinition = <TStepDefinition extends StreamlangStep
};
};

const stripUndefinedValues = <T extends object>(obj: T): T =>
Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as T;

type StreamlangStepWithUIProps = StreamlangStep & {
parentId: string | null;
branch?: StreamlangUIBranch;
Expand Down Expand Up @@ -157,7 +160,10 @@ export const convertUIStepsToDSL = (
: { ...whereRest, customIdentifier, condition };
} else {
const { parentId, branch, customIdentifier, ...actionRest } = step;
return removeCustomIdentifiers ? actionRest : { ...actionRest, customIdentifier };
const actionRestSanitised = stripUndefinedValues(actionRest);
return removeCustomIdentifiers
? actionRestSanitised
: { ...actionRestSanitised, customIdentifier };
Copy link
Copy Markdown
Contributor Author

@nikita-lavrov nikita-lavrov May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents the bottom bar from appearing after we reverted all the changes we've made.

This works because when we save processor changes, the state machine receives an action step that can contain undefined values (those that we left empty while editing the processor). Because these undefined values aren't present in the previousStreamlangDSL, the equality check fails.

I can extract this and the changes in the state machines into a separate PR if there are concerns.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50885,9 +50885,6 @@
"xpack.streams.enrichment.processor.discardChanges.confirmButtonText": "Verwerfen",
"xpack.streams.enrichment.processor.discardChanges.message": "Möchten Sie Ihre Änderungen wirklich verwerfen?",
"xpack.streams.enrichment.processor.discardChanges.title": "Änderungen verwerfen?",
"xpack.streams.enrichment.processor.editDescription.cancelButtonLabel": "Abbrechen",
"xpack.streams.enrichment.processor.editDescription.fieldAriaLabel": "Beschreibung des Prozessors",
"xpack.streams.enrichment.processor.editDescription.helpText": "Erklären Sie diesen Schritt, da er die Metadaten überschreiben würde. Wenn Sie die Beschreibung entfernen, werden die Metadaten wieder angezeigt.",
"xpack.streams.enrichment.simulation.dateSuggestionsError": "Beim Abrufen der Vorschläge für Datumsformate ist ein Fehler aufgetreten.",
"xpack.streams.enrichment.simulation.simulationRunError": "Beim Ausführen der Simulation ist ein Problem aufgetreten.",
"xpack.streams.enrichment.yamlMode.runSimulationButton.ariaLabel": "Simulation ausführen",
Expand Down Expand Up @@ -51656,7 +51653,6 @@
"xpack.streams.streamDetailView.managementTab.bottomBar.onlySimulate": "Sie haben nicht die erforderlichen Berechtigungen, um Änderungen zu speichern.",
"xpack.streams.streamDetailView.managementTab.bottomBar.viewCode": "API-Anfrage anzeigen",
"xpack.streams.streamDetailView.managementTab.enrichment.addButtonText": "Erstellen",
"xpack.streams.streamDetailView.managementTab.enrichment.addDescriptionButtonText": "Beschreibung hinzufügen",
"xpack.streams.streamDetailView.managementTab.enrichment.appendProcessorDescription": "Hängt {value} an „{field}“ an",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionPlural": "Verkettet die Werte {fromLength}.",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionSingular": "Verkettet den Wert {fromLength}.",
Expand Down Expand Up @@ -51720,7 +51716,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.dissectProcessorFlyout.tryAgain": "Wiederholen",
"xpack.streams.streamDetailView.managementTab.enrichment.dropProcessorDescription": "Legt Dokumente ab",
"xpack.streams.streamDetailView.managementTab.enrichment.duplicateItemButtonText": "Duplikat",
"xpack.streams.streamDetailView.managementTab.enrichment.editDescriptionButtonText": "Beschreibung bearbeiten",
"xpack.streams.streamDetailView.managementTab.enrichment.editItemButtonText": "Bearbeiten",
"xpack.streams.streamDetailView.managementTab.enrichment.enrichProcessorDescription": "Daten mit der Richtlinie „{policy_name}“ anreichern",
"xpack.streams.streamDetailView.managementTab.enrichment.errorPanel.title": "{count, plural, one {# Validation error or issue} other {# Validation errors or issues}}",
Expand Down Expand Up @@ -51982,7 +51977,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.refreshSuggestions": "Muster generieren",
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.tryAgain": "Wiederholen",
"xpack.streams.streamDetailView.managementTab.enrichment.removeByPrefixProcessorDescription": "Entfernt {field} und alle verschachtelten Felder",
"xpack.streams.streamDetailView.managementTab.enrichment.removeDescriptionButtonText": "Beschreibung entfernen",
"xpack.streams.streamDetailView.managementTab.enrichment.removeProcessorDescription": "Entfernt {field}",
"xpack.streams.streamDetailView.managementTab.enrichment.renameProcessorDescription": "Benennt „{field}“ in „{newField}“ um.",
"xpack.streams.streamDetailView.managementTab.enrichment.saveChangesError": "Beim Speichern der Änderungen der Prozessoren ist ein Problem aufgetreten.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50715,9 +50715,6 @@
"xpack.streams.enrichment.processor.discardChanges.confirmButtonText": "Abandonner",
"xpack.streams.enrichment.processor.discardChanges.message": "Voulez-vous vraiment abandonner vos modifications ?",
"xpack.streams.enrichment.processor.discardChanges.title": "Abandonner les modifications ?",
"xpack.streams.enrichment.processor.editDescription.cancelButtonLabel": "Annuler",
"xpack.streams.enrichment.processor.editDescription.fieldAriaLabel": "Description du processeur",
"xpack.streams.enrichment.processor.editDescription.helpText": "Expliquez cette étape, cela écrasera les métadonnées. Si vous décidez de supprimer la description, les métadonnées réapparaîtront.",
"xpack.streams.enrichment.simulation.dateSuggestionsError": "Une erreur s'est produite lors de la récupération des suggestions de formats de date.",
"xpack.streams.enrichment.simulation.simulationRunError": "Un problème s'est produit lors de l'exécution de la simulation.",
"xpack.streams.enrichment.yamlMode.runSimulationButton.ariaLabel": "Exécuter la simulation",
Expand Down Expand Up @@ -51480,7 +51477,6 @@
"xpack.streams.streamDetailView.managementTab.bottomBar.onlySimulate": "Vous n'avez pas les privilèges suffisants pour enregistrer les modifications.",
"xpack.streams.streamDetailView.managementTab.bottomBar.viewCode": "Afficher la requête API",
"xpack.streams.streamDetailView.managementTab.enrichment.addButtonText": "Créer",
"xpack.streams.streamDetailView.managementTab.enrichment.addDescriptionButtonText": "Ajouter une description",
"xpack.streams.streamDetailView.managementTab.enrichment.appendProcessorDescription": "Ajoute {value} à \"{field}\"",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionPlural": "Concatène les valeurs {fromLength}.",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionSingular": "Concatène la valeur {fromLength}.",
Expand Down Expand Up @@ -51544,7 +51540,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.dissectProcessorFlyout.tryAgain": "Réessayer",
"xpack.streams.streamDetailView.managementTab.enrichment.dropProcessorDescription": "Abandonne des documents",
"xpack.streams.streamDetailView.managementTab.enrichment.duplicateItemButtonText": "Dupliquer",
"xpack.streams.streamDetailView.managementTab.enrichment.editDescriptionButtonText": "Modifier la description",
"xpack.streams.streamDetailView.managementTab.enrichment.editItemButtonText": "Modifier",
"xpack.streams.streamDetailView.managementTab.enrichment.enrichProcessorDescription": "Enrichir les données avec la politique \"{policy_name}\"",
"xpack.streams.streamDetailView.managementTab.enrichment.errorPanel.title": "{count, plural, one {# Validation error or issue} other {# Erreurs ou problèmes de validation}}",
Expand Down Expand Up @@ -51809,7 +51804,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.refreshSuggestions": "Générer un modèle",
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.tryAgain": "Réessayer",
"xpack.streams.streamDetailView.managementTab.enrichment.removeByPrefixProcessorDescription": "Supprime {field} et tous les champs imbriqués",
"xpack.streams.streamDetailView.managementTab.enrichment.removeDescriptionButtonText": "Supprimer la description",
"xpack.streams.streamDetailView.managementTab.enrichment.removeProcessorDescription": "Supprime {field}",
"xpack.streams.streamDetailView.managementTab.enrichment.renameProcessorDescription": "Renomme « {field} » en « {newField} »",
"xpack.streams.streamDetailView.managementTab.enrichment.saveChangesError": "Un problème a eu lieu lors de l'enregistrement des modifications des processeurs.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51073,9 +51073,6 @@
"xpack.streams.enrichment.processor.discardChanges.confirmButtonText": "破棄",
"xpack.streams.enrichment.processor.discardChanges.message": "変更を破棄しますか?",
"xpack.streams.enrichment.processor.discardChanges.title": "変更を破棄しますか?",
"xpack.streams.enrichment.processor.editDescription.cancelButtonLabel": "キャンセル",
"xpack.streams.enrichment.processor.editDescription.fieldAriaLabel": "プロセッサーの説明",
"xpack.streams.enrichment.processor.editDescription.helpText": "このステップについて説明します。これによりメタデータが上書きされます。説明を削除すると、メタデータが再び表示されます。",
"xpack.streams.enrichment.simulation.dateSuggestionsError": "日付形式の提案を取得中にエラーが発生しました。",
"xpack.streams.enrichment.simulation.simulationRunError": "シミュレーションの実行中に問題が発生しました。",
"xpack.streams.enrichment.yamlMode.runSimulationButton.ariaLabel": "シミュレーションを実行",
Expand Down Expand Up @@ -51844,7 +51841,6 @@
"xpack.streams.streamDetailView.managementTab.bottomBar.onlySimulate": "変更を保存するのに十分な権限がありません。",
"xpack.streams.streamDetailView.managementTab.bottomBar.viewCode": "APIリクエストを表示",
"xpack.streams.streamDetailView.managementTab.enrichment.addButtonText": "作成",
"xpack.streams.streamDetailView.managementTab.enrichment.addDescriptionButtonText": "説明を追加",
"xpack.streams.streamDetailView.managementTab.enrichment.appendProcessorDescription": "「{field}」の末尾に{value}を追加します",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionPlural": "{fromLength}の値を連結します。",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionSingular": "{fromLength}値を連結します。",
Expand Down Expand Up @@ -51908,7 +51904,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.dissectProcessorFlyout.tryAgain": "再試行",
"xpack.streams.streamDetailView.managementTab.enrichment.dropProcessorDescription": "ドキュメントをドロップします",
"xpack.streams.streamDetailView.managementTab.enrichment.duplicateItemButtonText": "複製",
"xpack.streams.streamDetailView.managementTab.enrichment.editDescriptionButtonText": "説明を編集",
"xpack.streams.streamDetailView.managementTab.enrichment.editItemButtonText": "編集",
"xpack.streams.streamDetailView.managementTab.enrichment.enrichProcessorDescription": "ポリシー「{policy_name}」でデータをエンリッチ",
"xpack.streams.streamDetailView.managementTab.enrichment.errorPanel.title": "{count, plural, one {# Validation error or issue} other {#件の検証エラーまたは問題}}",
Expand Down Expand Up @@ -52169,7 +52164,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.refreshSuggestions": "パターンを生成",
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.tryAgain": "再試行",
"xpack.streams.streamDetailView.managementTab.enrichment.removeByPrefixProcessorDescription": "{field}とネストされたすべてのフィールドを削除します",
"xpack.streams.streamDetailView.managementTab.enrichment.removeDescriptionButtonText": "説明を削除",
"xpack.streams.streamDetailView.managementTab.enrichment.removeProcessorDescription": "{field} を削除します",
"xpack.streams.streamDetailView.managementTab.enrichment.renameProcessorDescription": "「{field}」の名前を「{newField}」に変更します",
"xpack.streams.streamDetailView.managementTab.enrichment.saveChangesError": "プロセッサーの変更の保存中に問題が発生しました。",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51064,9 +51064,6 @@
"xpack.streams.enrichment.processor.discardChanges.confirmButtonText": "丢弃",
"xpack.streams.enrichment.processor.discardChanges.message": "是否确定要舍弃您的更改?",
"xpack.streams.enrichment.processor.discardChanges.title": "放弃更改?",
"xpack.streams.enrichment.processor.editDescription.cancelButtonLabel": "取消",
"xpack.streams.enrichment.processor.editDescription.fieldAriaLabel": "处理器说明",
"xpack.streams.enrichment.processor.editDescription.helpText": "解释这一步,这将覆盖元数据。如果您决定删除描述,元数据会重新显示出来。",
"xpack.streams.enrichment.simulation.dateSuggestionsError": "在获取日期格式建议时发生错误。",
"xpack.streams.enrichment.simulation.simulationRunError": "运行模拟时出现问题。",
"xpack.streams.enrichment.yamlMode.runSimulationButton.ariaLabel": "运行模拟",
Expand Down Expand Up @@ -51835,7 +51832,6 @@
"xpack.streams.streamDetailView.managementTab.bottomBar.onlySimulate": "您没有足够的权限来保存更改。",
"xpack.streams.streamDetailView.managementTab.bottomBar.viewCode": "查看 API 请求",
"xpack.streams.streamDetailView.managementTab.enrichment.addButtonText": "创建",
"xpack.streams.streamDetailView.managementTab.enrichment.addDescriptionButtonText": "添加描述",
"xpack.streams.streamDetailView.managementTab.enrichment.appendProcessorDescription": "将 {value} 追加到“{field}”字段",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionPlural": "串联 {fromLength} 个值。",
"xpack.streams.streamDetailView.managementTab.enrichment.concatProcessorDescriptionSingular": "串联 {fromLength} 个值。",
Expand Down Expand Up @@ -51899,7 +51895,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.dissectProcessorFlyout.tryAgain": "重试",
"xpack.streams.streamDetailView.managementTab.enrichment.dropProcessorDescription": "Drops文档",
"xpack.streams.streamDetailView.managementTab.enrichment.duplicateItemButtonText": "复制",
"xpack.streams.streamDetailView.managementTab.enrichment.editDescriptionButtonText": "编辑描述",
"xpack.streams.streamDetailView.managementTab.enrichment.editItemButtonText": "编辑",
"xpack.streams.streamDetailView.managementTab.enrichment.enrichProcessorDescription": "使用策略“{policy_name}”扩充数据",
"xpack.streams.streamDetailView.managementTab.enrichment.errorPanel.title": "{count, plural, one {# Validation error or issue} other {# 个验证错误或问题}}",
Expand Down Expand Up @@ -52162,7 +52157,6 @@
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.refreshSuggestions": "生成模式",
"xpack.streams.streamDetailView.managementTab.enrichment.processorFlyout.tryAgain": "重试",
"xpack.streams.streamDetailView.managementTab.enrichment.removeByPrefixProcessorDescription": "移除 {field} 和所有嵌套字段",
"xpack.streams.streamDetailView.managementTab.enrichment.removeDescriptionButtonText": "删除说明",
"xpack.streams.streamDetailView.managementTab.enrichment.removeProcessorDescription": "移除 {field}",
"xpack.streams.streamDetailView.managementTab.enrichment.renameProcessorDescription": "将“{field}”重命名为“{newField}”",
"xpack.streams.streamDetailView.managementTab.enrichment.saveChangesError": "保存处理器的更改时出现问题。",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ export const interactiveModeMachine = setup({
'step.change': {
actions: [
{ type: 'reassignSteps' },
{ type: 'syncToDSL' },
{ type: 'sendStepsToSimulator', params: ({ event }) => event },
],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { isEqual, isUndefined, omitBy } from 'lodash';
import type { ActorRefFrom, SnapshotFrom } from 'xstate';
import { and, assign, forwardTo, sendTo, setup } from 'xstate';
import type {
Expand All @@ -18,6 +19,15 @@ import type { StepContext, StepEvent, StepInput } from './types';
export type StepActorRef = ActorRefFrom<typeof stepMachine>;
export type StepActorSnapshot = SnapshotFrom<typeof stepMachine>;

// Strips customIdentifier and undefined values from a step
const sanitiseStep = ({ customIdentifier, ...restOfStep }: StreamlangStepWithUIAttributes) =>
omitBy(restOfStep, isUndefined);

const isStepUpdated = (
step: StreamlangStepWithUIAttributes,
originalStep: StreamlangStepWithUIAttributes
): boolean => !isEqual(sanitiseStep(step), sanitiseStep(originalStep));

export const stepMachine = setup({
types: {
input: {} as StepInput,
Expand Down Expand Up @@ -73,7 +83,7 @@ export const stepMachine = setup({
return {
step: updatedStep,
previousStep: updatedStep,
isUpdated: true,
isUpdated: isStepUpdated(updatedStep, context.originalStep),
};
}),
changeParent: assign(
Expand All @@ -90,7 +100,7 @@ export const stepMachine = setup({
return {
step: updatedStep,
previousStep: updatedStep,
isUpdated: true,
isUpdated: isStepUpdated(updatedStep, context.originalStep),
};
}
),
Expand All @@ -99,7 +109,7 @@ export const stepMachine = setup({
})),
markAsUpdated: assign(({ context }) => ({
previousStep: context.step,
isUpdated: true,
isUpdated: isStepUpdated(context.step, context.originalStep),
})),
forwardEventToParent: forwardTo(({ context }) => context.parentRef),
notifyStepSave: sendTo(
Expand Down Expand Up @@ -172,6 +182,7 @@ export const stepMachine = setup({
id: 'processor',
context: ({ input }) => ({
parentRef: input.parentRef,
originalStep: input.step,
previousStep: input.step,
step: input.step,
isNew: input.isNew ?? false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type StepParentActor = Omit<AnyActorRef, 'send'> & {

export interface StepContext {
parentRef: StepParentActor;
originalStep: StreamlangStepWithUIAttributes;
previousStep: StreamlangStepWithUIAttributes;
step: StreamlangStepWithUIAttributes;
isNew: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
streamlangDSLSchemaStrict,
type StreamlangDSL,
} from '@kbn/streamlang/types/streamlang';
import { isEqual } from 'lodash';
import type {
EnrichmentDataSource,
EnrichmentUrlState,
Expand Down Expand Up @@ -728,9 +729,9 @@ const hasChanges = (nextStreamlangDSL: StreamlangDSL, previousStreamlangDSL: Str
if (!isValidSchema) {
return true;
} else {
return (
JSON.stringify(sanitiseForEditing(nextStreamlangDSL)) !==
JSON.stringify(sanitiseForEditing(previousStreamlangDSL))
return !isEqual(
sanitiseForEditing(nextStreamlangDSL),
sanitiseForEditing(previousStreamlangDSL)
Comment on lines +732 to +734
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StreamlangDSL might have the same object and properties, but their order might be different. This causes the equality check to fail when we convert them to strings.

);
}
};
Loading
Loading