From 9643b03578287fa49ebbc3e82995403a4ceabdb6 Mon Sep 17 00:00:00 2001 From: Eleazar Resendez Date: Mon, 15 Jun 2026 09:31:16 -0600 Subject: [PATCH] FOUR-22083: Preserve data object select values on refresh --- src/components/FormSelectList.vue | 22 ++++- tests/unit/FormSelectListDataObject.spec.js | 95 +++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 tests/unit/FormSelectListDataObject.spec.js diff --git a/src/components/FormSelectList.vue b/src/components/FormSelectList.vue index 678dd873..ed1d0232 100644 --- a/src/components/FormSelectList.vue +++ b/src/components/FormSelectList.vue @@ -107,6 +107,7 @@ export default { selectedOption: null, loading: false, loaded: false, + dataObjectOptionsPending: false, previousDependentValue: null, filter: "", countWithoutFilter: null @@ -178,7 +179,7 @@ export default { this.addObjectContentProp(item); }); } - return this.areItemsInSelectListOptions(newValue) ? this.value : []; + return this.shouldPreservePendingDataObjectValue(newValue) || this.areItemsInSelectListOptions(newValue) ? this.value : []; } return this.value; }, @@ -493,6 +494,7 @@ export default { requestOptions = []; } + this.dataObjectOptionsPending = requestOptions === null || requestOptions === undefined; const list = requestOptions || []; this.selectListOptions = this.transformOptions(list); wasUpdated = true; @@ -666,6 +668,10 @@ export default { * @param {boolean} resetValueIfNotInOptions */ updateWatcherDependentFieldValue(resetValueIfNotInOptions) { + if (this.shouldPreservePendingDataObjectValue(this.value)) { + return; + } + let hasKeyInOptions = true; if (Array.isArray(this.value)) { @@ -693,6 +699,20 @@ export default { this.$emit("reset", this.name); } }, + hasValue(value) { + if (Array.isArray(value)) { + return value.length > 0; + } + return value !== null && value !== undefined && value !== ""; + }, + shouldPreservePendingDataObjectValue(value) { + return ( + this.options.dataSource === "dataObject" && + this.dataObjectOptionsPending && + this.selectListOptions.length === 0 && + this.hasValue(value) + ); + }, /** * Returns true if one or more items in list (an array) are in Select List's options * @param {array} list diff --git a/tests/unit/FormSelectListDataObject.spec.js b/tests/unit/FormSelectListDataObject.spec.js new file mode 100644 index 00000000..c2b4ee05 --- /dev/null +++ b/tests/unit/FormSelectListDataObject.spec.js @@ -0,0 +1,95 @@ +import { shallowMount } from "@vue/test-utils"; +import FormSelectList from "../../src/components/FormSelectList.vue"; + +describe("FormSelectList data object options", () => { + const $t = () => {}; + const dataObjectOptions = { + allowMultiSelect: true, + dataName: "albumData", + dataSource: "dataObject", + key: "id", + renderAs: "dropdown", + value: "title", + valueTypeReturned: "single" + }; + + const nextTicks = async (wrapper) => { + await wrapper.vm.$nextTick(); + await wrapper.vm.$nextTick(); + }; + + const factory = (propsData, getScreenData) => + shallowMount(FormSelectList, { + mocks: { $t }, + propsData: { + name: "informationObtained", + ...propsData + }, + methods: { + makeProxyData: getScreenData + } + }); + + it("keeps draft values while data object options are pending", async () => { + const wrapper = factory( + { + value: ["2", "3"], + options: dataObjectOptions + }, + () => ({ albumData: null }) + ); + + await nextTicks(wrapper); + + expect(wrapper.vm.dataObjectOptionsPending).toBe(true); + expect(wrapper.vm.selectListOptions).toEqual([]); + expect(wrapper.vm.valueProxy).toEqual(["2", "3"]); + expect(wrapper.emitted().reset).toBeUndefined(); + expect(wrapper.emitted().input).toBeUndefined(); + }); + + it("resolves preserved draft values after data object options load", async () => { + const screenData = { albumData: null }; + const wrapper = factory( + { + value: ["2", "3"], + options: dataObjectOptions + }, + () => screenData + ); + + await nextTicks(wrapper); + + screenData.albumData = [ + { id: "2", title: "sunt qui excepturi placeat culpa" }, + { id: "3", title: "omnis laborum odio" } + ]; + await wrapper.vm.fillSelectListOptions(true); + await nextTicks(wrapper); + + expect(wrapper.vm.dataObjectOptionsPending).toBe(false); + expect(wrapper.vm.selectListOptions).toHaveLength(2); + expect(wrapper.vm.valueProxy).toEqual(["2", "3"]); + expect(wrapper.emitted().reset).toBeUndefined(); + }); + + it("resets invalid values once data object options are available", async () => { + const wrapper = factory( + { + value: ["999"], + options: dataObjectOptions + }, + () => ({ + albumData: [ + { id: "2", title: "sunt qui excepturi placeat culpa" }, + { id: "3", title: "omnis laborum odio" } + ] + }) + ); + + await nextTicks(wrapper); + + expect(wrapper.vm.dataObjectOptionsPending).toBe(false); + expect(wrapper.emitted().reset).toEqual([["informationObtained"]]); + }); +});