On a few different threads, people have been asking about how to create custom desk pages for displaying data and executing workflows. The Page API has a bit of documentation, but there’s not much really showing how to get started. Here’s a very simple example that will hopefully help with that.
As administrator, create a new Page
document with settings that look like this:
The module field should link a module in your custom app.
In your module’s pages folder on your server, you’ll find a file called demo.js (or whatever you called your page). It comes pre-filled with boilerplate code that invokes the make_app_page
method:
frappe.pages['demo'].on_page_load = function(wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
title: 'Demo',
single_column: true
});
}
From here, your options are limitless really. The make_app_page
method generates a bit of html at the wrapper location, and you can hook into that html using whatever frontend tools you prefer.
Here is a very simple illustration using Frappe’s DataTable library. (You could just as easily use Vue or whatever else you like.)
frappe.pages['demo'].on_page_load = function(wrapper) {
var page = frappe.ui.make_app_page({
parent: wrapper,
title: 'Demo',
single_column: true
});
//set up our empty datatable
let el = document.querySelector('.layout-main-section')
let button_formatter = (value) => `<button onclick="alert('This is ${value}')">Action!</button>`
let columns = ['Name', 'Territory', 'Account Manager',
{name: "Action Button", focusable: false, format: button_formatter }]
let datatable = new frappe.DataTable(el, { columns: columns, data: [], layout: "fluid" });
//use regular ajax api methods to fetch document data, then refresh
frappe.db.get_list("Customer",
{fields: ['customer_name', 'territory', 'account_manager', 'name']}
).then((r) => {
let data = r.map(Object.values)
datatable.refresh(data, columns)
})
}
That gives me a page that looks like this:
We’re pulling data from the database and creating a button for each Customer that triggers arbitrary javascript. Nothing fancy, but pretty much anything is possible on the same principles.