Agent Wranglers

Feedback and dialogs Required

Let people undo or confirm destructive actions

For deletes and other changes that lose data, offer undo when the change can be reversed, and ask for confirmation when it can't. Name the object and the count in both.

How to do it

Prefer undo. Mark the record deleted at once, show "Invoice 1042 deleted" with an Undo button, and purge it after a set time, such as 30 days. For actions that can't be reversed, confirm in a dialog. Its button names the action, such as "Delete 3 projects", never "OK". For large or account-wide deletes, ask people to type the name. This meets error prevention.

Example

export async function deleteInvoice(invoice: Invoice) {
  await api.post(`/api/invoices/${invoice.id}/delete`);
  showUndo(`Invoice ${invoice.number} deleted`, () => api.post(`/api/invoices/${invoice.id}/restore`));
}
PURGE_AFTER = timedelta(days=30)

@app.post("/api/invoices/<invoice_id>/delete")
def delete_invoice(invoice_id):
    invoices.mark_deleted(current_user().account_id, invoice_id, purge_at=datetime.now(timezone.utc) + PURGE_AFTER)
    return "", 204

@app.post("/api/invoices/<invoice_id>/restore")
def restore_invoice(invoice_id):
    invoices.restore(current_user().account_id, invoice_id)
    return "", 204

How to check

A browser test deletes a record and presses Undo, and the record is back with the same ID. A test of each action that can't be reversed finds a confirmation whose button names the action.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/feedback-and-dialogs/confirm-or-undo.