home-assistant / frontend

:lollipop: Frontend for Home Assistant
https://demo.home-assistant.io
Other
4.13k stars 2.82k forks source link

Config Flow: SelectSelectorConfig does not display the saved selected item inside a section #22590

Open EnzoD86 opened 1 month ago

EnzoD86 commented 1 month ago

Checklist

Describe the issue you are experiencing

Hi, I have a ConfigFlow with a section inside that contains a SelectSelectorConfig. When I select an item and save the changes, when I reopen the configuration, the data that was selected is no longer selected (even though this was actually saved correctly).

Describe the behavior you expected

-

Steps to reproduce the issue

Here is an example of the saved data (including 2 BooleanSelectors). As you can see when you reopen the config flow, the BooleanSelectors keep the selected values ​​while the SelectSelectorConfig does not.

image

What version of Home Assistant Core has the issue?

2024.10.4

What was the last working version of Home Assistant Core?

No response

In which browser are you experiencing the issue with?

No response

Which operating system are you using to run this browser?

No response

State of relevant entities

No response

Problem-relevant frontend configuration

No response

Javascript errors shown in your browser console/inspector

No response

Additional information

No response

karwosts commented 1 month ago

Can you share the code of your config flow that's exhibiting this problem?

EnzoD86 commented 1 month ago

Hi, thanks for the quick reply; I created a configuration flow that reproduces the problem, let me know if you need anything else.

config_flow.py

import logging
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.data_entry_flow import section
from homeassistant.helpers.selector import (
    BooleanSelector,
    SelectSelector,
    SelectSelectorConfig,
    SelectSelectorMode,
    TextSelector,
    TextSelectorConfig,
    TextSelectorType
)
from homeassistant.const import CONF_NAME
from .const import DOMAIN

_LOGGER = logging.getLogger(__package__)

class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
    async def async_step_user(self, user_input):
        if user_input is not None:
            return self.async_create_entry(title=user_input[CONF_NAME], data=user_input)

        data_schema = {
            vol.Required(CONF_NAME): TextSelector(
                TextSelectorConfig(type=TextSelectorType.TEXT)
            ),
            "additional_options": section(
                vol.Schema(
                    {
                        vol.Optional("test1", default="Test1"): SelectSelector(
                            SelectSelectorConfig(options=['Test1', 'Test2', 'Test3'], multiple=False, mode=SelectSelectorMode.LIST)
                        ),
                        vol.Optional("test2", default=False): BooleanSelector(),
                        vol.Optional("test3", default=False): BooleanSelector()
                    }
                ),
                {"collapsed": False},
            )
        }
        return self.async_show_form(step_id="user", data_schema=vol.Schema(data_schema))

    @staticmethod
    @callback
    def async_get_options_flow(config_entry):
        return OptionsFlowHandler(config_entry)

class OptionsFlowHandler(config_entries.OptionsFlow):
    def __init__(self, config_entry):
        self.config_entry = config_entry

    async def async_step_init(self, user_input):
        return await self.async_step_user(user_input)

    async def async_step_user(self, user_input):
        if user_input is not None:
            self.hass.config_entries.async_update_entry(
                self.config_entry, data=self.config_entry.data | user_input
            )
            return self.async_create_entry(title="", data={})

        config = {**self.config_entry.data, **self.config_entry.options}   
        additional_options = config.get("additional_options", {})

        data_schema = {
            "additional_options": section(
                vol.Schema(
                    {
                        vol.Optional("test1", default=additional_options.get("test1", "Test1")): SelectSelector(
                            SelectSelectorConfig(options=['Test1', 'Test2', 'Test3'], multiple=False, mode=SelectSelectorMode.LIST)
                        ),
                        vol.Optional("test2", default=additional_options.get("test2", False)): BooleanSelector(),
                        vol.Optional("test3", default=additional_options.get("test3", False)): BooleanSelector()
                    }
                ),
                {"collapsed": False},
            )
        }
        return self.async_show_form(step_id="user", data_schema=vol.Schema(data_schema))

en.json

{
  "config": {
    "step": {
      "user": {
        "title": "Test",
        "data": {
          "name": "Name"
        },
        "sections": {
          "additional_options": {
            "name": "Test section",
            "data": {
              "test1": "Test select selector",
              "test2": "Test boolean selector",
              "test3": "Test boolean selector"
            }
          }
        }
      }
    }
  },
  "options": {
    "step": {
      "user": {
        "title": "Test",
        "sections": {
          "additional_options": {
            "name": "Test section",
            "data": {
              "test1": "Test select selector",
              "test2": "Test boolean selector",
              "test3": "Test boolean selector"
            }
          }
        }
      }
    }
  }
}
karwosts commented 1 month ago

So I tried this out w/ kitchen_sink integration (a dummy/testing integration), and I couldn't find a problem.

If I run options flow and select a value in the selector, and save, and run options flow again, the previously selected item is populated.

If you have a core dev environment, do you want to try running this PR (https://github.com/home-assistant/core/pull/129503), and see if it's working as you would expect? Maybe you can compare the code difference between the two to see if anything is missing.

I don't see anything obviously wrong in your code, but I am not an expert in config flows.

EnzoD86 commented 1 month ago

Hi, I can't do this kind of test at the moment, because I don't have a development environment. I'll try to put it up as soon as I have some time Thanks for looking anyway!

dummylabs commented 2 weeks ago

The working solution is given in #22419. PR to fix documentation: https://github.com/home-assistant/developers.home-assistant/pull/2454