feat: conistent danger zone delete flow
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
carla 2026-02-25 15:09:37 +01:00
parent e5a6003ace
commit 91cf7cca6a
19 changed files with 499 additions and 287 deletions

View file

@ -365,3 +365,46 @@ Detail pages should not drift into random layouts.
Add to this glossary when new terminology appears.
---
## 14) Destructive actions: Delete flow (canonical)
This section defines the canonical delete flow for list/detail/form resources (e.g. members). Use it as the single pattern; do not introduce a second pattern elsewhere.
### Tables: no row action buttons
- **MUST NOT:** Show Edit or Delete as row action buttons (or dropdown actions) in list/table views.
- **MUST:** Remove any existing edit/delete row actions from tables so that the only way to edit or delete is via the flow below.
### Navigation: row click → details
- **MUST:** Clicking a table row navigates to the resource details page (e.g. `/members/:id`).
- **MUST NOT:** Use the table for primary edit/delete actions.
### Edit: from details header, not from table
- **MUST:** Provide a clear primary “Edit” CTA in the details page header (e.g. “Edit member”).
- **MUST:** Edit is reached from the details page (e.g. “Edit member” button in header), not from the list/table.
### Delete: only via “Danger zone”
- **MUST:** Delete is available only in a dedicated “Danger zone” section at the bottom of the page.
- **MUST:** Use the same “Danger zone” on both the details page and the edit form when the user is authorized to destroy the resource.
- **MUST NOT:** Place delete in the table, in the header next to Edit, or in any other location outside the Danger zone.
### Danger zone layout and wording (canonical pattern)
- **Heading:** “Danger zone” (H2, `aria-labelledby` for the section, semantic colour e.g. `text-error`).
- **Explanatory text:** One short paragraph stating that the action cannot be undone and mentioning consequences (e.g. related data removed). Use `text-base-content/70` for the text.
- **Layout:** Section with heading outside a bordered box; content inside a single bordered, rounded box (`border border-base-300 rounded-lg p-4 bg-base-100`).
- **Button:** One destructive action only (e.g. “Delete member”). Use CoreComponents `<.button variant="danger">`. No primary or secondary actions mixed inside the Danger zone.
### Confirmation and button semantics
- **MUST:** Use a single confirmation step (e.g. `data-confirm` / browser confirm or one modal). Do not introduce a second confirmation pattern in this flow.
- **Confirm copy:** Message must include the resource name and state that the action “cannot be undone” (e.g. “Are you sure you want to delete %{name}? This action cannot be undone.”).
- **Button:** Accessible label (visible text + `aria-label` that includes the resource name, e.g. “Delete member %{name}”). Icon (e.g. trash) is optional and must not replace the text label for the primary action.
### Accessibility
- **MUST:** Button has an accessible name (`aria-label` when icon-only or in addition to visible text as above).
- **MUST:** Focus and keyboard: button is focusable and activatable via keyboard; focus management must not trap the user.
- **MUST:** Contrast and visibility: Danger zone heading and button use semantic danger styling with sufficient contrast (WCAG AA).
### Authorization visibility
- **MUST:** Show the Danger zone only when the current user is authorized to destroy the resource (e.g. `can?(current_user, :destroy, resource)`).
- **MUST NOT:** Show the Danger zone or the delete button when the user cannot destroy the resource; no “disabled” delete button for unauthorized users.
---