Actions
Actions run your own business logic on one or several records, from the back-office: validate a KYC, refund an order, resend an email, generate an invoice… They are declared in the actions array of a model.
Out of the box, every model has a Delete action and an Export CSV action on selections. Your actions are added next to them.
Example
Section titled “Example”{ slug: 'users', model: models.users, actions: [ { label: 'Validate KYC', code: 'validate_kyc', target: ['item', 'bulk'], filter: user => user.kyc_status === 'pending', handler: async ({ ids }, success, error) => { const users = await models.users.find({ _id: { $in: ids } });
if (users.some(user => !user.id_document)) { return error({ message: 'Some users did not upload their ID document' }); }
await models.users.updateMany({ _id: { $in: ids } }, { kyc_status: 'validated' }); success({ message: `${ids.length} user(s) validated`, reload: true }); } } ]}Properties
Section titled “Properties”| Property | Required | Description |
|---|---|---|
label |
Yes | The name of the action in the back-office. |
code |
Yes | A unique identifier. It is used in the activity log and in team permissions: avoid changing it once in use. |
target |
Yes | Where the action is available: 'item' (on the item page), 'bulk' (on a selection in the list), or ['item', 'bulk']. |
filter |
No | A function receiving a record and returning false to hide the action for it. On a selection, the action is shown only if all the selected records pass the filter. |
handler |
Yes | The function executed when the action is triggered. |
The handler function
Section titled “The handler function”handler: async (attrs, success, error) => { ... }attrs contains:
| Property | Description |
|---|---|
ids |
The IDs of the selected records. |
data |
The values of the form filled by the user, if you asked for one (see below). |
whereClause |
A ready-to-use query matching the selected records: Model.update(values, { where: whereClause }) with Sequelize, Model.updateMany(whereClause, values) with Mongoose. Handy with composite primary keys. |
Call success() when the action succeeded, or error() when it failed. Exactly one of them must be called.
Responses
Section titled “Responses”// Show a messagesuccess({ message: 'The user has been updated' });
// Reload the data of the pagesuccess({ reload: true });
// Open a link in a new tabsuccess({ action: 'open_tab', link: 'https://dashboard.stripe.com/payments/py_123' });
// Download a generated file (text content, such as CSV)success({ action: 'download', data: csvContent, filename: 'report.csv' });
// Show an error messageerror({ message: 'This user cannot be updated' });Ask for more information with a form
Section titled “Ask for more information with a form”When an action needs input from the user, call error() with a form. The back-office displays it, and runs the action again with the values in attrs.data:
handler: async ({ ids, data }, success, error) => { if (!data || !data.amount) { return error({ form: { title: 'Refund the order', submitLabel: 'Refund', fields: [ { label: 'Amount', name: 'amount', type: 'number', isFloat: true, required: true }, { label: 'Reason', name: 'reason', type: 'select', options: [ { label: 'Damaged product', value: 'damaged' }, { label: 'Late delivery', value: 'late' } ] }, { label: 'Refund date', name: 'refund_date', type: 'date' } ] } }); }
await refundOrder(ids[0], data.amount, data.reason); success({ message: 'Refund done', reload: true });}Available field types: text, number (add isFloat: true for decimals), date and select (with options). Each field accepts label, name, required and defaultValue.
Permissions
Section titled “Permissions”Admins and developers can use every action. For users, choose which actions each team can use in its permissions. Every execution is recorded in the activity log.