2. State user tasks
State tasks can be used to allow for manual interaction with a project based on the current state of it. Check out our manual on state tasks to learn more about how they work.
-
Setup state tasks
Add a new class method to your state class called
get_tasks(). This method will be executed when the frontend requests the currently available tasks for this state.custom/MyState.py from ..BaseState import BaseStatefrom ..Task import Taskclass MyState(BaseState):...@classmethoddef get_tasks(cls, include_form: bool = True, project_id: str | None = None, **kwargs) -> list[Task]:...This method will return a list of tasks. If you wish to not return any tasks, add
return [].Parameters
include_form: bool = TrueUsed to improve performance. In case the frontend only requires a list of available tasks and not their forms,
include_formwill beFalse. To make use of it, check this parameter before creating the task form(s), which can potentially be time-consuming.project_id: str | None = NoneIndicates if tasks for all project within the state need to be returned or for just one. Used when the frontend has to display tasks for a specific project.
-
Iterate trough projects
To iterate trough all projects in this current state, you can use the state’s
get_state_projects()method.custom/MyState.py @classmethoddef get_tasks(cls, include_form: bool = True, project_id: str | None = None, **kwargs) -> list[Task]:tasks = []for project in MyState.get_state_projects():if project_id is not None and str(project.db_id) != project_id:continue...return tasksInside this for loop, you can check if you want to add a task for the current project and if so, add as many tasks as you would like.
-
Add custom state tasks
A task consists of the following attributes:
id: Used to identify a specific task in combination with the project IDtitle: Shown name of the task when displayed in the frontendproject_id: Used to identify a specific task in combination with the task IDproject_type: Shown project type of the task when displayed in the frontendassignee: Who is assigned to that task, usually dynamically set by usingMyState.task_assignee(project, task_id)form: The form of the task (learn more about forms here).
An example could look like this:
custom/MyState.py from ..BaseState import BaseStatefrom ..Task import Taskfrom perseus.frontend_form import TextBlock, RadioInputfrom perseus.states.custom import TemplateBasicclass MyState(BaseState):...@classmethoddef get_tasks(cls, include_form: bool = True, project_id: str | None = None, **kwargs) -> list[Task]:tasks = []for project in MyState.get_state_projects():if project_id is not None and str(project.db_id) != project_id:continuetask_id = "MY_TASK_ID" # Use this task id to identify the submitted task in case there is more than one task per project# Create a form and add items to itform = Noneif include_form:form = TemplateBasic.get_basic_form(project, task_id)form.add_items(TextBlock("You can type **some** markup text <a href='some://link' target='_blank'>here</a>"),RadioInput("decision",("Yes", "Y"),("No", "N"),label="Decision",),) # Please check out the documentation on what items you can add to forms# Append task to listtasks.append(Task(id=task_id,title="Title of this task",project_id=str(project.db_id),project_type=project.project_type,assignee=MyState.task_assignee(project, task_id),form=form,))return tasks -
Task IDs
Task IDs will be used to identify tasks in states. Please return all possible IDs in the state’s method
get_task_ids(). PERSEUS will use this to improve performance hen determining how many open tasks exist.custom/MyState.py @classmethoddef get_task_ids(cls) -> list[str]:return ["CHECKING"]
In the next step, we will handle the submission of a task form.