fix: custom variable typed variable default value main (#12549)

This commit is contained in:
Abhay Padamani
2026-06-10 11:04:00 +00:00
committed by GitHub
parent 96f6ea0d70
commit 60b9f882c3
4 changed files with 194 additions and 8 deletions
@@ -442,6 +442,98 @@ describe("VariablesValueSelector", () => {
expect(testVariable.value).toEqual(["value1", "value2"]);
});
it("should select the option marked as default (selected) for single-select custom variables", async () => {
// Regression: previously the first option was always used on initial load,
// ignoring the per-option "Default" checkbox (option.selected).
const customConfig = {
list: [
{
name: "custom_stream",
type: "custom",
multiSelect: false,
options: [
{ label: "e2e_automate", value: "e2e_automate", selected: false },
{ label: "default", value: "default", selected: true },
],
},
],
};
wrapper = createWrapper({
variablesConfig: customConfig,
initialVariableValues: { value: {} },
});
await nextTick();
const vm = wrapper.vm as any;
const testVariable = vm.variablesData.values.find(
(v: any) => v.name === "custom_stream",
);
// Should pick the default-marked option ("default"), not the first option
expect(testVariable.value).toBe("default");
});
it("should select the options marked as default (selected) for multiSelect custom variables", async () => {
const customConfig = {
list: [
{
name: "custom_multi",
type: "custom",
multiSelect: true,
options: [
{ label: "one", value: "one", selected: false },
{ label: "two", value: "two", selected: true },
{ label: "three", value: "three", selected: true },
],
},
],
};
wrapper = createWrapper({
variablesConfig: customConfig,
initialVariableValues: { value: {} },
});
await nextTick();
const vm = wrapper.vm as any;
const testVariable = vm.variablesData.values.find(
(v: any) => v.name === "custom_multi",
);
// Should pick all default-marked options, not just the first
expect(testVariable.value).toEqual(["two", "three"]);
});
it("should fall back to first option for custom variables when none are marked default", async () => {
const customConfig = {
list: [
{
name: "custom_no_default",
type: "custom",
multiSelect: false,
options: [
{ label: "alpha", value: "alpha", selected: false },
{ label: "beta", value: "beta", selected: false },
],
},
],
};
wrapper = createWrapper({
variablesConfig: customConfig,
initialVariableValues: { value: {} },
});
await nextTick();
const vm = wrapper.vm as any;
const testVariable = vm.variablesData.values.find(
(v: any) => v.name === "custom_no_default",
);
expect(testVariable.value).toBe("alpha");
});
it("should handle SELECT_ALL value for multiSelect variables", async () => {
const customConfig = {
list: [
@@ -873,7 +873,8 @@ export default defineComponent({
? [SELECT_ALL_VALUE]
: SELECT_ALL_VALUE;
} else if (item.type === "custom") {
// For custom type variables, set first option as default if no initial value
// For custom type variables, honor the per-option default (the "Default"
// checkbox in variable settings, stored as `option.selected`) if no initial value
if (
initialValue !== null &&
initialValue !== undefined &&
@@ -882,10 +883,24 @@ export default defineComponent({
// Use initial value if it exists
variableData.value = initialValue;
} else if (variableData.options && variableData.options.length > 0) {
// Set first option as default value
variableData.value = item.multiSelect
? [variableData.options[0].value]
: variableData.options[0].value;
// Collect options explicitly marked as default
const defaultOptionValues = variableData.options
.filter((option: any) => option.selected)
.map((option: any) => option.value);
if (item.multiSelect) {
// Use all default-marked options, fall back to first option
variableData.value =
defaultOptionValues.length > 0
? defaultOptionValues
: [variableData.options[0].value];
} else {
// Use the default-marked option, fall back to first option
variableData.value =
defaultOptionValues.length > 0
? defaultOptionValues[0]
: variableData.options[0].value;
}
} else {
// No options available, set to null/empty array
variableData.value = item.multiSelect ? [] : null;
@@ -97,6 +97,74 @@ describe("useVariablesManager", () => {
expect(manager.variablesData.panels["panel-2"][0].panelId).toBe("panel-2");
});
it("should use the option marked as default (selected) for single-select custom variables", () => {
// Regression: previously the first option was always used as the default,
// ignoring the per-option "Default" checkbox (option.selected).
const manager = useVariablesManager();
const config: VariableConfig[] = [
{
name: "custom_stream",
type: "custom",
scope: "panels",
panels: ["panel-1"],
multiSelect: false,
value: "",
options: [
{ label: "e2e_automate", value: "e2e_automate", selected: false },
{ label: "default", value: "default", selected: true },
],
},
];
manager.initialize(config, {});
// Should resolve to the default-marked option ("default"), not the first option
expect(manager.variablesData.panels["panel-1"][0].value).toBe("default");
});
it("should use options marked as default (selected) for multiSelect custom variables", () => {
const manager = useVariablesManager();
const config: VariableConfig[] = [
{
name: "custom_multi",
type: "custom",
scope: "global",
multiSelect: true,
value: "",
options: [
{ label: "one", value: "one", selected: false },
{ label: "two", value: "two", selected: true },
{ label: "three", value: "three", selected: true },
],
},
];
manager.initialize(config, {});
expect(manager.variablesData.global[0].value).toEqual(["two", "three"]);
});
it("should fall back to the first option when no custom option is marked default", () => {
const manager = useVariablesManager();
const config: VariableConfig[] = [
{
name: "custom_no_default",
type: "custom",
scope: "global",
multiSelect: false,
value: "",
options: [
{ label: "alpha", value: "alpha", selected: false },
{ label: "beta", value: "beta", selected: false },
],
},
];
manager.initialize(config, {});
expect(manager.variablesData.global[0].value).toBe("alpha");
});
it("should migrate legacy variables to global scope", () => {
const manager = useVariablesManager();
const config: any[] = [
@@ -106,12 +106,23 @@ const expandVariablesForScopes = (
}
}
// For custom type variables, select first option as default
// For custom type variables, honor the per-option default (the "Default"
// checkbox in variable settings, stored as `option.selected`); fall back to
// the first option only when none is marked as default.
if (variable.type === "custom") {
const options = (variable as any).options;
if (options && options.length > 0) {
return variable.multiSelect
? [options[0].value]
const defaultOptionValues = options
.filter((option: any) => option.selected)
.map((option: any) => option.value);
if (variable.multiSelect) {
return defaultOptionValues.length > 0
? defaultOptionValues
: [options[0].value];
}
return defaultOptionValues.length > 0
? defaultOptionValues[0]
: options[0].value;
}
}