Package su.onno.ui

Class ActionController

java.lang.Object
su.onno.ui.ActionController

@RestController @RequestMapping("/api/actions") public class ActionController extends Object
Runs a custom ActionSpec server handler for an entity. The button on the list (toolbar / row) or detail surface posts here with the action key and (for row/detail actions) the record id; we resolve the entity, enforce write access, invoke the handler bean, and return its ActionResult so the client can show typed feedback and/or refresh. Navigation-only actions never reach the server — the client routes them directly.
  • Constructor Details

  • Method Details

    • descriptors

      @GetMapping("/{kind}/{name}") public Map<String,Object> descriptors(@PathVariable String kind, @PathVariable String name, @RequestParam(required=false) UUID id, Principal principal)
      Current toolbar/row descriptors for an entity with late-bound actions. The list descriptor advertises whether this request is needed; static-only entities never call it. Dynamic providers are evaluated for every menu open, so catalog-backed add/remove/rename/reorder and presentation changes appear without a restart or page reload.
    • run

      @PostMapping("/{kind}/{name}/{key}") public ActionResult run(@PathVariable String kind, @PathVariable String name, @PathVariable String key, @RequestParam(required=false) UUID id, @RequestBody(required=false) Map<String,Object> body, Principal principal)
    • formDefaults

      @GetMapping("/{kind}/{name}/{key}/form") public Map<String,Object> formDefaults(@PathVariable String kind, @PathVariable String name, @PathVariable String key, @RequestParam(required=false) UUID id, Principal principal)
      The opening values of an action's form for one record — the formDefaults hook (ActionSpec.ActionBuilder.formDefaults(java.util.function.Function<su.onno.ui.ActionContext, su.onno.ui.ActionSpec.FormDefaults>)) evaluated at open time. The modal fetches this before rendering when the action descriptor carries dynamicForm: true.

      A read: no requireWritable gate (that stays on the POST that actually runs the handler), but the caller must still hold entity write access + the action's roles — the same checks that gate seeing/running the button. A hook that throws yields empty defaults (the dialog falls back to the static seeding) rather than breaking the modal.

    • runBatch

      @PostMapping("/{kind}/{name}/{key}/batch") public Map<String,Object> runBatch(@PathVariable String kind, @PathVariable String name, @PathVariable String key, @RequestBody Map<String,Object> body, Principal principal)
      Run a server action over a set of records in one request — the list's batch selection posts here instead of firing N single calls. The handler is invoked per id in its own transaction-per-invocation semantics (identical to N single calls, minus the HTTP round-trips); a failing id is recorded and the batch continues. Ids are resolved concurrently on the shared BatchRunner pool (onno.ui.batch.parallelism). Returns {ok, failed, total} so the client can toast a summary. Capped at BATCH_LIMIT ids.