feat(18-01): money list column, danger record actions, preview Edit rule and table kit (task 2)
- columns.yaml type: money with currency or currencyFrom (exactly one), never searchable, not sortable by default; every list row carries the currencyFrom column's value under its own key; the schema serves currency and currencyFrom on the column - pact.AdminRecordAction.Danger, served as danger on cabana.RecordAction (absent when false); RecordActions.vue passes it to the confirm dialog - CellValue money kind through formatMoney with the row's code, the em dash when empty and the amount alone without a code; DataTable aligns money headers and cells to the right - PreviewView renders Edit only when a registered value field allows update (F6) - main.css .summer-table* and .summer-stat__note kit classes (F7) over --c-* variables; cabana README kit rows - fixture record actions void (danger) and resend; TestMoneyListCompile, TestMoneyListSmoke and TestRecordActionDangerSmoke; regenerated OpenAPI and TS types; rebuilt dist; lists-and-filters and admin-controllers docs
This commit is contained in:
@@ -480,11 +480,12 @@ messages:
|
||||
edit: acme.roster::lang.people.edit
|
||||
```
|
||||
|
||||
Each `pact.AdminRecordAction` has a `Name`, a `Label`, an optional `Confirm` text, its own `Permissions`, an optional `Applies` function and `Run`:
|
||||
Each `pact.AdminRecordAction` has a `Name`, a `Label`, an optional `Confirm` text, its own `Permissions`, an optional `Danger` flag, an optional `Applies` function and `Run`:
|
||||
|
||||
- `Applies` reports whether the action fits the record's current state; without one the action always applies. It must only read, because it runs in two places: when a record is shown, to decide which actions to offer, and again inside the action's transaction, right before `Run`.
|
||||
- The show response (`GET /{controller}/{id}`) lists the offered actions in `meta.actions` as `cabana.RecordAction` entries: only those the administrator may run and that apply to the record. The key is absent when none is offered, and create and update responses never carry it.
|
||||
- `POST /{controller}/{id}/actions/{action}` takes an empty `{}` body. cabana loads the record through `pact.FormExtendQuery` with a row lock in one transaction and hands it to `Run` in `pact.AdminRecordActionInput`. A missing record and a record outside the scope are the same 404; an action whose `Applies` reports false answers 409 `conflict`; an administrator without the action's permissions gets 403.
|
||||
- `Run` writes through `cabana.TxFromContext(ctx)` and returns a `pact.AdminRecordActionResult` with an optional `Message`. Any error rolls the transaction back.
|
||||
- `Danger: true` marks an action that moves money out or cannot be undone, such as a refund. The record response serializes it as `danger` on the `cabana.RecordAction` entry (the key is absent for an ordinary action, so existing payloads are unchanged), and the admin's confirm dialog then shows its confirm button in the danger variant; the footer button itself stays the same. The flag changes nothing on the server: permissions and `Applies` are checked as for any action.
|
||||
|
||||
Record actions have their own namespace: a record action and a bulk action may share a name, such as `activate` here. `create` and `delete` are reserved. A name in `recordActions` that the controller does not register, a duplicate, or an action without a label stops the start-up.
|
||||
|
||||
Reference in New Issue
Block a user