OctoWiki
Memory Appendix

No Confirm Use Modal

All destructive/state-changing prompts in views/admin/ must go through the canonical confirmAction(opts) Bootstrap modal helper, never browser confirm()

Source memory file: feedback_no_confirm_use_modal.md · Category: Feedback / working-preference This is a verbatim dump of Claude's persistent memory for the Octopus project. Rendered inside a code block so nothing is altered.

---
name: No confirm() in admin UI — use confirmAction modal
description: All destructive/state-changing prompts in views/admin/ must go through the canonical confirmAction(opts) Bootstrap modal helper, never browser confirm()
type: feedback
originSessionId: 2130eb26-f4a9-405f-a19f-b1a1fa5a2f96
---
Never use browser `confirm()` in admin views (`views/admin/**/*.jet`). All confirmation prompts go through the canonical async helper:

```js
if (!await confirmAction({
    title: 'Disable Job',
    body: 'Are you sure you want to disable this job?',
    confirmLabel: 'Disable',          // default 'Confirm'
    cancelLabel: 'Cancel',            // default 'Cancel' (use 'Keep' for irreversible cancels)
    confirmVariant: 'danger',         // primary | success | warning | danger; default 'primary'
    icon: 'mdi-power-off',            // optional MDI icon on the confirm button
})) return;
```

The helper is defined globally in [views/layouts/admin/base.jet](views/layouts/admin/base.jet). It returns `Promise<boolean>` — true on confirm, false on dismiss. Caller must be `async`.

**Why:** `confirm()` is a blocking native dialog that doesn't match the admin Bootstrap UI, can't carry brand styling/icons, and looks unprofessional. The codebase was unified to a Bootstrap-modal-based confirm in this pass — re-introducing `confirm()` would split the convention again.

**How to apply:**
- New admin views or edits: use `confirmAction({...})` instead of `confirm(...)`. Caller function must be marked `async`.
- Variant convention used in the existing call sites:
  - destructive (disable, deactivate, delete) → `danger`
  - irreversible cancel → `danger` + `cancelLabel: 'Keep'` (so the modal-close button doesn't read like the destructive choice)
  - retry / resend / generic continue → `primary`
  - activate / resume → `success`
  - pause → `warning`
- For action sets (pause/resume/cancel etc.), prefer a table-keyed config object (see [payouts/schedule_detail.jet](views/admin/payouts/schedule_detail.jet) `SCHEDULE_ACTIONS`) over duplicating per-button options.
- Existing inline modals with form fields (e.g. `esimRefundModal`, `esimForceDeliverModal`, `cancelOrderModal`) are not in scope — they need the form anyway and stay as hand-rolled Bootstrap modals.