Repository: kestra-io/kestra
Issue: [UI] Boolean input always have a value
Labels: bug

### Expected Behavior

Boolean inputs should be able to have no value.

### Actual Behaviour

When executing a flow that have a boolean input from the UI, the execution will always have a value for the input even if it has a default value or is not mandatory.
This is because the UI uses a Switch with true/false so no-value or undefined didn't exist.

As the input is always send, if it's optional or with a default value of true, it will be set to false which is not what we want.

### Steps To Reproduce

_No response_

### Environment Information

- Kestra Version:
- Operating System (OS / Docker / Kubernetes):
- Java Version (If not docker):


### Example flow

Launching this flow from the UI will output false in the logs whereas true should be outputted as the default of the input is true.

```
id: hello-world
namespace: dev
inputs:
  - name: clear_landing_before
    type: BOOLEAN
    required: true
    defaults: true
tasks:
  - id: echo_input
    type: io.kestra.core.tasks.debugs.Echo
    format: "{{inputs.clear_landing_before}}"
```

Issue comments:

Pull request review comments:
Avoid console logging (twice)
```suggestion
                if (input.type === "BOOLEAN" && input.defaults === undefined){
```
```suggestion
                    <el-radio-button :label="$t('true')" />
                    <el-radio-button :label="$t('false')" />
                    <el-radio-button :label="$t('undefined')"/>
```

Patch that resolved the issue:
diff --git a/ui/src/components/flows/FlowRun.vue b/ui/src/components/flows/FlowRun.vue
index a66721107d..ad3fc6bed5 100644
--- a/ui/src/components/flows/FlowRun.vue
+++ b/ui/src/components/flows/FlowRun.vue
@@ -36,10 +36,14 @@
                     v-model="inputs[input.name]"
                     :step="0.001"
                 />
-                <el-switch
+                <el-radio-group
                     v-if="input.type === 'BOOLEAN'"
                     v-model="inputs[input.name]"
-                />
+                >
+                    <el-radio-button label="true" />
+                    <el-radio-button label="false" />
+                    <el-radio-button label="undefined" />
+                </el-radio-group>
                 <el-date-picker
                     v-if="input.type === 'DATETIME'"
                     v-model="inputs[input.name]"
@@ -146,8 +150,8 @@
             for (const input of this.flow.inputs || []) {
                 this.inputs[input.name] = input.defaults;
 
-                if (input.type === "BOOLEAN" && input.defaults){
-                    this.inputs[input.name] = (/true/i).test(input.defaults) || input.defaults === true;
+                if (input.type === "BOOLEAN" && input.defaults === undefined){
+                    this.inputs[input.name] = "undefined";
                 }
             }
         },
@@ -177,6 +181,16 @@
             ...mapState("execution", ["execution"]),
             haveBadLabels() {
                 return this.executionLabels.some(label => (label.key && !label.value) || (!label.key && label.value));
+            },
+            // Required to have "undefined" value for boolean
+            cleanInputs() {
+                var inputs = this.inputs
+                for (const input of this.flow.inputs || []) {
+                    if (input.type === "BOOLEAN" && inputs[input.name] === "undefined") {
+                        inputs[input.name] = undefined;
+                    }
+                }
+                return inputs;
             }
         },
         methods: {
@@ -210,7 +224,7 @@
                             return false;
                         }
 
-                        executeTask(this, this.flow, this.inputs, {
+                        executeTask(this, this.flow, this.cleanInputs, {
                             redirect: this.redirect,
                             id: this.flow.id,
                             namespace: this.flow.namespace,


Test patch: