Exploring Usability in Frappe Dashboards
I’ve been thinking about ways to make Frappe app data more easier to consume for users, specifically through dashboards and I’ve quickly encountered some limitations.
Here’s what I’ve put together so far:
To add advanced custom data for dashboard charts and number cards, it’s usually best to handle it in Python and then pull the data into the “doctype.” While this approach can feel like a workaround rather than an intended design, it’s a lot more flexible with regards to filtered data and what happens when you click the component.
The standard data options in Number Cards and Charts are limited, but you can select the Custom
option and set the path to your Python code like this:
Here’s an example of the values the Number Card expects:
{
"value": value,
"fieldtype": "Currency",
"route_options": {"from_date": "2023-05-23"},
"route": ["query-report", "Permitted Documents For User"]
}
Using route_options
, you can set filters for the data displayed.
Example: Dynamic Filtering for Payment Requisitions (Custom)
In my setup, I wanted to filter Payment Requisitions based on each user’s role. This is where Python came in handy:
@frappe.whitelist()
def my_approvals_card_data():
user = frappe.session.user
workflow = frappe.get_doc("Workflow", "Payment Requisition")
transitions = workflow.transitions
user_roles = frappe.get_roles(user)
# Create a list of states where the user has the required role
workflow_list = []
for row in transitions:
if row.allowed in user_roles:
workflow_list.append(row.state)
# Remove duplicates if any
user_workflows = set(workflow_list)
count = frappe.db.count("Payment Requisition", {
"workflow_state": ["in", user_workflows]
})
return {
"value": count,
"fieldtype": "Int",
"route_options": {
"workflow_state": ["in", workflow_list]
},
"route": ["payment-requisition"]
}
With this, each user sees a dynamic count of documents needing their attention. Clicking the number card opens a list of relevant documents:
When we click the card, we get a list of the 26 documents, including rejected ones to give the user full context:
EDIT
Charts need a little difference in approach: