Custom Actions
Custom actions allow you to perform specific tasks directly from the Lead or Deal page, aligning with your sales process stages. These actions can be anything from integrating with external apps to updating deal statuses or creating related documents.
Creating Custom Actions
Custom actions are implemented using Form Scripts in Desk:
- Navigate to Desk: Switch to Desk and navigate to CRM Form Script.
- Select Doctype: Choose the Doctype (e.g., Lead or Deal) where you want to add the custom action. You'll be presented with a boilerplate code.
- Apply To: Choose "Form".
Define Your Action: Here's how to define different types of actions:
Single Button: This code creates a single button labelled "Open in Desk" that opens the current Lead/Deal in a new browser tab.
const actions = [{ "label": "Open in Desk", "onClick": () => { let URL = `https://frappecrm.frappe.cloud/app/crm-deal/${doc.name}` window.open(URL, '_blank') } }]
Grouped Actions: This code creates a group of buttons hidden under a three-dot menu labelled "Add." Clicking on either "Create Quotation or "Create Sales Order" will trigger their respective onClick functions (defined elsewhere).
const actions = [{ "group": "Add", "hideLabel": true, "items": [ { "label": 'Create Quotation', "onClick": () => {} }, { "label": 'Create Sales Order', "onClick": () => {} }, ] }, { "group": "Delete", "items": [ { "label": 'Delete Quotation', "onClick": () => {} }, { "label": 'Delete Sales Order', "onClick": () => {} }, ] }]
Grouped Actions with label: This code creates a group of buttons hidden under a dropdown button labelled "Create". Clicking on either "Create Quotation" or "Create Sales Order" will trigger their respective onClick functions.
const actions = [{ "buttonLabel": "Create", "group": "Add", "hideLabel": true, "items": [ { "label": 'Create Quotation', "onClick": () => {} }, { "label": 'Create Sales Order', "onClick": () => {} }, ] }]
- Combined Actions: You can combine both single buttons and group actions into a single list and pass them as the "actions" property.
Using Context and Actions
The doc
parameter provides context about the current Lead/Deal page. You can utilize this context along with various functionalities to create your custom actions:
doc
: Access Lead/Deal field values (e.g.,doc.lead_owner
,doc.name
).deleteDoc
: Deletes the current Lead/Deal document.$dialog
: Opens a confirmation dialog with actions.updateField
: Updates a specific field value (e.g.,updateField('status', 'Lost', callback)
).router
: Navigate to a different page using Vue Router.createToast
: Displays success or error messages.call
: Calls an API from the client side.
Example: Custom Actions for Deal Management
Here's an example showcasing various custom actions you can create to manage Deals:
const actions = [
{
group: "Actions",
hideLabel: true,
items: [
{
label: "Create Quotation",
onClick: () => {
if (doc.status === "Won") {
// Call API to create quotation based on deal fields
call("create_quotation", {
deal: doc.name,
// Include relevant deal fields for quotation creation
}).then((data) => {
if (data.name) {
router.push({ name: "Quotation", params: { name: data.name } });
createToast({
title: "Quotation Created",
icon: "check",
iconClasses: "text-green-600",
});
} else {
createToast({
title: "Error Creating Quotation",
icon: "x",
iconClasses: "text-red-600",
});
}
});
} else {
createToast({
title: "Action only available for Won Deals",
icon: "info",
});
}
},
},
{
label: "Mark Lost",
onClick: () => {
$dialog({
title: "Mark Deal Lost",
message: "Are you sure you want to mark this deal as Lost?",
actions: [
{
label: "Mark Lost",
theme: "red",
variant: "solid",
onClick(close) {
updateField("status", "Lost", () => {
createToast({ title: "Deal Marked Lost", icon: "alert-circle" });
close();
});
},
},
{
label: "Cancel",
variant: "outline",
onClick(close) {
close();
},
},
],
});
},
}
],
},
{
label: "Delete",
onClick: () => {
$dialog({
title: "Delete Deal",
message: "Are you sure you want to delete this deal?",
actions: [
{
label: "Delete",
theme: "red",
variant: "solid",
onClick(close) {
deleteDoc();
close();
},
},
{
label: "Cancel",
variant: "outline",
onClick(close) {
close();
},
},
],
});
},
}
];