Allow dynamically creating menu options in SchemaFlowHandler (#151191)

This commit is contained in:
Erik Montnemery
2025-08-26 14:38:14 +02:00
committed by GitHub
parent e2faa7020b
commit a90ac612f0
2 changed files with 20 additions and 5 deletions

View File

@@ -107,7 +107,15 @@ class SchemaFlowMenuStep(SchemaFlowStep):
"""Define a config or options flow menu step.""" """Define a config or options flow menu step."""
# Menu options # Menu options
options: Container[str] options: (
Container[str]
| Callable[[SchemaCommonFlowHandler], Coroutine[Any, Any, Container[str]]]
)
"""Menu options, or function which returns menu options.
- If a function is specified, the function will be passed the current
`SchemaCommonFlowHandler`.
"""
class SchemaCommonFlowHandler: class SchemaCommonFlowHandler:
@@ -152,6 +160,11 @@ class SchemaCommonFlowHandler:
return await self._async_form_step(step_id, user_input) return await self._async_form_step(step_id, user_input)
return await self._async_menu_step(step_id, user_input) return await self._async_menu_step(step_id, user_input)
async def _get_options(self, form_step: SchemaFlowMenuStep) -> Container[str]:
if isinstance(form_step.options, Container):
return form_step.options
return await form_step.options(self)
async def _get_schema(self, form_step: SchemaFlowFormStep) -> vol.Schema | None: async def _get_schema(self, form_step: SchemaFlowFormStep) -> vol.Schema | None:
if form_step.schema is None: if form_step.schema is None:
return None return None
@@ -255,7 +268,7 @@ class SchemaCommonFlowHandler:
menu_step = cast(SchemaFlowMenuStep, self._flow[next_step_id]) menu_step = cast(SchemaFlowMenuStep, self._flow[next_step_id])
return self._handler.async_show_menu( return self._handler.async_show_menu(
step_id=next_step_id, step_id=next_step_id,
menu_options=menu_step.options, menu_options=await self._get_options(menu_step),
) )
form_step = cast(SchemaFlowFormStep, self._flow[next_step_id]) form_step = cast(SchemaFlowFormStep, self._flow[next_step_id])
@@ -308,7 +321,7 @@ class SchemaCommonFlowHandler:
menu_step: SchemaFlowMenuStep = cast(SchemaFlowMenuStep, self._flow[step_id]) menu_step: SchemaFlowMenuStep = cast(SchemaFlowMenuStep, self._flow[step_id])
return self._handler.async_show_menu( return self._handler.async_show_menu(
step_id=step_id, step_id=step_id,
menu_options=menu_step.options, menu_options=await self._get_options(menu_step),
) )

View File

@@ -317,7 +317,9 @@ async def test_menu_step(hass: HomeAssistant) -> None:
"""Test menu step.""" """Test menu step."""
MENU_1 = ["option1", "option2"] MENU_1 = ["option1", "option2"]
MENU_2 = ["option3", "option4"]
async def menu_2(handler: SchemaCommonFlowHandler) -> list[str]:
return ["option3", "option4"]
async def _option1_next_step(_: dict[str, Any]) -> str: async def _option1_next_step(_: dict[str, Any]) -> str:
return "menu2" return "menu2"
@@ -325,7 +327,7 @@ async def test_menu_step(hass: HomeAssistant) -> None:
CONFIG_FLOW: dict[str, SchemaFlowFormStep | SchemaFlowMenuStep] = { CONFIG_FLOW: dict[str, SchemaFlowFormStep | SchemaFlowMenuStep] = {
"user": SchemaFlowMenuStep(MENU_1), "user": SchemaFlowMenuStep(MENU_1),
"option1": SchemaFlowFormStep(vol.Schema({}), next_step=_option1_next_step), "option1": SchemaFlowFormStep(vol.Schema({}), next_step=_option1_next_step),
"menu2": SchemaFlowMenuStep(MENU_2), "menu2": SchemaFlowMenuStep(menu_2),
"option3": SchemaFlowFormStep(vol.Schema({}), next_step="option4"), "option3": SchemaFlowFormStep(vol.Schema({}), next_step="option4"),
"option4": SchemaFlowFormStep(vol.Schema({})), "option4": SchemaFlowFormStep(vol.Schema({})),
} }