diff --git a/src/openforms/js/components/admin/form_design/variables/utils.js b/src/openforms/js/components/admin/form_design/variables/utils.js index 393e75cf49..c4ec01238a 100644 --- a/src/openforms/js/components/admin/form_design/variables/utils.js +++ b/src/openforms/js/components/admin/form_design/variables/utils.js @@ -84,13 +84,26 @@ const shouldNotUpdateVariables = (newComponent, oldComponent, mutationType, step return isComponentWithVariable || isEditGridChild; }; +/** + * Transform the Formio configuration into FormVariable instances. + * @param {String} formDefinition API resource of the form definition that the configuration belongs to. + * @param {OBject} configuration The Formio form configuration. + */ const getFormVariables = (formDefinition, configuration) => { const newFormVariables = []; FormioUtils.eachComponent(configuration.components, component => { if (component.type === 'softRequiredErrors') return; + + // sEE #5035 - the client side upload components variables are created on load, and + // then they get pushed to the server on save and are persisted too, which causes + // upload issues. This may even have been the root cause of this issue where + // "phantom" variables show up in the step data. + if (isInEditGrid(component, configuration)) return; + newFormVariables.push(makeNewVariableFromComponent(component, formDefinition)); }); + return newFormVariables; }; diff --git a/src/openforms/submissions/models/submission.py b/src/openforms/submissions/models/submission.py index 8592e308c2..1fa6c42d4d 100644 --- a/src/openforms/submissions/models/submission.py +++ b/src/openforms/submissions/models/submission.py @@ -2,6 +2,7 @@ import logging import uuid +from copy import deepcopy from dataclasses import dataclass from typing import TYPE_CHECKING, Any, Mapping @@ -429,9 +430,8 @@ def total_configuration_wrapper(self) -> FormioConfigurationWrapper: if len(form_steps) == 0: return FormioConfigurationWrapper(configuration={}) - wrapper = FormioConfigurationWrapper( - form_steps[0].form_definition.configuration - ) + begin_configuration = deepcopy(form_steps[0].form_definition.configuration) + wrapper = FormioConfigurationWrapper(begin_configuration) for form_step in form_steps[1:]: wrapper += form_step.form_definition.configuration_wrapper self._total_configuration_wrapper = wrapper diff --git a/src/openforms/submissions/tests/test_models.py b/src/openforms/submissions/tests/test_models.py index 282059960f..c6c5550844 100644 --- a/src/openforms/submissions/tests/test_models.py +++ b/src/openforms/submissions/tests/test_models.py @@ -456,3 +456,54 @@ def test_names_do_not_break_pdf_saving_to_disk(self): report.generate_submission_report_pdf() self.assertTrue(report.content.storage.exists(report.content.name)) + + @tag("gh-5035") + def test_total_configuration_wrapper_does_not_mutate_first_step(self): + form = FormFactory.create( + generate_minimal_setup=True, + formstep__form_definition__configuration={ + "components": [ + { + "key": "textfield1", + "type": "textfield", + "label": "textfield", + } + ] + }, + ) + FormStepFactory.create( + form=form, + order=1, + form_definition__configuration={ + "components": [ + { + "key": "textfield2", + "type": "textfield", + "label": "Text field 2", + } + ] + }, + ) + submission = SubmissionFactory.create(form=form) + + configuration_wrapper = submission.total_configuration_wrapper + + with self.subTest("all keys present"): + self.assertIn("textfield1", configuration_wrapper) + self.assertIn("textfield2", configuration_wrapper) + + step1, step2 = submission.steps + + with self.subTest("step 1 keys"): + step1_keys = [ + c["key"] + for c in step1.form_step.form_definition.configuration["components"] + ] + self.assertEqual(step1_keys, ["textfield1"]) + + with self.subTest("step 2 keys"): + step2_keys = [ + c["key"] + for c in step2.form_step.form_definition.configuration["components"] + ] + self.assertEqual(step2_keys, ["textfield2"])