From 9b7bcb7e785cab0231ec59d92aeb8cd2ebc2dd4d Mon Sep 17 00:00:00 2001 From: Michael Oppitz Date: Wed, 22 Jul 2026 13:05:42 +0200 Subject: [PATCH] SS-9900: fixed export form --- .../mergeFormExportParameterValues.test.ts | 48 +++++++++++++++++++ .../lib/mergeFormExportParameterValues.ts | 21 ++++++++ .../ui/AppBuilderFormWidgetComponent.tsx | 20 ++++---- 3 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 widgets/appbuilder/lib/mergeFormExportParameterValues.test.ts diff --git a/widgets/appbuilder/lib/mergeFormExportParameterValues.test.ts b/widgets/appbuilder/lib/mergeFormExportParameterValues.test.ts new file mode 100644 index 00000000..4ce11343 --- /dev/null +++ b/widgets/appbuilder/lib/mergeFormExportParameterValues.test.ts @@ -0,0 +1,48 @@ +import { + createFormExportParameterValue, + mergeFormExportParameterValues, +} from "./mergeFormExportParameterValues"; + +describe("createFormExportParameterValue", () => { + it("uses the parameter id rather than its display name as the export key", () => { + const value = createFormExportParameterValue( + "8c03f4ca-cc79-4f14-9a17-6ae1a1e5c1e1", + "default", + "default", + "make it funny", + ); + + expect(value).toEqual({ + name: "8c03f4ca-cc79-4f14-9a17-6ae1a1e5c1e1", + value: "make it funny", + }); + }); + + it("keeps a non-default parameter namespace", () => { + expect( + createFormExportParameterValue( + "parameter-id", + "other", + "default", + "value", + ), + ).toEqual({name: "parameter-id", sessionId: "other", value: "value"}); + }); +}); + +describe("mergeFormExportParameterValues", () => { + it("includes form values with their stable parameter ids", () => { + expect( + mergeFormExportParameterValues(undefined, [ + createFormExportParameterValue( + "parameter-id", + "default", + "default", + "make it funny", + ), + ]), + ).toEqual([ + {parameter: {name: "parameter-id"}, value: "make it funny"}, + ]); + }); +}); diff --git a/widgets/appbuilder/lib/mergeFormExportParameterValues.ts b/widgets/appbuilder/lib/mergeFormExportParameterValues.ts index 35904f53..f00d6979 100644 --- a/widgets/appbuilder/lib/mergeFormExportParameterValues.ts +++ b/widgets/appbuilder/lib/mergeFormExportParameterValues.ts @@ -6,6 +6,27 @@ export interface FormWidgetParameterValue { readonly value: string; } +/** + * Builds an export parameter value from a form field. + * + * Export requests use parameter ids as keys. A display name can contain spaces + * and is not a stable request identifier, so it must not be used here. + */ +export function createFormExportParameterValue( + parameterId: string, + parameterNamespace: string, + formNamespace: string, + value: string, +): FormWidgetParameterValue { + return { + name: parameterId, + ...(parameterNamespace !== formNamespace + ? {sessionId: parameterNamespace} + : {}), + value, + }; +} + /** * Merges export-control parameter values with form field values for form submit. * Export values are applied first; form values add missing parameters or override by name. diff --git a/widgets/appbuilder/ui/AppBuilderFormWidgetComponent.tsx b/widgets/appbuilder/ui/AppBuilderFormWidgetComponent.tsx index d0594a53..25c5caca 100644 --- a/widgets/appbuilder/ui/AppBuilderFormWidgetComponent.tsx +++ b/widgets/appbuilder/ui/AppBuilderFormWidgetComponent.tsx @@ -39,7 +39,10 @@ import { useMemo, useState, } from "react"; -import {mergeFormExportParameterValues} from "../lib/mergeFormExportParameterValues"; +import { + createFormExportParameterValue, + mergeFormExportParameterValues, +} from "../lib/mergeFormExportParameterValues"; /** * @docAttached @@ -206,14 +209,13 @@ export default function AppBuilderFormWidgetComponent(props: Props) { return undefined; } const ref = parameterProps[index]; - const sessionId = - ref.namespace !== namespace ? ref.namespace : undefined; - - return { - name: param.definition.name, - sessionId, - value: String(values[param.definition.id] ?? ""), - }; + + return createFormExportParameterValue( + param.definition.id, + ref.namespace, + namespace, + String(values[param.definition.id] ?? ""), + ); }) .filter((entry) => entry !== undefined); }, [parameters, parameterProps, values, namespace]);