Explorar o código

Use async_show_menu for options flow entry point

Replaces the radio-button init form with HA's native menu UI.
Each section now initializes _pending_options when it displays
its form, since the menu dispatches directly to step handlers.
ZiB hai 4 meses
pai
achega
7ccae52ddb

+ 5 - 24
custom_components/room_cal_ha/config_flow.py

@@ -160,31 +160,9 @@ class RoomCalOptionsFlow(OptionsFlow):
   async def async_step_init(
   async def async_step_init(
     self, user_input: dict[str, Any] | None = None
     self, user_input: dict[str, Any] | None = None
   ) -> ConfigFlowResult:
   ) -> ConfigFlowResult:
-    if user_input is not None:
-      self._pending_options = {**self.config_entry.options}
-      section = user_input["section"]
-      if section == "sync":
-        return await self.async_step_sync_mode()
-      if section == "defaults":
-        return await self.async_step_defaults()
-      return await self.async_step_locks()
-
-    opts = self.config_entry.options
-    current_mode = opts.get(CONF_SYNC_MODE, SYNC_MODE_MANUAL)
-    return self.async_show_form(
+    return self.async_show_menu(
       step_id="init",
       step_id="init",
-      data_schema=vol.Schema({
-        vol.Required("section"): SelectSelector(
-          SelectSelectorConfig(
-            options=[
-              {"value": "sync", "label": f"Sync Mode & Connection (currently: {current_mode})"},
-              {"value": "defaults", "label": "Reservation Defaults"},
-              {"value": "locks", "label": "Z-Wave Locks"},
-            ],
-            mode=SelectSelectorMode.LIST,
-          )
-        ),
-      }),
+      menu_options=["sync_mode", "defaults", "locks"],
     )
     )
 
 
   async def async_step_sync_mode(
   async def async_step_sync_mode(
@@ -199,6 +177,7 @@ class RoomCalOptionsFlow(OptionsFlow):
         return await self.async_step_api()
         return await self.async_step_api()
       return self.async_create_entry(data=self._pending_options)
       return self.async_create_entry(data=self._pending_options)
 
 
+    self._pending_options = {**self.config_entry.options}
     opts = self.config_entry.options
     opts = self.config_entry.options
     return self.async_show_form(
     return self.async_show_form(
       step_id="sync_mode",
       step_id="sync_mode",
@@ -338,6 +317,7 @@ class RoomCalOptionsFlow(OptionsFlow):
         self._pending_options[CONF_RESERVATION_DEFAULTS] = defaults
         self._pending_options[CONF_RESERVATION_DEFAULTS] = defaults
         return self.async_create_entry(data=self._pending_options)
         return self.async_create_entry(data=self._pending_options)
 
 
+    self._pending_options = {**self.config_entry.options}
     existing = self.config_entry.options.get(CONF_RESERVATION_DEFAULTS, {})
     existing = self.config_entry.options.get(CONF_RESERVATION_DEFAULTS, {})
     return self.async_show_form(
     return self.async_show_form(
       step_id="defaults",
       step_id="defaults",
@@ -362,6 +342,7 @@ class RoomCalOptionsFlow(OptionsFlow):
       self._pending_options[CONF_ZWAVE_SLOT] = int(slot) if slot is not None else None
       self._pending_options[CONF_ZWAVE_SLOT] = int(slot) if slot is not None else None
       return self.async_create_entry(data=self._pending_options)
       return self.async_create_entry(data=self._pending_options)
 
 
+    self._pending_options = {**self.config_entry.options}
     opts = self.config_entry.options
     opts = self.config_entry.options
     return self.async_show_form(
     return self.async_show_form(
       step_id="locks",
       step_id="locks",

+ 4 - 4
custom_components/room_cal_ha/strings.json

@@ -35,10 +35,10 @@
   "options": {
   "options": {
     "step": {
     "step": {
       "init": {
       "init": {
-        "title": "Configure Options",
-        "description": "Choose which settings to update.",
-        "data": {
-          "section": "Section"
+        "menu_options": {
+          "sync_mode": "Sync Mode & Connection",
+          "defaults": "Reservation Defaults",
+          "locks": "Z-Wave Locks"
         }
         }
       },
       },
       "sync_mode": {
       "sync_mode": {

+ 4 - 4
custom_components/room_cal_ha/translations/en.json

@@ -35,10 +35,10 @@
   "options": {
   "options": {
     "step": {
     "step": {
       "init": {
       "init": {
-        "title": "Configure Options",
-        "description": "Choose which settings to update.",
-        "data": {
-          "section": "Section"
+        "menu_options": {
+          "sync_mode": "Sync Mode & Connection",
+          "defaults": "Reservation Defaults",
+          "locks": "Z-Wave Locks"
         }
         }
       },
       },
       "sync_mode": {
       "sync_mode": {

+ 11 - 10
tests/test_config_flow.py

@@ -41,14 +41,15 @@ async def _options_init(hass: HomeAssistant, mock_entry):
   """Start an options flow; returns the init-step result."""
   """Start an options flow; returns the init-step result."""
   mock_entry.add_to_hass(hass)
   mock_entry.add_to_hass(hass)
   result = await hass.config_entries.options.async_init(mock_entry.entry_id)
   result = await hass.config_entries.options.async_init(mock_entry.entry_id)
+  assert result["type"] == "menu"
   assert result["step_id"] == "init"
   assert result["step_id"] == "init"
   return result
   return result
 
 
 
 
-async def _select_section(hass: HomeAssistant, flow_id: str, section: str):
+async def _select_section(hass: HomeAssistant, flow_id: str, step_id: str):
   """Choose a section from the init menu."""
   """Choose a section from the init menu."""
   return await hass.config_entries.options.async_configure(
   return await hass.config_entries.options.async_configure(
-    flow_id, user_input={"section": section}
+    flow_id, user_input={"next_step_id": step_id}
   )
   )
 
 
 
 
@@ -87,15 +88,15 @@ async def test_user_step_creates_entry_with_room_name(hass: HomeAssistant):
 # Options flow — init (menu) step
 # Options flow — init (menu) step
 # ---------------------------------------------------------------------------
 # ---------------------------------------------------------------------------
 
 
-async def test_options_init_shows_form(hass: HomeAssistant, mock_entry):
+async def test_options_init_shows_menu(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  assert result["type"] == "form"
+  assert result["type"] == "menu"
   assert result["step_id"] == "init"
   assert result["step_id"] == "init"
 
 
 
 
 async def test_options_init_sync_leads_to_sync_mode(hass: HomeAssistant, mock_entry):
 async def test_options_init_sync_leads_to_sync_mode(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   assert result["type"] == "form"
   assert result["type"] == "form"
   assert result["step_id"] == "sync_mode"
   assert result["step_id"] == "sync_mode"
 
 
@@ -120,7 +121,7 @@ async def test_options_init_locks_leads_to_locks(hass: HomeAssistant, mock_entry
 
 
 async def test_options_sync_mode_manual_saves(hass: HomeAssistant, mock_entry):
 async def test_options_sync_mode_manual_saves(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   assert result["step_id"] == "sync_mode"
   assert result["step_id"] == "sync_mode"
 
 
   result = await hass.config_entries.options.async_configure(
   result = await hass.config_entries.options.async_configure(
@@ -133,7 +134,7 @@ async def test_options_sync_mode_manual_saves(hass: HomeAssistant, mock_entry):
 
 
 async def test_options_sync_mode_caldav_proceeds_to_caldav_step(hass: HomeAssistant, mock_entry):
 async def test_options_sync_mode_caldav_proceeds_to_caldav_step(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   result = await hass.config_entries.options.async_configure(
   result = await hass.config_entries.options.async_configure(
     result["flow_id"],
     result["flow_id"],
     user_input={CONF_SYNC_MODE: SYNC_MODE_CALDAV},
     user_input={CONF_SYNC_MODE: SYNC_MODE_CALDAV},
@@ -144,7 +145,7 @@ async def test_options_sync_mode_caldav_proceeds_to_caldav_step(hass: HomeAssist
 
 
 async def test_options_sync_mode_api_proceeds_to_api_step(hass: HomeAssistant, mock_entry):
 async def test_options_sync_mode_api_proceeds_to_api_step(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   result = await hass.config_entries.options.async_configure(
   result = await hass.config_entries.options.async_configure(
     result["flow_id"],
     result["flow_id"],
     user_input={CONF_SYNC_MODE: SYNC_MODE_API},
     user_input={CONF_SYNC_MODE: SYNC_MODE_API},
@@ -159,7 +160,7 @@ async def test_options_sync_mode_api_proceeds_to_api_step(hass: HomeAssistant, m
 
 
 async def _reach_caldav_step(hass: HomeAssistant, mock_entry):
 async def _reach_caldav_step(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   result = await hass.config_entries.options.async_configure(
   result = await hass.config_entries.options.async_configure(
     result["flow_id"], user_input={CONF_SYNC_MODE: SYNC_MODE_CALDAV}
     result["flow_id"], user_input={CONF_SYNC_MODE: SYNC_MODE_CALDAV}
   )
   )
@@ -238,7 +239,7 @@ async def test_options_caldav_connect_error_shows_error(hass: HomeAssistant, moc
 
 
 async def _reach_api_step(hass: HomeAssistant, mock_entry):
 async def _reach_api_step(hass: HomeAssistant, mock_entry):
   result = await _options_init(hass, mock_entry)
   result = await _options_init(hass, mock_entry)
-  result = await _select_section(hass, result["flow_id"], "sync")
+  result = await _select_section(hass, result["flow_id"], "sync_mode")
   result = await hass.config_entries.options.async_configure(
   result = await hass.config_entries.options.async_configure(
     result["flow_id"], user_input={CONF_SYNC_MODE: SYNC_MODE_API}
     result["flow_id"], user_input={CONF_SYNC_MODE: SYNC_MODE_API}
   )
   )