diff --git a/docs/data_entry_flow_index.md b/docs/data_entry_flow_index.md index 0f1826da..92feee76 100644 --- a/docs/data_entry_flow_index.md +++ b/docs/data_entry_flow_index.md @@ -290,9 +290,9 @@ _The example is about config entries, but works with other parts that use data e The flow works as follows: -1. The user starts config flow in Home Assistant. -2. The config flow prompts the user that a task in progress and will take some time to finish. -3. The flow is responsible to manage the background task and continue the flow when the task is done or canceled. +1. The user starts the config flow in Home Assistant. +2. The config flow prompts the user that a task is in progress and will take some time to finish by calling `async_show_progress`. The flow should pass a task specific string as `progress_action` parameter to represent the translated text string for the prompt. +3. The flow is responsible for managing the background task and continuing the flow when the task is done or canceled. Continue the flow by calling the `FlowManager.async_configure` method, e.g. via `hass.config_entries.flow.async_configure`. Create a new task that does this to avoid a deadlock. 4. When the task or tasks are done, the flow should mark the progress to be done with the `async_show_progress_done` method. 5. The frontend will update each time we call show progress or show progress done. 6. The config flow will automatically advance to the next step when the progress was marked as done. The user is prompted with the next step. @@ -307,15 +307,29 @@ from .const import DOMAIN # pylint:disable=unused-import class TestFlow(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - data = None - task_one_done = False + task_one = None + task_two = None + + async def _async_do_task(self, task): + await task # A task that take some time to complete. + + # Continue the flow after show progress when the task is done. + # To avoid a potential deadlock we create a new task that continues the flow. + # The task must be completely done so the flow can await the task + # if needed and get the task result. + self.hass.async_create_task( + self.hass.config_entries.flow.async_configure(flow_id=self.flow_id) + ) async def async_step_user(self, user_input=None): - if not user_input: - if not self.task_one_done: - self.task_one_done = True + if not self.task_one or not self.task_two: + if not self.task_one: + task = asyncio.sleep(10) + self.task_one = self.hass.async_create_task(self._async_do_task(task)) progress_action = "task_one" else: + task = asyncio.sleep(10) + self.task_two = self.hass.async_create_task(self._async_do_task(task)) progress_action = "task_two" return self.async_show_progress( step_id="user", @@ -325,7 +339,9 @@ class TestFlow(config_entries.ConfigFlow, domain=DOMAIN): return self.async_show_progress_done(next_step_id="finish") async def async_step_finish(self, user_input=None): - return self.async_create_entry(title=self.data["title"], data=self.data) + if not user_input: + return self.async_show_form(step_id="finish") + return self.async_create_entry(title="Some title", data={}) ``` ## Translations