Class RowAction

java.lang.Object
org.apache.juneau.console.views.RowAction

@BeanType(properties="id,label,icon,endpoint,method,confirm,confirmTitle,bulkMode,form,present,onSuccess,enabledWhen,visibleWhen,tone,confirmLabel,confirmRenderer") public class RowAction extends Object
A per-row action descriptor in the VIEW_META wire contract (the transport-agnostic "row-action intent" model).

An FTL <@card type="datatables"> VIEW_META catalog declares zero or more of these via rowActions; the juneau-views.js runtime renders each as a row-menu item and, on activation, submits the declared endpoint with the declared method as a JSON request carrying the process's CSRF token.

The frozen wire schema

This is the complete set of wire fields; it is pinned in full now so that later waves (a future declarative modal/form + typed result) can rely on it verbatim without forcing another fail-loud contract bump. Only id is required; every other field is optional and is omitted from the serialized form when unset (null-valued properties are dropped).

FieldType / tokensMeaning
idstringStable action id (menu-item key; also the submit's logical name).
labelstringThe menu-item text.
iconstringOptional glyph name (resolved by the shared icon registry).
endpointstringThe URL the action submits to; may carry a {property} token substituted from the current row - a value that cannot be resolved refuses the submission (see endpoint).
methodPOST|PUT|PATCH|DELETE The non-safe HTTP method (see RowAction.Method).
confirmstringOptional confirmation prompt shown before the submit.
formstringOptional form-source URL supplying the action's input fields; may carry a {property} token substituted from the current row before the confirmation GET (see form). Blank/absent form is the confirm-only local path.
presentpage|dialog|inline How the action's form/confirmation is presented (see RowAction.Present); inline keeps it out of the row menu.
onSuccessredraw|mergeRow|navigate What the runtime does with a successful result (see RowAction.OnSuccess).
enabledWhen[{field,op,value?,reason}, ...] Row-state disable-with-reason rules (see enabledWhen(String,Op,Object,String)).
visibleWhen[{field,op,value?}, ...] Row-state visibility rules (see visibleWhen(VisibilityRule...)).
tonedefault|danger Styling of the confirmation (see RowAction.Tone); danger focuses Cancel first.
confirmLabelstring Text of the confirm button; defaults to the action's label.
confirmRendererstring Name of a confirm renderer registered with the client runtime; absent means the built-in modal. Like confirm, it is not consulted when an inline cell edit commits (that never prompts).

enabledWhen was added after this schema was first frozen; like ModalDef#barSlot, it is additive-only (null when unset, omitted from the serialized form) and its presence does not bump VIEW_META — a RowAction that leaves it unset serializes unchanged, and old juneau-views.js ignores the unknown key.

Why method cannot be a safe method

RowAction.Method enumerates only POST/PUT/PATCH/DELETE, so a safe (CSRF-exempt) method cannot be declared at all — a build-time refusal by construction. This mirrors the server boundary: MethodSafety fails any @Mutating operation bound to a safe method at startup, and LoopbackBoundary applies its Origin/CSRF/JSON checks only to non-safe methods. A mutating action bound to GET would be a CSRF-able write; the type system forbids expressing one.

Per-row {property} substitution in endpoint and form

endpoint and form may each carry a {property} token (e.g. {id}, as in the example below) that the client-side runtime substitutes from the row — the SAME mechanism, same token grammar, and same per-value escaping as the linked cell renderer's href interpolation. Unlike a rendered href, these URLs are fetched (form: confirmation GET) or submitted (endpoint: mutating write), so an unresolved substitution refuses instead of issuing a malformed request; see each setter's javadoc for the full contract. A value with no token is unaffected and is used as declared. A blank/absent form is the confirm-only local path (no GET), not a refusal.

Example:

RowAction delete = RowAction.create("delete") .label("Delete") .endpoint("servlet:/incidents/{id}") .method(RowAction.Method.DELETE) .confirm("Delete incident {id}?") .confirmLabel("Delete forever") .tone(RowAction.Tone.DANGER) .visibleWhen(VisibilityRule.when("locked").ne(true));

See Also:
Since:
10.0.0
  • Field Details

    • id

      public String id
      The stable action id (menu-item key; also the submit's logical name).
    • label

      public String label
      The menu-item text.
    • icon

      public String icon
      Optional glyph/icon name (resolved by the shared icon registry).
    • endpoint

      public String endpoint
      The URL this action submits to (see endpoint for the {property} substitution grammar).
    • method

      public String method
      The non-safe HTTP method wire token (see RowAction.Method.wire()).
    • confirm

      public Object confirm
      Optional confirmation prompt shown before the submit, or literal false for none (see noConfirm()).
    • confirmTitle

      Optional confirm-dialog title when this action is driven in bulk.
    • bulkMode

      public String bulkMode
      Optional bulk-mode wire token (see RowAction.BulkMode.wire()); null means perRow.
    • form

      public String form
      Optional form-source URL supplying the action's input fields.
    • present

      public String present
      Optional presentation hint wire token (see RowAction.Present.wire()).
    • onSuccess

      public String onSuccess
      Optional success-behavior hint wire token (see RowAction.OnSuccess.wire()).
    • enabledWhen

      The row-state rules that must all match for this action to render enabled.

      null or empty means "never gated" — the action renders exactly as it does today. See enabledWhen(String,Op,Object,String) for the semantics, which mirror ActionRef.enabledWhen on the detail-panel ActionBar (widgets module): presentation only, disabled never hidden, first-declared-rule-wins, and a field the row does not carry fails closed.

    • visibleWhen

      The rules that must all match for this action to render at all. null or empty means always visible.

      Unlike enabledWhen, which disables but never hides, a row whose data does not satisfy every rule here has this action hidden entirely (re-evaluated on every draw). Prefer enabledWhen, which tells the user why an action is unavailable, and hide only when the action is irrelevant to the row. Still presentation only — the endpoint must authorize independently. The evaluation map is the row, plus the page's facts under a facts. prefix, so a rule can test either "status" or "facts.viewer.roles".

    • tone

      public String tone
      Optional confirmation tone wire token (see RowAction.Tone.wire()).
    • confirmLabel

      Optional text of the confirm button; null means the action's label.
    • confirmRenderer

      Optional name of a confirm renderer registered with the client runtime; null means the built-in modal.
  • Constructor Details

  • Method Details

    • create

      public static RowAction create(String id)
      Starts a new RowAction with the specified stable action id.
      Parameters:
      id - The stable action id. Must not be null or blank.
      Returns:
      A new mutable RowAction to chain builder calls on.
      Throws:
      IllegalArgumentException - If id is null or blank.
    • label

      public RowAction label(String value)
      Sets the menu-item text.
      Parameters:
      value - The new value.
      Returns:
      This object.
    • icon

      public RowAction icon(String value)
      Sets the glyph/icon name.
      Parameters:
      value - The new value.
      Returns:
      This object.
    • endpoint

      public RowAction endpoint(String value)
      Sets the URL this action submits to.

      May contain one or more {property} tokens (e.g. "servlet:/incidents/{id}/ack"), substituted from the CURRENT ROW's own already-fetched data at submit time — the client-side ( juneau-views.js) runtime, not this Java layer, performs the substitution, by delegating to the identical interpolateHref helper the linked cell renderer uses (juneau-renders.js): the SAME token grammar (any {property}, not a hardcoded {id}) and the SAME per-value encodeURIComponent escaping — unchanged.

      Divergence from a rendered href is deliberate: because this URL is submitted rather than merely rendered, the runtime refuses the submission (renders a visible refusal; issues no request; never a request-time exception) instead of firing a malformed or undeclared write, when:

      • a {property} token's row value is absent, null, or blank;
      • the resolved URL still carries an unsubstituted {property} token (e.g. the page shipped juneau-views.js without its juneau-renders.js peer);
      • the resolved URL contains a .. path segment (which browser URL resolution would otherwise normalize into a different, undeclared endpoint); or
      • no endpoint is declared at all.
      Column.href keeps substituting to an empty string in each of these cases, because a rendered link is not a write.

      Backward compatible, narrowed: an endpoint with no {...} token is still issued as declared (three of the four guards above cannot fire on it; the fourth, the .. check, only fires on an author-declared ..). An endpoint WITH a token now refuses in cases that previously submitted a malformed URL (e.g. "servlet:/incidents//ack" for a row with no id) rather than issuing it.

      Parameters:
      value - The new value.
      Returns:
      This object.
    • method

      Sets the non-safe HTTP method this action submits with.

      Only a RowAction.Method (POST/PUT/PATCH/DELETE) can be passed, so a safe method can never be declared — the build-time half of the safe-method refusal.

      Parameters:
      value - The method. Must not be null.
      Returns:
      This object.
    • confirm

      public RowAction confirm(String value)
      Sets the confirmation prompt shown before the submit.

      The prompt is shown whatever present says: without RowAction.Present.DIALOG the action opens a confirm-only dialog (or its confirmRenderer) and submits only on Confirm. Use noConfirm() for an action that never prompts.

      One surface never prompts: committing an inline cell edit (the edit renderer's pencil) submits the action directly on Enter or blur even when the action declares a confirm or a confirmRenderer, because a dialog opening on Enter or blur is awkward. Do not wire a confirm-guarded action to an inline editor.

      Parameters:
      value - The new value.
      Returns:
      This object.
    • bulkMode

      Sets how this action behaves when driven from a bulk-mutate toolbar: one call per selected row (RowAction.BulkMode.PER_ROW, the default) or a single call carrying every selected id (RowAction.BulkMode.AGGREGATE).
      Parameters:
      value - The new mode. A null value clears it (the default, RowAction.BulkMode.PER_ROW).
      Returns:
      This object.
    • confirmTitle

      public RowAction confirmTitle(String value)
      Sets the confirm dialog's title when this action is driven in bulk (e.g. "Abort {count} pending changes").
      Parameters:
      value - The title template. May be null.
      Returns:
      This object.
    • noConfirm

      public RowAction noConfirm()
      Marks this action as never requiring a confirm dialog, in bulk or otherwise — writes a literal false onto the same confirm wire key a confirm message would otherwise occupy.
      Returns:
      This object.
    • form

      public RowAction form(String value)
      Sets the form-source URL supplying the action's input fields.

      May contain one or more {property} tokens (e.g. "/data/alerts/{id}/ack-form"), substituted from the CURRENT ROW's own already-fetched data before the confirmation GET — the client-side (juneau-views.js) runtime, not this Java layer, performs the substitution, by delegating to the identical interpolateHref helper the linked cell renderer uses (juneau-renders.js): the SAME token grammar (any {property}, not a hardcoded {id}) and the SAME per-value encodeURIComponent escaping.

      Divergence from a rendered href: because this URL is fetched (the confirmation GET) rather than merely rendered, the runtime refuses the open (renders a visible refusal; issues no fetch) instead of GETting a malformed or undeclared path, when:

      • a {property} token's row value is absent, null, or blank;
      • the resolved URL still carries an unsubstituted {property} token (e.g. the page shipped juneau-views.js without its juneau-renders.js peer); or
      • the resolved URL contains a .. path segment (which browser URL resolution would otherwise normalize into a different, undeclared endpoint).
      href keeps substituting to an empty string in each of these cases, because a rendered link is not a fetch.

      Divergence from endpoint: a blank/absent form is still the confirm-only local path (no GET), not a no-endpoint refusal. A token-less form is fetched as declared.

      Parameters:
      value - The new value. Can be null or blank for a confirm-only dialog.
      Returns:
      This object.
    • present

      Sets the presentation hint.
      Parameters:
      value - The presentation. Must not be null.
      Returns:
      This object.
    • onSuccess

      Sets the success-behavior hint.
      Parameters:
      value - The success behavior. Must not be null.
      Returns:
      This object.
    • enabledWhen

      public RowAction enabledWhen(String field, Op op, Object value, String reason)
      Gates this action on the row's own state, comparing one field against one value.

      Mirrors ActionRef.enabledWhen(String,Op,Object,String) on the detail-panel ActionBar (widgets module). This is presentation only, never the authorization gate: the endpoint behind this action must still perform its own real check and refuse on its own authority. A row whose field does not satisfy every declared rule renders this action present but disabled, carrying reason as its explanation; disabled, never hidden. Call this more than once to declare more than one rule — all of them must match, and when several fail, the runtime shows the first-declared failing reason.

      Parameters:
      field - The row field to test. Must not be null or blank.
      op - The comparison operator. Must be Op.EQ or Op.NE.
      value - The comparison value. Must not be null.
      reason - Why the action is unavailable when this rule does not match. Must not be null or blank.
      Returns:
      This object.
    • enabledWhen

      public RowAction enabledWhen(String field, Op op, String reason)
      Gates this action on the presence or absence of a row field.

      The presence-based counterpart of enabledWhen(String,Op,Object,String), which carries the full semantics.

      Parameters:
      field - The row field to test. Must not be null or blank.
      op - The comparison operator. Must be Op.PRESENT or Op.ABSENT.
      reason - Why the action is unavailable when this rule does not match. Must not be null or blank.
      Returns:
      This object.
    • visibleWhen

      Hides this action, per row, unless every rule matches (see visibleWhen for the semantics).
      Parameters:
      rules - The rules; all must match. Replaces any rules set by an earlier call.
      Returns:
      This object.
    • tone

      public RowAction tone(RowAction.Tone value)
      Sets the confirmation tone.
      Parameters:
      value - The tone. Must not be null.
      Returns:
      This object.
    • confirmLabel

      public RowAction confirmLabel(String value)
      Sets the text of the confirm button.
      Parameters:
      value - The label. Can be null to fall back to label.
      Returns:
      This object.
    • confirmRenderer

      Sets the name of the confirm renderer to use for this action's confirmation.

      The name must be registered on the client with JuneauViews.rowActions.registerConfirmRenderer; an unregistered name refuses the confirmation.

      A renderer on its own, with no confirm text, is enough to prompt: the action asks the renderer before it submits even without present(DIALOG), and the prompt is titled with the action's name.

      Parameters:
      value - The renderer name. Can be null for the built-in modal.
      Returns:
      This object.