feat(12.1-01): declared bulk actions on admin lists
- pact.HasAdminBulkActions with AdminBulkAction, its input and result
- config_list.yaml bulkActions, compiled fail-loud, needs showCheckboxes
- POST .../{controller}/bulk/{action}: ids resolved and locked through the
list scope in one transaction; partial selection is 409
- list schema offers declared actions per principal, with confirm text
- admin SPA bulk actions menu with confirm, busy state and failure toasts
- acme.roster fixture, tracer test, OpenAPI, TS types, dist, READMEs, docs
This commit is contained in:
41
admin/tests/fixtures/roster.list-schema.json
vendored
Normal file
41
admin/tests/fixtures/roster.list-schema.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"data": {
|
||||
"title": "People",
|
||||
"recordsPerPage": 20,
|
||||
"perPageOptions": [],
|
||||
"showSearch": true,
|
||||
"showSetup": false,
|
||||
"showCheckboxes": true,
|
||||
"showSorting": true,
|
||||
"searchTerm": "search",
|
||||
"recordUrl": "acme/roster/people/update/:id",
|
||||
"toolbarButtons": ["create", "delete"],
|
||||
"toolbarActions": [],
|
||||
"assets": { "scripts": [], "styles": [] },
|
||||
"columns": [
|
||||
{ "key": "name", "label": "Name", "searchable": true, "sortable": true },
|
||||
{ "key": "email", "label": "Email", "searchable": true, "sortable": true }
|
||||
],
|
||||
"filters": [],
|
||||
"rowActions": [],
|
||||
"bulkActions": [
|
||||
{ "name": "delete", "label": "Delete selected" },
|
||||
{ "name": "activate", "label": "Activate", "confirm": "Activate the selected people?" },
|
||||
{ "name": "archive", "label": "Archive" }
|
||||
],
|
||||
"messages": {
|
||||
"create": { "other": "New person" },
|
||||
"deleteConfirm": { "other": "Delete the selected (:count)?" },
|
||||
"deleteSelected": { "other": "Delete selected" },
|
||||
"deleted": { "one": "Deleted :count record", "other": "Deleted :count records" },
|
||||
"empty": { "other": "There are no records in this view." },
|
||||
"emptySearch": { "other": "Nothing found" },
|
||||
"emptySearchHint": { "other": "No record matches “:term”. Try another search." },
|
||||
"recordCount": { "one": ":count record", "other": ":count records" },
|
||||
"searchPrompt": { "other": "Search…" },
|
||||
"selected": { "other": ":count selected" }
|
||||
},
|
||||
"meta": { "locale": "en" }
|
||||
},
|
||||
"meta": { "locale": "en" }
|
||||
}
|
||||
8
admin/tests/fixtures/roster.list.json
vendored
Normal file
8
admin/tests/fixtures/roster.list.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"data": [
|
||||
{ "id": 1, "name": "Ada Lovelace", "email": "ada@example.test" },
|
||||
{ "id": 2, "name": "Bob Stone", "email": "bob@example.test" },
|
||||
{ "id": 3, "name": "Cy Young", "email": "cy@example.test" }
|
||||
],
|
||||
"meta": { "page": 1, "per_page": 20, "total": 3, "last_page": 1 }
|
||||
}
|
||||
6
admin/tests/fixtures/typed.ts
vendored
6
admin/tests/fixtures/typed.ts
vendored
@@ -17,6 +17,8 @@ import formSchemaJson from './widgets.form-schema.json'
|
||||
import listJson from './widgets.list.json'
|
||||
import listSchemaJson from './widgets.list-schema.json'
|
||||
import optionsJson from './widgets.options.json'
|
||||
import rosterListJson from './roster.list.json'
|
||||
import rosterListSchemaJson from './roster.list-schema.json'
|
||||
import recordJson from './widgets.record.json'
|
||||
import candidatesJson from './widgets.relation-candidates.json'
|
||||
import linkedJson from './widgets.relation-linked.json'
|
||||
@@ -54,6 +56,10 @@ export const extensionListSchemaFixture: S['cabana.Envelope-cabana_ListSchema']
|
||||
*/
|
||||
export const extensionPartialFixture = extensionPartialJson as S['cabana.Envelope-cabana_PartialView']
|
||||
export const listFixture: Rows = listJson
|
||||
/** A people list with declared bulk actions (Phase 12.1). */
|
||||
export const rosterListSchemaFixture: S['cabana.Envelope-cabana_ListSchema'] = rosterListSchemaJson
|
||||
/** The people of the roster list (Phase 12.1). */
|
||||
export const rosterListFixture: Rows = rosterListJson
|
||||
export const listSchemaFixture: S['cabana.Envelope-cabana_ListSchema'] = listSchemaJson
|
||||
export const optionsFixture: {
|
||||
maker: S['cabana.Envelope-array_cabana_FilterOption']
|
||||
|
||||
Reference in New Issue
Block a user