This is a more complicated project that will showcase some non trivial aspects of the framework. The goal is to practice composing views, coordinating various aspects of the UI and doing it in a maintainable way.
Bafien had the greatest idea ever (after the freeze!): a mix of a Kanban View and a list view would be perfect for your needs! In a nutshell, he wants a list of customers on the left of the task kanban view. When you click on a customer on the left sidebar, the kanban view on the right is filtered to only display orders linked to that customer.
Since we are customizing the kanban view, let us start by extending it and using our extension in the kanban view for the tshirt orders
- extend the kanban view
- register it under the
awesome_tshirt.kanbanview_with_customers
- use it in the
js_class
We will need to display a list of customers, so we might as well create the component.
- create a
CustomerList
component (which just display a div with some text for now) - it should have a
selectCustomer
prop - create a new template extending (xpath) the kanban controller template to add
the
CustomerList
next to the kanban renderer, give it an empty function asselectCustomer
for now - subclass the kanban controller to add
CustomerList
in its sub components - make sure you see your component in the kanban view
- modify the
CustomerList
component to fetch a list of all customers in its willStart - display it in the template in a
t-foreach
- add an event handler on click
- whenever a customer is selected, call the
selectCustomer
function prop
- implement
selectCustomer
in the kanban controller to add the proper domain - modify the template to give the real function to the CustomerList
selectCustomer
prop
Since it is not trivial to interact with the search view, here is a quick snippet to help:
selectCustomer(customer_id, customer_name) {
this.env.searchModel.setDomainParts({
customer: {
domain: [["customer_id", "=", customer_id]],
facetLabel: customer_name,
},
});
}
There is a has_active_order
field on res.partner
. Let us allow the user to
filter results on customers with an active order.
- add an input of type checkbox in the
CustomerList
component, with a labelActive customers
next to it - changing the value of the checkbox should filter the list on customers with an active order
Add an input above the customer list that allows the user to enter a string and
to filter the displayed customers, according to their name. Note that you can
use the fuzzyLookup
function to perform the filter.
To solve the previous two exercises, it is likely that you used an event listener
on the inputs. Let us see how we could do it in a more declarative way, with the
t-model
directive.
- make sure you have a reactive object that represents the fact that the filter is active (so, something like
this.state = useState({ displayActiveCustomers: false, searchString: ''})
) - modify the code to add a getter
displayedCustomers
which returns the currently active list of customers - modify the template to use
t-model
Resources
- Add a
Pager
in theCustomerList
, and only load/render the first 20 customers - whenever the pager is changed, the customer list should update accordingly.
This is actually pretty hard, in particular in combination with the filtering done in the previous exercise. There are many edge cases to take into account.