This chapter will help you learn how to build the graphical interface for users to interact with the To-Do application. You will discover the distinct types of views and widgets available, understand what context and domain are, and learn how to use them to provide a good user experience.

We will continue working with the todo_ui module. It already has the Model layer ready, and now it needs the View layer for the user interface.

Each component of the user interface is stored in a database record, just like business records are. Modules add UI elements to the database loading the corresponding data from XML files.

This means that a new XML data file for our UI needs to be added to the todo_ui module. We can start by editing the __manifest__.py file to declare these new data files:

{ 
  'name': 'User interface improvements to the To-Do app', 
  'description': 'User friendly features.', 
  'author': 'Daniel Reis', 
  'depends': ['todo_user'], 
  'data': [ 
    'security/ir.model.access.csv', 
    'views/todo_view.xml', 
    'views/todo_menu.xml', 
  ]} 

We might also create the subdirectory and the views/todo_view.xml and views/todo_menu.xml files with a minimal structure:

<?xml version="1.0"?> 
<odoo> 
  <!-- Content will go here... --> 
</odoo> 

In Chapter 3, Inheritance - Extending Existing Applications, a basic menu was given to our application, but we now want to improve it. So we will be adding new menu items and the corresponding window actions, to be triggered when they are selected.

Menu items are stored in the ir.ui.menu model and can be browsed via the Settings menu under Technical | User Interface | Menu Items.

The todo_app addon created a top-level menu to open the To-Do app tasks. Now we want to modify it to a second-level menu and have other menu options alongside it.

To do this, we will add a new top-level menu for the app and modify the existing To-Do task menu option. To views/todo_menu.xml, add:

<!-- Menu items -->
<!-- Modify top menu item -->
<menuitem id="todo_app.menu_todo_task" name="To-Do" />
<!-- App menu items -->
<menuitem id="menu_todo_task_view"
  name="Tasks"
  parent="todo_app.menu_todo_task"
  sequence="10"
  action="todo_app.action_todo_task" />
<menuitem id="menu_todo_config"
  name="Configuration"
  parent="todo_app.menu_todo_task"
  sequence="100"
  groups="base.group_system" /> 
<menuitem id="menu_todo_task_stage"
  name="Stages"
  parent="menu_todo_config"
  sequence="10"
  action="action_todo_stage" />

Instead of using <record model="ir.ui.menu"> elements, we can use the more convenient <menuitem> shortcut element, that provides an abbreviated way to define the record to load.

Our first menu item is for the To-do app top menu entry, with only the name attribute, and will be used as the parent for the next two options.

Notice that it uses the existing XML ID todo_app.menu_todo_task, thus rewriting the menu item, defined in the todo_app module, without any action attached to it. This is because we will be adding child menu items, and the action to open the Task views will now be called from one of them.

Then next menu items are placed under the top level item, through the parent="todo_app.menu_todo_task" attribute.

The second menu is the one opening the Task views, through the action="todo_app.action_todo_task" attribute. As you can see from the XML ID used, it is reusing an action already created by the todo_app module.

The third menu item adds the Configuration section for our app. We want it to be available only for super users, so we also use the groups attribute to make it visible only to the Administration | Settings security group.

Finally, under the Configuration menu we add the option for the task Stages. We will use it to maintain the Stages to be used by the kanban feature we will be adding to the To-do Tasks.

At this point, if we try to upgrade the addon we should get errors because we haven't defined the XML IDs used in the action attributes. We will be adding them in the next section.

A window action gives instructions to the GUI client, and is usually used by menu items or buttons in views. It tells the GUI what model to work on, and what views to make available. These actions can force for only a subset of the records to be visible, using a domain filter. They can also set default values and filters through the context attribute.

We will add window actions to the views/todo_menu.xml data file, which will be used by the menu items created in previous section. Edit the file, and make sure they are added before the menu items:

<!-- Actions for the menu items --> 
<act_window id="action_todo_stage" 
  name="To-Do Task Stages" 
  res_model="todo.task.stage" 
  view_mode="tree,form" 
  target="current" 
  context="{'default_state': 'open'}" 
  domain="[]" 
  limit="80" 
/> 
<act_window id="todo_app.action_todo_task" 
  name="To-Do Tasks" 
  res_model="todo.task" 
  view_mode="tree,form,calendar,graph,pivot" 
  target="current" 
  context="{'search_default_filter_my_tasks': True}" 
/> 
<!-- Add option to the "More" button --> 
<act_window id="action_todo_task_stage" 
  name="To-Do Task Stages" 
  res_model="todo.task.stage" 
  src_model="todo.task"  
  multi="False" 
/> 

Window actions are stored in the ir.actions.act_window model and can be defined in XML files using the <act_window> shortcut used in the preceding code.

The first action will open the Task Stages model and include the most relevant attributes for window actions:

The second action defined in the XML is replacing the original To-do Tasks action of the todo_app addon so that it displays the other view types we will explore later in this chapter: calendar and graph. After these changes are installed, you'll see additional buttons in the top-right corner, after the list and form buttons; however, these won't work until we create the corresponding views.

We also added a third action, not used in any of the menu items. It shows us how to add an option to the More menu, available at the top-right part of the list and form views. To do so, it uses two specific attributes: