Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
22 changes: 21 additions & 1 deletion src/components/FormSelectList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export default {
selectedOption: null,
loading: false,
loaded: false,
dataObjectOptionsPending: false,
previousDependentValue: null,
filter: "",
countWithoutFilter: null
Expand Down Expand Up @@ -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;
},
Expand Down Expand Up @@ -493,6 +494,7 @@ export default {
requestOptions = [];
}

this.dataObjectOptionsPending = requestOptions === null || requestOptions === undefined;
const list = requestOptions || [];
this.selectListOptions = this.transformOptions(list);
wasUpdated = true;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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
Expand Down
95 changes: 95 additions & 0 deletions tests/unit/FormSelectListDataObject.spec.js
Original file line number Diff line number Diff line change
@@ -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"]]);
});
});
Loading